blob: 10f272881c2aedfbf836482404ef0ec9f20115e3 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
21** Enable large-file support for fopen() and friends on unix.
22*/
23#ifndef SQLITE_DISABLE_LFS
24# define _LARGE_FILE 1
25# ifndef _FILE_OFFSET_BITS
26# define _FILE_OFFSET_BITS 64
27# endif
28# define _LARGEFILE_SOURCE 1
29#endif
30
drh75897232000-05-29 14:26:00 +000031#include <stdlib.h>
32#include <string.h>
33#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000034#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000035#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000036#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000037#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000038
drh83905c92012-06-21 13:00:37 +000039#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000040# include <signal.h>
chw97185482008-11-17 08:05:31 +000041# if !defined(__RTP__) && !defined(_WRS_KERNEL)
42# include <pwd.h>
43# endif
drhdd45df82002-04-18 12:39:03 +000044# include <unistd.h>
45# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000046#endif
drh75897232000-05-29 14:26:00 +000047
drh81d7fd12010-12-08 00:02:26 +000048#ifdef HAVE_EDITLINE
49# include <editline/editline.h>
50#endif
drh16e59552000-07-31 11:57:37 +000051#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000052# include <readline/readline.h>
53# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000054#endif
55#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
drh18f52e02012-01-16 16:56:31 +000056# define readline(p) local_getline(p,stdin,0)
persicom1d0b8722002-04-18 02:53:04 +000057# define add_history(X)
drh67505e72002-04-19 12:34:06 +000058# define read_history(X)
59# define write_history(X)
60# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000061#endif
62
adamd2e8464a2006-09-06 21:39:40 +000063#if defined(_WIN32) || defined(WIN32)
64# include <io.h>
shane18e526c2008-12-10 22:30:24 +000065#define isatty(h) _isatty(h)
66#define access(f,m) _access((f),(m))
drh67ceaa62012-08-27 21:19:03 +000067#undef popen
drhe1da8fa2012-03-30 00:05:57 +000068#define popen(a,b) _popen((a),(b))
drh67ceaa62012-08-27 21:19:03 +000069#undef pclose
drhe1da8fa2012-03-30 00:05:57 +000070#define pclose(x) _pclose(x)
adamd2e8464a2006-09-06 21:39:40 +000071#else
drh4328c8b2003-04-26 02:50:11 +000072/* Make sure isatty() has a prototype.
73*/
drhb2acc3b2011-10-13 16:36:29 +000074extern int isatty(int);
adamd2e8464a2006-09-06 21:39:40 +000075#endif
drh4328c8b2003-04-26 02:50:11 +000076
chw65d3c132007-11-12 21:09:10 +000077#if defined(_WIN32_WCE)
78/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
79 * thus we always assume that we have a console. That can be
80 * overridden with the -batch command line option.
81 */
82#define isatty(x) 1
83#endif
84
drhc6e41722011-04-11 15:36:26 +000085/* True if the timer is enabled */
86static int enableTimer = 0;
87
drhf0693c82011-10-11 20:41:54 +000088/* ctype macros that work with signed characters */
89#define IsSpace(X) isspace((unsigned char)X)
90#define IsDigit(X) isdigit((unsigned char)X)
91#define ToLower(X) (char)tolower((unsigned char)X)
92
drh83905c92012-06-21 13:00:37 +000093#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000094#include <sys/time.h>
95#include <sys/resource.h>
96
drhda108222009-02-25 19:07:24 +000097/* Saved resource information for the beginning of an operation */
98static struct rusage sBegin;
99
drhda108222009-02-25 19:07:24 +0000100/*
101** Begin timing an operation
102*/
103static void beginTimer(void){
104 if( enableTimer ){
105 getrusage(RUSAGE_SELF, &sBegin);
106 }
107}
108
109/* Return the difference of two time_structs in seconds */
110static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
111 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
112 (double)(pEnd->tv_sec - pStart->tv_sec);
113}
114
115/*
116** Print the timing results.
117*/
118static void endTimer(void){
119 if( enableTimer ){
120 struct rusage sEnd;
121 getrusage(RUSAGE_SELF, &sEnd);
122 printf("CPU Time: user %f sys %f\n",
123 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
124 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
125 }
126}
shaneb320ccd2009-10-21 03:42:58 +0000127
drhda108222009-02-25 19:07:24 +0000128#define BEGIN_TIMER beginTimer()
129#define END_TIMER endTimer()
130#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000131
132#elif (defined(_WIN32) || defined(WIN32))
133
134#include <windows.h>
135
136/* Saved resource information for the beginning of an operation */
137static HANDLE hProcess;
138static FILETIME ftKernelBegin;
139static FILETIME ftUserBegin;
140typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
141static GETPROCTIMES getProcessTimesAddr = NULL;
142
shaneb320ccd2009-10-21 03:42:58 +0000143/*
144** Check to see if we have timer support. Return 1 if necessary
145** support found (or found previously).
146*/
147static int hasTimer(void){
148 if( getProcessTimesAddr ){
149 return 1;
150 } else {
151 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
152 ** See if the version we are running on has it, and if it does, save off
153 ** a pointer to it and the current process handle.
154 */
155 hProcess = GetCurrentProcess();
156 if( hProcess ){
157 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
158 if( NULL != hinstLib ){
159 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
160 if( NULL != getProcessTimesAddr ){
161 return 1;
162 }
163 FreeLibrary(hinstLib);
164 }
165 }
166 }
167 return 0;
168}
169
170/*
171** Begin timing an operation
172*/
173static void beginTimer(void){
174 if( enableTimer && getProcessTimesAddr ){
175 FILETIME ftCreation, ftExit;
176 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
177 }
178}
179
180/* Return the difference of two FILETIME structs in seconds */
181static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
182 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
183 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
184 return (double) ((i64End - i64Start) / 10000000.0);
185}
186
187/*
188** Print the timing results.
189*/
190static void endTimer(void){
191 if( enableTimer && getProcessTimesAddr){
192 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
193 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
194 printf("CPU Time: user %f sys %f\n",
195 timeDiff(&ftUserBegin, &ftUserEnd),
196 timeDiff(&ftKernelBegin, &ftKernelEnd));
197 }
198}
199
200#define BEGIN_TIMER beginTimer()
201#define END_TIMER endTimer()
202#define HAS_TIMER hasTimer()
203
drhda108222009-02-25 19:07:24 +0000204#else
205#define BEGIN_TIMER
206#define END_TIMER
207#define HAS_TIMER 0
208#endif
209
shanec0688ea2009-03-05 03:48:06 +0000210/*
211** Used to prevent warnings about unused parameters
212*/
213#define UNUSED_PARAMETER(x) (void)(x)
214
drhe91d16b2008-12-08 18:27:31 +0000215/*
drhc49f44e2006-10-26 18:15:42 +0000216** If the following flag is set, then command execution stops
217** at an error if we are not interactive.
218*/
219static int bail_on_error = 0;
220
221/*
drhc28490c2006-10-26 14:25:58 +0000222** Threat stdin as an interactive input if the following variable
223** is true. Otherwise, assume stdin is connected to a file or pipe.
224*/
225static int stdin_is_interactive = 1;
226
227/*
drh4c504392000-10-16 22:06:40 +0000228** The following is the open SQLite database. We make a pointer
229** to this database a static variable so that it can be accessed
230** by the SIGINT handler to interrupt database processing.
231*/
danielk197792f9a1b2004-06-19 09:08:16 +0000232static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000233
234/*
drh67505e72002-04-19 12:34:06 +0000235** True if an interrupt (Control-C) has been received.
236*/
drh43617e92006-03-06 20:55:46 +0000237static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000238
239/*
persicom7e2dfdd2002-04-18 02:46:52 +0000240** This is the name of our program. It is set in main(), used
241** in a number of other places, mostly for error messages.
242*/
243static char *Argv0;
244
245/*
246** Prompt strings. Initialized in main. Settable with
247** .prompt main continue
248*/
249static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
250static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
251
drhb0603412007-02-28 04:47:26 +0000252/*
253** Write I/O traces to the following stream.
254*/
rsebe0a9092007-07-30 18:24:38 +0000255#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000256static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000257#endif
drhb0603412007-02-28 04:47:26 +0000258
259/*
260** This routine works like printf in that its first argument is a
261** format string and subsequent arguments are values to be substituted
262** in place of % fields. The result of formatting this string
263** is written to iotrace.
264*/
rsebe0a9092007-07-30 18:24:38 +0000265#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000266static void iotracePrintf(const char *zFormat, ...){
267 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000268 char *z;
drhb0603412007-02-28 04:47:26 +0000269 if( iotrace==0 ) return;
270 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000271 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000272 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000273 fprintf(iotrace, "%s", z);
274 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000275}
rsebe0a9092007-07-30 18:24:38 +0000276#endif
drhb0603412007-02-28 04:47:26 +0000277
drh44c2eb12003-04-30 11:38:26 +0000278
persicom7e2dfdd2002-04-18 02:46:52 +0000279/*
drh83965662003-04-17 02:54:13 +0000280** Determines if a string is a number of not.
281*/
danielk19772e588c72005-12-09 14:25:08 +0000282static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000283 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000284 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000285 return 0;
286 }
287 z++;
288 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000289 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000290 if( *z=='.' ){
291 z++;
drhf0693c82011-10-11 20:41:54 +0000292 if( !IsDigit(*z) ) return 0;
293 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000294 if( realnum ) *realnum = 1;
295 }
296 if( *z=='e' || *z=='E' ){
297 z++;
298 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000299 if( !IsDigit(*z) ) return 0;
300 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000301 if( realnum ) *realnum = 1;
302 }
303 return *z==0;
304}
drh83965662003-04-17 02:54:13 +0000305
306/*
danielk1977bc6ada42004-06-30 08:20:16 +0000307** A global char* and an SQL function to access its current value
308** from within an SQL statement. This program used to use the
309** sqlite_exec_printf() API to substitue a string into an SQL statement.
310** The correct way to do this with sqlite3 is to use the bind API, but
311** since the shell is built around the callback paradigm it would be a lot
312** of work. Instead just use this hack, which is quite harmless.
313*/
314static const char *zShellStatic = 0;
315static void shellstaticFunc(
316 sqlite3_context *context,
317 int argc,
318 sqlite3_value **argv
319){
320 assert( 0==argc );
321 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000322 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000323 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000324 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
325}
326
327
328/*
drhfeac5f82004-08-01 00:10:45 +0000329** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000330** the text in memory obtained from malloc() and returns a pointer
331** to the text. NULL is returned at end of file, or if malloc()
332** fails.
333**
334** The interface is like "readline" but no command-line editing
335** is done.
336*/
drh18f52e02012-01-16 16:56:31 +0000337static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
drh8e7e7a22000-05-30 18:45:23 +0000338 char *zLine;
339 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000340 int n;
drh18f52e02012-01-16 16:56:31 +0000341 int inQuote = 0;
drh8e7e7a22000-05-30 18:45:23 +0000342
343 if( zPrompt && *zPrompt ){
344 printf("%s",zPrompt);
345 fflush(stdout);
346 }
347 nLine = 100;
348 zLine = malloc( nLine );
349 if( zLine==0 ) return 0;
350 n = 0;
drhb07028f2011-10-14 21:49:18 +0000351 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000352 if( n+100>nLine ){
353 nLine = nLine*2 + 100;
354 zLine = realloc(zLine, nLine);
355 if( zLine==0 ) return 0;
356 }
drhdaffd0e2001-04-11 14:28:42 +0000357 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000358 if( n==0 ){
359 free(zLine);
360 return 0;
361 }
362 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000363 break;
364 }
drh18f52e02012-01-16 16:56:31 +0000365 while( zLine[n] ){
366 if( zLine[n]=='"' ) inQuote = !inQuote;
367 n++;
368 }
369 if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
drh8e7e7a22000-05-30 18:45:23 +0000370 n--;
shaneh13b36022009-12-17 21:07:15 +0000371 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000372 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000373 break;
drh8e7e7a22000-05-30 18:45:23 +0000374 }
375 }
376 zLine = realloc( zLine, n+1 );
377 return zLine;
378}
379
380/*
drhc28490c2006-10-26 14:25:58 +0000381** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000382**
383** zPrior is a string of prior text retrieved. If not the empty
384** string, then issue a continuation prompt.
385*/
drhdaffd0e2001-04-11 14:28:42 +0000386static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000387 char *zPrompt;
388 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000389 if( in!=0 ){
drh18f52e02012-01-16 16:56:31 +0000390 return local_getline(0, in, 0);
drh8e7e7a22000-05-30 18:45:23 +0000391 }
392 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000393 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000394 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000395 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000396 }
397 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000398#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000399 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000400#endif
drh8e7e7a22000-05-30 18:45:23 +0000401 return zResult;
402}
403
persicom7e2dfdd2002-04-18 02:46:52 +0000404struct previous_mode_data {
405 int valid; /* Is there legit data in here? */
406 int mode;
407 int showHeader;
408 int colWidth[100];
409};
drh45e29d82006-11-20 16:21:10 +0000410
drh8e7e7a22000-05-30 18:45:23 +0000411/*
drh75897232000-05-29 14:26:00 +0000412** An pointer to an instance of this structure is passed from
413** the main program to the callback. This is used to communicate
414** state and mode information.
415*/
416struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000417 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000418 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000419 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000420 int cnt; /* Number of records displayed so far */
421 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000422 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000423 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000424 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000425 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000426 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000427 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000428 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000429 int colWidth[100]; /* Requested width of each column when in column mode*/
430 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000431 char nullvalue[20]; /* The text to print when a NULL comes back from
432 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000433 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000434 /* Holds the mode information just before
435 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000436 char outfile[FILENAME_MAX]; /* Filename for *out */
437 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000438 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000439 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000440 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000441};
442
443/*
444** These are the allowed modes.
445*/
drh967e8b72000-06-21 13:59:10 +0000446#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000447#define MODE_Column 1 /* One record per line in neat columns */
448#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000449#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
450#define MODE_Html 4 /* Generate an XHTML table */
451#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000452#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000453#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000454#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000455
drh66ce4d02008-02-15 17:38:06 +0000456static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000457 "line",
458 "column",
459 "list",
460 "semi",
461 "html",
drhfeac5f82004-08-01 00:10:45 +0000462 "insert",
463 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000464 "csv",
drh66ce4d02008-02-15 17:38:06 +0000465 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000466};
drh75897232000-05-29 14:26:00 +0000467
468/*
469** Number of elements in an array
470*/
drh902b9ee2008-12-05 17:17:07 +0000471#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000472
473/*
drhea678832008-12-10 19:26:22 +0000474** Compute a string length that is limited to what can be stored in
475** lower 30 bits of a 32-bit signed integer.
476*/
drh4f21c4a2008-12-10 22:15:00 +0000477static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000478 const char *z2 = z;
479 while( *z2 ){ z2++; }
480 return 0x3fffffff & (int)(z2 - z);
481}
482
483/*
drh127f9d72010-02-23 01:47:00 +0000484** A callback for the sqlite3_log() interface.
485*/
486static void shellLog(void *pArg, int iErrCode, const char *zMsg){
487 struct callback_data *p = (struct callback_data*)pArg;
488 if( p->pLog==0 ) return;
489 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
490 fflush(p->pLog);
491}
492
493/*
shane626a6e42009-10-22 17:30:15 +0000494** Output the given string as a hex-encoded blob (eg. X'1234' )
495*/
496static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
497 int i;
498 char *zBlob = (char *)pBlob;
499 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000500 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000501 fprintf(out,"'");
502}
503
504/*
drh28bd4bc2000-06-15 15:57:22 +0000505** Output the given string as a quoted string using SQL quoting conventions.
506*/
507static void output_quoted_string(FILE *out, const char *z){
508 int i;
509 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000510 for(i=0; z[i]; i++){
511 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000512 }
513 if( nSingle==0 ){
514 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000515 }else{
516 fprintf(out,"'");
517 while( *z ){
518 for(i=0; z[i] && z[i]!='\''; i++){}
519 if( i==0 ){
520 fprintf(out,"''");
521 z++;
522 }else if( z[i]=='\'' ){
523 fprintf(out,"%.*s''",i,z);
524 z += i+1;
525 }else{
drhcd7d2732002-02-26 23:24:26 +0000526 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000527 break;
528 }
529 }
drhcd7d2732002-02-26 23:24:26 +0000530 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000531 }
532}
533
534/*
drhfeac5f82004-08-01 00:10:45 +0000535** Output the given string as a quoted according to C or TCL quoting rules.
536*/
537static void output_c_string(FILE *out, const char *z){
538 unsigned int c;
539 fputc('"', out);
540 while( (c = *(z++))!=0 ){
541 if( c=='\\' ){
542 fputc(c, out);
543 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000544 }else if( c=='"' ){
545 fputc('\\', out);
546 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000547 }else if( c=='\t' ){
548 fputc('\\', out);
549 fputc('t', out);
550 }else if( c=='\n' ){
551 fputc('\\', out);
552 fputc('n', out);
553 }else if( c=='\r' ){
554 fputc('\\', out);
555 fputc('r', out);
556 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000557 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000558 }else{
559 fputc(c, out);
560 }
561 }
562 fputc('"', out);
563}
564
565/*
drhc08a4f12000-06-15 16:49:48 +0000566** Output the given string with characters that are special to
567** HTML escaped.
568*/
569static void output_html_string(FILE *out, const char *z){
570 int i;
571 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000572 for(i=0; z[i]
573 && z[i]!='<'
574 && z[i]!='&'
575 && z[i]!='>'
576 && z[i]!='\"'
577 && z[i]!='\'';
578 i++){}
drhc08a4f12000-06-15 16:49:48 +0000579 if( i>0 ){
580 fprintf(out,"%.*s",i,z);
581 }
582 if( z[i]=='<' ){
583 fprintf(out,"&lt;");
584 }else if( z[i]=='&' ){
585 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000586 }else if( z[i]=='>' ){
587 fprintf(out,"&gt;");
588 }else if( z[i]=='\"' ){
589 fprintf(out,"&quot;");
590 }else if( z[i]=='\'' ){
591 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000592 }else{
593 break;
594 }
595 z += i + 1;
596 }
597}
598
599/*
drhc49f44e2006-10-26 18:15:42 +0000600** If a field contains any character identified by a 1 in the following
601** array, then the string must be quoted for CSV.
602*/
603static const char needCsvQuote[] = {
604 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
605 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
606 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
607 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
608 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
609 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
610 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
611 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
612 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
613 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
614 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
615 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
616 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
617 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
618 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
619 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
620};
621
622/*
drh8e64d1c2004-10-07 00:32:39 +0000623** Output a single term of CSV. Actually, p->separator is used for
624** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000625** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000626*/
627static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000628 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000629 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000630 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000631 }else{
drhc49f44e2006-10-26 18:15:42 +0000632 int i;
drh4f21c4a2008-12-10 22:15:00 +0000633 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000634 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000635 if( needCsvQuote[((unsigned char*)z)[i]]
636 || (z[i]==p->separator[0] &&
637 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000638 i = 0;
639 break;
640 }
641 }
642 if( i==0 ){
643 putc('"', out);
644 for(i=0; z[i]; i++){
645 if( z[i]=='"' ) putc('"', out);
646 putc(z[i], out);
647 }
648 putc('"', out);
649 }else{
650 fprintf(out, "%s", z);
651 }
drh8e64d1c2004-10-07 00:32:39 +0000652 }
653 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000654 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000655 }
656}
657
danielk19774af00c62005-01-23 23:43:21 +0000658#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000659/*
drh4c504392000-10-16 22:06:40 +0000660** This routine runs when the user presses Ctrl-C
661*/
662static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000663 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000664 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000665 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000666}
danielk19774af00c62005-01-23 23:43:21 +0000667#endif
drh4c504392000-10-16 22:06:40 +0000668
669/*
shane626a6e42009-10-22 17:30:15 +0000670** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000671** invokes for each row of a query result.
672*/
shane626a6e42009-10-22 17:30:15 +0000673static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000674 int i;
675 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000676
drh75897232000-05-29 14:26:00 +0000677 switch( p->mode ){
678 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000679 int w = 5;
drh6a535342001-10-19 16:44:56 +0000680 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000681 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000682 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000683 if( len>w ) w = len;
684 }
drh75897232000-05-29 14:26:00 +0000685 if( p->cnt++>0 ) fprintf(p->out,"\n");
686 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000687 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000688 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000689 }
690 break;
691 }
danielk19770d78bae2008-01-03 07:09:48 +0000692 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000693 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000694 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000695 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000696 int w, n;
697 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000698 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000699 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000700 w = 0;
drh75897232000-05-29 14:26:00 +0000701 }
drh078b1fd2012-09-21 13:40:02 +0000702 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000703 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000704 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000705 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000706 if( w<n ) w = n;
707 }
708 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000709 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000710 }
711 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000712 if( w<0 ){
713 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
714 }else{
715 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
716 }
drha0c66f52000-07-29 13:20:21 +0000717 }
718 }
719 if( p->showHeader ){
720 for(i=0; i<nArg; i++){
721 int w;
722 if( i<ArraySize(p->actualWidth) ){
723 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000724 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000725 }else{
726 w = 10;
727 }
728 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
729 "----------------------------------------------------------",
730 i==nArg-1 ? "\n": " ");
731 }
drh75897232000-05-29 14:26:00 +0000732 }
733 }
drh6a535342001-10-19 16:44:56 +0000734 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000735 for(i=0; i<nArg; i++){
736 int w;
drha0c66f52000-07-29 13:20:21 +0000737 if( i<ArraySize(p->actualWidth) ){
738 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000739 }else{
740 w = 10;
741 }
drhea678832008-12-10 19:26:22 +0000742 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000743 strlen30(azArg[i])>w ){
744 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000745 }
drh078b1fd2012-09-21 13:40:02 +0000746 if( w<0 ){
747 fprintf(p->out,"%*.*s%s",-w,-w,
748 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
749 }else{
750 fprintf(p->out,"%-*.*s%s",w,w,
751 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
752 }
drh75897232000-05-29 14:26:00 +0000753 }
754 break;
755 }
drhe3710332000-09-29 13:30:53 +0000756 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000757 case MODE_List: {
758 if( p->cnt++==0 && p->showHeader ){
759 for(i=0; i<nArg; i++){
760 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
761 }
762 }
drh6a535342001-10-19 16:44:56 +0000763 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000764 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000765 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000766 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000767 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000768 if( i<nArg-1 ){
769 fprintf(p->out, "%s", p->separator);
770 }else if( p->mode==MODE_Semi ){
771 fprintf(p->out, ";\n");
772 }else{
773 fprintf(p->out, "\n");
774 }
drh75897232000-05-29 14:26:00 +0000775 }
776 break;
777 }
drh1e5d0e92000-05-31 23:33:17 +0000778 case MODE_Html: {
779 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000780 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000781 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000782 fprintf(p->out,"<TH>");
783 output_html_string(p->out, azCol[i]);
784 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000785 }
mihailim57c591a2008-06-23 21:26:05 +0000786 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000787 }
drh6a535342001-10-19 16:44:56 +0000788 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000789 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000790 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000791 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000792 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000793 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000794 }
mihailim57c591a2008-06-23 21:26:05 +0000795 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000796 break;
797 }
drhfeac5f82004-08-01 00:10:45 +0000798 case MODE_Tcl: {
799 if( p->cnt++==0 && p->showHeader ){
800 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000801 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin585dcb22012-12-04 00:23:43 +0000802 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000803 }
804 fprintf(p->out,"\n");
805 }
806 if( azArg==0 ) break;
807 for(i=0; i<nArg; i++){
808 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mistachkin585dcb22012-12-04 00:23:43 +0000809 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000810 }
811 fprintf(p->out,"\n");
812 break;
813 }
drh8e64d1c2004-10-07 00:32:39 +0000814 case MODE_Csv: {
815 if( p->cnt++==0 && p->showHeader ){
816 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000817 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000818 }
819 fprintf(p->out,"\n");
820 }
821 if( azArg==0 ) break;
822 for(i=0; i<nArg; i++){
823 output_csv(p, azArg[i], i<nArg-1);
824 }
825 fprintf(p->out,"\n");
826 break;
827 }
drh28bd4bc2000-06-15 15:57:22 +0000828 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000829 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000830 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000831 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000832 for(i=0; i<nArg; i++){
833 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000834 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000835 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000836 }else if( aiType && aiType[i]==SQLITE_TEXT ){
837 if( zSep[0] ) fprintf(p->out,"%s",zSep);
838 output_quoted_string(p->out, azArg[i]);
839 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
840 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000841 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
842 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
843 int nBlob = sqlite3_column_bytes(p->pStmt, i);
844 if( zSep[0] ) fprintf(p->out,"%s",zSep);
845 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000846 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000847 fprintf(p->out,"%s%s",zSep, azArg[i]);
848 }else{
849 if( zSep[0] ) fprintf(p->out,"%s",zSep);
850 output_quoted_string(p->out, azArg[i]);
851 }
852 }
853 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000854 break;
drh28bd4bc2000-06-15 15:57:22 +0000855 }
persicom1d0b8722002-04-18 02:53:04 +0000856 }
drh75897232000-05-29 14:26:00 +0000857 return 0;
858}
859
860/*
shane626a6e42009-10-22 17:30:15 +0000861** This is the callback routine that the SQLite library
862** invokes for each row of a query result.
863*/
864static int callback(void *pArg, int nArg, char **azArg, char **azCol){
865 /* since we don't have type info, call the shell_callback with a NULL value */
866 return shell_callback(pArg, nArg, azArg, azCol, NULL);
867}
868
869/*
drh33048c02001-10-01 14:29:22 +0000870** Set the destination table field of the callback_data structure to
871** the name of the table given. Escape any quote characters in the
872** table name.
873*/
874static void set_table_name(struct callback_data *p, const char *zName){
875 int i, n;
876 int needQuote;
877 char *z;
878
879 if( p->zDestTable ){
880 free(p->zDestTable);
881 p->zDestTable = 0;
882 }
883 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000884 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000885 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000886 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000887 needQuote = 1;
888 if( zName[i]=='\'' ) n++;
889 }
890 }
891 if( needQuote ) n += 2;
892 z = p->zDestTable = malloc( n+1 );
893 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000894 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000895 exit(1);
896 }
897 n = 0;
898 if( needQuote ) z[n++] = '\'';
899 for(i=0; zName[i]; i++){
900 z[n++] = zName[i];
901 if( zName[i]=='\'' ) z[n++] = '\'';
902 }
903 if( needQuote ) z[n++] = '\'';
904 z[n] = 0;
905}
906
danielk19772a02e332004-06-05 08:04:36 +0000907/* zIn is either a pointer to a NULL-terminated string in memory obtained
908** from malloc(), or a NULL pointer. The string pointed to by zAppend is
909** added to zIn, and the result returned in memory obtained from malloc().
910** zIn, if it was not NULL, is freed.
911**
912** If the third argument, quote, is not '\0', then it is used as a
913** quote character for zAppend.
914*/
drhc28490c2006-10-26 14:25:58 +0000915static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000916 int len;
917 int i;
drh4f21c4a2008-12-10 22:15:00 +0000918 int nAppend = strlen30(zAppend);
919 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000920
921 len = nAppend+nIn+1;
922 if( quote ){
923 len += 2;
924 for(i=0; i<nAppend; i++){
925 if( zAppend[i]==quote ) len++;
926 }
927 }
928
929 zIn = (char *)realloc(zIn, len);
930 if( !zIn ){
931 return 0;
932 }
933
934 if( quote ){
935 char *zCsr = &zIn[nIn];
936 *zCsr++ = quote;
937 for(i=0; i<nAppend; i++){
938 *zCsr++ = zAppend[i];
939 if( zAppend[i]==quote ) *zCsr++ = quote;
940 }
941 *zCsr++ = quote;
942 *zCsr++ = '\0';
943 assert( (zCsr-zIn)==len );
944 }else{
945 memcpy(&zIn[nIn], zAppend, nAppend);
946 zIn[len-1] = '\0';
947 }
948
949 return zIn;
950}
951
drhdd3d4592004-08-30 01:54:05 +0000952
953/*
drhb21a8e42012-01-28 21:08:51 +0000954** Execute a query statement that will generate SQL output. Print
955** the result columns, comma-separated, on a line and then add a
956** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000957**
drhb21a8e42012-01-28 21:08:51 +0000958** If the number of columns is 1 and that column contains text "--"
959** then write the semicolon on a separate line. That way, if a
960** "--" comment occurs at the end of the statement, the comment
961** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000962*/
drh157e29a2009-05-21 15:15:00 +0000963static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000964 struct callback_data *p, /* Query context */
965 const char *zSelect, /* SELECT statement to extract content */
966 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000967){
drhdd3d4592004-08-30 01:54:05 +0000968 sqlite3_stmt *pSelect;
969 int rc;
drhb21a8e42012-01-28 21:08:51 +0000970 int nResult;
971 int i;
972 const char *z;
drh2f464a02011-10-13 00:41:49 +0000973 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000974 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000975 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
976 p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000977 return rc;
978 }
979 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000980 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000981 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000982 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000983 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000984 zFirstRow = 0;
985 }
drhb21a8e42012-01-28 21:08:51 +0000986 z = (const char*)sqlite3_column_text(pSelect, 0);
987 fprintf(p->out, "%s", z);
988 for(i=1; i<nResult; i++){
989 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
990 }
991 if( z==0 ) z = "";
992 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
993 if( z[0] ){
994 fprintf(p->out, "\n;\n");
995 }else{
996 fprintf(p->out, ";\n");
997 }
drhdd3d4592004-08-30 01:54:05 +0000998 rc = sqlite3_step(pSelect);
999 }
drh2f464a02011-10-13 00:41:49 +00001000 rc = sqlite3_finalize(pSelect);
1001 if( rc!=SQLITE_OK ){
1002 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
1003 p->nErr++;
1004 }
1005 return rc;
drhdd3d4592004-08-30 01:54:05 +00001006}
1007
shane626a6e42009-10-22 17:30:15 +00001008/*
1009** Allocate space and save off current error string.
1010*/
1011static char *save_err_msg(
1012 sqlite3 *db /* Database to query */
1013){
1014 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1015 char *zErrMsg = sqlite3_malloc(nErrMsg);
1016 if( zErrMsg ){
1017 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1018 }
1019 return zErrMsg;
1020}
1021
1022/*
shaneh642d8b82010-07-28 16:05:34 +00001023** Display memory stats.
1024*/
1025static int display_stats(
1026 sqlite3 *db, /* Database to query */
1027 struct callback_data *pArg, /* Pointer to struct callback_data */
1028 int bReset /* True to reset the stats */
1029){
1030 int iCur;
1031 int iHiwtr;
1032
1033 if( pArg && pArg->out ){
1034
1035 iHiwtr = iCur = -1;
1036 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001037 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001038 iHiwtr = iCur = -1;
1039 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001040 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001041/*
1042** Not currently used by the CLI.
1043** iHiwtr = iCur = -1;
1044** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1045** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1046*/
1047 iHiwtr = iCur = -1;
1048 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1049 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1050/*
1051** Not currently used by the CLI.
1052** iHiwtr = iCur = -1;
1053** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1054** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1055*/
1056 iHiwtr = iCur = -1;
1057 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1058 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1059 iHiwtr = iCur = -1;
1060 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1061 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1062 iHiwtr = iCur = -1;
1063 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1064 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1065 iHiwtr = iCur = -1;
1066 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1067 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1068#ifdef YYTRACKMAXSTACKDEPTH
1069 iHiwtr = iCur = -1;
1070 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1071 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1072#endif
1073 }
1074
1075 if( pArg && pArg->out && db ){
1076 iHiwtr = iCur = -1;
1077 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1078 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001079 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1080 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1081 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1082 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1083 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1084 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001085 iHiwtr = iCur = -1;
1086 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001087 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1088 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1089 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1090 iHiwtr = iCur = -1;
1091 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1092 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001093 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001094 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1095 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1096 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001097 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1098 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1099 iHiwtr = iCur = -1;
1100 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1101 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1102 }
1103
1104 if( pArg && pArg->out && db && pArg->pStmt ){
1105 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1106 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1107 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1108 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1109 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1110 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1111 }
1112
1113 return 0;
1114}
1115
1116/*
shane626a6e42009-10-22 17:30:15 +00001117** Execute a statement or set of statements. Print
1118** any result rows/columns depending on the current mode
1119** set via the supplied callback.
1120**
1121** This is very similar to SQLite's built-in sqlite3_exec()
1122** function except it takes a slightly different callback
1123** and callback data argument.
1124*/
1125static int shell_exec(
1126 sqlite3 *db, /* An open database */
1127 const char *zSql, /* SQL to be evaluated */
1128 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1129 /* (not the same as sqlite3_exec) */
1130 struct callback_data *pArg, /* Pointer to struct callback_data */
1131 char **pzErrMsg /* Error msg written here */
1132){
dan4564ced2010-01-05 04:59:56 +00001133 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1134 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001135 int rc2;
dan4564ced2010-01-05 04:59:56 +00001136 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001137
1138 if( pzErrMsg ){
1139 *pzErrMsg = NULL;
1140 }
1141
shaneb9fc17d2009-10-22 21:23:35 +00001142 while( zSql[0] && (SQLITE_OK == rc) ){
1143 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1144 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001145 if( pzErrMsg ){
1146 *pzErrMsg = save_err_msg(db);
1147 }
1148 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001149 if( !pStmt ){
1150 /* this happens for a comment or white-space */
1151 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001152 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001153 continue;
1154 }
shane626a6e42009-10-22 17:30:15 +00001155
shaneh642d8b82010-07-28 16:05:34 +00001156 /* save off the prepared statment handle and reset row count */
1157 if( pArg ){
1158 pArg->pStmt = pStmt;
1159 pArg->cnt = 0;
1160 }
1161
shanehb7977c52010-01-18 18:17:10 +00001162 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001163 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001164 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001165 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001166 }
shanehb7977c52010-01-18 18:17:10 +00001167
drh7e02e5e2011-12-06 19:44:51 +00001168 /* Output TESTCTRL_EXPLAIN text of requested */
1169 if( pArg && pArg->mode==MODE_Explain ){
1170 const char *zExplain = 0;
1171 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1172 if( zExplain && zExplain[0] ){
1173 fprintf(pArg->out, "%s", zExplain);
1174 }
1175 }
1176
shaneb9fc17d2009-10-22 21:23:35 +00001177 /* perform the first step. this will tell us if we
1178 ** have a result set or not and how wide it is.
1179 */
1180 rc = sqlite3_step(pStmt);
1181 /* if we have a result set... */
1182 if( SQLITE_ROW == rc ){
1183 /* if we have a callback... */
1184 if( xCallback ){
1185 /* allocate space for col name ptr, value ptr, and type */
1186 int nCol = sqlite3_column_count(pStmt);
1187 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1188 if( !pData ){
1189 rc = SQLITE_NOMEM;
1190 }else{
1191 char **azCols = (char **)pData; /* Names of result columns */
1192 char **azVals = &azCols[nCol]; /* Results */
1193 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1194 int i;
1195 assert(sizeof(int) <= sizeof(char *));
1196 /* save off ptrs to column names */
1197 for(i=0; i<nCol; i++){
1198 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1199 }
shaneb9fc17d2009-10-22 21:23:35 +00001200 do{
1201 /* extract the data and data types */
1202 for(i=0; i<nCol; i++){
1203 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1204 aiTypes[i] = sqlite3_column_type(pStmt, i);
1205 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1206 rc = SQLITE_NOMEM;
1207 break; /* from for */
1208 }
1209 } /* end for */
1210
1211 /* if data and types extracted successfully... */
1212 if( SQLITE_ROW == rc ){
1213 /* call the supplied callback with the result row data */
1214 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1215 rc = SQLITE_ABORT;
1216 }else{
1217 rc = sqlite3_step(pStmt);
1218 }
1219 }
1220 } while( SQLITE_ROW == rc );
1221 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001222 }
1223 }else{
1224 do{
1225 rc = sqlite3_step(pStmt);
1226 } while( rc == SQLITE_ROW );
1227 }
1228 }
1229
shaneh642d8b82010-07-28 16:05:34 +00001230 /* print usage stats if stats on */
1231 if( pArg && pArg->statsOn ){
1232 display_stats(db, pArg, 0);
1233 }
1234
dan4564ced2010-01-05 04:59:56 +00001235 /* Finalize the statement just executed. If this fails, save a
1236 ** copy of the error message. Otherwise, set zSql to point to the
1237 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001238 rc2 = sqlite3_finalize(pStmt);
1239 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001240 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001241 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001242 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001243 }else if( pzErrMsg ){
1244 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001245 }
shaneh642d8b82010-07-28 16:05:34 +00001246
1247 /* clear saved stmt handle */
1248 if( pArg ){
1249 pArg->pStmt = NULL;
1250 }
shane626a6e42009-10-22 17:30:15 +00001251 }
shaneb9fc17d2009-10-22 21:23:35 +00001252 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001253
1254 return rc;
1255}
1256
drhdd3d4592004-08-30 01:54:05 +00001257
drh33048c02001-10-01 14:29:22 +00001258/*
drh4c653a02000-06-07 01:27:47 +00001259** This is a different callback routine used for dumping the database.
1260** Each row received by this callback consists of a table name,
1261** the table type ("index" or "table") and SQL to create the table.
1262** This routine should print text sufficient to recreate the table.
1263*/
1264static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001265 int rc;
1266 const char *zTable;
1267 const char *zType;
1268 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001269 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001270 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001271
drh902b9ee2008-12-05 17:17:07 +00001272 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001273 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001274 zTable = azArg[0];
1275 zType = azArg[1];
1276 zSql = azArg[2];
1277
drh00b950d2005-09-11 02:03:03 +00001278 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001279 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001280 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1281 fprintf(p->out, "ANALYZE sqlite_master;\n");
1282 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1283 return 0;
drh45e29d82006-11-20 16:21:10 +00001284 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1285 char *zIns;
1286 if( !p->writableSchema ){
1287 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1288 p->writableSchema = 1;
1289 }
1290 zIns = sqlite3_mprintf(
1291 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1292 "VALUES('table','%q','%q',0,'%q');",
1293 zTable, zTable, zSql);
1294 fprintf(p->out, "%s\n", zIns);
1295 sqlite3_free(zIns);
1296 return 0;
drh00b950d2005-09-11 02:03:03 +00001297 }else{
1298 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001299 }
danielk19772a02e332004-06-05 08:04:36 +00001300
1301 if( strcmp(zType, "table")==0 ){
1302 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001303 char *zSelect = 0;
1304 char *zTableInfo = 0;
1305 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001306 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001307
1308 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1309 zTableInfo = appendText(zTableInfo, zTable, '"');
1310 zTableInfo = appendText(zTableInfo, ");", 0);
1311
1312 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001313 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001314 if( rc!=SQLITE_OK || !pTableInfo ){
1315 return 1;
1316 }
1317
1318 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001319 /* Always quote the table name, even if it appears to be pure ascii,
1320 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1321 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001322 if( zTmp ){
1323 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001324 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001325 }
1326 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1327 rc = sqlite3_step(pTableInfo);
1328 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001329 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001330 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001331 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001332 rc = sqlite3_step(pTableInfo);
1333 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001334 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001335 }else{
1336 zSelect = appendText(zSelect, ") ", 0);
1337 }
drh157e29a2009-05-21 15:15:00 +00001338 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001339 }
1340 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001341 if( rc!=SQLITE_OK || nRow==0 ){
1342 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001343 return 1;
1344 }
1345 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1346 zSelect = appendText(zSelect, zTable, '"');
1347
drh2f464a02011-10-13 00:41:49 +00001348 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001349 if( rc==SQLITE_CORRUPT ){
1350 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001351 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001352 }
drh85e72432012-04-11 11:38:53 +00001353 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001354 }
drh4c653a02000-06-07 01:27:47 +00001355 return 0;
1356}
1357
1358/*
drh45e29d82006-11-20 16:21:10 +00001359** Run zQuery. Use dump_callback() as the callback routine so that
1360** the contents of the query are output as SQL statements.
1361**
drhdd3d4592004-08-30 01:54:05 +00001362** If we get a SQLITE_CORRUPT error, rerun the query after appending
1363** "ORDER BY rowid DESC" to the end.
1364*/
1365static int run_schema_dump_query(
1366 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001367 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001368){
1369 int rc;
drh2f464a02011-10-13 00:41:49 +00001370 char *zErr = 0;
1371 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001372 if( rc==SQLITE_CORRUPT ){
1373 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001374 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001375 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1376 if( zErr ){
1377 fprintf(p->out, "/****** %s ******/\n", zErr);
1378 sqlite3_free(zErr);
1379 zErr = 0;
1380 }
drhdd3d4592004-08-30 01:54:05 +00001381 zQ2 = malloc( len+100 );
1382 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001383 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001384 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1385 if( rc ){
1386 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1387 }else{
1388 rc = SQLITE_CORRUPT;
1389 }
1390 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001391 free(zQ2);
1392 }
1393 return rc;
1394}
1395
1396/*
drh75897232000-05-29 14:26:00 +00001397** Text of a help message
1398*/
persicom1d0b8722002-04-18 02:53:04 +00001399static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001400 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001401 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001402 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001403 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001404 " If TABLE specified, only dump tables matching\n"
1405 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001406 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001407 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001408 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1409 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001410 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001411 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001412 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001413 ".indices ?TABLE? Show names of all indices\n"
1414 " If TABLE specified, only show indices for tables\n"
1415 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001416#ifdef SQLITE_ENABLE_IOTRACE
1417 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1418#endif
drh70df4fe2006-06-13 15:12:21 +00001419#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001420 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001421#endif
drh127f9d72010-02-23 01:47:00 +00001422 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001423 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001424 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001425 " column Left-aligned columns. (See .width)\n"
1426 " html HTML <table> code\n"
1427 " insert SQL insert statements for TABLE\n"
1428 " line One value per line\n"
1429 " list Values delimited by .separator string\n"
1430 " tabs Tab-separated values\n"
1431 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001432 ".nullvalue STRING Use STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001433 ".output FILENAME Send output to FILENAME\n"
1434 ".output stdout Send output to the screen\n"
drh078b1fd2012-09-21 13:40:02 +00001435 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001436 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001437 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001438 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001439 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001440 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001441 " If TABLE specified, only show tables matching\n"
1442 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001443 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001444 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001445 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001446 ".tables ?TABLE? List names of tables\n"
1447 " If TABLE specified, only list tables matching\n"
1448 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001449 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001450 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001451 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001452 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001453;
1454
shaneb320ccd2009-10-21 03:42:58 +00001455static char zTimerHelp[] =
1456 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1457;
1458
drhdaffd0e2001-04-11 14:28:42 +00001459/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001460static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001461
drh75897232000-05-29 14:26:00 +00001462/*
drh44c2eb12003-04-30 11:38:26 +00001463** Make sure the database is open. If it is not, then open it. If
1464** the database fails to open, print an error message and exit.
1465*/
1466static void open_db(struct callback_data *p){
1467 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001468 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001469 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001470 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001471 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1472 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1473 shellstaticFunc, 0, 0);
1474 }
1475 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001476 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001477 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001478 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001479 }
drhc2e87a32006-06-27 15:16:14 +00001480#ifndef SQLITE_OMIT_LOAD_EXTENSION
1481 sqlite3_enable_load_extension(p->db, 1);
1482#endif
drh14172742012-12-31 19:18:38 +00001483#ifdef SQLITE_ENABLE_REGEXP
1484 {
drh25846af2012-12-31 20:16:35 +00001485 extern int sqlite3_add_regexp_func(sqlite3*);
drh14172742012-12-31 19:18:38 +00001486 sqlite3_add_regexp_func(db);
1487 }
1488#endif
drh44c2eb12003-04-30 11:38:26 +00001489 }
1490}
1491
1492/*
drhfeac5f82004-08-01 00:10:45 +00001493** Do C-language style dequoting.
1494**
1495** \t -> tab
1496** \n -> newline
1497** \r -> carriage return
1498** \NNN -> ascii character NNN in octal
1499** \\ -> backslash
1500*/
1501static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001502 int i, j;
1503 char c;
drhfeac5f82004-08-01 00:10:45 +00001504 for(i=j=0; (c = z[i])!=0; i++, j++){
1505 if( c=='\\' ){
1506 c = z[++i];
1507 if( c=='n' ){
1508 c = '\n';
1509 }else if( c=='t' ){
1510 c = '\t';
1511 }else if( c=='r' ){
1512 c = '\r';
1513 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001514 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001515 if( z[i+1]>='0' && z[i+1]<='7' ){
1516 i++;
1517 c = (c<<3) + z[i] - '0';
1518 if( z[i+1]>='0' && z[i+1]<='7' ){
1519 i++;
1520 c = (c<<3) + z[i] - '0';
1521 }
1522 }
1523 }
1524 }
1525 z[j] = c;
1526 }
1527 z[j] = 0;
1528}
1529
1530/*
drhc28490c2006-10-26 14:25:58 +00001531** Interpret zArg as a boolean value. Return either 0 or 1.
1532*/
1533static int booleanValue(char *zArg){
1534 int val = atoi(zArg);
1535 int j;
1536 for(j=0; zArg[j]; j++){
drhf0693c82011-10-11 20:41:54 +00001537 zArg[j] = ToLower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001538 }
1539 if( strcmp(zArg,"on")==0 ){
1540 val = 1;
1541 }else if( strcmp(zArg,"yes")==0 ){
1542 val = 1;
1543 }
1544 return val;
1545}
1546
1547/*
drh42f64e52012-04-04 16:56:23 +00001548** Close an output file, assuming it is not stderr or stdout
1549*/
1550static void output_file_close(FILE *f){
1551 if( f && f!=stdout && f!=stderr ) fclose(f);
1552}
1553
1554/*
1555** Try to open an output file. The names "stdout" and "stderr" are
1556** recognized and do the right thing. NULL is returned if the output
1557** filename is "off".
1558*/
1559static FILE *output_file_open(const char *zFile){
1560 FILE *f;
1561 if( strcmp(zFile,"stdout")==0 ){
1562 f = stdout;
1563 }else if( strcmp(zFile, "stderr")==0 ){
1564 f = stderr;
1565 }else if( strcmp(zFile, "off")==0 ){
1566 f = 0;
1567 }else{
1568 f = fopen(zFile, "wb");
1569 if( f==0 ){
1570 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1571 }
1572 }
1573 return f;
1574}
1575
1576/*
1577** A routine for handling output from sqlite3_trace().
1578*/
1579static void sql_trace_callback(void *pArg, const char *z){
1580 FILE *f = (FILE*)pArg;
1581 if( f ) fprintf(f, "%s\n", z);
1582}
1583
1584/*
drhd8621b92012-04-17 09:09:33 +00001585** A no-op routine that runs with the ".breakpoint" doc-command. This is
1586** a useful spot to set a debugger breakpoint.
1587*/
1588static void test_breakpoint(void){
1589 static int nCall = 0;
1590 nCall++;
1591}
1592
1593/*
drh75897232000-05-29 14:26:00 +00001594** If an input line begins with "." then invoke this routine to
1595** process that line.
drh67505e72002-04-19 12:34:06 +00001596**
drh47ad6842006-11-08 12:25:42 +00001597** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001598*/
drh44c2eb12003-04-30 11:38:26 +00001599static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001600 int i = 1;
1601 int nArg = 0;
1602 int n, c;
drh67505e72002-04-19 12:34:06 +00001603 int rc = 0;
drh75897232000-05-29 14:26:00 +00001604 char *azArg[50];
1605
1606 /* Parse the input line into tokens.
1607 */
1608 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001609 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001610 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001611 if( zLine[i]=='\'' || zLine[i]=='"' ){
1612 int delim = zLine[i++];
1613 azArg[nArg++] = &zLine[i];
1614 while( zLine[i] && zLine[i]!=delim ){ i++; }
1615 if( zLine[i]==delim ){
1616 zLine[i++] = 0;
1617 }
drhfeac5f82004-08-01 00:10:45 +00001618 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001619 }else{
1620 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001621 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001622 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001623 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001624 }
1625 }
1626
1627 /* Process the input line.
1628 */
shane9bd1b442009-10-23 01:27:39 +00001629 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001630 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001631 c = azArg[0][0];
drhbc46f022013-01-23 18:53:23 +00001632 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1633 const char *zDestFile = 0;
1634 const char *zDb = 0;
1635 const char *zKey = 0;
drh9ff849f2009-02-04 20:55:57 +00001636 sqlite3 *pDest;
1637 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00001638 int j;
1639 for(j=1; j<nArg; j++){
1640 const char *z = azArg[j];
1641 if( z[0]=='-' ){
1642 while( z[0]=='-' ) z++;
1643 if( strcmp(z,"key")==0 && j<nArg-1 ){
1644 zKey = azArg[++j];
1645 }else
1646 {
1647 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1648 return 1;
1649 }
1650 }else if( zDestFile==0 ){
1651 zDestFile = azArg[j];
1652 }else if( zDb==0 ){
1653 zDb = zDestFile;
1654 zDestFile = azArg[j];
1655 }else{
1656 fprintf(stderr, "too many arguments to .backup\n");
1657 return 1;
1658 }
drh9ff849f2009-02-04 20:55:57 +00001659 }
drhbc46f022013-01-23 18:53:23 +00001660 if( zDestFile==0 ){
1661 fprintf(stderr, "missing FILENAME argument on .backup\n");
1662 return 1;
1663 }
1664 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00001665 rc = sqlite3_open(zDestFile, &pDest);
1666 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001667 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001668 sqlite3_close(pDest);
1669 return 1;
1670 }
drhbc46f022013-01-23 18:53:23 +00001671#ifdef SQLITE_HAS_CODEC
1672 sqlite3_key(pDest, zKey, (int)strlen(zKey));
1673#else
1674 (void)zKey;
1675#endif
drhdc2c4912009-02-04 22:46:47 +00001676 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001677 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1678 if( pBackup==0 ){
1679 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1680 sqlite3_close(pDest);
1681 return 1;
1682 }
1683 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1684 sqlite3_backup_finish(pBackup);
1685 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001686 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001687 }else{
1688 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001689 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001690 }
1691 sqlite3_close(pDest);
1692 }else
1693
shanehe2aa9d72009-11-06 17:20:17 +00001694 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001695 bail_on_error = booleanValue(azArg[1]);
1696 }else
1697
drhd8621b92012-04-17 09:09:33 +00001698 /* The undocumented ".breakpoint" command causes a call to the no-op
1699 ** routine named test_breakpoint().
1700 */
1701 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1702 test_breakpoint();
1703 }else
1704
shanehe2aa9d72009-11-06 17:20:17 +00001705 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001706 struct callback_data data;
1707 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001708 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001709 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001710 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001711 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001712 data.colWidth[0] = 3;
1713 data.colWidth[1] = 15;
1714 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001715 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001716 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001717 if( zErrMsg ){
1718 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001719 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001720 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001721 }
1722 }else
1723
shanehe2aa9d72009-11-06 17:20:17 +00001724 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001725 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001726 /* When playing back a "dump", the content might appear in an order
1727 ** which causes immediate foreign key constraints to be violated.
1728 ** So disable foreign-key constraint enforcement to prevent problems. */
1729 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001730 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001731 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001732 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001733 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001734 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001735 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001736 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001737 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001738 );
1739 run_schema_dump_query(p,
1740 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001741 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001742 );
drh2f464a02011-10-13 00:41:49 +00001743 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001744 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001745 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001746 );
drh4c653a02000-06-07 01:27:47 +00001747 }else{
1748 int i;
drhdd3d4592004-08-30 01:54:05 +00001749 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001750 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001751 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001752 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001753 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001754 " AND sql NOT NULL");
1755 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001756 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001757 "WHERE sql NOT NULL"
1758 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001759 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001760 );
danielk1977bc6ada42004-06-30 08:20:16 +00001761 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001762 }
1763 }
drh45e29d82006-11-20 16:21:10 +00001764 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001765 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001766 p->writableSchema = 0;
1767 }
drh56197952011-10-13 16:30:13 +00001768 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1769 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001770 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001771 }else
drh75897232000-05-29 14:26:00 +00001772
shanehe2aa9d72009-11-06 17:20:17 +00001773 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001774 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001775 }else
1776
drhd3ac7d92013-01-25 18:33:43 +00001777 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
1778 if( nArg>1 && (rc = atoi(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00001779 rc = 2;
drh75897232000-05-29 14:26:00 +00001780 }else
1781
shanehe2aa9d72009-11-06 17:20:17 +00001782 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001783 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001784 if(val == 1) {
1785 if(!p->explainPrev.valid) {
1786 p->explainPrev.valid = 1;
1787 p->explainPrev.mode = p->mode;
1788 p->explainPrev.showHeader = p->showHeader;
1789 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1790 }
1791 /* We could put this code under the !p->explainValid
1792 ** condition so that it does not execute if we are already in
1793 ** explain mode. However, always executing it allows us an easy
1794 ** was to reset to explain mode in case the user previously
1795 ** did an .explain followed by a .width, .mode or .header
1796 ** command.
1797 */
danielk19770d78bae2008-01-03 07:09:48 +00001798 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001799 p->showHeader = 1;
1800 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001801 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001802 p->colWidth[1] = 13; /* opcode */
1803 p->colWidth[2] = 4; /* P1 */
1804 p->colWidth[3] = 4; /* P2 */
1805 p->colWidth[4] = 4; /* P3 */
1806 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001807 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001808 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001809 }else if (p->explainPrev.valid) {
1810 p->explainPrev.valid = 0;
1811 p->mode = p->explainPrev.mode;
1812 p->showHeader = p->explainPrev.showHeader;
1813 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1814 }
drh75897232000-05-29 14:26:00 +00001815 }else
1816
drhc28490c2006-10-26 14:25:58 +00001817 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001818 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001819 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001820 }else
1821
1822 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001823 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001824 if( HAS_TIMER ){
1825 fprintf(stderr,"%s",zTimerHelp);
1826 }
drh75897232000-05-29 14:26:00 +00001827 }else
1828
shanehe2aa9d72009-11-06 17:20:17 +00001829 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001830 char *zTable = azArg[2]; /* Insert data into this table */
1831 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001832 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001833 int nCol; /* Number of columns in the table */
1834 int nByte; /* Number of bytes in an SQL string */
1835 int i, j; /* Loop counters */
1836 int nSep; /* Number of bytes in p->separator[] */
1837 char *zSql; /* An SQL statement */
1838 char *zLine; /* A single line of input from the file */
1839 char **azCol; /* zLine[] broken up into columns */
1840 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001841 FILE *in; /* The input file */
1842 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001843
drha543c822006-06-08 16:10:14 +00001844 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001845 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001846 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001847 fprintf(stderr, "Error: non-null separator required for import\n");
1848 return 1;
drhfeac5f82004-08-01 00:10:45 +00001849 }
drh7b075e32011-09-28 01:10:00 +00001850 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00001851 if( zSql==0 ){
1852 fprintf(stderr, "Error: out of memory\n");
1853 return 1;
1854 }
drh4f21c4a2008-12-10 22:15:00 +00001855 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001856 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001857 sqlite3_free(zSql);
1858 if( rc ){
shane916f9612009-10-23 00:37:15 +00001859 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001860 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001861 return 1;
drhfeac5f82004-08-01 00:10:45 +00001862 }
shane916f9612009-10-23 00:37:15 +00001863 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001864 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001865 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001866 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001867 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001868 if( zSql==0 ){
1869 fprintf(stderr, "Error: out of memory\n");
1870 return 1;
1871 }
drh7b075e32011-09-28 01:10:00 +00001872 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001873 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001874 for(i=1; i<nCol; i++){
1875 zSql[j++] = ',';
1876 zSql[j++] = '?';
1877 }
1878 zSql[j++] = ')';
1879 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001880 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001881 free(zSql);
1882 if( rc ){
1883 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001884 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001885 return 1;
drhfeac5f82004-08-01 00:10:45 +00001886 }
1887 in = fopen(zFile, "rb");
1888 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001889 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001890 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001891 return 1;
drhfeac5f82004-08-01 00:10:45 +00001892 }
1893 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001894 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001895 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001896 fclose(in);
shane916f9612009-10-23 00:37:15 +00001897 sqlite3_finalize(pStmt);
1898 return 1;
drh43617e92006-03-06 20:55:46 +00001899 }
drhfeac5f82004-08-01 00:10:45 +00001900 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1901 zCommit = "COMMIT";
drh18f52e02012-01-16 16:56:31 +00001902 while( (zLine = local_getline(0, in, 1))!=0 ){
1903 char *z, c;
1904 int inQuote = 0;
drhb860bc92004-08-04 15:16:55 +00001905 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001906 azCol[0] = zLine;
drh18f52e02012-01-16 16:56:31 +00001907 for(i=0, z=zLine; (c = *z)!=0; z++){
1908 if( c=='"' ) inQuote = !inQuote;
1909 if( c=='\n' ) lineno++;
1910 if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001911 *z = 0;
1912 i++;
drhb860bc92004-08-04 15:16:55 +00001913 if( i<nCol ){
1914 azCol[i] = &z[nSep];
1915 z += nSep-1;
1916 }
drhfeac5f82004-08-01 00:10:45 +00001917 }
shane916f9612009-10-23 00:37:15 +00001918 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001919 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001920 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001921 fprintf(stderr,
1922 "Error: %s line %d: expected %d columns of data but found %d\n",
1923 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001924 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001925 free(zLine);
shane916f9612009-10-23 00:37:15 +00001926 rc = 1;
1927 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001928 }
drhfeac5f82004-08-01 00:10:45 +00001929 for(i=0; i<nCol; i++){
drh18f52e02012-01-16 16:56:31 +00001930 if( azCol[i][0]=='"' ){
1931 int k;
1932 for(z=azCol[i], j=1, k=0; z[j]; j++){
1933 if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1934 z[k++] = z[j];
1935 }
1936 z[k] = 0;
1937 }
drhfeac5f82004-08-01 00:10:45 +00001938 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1939 }
1940 sqlite3_step(pStmt);
1941 rc = sqlite3_reset(pStmt);
1942 free(zLine);
1943 if( rc!=SQLITE_OK ){
1944 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1945 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001946 rc = 1;
shane916f9612009-10-23 00:37:15 +00001947 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001948 }
shane916f9612009-10-23 00:37:15 +00001949 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001950 free(azCol);
1951 fclose(in);
1952 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001953 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001954 }else
1955
shanehe2aa9d72009-11-06 17:20:17 +00001956 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001957 struct callback_data data;
1958 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001959 open_db(p);
drh75897232000-05-29 14:26:00 +00001960 memcpy(&data, p, sizeof(data));
1961 data.showHeader = 0;
1962 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001963 if( nArg==1 ){
1964 rc = sqlite3_exec(p->db,
1965 "SELECT name FROM sqlite_master "
1966 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1967 "UNION ALL "
1968 "SELECT name FROM sqlite_temp_master "
1969 "WHERE type='index' "
1970 "ORDER BY 1",
1971 callback, &data, &zErrMsg
1972 );
1973 }else{
1974 zShellStatic = azArg[1];
1975 rc = sqlite3_exec(p->db,
1976 "SELECT name FROM sqlite_master "
1977 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1978 "UNION ALL "
1979 "SELECT name FROM sqlite_temp_master "
1980 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1981 "ORDER BY 1",
1982 callback, &data, &zErrMsg
1983 );
1984 zShellStatic = 0;
1985 }
drh75897232000-05-29 14:26:00 +00001986 if( zErrMsg ){
1987 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001988 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001989 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001990 }else if( rc != SQLITE_OK ){
1991 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1992 rc = 1;
drh75897232000-05-29 14:26:00 +00001993 }
1994 }else
1995
drhae5e4452007-05-03 17:18:36 +00001996#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001997 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001998 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001999 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2000 iotrace = 0;
2001 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002002 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002003 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002004 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002005 iotrace = stdout;
2006 }else{
2007 iotrace = fopen(azArg[1], "w");
2008 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002009 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002010 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002011 rc = 1;
drhb0603412007-02-28 04:47:26 +00002012 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002013 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002014 }
2015 }
2016 }else
drhae5e4452007-05-03 17:18:36 +00002017#endif
drhb0603412007-02-28 04:47:26 +00002018
drh70df4fe2006-06-13 15:12:21 +00002019#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002020 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2021 const char *zFile, *zProc;
2022 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00002023 zFile = azArg[1];
2024 zProc = nArg>=3 ? azArg[2] : 0;
2025 open_db(p);
2026 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2027 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002028 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002029 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002030 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002031 }
2032 }else
drh70df4fe2006-06-13 15:12:21 +00002033#endif
drh1e397f82006-06-08 15:28:43 +00002034
drhc8ba2122011-03-23 11:16:22 +00002035 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00002036 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00002037 output_file_close(p->pLog);
2038 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00002039 }else
2040
shanehe2aa9d72009-11-06 17:20:17 +00002041 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00002042 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002043 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002044 ||
shanehe2aa9d72009-11-06 17:20:17 +00002045 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002046 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002047 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002048 ||
shanehe2aa9d72009-11-06 17:20:17 +00002049 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002050 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002051 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002052 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002053 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002054 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002055 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002056 p->mode = MODE_Tcl;
mistachkin585dcb22012-12-04 00:23:43 +00002057 sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
shanehe2aa9d72009-11-06 17:20:17 +00002058 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002059 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002060 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002061 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002062 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002063 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002064 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002065 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002066 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002067 }else {
shane9bd1b442009-10-23 01:27:39 +00002068 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002069 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002070 rc = 1;
drh75897232000-05-29 14:26:00 +00002071 }
2072 }else
2073
shanehe2aa9d72009-11-06 17:20:17 +00002074 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2075 int n2 = strlen30(azArg[1]);
2076 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2077 p->mode = MODE_Insert;
2078 set_table_name(p, azArg[2]);
2079 }else {
2080 fprintf(stderr, "Error: invalid arguments: "
2081 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2082 rc = 1;
2083 }
2084 }else
2085
persicom7e2dfdd2002-04-18 02:46:52 +00002086 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002087 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2088 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002089 }else
2090
drh75897232000-05-29 14:26:00 +00002091 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002092 if( p->outfile[0]=='|' ){
2093 pclose(p->out);
2094 }else{
2095 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002096 }
drh42f64e52012-04-04 16:56:23 +00002097 p->outfile[0] = 0;
2098 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002099 p->out = popen(&azArg[1][1], "w");
2100 if( p->out==0 ){
2101 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2102 p->out = stdout;
2103 rc = 1;
2104 }else{
2105 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2106 }
drh75897232000-05-29 14:26:00 +00002107 }else{
drh42f64e52012-04-04 16:56:23 +00002108 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002109 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002110 if( strcmp(azArg[1],"off")!=0 ){
2111 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2112 }
drh75897232000-05-29 14:26:00 +00002113 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002114 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002115 } else {
drh42f64e52012-04-04 16:56:23 +00002116 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002117 }
2118 }
2119 }else
2120
drh078b1fd2012-09-21 13:40:02 +00002121 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2122 int i;
2123 for(i=1; i<nArg; i++){
2124 if( i>1 ) fprintf(p->out, " ");
2125 fprintf(p->out, "%s", azArg[i]);
2126 }
2127 fprintf(p->out, "\n");
2128 }else
2129
drhdd45df82002-04-18 12:39:03 +00002130 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002131 if( nArg >= 2) {
2132 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2133 }
2134 if( nArg >= 3) {
2135 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2136 }
2137 }else
2138
shanehe2aa9d72009-11-06 17:20:17 +00002139 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002140 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002141 }else
2142
drh9ff849f2009-02-04 20:55:57 +00002143 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002144 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002145 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002146 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2147 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002148 }else{
shane9bd1b442009-10-23 01:27:39 +00002149 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002150 fclose(alt);
2151 }
2152 }else
2153
shanehe2aa9d72009-11-06 17:20:17 +00002154 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002155 const char *zSrcFile;
2156 const char *zDb;
2157 sqlite3 *pSrc;
2158 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002159 int nTimeout = 0;
2160
drh9ff849f2009-02-04 20:55:57 +00002161 if( nArg==2 ){
2162 zSrcFile = azArg[1];
2163 zDb = "main";
2164 }else{
2165 zSrcFile = azArg[2];
2166 zDb = azArg[1];
2167 }
2168 rc = sqlite3_open(zSrcFile, &pSrc);
2169 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002170 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002171 sqlite3_close(pSrc);
2172 return 1;
2173 }
drhdc2c4912009-02-04 22:46:47 +00002174 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002175 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2176 if( pBackup==0 ){
2177 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2178 sqlite3_close(pSrc);
2179 return 1;
2180 }
drhdc2c4912009-02-04 22:46:47 +00002181 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2182 || rc==SQLITE_BUSY ){
2183 if( rc==SQLITE_BUSY ){
2184 if( nTimeout++ >= 3 ) break;
2185 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002186 }
2187 }
2188 sqlite3_backup_finish(pBackup);
2189 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002190 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002191 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002192 fprintf(stderr, "Error: source database is busy\n");
2193 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002194 }else{
2195 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002196 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002197 }
2198 sqlite3_close(pSrc);
2199 }else
2200
shanehe2aa9d72009-11-06 17:20:17 +00002201 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002202 struct callback_data data;
2203 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002204 open_db(p);
drh75897232000-05-29 14:26:00 +00002205 memcpy(&data, p, sizeof(data));
2206 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002207 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002208 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002209 int i;
drhf0693c82011-10-11 20:41:54 +00002210 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002211 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002212 char *new_argv[2], *new_colv[2];
2213 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2214 " type text,\n"
2215 " name text,\n"
2216 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002217 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002218 " sql text\n"
2219 ")";
2220 new_argv[1] = 0;
2221 new_colv[0] = "sql";
2222 new_colv[1] = 0;
2223 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002224 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002225 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002226 char *new_argv[2], *new_colv[2];
2227 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2228 " type text,\n"
2229 " name text,\n"
2230 " tbl_name text,\n"
2231 " rootpage integer,\n"
2232 " sql text\n"
2233 ")";
2234 new_argv[1] = 0;
2235 new_colv[0] = "sql";
2236 new_colv[1] = 0;
2237 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002238 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002239 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002240 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002241 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002242 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002243 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002244 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002245 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002246 "WHERE lower(tbl_name) LIKE shellstatic()"
2247 " AND type!='meta' AND sql NOTNULL "
drhac43e982012-05-21 03:15:06 +00002248 "ORDER BY substr(type,2,1), "
2249 " CASE type WHEN 'view' THEN rowid ELSE name END",
danielk1977bc6ada42004-06-30 08:20:16 +00002250 callback, &data, &zErrMsg);
2251 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002252 }
drh75897232000-05-29 14:26:00 +00002253 }else{
shane9bd1b442009-10-23 01:27:39 +00002254 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002255 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002256 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002257 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002258 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002259 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhac43e982012-05-21 03:15:06 +00002260 "ORDER BY substr(type,2,1),"
2261 " CASE type WHEN 'view' THEN rowid ELSE name END",
drha18c5682000-10-08 22:20:57 +00002262 callback, &data, &zErrMsg
2263 );
drh75897232000-05-29 14:26:00 +00002264 }
drh75897232000-05-29 14:26:00 +00002265 if( zErrMsg ){
2266 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002267 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002268 rc = 1;
2269 }else if( rc != SQLITE_OK ){
2270 fprintf(stderr,"Error: querying schema information\n");
2271 rc = 1;
2272 }else{
2273 rc = 0;
drh75897232000-05-29 14:26:00 +00002274 }
2275 }else
2276
2277 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002278 sqlite3_snprintf(sizeof(p->separator), p->separator,
2279 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002280 }else
2281
shanehe2aa9d72009-11-06 17:20:17 +00002282 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002283 int i;
2284 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002285 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002286 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002287 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002288 fprintf(p->out,"%9.9s: ", "nullvalue");
2289 output_c_string(p->out, p->nullvalue);
2290 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002291 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002292 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002293 fprintf(p->out,"%9.9s: ", "separator");
2294 output_c_string(p->out, p->separator);
2295 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002296 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002297 fprintf(p->out,"%9.9s: ","width");
2298 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002299 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002300 }
drhfeac5f82004-08-01 00:10:45 +00002301 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002302 }else
2303
shaneh642d8b82010-07-28 16:05:34 +00002304 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2305 p->statsOn = booleanValue(azArg[1]);
2306 }else
2307
shanehe2aa9d72009-11-06 17:20:17 +00002308 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002309 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002310 char **azResult;
drh98781232012-04-23 12:38:05 +00002311 int nRow, nAlloc;
2312 char *zSql = 0;
2313 int ii;
drh44c2eb12003-04-30 11:38:26 +00002314 open_db(p);
drh98781232012-04-23 12:38:05 +00002315 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2316 if( rc ) return rc;
2317 zSql = sqlite3_mprintf(
2318 "SELECT name FROM sqlite_master"
2319 " WHERE type IN ('table','view')"
2320 " AND name NOT LIKE 'sqlite_%%'"
2321 " AND name LIKE ?1");
2322 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2323 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2324 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2325 if( strcmp(zDbName,"temp")==0 ){
2326 zSql = sqlite3_mprintf(
2327 "%z UNION ALL "
2328 "SELECT 'temp.' || name FROM sqlite_temp_master"
2329 " WHERE type IN ('table','view')"
2330 " AND name NOT LIKE 'sqlite_%%'"
2331 " AND name LIKE ?1", zSql);
2332 }else{
2333 zSql = sqlite3_mprintf(
2334 "%z UNION ALL "
2335 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2336 " WHERE type IN ('table','view')"
2337 " AND name NOT LIKE 'sqlite_%%'"
2338 " AND name LIKE ?1", zSql, zDbName, zDbName);
2339 }
drha50da102000-08-08 20:19:09 +00002340 }
drh98781232012-04-23 12:38:05 +00002341 sqlite3_finalize(pStmt);
2342 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2343 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2344 sqlite3_free(zSql);
2345 if( rc ) return rc;
2346 nRow = nAlloc = 0;
2347 azResult = 0;
2348 if( nArg>1 ){
2349 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002350 }else{
drh98781232012-04-23 12:38:05 +00002351 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2352 }
2353 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2354 if( nRow>=nAlloc ){
2355 char **azNew;
2356 int n = nAlloc*2 + 10;
2357 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2358 if( azNew==0 ){
2359 fprintf(stderr, "Error: out of memory\n");
2360 break;
2361 }
2362 nAlloc = n;
2363 azResult = azNew;
2364 }
2365 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2366 if( azResult[nRow] ) nRow++;
2367 }
2368 sqlite3_finalize(pStmt);
2369 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002370 int len, maxlen = 0;
2371 int i, j;
2372 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002373 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002374 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002375 if( len>maxlen ) maxlen = len;
2376 }
2377 nPrintCol = 80/(maxlen+2);
2378 if( nPrintCol<1 ) nPrintCol = 1;
2379 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2380 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002381 for(j=i; j<nRow; j+=nPrintRow){
2382 char *zSp = j<nPrintRow ? "" : " ";
drhe3710332000-09-29 13:30:53 +00002383 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2384 }
2385 printf("\n");
2386 }
2387 }
drh98781232012-04-23 12:38:05 +00002388 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2389 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002390 }else
2391
shaneh96887e12011-02-10 21:08:58 +00002392 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002393 static const struct {
2394 const char *zCtrlName; /* Name of a test-control option */
2395 int ctrlCode; /* Integer code for that option */
2396 } aCtrl[] = {
2397 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2398 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2399 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2400 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2401 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2402 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2403 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2404 { "assert", SQLITE_TESTCTRL_ASSERT },
2405 { "always", SQLITE_TESTCTRL_ALWAYS },
2406 { "reserve", SQLITE_TESTCTRL_RESERVE },
2407 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2408 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002409 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2410 };
shaneh96887e12011-02-10 21:08:58 +00002411 int testctrl = -1;
2412 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002413 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002414 open_db(p);
2415
drhd416fe72011-03-17 16:45:50 +00002416 /* convert testctrl text option to value. allow any unique prefix
2417 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002418 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002419 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002420 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2421 if( testctrl<0 ){
2422 testctrl = aCtrl[i].ctrlCode;
2423 }else{
drhb07028f2011-10-14 21:49:18 +00002424 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002425 testctrl = -1;
2426 break;
2427 }
2428 }
2429 }
2430 if( testctrl<0 ) testctrl = atoi(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002431 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2432 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2433 }else{
2434 switch(testctrl){
2435
2436 /* sqlite3_test_control(int, db, int) */
2437 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2438 case SQLITE_TESTCTRL_RESERVE:
2439 if( nArg==3 ){
2440 int opt = (int)strtol(azArg[2], 0, 0);
2441 rc = sqlite3_test_control(testctrl, p->db, opt);
2442 printf("%d (0x%08x)\n", rc, rc);
2443 } else {
drhd416fe72011-03-17 16:45:50 +00002444 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2445 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002446 }
2447 break;
2448
2449 /* sqlite3_test_control(int) */
2450 case SQLITE_TESTCTRL_PRNG_SAVE:
2451 case SQLITE_TESTCTRL_PRNG_RESTORE:
2452 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002453 if( nArg==2 ){
2454 rc = sqlite3_test_control(testctrl);
2455 printf("%d (0x%08x)\n", rc, rc);
2456 } else {
2457 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2458 }
2459 break;
2460
2461 /* sqlite3_test_control(int, uint) */
2462 case SQLITE_TESTCTRL_PENDING_BYTE:
2463 if( nArg==3 ){
2464 unsigned int opt = (unsigned int)atoi(azArg[2]);
2465 rc = sqlite3_test_control(testctrl, opt);
2466 printf("%d (0x%08x)\n", rc, rc);
2467 } else {
drhd416fe72011-03-17 16:45:50 +00002468 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2469 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002470 }
2471 break;
2472
2473 /* sqlite3_test_control(int, int) */
2474 case SQLITE_TESTCTRL_ASSERT:
2475 case SQLITE_TESTCTRL_ALWAYS:
2476 if( nArg==3 ){
2477 int opt = atoi(azArg[2]);
2478 rc = sqlite3_test_control(testctrl, opt);
2479 printf("%d (0x%08x)\n", rc, rc);
2480 } else {
drhd416fe72011-03-17 16:45:50 +00002481 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2482 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002483 }
2484 break;
2485
2486 /* sqlite3_test_control(int, char *) */
2487#ifdef SQLITE_N_KEYWORD
2488 case SQLITE_TESTCTRL_ISKEYWORD:
2489 if( nArg==3 ){
2490 const char *opt = azArg[2];
2491 rc = sqlite3_test_control(testctrl, opt);
2492 printf("%d (0x%08x)\n", rc, rc);
2493 } else {
drhd416fe72011-03-17 16:45:50 +00002494 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2495 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002496 }
2497 break;
2498#endif
2499
2500 case SQLITE_TESTCTRL_BITVEC_TEST:
2501 case SQLITE_TESTCTRL_FAULT_INSTALL:
2502 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2503 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2504 default:
drhd416fe72011-03-17 16:45:50 +00002505 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2506 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002507 break;
2508 }
2509 }
2510 }else
2511
shanehe2aa9d72009-11-06 17:20:17 +00002512 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002513 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002514 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002515 }else
2516
drhd416fe72011-03-17 16:45:50 +00002517 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2518 && nArg==2
2519 ){
drh3b1a9882007-11-02 12:53:03 +00002520 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002521 }else
2522
drh42f64e52012-04-04 16:56:23 +00002523 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh98781232012-04-23 12:38:05 +00002524 open_db(p);
drh42f64e52012-04-04 16:56:23 +00002525 output_file_close(p->traceOut);
2526 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00002527#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002528 if( p->traceOut==0 ){
2529 sqlite3_trace(p->db, 0, 0);
2530 }else{
2531 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2532 }
2533#endif
2534 }else
2535
drh9fd301b2011-06-03 13:28:22 +00002536 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh743e0032011-12-12 16:51:50 +00002537 printf("SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002538 sqlite3_libversion(), sqlite3_sourceid());
2539 }else
2540
drhde60fc22011-12-14 17:53:36 +00002541 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2542 const char *zDbName = nArg==2 ? azArg[1] : "main";
2543 char *zVfsName = 0;
2544 if( p->db ){
2545 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2546 if( zVfsName ){
2547 printf("%s\n", zVfsName);
2548 sqlite3_free(zVfsName);
2549 }
2550 }
2551 }else
2552
drhcef4fc82012-09-21 22:50:45 +00002553#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2554 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
2555 extern int sqlite3WhereTrace;
2556 sqlite3WhereTrace = atoi(azArg[1]);
2557 }else
2558#endif
2559
shanehe2aa9d72009-11-06 17:20:17 +00002560 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002561 int j;
drh43617e92006-03-06 20:55:46 +00002562 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002563 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2564 p->colWidth[j-1] = atoi(azArg[j]);
2565 }
2566 }else
2567
2568 {
shane9bd1b442009-10-23 01:27:39 +00002569 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002570 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002571 rc = 1;
drh75897232000-05-29 14:26:00 +00002572 }
drh67505e72002-04-19 12:34:06 +00002573
2574 return rc;
drh75897232000-05-29 14:26:00 +00002575}
2576
drh67505e72002-04-19 12:34:06 +00002577/*
drh91a66392007-09-07 01:12:32 +00002578** Return TRUE if a semicolon occurs anywhere in the first N characters
2579** of string z[].
drh324ccef2003-02-05 14:06:20 +00002580*/
drh91a66392007-09-07 01:12:32 +00002581static int _contains_semicolon(const char *z, int N){
2582 int i;
2583 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2584 return 0;
drh324ccef2003-02-05 14:06:20 +00002585}
2586
2587/*
drh70c7a4b2003-04-26 03:03:06 +00002588** Test to see if a line consists entirely of whitespace.
2589*/
2590static int _all_whitespace(const char *z){
2591 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002592 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002593 if( *z=='/' && z[1]=='*' ){
2594 z += 2;
2595 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2596 if( *z==0 ) return 0;
2597 z++;
2598 continue;
2599 }
2600 if( *z=='-' && z[1]=='-' ){
2601 z += 2;
2602 while( *z && *z!='\n' ){ z++; }
2603 if( *z==0 ) return 1;
2604 continue;
2605 }
2606 return 0;
2607 }
2608 return 1;
2609}
2610
2611/*
drha9b17162003-04-29 18:01:28 +00002612** Return TRUE if the line typed in is an SQL command terminator other
2613** than a semi-colon. The SQL Server style "go" command is understood
2614** as is the Oracle "/".
2615*/
2616static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002617 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002618 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2619 return 1; /* Oracle */
2620 }
drhf0693c82011-10-11 20:41:54 +00002621 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002622 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002623 return 1; /* SQL Server */
2624 }
2625 return 0;
2626}
2627
2628/*
drh233a5312008-12-18 22:25:13 +00002629** Return true if zSql is a complete SQL statement. Return false if it
2630** ends in the middle of a string literal or C-style comment.
2631*/
2632static int _is_complete(char *zSql, int nSql){
2633 int rc;
2634 if( zSql==0 ) return 1;
2635 zSql[nSql] = ';';
2636 zSql[nSql+1] = 0;
2637 rc = sqlite3_complete(zSql);
2638 zSql[nSql] = 0;
2639 return rc;
2640}
2641
2642/*
drh67505e72002-04-19 12:34:06 +00002643** Read input from *in and process it. If *in==0 then input
2644** is interactive - the user is typing it it. Otherwise, input
2645** is coming from a file or device. A prompt is issued and history
2646** is saved only if input is interactive. An interrupt signal will
2647** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002648**
2649** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002650*/
drhc28490c2006-10-26 14:25:58 +00002651static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002652 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002653 char *zSql = 0;
2654 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002655 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002656 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002657 int rc;
2658 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002659 int lineno = 0;
2660 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002661
2662 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2663 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002664 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002665 zLine = one_input_line(zSql, in);
2666 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002667 /* End of input */
2668 if( stdin_is_interactive ) printf("\n");
2669 break;
drhc49f44e2006-10-26 18:15:42 +00002670 }
drh67505e72002-04-19 12:34:06 +00002671 if( seenInterrupt ){
2672 if( in!=0 ) break;
2673 seenInterrupt = 0;
2674 }
drhc28490c2006-10-26 14:25:58 +00002675 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002676 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002677 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002678 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002679 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002680 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002681 break;
2682 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002683 errCnt++;
2684 }
drhdaffd0e2001-04-11 14:28:42 +00002685 continue;
2686 }
drh233a5312008-12-18 22:25:13 +00002687 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002688 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002689 }
drh91a66392007-09-07 01:12:32 +00002690 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002691 if( zSql==0 ){
2692 int i;
drhf0693c82011-10-11 20:41:54 +00002693 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002694 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002695 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002696 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002697 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002698 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002699 exit(1);
2700 }
drh5bb3eb92007-05-04 13:15:55 +00002701 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002702 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002703 }
2704 }else{
drh4f21c4a2008-12-10 22:15:00 +00002705 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002706 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002707 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002708 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002709 exit(1);
2710 }
drh5bb3eb92007-05-04 13:15:55 +00002711 zSql[nSql++] = '\n';
2712 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002713 nSql += len;
2714 }
drh91a66392007-09-07 01:12:32 +00002715 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2716 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002717 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002718 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002719 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002720 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002721 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002722 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002723 char zPrefix[100];
2724 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002725 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002726 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002727 }else{
shane9bd1b442009-10-23 01:27:39 +00002728 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002729 }
drh7f953e22002-07-13 17:33:45 +00002730 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002731 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002732 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002733 zErrMsg = 0;
2734 }else{
shaned2bed1c2009-10-21 03:56:54 +00002735 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002736 }
drhc49f44e2006-10-26 18:15:42 +00002737 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002738 }
2739 free(zSql);
2740 zSql = 0;
2741 nSql = 0;
2742 }
2743 }
2744 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002745 if( !_all_whitespace(zSql) ){
2746 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2747 }
drhdaffd0e2001-04-11 14:28:42 +00002748 free(zSql);
2749 }
danielk19772ac27622007-07-03 05:31:16 +00002750 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00002751 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00002752}
2753
drh67505e72002-04-19 12:34:06 +00002754/*
2755** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002756** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002757*/
2758static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002759 static char *home_dir = NULL;
2760 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002761
drh83905c92012-06-21 13:00:37 +00002762#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00002763 {
2764 struct passwd *pwent;
2765 uid_t uid = getuid();
2766 if( (pwent=getpwuid(uid)) != NULL) {
2767 home_dir = pwent->pw_dir;
2768 }
drh67505e72002-04-19 12:34:06 +00002769 }
2770#endif
2771
chw65d3c132007-11-12 21:09:10 +00002772#if defined(_WIN32_WCE)
2773 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2774 */
drh85e72432012-04-11 11:38:53 +00002775 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00002776#else
2777
drh83905c92012-06-21 13:00:37 +00002778#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00002779 if (!home_dir) {
2780 home_dir = getenv("USERPROFILE");
2781 }
2782#endif
2783
drh67505e72002-04-19 12:34:06 +00002784 if (!home_dir) {
2785 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002786 }
2787
drh83905c92012-06-21 13:00:37 +00002788#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00002789 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002790 char *zDrive, *zPath;
2791 int n;
2792 zDrive = getenv("HOMEDRIVE");
2793 zPath = getenv("HOMEPATH");
2794 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002795 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002796 home_dir = malloc( n );
2797 if( home_dir==0 ) return 0;
2798 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2799 return home_dir;
2800 }
2801 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002802 }
2803#endif
2804
chw65d3c132007-11-12 21:09:10 +00002805#endif /* !_WIN32_WCE */
2806
drh67505e72002-04-19 12:34:06 +00002807 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002808 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002809 char *z = malloc( n );
2810 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002811 home_dir = z;
2812 }
drhe98d4fa2002-04-21 19:06:22 +00002813
drh67505e72002-04-19 12:34:06 +00002814 return home_dir;
2815}
2816
2817/*
2818** Read input from the file given by sqliterc_override. Or if that
2819** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002820**
2821** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002822*/
shane9bd1b442009-10-23 01:27:39 +00002823static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002824 struct callback_data *p, /* Configuration data */
2825 const char *sqliterc_override /* Name of config file. NULL to use default */
2826){
persicom7e2dfdd2002-04-18 02:46:52 +00002827 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002828 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002829 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002830 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00002831 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002832
2833 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002834 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002835 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002836#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002837 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002838#endif
shane9bd1b442009-10-23 01:27:39 +00002839 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002840 }
drh2f3de322012-06-27 16:41:31 +00002841 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00002842 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
2843 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002844 }
drha1f9b5e2004-02-14 16:31:02 +00002845 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002846 if( in ){
drhc28490c2006-10-26 14:25:58 +00002847 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002848 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002849 }
shane9bd1b442009-10-23 01:27:39 +00002850 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002851 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002852 }
drh85e72432012-04-11 11:38:53 +00002853 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002854 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002855}
2856
drh67505e72002-04-19 12:34:06 +00002857/*
drhe1e38c42003-05-04 18:30:59 +00002858** Show available command line options
2859*/
2860static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00002861 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00002862 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002863 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00002864 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00002865 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00002866 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00002867 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00002868 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00002869#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2870 " -heap SIZE Size of heap for memsys3 or memsys5\n"
2871#endif
drhcc3b4f82012-02-07 14:13:50 +00002872 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002873 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00002874 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002875 " -line set output mode to 'line'\n"
2876 " -list set output mode to 'list'\n"
drhcc3b4f82012-02-07 14:13:50 +00002877#ifdef SQLITE_ENABLE_MULTIPLEX
2878 " -multiplex enable the multiplexor VFS\n"
2879#endif
drh98d312f2012-10-25 15:23:14 +00002880 " -nullvalue TEXT set text string for NULL values. Default ''\n"
2881 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00002882 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002883 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002884 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00002885#ifdef SQLITE_ENABLE_VFSTRACE
2886 " -vfstrace enable tracing of all VFS calls\n"
2887#endif
drhe1e38c42003-05-04 18:30:59 +00002888;
2889static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002890 fprintf(stderr,
2891 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2892 "FILENAME is the name of an SQLite database. A new database is created\n"
2893 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002894 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002895 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002896 }else{
2897 fprintf(stderr, "Use the -help option for additional information\n");
2898 }
2899 exit(1);
2900}
2901
2902/*
drh67505e72002-04-19 12:34:06 +00002903** Initialize the state information in data
2904*/
drh0850b532006-01-31 19:31:43 +00002905static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002906 memset(data, 0, sizeof(*data));
2907 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002908 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002909 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00002910 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00002911 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002912 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2913 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002914 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002915}
2916
drh98d312f2012-10-25 15:23:14 +00002917/*
2918** Get the argument to an --option. Throw an error and die if no argument
2919** is available.
2920*/
2921static char *cmdline_option_value(int argc, char **argv, int i){
2922 if( i==argc ){
2923 fprintf(stderr, "%s: Error: missing argument to %s\n",
2924 argv[0], argv[argc-1]);
2925 exit(1);
2926 }
2927 return argv[i];
2928}
2929
drh75897232000-05-29 14:26:00 +00002930int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002931 char *zErrMsg = 0;
2932 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002933 const char *zInitFile = 0;
2934 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002935 int i;
drhc28490c2006-10-26 14:25:58 +00002936 int rc = 0;
drh75897232000-05-29 14:26:00 +00002937
drh52784bd2011-05-18 17:15:06 +00002938 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
2939 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
2940 sqlite3_sourceid(), SQLITE_SOURCE_ID);
2941 exit(1);
2942 }
drhdaffd0e2001-04-11 14:28:42 +00002943 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002944 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002945 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002946
drh44c2eb12003-04-30 11:38:26 +00002947 /* Make sure we have a valid signal handler early, before anything
2948 ** else is done.
2949 */
drh4c504392000-10-16 22:06:40 +00002950#ifdef SIGINT
2951 signal(SIGINT, interrupt_handler);
2952#endif
drh44c2eb12003-04-30 11:38:26 +00002953
drh22fbcb82004-02-01 01:22:50 +00002954 /* Do an initial pass through the command-line argument to locate
2955 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002956 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002957 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002958 */
drh98d312f2012-10-25 15:23:14 +00002959 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00002960 char *z;
drhc28490c2006-10-26 14:25:58 +00002961 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00002962 if( z[0]!='-' ){
2963 if( data.zDbFilename==0 ){
2964 data.zDbFilename = z;
2965 continue;
2966 }
2967 if( zFirstCmd==0 ){
2968 zFirstCmd = z;
2969 continue;
2970 }
2971 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2972 fprintf(stderr,"Use -help for a list of options.\n");
2973 return 1;
2974 }
drhcc3b4f82012-02-07 14:13:50 +00002975 if( z[1]=='-' ) z++;
2976 if( strcmp(z,"-separator")==0
2977 || strcmp(z,"-nullvalue")==0
2978 || strcmp(z,"-cmd")==0
2979 ){
drh98d312f2012-10-25 15:23:14 +00002980 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00002981 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00002982 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00002983 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00002984 /* Need to check for batch mode here to so we can avoid printing
2985 ** informational messages (like from process_sqliterc) before
2986 ** we do the actual processing of arguments later in a second pass.
2987 */
shanef69573d2009-10-24 02:06:14 +00002988 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00002989 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00002990#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00002991 int j, c;
2992 const char *zSize;
2993 sqlite3_int64 szHeap;
2994
drh98d312f2012-10-25 15:23:14 +00002995 zSize = cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00002996 szHeap = atoi(zSize);
2997 for(j=0; (c = zSize[j])!=0; j++){
2998 if( c=='M' ){ szHeap *= 1000000; break; }
2999 if( c=='K' ){ szHeap *= 1000; break; }
3000 if( c=='G' ){ szHeap *= 1000000000; break; }
3001 }
3002 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00003003 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3004#endif
drh97ae8ff2011-03-16 16:56:29 +00003005#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00003006 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00003007 extern int vfstrace_register(
3008 const char *zTraceName,
3009 const char *zOldVfsName,
3010 int (*xOut)(const char*,void*),
3011 void *pOutArg,
3012 int makeDefault
3013 );
drh2b625e22011-03-16 17:05:28 +00003014 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00003015#endif
drh6f25e892011-07-08 17:02:57 +00003016#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00003017 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00003018 extern int sqlite3_multiple_initialize(const char*,int);
3019 sqlite3_multiplex_initialize(0, 1);
3020#endif
drhcc3b4f82012-02-07 14:13:50 +00003021 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00003022 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00003023 if( pVfs ){
3024 sqlite3_vfs_register(pVfs, 1);
3025 }else{
3026 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3027 exit(1);
3028 }
drh44c2eb12003-04-30 11:38:26 +00003029 }
3030 }
drh98d312f2012-10-25 15:23:14 +00003031 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00003032#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003033 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003034#else
shane86f5bdb2009-10-24 02:00:07 +00003035 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3036 return 1;
drh01b41712005-08-29 23:06:23 +00003037#endif
drh98d312f2012-10-25 15:23:14 +00003038 }
3039 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00003040
drh44c2eb12003-04-30 11:38:26 +00003041 /* Go ahead and open the database file if it already exists. If the
3042 ** file does not exist, delay opening it. This prevents empty database
3043 ** files from being created if a user mistypes the database name argument
3044 ** to the sqlite command-line tool.
3045 */
drhc8d74412004-08-31 23:41:26 +00003046 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003047 open_db(&data);
3048 }
3049
drh22fbcb82004-02-01 01:22:50 +00003050 /* Process the initialization file if there is one. If no -init option
3051 ** is given on the command line, look for a file named ~/.sqliterc and
3052 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003053 */
shane86f5bdb2009-10-24 02:00:07 +00003054 rc = process_sqliterc(&data,zInitFile);
3055 if( rc>0 ){
3056 return rc;
3057 }
drh44c2eb12003-04-30 11:38:26 +00003058
drh22fbcb82004-02-01 01:22:50 +00003059 /* Make a second pass through the command-line argument and set
3060 ** options. This second pass is delayed until after the initialization
3061 ** file is processed so that the command-line arguments will override
3062 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003063 */
drh98d312f2012-10-25 15:23:14 +00003064 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00003065 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003066 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00003067 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003068 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003069 i++;
3070 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003071 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003072 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003073 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003074 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003075 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003076 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003077 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003078 }else if( strcmp(z,"-csv")==0 ){
3079 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003080 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003081 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003082 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00003083 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003084 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003085 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00003086 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003087 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003088 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003089 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003090 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003091 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003092 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003093 }else if( strcmp(z,"-stats")==0 ){
3094 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003095 }else if( strcmp(z,"-bail")==0 ){
3096 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003097 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003098 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003099 return 0;
drhc28490c2006-10-26 14:25:58 +00003100 }else if( strcmp(z,"-interactive")==0 ){
3101 stdin_is_interactive = 1;
3102 }else if( strcmp(z,"-batch")==0 ){
3103 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003104 }else if( strcmp(z,"-heap")==0 ){
3105 i++;
drha7e61d82011-03-12 17:02:57 +00003106 }else if( strcmp(z,"-vfs")==0 ){
3107 i++;
drh6f25e892011-07-08 17:02:57 +00003108#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003109 }else if( strcmp(z,"-vfstrace")==0 ){
3110 i++;
drh6f25e892011-07-08 17:02:57 +00003111#endif
3112#ifdef SQLITE_ENABLE_MULTIPLEX
3113 }else if( strcmp(z,"-multiplex")==0 ){
3114 i++;
3115#endif
drhcc3b4f82012-02-07 14:13:50 +00003116 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003117 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003118 }else if( strcmp(z,"-cmd")==0 ){
3119 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00003120 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00003121 if( z[0]=='.' ){
3122 rc = do_meta_command(z, &data);
3123 if( rc && bail_on_error ) return rc;
3124 }else{
3125 open_db(&data);
3126 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3127 if( zErrMsg!=0 ){
3128 fprintf(stderr,"Error: %s\n", zErrMsg);
3129 if( bail_on_error ) return rc!=0 ? rc : 1;
3130 }else if( rc!=0 ){
3131 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3132 if( bail_on_error ) return rc;
3133 }
3134 }
drh1e5d0e92000-05-31 23:33:17 +00003135 }else{
shane86f5bdb2009-10-24 02:00:07 +00003136 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003137 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003138 return 1;
3139 }
3140 }
drh44c2eb12003-04-30 11:38:26 +00003141
drh22fbcb82004-02-01 01:22:50 +00003142 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003143 /* Run just the command that follows the database name
3144 */
drh22fbcb82004-02-01 01:22:50 +00003145 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003146 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003147 }else{
drh44c2eb12003-04-30 11:38:26 +00003148 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003149 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003150 if( zErrMsg!=0 ){
3151 fprintf(stderr,"Error: %s\n", zErrMsg);
3152 return rc!=0 ? rc : 1;
3153 }else if( rc!=0 ){
3154 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3155 return rc;
drh6ff13852001-11-25 13:18:23 +00003156 }
drh75897232000-05-29 14:26:00 +00003157 }
3158 }else{
drh44c2eb12003-04-30 11:38:26 +00003159 /* Run commands received from standard input
3160 */
drhc28490c2006-10-26 14:25:58 +00003161 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003162 char *zHome;
3163 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003164 int nHistory;
drh75897232000-05-29 14:26:00 +00003165 printf(
drh743e0032011-12-12 16:51:50 +00003166 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003167 "Enter \".help\" for instructions\n"
3168 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003169 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003170 );
drh67505e72002-04-19 12:34:06 +00003171 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003172 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003173 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003174 if( (zHistory = malloc(nHistory))!=0 ){
3175 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3176 }
drh67505e72002-04-19 12:34:06 +00003177 }
danielk19774af00c62005-01-23 23:43:21 +00003178#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003179 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003180#endif
drhc28490c2006-10-26 14:25:58 +00003181 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003182 if( zHistory ){
3183 stifle_history(100);
3184 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003185 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003186 }
drhdaffd0e2001-04-11 14:28:42 +00003187 }else{
drhc28490c2006-10-26 14:25:58 +00003188 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003189 }
3190 }
drh33048c02001-10-01 14:29:22 +00003191 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003192 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003193 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003194 }
drhc28490c2006-10-26 14:25:58 +00003195 return rc;
drh75897232000-05-29 14:26:00 +00003196}