blob: 7b8a8ad7f305b2bdbbcb921b1938843440b4ba92 [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
drh53371f92013-07-25 17:07:03 +000068#define popen _popen
drh67ceaa62012-08-27 21:19:03 +000069#undef pclose
drh12cd6cf2013-06-29 15:40:22 +000070#define pclose _pclose
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
drh53371f92013-07-25 17:07:03 +000077/* popen and pclose are not C89 functions and so are sometimes omitted from
78** the <stdio.h> header */
79FILE *popen(const char*,const char*);
80int pclose(FILE*);
81
chw65d3c132007-11-12 21:09:10 +000082#if defined(_WIN32_WCE)
83/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
84 * thus we always assume that we have a console. That can be
85 * overridden with the -batch command line option.
86 */
87#define isatty(x) 1
88#endif
89
drhc6e41722011-04-11 15:36:26 +000090/* True if the timer is enabled */
91static int enableTimer = 0;
92
drhf0693c82011-10-11 20:41:54 +000093/* ctype macros that work with signed characters */
94#define IsSpace(X) isspace((unsigned char)X)
95#define IsDigit(X) isdigit((unsigned char)X)
96#define ToLower(X) (char)tolower((unsigned char)X)
97
drhd5d0f642013-02-20 00:54:21 +000098#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
99 && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000100#include <sys/time.h>
101#include <sys/resource.h>
102
drhda108222009-02-25 19:07:24 +0000103/* Saved resource information for the beginning of an operation */
104static struct rusage sBegin;
105
drhda108222009-02-25 19:07:24 +0000106/*
107** Begin timing an operation
108*/
109static void beginTimer(void){
110 if( enableTimer ){
111 getrusage(RUSAGE_SELF, &sBegin);
112 }
113}
114
115/* Return the difference of two time_structs in seconds */
116static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
117 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
118 (double)(pEnd->tv_sec - pStart->tv_sec);
119}
120
121/*
122** Print the timing results.
123*/
124static void endTimer(void){
125 if( enableTimer ){
126 struct rusage sEnd;
127 getrusage(RUSAGE_SELF, &sEnd);
128 printf("CPU Time: user %f sys %f\n",
129 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
130 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
131 }
132}
shaneb320ccd2009-10-21 03:42:58 +0000133
drhda108222009-02-25 19:07:24 +0000134#define BEGIN_TIMER beginTimer()
135#define END_TIMER endTimer()
136#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000137
138#elif (defined(_WIN32) || defined(WIN32))
139
140#include <windows.h>
141
142/* Saved resource information for the beginning of an operation */
143static HANDLE hProcess;
144static FILETIME ftKernelBegin;
145static FILETIME ftUserBegin;
146typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
147static GETPROCTIMES getProcessTimesAddr = NULL;
148
shaneb320ccd2009-10-21 03:42:58 +0000149/*
150** Check to see if we have timer support. Return 1 if necessary
151** support found (or found previously).
152*/
153static int hasTimer(void){
154 if( getProcessTimesAddr ){
155 return 1;
156 } else {
157 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
158 ** See if the version we are running on has it, and if it does, save off
159 ** a pointer to it and the current process handle.
160 */
161 hProcess = GetCurrentProcess();
162 if( hProcess ){
163 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
164 if( NULL != hinstLib ){
165 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
166 if( NULL != getProcessTimesAddr ){
167 return 1;
168 }
169 FreeLibrary(hinstLib);
170 }
171 }
172 }
173 return 0;
174}
175
176/*
177** Begin timing an operation
178*/
179static void beginTimer(void){
180 if( enableTimer && getProcessTimesAddr ){
181 FILETIME ftCreation, ftExit;
182 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
183 }
184}
185
186/* Return the difference of two FILETIME structs in seconds */
187static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
188 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
189 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
190 return (double) ((i64End - i64Start) / 10000000.0);
191}
192
193/*
194** Print the timing results.
195*/
196static void endTimer(void){
197 if( enableTimer && getProcessTimesAddr){
198 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
199 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
200 printf("CPU Time: user %f sys %f\n",
201 timeDiff(&ftUserBegin, &ftUserEnd),
202 timeDiff(&ftKernelBegin, &ftKernelEnd));
203 }
204}
205
206#define BEGIN_TIMER beginTimer()
207#define END_TIMER endTimer()
208#define HAS_TIMER hasTimer()
209
drhda108222009-02-25 19:07:24 +0000210#else
211#define BEGIN_TIMER
212#define END_TIMER
213#define HAS_TIMER 0
214#endif
215
shanec0688ea2009-03-05 03:48:06 +0000216/*
217** Used to prevent warnings about unused parameters
218*/
219#define UNUSED_PARAMETER(x) (void)(x)
220
drhe91d16b2008-12-08 18:27:31 +0000221/*
drhc49f44e2006-10-26 18:15:42 +0000222** If the following flag is set, then command execution stops
223** at an error if we are not interactive.
224*/
225static int bail_on_error = 0;
226
227/*
drhc28490c2006-10-26 14:25:58 +0000228** Threat stdin as an interactive input if the following variable
229** is true. Otherwise, assume stdin is connected to a file or pipe.
230*/
231static int stdin_is_interactive = 1;
232
233/*
drh4c504392000-10-16 22:06:40 +0000234** The following is the open SQLite database. We make a pointer
235** to this database a static variable so that it can be accessed
236** by the SIGINT handler to interrupt database processing.
237*/
danielk197792f9a1b2004-06-19 09:08:16 +0000238static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000239
240/*
drh67505e72002-04-19 12:34:06 +0000241** True if an interrupt (Control-C) has been received.
242*/
drh43617e92006-03-06 20:55:46 +0000243static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000244
245/*
persicom7e2dfdd2002-04-18 02:46:52 +0000246** This is the name of our program. It is set in main(), used
247** in a number of other places, mostly for error messages.
248*/
249static char *Argv0;
250
251/*
252** Prompt strings. Initialized in main. Settable with
253** .prompt main continue
254*/
255static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
256static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
257
drhb0603412007-02-28 04:47:26 +0000258/*
259** Write I/O traces to the following stream.
260*/
rsebe0a9092007-07-30 18:24:38 +0000261#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000262static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000263#endif
drhb0603412007-02-28 04:47:26 +0000264
265/*
266** This routine works like printf in that its first argument is a
267** format string and subsequent arguments are values to be substituted
268** in place of % fields. The result of formatting this string
269** is written to iotrace.
270*/
rsebe0a9092007-07-30 18:24:38 +0000271#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000272static void iotracePrintf(const char *zFormat, ...){
273 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000274 char *z;
drhb0603412007-02-28 04:47:26 +0000275 if( iotrace==0 ) return;
276 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000277 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000278 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000279 fprintf(iotrace, "%s", z);
280 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000281}
rsebe0a9092007-07-30 18:24:38 +0000282#endif
drhb0603412007-02-28 04:47:26 +0000283
drh44c2eb12003-04-30 11:38:26 +0000284
persicom7e2dfdd2002-04-18 02:46:52 +0000285/*
drh83965662003-04-17 02:54:13 +0000286** Determines if a string is a number of not.
287*/
danielk19772e588c72005-12-09 14:25:08 +0000288static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000289 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000290 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000291 return 0;
292 }
293 z++;
294 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000295 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000296 if( *z=='.' ){
297 z++;
drhf0693c82011-10-11 20:41:54 +0000298 if( !IsDigit(*z) ) return 0;
299 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000300 if( realnum ) *realnum = 1;
301 }
302 if( *z=='e' || *z=='E' ){
303 z++;
304 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000305 if( !IsDigit(*z) ) return 0;
306 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000307 if( realnum ) *realnum = 1;
308 }
309 return *z==0;
310}
drh83965662003-04-17 02:54:13 +0000311
312/*
danielk1977bc6ada42004-06-30 08:20:16 +0000313** A global char* and an SQL function to access its current value
314** from within an SQL statement. This program used to use the
315** sqlite_exec_printf() API to substitue a string into an SQL statement.
316** The correct way to do this with sqlite3 is to use the bind API, but
317** since the shell is built around the callback paradigm it would be a lot
318** of work. Instead just use this hack, which is quite harmless.
319*/
320static const char *zShellStatic = 0;
321static void shellstaticFunc(
322 sqlite3_context *context,
323 int argc,
324 sqlite3_value **argv
325){
326 assert( 0==argc );
327 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000328 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000329 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000330 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
331}
332
333
334/*
drhfeac5f82004-08-01 00:10:45 +0000335** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000336** the text in memory obtained from malloc() and returns a pointer
337** to the text. NULL is returned at end of file, or if malloc()
338** fails.
339**
340** The interface is like "readline" but no command-line editing
341** is done.
342*/
drh18f52e02012-01-16 16:56:31 +0000343static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
drh8e7e7a22000-05-30 18:45:23 +0000344 char *zLine;
345 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000346 int n;
drh18f52e02012-01-16 16:56:31 +0000347 int inQuote = 0;
drh8e7e7a22000-05-30 18:45:23 +0000348
349 if( zPrompt && *zPrompt ){
350 printf("%s",zPrompt);
351 fflush(stdout);
352 }
353 nLine = 100;
354 zLine = malloc( nLine );
355 if( zLine==0 ) return 0;
356 n = 0;
drhb07028f2011-10-14 21:49:18 +0000357 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000358 if( n+100>nLine ){
359 nLine = nLine*2 + 100;
360 zLine = realloc(zLine, nLine);
361 if( zLine==0 ) return 0;
362 }
drhdaffd0e2001-04-11 14:28:42 +0000363 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000364 if( n==0 ){
365 free(zLine);
366 return 0;
367 }
368 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000369 break;
370 }
drh18f52e02012-01-16 16:56:31 +0000371 while( zLine[n] ){
372 if( zLine[n]=='"' ) inQuote = !inQuote;
373 n++;
374 }
375 if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
drh8e7e7a22000-05-30 18:45:23 +0000376 n--;
shaneh13b36022009-12-17 21:07:15 +0000377 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000378 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000379 break;
drh8e7e7a22000-05-30 18:45:23 +0000380 }
381 }
382 zLine = realloc( zLine, n+1 );
383 return zLine;
384}
385
386/*
drhc28490c2006-10-26 14:25:58 +0000387** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000388**
389** zPrior is a string of prior text retrieved. If not the empty
390** string, then issue a continuation prompt.
391*/
drhdaffd0e2001-04-11 14:28:42 +0000392static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000393 char *zPrompt;
394 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000395 if( in!=0 ){
drh18f52e02012-01-16 16:56:31 +0000396 return local_getline(0, in, 0);
drh8e7e7a22000-05-30 18:45:23 +0000397 }
398 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000399 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000400 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000401 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000402 }
403 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000404#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000405 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000406#endif
drh8e7e7a22000-05-30 18:45:23 +0000407 return zResult;
408}
409
persicom7e2dfdd2002-04-18 02:46:52 +0000410struct previous_mode_data {
411 int valid; /* Is there legit data in here? */
412 int mode;
413 int showHeader;
414 int colWidth[100];
415};
drh45e29d82006-11-20 16:21:10 +0000416
drh8e7e7a22000-05-30 18:45:23 +0000417/*
drh75897232000-05-29 14:26:00 +0000418** An pointer to an instance of this structure is passed from
419** the main program to the callback. This is used to communicate
420** state and mode information.
421*/
422struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000423 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000424 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000425 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000426 int cnt; /* Number of records displayed so far */
427 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000428 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000429 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000430 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000431 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000432 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000433 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000434 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000435 int colWidth[100]; /* Requested width of each column when in column mode*/
436 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000437 char nullvalue[20]; /* The text to print when a NULL comes back from
438 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000439 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000440 /* Holds the mode information just before
441 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000442 char outfile[FILENAME_MAX]; /* Filename for *out */
443 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000444 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000445 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000446 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000447};
448
449/*
450** These are the allowed modes.
451*/
drh967e8b72000-06-21 13:59:10 +0000452#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000453#define MODE_Column 1 /* One record per line in neat columns */
454#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000455#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
456#define MODE_Html 4 /* Generate an XHTML table */
457#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000458#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000459#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000460#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000461
drh66ce4d02008-02-15 17:38:06 +0000462static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000463 "line",
464 "column",
465 "list",
466 "semi",
467 "html",
drhfeac5f82004-08-01 00:10:45 +0000468 "insert",
469 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000470 "csv",
drh66ce4d02008-02-15 17:38:06 +0000471 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000472};
drh75897232000-05-29 14:26:00 +0000473
474/*
475** Number of elements in an array
476*/
drh902b9ee2008-12-05 17:17:07 +0000477#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000478
479/*
drhea678832008-12-10 19:26:22 +0000480** Compute a string length that is limited to what can be stored in
481** lower 30 bits of a 32-bit signed integer.
482*/
drh4f21c4a2008-12-10 22:15:00 +0000483static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000484 const char *z2 = z;
485 while( *z2 ){ z2++; }
486 return 0x3fffffff & (int)(z2 - z);
487}
488
489/*
drh127f9d72010-02-23 01:47:00 +0000490** A callback for the sqlite3_log() interface.
491*/
492static void shellLog(void *pArg, int iErrCode, const char *zMsg){
493 struct callback_data *p = (struct callback_data*)pArg;
494 if( p->pLog==0 ) return;
495 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
496 fflush(p->pLog);
497}
498
499/*
shane626a6e42009-10-22 17:30:15 +0000500** Output the given string as a hex-encoded blob (eg. X'1234' )
501*/
502static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
503 int i;
504 char *zBlob = (char *)pBlob;
505 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000506 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000507 fprintf(out,"'");
508}
509
510/*
drh28bd4bc2000-06-15 15:57:22 +0000511** Output the given string as a quoted string using SQL quoting conventions.
512*/
513static void output_quoted_string(FILE *out, const char *z){
514 int i;
515 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000516 for(i=0; z[i]; i++){
517 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000518 }
519 if( nSingle==0 ){
520 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000521 }else{
522 fprintf(out,"'");
523 while( *z ){
524 for(i=0; z[i] && z[i]!='\''; i++){}
525 if( i==0 ){
526 fprintf(out,"''");
527 z++;
528 }else if( z[i]=='\'' ){
529 fprintf(out,"%.*s''",i,z);
530 z += i+1;
531 }else{
drhcd7d2732002-02-26 23:24:26 +0000532 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000533 break;
534 }
535 }
drhcd7d2732002-02-26 23:24:26 +0000536 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000537 }
538}
539
540/*
drhfeac5f82004-08-01 00:10:45 +0000541** Output the given string as a quoted according to C or TCL quoting rules.
542*/
543static void output_c_string(FILE *out, const char *z){
544 unsigned int c;
545 fputc('"', out);
546 while( (c = *(z++))!=0 ){
547 if( c=='\\' ){
548 fputc(c, out);
549 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000550 }else if( c=='"' ){
551 fputc('\\', out);
552 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000553 }else if( c=='\t' ){
554 fputc('\\', out);
555 fputc('t', out);
556 }else if( c=='\n' ){
557 fputc('\\', out);
558 fputc('n', out);
559 }else if( c=='\r' ){
560 fputc('\\', out);
561 fputc('r', out);
562 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000563 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000564 }else{
565 fputc(c, out);
566 }
567 }
568 fputc('"', out);
569}
570
571/*
drhc08a4f12000-06-15 16:49:48 +0000572** Output the given string with characters that are special to
573** HTML escaped.
574*/
575static void output_html_string(FILE *out, const char *z){
576 int i;
577 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000578 for(i=0; z[i]
579 && z[i]!='<'
580 && z[i]!='&'
581 && z[i]!='>'
582 && z[i]!='\"'
583 && z[i]!='\'';
584 i++){}
drhc08a4f12000-06-15 16:49:48 +0000585 if( i>0 ){
586 fprintf(out,"%.*s",i,z);
587 }
588 if( z[i]=='<' ){
589 fprintf(out,"&lt;");
590 }else if( z[i]=='&' ){
591 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000592 }else if( z[i]=='>' ){
593 fprintf(out,"&gt;");
594 }else if( z[i]=='\"' ){
595 fprintf(out,"&quot;");
596 }else if( z[i]=='\'' ){
597 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000598 }else{
599 break;
600 }
601 z += i + 1;
602 }
603}
604
605/*
drhc49f44e2006-10-26 18:15:42 +0000606** If a field contains any character identified by a 1 in the following
607** array, then the string must be quoted for CSV.
608*/
609static const char needCsvQuote[] = {
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, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
613 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
614 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
615 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
616 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
617 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
618 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
619 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
620 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
621 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
622 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
623 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
624 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
625 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
626};
627
628/*
drh8e64d1c2004-10-07 00:32:39 +0000629** Output a single term of CSV. Actually, p->separator is used for
630** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000631** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000632*/
633static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000634 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000635 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000636 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000637 }else{
drhc49f44e2006-10-26 18:15:42 +0000638 int i;
drh4f21c4a2008-12-10 22:15:00 +0000639 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000640 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000641 if( needCsvQuote[((unsigned char*)z)[i]]
642 || (z[i]==p->separator[0] &&
643 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000644 i = 0;
645 break;
646 }
647 }
648 if( i==0 ){
649 putc('"', out);
650 for(i=0; z[i]; i++){
651 if( z[i]=='"' ) putc('"', out);
652 putc(z[i], out);
653 }
654 putc('"', out);
655 }else{
656 fprintf(out, "%s", z);
657 }
drh8e64d1c2004-10-07 00:32:39 +0000658 }
659 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000660 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000661 }
662}
663
danielk19774af00c62005-01-23 23:43:21 +0000664#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000665/*
drh4c504392000-10-16 22:06:40 +0000666** This routine runs when the user presses Ctrl-C
667*/
668static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000669 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000670 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000671 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000672}
danielk19774af00c62005-01-23 23:43:21 +0000673#endif
drh4c504392000-10-16 22:06:40 +0000674
675/*
shane626a6e42009-10-22 17:30:15 +0000676** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000677** invokes for each row of a query result.
678*/
shane626a6e42009-10-22 17:30:15 +0000679static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000680 int i;
681 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000682
drh75897232000-05-29 14:26:00 +0000683 switch( p->mode ){
684 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000685 int w = 5;
drh6a535342001-10-19 16:44:56 +0000686 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000687 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000688 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000689 if( len>w ) w = len;
690 }
drh75897232000-05-29 14:26:00 +0000691 if( p->cnt++>0 ) fprintf(p->out,"\n");
692 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000693 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000694 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000695 }
696 break;
697 }
danielk19770d78bae2008-01-03 07:09:48 +0000698 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000699 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000700 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000701 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000702 int w, n;
703 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000704 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000705 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000706 w = 0;
drh75897232000-05-29 14:26:00 +0000707 }
drh078b1fd2012-09-21 13:40:02 +0000708 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000709 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000710 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000711 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000712 if( w<n ) w = n;
713 }
714 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000715 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000716 }
717 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000718 if( w<0 ){
719 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
720 }else{
721 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
722 }
drha0c66f52000-07-29 13:20:21 +0000723 }
724 }
725 if( p->showHeader ){
726 for(i=0; i<nArg; i++){
727 int w;
728 if( i<ArraySize(p->actualWidth) ){
729 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000730 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000731 }else{
732 w = 10;
733 }
734 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
735 "----------------------------------------------------------",
736 i==nArg-1 ? "\n": " ");
737 }
drh75897232000-05-29 14:26:00 +0000738 }
739 }
drh6a535342001-10-19 16:44:56 +0000740 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000741 for(i=0; i<nArg; i++){
742 int w;
drha0c66f52000-07-29 13:20:21 +0000743 if( i<ArraySize(p->actualWidth) ){
744 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000745 }else{
746 w = 10;
747 }
drhea678832008-12-10 19:26:22 +0000748 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000749 strlen30(azArg[i])>w ){
750 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000751 }
drh078b1fd2012-09-21 13:40:02 +0000752 if( w<0 ){
753 fprintf(p->out,"%*.*s%s",-w,-w,
754 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
755 }else{
756 fprintf(p->out,"%-*.*s%s",w,w,
757 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
758 }
drh75897232000-05-29 14:26:00 +0000759 }
760 break;
761 }
drhe3710332000-09-29 13:30:53 +0000762 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000763 case MODE_List: {
764 if( p->cnt++==0 && p->showHeader ){
765 for(i=0; i<nArg; i++){
766 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
767 }
768 }
drh6a535342001-10-19 16:44:56 +0000769 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000770 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000771 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000772 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000773 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000774 if( i<nArg-1 ){
775 fprintf(p->out, "%s", p->separator);
776 }else if( p->mode==MODE_Semi ){
777 fprintf(p->out, ";\n");
778 }else{
779 fprintf(p->out, "\n");
780 }
drh75897232000-05-29 14:26:00 +0000781 }
782 break;
783 }
drh1e5d0e92000-05-31 23:33:17 +0000784 case MODE_Html: {
785 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000786 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000787 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000788 fprintf(p->out,"<TH>");
789 output_html_string(p->out, azCol[i]);
790 fprintf(p->out,"</TH>\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 }
drh6a535342001-10-19 16:44:56 +0000794 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000795 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000796 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000797 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000798 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000799 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000800 }
mihailim57c591a2008-06-23 21:26:05 +0000801 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000802 break;
803 }
drhfeac5f82004-08-01 00:10:45 +0000804 case MODE_Tcl: {
805 if( p->cnt++==0 && p->showHeader ){
806 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000807 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin585dcb22012-12-04 00:23:43 +0000808 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000809 }
810 fprintf(p->out,"\n");
811 }
812 if( azArg==0 ) break;
813 for(i=0; i<nArg; i++){
814 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mistachkin585dcb22012-12-04 00:23:43 +0000815 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000816 }
817 fprintf(p->out,"\n");
818 break;
819 }
drh8e64d1c2004-10-07 00:32:39 +0000820 case MODE_Csv: {
821 if( p->cnt++==0 && p->showHeader ){
822 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000823 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000824 }
825 fprintf(p->out,"\n");
826 }
827 if( azArg==0 ) break;
828 for(i=0; i<nArg; i++){
829 output_csv(p, azArg[i], i<nArg-1);
830 }
831 fprintf(p->out,"\n");
832 break;
833 }
drh28bd4bc2000-06-15 15:57:22 +0000834 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000835 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000836 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000837 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000838 for(i=0; i<nArg; i++){
839 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000840 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000841 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000842 }else if( aiType && aiType[i]==SQLITE_TEXT ){
843 if( zSep[0] ) fprintf(p->out,"%s",zSep);
844 output_quoted_string(p->out, azArg[i]);
845 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
846 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000847 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
848 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
849 int nBlob = sqlite3_column_bytes(p->pStmt, i);
850 if( zSep[0] ) fprintf(p->out,"%s",zSep);
851 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000852 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000853 fprintf(p->out,"%s%s",zSep, azArg[i]);
854 }else{
855 if( zSep[0] ) fprintf(p->out,"%s",zSep);
856 output_quoted_string(p->out, azArg[i]);
857 }
858 }
859 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000860 break;
drh28bd4bc2000-06-15 15:57:22 +0000861 }
persicom1d0b8722002-04-18 02:53:04 +0000862 }
drh75897232000-05-29 14:26:00 +0000863 return 0;
864}
865
866/*
shane626a6e42009-10-22 17:30:15 +0000867** This is the callback routine that the SQLite library
868** invokes for each row of a query result.
869*/
870static int callback(void *pArg, int nArg, char **azArg, char **azCol){
871 /* since we don't have type info, call the shell_callback with a NULL value */
872 return shell_callback(pArg, nArg, azArg, azCol, NULL);
873}
874
875/*
drh33048c02001-10-01 14:29:22 +0000876** Set the destination table field of the callback_data structure to
877** the name of the table given. Escape any quote characters in the
878** table name.
879*/
880static void set_table_name(struct callback_data *p, const char *zName){
881 int i, n;
882 int needQuote;
883 char *z;
884
885 if( p->zDestTable ){
886 free(p->zDestTable);
887 p->zDestTable = 0;
888 }
889 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000890 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000891 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000892 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000893 needQuote = 1;
894 if( zName[i]=='\'' ) n++;
895 }
896 }
897 if( needQuote ) n += 2;
898 z = p->zDestTable = malloc( n+1 );
899 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000900 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000901 exit(1);
902 }
903 n = 0;
904 if( needQuote ) z[n++] = '\'';
905 for(i=0; zName[i]; i++){
906 z[n++] = zName[i];
907 if( zName[i]=='\'' ) z[n++] = '\'';
908 }
909 if( needQuote ) z[n++] = '\'';
910 z[n] = 0;
911}
912
danielk19772a02e332004-06-05 08:04:36 +0000913/* zIn is either a pointer to a NULL-terminated string in memory obtained
914** from malloc(), or a NULL pointer. The string pointed to by zAppend is
915** added to zIn, and the result returned in memory obtained from malloc().
916** zIn, if it was not NULL, is freed.
917**
918** If the third argument, quote, is not '\0', then it is used as a
919** quote character for zAppend.
920*/
drhc28490c2006-10-26 14:25:58 +0000921static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000922 int len;
923 int i;
drh4f21c4a2008-12-10 22:15:00 +0000924 int nAppend = strlen30(zAppend);
925 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000926
927 len = nAppend+nIn+1;
928 if( quote ){
929 len += 2;
930 for(i=0; i<nAppend; i++){
931 if( zAppend[i]==quote ) len++;
932 }
933 }
934
935 zIn = (char *)realloc(zIn, len);
936 if( !zIn ){
937 return 0;
938 }
939
940 if( quote ){
941 char *zCsr = &zIn[nIn];
942 *zCsr++ = quote;
943 for(i=0; i<nAppend; i++){
944 *zCsr++ = zAppend[i];
945 if( zAppend[i]==quote ) *zCsr++ = quote;
946 }
947 *zCsr++ = quote;
948 *zCsr++ = '\0';
949 assert( (zCsr-zIn)==len );
950 }else{
951 memcpy(&zIn[nIn], zAppend, nAppend);
952 zIn[len-1] = '\0';
953 }
954
955 return zIn;
956}
957
drhdd3d4592004-08-30 01:54:05 +0000958
959/*
drhb21a8e42012-01-28 21:08:51 +0000960** Execute a query statement that will generate SQL output. Print
961** the result columns, comma-separated, on a line and then add a
962** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000963**
drhb21a8e42012-01-28 21:08:51 +0000964** If the number of columns is 1 and that column contains text "--"
965** then write the semicolon on a separate line. That way, if a
966** "--" comment occurs at the end of the statement, the comment
967** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000968*/
drh157e29a2009-05-21 15:15:00 +0000969static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000970 struct callback_data *p, /* Query context */
971 const char *zSelect, /* SELECT statement to extract content */
972 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000973){
drhdd3d4592004-08-30 01:54:05 +0000974 sqlite3_stmt *pSelect;
975 int rc;
drhb21a8e42012-01-28 21:08:51 +0000976 int nResult;
977 int i;
978 const char *z;
drh2f464a02011-10-13 00:41:49 +0000979 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000980 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000981 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
982 p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000983 return rc;
984 }
985 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000986 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000987 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000988 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000989 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000990 zFirstRow = 0;
991 }
drhb21a8e42012-01-28 21:08:51 +0000992 z = (const char*)sqlite3_column_text(pSelect, 0);
993 fprintf(p->out, "%s", z);
994 for(i=1; i<nResult; i++){
995 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
996 }
997 if( z==0 ) z = "";
998 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
999 if( z[0] ){
1000 fprintf(p->out, "\n;\n");
1001 }else{
1002 fprintf(p->out, ";\n");
1003 }
drhdd3d4592004-08-30 01:54:05 +00001004 rc = sqlite3_step(pSelect);
1005 }
drh2f464a02011-10-13 00:41:49 +00001006 rc = sqlite3_finalize(pSelect);
1007 if( rc!=SQLITE_OK ){
1008 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
1009 p->nErr++;
1010 }
1011 return rc;
drhdd3d4592004-08-30 01:54:05 +00001012}
1013
shane626a6e42009-10-22 17:30:15 +00001014/*
1015** Allocate space and save off current error string.
1016*/
1017static char *save_err_msg(
1018 sqlite3 *db /* Database to query */
1019){
1020 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1021 char *zErrMsg = sqlite3_malloc(nErrMsg);
1022 if( zErrMsg ){
1023 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1024 }
1025 return zErrMsg;
1026}
1027
1028/*
shaneh642d8b82010-07-28 16:05:34 +00001029** Display memory stats.
1030*/
1031static int display_stats(
1032 sqlite3 *db, /* Database to query */
1033 struct callback_data *pArg, /* Pointer to struct callback_data */
1034 int bReset /* True to reset the stats */
1035){
1036 int iCur;
1037 int iHiwtr;
1038
1039 if( pArg && pArg->out ){
1040
1041 iHiwtr = iCur = -1;
1042 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001043 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001044 iHiwtr = iCur = -1;
1045 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001046 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001047/*
1048** Not currently used by the CLI.
1049** iHiwtr = iCur = -1;
1050** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1051** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1052*/
1053 iHiwtr = iCur = -1;
1054 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1055 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1056/*
1057** Not currently used by the CLI.
1058** iHiwtr = iCur = -1;
1059** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1060** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1061*/
1062 iHiwtr = iCur = -1;
1063 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1064 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1065 iHiwtr = iCur = -1;
1066 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1067 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1068 iHiwtr = iCur = -1;
1069 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1070 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1071 iHiwtr = iCur = -1;
1072 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1073 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1074#ifdef YYTRACKMAXSTACKDEPTH
1075 iHiwtr = iCur = -1;
1076 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1077 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1078#endif
1079 }
1080
1081 if( pArg && pArg->out && db ){
1082 iHiwtr = iCur = -1;
1083 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1084 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001085 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1086 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1087 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1088 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1089 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1090 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001091 iHiwtr = iCur = -1;
1092 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001093 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1094 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1095 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1096 iHiwtr = iCur = -1;
1097 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1098 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001099 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001100 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1101 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1102 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001103 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1104 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1105 iHiwtr = iCur = -1;
1106 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1107 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1108 }
1109
1110 if( pArg && pArg->out && db && pArg->pStmt ){
1111 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1112 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1113 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1114 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1115 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1116 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001117 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1118 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001119 }
1120
1121 return 0;
1122}
1123
1124/*
shane626a6e42009-10-22 17:30:15 +00001125** Execute a statement or set of statements. Print
1126** any result rows/columns depending on the current mode
1127** set via the supplied callback.
1128**
1129** This is very similar to SQLite's built-in sqlite3_exec()
1130** function except it takes a slightly different callback
1131** and callback data argument.
1132*/
1133static int shell_exec(
1134 sqlite3 *db, /* An open database */
1135 const char *zSql, /* SQL to be evaluated */
1136 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1137 /* (not the same as sqlite3_exec) */
1138 struct callback_data *pArg, /* Pointer to struct callback_data */
1139 char **pzErrMsg /* Error msg written here */
1140){
dan4564ced2010-01-05 04:59:56 +00001141 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1142 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001143 int rc2;
dan4564ced2010-01-05 04:59:56 +00001144 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001145
1146 if( pzErrMsg ){
1147 *pzErrMsg = NULL;
1148 }
1149
shaneb9fc17d2009-10-22 21:23:35 +00001150 while( zSql[0] && (SQLITE_OK == rc) ){
1151 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1152 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001153 if( pzErrMsg ){
1154 *pzErrMsg = save_err_msg(db);
1155 }
1156 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001157 if( !pStmt ){
1158 /* this happens for a comment or white-space */
1159 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001160 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001161 continue;
1162 }
shane626a6e42009-10-22 17:30:15 +00001163
shaneh642d8b82010-07-28 16:05:34 +00001164 /* save off the prepared statment handle and reset row count */
1165 if( pArg ){
1166 pArg->pStmt = pStmt;
1167 pArg->cnt = 0;
1168 }
1169
shanehb7977c52010-01-18 18:17:10 +00001170 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001171 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001172 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001173 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001174 }
shanehb7977c52010-01-18 18:17:10 +00001175
drh7e02e5e2011-12-06 19:44:51 +00001176 /* Output TESTCTRL_EXPLAIN text of requested */
1177 if( pArg && pArg->mode==MODE_Explain ){
1178 const char *zExplain = 0;
1179 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1180 if( zExplain && zExplain[0] ){
1181 fprintf(pArg->out, "%s", zExplain);
1182 }
1183 }
1184
shaneb9fc17d2009-10-22 21:23:35 +00001185 /* perform the first step. this will tell us if we
1186 ** have a result set or not and how wide it is.
1187 */
1188 rc = sqlite3_step(pStmt);
1189 /* if we have a result set... */
1190 if( SQLITE_ROW == rc ){
1191 /* if we have a callback... */
1192 if( xCallback ){
1193 /* allocate space for col name ptr, value ptr, and type */
1194 int nCol = sqlite3_column_count(pStmt);
1195 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1196 if( !pData ){
1197 rc = SQLITE_NOMEM;
1198 }else{
1199 char **azCols = (char **)pData; /* Names of result columns */
1200 char **azVals = &azCols[nCol]; /* Results */
1201 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1202 int i;
1203 assert(sizeof(int) <= sizeof(char *));
1204 /* save off ptrs to column names */
1205 for(i=0; i<nCol; i++){
1206 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1207 }
shaneb9fc17d2009-10-22 21:23:35 +00001208 do{
1209 /* extract the data and data types */
1210 for(i=0; i<nCol; i++){
1211 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1212 aiTypes[i] = sqlite3_column_type(pStmt, i);
1213 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1214 rc = SQLITE_NOMEM;
1215 break; /* from for */
1216 }
1217 } /* end for */
1218
1219 /* if data and types extracted successfully... */
1220 if( SQLITE_ROW == rc ){
1221 /* call the supplied callback with the result row data */
1222 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1223 rc = SQLITE_ABORT;
1224 }else{
1225 rc = sqlite3_step(pStmt);
1226 }
1227 }
1228 } while( SQLITE_ROW == rc );
1229 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001230 }
1231 }else{
1232 do{
1233 rc = sqlite3_step(pStmt);
1234 } while( rc == SQLITE_ROW );
1235 }
1236 }
1237
shaneh642d8b82010-07-28 16:05:34 +00001238 /* print usage stats if stats on */
1239 if( pArg && pArg->statsOn ){
1240 display_stats(db, pArg, 0);
1241 }
1242
dan4564ced2010-01-05 04:59:56 +00001243 /* Finalize the statement just executed. If this fails, save a
1244 ** copy of the error message. Otherwise, set zSql to point to the
1245 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001246 rc2 = sqlite3_finalize(pStmt);
1247 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001248 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001249 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001250 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001251 }else if( pzErrMsg ){
1252 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001253 }
shaneh642d8b82010-07-28 16:05:34 +00001254
1255 /* clear saved stmt handle */
1256 if( pArg ){
1257 pArg->pStmt = NULL;
1258 }
shane626a6e42009-10-22 17:30:15 +00001259 }
shaneb9fc17d2009-10-22 21:23:35 +00001260 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001261
1262 return rc;
1263}
1264
drhdd3d4592004-08-30 01:54:05 +00001265
drh33048c02001-10-01 14:29:22 +00001266/*
drh4c653a02000-06-07 01:27:47 +00001267** This is a different callback routine used for dumping the database.
1268** Each row received by this callback consists of a table name,
1269** the table type ("index" or "table") and SQL to create the table.
1270** This routine should print text sufficient to recreate the table.
1271*/
1272static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001273 int rc;
1274 const char *zTable;
1275 const char *zType;
1276 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001277 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001278 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001279
drh902b9ee2008-12-05 17:17:07 +00001280 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001281 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001282 zTable = azArg[0];
1283 zType = azArg[1];
1284 zSql = azArg[2];
1285
drh00b950d2005-09-11 02:03:03 +00001286 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001287 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001288 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1289 fprintf(p->out, "ANALYZE sqlite_master;\n");
1290 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1291 return 0;
drh45e29d82006-11-20 16:21:10 +00001292 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1293 char *zIns;
1294 if( !p->writableSchema ){
1295 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1296 p->writableSchema = 1;
1297 }
1298 zIns = sqlite3_mprintf(
1299 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1300 "VALUES('table','%q','%q',0,'%q');",
1301 zTable, zTable, zSql);
1302 fprintf(p->out, "%s\n", zIns);
1303 sqlite3_free(zIns);
1304 return 0;
drh00b950d2005-09-11 02:03:03 +00001305 }else{
1306 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001307 }
danielk19772a02e332004-06-05 08:04:36 +00001308
1309 if( strcmp(zType, "table")==0 ){
1310 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001311 char *zSelect = 0;
1312 char *zTableInfo = 0;
1313 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001314 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001315
1316 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1317 zTableInfo = appendText(zTableInfo, zTable, '"');
1318 zTableInfo = appendText(zTableInfo, ");", 0);
1319
1320 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001321 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001322 if( rc!=SQLITE_OK || !pTableInfo ){
1323 return 1;
1324 }
1325
1326 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001327 /* Always quote the table name, even if it appears to be pure ascii,
1328 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1329 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001330 if( zTmp ){
1331 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001332 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001333 }
1334 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1335 rc = sqlite3_step(pTableInfo);
1336 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001337 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001338 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001339 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001340 rc = sqlite3_step(pTableInfo);
1341 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001342 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001343 }else{
1344 zSelect = appendText(zSelect, ") ", 0);
1345 }
drh157e29a2009-05-21 15:15:00 +00001346 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001347 }
1348 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001349 if( rc!=SQLITE_OK || nRow==0 ){
1350 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001351 return 1;
1352 }
1353 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1354 zSelect = appendText(zSelect, zTable, '"');
1355
drh2f464a02011-10-13 00:41:49 +00001356 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001357 if( rc==SQLITE_CORRUPT ){
1358 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001359 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001360 }
drh85e72432012-04-11 11:38:53 +00001361 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001362 }
drh4c653a02000-06-07 01:27:47 +00001363 return 0;
1364}
1365
1366/*
drh45e29d82006-11-20 16:21:10 +00001367** Run zQuery. Use dump_callback() as the callback routine so that
1368** the contents of the query are output as SQL statements.
1369**
drhdd3d4592004-08-30 01:54:05 +00001370** If we get a SQLITE_CORRUPT error, rerun the query after appending
1371** "ORDER BY rowid DESC" to the end.
1372*/
1373static int run_schema_dump_query(
1374 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001375 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001376){
1377 int rc;
drh2f464a02011-10-13 00:41:49 +00001378 char *zErr = 0;
1379 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001380 if( rc==SQLITE_CORRUPT ){
1381 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001382 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001383 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1384 if( zErr ){
1385 fprintf(p->out, "/****** %s ******/\n", zErr);
1386 sqlite3_free(zErr);
1387 zErr = 0;
1388 }
drhdd3d4592004-08-30 01:54:05 +00001389 zQ2 = malloc( len+100 );
1390 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001391 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001392 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1393 if( rc ){
1394 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1395 }else{
1396 rc = SQLITE_CORRUPT;
1397 }
1398 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001399 free(zQ2);
1400 }
1401 return rc;
1402}
1403
1404/*
drh75897232000-05-29 14:26:00 +00001405** Text of a help message
1406*/
persicom1d0b8722002-04-18 02:53:04 +00001407static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001408 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001409 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001410 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001411 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001412 " If TABLE specified, only dump tables matching\n"
1413 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001414 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001415 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001416 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1417 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001418 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001419 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001420 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001421 ".indices ?TABLE? Show names of all indices\n"
1422 " If TABLE specified, only show indices for tables\n"
1423 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001424#ifdef SQLITE_ENABLE_IOTRACE
1425 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1426#endif
drh70df4fe2006-06-13 15:12:21 +00001427#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001428 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001429#endif
drh127f9d72010-02-23 01:47:00 +00001430 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001431 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001432 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001433 " column Left-aligned columns. (See .width)\n"
1434 " html HTML <table> code\n"
1435 " insert SQL insert statements for TABLE\n"
1436 " line One value per line\n"
1437 " list Values delimited by .separator string\n"
1438 " tabs Tab-separated values\n"
1439 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001440 ".nullvalue STRING Use STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001441 ".output FILENAME Send output to FILENAME\n"
1442 ".output stdout Send output to the screen\n"
drh078b1fd2012-09-21 13:40:02 +00001443 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001444 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001445 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001446 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001447 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001448 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001449 " If TABLE specified, only show tables matching\n"
1450 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001451 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001452 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001453 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001454 ".tables ?TABLE? List names of tables\n"
1455 " If TABLE specified, only list tables matching\n"
1456 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001457 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001458 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001459 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001460 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001461;
1462
shaneb320ccd2009-10-21 03:42:58 +00001463static char zTimerHelp[] =
1464 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1465;
1466
drhdaffd0e2001-04-11 14:28:42 +00001467/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001468static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001469
drh75897232000-05-29 14:26:00 +00001470/*
drh44c2eb12003-04-30 11:38:26 +00001471** Make sure the database is open. If it is not, then open it. If
1472** the database fails to open, print an error message and exit.
1473*/
1474static void open_db(struct callback_data *p){
1475 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001476 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001477 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001478 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001479 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1480 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1481 shellstaticFunc, 0, 0);
1482 }
1483 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001484 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001485 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001486 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001487 }
drhc2e87a32006-06-27 15:16:14 +00001488#ifndef SQLITE_OMIT_LOAD_EXTENSION
1489 sqlite3_enable_load_extension(p->db, 1);
1490#endif
drh44c2eb12003-04-30 11:38:26 +00001491 }
1492}
1493
1494/*
drhfeac5f82004-08-01 00:10:45 +00001495** Do C-language style dequoting.
1496**
1497** \t -> tab
1498** \n -> newline
1499** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001500** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001501** \NNN -> ascii character NNN in octal
1502** \\ -> backslash
1503*/
1504static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001505 int i, j;
1506 char c;
drhfeac5f82004-08-01 00:10:45 +00001507 for(i=j=0; (c = z[i])!=0; i++, j++){
1508 if( c=='\\' ){
1509 c = z[++i];
1510 if( c=='n' ){
1511 c = '\n';
1512 }else if( c=='t' ){
1513 c = '\t';
1514 }else if( c=='r' ){
1515 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001516 }else if( c=='\\' ){
1517 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001518 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001519 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001520 if( z[i+1]>='0' && z[i+1]<='7' ){
1521 i++;
1522 c = (c<<3) + z[i] - '0';
1523 if( z[i+1]>='0' && z[i+1]<='7' ){
1524 i++;
1525 c = (c<<3) + z[i] - '0';
1526 }
1527 }
1528 }
1529 }
1530 z[j] = c;
1531 }
1532 z[j] = 0;
1533}
1534
1535/*
drh348d19c2013-06-03 12:47:43 +00001536** Return the value of a hexadecimal digit. Return -1 if the input
1537** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001538*/
drh348d19c2013-06-03 12:47:43 +00001539static int hexDigitValue(char c){
1540 if( c>='0' && c<='9' ) return c - '0';
1541 if( c>='a' && c<='f' ) return c - 'a' + 10;
1542 if( c>='A' && c<='F' ) return c - 'A' + 10;
1543 return -1;
drhc28490c2006-10-26 14:25:58 +00001544}
1545
1546/*
drh7d9f3942013-04-03 01:26:54 +00001547** Interpret zArg as an integer value, possibly with suffixes.
1548*/
1549static sqlite3_int64 integerValue(const char *zArg){
1550 sqlite3_int64 v = 0;
1551 static const struct { char *zSuffix; int iMult; } aMult[] = {
1552 { "KiB", 1024 },
1553 { "MiB", 1024*1024 },
1554 { "GiB", 1024*1024*1024 },
1555 { "KB", 1000 },
1556 { "MB", 1000000 },
1557 { "GB", 1000000000 },
1558 { "K", 1000 },
1559 { "M", 1000000 },
1560 { "G", 1000000000 },
1561 };
1562 int i;
1563 int isNeg = 0;
1564 if( zArg[0]=='-' ){
1565 isNeg = 1;
1566 zArg++;
1567 }else if( zArg[0]=='+' ){
1568 zArg++;
1569 }
drh348d19c2013-06-03 12:47:43 +00001570 if( zArg[0]=='0' && zArg[1]=='x' ){
1571 int x;
1572 zArg += 2;
1573 while( (x = hexDigitValue(zArg[0]))>=0 ){
1574 v = (v<<4) + x;
1575 zArg++;
1576 }
1577 }else{
1578 while( IsDigit(zArg[0]) ){
1579 v = v*10 + zArg[0] - '0';
1580 zArg++;
1581 }
drh7d9f3942013-04-03 01:26:54 +00001582 }
drhc2bed0a2013-05-24 11:57:50 +00001583 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001584 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1585 v *= aMult[i].iMult;
1586 break;
1587 }
1588 }
1589 return isNeg? -v : v;
1590}
1591
1592/*
drh348d19c2013-06-03 12:47:43 +00001593** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1594** for TRUE and FALSE. Return the integer value if appropriate.
1595*/
1596static int booleanValue(char *zArg){
1597 int i;
1598 if( zArg[0]=='0' && zArg[1]=='x' ){
1599 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1600 }else{
1601 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1602 }
1603 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1604 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1605 return 1;
1606 }
1607 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1608 return 0;
1609 }
1610 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1611 zArg);
1612 return 0;
1613}
1614
1615/*
drh42f64e52012-04-04 16:56:23 +00001616** Close an output file, assuming it is not stderr or stdout
1617*/
1618static void output_file_close(FILE *f){
1619 if( f && f!=stdout && f!=stderr ) fclose(f);
1620}
1621
1622/*
1623** Try to open an output file. The names "stdout" and "stderr" are
1624** recognized and do the right thing. NULL is returned if the output
1625** filename is "off".
1626*/
1627static FILE *output_file_open(const char *zFile){
1628 FILE *f;
1629 if( strcmp(zFile,"stdout")==0 ){
1630 f = stdout;
1631 }else if( strcmp(zFile, "stderr")==0 ){
1632 f = stderr;
1633 }else if( strcmp(zFile, "off")==0 ){
1634 f = 0;
1635 }else{
1636 f = fopen(zFile, "wb");
1637 if( f==0 ){
1638 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1639 }
1640 }
1641 return f;
1642}
1643
1644/*
1645** A routine for handling output from sqlite3_trace().
1646*/
1647static void sql_trace_callback(void *pArg, const char *z){
1648 FILE *f = (FILE*)pArg;
1649 if( f ) fprintf(f, "%s\n", z);
1650}
1651
1652/*
drhd8621b92012-04-17 09:09:33 +00001653** A no-op routine that runs with the ".breakpoint" doc-command. This is
1654** a useful spot to set a debugger breakpoint.
1655*/
1656static void test_breakpoint(void){
1657 static int nCall = 0;
1658 nCall++;
1659}
1660
1661/*
drhdb95f682013-06-26 22:46:00 +00001662** An object used to read a CSV file
1663*/
1664typedef struct CSVReader CSVReader;
1665struct CSVReader {
1666 const char *zFile; /* Name of the input file */
1667 FILE *in; /* Read the CSV text from this input stream */
1668 char *z; /* Accumulated text for a field */
1669 int n; /* Number of bytes in z */
1670 int nAlloc; /* Space allocated for z[] */
1671 int nLine; /* Current line number */
1672 int cTerm; /* Character that terminated the most recent field */
1673 int cSeparator; /* The separator character. (Usually ",") */
1674};
1675
1676/* Append a single byte to z[] */
1677static void csv_append_char(CSVReader *p, int c){
1678 if( p->n+1>=p->nAlloc ){
1679 p->nAlloc += p->nAlloc + 100;
1680 p->z = sqlite3_realloc(p->z, p->nAlloc);
1681 if( p->z==0 ){
1682 fprintf(stderr, "out of memory\n");
1683 exit(1);
1684 }
1685 }
1686 p->z[p->n++] = (char)c;
1687}
1688
1689/* Read a single field of CSV text. Compatible with rfc4180 and extended
1690** with the option of having a separator other than ",".
1691**
1692** + Input comes from p->in.
1693** + Store results in p->z of length p->n. Space to hold p->z comes
1694** from sqlite3_malloc().
1695** + Use p->cSep as the separator. The default is ",".
1696** + Keep track of the line number in p->nLine.
1697** + Store the character that terminates the field in p->cTerm. Store
1698** EOF on end-of-file.
1699** + Report syntax errors on stderr
1700*/
1701static char *csv_read_one_field(CSVReader *p){
1702 int c, pc;
1703 int cSep = p->cSeparator;
1704 p->n = 0;
1705 c = fgetc(p->in);
1706 if( c==EOF || seenInterrupt ){
1707 p->cTerm = EOF;
1708 return 0;
1709 }
1710 if( c=='"' ){
1711 int startLine = p->nLine;
1712 int cQuote = c;
1713 pc = 0;
1714 while( 1 ){
1715 c = fgetc(p->in);
1716 if( c=='\n' ) p->nLine++;
1717 if( c==cQuote ){
1718 if( pc==cQuote ){
1719 pc = 0;
1720 continue;
1721 }
1722 }
1723 if( (c==cSep && pc==cQuote)
1724 || (c=='\n' && pc==cQuote)
1725 || (c=='\n' && pc=='\r' && p->n>2 && p->z[p->n-2]==cQuote)
1726 || (c==EOF && pc==cQuote)
1727 ){
1728 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00001729 p->cTerm = c;
1730 break;
1731 }
1732 if( pc==cQuote && c!='\r' ){
1733 fprintf(stderr, "%s:%d: unescaped %c character\n",
1734 p->zFile, p->nLine, cQuote);
1735 }
1736 if( c==EOF ){
1737 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
1738 p->zFile, startLine, cQuote);
drhdb95f682013-06-26 22:46:00 +00001739 p->cTerm = EOF;
1740 break;
1741 }
1742 csv_append_char(p, c);
1743 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00001744 }
drhdb95f682013-06-26 22:46:00 +00001745 }else{
drhd0a64dc2013-06-30 20:24:26 +00001746 while( c!=EOF && c!=cSep && c!='\n' ){
drhdb95f682013-06-26 22:46:00 +00001747 csv_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00001748 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00001749 }
1750 if( c=='\n' ){
1751 p->nLine++;
1752 if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
1753 }
drhdb95f682013-06-26 22:46:00 +00001754 p->cTerm = c;
1755 }
drh8dd675e2013-07-12 21:09:24 +00001756 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00001757 return p->z;
1758}
1759
1760/*
drh75897232000-05-29 14:26:00 +00001761** If an input line begins with "." then invoke this routine to
1762** process that line.
drh67505e72002-04-19 12:34:06 +00001763**
drh47ad6842006-11-08 12:25:42 +00001764** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001765*/
drh44c2eb12003-04-30 11:38:26 +00001766static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001767 int i = 1;
1768 int nArg = 0;
1769 int n, c;
drh67505e72002-04-19 12:34:06 +00001770 int rc = 0;
drh75897232000-05-29 14:26:00 +00001771 char *azArg[50];
1772
1773 /* Parse the input line into tokens.
1774 */
1775 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001776 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001777 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001778 if( zLine[i]=='\'' || zLine[i]=='"' ){
1779 int delim = zLine[i++];
1780 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00001781 while( zLine[i] && zLine[i]!=delim ){
1782 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
1783 i++;
1784 }
drh75897232000-05-29 14:26:00 +00001785 if( zLine[i]==delim ){
1786 zLine[i++] = 0;
1787 }
drhfeac5f82004-08-01 00:10:45 +00001788 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001789 }else{
1790 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001791 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001792 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001793 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001794 }
1795 }
1796
1797 /* Process the input line.
1798 */
shane9bd1b442009-10-23 01:27:39 +00001799 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001800 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001801 c = azArg[0][0];
drhbc46f022013-01-23 18:53:23 +00001802 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1803 const char *zDestFile = 0;
1804 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00001805 sqlite3 *pDest;
1806 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00001807 int j;
1808 for(j=1; j<nArg; j++){
1809 const char *z = azArg[j];
1810 if( z[0]=='-' ){
1811 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00001812 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00001813 {
1814 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1815 return 1;
1816 }
1817 }else if( zDestFile==0 ){
1818 zDestFile = azArg[j];
1819 }else if( zDb==0 ){
1820 zDb = zDestFile;
1821 zDestFile = azArg[j];
1822 }else{
1823 fprintf(stderr, "too many arguments to .backup\n");
1824 return 1;
1825 }
drh9ff849f2009-02-04 20:55:57 +00001826 }
drhbc46f022013-01-23 18:53:23 +00001827 if( zDestFile==0 ){
1828 fprintf(stderr, "missing FILENAME argument on .backup\n");
1829 return 1;
1830 }
1831 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00001832 rc = sqlite3_open(zDestFile, &pDest);
1833 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001834 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001835 sqlite3_close(pDest);
1836 return 1;
1837 }
drhdc2c4912009-02-04 22:46:47 +00001838 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001839 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1840 if( pBackup==0 ){
1841 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1842 sqlite3_close(pDest);
1843 return 1;
1844 }
1845 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1846 sqlite3_backup_finish(pBackup);
1847 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001848 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001849 }else{
1850 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001851 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001852 }
1853 sqlite3_close(pDest);
1854 }else
1855
shanehe2aa9d72009-11-06 17:20:17 +00001856 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001857 bail_on_error = booleanValue(azArg[1]);
1858 }else
1859
drhd8621b92012-04-17 09:09:33 +00001860 /* The undocumented ".breakpoint" command causes a call to the no-op
1861 ** routine named test_breakpoint().
1862 */
1863 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1864 test_breakpoint();
1865 }else
1866
shanehe2aa9d72009-11-06 17:20:17 +00001867 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001868 struct callback_data data;
1869 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001870 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001871 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001872 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001873 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001874 data.colWidth[0] = 3;
1875 data.colWidth[1] = 15;
1876 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001877 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001878 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001879 if( zErrMsg ){
1880 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001881 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001882 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001883 }
1884 }else
1885
shanehe2aa9d72009-11-06 17:20:17 +00001886 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001887 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001888 /* When playing back a "dump", the content might appear in an order
1889 ** which causes immediate foreign key constraints to be violated.
1890 ** So disable foreign-key constraint enforcement to prevent problems. */
1891 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001892 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001893 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001894 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001895 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001896 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001897 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001898 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001899 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001900 );
1901 run_schema_dump_query(p,
1902 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001903 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001904 );
drh2f464a02011-10-13 00:41:49 +00001905 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001906 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001907 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001908 );
drh4c653a02000-06-07 01:27:47 +00001909 }else{
1910 int i;
drhdd3d4592004-08-30 01:54:05 +00001911 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001912 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001913 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001914 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001915 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001916 " AND sql NOT NULL");
1917 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001918 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001919 "WHERE sql NOT NULL"
1920 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001921 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001922 );
danielk1977bc6ada42004-06-30 08:20:16 +00001923 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001924 }
1925 }
drh45e29d82006-11-20 16:21:10 +00001926 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001927 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001928 p->writableSchema = 0;
1929 }
drh56197952011-10-13 16:30:13 +00001930 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1931 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001932 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001933 }else
drh75897232000-05-29 14:26:00 +00001934
shanehe2aa9d72009-11-06 17:20:17 +00001935 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001936 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001937 }else
1938
drhd3ac7d92013-01-25 18:33:43 +00001939 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00001940 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00001941 rc = 2;
drh75897232000-05-29 14:26:00 +00001942 }else
1943
shanehe2aa9d72009-11-06 17:20:17 +00001944 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001945 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001946 if(val == 1) {
1947 if(!p->explainPrev.valid) {
1948 p->explainPrev.valid = 1;
1949 p->explainPrev.mode = p->mode;
1950 p->explainPrev.showHeader = p->showHeader;
1951 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1952 }
1953 /* We could put this code under the !p->explainValid
1954 ** condition so that it does not execute if we are already in
1955 ** explain mode. However, always executing it allows us an easy
1956 ** was to reset to explain mode in case the user previously
1957 ** did an .explain followed by a .width, .mode or .header
1958 ** command.
1959 */
danielk19770d78bae2008-01-03 07:09:48 +00001960 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001961 p->showHeader = 1;
1962 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001963 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001964 p->colWidth[1] = 13; /* opcode */
1965 p->colWidth[2] = 4; /* P1 */
1966 p->colWidth[3] = 4; /* P2 */
1967 p->colWidth[4] = 4; /* P3 */
1968 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001969 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001970 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001971 }else if (p->explainPrev.valid) {
1972 p->explainPrev.valid = 0;
1973 p->mode = p->explainPrev.mode;
1974 p->showHeader = p->explainPrev.showHeader;
1975 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1976 }
drh75897232000-05-29 14:26:00 +00001977 }else
1978
drhc28490c2006-10-26 14:25:58 +00001979 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001980 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001981 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001982 }else
1983
1984 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001985 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001986 if( HAS_TIMER ){
1987 fprintf(stderr,"%s",zTimerHelp);
1988 }
drh75897232000-05-29 14:26:00 +00001989 }else
1990
shanehe2aa9d72009-11-06 17:20:17 +00001991 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001992 char *zTable = azArg[2]; /* Insert data into this table */
drh5bde8162013-06-27 14:07:53 +00001993 char *zFile = azArg[1]; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00001994 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001995 int nCol; /* Number of columns in the table */
1996 int nByte; /* Number of bytes in an SQL string */
1997 int i, j; /* Loop counters */
1998 int nSep; /* Number of bytes in p->separator[] */
1999 char *zSql; /* An SQL statement */
drhdb95f682013-06-26 22:46:00 +00002000 CSVReader sCsv; /* Reader context */
drh5bde8162013-06-27 14:07:53 +00002001 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002002
drhdb95f682013-06-26 22:46:00 +00002003 seenInterrupt = 0;
2004 memset(&sCsv, 0, sizeof(sCsv));
drha543c822006-06-08 16:10:14 +00002005 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002006 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002007 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00002008 fprintf(stderr, "Error: non-null separator required for import\n");
2009 return 1;
drhfeac5f82004-08-01 00:10:45 +00002010 }
drhdb95f682013-06-26 22:46:00 +00002011 if( nSep>1 ){
2012 fprintf(stderr, "Error: multi-character separators not allowed"
2013 " for import\n");
2014 return 1;
2015 }
drh5bde8162013-06-27 14:07:53 +00002016 sCsv.zFile = zFile;
2017 sCsv.nLine = 1;
2018 if( sCsv.zFile[0]=='|' ){
2019 sCsv.in = popen(sCsv.zFile+1, "r");
2020 sCsv.zFile = "<pipe>";
2021 xCloser = pclose;
2022 }else{
2023 sCsv.in = fopen(sCsv.zFile, "rb");
2024 xCloser = fclose;
2025 }
drhdb95f682013-06-26 22:46:00 +00002026 if( sCsv.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002027 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002028 return 1;
2029 }
2030 sCsv.cSeparator = p->separator[0];
drh7b075e32011-09-28 01:10:00 +00002031 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002032 if( zSql==0 ){
2033 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002034 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002035 return 1;
2036 }
drh4f21c4a2008-12-10 22:15:00 +00002037 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002038 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002039 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2040 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2041 char cSep = '(';
2042 while( csv_read_one_field(&sCsv) ){
2043 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
2044 cSep = ',';
2045 if( sCsv.cTerm!=sCsv.cSeparator ) break;
2046 }
drh5bde8162013-06-27 14:07:53 +00002047 if( cSep=='(' ){
2048 sqlite3_free(zCreate);
2049 sqlite3_free(sCsv.z);
2050 xCloser(sCsv.in);
2051 fprintf(stderr,"%s: empty file\n", sCsv.zFile);
2052 return 1;
2053 }
drhdb95f682013-06-26 22:46:00 +00002054 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2055 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2056 sqlite3_free(zCreate);
2057 if( rc ){
2058 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2059 sqlite3_errmsg(db));
2060 sqlite3_free(sCsv.z);
drh5bde8162013-06-27 14:07:53 +00002061 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002062 return 1;
2063 }
2064 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
2065 }
drhfeac5f82004-08-01 00:10:45 +00002066 sqlite3_free(zSql);
2067 if( rc ){
shane916f9612009-10-23 00:37:15 +00002068 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002069 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
drh5bde8162013-06-27 14:07:53 +00002070 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002071 return 1;
drhfeac5f82004-08-01 00:10:45 +00002072 }
shane916f9612009-10-23 00:37:15 +00002073 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002074 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002075 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002076 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002077 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002078 if( zSql==0 ){
2079 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002080 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002081 return 1;
2082 }
drhdb95f682013-06-26 22:46:00 +00002083 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002084 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002085 for(i=1; i<nCol; i++){
2086 zSql[j++] = ',';
2087 zSql[j++] = '?';
2088 }
2089 zSql[j++] = ')';
2090 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002091 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002092 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002093 if( rc ){
2094 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002095 if (pStmt) sqlite3_finalize(pStmt);
drh5bde8162013-06-27 14:07:53 +00002096 xCloser(sCsv.in);
drh47ad6842006-11-08 12:25:42 +00002097 return 1;
drhfeac5f82004-08-01 00:10:45 +00002098 }
drhdb95f682013-06-26 22:46:00 +00002099 do{
2100 int startLine = sCsv.nLine;
drhfeac5f82004-08-01 00:10:45 +00002101 for(i=0; i<nCol; i++){
drhdb95f682013-06-26 22:46:00 +00002102 char *z = csv_read_one_field(&sCsv);
2103 if( z==0 && i==0 ) break;
2104 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
2105 if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
2106 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2107 "filling the rest with NULL\n",
2108 sCsv.zFile, startLine, nCol, i+1);
2109 i++;
2110 while( i<nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002111 }
drhfeac5f82004-08-01 00:10:45 +00002112 }
drhdb95f682013-06-26 22:46:00 +00002113 if( sCsv.cTerm==sCsv.cSeparator ){
2114 do{
2115 csv_read_one_field(&sCsv);
2116 i++;
2117 }while( sCsv.cTerm==sCsv.cSeparator );
2118 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2119 "extras ignored\n",
2120 sCsv.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002121 }
drhdb95f682013-06-26 22:46:00 +00002122 if( i>=nCol ){
2123 sqlite3_step(pStmt);
2124 rc = sqlite3_reset(pStmt);
2125 if( rc!=SQLITE_OK ){
2126 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
2127 sqlite3_errmsg(db));
2128 }
2129 }
2130 }while( sCsv.cTerm!=EOF );
2131
drh5bde8162013-06-27 14:07:53 +00002132 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002133 sqlite3_free(sCsv.z);
drhfeac5f82004-08-01 00:10:45 +00002134 sqlite3_finalize(pStmt);
drhdb95f682013-06-26 22:46:00 +00002135 sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002136 }else
2137
shanehe2aa9d72009-11-06 17:20:17 +00002138 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002139 struct callback_data data;
2140 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002141 open_db(p);
drh75897232000-05-29 14:26:00 +00002142 memcpy(&data, p, sizeof(data));
2143 data.showHeader = 0;
2144 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002145 if( nArg==1 ){
2146 rc = sqlite3_exec(p->db,
2147 "SELECT name FROM sqlite_master "
2148 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2149 "UNION ALL "
2150 "SELECT name FROM sqlite_temp_master "
2151 "WHERE type='index' "
2152 "ORDER BY 1",
2153 callback, &data, &zErrMsg
2154 );
2155 }else{
2156 zShellStatic = azArg[1];
2157 rc = sqlite3_exec(p->db,
2158 "SELECT name FROM sqlite_master "
2159 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2160 "UNION ALL "
2161 "SELECT name FROM sqlite_temp_master "
2162 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2163 "ORDER BY 1",
2164 callback, &data, &zErrMsg
2165 );
2166 zShellStatic = 0;
2167 }
drh75897232000-05-29 14:26:00 +00002168 if( zErrMsg ){
2169 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002170 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002171 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002172 }else if( rc != SQLITE_OK ){
2173 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2174 rc = 1;
drh75897232000-05-29 14:26:00 +00002175 }
2176 }else
2177
drhae5e4452007-05-03 17:18:36 +00002178#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002179 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002180 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002181 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2182 iotrace = 0;
2183 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002184 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002185 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002186 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002187 iotrace = stdout;
2188 }else{
2189 iotrace = fopen(azArg[1], "w");
2190 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002191 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002192 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002193 rc = 1;
drhb0603412007-02-28 04:47:26 +00002194 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002195 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002196 }
2197 }
2198 }else
drhae5e4452007-05-03 17:18:36 +00002199#endif
drhb0603412007-02-28 04:47:26 +00002200
drh70df4fe2006-06-13 15:12:21 +00002201#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002202 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2203 const char *zFile, *zProc;
2204 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00002205 zFile = azArg[1];
2206 zProc = nArg>=3 ? azArg[2] : 0;
2207 open_db(p);
2208 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2209 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002210 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002211 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002212 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002213 }
2214 }else
drh70df4fe2006-06-13 15:12:21 +00002215#endif
drh1e397f82006-06-08 15:28:43 +00002216
drhc8ba2122011-03-23 11:16:22 +00002217 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00002218 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00002219 output_file_close(p->pLog);
2220 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00002221 }else
2222
shanehe2aa9d72009-11-06 17:20:17 +00002223 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00002224 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002225 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002226 ||
shanehe2aa9d72009-11-06 17:20:17 +00002227 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002228 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002229 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002230 ||
shanehe2aa9d72009-11-06 17:20:17 +00002231 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002232 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002233 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002234 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002235 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002236 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002237 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002238 p->mode = MODE_Tcl;
mistachkin585dcb22012-12-04 00:23:43 +00002239 sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
shanehe2aa9d72009-11-06 17:20:17 +00002240 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002241 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002242 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002243 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002244 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002245 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002246 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002247 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002248 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002249 }else {
shane9bd1b442009-10-23 01:27:39 +00002250 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002251 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002252 rc = 1;
drh75897232000-05-29 14:26:00 +00002253 }
2254 }else
2255
shanehe2aa9d72009-11-06 17:20:17 +00002256 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2257 int n2 = strlen30(azArg[1]);
2258 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2259 p->mode = MODE_Insert;
2260 set_table_name(p, azArg[2]);
2261 }else {
2262 fprintf(stderr, "Error: invalid arguments: "
2263 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2264 rc = 1;
2265 }
2266 }else
2267
persicom7e2dfdd2002-04-18 02:46:52 +00002268 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002269 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2270 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002271 }else
2272
drh75897232000-05-29 14:26:00 +00002273 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002274 if( p->outfile[0]=='|' ){
2275 pclose(p->out);
2276 }else{
2277 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002278 }
drh42f64e52012-04-04 16:56:23 +00002279 p->outfile[0] = 0;
2280 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002281 p->out = popen(&azArg[1][1], "w");
2282 if( p->out==0 ){
2283 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2284 p->out = stdout;
2285 rc = 1;
2286 }else{
2287 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2288 }
drh75897232000-05-29 14:26:00 +00002289 }else{
drh42f64e52012-04-04 16:56:23 +00002290 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002291 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002292 if( strcmp(azArg[1],"off")!=0 ){
2293 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2294 }
drh75897232000-05-29 14:26:00 +00002295 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002296 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002297 } else {
drh42f64e52012-04-04 16:56:23 +00002298 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002299 }
2300 }
2301 }else
2302
drh078b1fd2012-09-21 13:40:02 +00002303 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2304 int i;
2305 for(i=1; i<nArg; i++){
2306 if( i>1 ) fprintf(p->out, " ");
2307 fprintf(p->out, "%s", azArg[i]);
2308 }
2309 fprintf(p->out, "\n");
2310 }else
2311
drhdd45df82002-04-18 12:39:03 +00002312 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002313 if( nArg >= 2) {
2314 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2315 }
2316 if( nArg >= 3) {
2317 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2318 }
2319 }else
2320
shanehe2aa9d72009-11-06 17:20:17 +00002321 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002322 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002323 }else
2324
drh9ff849f2009-02-04 20:55:57 +00002325 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002326 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002327 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002328 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2329 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002330 }else{
shane9bd1b442009-10-23 01:27:39 +00002331 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002332 fclose(alt);
2333 }
2334 }else
2335
shanehe2aa9d72009-11-06 17:20:17 +00002336 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002337 const char *zSrcFile;
2338 const char *zDb;
2339 sqlite3 *pSrc;
2340 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002341 int nTimeout = 0;
2342
drh9ff849f2009-02-04 20:55:57 +00002343 if( nArg==2 ){
2344 zSrcFile = azArg[1];
2345 zDb = "main";
2346 }else{
2347 zSrcFile = azArg[2];
2348 zDb = azArg[1];
2349 }
2350 rc = sqlite3_open(zSrcFile, &pSrc);
2351 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002352 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002353 sqlite3_close(pSrc);
2354 return 1;
2355 }
drhdc2c4912009-02-04 22:46:47 +00002356 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002357 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2358 if( pBackup==0 ){
2359 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2360 sqlite3_close(pSrc);
2361 return 1;
2362 }
drhdc2c4912009-02-04 22:46:47 +00002363 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2364 || rc==SQLITE_BUSY ){
2365 if( rc==SQLITE_BUSY ){
2366 if( nTimeout++ >= 3 ) break;
2367 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002368 }
2369 }
2370 sqlite3_backup_finish(pBackup);
2371 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002372 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002373 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002374 fprintf(stderr, "Error: source database is busy\n");
2375 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002376 }else{
2377 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002378 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002379 }
2380 sqlite3_close(pSrc);
2381 }else
2382
shanehe2aa9d72009-11-06 17:20:17 +00002383 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002384 struct callback_data data;
2385 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002386 open_db(p);
drh75897232000-05-29 14:26:00 +00002387 memcpy(&data, p, sizeof(data));
2388 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002389 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002390 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002391 int i;
drhf0693c82011-10-11 20:41:54 +00002392 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002393 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002394 char *new_argv[2], *new_colv[2];
2395 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2396 " type text,\n"
2397 " name text,\n"
2398 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002399 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002400 " sql text\n"
2401 ")";
2402 new_argv[1] = 0;
2403 new_colv[0] = "sql";
2404 new_colv[1] = 0;
2405 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002406 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002407 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002408 char *new_argv[2], *new_colv[2];
2409 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2410 " type text,\n"
2411 " name text,\n"
2412 " tbl_name text,\n"
2413 " rootpage integer,\n"
2414 " sql text\n"
2415 ")";
2416 new_argv[1] = 0;
2417 new_colv[0] = "sql";
2418 new_colv[1] = 0;
2419 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002420 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002421 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002422 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002423 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002424 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002425 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002426 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002427 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002428 "WHERE lower(tbl_name) LIKE shellstatic()"
2429 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00002430 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00002431 callback, &data, &zErrMsg);
2432 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002433 }
drh75897232000-05-29 14:26:00 +00002434 }else{
shane9bd1b442009-10-23 01:27:39 +00002435 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002436 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002437 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002438 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002439 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002440 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drh1ba00292013-05-06 21:01:06 +00002441 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00002442 callback, &data, &zErrMsg
2443 );
drh75897232000-05-29 14:26:00 +00002444 }
drh75897232000-05-29 14:26:00 +00002445 if( zErrMsg ){
2446 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002447 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002448 rc = 1;
2449 }else if( rc != SQLITE_OK ){
2450 fprintf(stderr,"Error: querying schema information\n");
2451 rc = 1;
2452 }else{
2453 rc = 0;
drh75897232000-05-29 14:26:00 +00002454 }
2455 }else
2456
drh340f5822013-06-27 13:01:21 +00002457#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00002458 /* Undocumented commands for internal testing. Subject to change
2459 ** without notice. */
2460 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
2461 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
2462 int i, v;
2463 for(i=1; i<nArg; i++){
2464 v = booleanValue(azArg[i]);
2465 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
2466 }
2467 }
2468 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
2469 int i; sqlite3_int64 v;
2470 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00002471 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00002472 v = integerValue(azArg[i]);
drh340f5822013-06-27 13:01:21 +00002473 sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);
2474 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00002475 }
2476 }
2477 }else
drh340f5822013-06-27 13:01:21 +00002478#endif
drh348d19c2013-06-03 12:47:43 +00002479
drh75897232000-05-29 14:26:00 +00002480 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002481 sqlite3_snprintf(sizeof(p->separator), p->separator,
2482 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002483 }else
2484
shanehe2aa9d72009-11-06 17:20:17 +00002485 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002486 int i;
2487 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002488 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002489 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002490 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002491 fprintf(p->out,"%9.9s: ", "nullvalue");
2492 output_c_string(p->out, p->nullvalue);
2493 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002494 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002495 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002496 fprintf(p->out,"%9.9s: ", "separator");
2497 output_c_string(p->out, p->separator);
2498 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002499 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002500 fprintf(p->out,"%9.9s: ","width");
2501 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002502 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002503 }
drhfeac5f82004-08-01 00:10:45 +00002504 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002505 }else
2506
shaneh642d8b82010-07-28 16:05:34 +00002507 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2508 p->statsOn = booleanValue(azArg[1]);
2509 }else
2510
shanehe2aa9d72009-11-06 17:20:17 +00002511 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002512 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002513 char **azResult;
drh98781232012-04-23 12:38:05 +00002514 int nRow, nAlloc;
2515 char *zSql = 0;
2516 int ii;
drh44c2eb12003-04-30 11:38:26 +00002517 open_db(p);
drh98781232012-04-23 12:38:05 +00002518 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2519 if( rc ) return rc;
2520 zSql = sqlite3_mprintf(
2521 "SELECT name FROM sqlite_master"
2522 " WHERE type IN ('table','view')"
2523 " AND name NOT LIKE 'sqlite_%%'"
2524 " AND name LIKE ?1");
2525 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2526 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2527 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2528 if( strcmp(zDbName,"temp")==0 ){
2529 zSql = sqlite3_mprintf(
2530 "%z UNION ALL "
2531 "SELECT 'temp.' || name FROM sqlite_temp_master"
2532 " WHERE type IN ('table','view')"
2533 " AND name NOT LIKE 'sqlite_%%'"
2534 " AND name LIKE ?1", zSql);
2535 }else{
2536 zSql = sqlite3_mprintf(
2537 "%z UNION ALL "
2538 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2539 " WHERE type IN ('table','view')"
2540 " AND name NOT LIKE 'sqlite_%%'"
2541 " AND name LIKE ?1", zSql, zDbName, zDbName);
2542 }
drha50da102000-08-08 20:19:09 +00002543 }
drh98781232012-04-23 12:38:05 +00002544 sqlite3_finalize(pStmt);
2545 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2546 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2547 sqlite3_free(zSql);
2548 if( rc ) return rc;
2549 nRow = nAlloc = 0;
2550 azResult = 0;
2551 if( nArg>1 ){
2552 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002553 }else{
drh98781232012-04-23 12:38:05 +00002554 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2555 }
2556 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2557 if( nRow>=nAlloc ){
2558 char **azNew;
2559 int n = nAlloc*2 + 10;
2560 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2561 if( azNew==0 ){
2562 fprintf(stderr, "Error: out of memory\n");
2563 break;
2564 }
2565 nAlloc = n;
2566 azResult = azNew;
2567 }
2568 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2569 if( azResult[nRow] ) nRow++;
2570 }
2571 sqlite3_finalize(pStmt);
2572 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002573 int len, maxlen = 0;
2574 int i, j;
2575 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002576 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002577 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002578 if( len>maxlen ) maxlen = len;
2579 }
2580 nPrintCol = 80/(maxlen+2);
2581 if( nPrintCol<1 ) nPrintCol = 1;
2582 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2583 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002584 for(j=i; j<nRow; j+=nPrintRow){
2585 char *zSp = j<nPrintRow ? "" : " ";
drh151b7d52013-05-06 20:28:54 +00002586 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
drhe3710332000-09-29 13:30:53 +00002587 }
drh151b7d52013-05-06 20:28:54 +00002588 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00002589 }
2590 }
drh98781232012-04-23 12:38:05 +00002591 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2592 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002593 }else
2594
shaneh96887e12011-02-10 21:08:58 +00002595 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002596 static const struct {
2597 const char *zCtrlName; /* Name of a test-control option */
2598 int ctrlCode; /* Integer code for that option */
2599 } aCtrl[] = {
2600 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2601 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2602 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2603 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2604 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2605 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2606 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2607 { "assert", SQLITE_TESTCTRL_ASSERT },
2608 { "always", SQLITE_TESTCTRL_ALWAYS },
2609 { "reserve", SQLITE_TESTCTRL_RESERVE },
2610 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2611 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002612 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2613 };
shaneh96887e12011-02-10 21:08:58 +00002614 int testctrl = -1;
2615 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002616 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002617 open_db(p);
2618
drhd416fe72011-03-17 16:45:50 +00002619 /* convert testctrl text option to value. allow any unique prefix
2620 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002621 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002622 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002623 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2624 if( testctrl<0 ){
2625 testctrl = aCtrl[i].ctrlCode;
2626 }else{
drhb07028f2011-10-14 21:49:18 +00002627 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002628 testctrl = -1;
2629 break;
2630 }
2631 }
2632 }
drh348d19c2013-06-03 12:47:43 +00002633 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002634 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2635 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2636 }else{
2637 switch(testctrl){
2638
2639 /* sqlite3_test_control(int, db, int) */
2640 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2641 case SQLITE_TESTCTRL_RESERVE:
2642 if( nArg==3 ){
2643 int opt = (int)strtol(azArg[2], 0, 0);
2644 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00002645 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002646 } else {
drhd416fe72011-03-17 16:45:50 +00002647 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2648 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002649 }
2650 break;
2651
2652 /* sqlite3_test_control(int) */
2653 case SQLITE_TESTCTRL_PRNG_SAVE:
2654 case SQLITE_TESTCTRL_PRNG_RESTORE:
2655 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002656 if( nArg==2 ){
2657 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00002658 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002659 } else {
2660 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2661 }
2662 break;
2663
2664 /* sqlite3_test_control(int, uint) */
2665 case SQLITE_TESTCTRL_PENDING_BYTE:
2666 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00002667 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002668 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002669 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002670 } else {
drhd416fe72011-03-17 16:45:50 +00002671 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2672 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002673 }
2674 break;
2675
2676 /* sqlite3_test_control(int, int) */
2677 case SQLITE_TESTCTRL_ASSERT:
2678 case SQLITE_TESTCTRL_ALWAYS:
2679 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00002680 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002681 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002682 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002683 } else {
drhd416fe72011-03-17 16:45:50 +00002684 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2685 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002686 }
2687 break;
2688
2689 /* sqlite3_test_control(int, char *) */
2690#ifdef SQLITE_N_KEYWORD
2691 case SQLITE_TESTCTRL_ISKEYWORD:
2692 if( nArg==3 ){
2693 const char *opt = azArg[2];
2694 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002695 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002696 } else {
drhd416fe72011-03-17 16:45:50 +00002697 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2698 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002699 }
2700 break;
2701#endif
2702
2703 case SQLITE_TESTCTRL_BITVEC_TEST:
2704 case SQLITE_TESTCTRL_FAULT_INSTALL:
2705 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2706 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2707 default:
drhd416fe72011-03-17 16:45:50 +00002708 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2709 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002710 break;
2711 }
2712 }
2713 }else
2714
shanehe2aa9d72009-11-06 17:20:17 +00002715 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002716 open_db(p);
drh348d19c2013-06-03 12:47:43 +00002717 sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002718 }else
2719
drhd416fe72011-03-17 16:45:50 +00002720 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2721 && nArg==2
2722 ){
drh3b1a9882007-11-02 12:53:03 +00002723 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002724 }else
2725
drh42f64e52012-04-04 16:56:23 +00002726 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh98781232012-04-23 12:38:05 +00002727 open_db(p);
drh42f64e52012-04-04 16:56:23 +00002728 output_file_close(p->traceOut);
2729 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00002730#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002731 if( p->traceOut==0 ){
2732 sqlite3_trace(p->db, 0, 0);
2733 }else{
2734 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2735 }
2736#endif
2737 }else
2738
drh9fd301b2011-06-03 13:28:22 +00002739 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00002740 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002741 sqlite3_libversion(), sqlite3_sourceid());
2742 }else
2743
drhde60fc22011-12-14 17:53:36 +00002744 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2745 const char *zDbName = nArg==2 ? azArg[1] : "main";
2746 char *zVfsName = 0;
2747 if( p->db ){
2748 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2749 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00002750 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00002751 sqlite3_free(zVfsName);
2752 }
2753 }
2754 }else
2755
drhcef4fc82012-09-21 22:50:45 +00002756#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2757 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
2758 extern int sqlite3WhereTrace;
drh7d9f3942013-04-03 01:26:54 +00002759 sqlite3WhereTrace = booleanValue(azArg[1]);
drhcef4fc82012-09-21 22:50:45 +00002760 }else
2761#endif
2762
shanehe2aa9d72009-11-06 17:20:17 +00002763 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002764 int j;
drh43617e92006-03-06 20:55:46 +00002765 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002766 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00002767 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00002768 }
2769 }else
2770
2771 {
shane9bd1b442009-10-23 01:27:39 +00002772 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002773 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002774 rc = 1;
drh75897232000-05-29 14:26:00 +00002775 }
drh67505e72002-04-19 12:34:06 +00002776
2777 return rc;
drh75897232000-05-29 14:26:00 +00002778}
2779
drh67505e72002-04-19 12:34:06 +00002780/*
drh91a66392007-09-07 01:12:32 +00002781** Return TRUE if a semicolon occurs anywhere in the first N characters
2782** of string z[].
drh324ccef2003-02-05 14:06:20 +00002783*/
drh91a66392007-09-07 01:12:32 +00002784static int _contains_semicolon(const char *z, int N){
2785 int i;
2786 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2787 return 0;
drh324ccef2003-02-05 14:06:20 +00002788}
2789
2790/*
drh70c7a4b2003-04-26 03:03:06 +00002791** Test to see if a line consists entirely of whitespace.
2792*/
2793static int _all_whitespace(const char *z){
2794 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002795 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002796 if( *z=='/' && z[1]=='*' ){
2797 z += 2;
2798 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2799 if( *z==0 ) return 0;
2800 z++;
2801 continue;
2802 }
2803 if( *z=='-' && z[1]=='-' ){
2804 z += 2;
2805 while( *z && *z!='\n' ){ z++; }
2806 if( *z==0 ) return 1;
2807 continue;
2808 }
2809 return 0;
2810 }
2811 return 1;
2812}
2813
2814/*
drha9b17162003-04-29 18:01:28 +00002815** Return TRUE if the line typed in is an SQL command terminator other
2816** than a semi-colon. The SQL Server style "go" command is understood
2817** as is the Oracle "/".
2818*/
2819static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002820 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002821 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2822 return 1; /* Oracle */
2823 }
drhf0693c82011-10-11 20:41:54 +00002824 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002825 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002826 return 1; /* SQL Server */
2827 }
2828 return 0;
2829}
2830
2831/*
drh233a5312008-12-18 22:25:13 +00002832** Return true if zSql is a complete SQL statement. Return false if it
2833** ends in the middle of a string literal or C-style comment.
2834*/
2835static int _is_complete(char *zSql, int nSql){
2836 int rc;
2837 if( zSql==0 ) return 1;
2838 zSql[nSql] = ';';
2839 zSql[nSql+1] = 0;
2840 rc = sqlite3_complete(zSql);
2841 zSql[nSql] = 0;
2842 return rc;
2843}
2844
2845/*
drh67505e72002-04-19 12:34:06 +00002846** Read input from *in and process it. If *in==0 then input
2847** is interactive - the user is typing it it. Otherwise, input
2848** is coming from a file or device. A prompt is issued and history
2849** is saved only if input is interactive. An interrupt signal will
2850** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002851**
2852** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002853*/
drhc28490c2006-10-26 14:25:58 +00002854static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002855 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002856 char *zSql = 0;
2857 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002858 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002859 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002860 int rc;
2861 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002862 int lineno = 0;
2863 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002864
2865 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2866 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002867 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002868 zLine = one_input_line(zSql, in);
2869 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002870 /* End of input */
2871 if( stdin_is_interactive ) printf("\n");
2872 break;
drhc49f44e2006-10-26 18:15:42 +00002873 }
drh67505e72002-04-19 12:34:06 +00002874 if( seenInterrupt ){
2875 if( in!=0 ) break;
2876 seenInterrupt = 0;
2877 }
drhc28490c2006-10-26 14:25:58 +00002878 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002879 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002880 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002881 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002882 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002883 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002884 break;
2885 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002886 errCnt++;
2887 }
drhdaffd0e2001-04-11 14:28:42 +00002888 continue;
2889 }
drh233a5312008-12-18 22:25:13 +00002890 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002891 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002892 }
drh91a66392007-09-07 01:12:32 +00002893 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002894 if( zSql==0 ){
2895 int i;
drhf0693c82011-10-11 20:41:54 +00002896 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002897 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002898 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002899 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002900 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002901 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002902 exit(1);
2903 }
drh5bb3eb92007-05-04 13:15:55 +00002904 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002905 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002906 }
2907 }else{
drh4f21c4a2008-12-10 22:15:00 +00002908 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002909 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002910 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002911 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002912 exit(1);
2913 }
drh5bb3eb92007-05-04 13:15:55 +00002914 zSql[nSql++] = '\n';
2915 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002916 nSql += len;
2917 }
drh91a66392007-09-07 01:12:32 +00002918 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2919 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002920 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002921 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002922 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002923 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002924 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002925 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002926 char zPrefix[100];
2927 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002928 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002929 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002930 }else{
shane9bd1b442009-10-23 01:27:39 +00002931 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002932 }
drh7f953e22002-07-13 17:33:45 +00002933 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002934 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002935 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002936 zErrMsg = 0;
2937 }else{
shaned2bed1c2009-10-21 03:56:54 +00002938 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002939 }
drhc49f44e2006-10-26 18:15:42 +00002940 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002941 }
2942 free(zSql);
2943 zSql = 0;
2944 nSql = 0;
drh7a411f42013-04-17 17:33:17 +00002945 }else if( zSql && _all_whitespace(zSql) ){
2946 free(zSql);
2947 zSql = 0;
2948 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00002949 }
2950 }
2951 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002952 if( !_all_whitespace(zSql) ){
2953 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2954 }
drhdaffd0e2001-04-11 14:28:42 +00002955 free(zSql);
2956 }
danielk19772ac27622007-07-03 05:31:16 +00002957 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00002958 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00002959}
2960
drh67505e72002-04-19 12:34:06 +00002961/*
2962** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002963** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002964*/
2965static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002966 static char *home_dir = NULL;
2967 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002968
drh83905c92012-06-21 13:00:37 +00002969#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00002970 {
2971 struct passwd *pwent;
2972 uid_t uid = getuid();
2973 if( (pwent=getpwuid(uid)) != NULL) {
2974 home_dir = pwent->pw_dir;
2975 }
drh67505e72002-04-19 12:34:06 +00002976 }
2977#endif
2978
chw65d3c132007-11-12 21:09:10 +00002979#if defined(_WIN32_WCE)
2980 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2981 */
drh85e72432012-04-11 11:38:53 +00002982 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00002983#else
2984
drh83905c92012-06-21 13:00:37 +00002985#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00002986 if (!home_dir) {
2987 home_dir = getenv("USERPROFILE");
2988 }
2989#endif
2990
drh67505e72002-04-19 12:34:06 +00002991 if (!home_dir) {
2992 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002993 }
2994
drh83905c92012-06-21 13:00:37 +00002995#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00002996 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002997 char *zDrive, *zPath;
2998 int n;
2999 zDrive = getenv("HOMEDRIVE");
3000 zPath = getenv("HOMEPATH");
3001 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00003002 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00003003 home_dir = malloc( n );
3004 if( home_dir==0 ) return 0;
3005 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3006 return home_dir;
3007 }
3008 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00003009 }
3010#endif
3011
chw65d3c132007-11-12 21:09:10 +00003012#endif /* !_WIN32_WCE */
3013
drh67505e72002-04-19 12:34:06 +00003014 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00003015 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00003016 char *z = malloc( n );
3017 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00003018 home_dir = z;
3019 }
drhe98d4fa2002-04-21 19:06:22 +00003020
drh67505e72002-04-19 12:34:06 +00003021 return home_dir;
3022}
3023
3024/*
3025** Read input from the file given by sqliterc_override. Or if that
3026** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00003027**
3028** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00003029*/
shane9bd1b442009-10-23 01:27:39 +00003030static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00003031 struct callback_data *p, /* Configuration data */
3032 const char *sqliterc_override /* Name of config file. NULL to use default */
3033){
persicom7e2dfdd2002-04-18 02:46:52 +00003034 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00003035 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00003036 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003037 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00003038 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003039
3040 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00003041 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00003042 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00003043#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00003044 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00003045#endif
shane9bd1b442009-10-23 01:27:39 +00003046 return 1;
drhe98d4fa2002-04-21 19:06:22 +00003047 }
drh2f3de322012-06-27 16:41:31 +00003048 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00003049 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
3050 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003051 }
drha1f9b5e2004-02-14 16:31:02 +00003052 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00003053 if( in ){
drhc28490c2006-10-26 14:25:58 +00003054 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00003055 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00003056 }
shane9bd1b442009-10-23 01:27:39 +00003057 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00003058 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00003059 }
drh85e72432012-04-11 11:38:53 +00003060 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00003061 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00003062}
3063
drh67505e72002-04-19 12:34:06 +00003064/*
drhe1e38c42003-05-04 18:30:59 +00003065** Show available command line options
3066*/
3067static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00003068 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00003069 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003070 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00003071 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00003072 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00003073 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00003074 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00003075 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00003076#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3077 " -heap SIZE Size of heap for memsys3 or memsys5\n"
3078#endif
drhcc3b4f82012-02-07 14:13:50 +00003079 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00003080 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00003081 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003082 " -line set output mode to 'line'\n"
3083 " -list set output mode to 'list'\n"
drh7d9f3942013-04-03 01:26:54 +00003084 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00003085#ifdef SQLITE_ENABLE_MULTIPLEX
3086 " -multiplex enable the multiplexor VFS\n"
3087#endif
drh98d312f2012-10-25 15:23:14 +00003088 " -nullvalue TEXT set text string for NULL values. Default ''\n"
3089 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00003090 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00003091 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00003092 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00003093#ifdef SQLITE_ENABLE_VFSTRACE
3094 " -vfstrace enable tracing of all VFS calls\n"
3095#endif
drhe1e38c42003-05-04 18:30:59 +00003096;
3097static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00003098 fprintf(stderr,
3099 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3100 "FILENAME is the name of an SQLite database. A new database is created\n"
3101 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00003102 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00003103 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00003104 }else{
3105 fprintf(stderr, "Use the -help option for additional information\n");
3106 }
3107 exit(1);
3108}
3109
3110/*
drh67505e72002-04-19 12:34:06 +00003111** Initialize the state information in data
3112*/
drh0850b532006-01-31 19:31:43 +00003113static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00003114 memset(data, 0, sizeof(*data));
3115 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00003116 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00003117 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00003118 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00003119 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00003120 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3121 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00003122 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00003123}
3124
drh98d312f2012-10-25 15:23:14 +00003125/*
3126** Get the argument to an --option. Throw an error and die if no argument
3127** is available.
3128*/
3129static char *cmdline_option_value(int argc, char **argv, int i){
3130 if( i==argc ){
3131 fprintf(stderr, "%s: Error: missing argument to %s\n",
3132 argv[0], argv[argc-1]);
3133 exit(1);
3134 }
3135 return argv[i];
3136}
3137
drh75897232000-05-29 14:26:00 +00003138int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003139 char *zErrMsg = 0;
3140 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00003141 const char *zInitFile = 0;
3142 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003143 int i;
drhc28490c2006-10-26 14:25:58 +00003144 int rc = 0;
drh75897232000-05-29 14:26:00 +00003145
drh52784bd2011-05-18 17:15:06 +00003146 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
3147 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
3148 sqlite3_sourceid(), SQLITE_SOURCE_ID);
3149 exit(1);
3150 }
drhdaffd0e2001-04-11 14:28:42 +00003151 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003152 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003153 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003154
drh44c2eb12003-04-30 11:38:26 +00003155 /* Make sure we have a valid signal handler early, before anything
3156 ** else is done.
3157 */
drh4c504392000-10-16 22:06:40 +00003158#ifdef SIGINT
3159 signal(SIGINT, interrupt_handler);
3160#endif
drh44c2eb12003-04-30 11:38:26 +00003161
drh22fbcb82004-02-01 01:22:50 +00003162 /* Do an initial pass through the command-line argument to locate
3163 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00003164 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00003165 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003166 */
drh98d312f2012-10-25 15:23:14 +00003167 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00003168 char *z;
drhc28490c2006-10-26 14:25:58 +00003169 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003170 if( z[0]!='-' ){
3171 if( data.zDbFilename==0 ){
3172 data.zDbFilename = z;
3173 continue;
3174 }
3175 if( zFirstCmd==0 ){
3176 zFirstCmd = z;
3177 continue;
3178 }
3179 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
3180 fprintf(stderr,"Use -help for a list of options.\n");
3181 return 1;
3182 }
drhcc3b4f82012-02-07 14:13:50 +00003183 if( z[1]=='-' ) z++;
3184 if( strcmp(z,"-separator")==0
3185 || strcmp(z,"-nullvalue")==0
3186 || strcmp(z,"-cmd")==0
3187 ){
drh98d312f2012-10-25 15:23:14 +00003188 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003189 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00003190 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003191 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00003192 /* Need to check for batch mode here to so we can avoid printing
3193 ** informational messages (like from process_sqliterc) before
3194 ** we do the actual processing of arguments later in a second pass.
3195 */
shanef69573d2009-10-24 02:06:14 +00003196 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00003197 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00003198#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00003199 int j, c;
3200 const char *zSize;
3201 sqlite3_int64 szHeap;
3202
drh98d312f2012-10-25 15:23:14 +00003203 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00003204 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00003205 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00003206 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3207#endif
drh97ae8ff2011-03-16 16:56:29 +00003208#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00003209 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00003210 extern int vfstrace_register(
3211 const char *zTraceName,
3212 const char *zOldVfsName,
3213 int (*xOut)(const char*,void*),
3214 void *pOutArg,
3215 int makeDefault
3216 );
drh2b625e22011-03-16 17:05:28 +00003217 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00003218#endif
drh6f25e892011-07-08 17:02:57 +00003219#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00003220 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00003221 extern int sqlite3_multiple_initialize(const char*,int);
3222 sqlite3_multiplex_initialize(0, 1);
3223#endif
drh7d9f3942013-04-03 01:26:54 +00003224 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00003225 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
3226 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00003227 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00003228 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00003229 if( pVfs ){
3230 sqlite3_vfs_register(pVfs, 1);
3231 }else{
3232 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3233 exit(1);
3234 }
drh44c2eb12003-04-30 11:38:26 +00003235 }
3236 }
drh98d312f2012-10-25 15:23:14 +00003237 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00003238#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003239 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003240#else
shane86f5bdb2009-10-24 02:00:07 +00003241 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3242 return 1;
drh01b41712005-08-29 23:06:23 +00003243#endif
drh98d312f2012-10-25 15:23:14 +00003244 }
3245 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00003246
drh44c2eb12003-04-30 11:38:26 +00003247 /* Go ahead and open the database file if it already exists. If the
3248 ** file does not exist, delay opening it. This prevents empty database
3249 ** files from being created if a user mistypes the database name argument
3250 ** to the sqlite command-line tool.
3251 */
drhc8d74412004-08-31 23:41:26 +00003252 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003253 open_db(&data);
3254 }
3255
drh22fbcb82004-02-01 01:22:50 +00003256 /* Process the initialization file if there is one. If no -init option
3257 ** is given on the command line, look for a file named ~/.sqliterc and
3258 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003259 */
shane86f5bdb2009-10-24 02:00:07 +00003260 rc = process_sqliterc(&data,zInitFile);
3261 if( rc>0 ){
3262 return rc;
3263 }
drh44c2eb12003-04-30 11:38:26 +00003264
drh22fbcb82004-02-01 01:22:50 +00003265 /* Make a second pass through the command-line argument and set
3266 ** options. This second pass is delayed until after the initialization
3267 ** file is processed so that the command-line arguments will override
3268 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003269 */
drh98d312f2012-10-25 15:23:14 +00003270 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00003271 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003272 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00003273 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003274 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003275 i++;
3276 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003277 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003278 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003279 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003280 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003281 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003282 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003283 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003284 }else if( strcmp(z,"-csv")==0 ){
3285 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003286 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003287 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003288 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00003289 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003290 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003291 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00003292 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003293 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003294 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003295 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003296 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003297 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003298 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003299 }else if( strcmp(z,"-stats")==0 ){
3300 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003301 }else if( strcmp(z,"-bail")==0 ){
3302 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003303 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003304 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003305 return 0;
drhc28490c2006-10-26 14:25:58 +00003306 }else if( strcmp(z,"-interactive")==0 ){
3307 stdin_is_interactive = 1;
3308 }else if( strcmp(z,"-batch")==0 ){
3309 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003310 }else if( strcmp(z,"-heap")==0 ){
3311 i++;
drh7d9f3942013-04-03 01:26:54 +00003312 }else if( strcmp(z,"-mmap")==0 ){
3313 i++;
drha7e61d82011-03-12 17:02:57 +00003314 }else if( strcmp(z,"-vfs")==0 ){
3315 i++;
drh6f25e892011-07-08 17:02:57 +00003316#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003317 }else if( strcmp(z,"-vfstrace")==0 ){
3318 i++;
drh6f25e892011-07-08 17:02:57 +00003319#endif
3320#ifdef SQLITE_ENABLE_MULTIPLEX
3321 }else if( strcmp(z,"-multiplex")==0 ){
3322 i++;
3323#endif
drhcc3b4f82012-02-07 14:13:50 +00003324 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003325 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003326 }else if( strcmp(z,"-cmd")==0 ){
3327 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00003328 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00003329 if( z[0]=='.' ){
3330 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00003331 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00003332 }else{
3333 open_db(&data);
3334 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3335 if( zErrMsg!=0 ){
3336 fprintf(stderr,"Error: %s\n", zErrMsg);
3337 if( bail_on_error ) return rc!=0 ? rc : 1;
3338 }else if( rc!=0 ){
3339 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3340 if( bail_on_error ) return rc;
3341 }
3342 }
drh1e5d0e92000-05-31 23:33:17 +00003343 }else{
shane86f5bdb2009-10-24 02:00:07 +00003344 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003345 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003346 return 1;
3347 }
3348 }
drh44c2eb12003-04-30 11:38:26 +00003349
drh22fbcb82004-02-01 01:22:50 +00003350 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003351 /* Run just the command that follows the database name
3352 */
drh22fbcb82004-02-01 01:22:50 +00003353 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003354 rc = do_meta_command(zFirstCmd, &data);
drh99b39082013-04-17 12:19:48 +00003355 if( rc==2 ) rc = 0;
drh6ff13852001-11-25 13:18:23 +00003356 }else{
drh44c2eb12003-04-30 11:38:26 +00003357 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003358 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003359 if( zErrMsg!=0 ){
3360 fprintf(stderr,"Error: %s\n", zErrMsg);
3361 return rc!=0 ? rc : 1;
3362 }else if( rc!=0 ){
3363 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3364 return rc;
drh6ff13852001-11-25 13:18:23 +00003365 }
drh75897232000-05-29 14:26:00 +00003366 }
3367 }else{
drh44c2eb12003-04-30 11:38:26 +00003368 /* Run commands received from standard input
3369 */
drhc28490c2006-10-26 14:25:58 +00003370 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003371 char *zHome;
3372 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003373 int nHistory;
drh75897232000-05-29 14:26:00 +00003374 printf(
drh743e0032011-12-12 16:51:50 +00003375 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003376 "Enter \".help\" for instructions\n"
3377 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003378 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003379 );
drh67505e72002-04-19 12:34:06 +00003380 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003381 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003382 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003383 if( (zHistory = malloc(nHistory))!=0 ){
3384 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3385 }
drh67505e72002-04-19 12:34:06 +00003386 }
danielk19774af00c62005-01-23 23:43:21 +00003387#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003388 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003389#endif
drhc28490c2006-10-26 14:25:58 +00003390 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003391 if( zHistory ){
3392 stifle_history(100);
3393 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003394 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003395 }
drhdaffd0e2001-04-11 14:28:42 +00003396 }else{
drhc28490c2006-10-26 14:25:58 +00003397 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003398 }
3399 }
drh33048c02001-10-01 14:29:22 +00003400 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003401 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003402 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003403 }
drhc28490c2006-10-26 14:25:58 +00003404 return rc;
drh75897232000-05-29 14:26:00 +00003405}