blob: adb816543459c6ba4b679cc110b9c648c8143107 [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);
544 }else if( c=='\t' ){
545 fputc('\\', out);
546 fputc('t', out);
547 }else if( c=='\n' ){
548 fputc('\\', out);
549 fputc('n', out);
550 }else if( c=='\r' ){
551 fputc('\\', out);
552 fputc('r', out);
553 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000554 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000555 }else{
556 fputc(c, out);
557 }
558 }
559 fputc('"', out);
560}
561
562/*
drhc08a4f12000-06-15 16:49:48 +0000563** Output the given string with characters that are special to
564** HTML escaped.
565*/
566static void output_html_string(FILE *out, const char *z){
567 int i;
568 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000569 for(i=0; z[i]
570 && z[i]!='<'
571 && z[i]!='&'
572 && z[i]!='>'
573 && z[i]!='\"'
574 && z[i]!='\'';
575 i++){}
drhc08a4f12000-06-15 16:49:48 +0000576 if( i>0 ){
577 fprintf(out,"%.*s",i,z);
578 }
579 if( z[i]=='<' ){
580 fprintf(out,"&lt;");
581 }else if( z[i]=='&' ){
582 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000583 }else if( z[i]=='>' ){
584 fprintf(out,"&gt;");
585 }else if( z[i]=='\"' ){
586 fprintf(out,"&quot;");
587 }else if( z[i]=='\'' ){
588 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000589 }else{
590 break;
591 }
592 z += i + 1;
593 }
594}
595
596/*
drhc49f44e2006-10-26 18:15:42 +0000597** If a field contains any character identified by a 1 in the following
598** array, then the string must be quoted for CSV.
599*/
600static const char needCsvQuote[] = {
601 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
602 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
603 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
604 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,
609 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
610 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
611 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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};
618
619/*
drh8e64d1c2004-10-07 00:32:39 +0000620** Output a single term of CSV. Actually, p->separator is used for
621** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000622** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000623*/
624static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000625 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000626 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000627 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000628 }else{
drhc49f44e2006-10-26 18:15:42 +0000629 int i;
drh4f21c4a2008-12-10 22:15:00 +0000630 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000631 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000632 if( needCsvQuote[((unsigned char*)z)[i]]
633 || (z[i]==p->separator[0] &&
634 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000635 i = 0;
636 break;
637 }
638 }
639 if( i==0 ){
640 putc('"', out);
641 for(i=0; z[i]; i++){
642 if( z[i]=='"' ) putc('"', out);
643 putc(z[i], out);
644 }
645 putc('"', out);
646 }else{
647 fprintf(out, "%s", z);
648 }
drh8e64d1c2004-10-07 00:32:39 +0000649 }
650 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000651 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000652 }
653}
654
danielk19774af00c62005-01-23 23:43:21 +0000655#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000656/*
drh4c504392000-10-16 22:06:40 +0000657** This routine runs when the user presses Ctrl-C
658*/
659static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000660 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000661 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000662 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000663}
danielk19774af00c62005-01-23 23:43:21 +0000664#endif
drh4c504392000-10-16 22:06:40 +0000665
666/*
shane626a6e42009-10-22 17:30:15 +0000667** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000668** invokes for each row of a query result.
669*/
shane626a6e42009-10-22 17:30:15 +0000670static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000671 int i;
672 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000673
drh75897232000-05-29 14:26:00 +0000674 switch( p->mode ){
675 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000676 int w = 5;
drh6a535342001-10-19 16:44:56 +0000677 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000678 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000679 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000680 if( len>w ) w = len;
681 }
drh75897232000-05-29 14:26:00 +0000682 if( p->cnt++>0 ) fprintf(p->out,"\n");
683 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000684 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000685 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000686 }
687 break;
688 }
danielk19770d78bae2008-01-03 07:09:48 +0000689 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000690 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000691 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000692 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000693 int w, n;
694 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000695 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000696 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000697 w = 0;
drh75897232000-05-29 14:26:00 +0000698 }
drh078b1fd2012-09-21 13:40:02 +0000699 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000700 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000701 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000702 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000703 if( w<n ) w = n;
704 }
705 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000706 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000707 }
708 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000709 if( w<0 ){
710 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
711 }else{
712 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
713 }
drha0c66f52000-07-29 13:20:21 +0000714 }
715 }
716 if( p->showHeader ){
717 for(i=0; i<nArg; i++){
718 int w;
719 if( i<ArraySize(p->actualWidth) ){
720 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000721 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000722 }else{
723 w = 10;
724 }
725 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
726 "----------------------------------------------------------",
727 i==nArg-1 ? "\n": " ");
728 }
drh75897232000-05-29 14:26:00 +0000729 }
730 }
drh6a535342001-10-19 16:44:56 +0000731 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000732 for(i=0; i<nArg; i++){
733 int w;
drha0c66f52000-07-29 13:20:21 +0000734 if( i<ArraySize(p->actualWidth) ){
735 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000736 }else{
737 w = 10;
738 }
drhea678832008-12-10 19:26:22 +0000739 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000740 strlen30(azArg[i])>w ){
741 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000742 }
drh078b1fd2012-09-21 13:40:02 +0000743 if( w<0 ){
744 fprintf(p->out,"%*.*s%s",-w,-w,
745 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
746 }else{
747 fprintf(p->out,"%-*.*s%s",w,w,
748 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
749 }
drh75897232000-05-29 14:26:00 +0000750 }
751 break;
752 }
drhe3710332000-09-29 13:30:53 +0000753 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000754 case MODE_List: {
755 if( p->cnt++==0 && p->showHeader ){
756 for(i=0; i<nArg; i++){
757 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
758 }
759 }
drh6a535342001-10-19 16:44:56 +0000760 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000761 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000762 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000763 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000764 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000765 if( i<nArg-1 ){
766 fprintf(p->out, "%s", p->separator);
767 }else if( p->mode==MODE_Semi ){
768 fprintf(p->out, ";\n");
769 }else{
770 fprintf(p->out, "\n");
771 }
drh75897232000-05-29 14:26:00 +0000772 }
773 break;
774 }
drh1e5d0e92000-05-31 23:33:17 +0000775 case MODE_Html: {
776 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000777 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000778 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000779 fprintf(p->out,"<TH>");
780 output_html_string(p->out, azCol[i]);
781 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000782 }
mihailim57c591a2008-06-23 21:26:05 +0000783 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000784 }
drh6a535342001-10-19 16:44:56 +0000785 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000786 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000787 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000788 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000789 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000790 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000791 }
mihailim57c591a2008-06-23 21:26:05 +0000792 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000793 break;
794 }
drhfeac5f82004-08-01 00:10:45 +0000795 case MODE_Tcl: {
796 if( p->cnt++==0 && p->showHeader ){
797 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000798 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000799 fprintf(p->out, "%s", p->separator);
800 }
801 fprintf(p->out,"\n");
802 }
803 if( azArg==0 ) break;
804 for(i=0; i<nArg; i++){
805 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
806 fprintf(p->out, "%s", p->separator);
807 }
808 fprintf(p->out,"\n");
809 break;
810 }
drh8e64d1c2004-10-07 00:32:39 +0000811 case MODE_Csv: {
812 if( p->cnt++==0 && p->showHeader ){
813 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000814 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000815 }
816 fprintf(p->out,"\n");
817 }
818 if( azArg==0 ) break;
819 for(i=0; i<nArg; i++){
820 output_csv(p, azArg[i], i<nArg-1);
821 }
822 fprintf(p->out,"\n");
823 break;
824 }
drh28bd4bc2000-06-15 15:57:22 +0000825 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000826 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000827 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000828 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000829 for(i=0; i<nArg; i++){
830 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000831 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000832 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000833 }else if( aiType && aiType[i]==SQLITE_TEXT ){
834 if( zSep[0] ) fprintf(p->out,"%s",zSep);
835 output_quoted_string(p->out, azArg[i]);
836 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
837 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000838 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
839 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
840 int nBlob = sqlite3_column_bytes(p->pStmt, i);
841 if( zSep[0] ) fprintf(p->out,"%s",zSep);
842 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000843 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000844 fprintf(p->out,"%s%s",zSep, azArg[i]);
845 }else{
846 if( zSep[0] ) fprintf(p->out,"%s",zSep);
847 output_quoted_string(p->out, azArg[i]);
848 }
849 }
850 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000851 break;
drh28bd4bc2000-06-15 15:57:22 +0000852 }
persicom1d0b8722002-04-18 02:53:04 +0000853 }
drh75897232000-05-29 14:26:00 +0000854 return 0;
855}
856
857/*
shane626a6e42009-10-22 17:30:15 +0000858** This is the callback routine that the SQLite library
859** invokes for each row of a query result.
860*/
861static int callback(void *pArg, int nArg, char **azArg, char **azCol){
862 /* since we don't have type info, call the shell_callback with a NULL value */
863 return shell_callback(pArg, nArg, azArg, azCol, NULL);
864}
865
866/*
drh33048c02001-10-01 14:29:22 +0000867** Set the destination table field of the callback_data structure to
868** the name of the table given. Escape any quote characters in the
869** table name.
870*/
871static void set_table_name(struct callback_data *p, const char *zName){
872 int i, n;
873 int needQuote;
874 char *z;
875
876 if( p->zDestTable ){
877 free(p->zDestTable);
878 p->zDestTable = 0;
879 }
880 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000881 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000882 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000883 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000884 needQuote = 1;
885 if( zName[i]=='\'' ) n++;
886 }
887 }
888 if( needQuote ) n += 2;
889 z = p->zDestTable = malloc( n+1 );
890 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000891 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000892 exit(1);
893 }
894 n = 0;
895 if( needQuote ) z[n++] = '\'';
896 for(i=0; zName[i]; i++){
897 z[n++] = zName[i];
898 if( zName[i]=='\'' ) z[n++] = '\'';
899 }
900 if( needQuote ) z[n++] = '\'';
901 z[n] = 0;
902}
903
danielk19772a02e332004-06-05 08:04:36 +0000904/* zIn is either a pointer to a NULL-terminated string in memory obtained
905** from malloc(), or a NULL pointer. The string pointed to by zAppend is
906** added to zIn, and the result returned in memory obtained from malloc().
907** zIn, if it was not NULL, is freed.
908**
909** If the third argument, quote, is not '\0', then it is used as a
910** quote character for zAppend.
911*/
drhc28490c2006-10-26 14:25:58 +0000912static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000913 int len;
914 int i;
drh4f21c4a2008-12-10 22:15:00 +0000915 int nAppend = strlen30(zAppend);
916 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000917
918 len = nAppend+nIn+1;
919 if( quote ){
920 len += 2;
921 for(i=0; i<nAppend; i++){
922 if( zAppend[i]==quote ) len++;
923 }
924 }
925
926 zIn = (char *)realloc(zIn, len);
927 if( !zIn ){
928 return 0;
929 }
930
931 if( quote ){
932 char *zCsr = &zIn[nIn];
933 *zCsr++ = quote;
934 for(i=0; i<nAppend; i++){
935 *zCsr++ = zAppend[i];
936 if( zAppend[i]==quote ) *zCsr++ = quote;
937 }
938 *zCsr++ = quote;
939 *zCsr++ = '\0';
940 assert( (zCsr-zIn)==len );
941 }else{
942 memcpy(&zIn[nIn], zAppend, nAppend);
943 zIn[len-1] = '\0';
944 }
945
946 return zIn;
947}
948
drhdd3d4592004-08-30 01:54:05 +0000949
950/*
drhb21a8e42012-01-28 21:08:51 +0000951** Execute a query statement that will generate SQL output. Print
952** the result columns, comma-separated, on a line and then add a
953** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000954**
drhb21a8e42012-01-28 21:08:51 +0000955** If the number of columns is 1 and that column contains text "--"
956** then write the semicolon on a separate line. That way, if a
957** "--" comment occurs at the end of the statement, the comment
958** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000959*/
drh157e29a2009-05-21 15:15:00 +0000960static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000961 struct callback_data *p, /* Query context */
962 const char *zSelect, /* SELECT statement to extract content */
963 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000964){
drhdd3d4592004-08-30 01:54:05 +0000965 sqlite3_stmt *pSelect;
966 int rc;
drhb21a8e42012-01-28 21:08:51 +0000967 int nResult;
968 int i;
969 const char *z;
drh2f464a02011-10-13 00:41:49 +0000970 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000971 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000972 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
973 p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000974 return rc;
975 }
976 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000977 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000978 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000979 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000980 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000981 zFirstRow = 0;
982 }
drhb21a8e42012-01-28 21:08:51 +0000983 z = (const char*)sqlite3_column_text(pSelect, 0);
984 fprintf(p->out, "%s", z);
985 for(i=1; i<nResult; i++){
986 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
987 }
988 if( z==0 ) z = "";
989 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
990 if( z[0] ){
991 fprintf(p->out, "\n;\n");
992 }else{
993 fprintf(p->out, ";\n");
994 }
drhdd3d4592004-08-30 01:54:05 +0000995 rc = sqlite3_step(pSelect);
996 }
drh2f464a02011-10-13 00:41:49 +0000997 rc = sqlite3_finalize(pSelect);
998 if( rc!=SQLITE_OK ){
999 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
1000 p->nErr++;
1001 }
1002 return rc;
drhdd3d4592004-08-30 01:54:05 +00001003}
1004
shane626a6e42009-10-22 17:30:15 +00001005/*
1006** Allocate space and save off current error string.
1007*/
1008static char *save_err_msg(
1009 sqlite3 *db /* Database to query */
1010){
1011 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1012 char *zErrMsg = sqlite3_malloc(nErrMsg);
1013 if( zErrMsg ){
1014 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1015 }
1016 return zErrMsg;
1017}
1018
1019/*
shaneh642d8b82010-07-28 16:05:34 +00001020** Display memory stats.
1021*/
1022static int display_stats(
1023 sqlite3 *db, /* Database to query */
1024 struct callback_data *pArg, /* Pointer to struct callback_data */
1025 int bReset /* True to reset the stats */
1026){
1027 int iCur;
1028 int iHiwtr;
1029
1030 if( pArg && pArg->out ){
1031
1032 iHiwtr = iCur = -1;
1033 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001034 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001035 iHiwtr = iCur = -1;
1036 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001037 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001038/*
1039** Not currently used by the CLI.
1040** iHiwtr = iCur = -1;
1041** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1042** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1043*/
1044 iHiwtr = iCur = -1;
1045 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1046 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1047/*
1048** Not currently used by the CLI.
1049** iHiwtr = iCur = -1;
1050** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1051** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1052*/
1053 iHiwtr = iCur = -1;
1054 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1055 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1056 iHiwtr = iCur = -1;
1057 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1058 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1059 iHiwtr = iCur = -1;
1060 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1061 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1062 iHiwtr = iCur = -1;
1063 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1064 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1065#ifdef YYTRACKMAXSTACKDEPTH
1066 iHiwtr = iCur = -1;
1067 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1068 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1069#endif
1070 }
1071
1072 if( pArg && pArg->out && db ){
1073 iHiwtr = iCur = -1;
1074 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1075 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001076 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1077 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1078 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1079 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1080 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1081 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001082 iHiwtr = iCur = -1;
1083 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001084 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1085 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1086 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1087 iHiwtr = iCur = -1;
1088 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1089 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001090 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001091 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1092 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1093 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001094 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1095 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1096 iHiwtr = iCur = -1;
1097 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1098 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1099 }
1100
1101 if( pArg && pArg->out && db && pArg->pStmt ){
1102 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1103 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1104 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1105 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1106 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1107 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1108 }
1109
1110 return 0;
1111}
1112
1113/*
shane626a6e42009-10-22 17:30:15 +00001114** Execute a statement or set of statements. Print
1115** any result rows/columns depending on the current mode
1116** set via the supplied callback.
1117**
1118** This is very similar to SQLite's built-in sqlite3_exec()
1119** function except it takes a slightly different callback
1120** and callback data argument.
1121*/
1122static int shell_exec(
1123 sqlite3 *db, /* An open database */
1124 const char *zSql, /* SQL to be evaluated */
1125 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1126 /* (not the same as sqlite3_exec) */
1127 struct callback_data *pArg, /* Pointer to struct callback_data */
1128 char **pzErrMsg /* Error msg written here */
1129){
dan4564ced2010-01-05 04:59:56 +00001130 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1131 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001132 int rc2;
dan4564ced2010-01-05 04:59:56 +00001133 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001134
1135 if( pzErrMsg ){
1136 *pzErrMsg = NULL;
1137 }
1138
shaneb9fc17d2009-10-22 21:23:35 +00001139 while( zSql[0] && (SQLITE_OK == rc) ){
1140 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1141 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001142 if( pzErrMsg ){
1143 *pzErrMsg = save_err_msg(db);
1144 }
1145 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001146 if( !pStmt ){
1147 /* this happens for a comment or white-space */
1148 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001149 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001150 continue;
1151 }
shane626a6e42009-10-22 17:30:15 +00001152
shaneh642d8b82010-07-28 16:05:34 +00001153 /* save off the prepared statment handle and reset row count */
1154 if( pArg ){
1155 pArg->pStmt = pStmt;
1156 pArg->cnt = 0;
1157 }
1158
shanehb7977c52010-01-18 18:17:10 +00001159 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001160 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001161 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001162 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001163 }
shanehb7977c52010-01-18 18:17:10 +00001164
drh7e02e5e2011-12-06 19:44:51 +00001165 /* Output TESTCTRL_EXPLAIN text of requested */
1166 if( pArg && pArg->mode==MODE_Explain ){
1167 const char *zExplain = 0;
1168 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1169 if( zExplain && zExplain[0] ){
1170 fprintf(pArg->out, "%s", zExplain);
1171 }
1172 }
1173
shaneb9fc17d2009-10-22 21:23:35 +00001174 /* perform the first step. this will tell us if we
1175 ** have a result set or not and how wide it is.
1176 */
1177 rc = sqlite3_step(pStmt);
1178 /* if we have a result set... */
1179 if( SQLITE_ROW == rc ){
1180 /* if we have a callback... */
1181 if( xCallback ){
1182 /* allocate space for col name ptr, value ptr, and type */
1183 int nCol = sqlite3_column_count(pStmt);
1184 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1185 if( !pData ){
1186 rc = SQLITE_NOMEM;
1187 }else{
1188 char **azCols = (char **)pData; /* Names of result columns */
1189 char **azVals = &azCols[nCol]; /* Results */
1190 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1191 int i;
1192 assert(sizeof(int) <= sizeof(char *));
1193 /* save off ptrs to column names */
1194 for(i=0; i<nCol; i++){
1195 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1196 }
shaneb9fc17d2009-10-22 21:23:35 +00001197 do{
1198 /* extract the data and data types */
1199 for(i=0; i<nCol; i++){
1200 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1201 aiTypes[i] = sqlite3_column_type(pStmt, i);
1202 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1203 rc = SQLITE_NOMEM;
1204 break; /* from for */
1205 }
1206 } /* end for */
1207
1208 /* if data and types extracted successfully... */
1209 if( SQLITE_ROW == rc ){
1210 /* call the supplied callback with the result row data */
1211 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1212 rc = SQLITE_ABORT;
1213 }else{
1214 rc = sqlite3_step(pStmt);
1215 }
1216 }
1217 } while( SQLITE_ROW == rc );
1218 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001219 }
1220 }else{
1221 do{
1222 rc = sqlite3_step(pStmt);
1223 } while( rc == SQLITE_ROW );
1224 }
1225 }
1226
shaneh642d8b82010-07-28 16:05:34 +00001227 /* print usage stats if stats on */
1228 if( pArg && pArg->statsOn ){
1229 display_stats(db, pArg, 0);
1230 }
1231
dan4564ced2010-01-05 04:59:56 +00001232 /* Finalize the statement just executed. If this fails, save a
1233 ** copy of the error message. Otherwise, set zSql to point to the
1234 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001235 rc2 = sqlite3_finalize(pStmt);
1236 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001237 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001238 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001239 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001240 }else if( pzErrMsg ){
1241 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001242 }
shaneh642d8b82010-07-28 16:05:34 +00001243
1244 /* clear saved stmt handle */
1245 if( pArg ){
1246 pArg->pStmt = NULL;
1247 }
shane626a6e42009-10-22 17:30:15 +00001248 }
shaneb9fc17d2009-10-22 21:23:35 +00001249 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001250
1251 return rc;
1252}
1253
drhdd3d4592004-08-30 01:54:05 +00001254
drh33048c02001-10-01 14:29:22 +00001255/*
drh4c653a02000-06-07 01:27:47 +00001256** This is a different callback routine used for dumping the database.
1257** Each row received by this callback consists of a table name,
1258** the table type ("index" or "table") and SQL to create the table.
1259** This routine should print text sufficient to recreate the table.
1260*/
1261static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001262 int rc;
1263 const char *zTable;
1264 const char *zType;
1265 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001266 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001267 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001268
drh902b9ee2008-12-05 17:17:07 +00001269 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001270 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001271 zTable = azArg[0];
1272 zType = azArg[1];
1273 zSql = azArg[2];
1274
drh00b950d2005-09-11 02:03:03 +00001275 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001276 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001277 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1278 fprintf(p->out, "ANALYZE sqlite_master;\n");
1279 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1280 return 0;
drh45e29d82006-11-20 16:21:10 +00001281 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1282 char *zIns;
1283 if( !p->writableSchema ){
1284 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1285 p->writableSchema = 1;
1286 }
1287 zIns = sqlite3_mprintf(
1288 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1289 "VALUES('table','%q','%q',0,'%q');",
1290 zTable, zTable, zSql);
1291 fprintf(p->out, "%s\n", zIns);
1292 sqlite3_free(zIns);
1293 return 0;
drh00b950d2005-09-11 02:03:03 +00001294 }else{
1295 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001296 }
danielk19772a02e332004-06-05 08:04:36 +00001297
1298 if( strcmp(zType, "table")==0 ){
1299 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001300 char *zSelect = 0;
1301 char *zTableInfo = 0;
1302 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001303 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001304
1305 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1306 zTableInfo = appendText(zTableInfo, zTable, '"');
1307 zTableInfo = appendText(zTableInfo, ");", 0);
1308
1309 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001310 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001311 if( rc!=SQLITE_OK || !pTableInfo ){
1312 return 1;
1313 }
1314
1315 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001316 /* Always quote the table name, even if it appears to be pure ascii,
1317 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1318 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001319 if( zTmp ){
1320 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001321 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001322 }
1323 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1324 rc = sqlite3_step(pTableInfo);
1325 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001326 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001327 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001328 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001329 rc = sqlite3_step(pTableInfo);
1330 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001331 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001332 }else{
1333 zSelect = appendText(zSelect, ") ", 0);
1334 }
drh157e29a2009-05-21 15:15:00 +00001335 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001336 }
1337 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001338 if( rc!=SQLITE_OK || nRow==0 ){
1339 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001340 return 1;
1341 }
1342 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1343 zSelect = appendText(zSelect, zTable, '"');
1344
drh2f464a02011-10-13 00:41:49 +00001345 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001346 if( rc==SQLITE_CORRUPT ){
1347 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001348 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001349 }
drh85e72432012-04-11 11:38:53 +00001350 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001351 }
drh4c653a02000-06-07 01:27:47 +00001352 return 0;
1353}
1354
1355/*
drh45e29d82006-11-20 16:21:10 +00001356** Run zQuery. Use dump_callback() as the callback routine so that
1357** the contents of the query are output as SQL statements.
1358**
drhdd3d4592004-08-30 01:54:05 +00001359** If we get a SQLITE_CORRUPT error, rerun the query after appending
1360** "ORDER BY rowid DESC" to the end.
1361*/
1362static int run_schema_dump_query(
1363 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001364 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001365){
1366 int rc;
drh2f464a02011-10-13 00:41:49 +00001367 char *zErr = 0;
1368 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001369 if( rc==SQLITE_CORRUPT ){
1370 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001371 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001372 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1373 if( zErr ){
1374 fprintf(p->out, "/****** %s ******/\n", zErr);
1375 sqlite3_free(zErr);
1376 zErr = 0;
1377 }
drhdd3d4592004-08-30 01:54:05 +00001378 zQ2 = malloc( len+100 );
1379 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001380 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001381 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1382 if( rc ){
1383 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1384 }else{
1385 rc = SQLITE_CORRUPT;
1386 }
1387 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001388 free(zQ2);
1389 }
1390 return rc;
1391}
1392
1393/*
drh75897232000-05-29 14:26:00 +00001394** Text of a help message
1395*/
persicom1d0b8722002-04-18 02:53:04 +00001396static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001397 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001398 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001399 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001400 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001401 " If TABLE specified, only dump tables matching\n"
1402 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001403 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001404 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001405 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1406 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001407 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001408 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001409 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001410 ".indices ?TABLE? Show names of all indices\n"
1411 " If TABLE specified, only show indices for tables\n"
1412 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001413#ifdef SQLITE_ENABLE_IOTRACE
1414 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1415#endif
drh70df4fe2006-06-13 15:12:21 +00001416#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001417 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001418#endif
drh127f9d72010-02-23 01:47:00 +00001419 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001420 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001421 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001422 " column Left-aligned columns. (See .width)\n"
1423 " html HTML <table> code\n"
1424 " insert SQL insert statements for TABLE\n"
1425 " line One value per line\n"
1426 " list Values delimited by .separator string\n"
1427 " tabs Tab-separated values\n"
1428 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001429 ".nullvalue STRING Use STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001430 ".output FILENAME Send output to FILENAME\n"
1431 ".output stdout Send output to the screen\n"
drh078b1fd2012-09-21 13:40:02 +00001432 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001433 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001434 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001435 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001436 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001437 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001438 " If TABLE specified, only show tables matching\n"
1439 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001440 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001441 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001442 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001443 ".tables ?TABLE? List names of tables\n"
1444 " If TABLE specified, only list tables matching\n"
1445 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001446 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001447 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001448 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001449 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001450;
1451
shaneb320ccd2009-10-21 03:42:58 +00001452static char zTimerHelp[] =
1453 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1454;
1455
drhdaffd0e2001-04-11 14:28:42 +00001456/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001457static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001458
drh75897232000-05-29 14:26:00 +00001459/*
drh44c2eb12003-04-30 11:38:26 +00001460** Make sure the database is open. If it is not, then open it. If
1461** the database fails to open, print an error message and exit.
1462*/
1463static void open_db(struct callback_data *p){
1464 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001465 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001466 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001467 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001468 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1469 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1470 shellstaticFunc, 0, 0);
1471 }
1472 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001473 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001474 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001475 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001476 }
drhc2e87a32006-06-27 15:16:14 +00001477#ifndef SQLITE_OMIT_LOAD_EXTENSION
1478 sqlite3_enable_load_extension(p->db, 1);
1479#endif
drh44c2eb12003-04-30 11:38:26 +00001480 }
1481}
1482
1483/*
drhfeac5f82004-08-01 00:10:45 +00001484** Do C-language style dequoting.
1485**
1486** \t -> tab
1487** \n -> newline
1488** \r -> carriage return
1489** \NNN -> ascii character NNN in octal
1490** \\ -> backslash
1491*/
1492static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001493 int i, j;
1494 char c;
drhfeac5f82004-08-01 00:10:45 +00001495 for(i=j=0; (c = z[i])!=0; i++, j++){
1496 if( c=='\\' ){
1497 c = z[++i];
1498 if( c=='n' ){
1499 c = '\n';
1500 }else if( c=='t' ){
1501 c = '\t';
1502 }else if( c=='r' ){
1503 c = '\r';
1504 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001505 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001506 if( z[i+1]>='0' && z[i+1]<='7' ){
1507 i++;
1508 c = (c<<3) + z[i] - '0';
1509 if( z[i+1]>='0' && z[i+1]<='7' ){
1510 i++;
1511 c = (c<<3) + z[i] - '0';
1512 }
1513 }
1514 }
1515 }
1516 z[j] = c;
1517 }
1518 z[j] = 0;
1519}
1520
1521/*
drhc28490c2006-10-26 14:25:58 +00001522** Interpret zArg as a boolean value. Return either 0 or 1.
1523*/
1524static int booleanValue(char *zArg){
1525 int val = atoi(zArg);
1526 int j;
1527 for(j=0; zArg[j]; j++){
drhf0693c82011-10-11 20:41:54 +00001528 zArg[j] = ToLower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001529 }
1530 if( strcmp(zArg,"on")==0 ){
1531 val = 1;
1532 }else if( strcmp(zArg,"yes")==0 ){
1533 val = 1;
1534 }
1535 return val;
1536}
1537
1538/*
drh42f64e52012-04-04 16:56:23 +00001539** Close an output file, assuming it is not stderr or stdout
1540*/
1541static void output_file_close(FILE *f){
1542 if( f && f!=stdout && f!=stderr ) fclose(f);
1543}
1544
1545/*
1546** Try to open an output file. The names "stdout" and "stderr" are
1547** recognized and do the right thing. NULL is returned if the output
1548** filename is "off".
1549*/
1550static FILE *output_file_open(const char *zFile){
1551 FILE *f;
1552 if( strcmp(zFile,"stdout")==0 ){
1553 f = stdout;
1554 }else if( strcmp(zFile, "stderr")==0 ){
1555 f = stderr;
1556 }else if( strcmp(zFile, "off")==0 ){
1557 f = 0;
1558 }else{
1559 f = fopen(zFile, "wb");
1560 if( f==0 ){
1561 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1562 }
1563 }
1564 return f;
1565}
1566
1567/*
1568** A routine for handling output from sqlite3_trace().
1569*/
1570static void sql_trace_callback(void *pArg, const char *z){
1571 FILE *f = (FILE*)pArg;
1572 if( f ) fprintf(f, "%s\n", z);
1573}
1574
1575/*
drhd8621b92012-04-17 09:09:33 +00001576** A no-op routine that runs with the ".breakpoint" doc-command. This is
1577** a useful spot to set a debugger breakpoint.
1578*/
1579static void test_breakpoint(void){
1580 static int nCall = 0;
1581 nCall++;
1582}
1583
1584/*
drh75897232000-05-29 14:26:00 +00001585** If an input line begins with "." then invoke this routine to
1586** process that line.
drh67505e72002-04-19 12:34:06 +00001587**
drh47ad6842006-11-08 12:25:42 +00001588** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001589*/
drh44c2eb12003-04-30 11:38:26 +00001590static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001591 int i = 1;
1592 int nArg = 0;
1593 int n, c;
drh67505e72002-04-19 12:34:06 +00001594 int rc = 0;
drh75897232000-05-29 14:26:00 +00001595 char *azArg[50];
1596
1597 /* Parse the input line into tokens.
1598 */
1599 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001600 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001601 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001602 if( zLine[i]=='\'' || zLine[i]=='"' ){
1603 int delim = zLine[i++];
1604 azArg[nArg++] = &zLine[i];
1605 while( zLine[i] && zLine[i]!=delim ){ i++; }
1606 if( zLine[i]==delim ){
1607 zLine[i++] = 0;
1608 }
drhfeac5f82004-08-01 00:10:45 +00001609 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001610 }else{
1611 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001612 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001613 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001614 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001615 }
1616 }
1617
1618 /* Process the input line.
1619 */
shane9bd1b442009-10-23 01:27:39 +00001620 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001621 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001622 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001623 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001624 const char *zDestFile;
1625 const char *zDb;
1626 sqlite3 *pDest;
1627 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001628 if( nArg==2 ){
1629 zDestFile = azArg[1];
1630 zDb = "main";
1631 }else{
1632 zDestFile = azArg[2];
1633 zDb = azArg[1];
1634 }
1635 rc = sqlite3_open(zDestFile, &pDest);
1636 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001637 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001638 sqlite3_close(pDest);
1639 return 1;
1640 }
drhdc2c4912009-02-04 22:46:47 +00001641 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001642 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1643 if( pBackup==0 ){
1644 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1645 sqlite3_close(pDest);
1646 return 1;
1647 }
1648 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1649 sqlite3_backup_finish(pBackup);
1650 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001651 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001652 }else{
1653 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001654 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001655 }
1656 sqlite3_close(pDest);
1657 }else
1658
shanehe2aa9d72009-11-06 17:20:17 +00001659 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001660 bail_on_error = booleanValue(azArg[1]);
1661 }else
1662
drhd8621b92012-04-17 09:09:33 +00001663 /* The undocumented ".breakpoint" command causes a call to the no-op
1664 ** routine named test_breakpoint().
1665 */
1666 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1667 test_breakpoint();
1668 }else
1669
shanehe2aa9d72009-11-06 17:20:17 +00001670 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001671 struct callback_data data;
1672 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001673 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001674 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001675 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001676 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001677 data.colWidth[0] = 3;
1678 data.colWidth[1] = 15;
1679 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001680 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001681 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001682 if( zErrMsg ){
1683 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001684 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001685 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001686 }
1687 }else
1688
shanehe2aa9d72009-11-06 17:20:17 +00001689 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001690 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001691 /* When playing back a "dump", the content might appear in an order
1692 ** which causes immediate foreign key constraints to be violated.
1693 ** So disable foreign-key constraint enforcement to prevent problems. */
1694 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001695 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001696 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001697 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001698 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001699 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001700 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001701 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001702 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001703 );
1704 run_schema_dump_query(p,
1705 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001706 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001707 );
drh2f464a02011-10-13 00:41:49 +00001708 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001709 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001710 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001711 );
drh4c653a02000-06-07 01:27:47 +00001712 }else{
1713 int i;
drhdd3d4592004-08-30 01:54:05 +00001714 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001715 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001716 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001717 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001718 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001719 " AND sql NOT NULL");
1720 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001721 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001722 "WHERE sql NOT NULL"
1723 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001724 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001725 );
danielk1977bc6ada42004-06-30 08:20:16 +00001726 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001727 }
1728 }
drh45e29d82006-11-20 16:21:10 +00001729 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001730 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001731 p->writableSchema = 0;
1732 }
drh56197952011-10-13 16:30:13 +00001733 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1734 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001735 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001736 }else
drh75897232000-05-29 14:26:00 +00001737
shanehe2aa9d72009-11-06 17:20:17 +00001738 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001739 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001740 }else
1741
shanehe2aa9d72009-11-06 17:20:17 +00001742 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001743 rc = 2;
drh75897232000-05-29 14:26:00 +00001744 }else
1745
shanehe2aa9d72009-11-06 17:20:17 +00001746 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001747 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001748 if(val == 1) {
1749 if(!p->explainPrev.valid) {
1750 p->explainPrev.valid = 1;
1751 p->explainPrev.mode = p->mode;
1752 p->explainPrev.showHeader = p->showHeader;
1753 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1754 }
1755 /* We could put this code under the !p->explainValid
1756 ** condition so that it does not execute if we are already in
1757 ** explain mode. However, always executing it allows us an easy
1758 ** was to reset to explain mode in case the user previously
1759 ** did an .explain followed by a .width, .mode or .header
1760 ** command.
1761 */
danielk19770d78bae2008-01-03 07:09:48 +00001762 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001763 p->showHeader = 1;
1764 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001765 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001766 p->colWidth[1] = 13; /* opcode */
1767 p->colWidth[2] = 4; /* P1 */
1768 p->colWidth[3] = 4; /* P2 */
1769 p->colWidth[4] = 4; /* P3 */
1770 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001771 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001772 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001773 }else if (p->explainPrev.valid) {
1774 p->explainPrev.valid = 0;
1775 p->mode = p->explainPrev.mode;
1776 p->showHeader = p->explainPrev.showHeader;
1777 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1778 }
drh75897232000-05-29 14:26:00 +00001779 }else
1780
drhc28490c2006-10-26 14:25:58 +00001781 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001782 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001783 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001784 }else
1785
1786 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001787 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001788 if( HAS_TIMER ){
1789 fprintf(stderr,"%s",zTimerHelp);
1790 }
drh75897232000-05-29 14:26:00 +00001791 }else
1792
shanehe2aa9d72009-11-06 17:20:17 +00001793 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001794 char *zTable = azArg[2]; /* Insert data into this table */
1795 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001796 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001797 int nCol; /* Number of columns in the table */
1798 int nByte; /* Number of bytes in an SQL string */
1799 int i, j; /* Loop counters */
1800 int nSep; /* Number of bytes in p->separator[] */
1801 char *zSql; /* An SQL statement */
1802 char *zLine; /* A single line of input from the file */
1803 char **azCol; /* zLine[] broken up into columns */
1804 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001805 FILE *in; /* The input file */
1806 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001807
drha543c822006-06-08 16:10:14 +00001808 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001809 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001810 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001811 fprintf(stderr, "Error: non-null separator required for import\n");
1812 return 1;
drhfeac5f82004-08-01 00:10:45 +00001813 }
drh7b075e32011-09-28 01:10:00 +00001814 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00001815 if( zSql==0 ){
1816 fprintf(stderr, "Error: out of memory\n");
1817 return 1;
1818 }
drh4f21c4a2008-12-10 22:15:00 +00001819 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001820 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001821 sqlite3_free(zSql);
1822 if( rc ){
shane916f9612009-10-23 00:37:15 +00001823 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001824 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001825 return 1;
drhfeac5f82004-08-01 00:10:45 +00001826 }
shane916f9612009-10-23 00:37:15 +00001827 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001828 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001829 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001830 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001831 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001832 if( zSql==0 ){
1833 fprintf(stderr, "Error: out of memory\n");
1834 return 1;
1835 }
drh7b075e32011-09-28 01:10:00 +00001836 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001837 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001838 for(i=1; i<nCol; i++){
1839 zSql[j++] = ',';
1840 zSql[j++] = '?';
1841 }
1842 zSql[j++] = ')';
1843 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001844 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001845 free(zSql);
1846 if( rc ){
1847 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001848 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001849 return 1;
drhfeac5f82004-08-01 00:10:45 +00001850 }
1851 in = fopen(zFile, "rb");
1852 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001853 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001854 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001855 return 1;
drhfeac5f82004-08-01 00:10:45 +00001856 }
1857 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001858 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001859 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001860 fclose(in);
shane916f9612009-10-23 00:37:15 +00001861 sqlite3_finalize(pStmt);
1862 return 1;
drh43617e92006-03-06 20:55:46 +00001863 }
drhfeac5f82004-08-01 00:10:45 +00001864 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1865 zCommit = "COMMIT";
drh18f52e02012-01-16 16:56:31 +00001866 while( (zLine = local_getline(0, in, 1))!=0 ){
1867 char *z, c;
1868 int inQuote = 0;
drhb860bc92004-08-04 15:16:55 +00001869 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001870 azCol[0] = zLine;
drh18f52e02012-01-16 16:56:31 +00001871 for(i=0, z=zLine; (c = *z)!=0; z++){
1872 if( c=='"' ) inQuote = !inQuote;
1873 if( c=='\n' ) lineno++;
1874 if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001875 *z = 0;
1876 i++;
drhb860bc92004-08-04 15:16:55 +00001877 if( i<nCol ){
1878 azCol[i] = &z[nSep];
1879 z += nSep-1;
1880 }
drhfeac5f82004-08-01 00:10:45 +00001881 }
shane916f9612009-10-23 00:37:15 +00001882 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001883 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001884 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001885 fprintf(stderr,
1886 "Error: %s line %d: expected %d columns of data but found %d\n",
1887 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001888 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001889 free(zLine);
shane916f9612009-10-23 00:37:15 +00001890 rc = 1;
1891 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001892 }
drhfeac5f82004-08-01 00:10:45 +00001893 for(i=0; i<nCol; i++){
drh18f52e02012-01-16 16:56:31 +00001894 if( azCol[i][0]=='"' ){
1895 int k;
1896 for(z=azCol[i], j=1, k=0; z[j]; j++){
1897 if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1898 z[k++] = z[j];
1899 }
1900 z[k] = 0;
1901 }
drhfeac5f82004-08-01 00:10:45 +00001902 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1903 }
1904 sqlite3_step(pStmt);
1905 rc = sqlite3_reset(pStmt);
1906 free(zLine);
1907 if( rc!=SQLITE_OK ){
1908 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1909 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001910 rc = 1;
shane916f9612009-10-23 00:37:15 +00001911 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001912 }
shane916f9612009-10-23 00:37:15 +00001913 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001914 free(azCol);
1915 fclose(in);
1916 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001917 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001918 }else
1919
shanehe2aa9d72009-11-06 17:20:17 +00001920 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001921 struct callback_data data;
1922 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001923 open_db(p);
drh75897232000-05-29 14:26:00 +00001924 memcpy(&data, p, sizeof(data));
1925 data.showHeader = 0;
1926 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001927 if( nArg==1 ){
1928 rc = sqlite3_exec(p->db,
1929 "SELECT name FROM sqlite_master "
1930 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1931 "UNION ALL "
1932 "SELECT name FROM sqlite_temp_master "
1933 "WHERE type='index' "
1934 "ORDER BY 1",
1935 callback, &data, &zErrMsg
1936 );
1937 }else{
1938 zShellStatic = azArg[1];
1939 rc = sqlite3_exec(p->db,
1940 "SELECT name FROM sqlite_master "
1941 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1942 "UNION ALL "
1943 "SELECT name FROM sqlite_temp_master "
1944 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1945 "ORDER BY 1",
1946 callback, &data, &zErrMsg
1947 );
1948 zShellStatic = 0;
1949 }
drh75897232000-05-29 14:26:00 +00001950 if( zErrMsg ){
1951 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001952 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001953 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001954 }else if( rc != SQLITE_OK ){
1955 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1956 rc = 1;
drh75897232000-05-29 14:26:00 +00001957 }
1958 }else
1959
drhae5e4452007-05-03 17:18:36 +00001960#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001961 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001962 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001963 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1964 iotrace = 0;
1965 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001966 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001967 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001968 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001969 iotrace = stdout;
1970 }else{
1971 iotrace = fopen(azArg[1], "w");
1972 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001973 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001974 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001975 rc = 1;
drhb0603412007-02-28 04:47:26 +00001976 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001977 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001978 }
1979 }
1980 }else
drhae5e4452007-05-03 17:18:36 +00001981#endif
drhb0603412007-02-28 04:47:26 +00001982
drh70df4fe2006-06-13 15:12:21 +00001983#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001984 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1985 const char *zFile, *zProc;
1986 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001987 zFile = azArg[1];
1988 zProc = nArg>=3 ? azArg[2] : 0;
1989 open_db(p);
1990 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1991 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001992 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001993 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001994 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001995 }
1996 }else
drh70df4fe2006-06-13 15:12:21 +00001997#endif
drh1e397f82006-06-08 15:28:43 +00001998
drhc8ba2122011-03-23 11:16:22 +00001999 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00002000 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00002001 output_file_close(p->pLog);
2002 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00002003 }else
2004
shanehe2aa9d72009-11-06 17:20:17 +00002005 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00002006 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002007 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002008 ||
shanehe2aa9d72009-11-06 17:20:17 +00002009 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002010 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002011 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002012 ||
shanehe2aa9d72009-11-06 17:20:17 +00002013 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002014 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002015 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002016 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002017 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002018 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002019 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002020 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00002021 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002022 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002023 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002024 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002025 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002026 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002027 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002028 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002029 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002030 }else {
shane9bd1b442009-10-23 01:27:39 +00002031 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002032 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002033 rc = 1;
drh75897232000-05-29 14:26:00 +00002034 }
2035 }else
2036
shanehe2aa9d72009-11-06 17:20:17 +00002037 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2038 int n2 = strlen30(azArg[1]);
2039 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2040 p->mode = MODE_Insert;
2041 set_table_name(p, azArg[2]);
2042 }else {
2043 fprintf(stderr, "Error: invalid arguments: "
2044 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2045 rc = 1;
2046 }
2047 }else
2048
persicom7e2dfdd2002-04-18 02:46:52 +00002049 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002050 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2051 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002052 }else
2053
drh75897232000-05-29 14:26:00 +00002054 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002055 if( p->outfile[0]=='|' ){
2056 pclose(p->out);
2057 }else{
2058 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002059 }
drh42f64e52012-04-04 16:56:23 +00002060 p->outfile[0] = 0;
2061 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002062 p->out = popen(&azArg[1][1], "w");
2063 if( p->out==0 ){
2064 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2065 p->out = stdout;
2066 rc = 1;
2067 }else{
2068 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2069 }
drh75897232000-05-29 14:26:00 +00002070 }else{
drh42f64e52012-04-04 16:56:23 +00002071 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002072 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002073 if( strcmp(azArg[1],"off")!=0 ){
2074 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2075 }
drh75897232000-05-29 14:26:00 +00002076 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002077 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002078 } else {
drh42f64e52012-04-04 16:56:23 +00002079 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002080 }
2081 }
2082 }else
2083
drh078b1fd2012-09-21 13:40:02 +00002084 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2085 int i;
2086 for(i=1; i<nArg; i++){
2087 if( i>1 ) fprintf(p->out, " ");
2088 fprintf(p->out, "%s", azArg[i]);
2089 }
2090 fprintf(p->out, "\n");
2091 }else
2092
drhdd45df82002-04-18 12:39:03 +00002093 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002094 if( nArg >= 2) {
2095 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2096 }
2097 if( nArg >= 3) {
2098 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2099 }
2100 }else
2101
shanehe2aa9d72009-11-06 17:20:17 +00002102 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002103 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002104 }else
2105
drh9ff849f2009-02-04 20:55:57 +00002106 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002107 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002108 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002109 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2110 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002111 }else{
shane9bd1b442009-10-23 01:27:39 +00002112 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002113 fclose(alt);
2114 }
2115 }else
2116
shanehe2aa9d72009-11-06 17:20:17 +00002117 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002118 const char *zSrcFile;
2119 const char *zDb;
2120 sqlite3 *pSrc;
2121 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002122 int nTimeout = 0;
2123
drh9ff849f2009-02-04 20:55:57 +00002124 if( nArg==2 ){
2125 zSrcFile = azArg[1];
2126 zDb = "main";
2127 }else{
2128 zSrcFile = azArg[2];
2129 zDb = azArg[1];
2130 }
2131 rc = sqlite3_open(zSrcFile, &pSrc);
2132 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002133 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002134 sqlite3_close(pSrc);
2135 return 1;
2136 }
drhdc2c4912009-02-04 22:46:47 +00002137 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002138 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2139 if( pBackup==0 ){
2140 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2141 sqlite3_close(pSrc);
2142 return 1;
2143 }
drhdc2c4912009-02-04 22:46:47 +00002144 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2145 || rc==SQLITE_BUSY ){
2146 if( rc==SQLITE_BUSY ){
2147 if( nTimeout++ >= 3 ) break;
2148 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002149 }
2150 }
2151 sqlite3_backup_finish(pBackup);
2152 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002153 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002154 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002155 fprintf(stderr, "Error: source database is busy\n");
2156 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002157 }else{
2158 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002159 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002160 }
2161 sqlite3_close(pSrc);
2162 }else
2163
shanehe2aa9d72009-11-06 17:20:17 +00002164 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002165 struct callback_data data;
2166 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002167 open_db(p);
drh75897232000-05-29 14:26:00 +00002168 memcpy(&data, p, sizeof(data));
2169 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002170 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002171 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002172 int i;
drhf0693c82011-10-11 20:41:54 +00002173 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002174 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002175 char *new_argv[2], *new_colv[2];
2176 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2177 " type text,\n"
2178 " name text,\n"
2179 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002180 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002181 " sql text\n"
2182 ")";
2183 new_argv[1] = 0;
2184 new_colv[0] = "sql";
2185 new_colv[1] = 0;
2186 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002187 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002188 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002189 char *new_argv[2], *new_colv[2];
2190 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2191 " type text,\n"
2192 " name text,\n"
2193 " tbl_name text,\n"
2194 " rootpage integer,\n"
2195 " sql text\n"
2196 ")";
2197 new_argv[1] = 0;
2198 new_colv[0] = "sql";
2199 new_colv[1] = 0;
2200 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002201 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002202 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002203 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002204 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002205 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002206 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002207 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002208 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002209 "WHERE lower(tbl_name) LIKE shellstatic()"
2210 " AND type!='meta' AND sql NOTNULL "
drhac43e982012-05-21 03:15:06 +00002211 "ORDER BY substr(type,2,1), "
2212 " CASE type WHEN 'view' THEN rowid ELSE name END",
danielk1977bc6ada42004-06-30 08:20:16 +00002213 callback, &data, &zErrMsg);
2214 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002215 }
drh75897232000-05-29 14:26:00 +00002216 }else{
shane9bd1b442009-10-23 01:27:39 +00002217 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002218 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002219 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002220 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002221 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002222 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhac43e982012-05-21 03:15:06 +00002223 "ORDER BY substr(type,2,1),"
2224 " CASE type WHEN 'view' THEN rowid ELSE name END",
drha18c5682000-10-08 22:20:57 +00002225 callback, &data, &zErrMsg
2226 );
drh75897232000-05-29 14:26:00 +00002227 }
drh75897232000-05-29 14:26:00 +00002228 if( zErrMsg ){
2229 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002230 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002231 rc = 1;
2232 }else if( rc != SQLITE_OK ){
2233 fprintf(stderr,"Error: querying schema information\n");
2234 rc = 1;
2235 }else{
2236 rc = 0;
drh75897232000-05-29 14:26:00 +00002237 }
2238 }else
2239
2240 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002241 sqlite3_snprintf(sizeof(p->separator), p->separator,
2242 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002243 }else
2244
shanehe2aa9d72009-11-06 17:20:17 +00002245 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002246 int i;
2247 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002248 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002249 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002250 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002251 fprintf(p->out,"%9.9s: ", "nullvalue");
2252 output_c_string(p->out, p->nullvalue);
2253 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002254 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002255 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002256 fprintf(p->out,"%9.9s: ", "separator");
2257 output_c_string(p->out, p->separator);
2258 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002259 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002260 fprintf(p->out,"%9.9s: ","width");
2261 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002262 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002263 }
drhfeac5f82004-08-01 00:10:45 +00002264 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002265 }else
2266
shaneh642d8b82010-07-28 16:05:34 +00002267 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2268 p->statsOn = booleanValue(azArg[1]);
2269 }else
2270
shanehe2aa9d72009-11-06 17:20:17 +00002271 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002272 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002273 char **azResult;
drh98781232012-04-23 12:38:05 +00002274 int nRow, nAlloc;
2275 char *zSql = 0;
2276 int ii;
drh44c2eb12003-04-30 11:38:26 +00002277 open_db(p);
drh98781232012-04-23 12:38:05 +00002278 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2279 if( rc ) return rc;
2280 zSql = sqlite3_mprintf(
2281 "SELECT name FROM sqlite_master"
2282 " WHERE type IN ('table','view')"
2283 " AND name NOT LIKE 'sqlite_%%'"
2284 " AND name LIKE ?1");
2285 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2286 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2287 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2288 if( strcmp(zDbName,"temp")==0 ){
2289 zSql = sqlite3_mprintf(
2290 "%z UNION ALL "
2291 "SELECT 'temp.' || name FROM sqlite_temp_master"
2292 " WHERE type IN ('table','view')"
2293 " AND name NOT LIKE 'sqlite_%%'"
2294 " AND name LIKE ?1", zSql);
2295 }else{
2296 zSql = sqlite3_mprintf(
2297 "%z UNION ALL "
2298 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2299 " WHERE type IN ('table','view')"
2300 " AND name NOT LIKE 'sqlite_%%'"
2301 " AND name LIKE ?1", zSql, zDbName, zDbName);
2302 }
drha50da102000-08-08 20:19:09 +00002303 }
drh98781232012-04-23 12:38:05 +00002304 sqlite3_finalize(pStmt);
2305 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2306 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2307 sqlite3_free(zSql);
2308 if( rc ) return rc;
2309 nRow = nAlloc = 0;
2310 azResult = 0;
2311 if( nArg>1 ){
2312 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002313 }else{
drh98781232012-04-23 12:38:05 +00002314 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2315 }
2316 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2317 if( nRow>=nAlloc ){
2318 char **azNew;
2319 int n = nAlloc*2 + 10;
2320 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2321 if( azNew==0 ){
2322 fprintf(stderr, "Error: out of memory\n");
2323 break;
2324 }
2325 nAlloc = n;
2326 azResult = azNew;
2327 }
2328 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2329 if( azResult[nRow] ) nRow++;
2330 }
2331 sqlite3_finalize(pStmt);
2332 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002333 int len, maxlen = 0;
2334 int i, j;
2335 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002336 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002337 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002338 if( len>maxlen ) maxlen = len;
2339 }
2340 nPrintCol = 80/(maxlen+2);
2341 if( nPrintCol<1 ) nPrintCol = 1;
2342 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2343 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002344 for(j=i; j<nRow; j+=nPrintRow){
2345 char *zSp = j<nPrintRow ? "" : " ";
drhe3710332000-09-29 13:30:53 +00002346 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2347 }
2348 printf("\n");
2349 }
2350 }
drh98781232012-04-23 12:38:05 +00002351 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2352 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002353 }else
2354
shaneh96887e12011-02-10 21:08:58 +00002355 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002356 static const struct {
2357 const char *zCtrlName; /* Name of a test-control option */
2358 int ctrlCode; /* Integer code for that option */
2359 } aCtrl[] = {
2360 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2361 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2362 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2363 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2364 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2365 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2366 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2367 { "assert", SQLITE_TESTCTRL_ASSERT },
2368 { "always", SQLITE_TESTCTRL_ALWAYS },
2369 { "reserve", SQLITE_TESTCTRL_RESERVE },
2370 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2371 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002372 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2373 };
shaneh96887e12011-02-10 21:08:58 +00002374 int testctrl = -1;
2375 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002376 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002377 open_db(p);
2378
drhd416fe72011-03-17 16:45:50 +00002379 /* convert testctrl text option to value. allow any unique prefix
2380 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002381 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002382 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002383 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2384 if( testctrl<0 ){
2385 testctrl = aCtrl[i].ctrlCode;
2386 }else{
drhb07028f2011-10-14 21:49:18 +00002387 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002388 testctrl = -1;
2389 break;
2390 }
2391 }
2392 }
2393 if( testctrl<0 ) testctrl = atoi(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002394 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2395 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2396 }else{
2397 switch(testctrl){
2398
2399 /* sqlite3_test_control(int, db, int) */
2400 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2401 case SQLITE_TESTCTRL_RESERVE:
2402 if( nArg==3 ){
2403 int opt = (int)strtol(azArg[2], 0, 0);
2404 rc = sqlite3_test_control(testctrl, p->db, opt);
2405 printf("%d (0x%08x)\n", rc, rc);
2406 } else {
drhd416fe72011-03-17 16:45:50 +00002407 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2408 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002409 }
2410 break;
2411
2412 /* sqlite3_test_control(int) */
2413 case SQLITE_TESTCTRL_PRNG_SAVE:
2414 case SQLITE_TESTCTRL_PRNG_RESTORE:
2415 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002416 if( nArg==2 ){
2417 rc = sqlite3_test_control(testctrl);
2418 printf("%d (0x%08x)\n", rc, rc);
2419 } else {
2420 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2421 }
2422 break;
2423
2424 /* sqlite3_test_control(int, uint) */
2425 case SQLITE_TESTCTRL_PENDING_BYTE:
2426 if( nArg==3 ){
2427 unsigned int opt = (unsigned int)atoi(azArg[2]);
2428 rc = sqlite3_test_control(testctrl, opt);
2429 printf("%d (0x%08x)\n", rc, rc);
2430 } else {
drhd416fe72011-03-17 16:45:50 +00002431 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2432 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002433 }
2434 break;
2435
2436 /* sqlite3_test_control(int, int) */
2437 case SQLITE_TESTCTRL_ASSERT:
2438 case SQLITE_TESTCTRL_ALWAYS:
2439 if( nArg==3 ){
2440 int opt = atoi(azArg[2]);
2441 rc = sqlite3_test_control(testctrl, 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, char *) */
2450#ifdef SQLITE_N_KEYWORD
2451 case SQLITE_TESTCTRL_ISKEYWORD:
2452 if( nArg==3 ){
2453 const char *opt = azArg[2];
2454 rc = sqlite3_test_control(testctrl, opt);
2455 printf("%d (0x%08x)\n", rc, rc);
2456 } else {
drhd416fe72011-03-17 16:45:50 +00002457 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2458 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002459 }
2460 break;
2461#endif
2462
2463 case SQLITE_TESTCTRL_BITVEC_TEST:
2464 case SQLITE_TESTCTRL_FAULT_INSTALL:
2465 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2466 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2467 default:
drhd416fe72011-03-17 16:45:50 +00002468 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2469 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002470 break;
2471 }
2472 }
2473 }else
2474
shanehe2aa9d72009-11-06 17:20:17 +00002475 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002476 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002477 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002478 }else
2479
drhd416fe72011-03-17 16:45:50 +00002480 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2481 && nArg==2
2482 ){
drh3b1a9882007-11-02 12:53:03 +00002483 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002484 }else
2485
drh42f64e52012-04-04 16:56:23 +00002486 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh98781232012-04-23 12:38:05 +00002487 open_db(p);
drh42f64e52012-04-04 16:56:23 +00002488 output_file_close(p->traceOut);
2489 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00002490#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002491 if( p->traceOut==0 ){
2492 sqlite3_trace(p->db, 0, 0);
2493 }else{
2494 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2495 }
2496#endif
2497 }else
2498
drh9fd301b2011-06-03 13:28:22 +00002499 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh743e0032011-12-12 16:51:50 +00002500 printf("SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002501 sqlite3_libversion(), sqlite3_sourceid());
2502 }else
2503
drhde60fc22011-12-14 17:53:36 +00002504 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2505 const char *zDbName = nArg==2 ? azArg[1] : "main";
2506 char *zVfsName = 0;
2507 if( p->db ){
2508 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2509 if( zVfsName ){
2510 printf("%s\n", zVfsName);
2511 sqlite3_free(zVfsName);
2512 }
2513 }
2514 }else
2515
drhcef4fc82012-09-21 22:50:45 +00002516#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2517 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
2518 extern int sqlite3WhereTrace;
2519 sqlite3WhereTrace = atoi(azArg[1]);
2520 }else
2521#endif
2522
shanehe2aa9d72009-11-06 17:20:17 +00002523 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002524 int j;
drh43617e92006-03-06 20:55:46 +00002525 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002526 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2527 p->colWidth[j-1] = atoi(azArg[j]);
2528 }
2529 }else
2530
2531 {
shane9bd1b442009-10-23 01:27:39 +00002532 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002533 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002534 rc = 1;
drh75897232000-05-29 14:26:00 +00002535 }
drh67505e72002-04-19 12:34:06 +00002536
2537 return rc;
drh75897232000-05-29 14:26:00 +00002538}
2539
drh67505e72002-04-19 12:34:06 +00002540/*
drh91a66392007-09-07 01:12:32 +00002541** Return TRUE if a semicolon occurs anywhere in the first N characters
2542** of string z[].
drh324ccef2003-02-05 14:06:20 +00002543*/
drh91a66392007-09-07 01:12:32 +00002544static int _contains_semicolon(const char *z, int N){
2545 int i;
2546 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2547 return 0;
drh324ccef2003-02-05 14:06:20 +00002548}
2549
2550/*
drh70c7a4b2003-04-26 03:03:06 +00002551** Test to see if a line consists entirely of whitespace.
2552*/
2553static int _all_whitespace(const char *z){
2554 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002555 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002556 if( *z=='/' && z[1]=='*' ){
2557 z += 2;
2558 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2559 if( *z==0 ) return 0;
2560 z++;
2561 continue;
2562 }
2563 if( *z=='-' && z[1]=='-' ){
2564 z += 2;
2565 while( *z && *z!='\n' ){ z++; }
2566 if( *z==0 ) return 1;
2567 continue;
2568 }
2569 return 0;
2570 }
2571 return 1;
2572}
2573
2574/*
drha9b17162003-04-29 18:01:28 +00002575** Return TRUE if the line typed in is an SQL command terminator other
2576** than a semi-colon. The SQL Server style "go" command is understood
2577** as is the Oracle "/".
2578*/
2579static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002580 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002581 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2582 return 1; /* Oracle */
2583 }
drhf0693c82011-10-11 20:41:54 +00002584 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002585 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002586 return 1; /* SQL Server */
2587 }
2588 return 0;
2589}
2590
2591/*
drh233a5312008-12-18 22:25:13 +00002592** Return true if zSql is a complete SQL statement. Return false if it
2593** ends in the middle of a string literal or C-style comment.
2594*/
2595static int _is_complete(char *zSql, int nSql){
2596 int rc;
2597 if( zSql==0 ) return 1;
2598 zSql[nSql] = ';';
2599 zSql[nSql+1] = 0;
2600 rc = sqlite3_complete(zSql);
2601 zSql[nSql] = 0;
2602 return rc;
2603}
2604
2605/*
drh67505e72002-04-19 12:34:06 +00002606** Read input from *in and process it. If *in==0 then input
2607** is interactive - the user is typing it it. Otherwise, input
2608** is coming from a file or device. A prompt is issued and history
2609** is saved only if input is interactive. An interrupt signal will
2610** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002611**
2612** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002613*/
drhc28490c2006-10-26 14:25:58 +00002614static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002615 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002616 char *zSql = 0;
2617 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002618 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002619 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002620 int rc;
2621 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002622 int lineno = 0;
2623 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002624
2625 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2626 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002627 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002628 zLine = one_input_line(zSql, in);
2629 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002630 /* End of input */
2631 if( stdin_is_interactive ) printf("\n");
2632 break;
drhc49f44e2006-10-26 18:15:42 +00002633 }
drh67505e72002-04-19 12:34:06 +00002634 if( seenInterrupt ){
2635 if( in!=0 ) break;
2636 seenInterrupt = 0;
2637 }
drhc28490c2006-10-26 14:25:58 +00002638 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002639 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002640 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002641 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002642 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002643 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002644 break;
2645 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002646 errCnt++;
2647 }
drhdaffd0e2001-04-11 14:28:42 +00002648 continue;
2649 }
drh233a5312008-12-18 22:25:13 +00002650 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002651 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002652 }
drh91a66392007-09-07 01:12:32 +00002653 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002654 if( zSql==0 ){
2655 int i;
drhf0693c82011-10-11 20:41:54 +00002656 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002657 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002658 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002659 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002660 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002661 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002662 exit(1);
2663 }
drh5bb3eb92007-05-04 13:15:55 +00002664 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002665 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002666 }
2667 }else{
drh4f21c4a2008-12-10 22:15:00 +00002668 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002669 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002670 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002671 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002672 exit(1);
2673 }
drh5bb3eb92007-05-04 13:15:55 +00002674 zSql[nSql++] = '\n';
2675 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002676 nSql += len;
2677 }
drh91a66392007-09-07 01:12:32 +00002678 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2679 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002680 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002681 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002682 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002683 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002684 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002685 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002686 char zPrefix[100];
2687 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002688 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002689 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002690 }else{
shane9bd1b442009-10-23 01:27:39 +00002691 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002692 }
drh7f953e22002-07-13 17:33:45 +00002693 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002694 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002695 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002696 zErrMsg = 0;
2697 }else{
shaned2bed1c2009-10-21 03:56:54 +00002698 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002699 }
drhc49f44e2006-10-26 18:15:42 +00002700 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002701 }
2702 free(zSql);
2703 zSql = 0;
2704 nSql = 0;
2705 }
2706 }
2707 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002708 if( !_all_whitespace(zSql) ){
2709 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2710 }
drhdaffd0e2001-04-11 14:28:42 +00002711 free(zSql);
2712 }
danielk19772ac27622007-07-03 05:31:16 +00002713 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002714 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002715}
2716
drh67505e72002-04-19 12:34:06 +00002717/*
2718** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002719** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002720*/
2721static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002722 static char *home_dir = NULL;
2723 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002724
drh83905c92012-06-21 13:00:37 +00002725#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00002726 {
2727 struct passwd *pwent;
2728 uid_t uid = getuid();
2729 if( (pwent=getpwuid(uid)) != NULL) {
2730 home_dir = pwent->pw_dir;
2731 }
drh67505e72002-04-19 12:34:06 +00002732 }
2733#endif
2734
chw65d3c132007-11-12 21:09:10 +00002735#if defined(_WIN32_WCE)
2736 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2737 */
drh85e72432012-04-11 11:38:53 +00002738 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00002739#else
2740
drh83905c92012-06-21 13:00:37 +00002741#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00002742 if (!home_dir) {
2743 home_dir = getenv("USERPROFILE");
2744 }
2745#endif
2746
drh67505e72002-04-19 12:34:06 +00002747 if (!home_dir) {
2748 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002749 }
2750
drh83905c92012-06-21 13:00:37 +00002751#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00002752 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002753 char *zDrive, *zPath;
2754 int n;
2755 zDrive = getenv("HOMEDRIVE");
2756 zPath = getenv("HOMEPATH");
2757 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002758 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002759 home_dir = malloc( n );
2760 if( home_dir==0 ) return 0;
2761 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2762 return home_dir;
2763 }
2764 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002765 }
2766#endif
2767
chw65d3c132007-11-12 21:09:10 +00002768#endif /* !_WIN32_WCE */
2769
drh67505e72002-04-19 12:34:06 +00002770 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002771 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002772 char *z = malloc( n );
2773 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002774 home_dir = z;
2775 }
drhe98d4fa2002-04-21 19:06:22 +00002776
drh67505e72002-04-19 12:34:06 +00002777 return home_dir;
2778}
2779
2780/*
2781** Read input from the file given by sqliterc_override. Or if that
2782** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002783**
2784** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002785*/
shane9bd1b442009-10-23 01:27:39 +00002786static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002787 struct callback_data *p, /* Configuration data */
2788 const char *sqliterc_override /* Name of config file. NULL to use default */
2789){
persicom7e2dfdd2002-04-18 02:46:52 +00002790 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002791 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002792 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002793 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00002794 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002795
2796 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002797 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002798 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002799#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002800 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002801#endif
shane9bd1b442009-10-23 01:27:39 +00002802 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002803 }
drh2f3de322012-06-27 16:41:31 +00002804 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00002805 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
2806 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002807 }
drha1f9b5e2004-02-14 16:31:02 +00002808 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002809 if( in ){
drhc28490c2006-10-26 14:25:58 +00002810 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002811 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002812 }
shane9bd1b442009-10-23 01:27:39 +00002813 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002814 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002815 }
drh85e72432012-04-11 11:38:53 +00002816 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002817 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002818}
2819
drh67505e72002-04-19 12:34:06 +00002820/*
drhe1e38c42003-05-04 18:30:59 +00002821** Show available command line options
2822*/
2823static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00002824 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00002825 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002826 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00002827 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00002828 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00002829 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00002830 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00002831 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00002832#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2833 " -heap SIZE Size of heap for memsys3 or memsys5\n"
2834#endif
drhcc3b4f82012-02-07 14:13:50 +00002835 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002836 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00002837 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002838 " -line set output mode to 'line'\n"
2839 " -list set output mode to 'list'\n"
drhcc3b4f82012-02-07 14:13:50 +00002840#ifdef SQLITE_ENABLE_MULTIPLEX
2841 " -multiplex enable the multiplexor VFS\n"
2842#endif
drh98d312f2012-10-25 15:23:14 +00002843 " -nullvalue TEXT set text string for NULL values. Default ''\n"
2844 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00002845 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002846 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002847 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00002848#ifdef SQLITE_ENABLE_VFSTRACE
2849 " -vfstrace enable tracing of all VFS calls\n"
2850#endif
drhe1e38c42003-05-04 18:30:59 +00002851;
2852static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002853 fprintf(stderr,
2854 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2855 "FILENAME is the name of an SQLite database. A new database is created\n"
2856 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002857 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002858 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002859 }else{
2860 fprintf(stderr, "Use the -help option for additional information\n");
2861 }
2862 exit(1);
2863}
2864
2865/*
drh67505e72002-04-19 12:34:06 +00002866** Initialize the state information in data
2867*/
drh0850b532006-01-31 19:31:43 +00002868static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002869 memset(data, 0, sizeof(*data));
2870 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002871 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002872 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00002873 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00002874 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002875 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2876 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002877 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002878}
2879
drh98d312f2012-10-25 15:23:14 +00002880/*
2881** Get the argument to an --option. Throw an error and die if no argument
2882** is available.
2883*/
2884static char *cmdline_option_value(int argc, char **argv, int i){
2885 if( i==argc ){
2886 fprintf(stderr, "%s: Error: missing argument to %s\n",
2887 argv[0], argv[argc-1]);
2888 exit(1);
2889 }
2890 return argv[i];
2891}
2892
drh75897232000-05-29 14:26:00 +00002893int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002894 char *zErrMsg = 0;
2895 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002896 const char *zInitFile = 0;
2897 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002898 int i;
drhc28490c2006-10-26 14:25:58 +00002899 int rc = 0;
drh75897232000-05-29 14:26:00 +00002900
drh52784bd2011-05-18 17:15:06 +00002901 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
2902 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
2903 sqlite3_sourceid(), SQLITE_SOURCE_ID);
2904 exit(1);
2905 }
drhdaffd0e2001-04-11 14:28:42 +00002906 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002907 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002908 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002909
drh44c2eb12003-04-30 11:38:26 +00002910 /* Make sure we have a valid signal handler early, before anything
2911 ** else is done.
2912 */
drh4c504392000-10-16 22:06:40 +00002913#ifdef SIGINT
2914 signal(SIGINT, interrupt_handler);
2915#endif
drh44c2eb12003-04-30 11:38:26 +00002916
drh22fbcb82004-02-01 01:22:50 +00002917 /* Do an initial pass through the command-line argument to locate
2918 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002919 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002920 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002921 */
drh98d312f2012-10-25 15:23:14 +00002922 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00002923 char *z;
drhc28490c2006-10-26 14:25:58 +00002924 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00002925 if( z[0]!='-' ){
2926 if( data.zDbFilename==0 ){
2927 data.zDbFilename = z;
2928 continue;
2929 }
2930 if( zFirstCmd==0 ){
2931 zFirstCmd = z;
2932 continue;
2933 }
2934 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2935 fprintf(stderr,"Use -help for a list of options.\n");
2936 return 1;
2937 }
drhcc3b4f82012-02-07 14:13:50 +00002938 if( z[1]=='-' ) z++;
2939 if( strcmp(z,"-separator")==0
2940 || strcmp(z,"-nullvalue")==0
2941 || strcmp(z,"-cmd")==0
2942 ){
drh98d312f2012-10-25 15:23:14 +00002943 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00002944 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00002945 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00002946 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00002947 /* Need to check for batch mode here to so we can avoid printing
2948 ** informational messages (like from process_sqliterc) before
2949 ** we do the actual processing of arguments later in a second pass.
2950 */
shanef69573d2009-10-24 02:06:14 +00002951 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00002952 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00002953#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00002954 int j, c;
2955 const char *zSize;
2956 sqlite3_int64 szHeap;
2957
drh98d312f2012-10-25 15:23:14 +00002958 zSize = cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00002959 szHeap = atoi(zSize);
2960 for(j=0; (c = zSize[j])!=0; j++){
2961 if( c=='M' ){ szHeap *= 1000000; break; }
2962 if( c=='K' ){ szHeap *= 1000; break; }
2963 if( c=='G' ){ szHeap *= 1000000000; break; }
2964 }
2965 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00002966 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2967#endif
drh97ae8ff2011-03-16 16:56:29 +00002968#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00002969 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00002970 extern int vfstrace_register(
2971 const char *zTraceName,
2972 const char *zOldVfsName,
2973 int (*xOut)(const char*,void*),
2974 void *pOutArg,
2975 int makeDefault
2976 );
drh2b625e22011-03-16 17:05:28 +00002977 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00002978#endif
drh6f25e892011-07-08 17:02:57 +00002979#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00002980 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00002981 extern int sqlite3_multiple_initialize(const char*,int);
2982 sqlite3_multiplex_initialize(0, 1);
2983#endif
drhcc3b4f82012-02-07 14:13:50 +00002984 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00002985 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00002986 if( pVfs ){
2987 sqlite3_vfs_register(pVfs, 1);
2988 }else{
2989 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
2990 exit(1);
2991 }
drh44c2eb12003-04-30 11:38:26 +00002992 }
2993 }
drh98d312f2012-10-25 15:23:14 +00002994 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00002995#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002996 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002997#else
shane86f5bdb2009-10-24 02:00:07 +00002998 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2999 return 1;
drh01b41712005-08-29 23:06:23 +00003000#endif
drh98d312f2012-10-25 15:23:14 +00003001 }
3002 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00003003
drh44c2eb12003-04-30 11:38:26 +00003004 /* Go ahead and open the database file if it already exists. If the
3005 ** file does not exist, delay opening it. This prevents empty database
3006 ** files from being created if a user mistypes the database name argument
3007 ** to the sqlite command-line tool.
3008 */
drhc8d74412004-08-31 23:41:26 +00003009 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003010 open_db(&data);
3011 }
3012
drh22fbcb82004-02-01 01:22:50 +00003013 /* Process the initialization file if there is one. If no -init option
3014 ** is given on the command line, look for a file named ~/.sqliterc and
3015 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003016 */
shane86f5bdb2009-10-24 02:00:07 +00003017 rc = process_sqliterc(&data,zInitFile);
3018 if( rc>0 ){
3019 return rc;
3020 }
drh44c2eb12003-04-30 11:38:26 +00003021
drh22fbcb82004-02-01 01:22:50 +00003022 /* Make a second pass through the command-line argument and set
3023 ** options. This second pass is delayed until after the initialization
3024 ** file is processed so that the command-line arguments will override
3025 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003026 */
drh98d312f2012-10-25 15:23:14 +00003027 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00003028 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003029 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00003030 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003031 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003032 i++;
3033 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003034 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003035 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003036 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003037 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003038 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003039 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003040 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003041 }else if( strcmp(z,"-csv")==0 ){
3042 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003043 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003044 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003045 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00003046 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003047 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003048 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00003049 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003050 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003051 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003052 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003053 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003054 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003055 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003056 }else if( strcmp(z,"-stats")==0 ){
3057 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003058 }else if( strcmp(z,"-bail")==0 ){
3059 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003060 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003061 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003062 return 0;
drhc28490c2006-10-26 14:25:58 +00003063 }else if( strcmp(z,"-interactive")==0 ){
3064 stdin_is_interactive = 1;
3065 }else if( strcmp(z,"-batch")==0 ){
3066 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003067 }else if( strcmp(z,"-heap")==0 ){
3068 i++;
drha7e61d82011-03-12 17:02:57 +00003069 }else if( strcmp(z,"-vfs")==0 ){
3070 i++;
drh6f25e892011-07-08 17:02:57 +00003071#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003072 }else if( strcmp(z,"-vfstrace")==0 ){
3073 i++;
drh6f25e892011-07-08 17:02:57 +00003074#endif
3075#ifdef SQLITE_ENABLE_MULTIPLEX
3076 }else if( strcmp(z,"-multiplex")==0 ){
3077 i++;
3078#endif
drhcc3b4f82012-02-07 14:13:50 +00003079 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003080 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003081 }else if( strcmp(z,"-cmd")==0 ){
3082 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00003083 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00003084 if( z[0]=='.' ){
3085 rc = do_meta_command(z, &data);
3086 if( rc && bail_on_error ) return rc;
3087 }else{
3088 open_db(&data);
3089 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3090 if( zErrMsg!=0 ){
3091 fprintf(stderr,"Error: %s\n", zErrMsg);
3092 if( bail_on_error ) return rc!=0 ? rc : 1;
3093 }else if( rc!=0 ){
3094 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3095 if( bail_on_error ) return rc;
3096 }
3097 }
drh1e5d0e92000-05-31 23:33:17 +00003098 }else{
shane86f5bdb2009-10-24 02:00:07 +00003099 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003100 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003101 return 1;
3102 }
3103 }
drh44c2eb12003-04-30 11:38:26 +00003104
drh22fbcb82004-02-01 01:22:50 +00003105 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003106 /* Run just the command that follows the database name
3107 */
drh22fbcb82004-02-01 01:22:50 +00003108 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003109 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003110 }else{
drh44c2eb12003-04-30 11:38:26 +00003111 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003112 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003113 if( zErrMsg!=0 ){
3114 fprintf(stderr,"Error: %s\n", zErrMsg);
3115 return rc!=0 ? rc : 1;
3116 }else if( rc!=0 ){
3117 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3118 return rc;
drh6ff13852001-11-25 13:18:23 +00003119 }
drh75897232000-05-29 14:26:00 +00003120 }
3121 }else{
drh44c2eb12003-04-30 11:38:26 +00003122 /* Run commands received from standard input
3123 */
drhc28490c2006-10-26 14:25:58 +00003124 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003125 char *zHome;
3126 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003127 int nHistory;
drh75897232000-05-29 14:26:00 +00003128 printf(
drh743e0032011-12-12 16:51:50 +00003129 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003130 "Enter \".help\" for instructions\n"
3131 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003132 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003133 );
drh67505e72002-04-19 12:34:06 +00003134 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003135 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003136 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003137 if( (zHistory = malloc(nHistory))!=0 ){
3138 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3139 }
drh67505e72002-04-19 12:34:06 +00003140 }
danielk19774af00c62005-01-23 23:43:21 +00003141#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003142 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003143#endif
drhc28490c2006-10-26 14:25:58 +00003144 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003145 if( zHistory ){
3146 stifle_history(100);
3147 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003148 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003149 }
drhdaffd0e2001-04-11 14:28:42 +00003150 }else{
drhc28490c2006-10-26 14:25:58 +00003151 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003152 }
3153 }
drh33048c02001-10-01 14:29:22 +00003154 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003155 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003156 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003157 }
drhc28490c2006-10-26 14:25:58 +00003158 return rc;
drh75897232000-05-29 14:26:00 +00003159}