blob: afe01ef1a16f5f8d4c3ac6f6c267049d21fa91c8 [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
drhaaa21b42014-02-11 14:37:51 +000048#if defined(HAVE_READLINE) && HAVE_READLINE!=0
drh8e7e7a22000-05-30 18:45:23 +000049# include <readline/readline.h>
50# include <readline/history.h>
drhaaa21b42014-02-11 14:37:51 +000051#else
52# undef HAVE_READLINE
drh81d7fd12010-12-08 00:02:26 +000053#endif
drhaaa21b42014-02-11 14:37:51 +000054#if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE)
55# define HAVE_READLINE 1
56# include <editline/readline.h>
57#endif
58#if !defined(HAVE_READLINE)
persicom1d0b8722002-04-18 02:53:04 +000059# define add_history(X)
drh67505e72002-04-19 12:34:06 +000060# define read_history(X)
61# define write_history(X)
62# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000063#endif
64
adamd2e8464a2006-09-06 21:39:40 +000065#if defined(_WIN32) || defined(WIN32)
66# include <io.h>
drh6976c212014-07-24 12:09:47 +000067# include <fcntl.h>
shane18e526c2008-12-10 22:30:24 +000068#define isatty(h) _isatty(h)
drh07901eb2014-02-28 19:37:45 +000069#ifndef access
70# define access(f,m) _access((f),(m))
71#endif
drh67ceaa62012-08-27 21:19:03 +000072#undef popen
drh53371f92013-07-25 17:07:03 +000073#define popen _popen
drh67ceaa62012-08-27 21:19:03 +000074#undef pclose
drh12cd6cf2013-06-29 15:40:22 +000075#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +000076#else
drh4328c8b2003-04-26 02:50:11 +000077/* Make sure isatty() has a prototype.
78*/
drhb2acc3b2011-10-13 16:36:29 +000079extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +000080
drh53371f92013-07-25 17:07:03 +000081/* popen and pclose are not C89 functions and so are sometimes omitted from
82** the <stdio.h> header */
mistachkinf6418892013-08-28 01:54:12 +000083extern FILE *popen(const char*,const char*);
84extern int pclose(FILE*);
85#endif
drh53371f92013-07-25 17:07:03 +000086
chw65d3c132007-11-12 21:09:10 +000087#if defined(_WIN32_WCE)
88/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
89 * thus we always assume that we have a console. That can be
90 * overridden with the -batch command line option.
91 */
92#define isatty(x) 1
93#endif
94
drhf0693c82011-10-11 20:41:54 +000095/* ctype macros that work with signed characters */
96#define IsSpace(X) isspace((unsigned char)X)
97#define IsDigit(X) isdigit((unsigned char)X)
98#define ToLower(X) (char)tolower((unsigned char)X)
99
drh43408312013-10-30 12:43:36 +0000100
101/* True if the timer is enabled */
102static int enableTimer = 0;
103
104/* Return the current wall-clock time */
105static sqlite3_int64 timeOfDay(void){
106 static sqlite3_vfs *clockVfs = 0;
107 sqlite3_int64 t;
108 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
109 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
110 clockVfs->xCurrentTimeInt64(clockVfs, &t);
111 }else{
112 double r;
113 clockVfs->xCurrentTime(clockVfs, &r);
114 t = (sqlite3_int64)(r*86400000.0);
115 }
116 return t;
117}
118
drhd5d0f642013-02-20 00:54:21 +0000119#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
120 && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000121#include <sys/time.h>
122#include <sys/resource.h>
123
drhda108222009-02-25 19:07:24 +0000124/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000125static struct rusage sBegin; /* CPU time at start */
126static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000127
drhda108222009-02-25 19:07:24 +0000128/*
129** Begin timing an operation
130*/
131static void beginTimer(void){
132 if( enableTimer ){
133 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000134 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000135 }
136}
137
138/* Return the difference of two time_structs in seconds */
139static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
140 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
141 (double)(pEnd->tv_sec - pStart->tv_sec);
142}
143
144/*
145** Print the timing results.
146*/
147static void endTimer(void){
148 if( enableTimer ){
149 struct rusage sEnd;
drh43408312013-10-30 12:43:36 +0000150 sqlite3_int64 iEnd = timeOfDay();
drhda108222009-02-25 19:07:24 +0000151 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000152 printf("Run Time: real %.3f user %f sys %f\n",
153 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000154 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
155 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
156 }
157}
shaneb320ccd2009-10-21 03:42:58 +0000158
drhda108222009-02-25 19:07:24 +0000159#define BEGIN_TIMER beginTimer()
160#define END_TIMER endTimer()
161#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000162
163#elif (defined(_WIN32) || defined(WIN32))
164
165#include <windows.h>
166
167/* Saved resource information for the beginning of an operation */
168static HANDLE hProcess;
169static FILETIME ftKernelBegin;
170static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000171static sqlite3_int64 ftWallBegin;
shaneb320ccd2009-10-21 03:42:58 +0000172typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
173static GETPROCTIMES getProcessTimesAddr = NULL;
174
shaneb320ccd2009-10-21 03:42:58 +0000175/*
176** Check to see if we have timer support. Return 1 if necessary
177** support found (or found previously).
178*/
179static int hasTimer(void){
180 if( getProcessTimesAddr ){
181 return 1;
182 } else {
183 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
184 ** See if the version we are running on has it, and if it does, save off
185 ** a pointer to it and the current process handle.
186 */
187 hProcess = GetCurrentProcess();
188 if( hProcess ){
189 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
190 if( NULL != hinstLib ){
191 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
192 if( NULL != getProcessTimesAddr ){
193 return 1;
194 }
195 FreeLibrary(hinstLib);
196 }
197 }
198 }
199 return 0;
200}
201
202/*
203** Begin timing an operation
204*/
205static void beginTimer(void){
206 if( enableTimer && getProcessTimesAddr ){
207 FILETIME ftCreation, ftExit;
208 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
drh43408312013-10-30 12:43:36 +0000209 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000210 }
211}
212
213/* Return the difference of two FILETIME structs in seconds */
214static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
215 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
216 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
217 return (double) ((i64End - i64Start) / 10000000.0);
218}
219
220/*
221** Print the timing results.
222*/
223static void endTimer(void){
224 if( enableTimer && getProcessTimesAddr){
225 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000226 sqlite3_int64 ftWallEnd = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000227 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
drh43408312013-10-30 12:43:36 +0000228 printf("Run Time: real %.3f user %f sys %f\n",
229 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000230 timeDiff(&ftUserBegin, &ftUserEnd),
231 timeDiff(&ftKernelBegin, &ftKernelEnd));
232 }
233}
234
235#define BEGIN_TIMER beginTimer()
236#define END_TIMER endTimer()
237#define HAS_TIMER hasTimer()
238
drhda108222009-02-25 19:07:24 +0000239#else
240#define BEGIN_TIMER
241#define END_TIMER
242#define HAS_TIMER 0
243#endif
244
shanec0688ea2009-03-05 03:48:06 +0000245/*
246** Used to prevent warnings about unused parameters
247*/
248#define UNUSED_PARAMETER(x) (void)(x)
249
drhe91d16b2008-12-08 18:27:31 +0000250/*
drhc49f44e2006-10-26 18:15:42 +0000251** If the following flag is set, then command execution stops
252** at an error if we are not interactive.
253*/
254static int bail_on_error = 0;
255
256/*
drhc28490c2006-10-26 14:25:58 +0000257** Threat stdin as an interactive input if the following variable
258** is true. Otherwise, assume stdin is connected to a file or pipe.
259*/
260static int stdin_is_interactive = 1;
261
262/*
drh4c504392000-10-16 22:06:40 +0000263** The following is the open SQLite database. We make a pointer
264** to this database a static variable so that it can be accessed
265** by the SIGINT handler to interrupt database processing.
266*/
danielk197792f9a1b2004-06-19 09:08:16 +0000267static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000268
269/*
drh67505e72002-04-19 12:34:06 +0000270** True if an interrupt (Control-C) has been received.
271*/
drh43617e92006-03-06 20:55:46 +0000272static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000273
274/*
persicom7e2dfdd2002-04-18 02:46:52 +0000275** This is the name of our program. It is set in main(), used
276** in a number of other places, mostly for error messages.
277*/
278static char *Argv0;
279
280/*
281** Prompt strings. Initialized in main. Settable with
282** .prompt main continue
283*/
284static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
285static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
286
drhb0603412007-02-28 04:47:26 +0000287/*
288** Write I/O traces to the following stream.
289*/
rsebe0a9092007-07-30 18:24:38 +0000290#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000291static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000292#endif
drhb0603412007-02-28 04:47:26 +0000293
294/*
295** This routine works like printf in that its first argument is a
296** format string and subsequent arguments are values to be substituted
297** in place of % fields. The result of formatting this string
298** is written to iotrace.
299*/
rsebe0a9092007-07-30 18:24:38 +0000300#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000301static void iotracePrintf(const char *zFormat, ...){
302 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000303 char *z;
drhb0603412007-02-28 04:47:26 +0000304 if( iotrace==0 ) return;
305 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000306 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000307 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000308 fprintf(iotrace, "%s", z);
309 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000310}
rsebe0a9092007-07-30 18:24:38 +0000311#endif
drhb0603412007-02-28 04:47:26 +0000312
drh44c2eb12003-04-30 11:38:26 +0000313
persicom7e2dfdd2002-04-18 02:46:52 +0000314/*
drh83965662003-04-17 02:54:13 +0000315** Determines if a string is a number of not.
316*/
danielk19772e588c72005-12-09 14:25:08 +0000317static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000318 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000319 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000320 return 0;
321 }
322 z++;
323 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000324 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000325 if( *z=='.' ){
326 z++;
drhf0693c82011-10-11 20:41:54 +0000327 if( !IsDigit(*z) ) return 0;
328 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000329 if( realnum ) *realnum = 1;
330 }
331 if( *z=='e' || *z=='E' ){
332 z++;
333 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000334 if( !IsDigit(*z) ) return 0;
335 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000336 if( realnum ) *realnum = 1;
337 }
338 return *z==0;
339}
drh83965662003-04-17 02:54:13 +0000340
341/*
danielk1977bc6ada42004-06-30 08:20:16 +0000342** A global char* and an SQL function to access its current value
343** from within an SQL statement. This program used to use the
344** sqlite_exec_printf() API to substitue a string into an SQL statement.
345** The correct way to do this with sqlite3 is to use the bind API, but
346** since the shell is built around the callback paradigm it would be a lot
347** of work. Instead just use this hack, which is quite harmless.
348*/
349static const char *zShellStatic = 0;
350static void shellstaticFunc(
351 sqlite3_context *context,
352 int argc,
353 sqlite3_value **argv
354){
355 assert( 0==argc );
356 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000357 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000358 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000359 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
360}
361
362
363/*
drhfeac5f82004-08-01 00:10:45 +0000364** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000365** the text in memory obtained from malloc() and returns a pointer
366** to the text. NULL is returned at end of file, or if malloc()
367** fails.
368**
drh9f099fd2013-08-06 14:01:46 +0000369** If zLine is not NULL then it is a malloced buffer returned from
370** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000371*/
drh9f099fd2013-08-06 14:01:46 +0000372static char *local_getline(char *zLine, FILE *in){
373 int nLine = zLine==0 ? 0 : 100;
374 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000375
drhb07028f2011-10-14 21:49:18 +0000376 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000377 if( n+100>nLine ){
378 nLine = nLine*2 + 100;
379 zLine = realloc(zLine, nLine);
380 if( zLine==0 ) return 0;
381 }
drhdaffd0e2001-04-11 14:28:42 +0000382 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000383 if( n==0 ){
384 free(zLine);
385 return 0;
386 }
387 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000388 break;
389 }
drh9f099fd2013-08-06 14:01:46 +0000390 while( zLine[n] ) n++;
391 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000392 n--;
shaneh13b36022009-12-17 21:07:15 +0000393 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000394 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000395 break;
drh8e7e7a22000-05-30 18:45:23 +0000396 }
397 }
drh8e7e7a22000-05-30 18:45:23 +0000398 return zLine;
399}
400
401/*
drhc28490c2006-10-26 14:25:58 +0000402** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000403**
drh9f099fd2013-08-06 14:01:46 +0000404** If in==0 then read from standard input and prompt before each line.
405** If isContinuation is true, then a continuation prompt is appropriate.
406** If isContinuation is zero, then the main prompt should be used.
407**
408** If zPrior is not NULL then it is a buffer from a prior call to this
409** routine that can be reused.
410**
411** The result is stored in space obtained from malloc() and must either
412** be freed by the caller or else passed back into this routine via the
413** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000414*/
drh9f099fd2013-08-06 14:01:46 +0000415static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000416 char *zPrompt;
417 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000418 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000419 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000420 }else{
drh9f099fd2013-08-06 14:01:46 +0000421 zPrompt = isContinuation ? continuePrompt : mainPrompt;
drhaaa21b42014-02-11 14:37:51 +0000422#if defined(HAVE_READLINE)
drh9f099fd2013-08-06 14:01:46 +0000423 free(zPrior);
424 zResult = readline(zPrompt);
425 if( zResult && *zResult ) add_history(zResult);
426#else
427 printf("%s", zPrompt);
428 fflush(stdout);
429 zResult = local_getline(zPrior, stdin);
danielk19774af00c62005-01-23 23:43:21 +0000430#endif
drh9f099fd2013-08-06 14:01:46 +0000431 }
drh8e7e7a22000-05-30 18:45:23 +0000432 return zResult;
433}
434
drhdcd87a92014-08-18 13:45:42 +0000435/*
436** Shell output mode information from before ".explain on",
437** saved so that it can be restored by ".explain off"
438*/
439typedef struct SavedModeInfo SavedModeInfo;
440struct SavedModeInfo {
441 int valid; /* Is there legit data in here? */
442 int mode; /* Mode prior to ".explain on" */
443 int showHeader; /* The ".header" setting prior to ".explain on" */
444 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000445};
drh45e29d82006-11-20 16:21:10 +0000446
drh8e7e7a22000-05-30 18:45:23 +0000447/*
drhdcd87a92014-08-18 13:45:42 +0000448** State information about the database connection is contained in an
449** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000450*/
drhdcd87a92014-08-18 13:45:42 +0000451typedef struct ShellState ShellState;
452struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000453 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000454 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000455 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000456 int statsOn; /* True to display memory stats before each finalize */
drhc2ce0be2014-05-29 12:36:14 +0000457 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000458 int cnt; /* Number of records displayed so far */
459 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000460 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000461 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000462 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000463 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000464 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000465 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000466 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000467 char separator[20]; /* Separator character for MODE_List */
drh6976c212014-07-24 12:09:47 +0000468 char newline[20]; /* Record separator in MODE_Csv */
drha0c66f52000-07-29 13:20:21 +0000469 int colWidth[100]; /* Requested width of each column when in column mode*/
470 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000471 char nullvalue[20]; /* The text to print when a NULL comes back from
472 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000473 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000474 char outfile[FILENAME_MAX]; /* Filename for *out */
475 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000476 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000477 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000478 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000479 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000480 int *aiIndent; /* Array of indents used in MODE_Explain */
481 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000482 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000483};
484
485/*
drh44dec872014-08-30 15:49:25 +0000486** These are the allowed shellFlgs values
487*/
488#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
489#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
490#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
491
492/*
drh75897232000-05-29 14:26:00 +0000493** These are the allowed modes.
494*/
drh967e8b72000-06-21 13:59:10 +0000495#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000496#define MODE_Column 1 /* One record per line in neat columns */
497#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000498#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
499#define MODE_Html 4 /* Generate an XHTML table */
500#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000501#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000502#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000503#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000504
drh66ce4d02008-02-15 17:38:06 +0000505static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000506 "line",
507 "column",
508 "list",
509 "semi",
510 "html",
drhfeac5f82004-08-01 00:10:45 +0000511 "insert",
512 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000513 "csv",
drh66ce4d02008-02-15 17:38:06 +0000514 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000515};
drh75897232000-05-29 14:26:00 +0000516
517/*
518** Number of elements in an array
519*/
drh902b9ee2008-12-05 17:17:07 +0000520#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000521
522/*
drhea678832008-12-10 19:26:22 +0000523** Compute a string length that is limited to what can be stored in
524** lower 30 bits of a 32-bit signed integer.
525*/
drh4f21c4a2008-12-10 22:15:00 +0000526static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000527 const char *z2 = z;
528 while( *z2 ){ z2++; }
529 return 0x3fffffff & (int)(z2 - z);
530}
531
532/*
drh127f9d72010-02-23 01:47:00 +0000533** A callback for the sqlite3_log() interface.
534*/
535static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000536 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000537 if( p->pLog==0 ) return;
538 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
539 fflush(p->pLog);
540}
541
542/*
shane626a6e42009-10-22 17:30:15 +0000543** Output the given string as a hex-encoded blob (eg. X'1234' )
544*/
545static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
546 int i;
547 char *zBlob = (char *)pBlob;
548 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000549 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000550 fprintf(out,"'");
551}
552
553/*
drh28bd4bc2000-06-15 15:57:22 +0000554** Output the given string as a quoted string using SQL quoting conventions.
555*/
556static void output_quoted_string(FILE *out, const char *z){
557 int i;
558 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000559 for(i=0; z[i]; i++){
560 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000561 }
562 if( nSingle==0 ){
563 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000564 }else{
565 fprintf(out,"'");
566 while( *z ){
567 for(i=0; z[i] && z[i]!='\''; i++){}
568 if( i==0 ){
569 fprintf(out,"''");
570 z++;
571 }else if( z[i]=='\'' ){
572 fprintf(out,"%.*s''",i,z);
573 z += i+1;
574 }else{
drhcd7d2732002-02-26 23:24:26 +0000575 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000576 break;
577 }
578 }
drhcd7d2732002-02-26 23:24:26 +0000579 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000580 }
581}
582
583/*
drhfeac5f82004-08-01 00:10:45 +0000584** Output the given string as a quoted according to C or TCL quoting rules.
585*/
586static void output_c_string(FILE *out, const char *z){
587 unsigned int c;
588 fputc('"', out);
589 while( (c = *(z++))!=0 ){
590 if( c=='\\' ){
591 fputc(c, out);
592 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000593 }else if( c=='"' ){
594 fputc('\\', out);
595 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000596 }else if( c=='\t' ){
597 fputc('\\', out);
598 fputc('t', out);
599 }else if( c=='\n' ){
600 fputc('\\', out);
601 fputc('n', out);
602 }else if( c=='\r' ){
603 fputc('\\', out);
604 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000605 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000606 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000607 }else{
608 fputc(c, out);
609 }
610 }
611 fputc('"', out);
612}
613
614/*
drhc08a4f12000-06-15 16:49:48 +0000615** Output the given string with characters that are special to
616** HTML escaped.
617*/
618static void output_html_string(FILE *out, const char *z){
619 int i;
drhc3d6ba42014-01-13 20:38:35 +0000620 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000621 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000622 for(i=0; z[i]
623 && z[i]!='<'
624 && z[i]!='&'
625 && z[i]!='>'
626 && z[i]!='\"'
627 && z[i]!='\'';
628 i++){}
drhc08a4f12000-06-15 16:49:48 +0000629 if( i>0 ){
630 fprintf(out,"%.*s",i,z);
631 }
632 if( z[i]=='<' ){
633 fprintf(out,"&lt;");
634 }else if( z[i]=='&' ){
635 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000636 }else if( z[i]=='>' ){
637 fprintf(out,"&gt;");
638 }else if( z[i]=='\"' ){
639 fprintf(out,"&quot;");
640 }else if( z[i]=='\'' ){
641 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000642 }else{
643 break;
644 }
645 z += i + 1;
646 }
647}
648
649/*
drhc49f44e2006-10-26 18:15:42 +0000650** If a field contains any character identified by a 1 in the following
651** array, then the string must be quoted for CSV.
652*/
653static const char needCsvQuote[] = {
654 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
655 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
656 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
657 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
659 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
660 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
661 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
662 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
663 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
664 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
665 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
666 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
667 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
668 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
669 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
670};
671
672/*
drh8e64d1c2004-10-07 00:32:39 +0000673** Output a single term of CSV. Actually, p->separator is used for
674** the separator, which may or may not be a comma. p->nullvalue is
drh6976c212014-07-24 12:09:47 +0000675** the null value. Strings are quoted if necessary. The separator
676** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000677*/
drhdcd87a92014-08-18 13:45:42 +0000678static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000679 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000680 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000681 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000682 }else{
drhc49f44e2006-10-26 18:15:42 +0000683 int i;
drh4f21c4a2008-12-10 22:15:00 +0000684 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000685 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000686 if( needCsvQuote[((unsigned char*)z)[i]]
687 || (z[i]==p->separator[0] &&
688 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000689 i = 0;
690 break;
691 }
692 }
693 if( i==0 ){
694 putc('"', out);
695 for(i=0; z[i]; i++){
696 if( z[i]=='"' ) putc('"', out);
697 putc(z[i], out);
698 }
699 putc('"', out);
700 }else{
701 fprintf(out, "%s", z);
702 }
drh8e64d1c2004-10-07 00:32:39 +0000703 }
704 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000705 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000706 }
707}
708
danielk19774af00c62005-01-23 23:43:21 +0000709#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000710/*
drh4c504392000-10-16 22:06:40 +0000711** This routine runs when the user presses Ctrl-C
712*/
713static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000714 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000715 seenInterrupt++;
716 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000717 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000718}
danielk19774af00c62005-01-23 23:43:21 +0000719#endif
drh4c504392000-10-16 22:06:40 +0000720
721/*
shane626a6e42009-10-22 17:30:15 +0000722** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000723** invokes for each row of a query result.
724*/
shane626a6e42009-10-22 17:30:15 +0000725static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000726 int i;
drhdcd87a92014-08-18 13:45:42 +0000727 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000728
drh75897232000-05-29 14:26:00 +0000729 switch( p->mode ){
730 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000731 int w = 5;
drh6a535342001-10-19 16:44:56 +0000732 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000733 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000734 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000735 if( len>w ) w = len;
736 }
drh75897232000-05-29 14:26:00 +0000737 if( p->cnt++>0 ) fprintf(p->out,"\n");
738 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000739 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000740 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000741 }
742 break;
743 }
danielk19770d78bae2008-01-03 07:09:48 +0000744 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000745 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000746 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000747 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000748 int w, n;
749 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000750 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000751 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000752 w = 0;
drh75897232000-05-29 14:26:00 +0000753 }
drh078b1fd2012-09-21 13:40:02 +0000754 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000755 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000756 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000757 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000758 if( w<n ) w = n;
759 }
760 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000761 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000762 }
763 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000764 if( w<0 ){
765 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
766 }else{
767 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
768 }
drha0c66f52000-07-29 13:20:21 +0000769 }
770 }
771 if( p->showHeader ){
772 for(i=0; i<nArg; i++){
773 int w;
774 if( i<ArraySize(p->actualWidth) ){
775 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000776 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000777 }else{
778 w = 10;
779 }
780 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
781 "----------------------------------------------------------",
782 i==nArg-1 ? "\n": " ");
783 }
drh75897232000-05-29 14:26:00 +0000784 }
785 }
drh6a535342001-10-19 16:44:56 +0000786 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000787 for(i=0; i<nArg; i++){
788 int w;
drha0c66f52000-07-29 13:20:21 +0000789 if( i<ArraySize(p->actualWidth) ){
790 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000791 }else{
792 w = 10;
793 }
dana98bf362013-11-13 18:35:01 +0000794 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000795 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000796 }
dana98bf362013-11-13 18:35:01 +0000797 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000798 if( p->iIndent<p->nIndent ){
799 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000800 }
danc4650bb2013-11-18 08:41:06 +0000801 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000802 }
drh078b1fd2012-09-21 13:40:02 +0000803 if( w<0 ){
804 fprintf(p->out,"%*.*s%s",-w,-w,
805 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
806 }else{
807 fprintf(p->out,"%-*.*s%s",w,w,
808 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
809 }
drh75897232000-05-29 14:26:00 +0000810 }
811 break;
812 }
drhe3710332000-09-29 13:30:53 +0000813 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000814 case MODE_List: {
815 if( p->cnt++==0 && p->showHeader ){
816 for(i=0; i<nArg; i++){
817 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
818 }
819 }
drh6a535342001-10-19 16:44:56 +0000820 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000821 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000822 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000823 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000824 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000825 if( i<nArg-1 ){
826 fprintf(p->out, "%s", p->separator);
827 }else if( p->mode==MODE_Semi ){
828 fprintf(p->out, ";\n");
829 }else{
830 fprintf(p->out, "\n");
831 }
drh75897232000-05-29 14:26:00 +0000832 }
833 break;
834 }
drh1e5d0e92000-05-31 23:33:17 +0000835 case MODE_Html: {
836 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000837 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000838 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000839 fprintf(p->out,"<TH>");
840 output_html_string(p->out, azCol[i]);
841 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000842 }
mihailim57c591a2008-06-23 21:26:05 +0000843 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000844 }
drh6a535342001-10-19 16:44:56 +0000845 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000846 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000847 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000848 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000849 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000850 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000851 }
mihailim57c591a2008-06-23 21:26:05 +0000852 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000853 break;
854 }
drhfeac5f82004-08-01 00:10:45 +0000855 case MODE_Tcl: {
856 if( p->cnt++==0 && p->showHeader ){
857 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000858 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin585dcb22012-12-04 00:23:43 +0000859 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000860 }
861 fprintf(p->out,"\n");
862 }
863 if( azArg==0 ) break;
864 for(i=0; i<nArg; i++){
865 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mistachkin585dcb22012-12-04 00:23:43 +0000866 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000867 }
868 fprintf(p->out,"\n");
869 break;
870 }
drh8e64d1c2004-10-07 00:32:39 +0000871 case MODE_Csv: {
drh6976c212014-07-24 12:09:47 +0000872#if defined(WIN32) || defined(_WIN32)
873 fflush(p->out);
874 _setmode(_fileno(p->out), _O_BINARY);
875#endif
drh8e64d1c2004-10-07 00:32:39 +0000876 if( p->cnt++==0 && p->showHeader ){
877 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000878 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000879 }
drh6976c212014-07-24 12:09:47 +0000880 fprintf(p->out,"%s",p->newline);
drh8e64d1c2004-10-07 00:32:39 +0000881 }
drh6976c212014-07-24 12:09:47 +0000882 if( azArg>0 ){
883 for(i=0; i<nArg; i++){
884 output_csv(p, azArg[i], i<nArg-1);
885 }
886 fprintf(p->out,"%s",p->newline);
drh8e64d1c2004-10-07 00:32:39 +0000887 }
drh6976c212014-07-24 12:09:47 +0000888#if defined(WIN32) || defined(_WIN32)
889 fflush(p->out);
890 _setmode(_fileno(p->out), _O_TEXT);
891#endif
drh8e64d1c2004-10-07 00:32:39 +0000892 break;
893 }
drh28bd4bc2000-06-15 15:57:22 +0000894 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000895 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000896 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000897 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000898 for(i=0; i<nArg; i++){
899 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000900 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000901 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000902 }else if( aiType && aiType[i]==SQLITE_TEXT ){
903 if( zSep[0] ) fprintf(p->out,"%s",zSep);
904 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +0000905 }else if( aiType && (aiType[i]==SQLITE_INTEGER
906 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +0000907 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000908 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
909 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
910 int nBlob = sqlite3_column_bytes(p->pStmt, i);
911 if( zSep[0] ) fprintf(p->out,"%s",zSep);
912 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000913 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000914 fprintf(p->out,"%s%s",zSep, azArg[i]);
915 }else{
916 if( zSep[0] ) fprintf(p->out,"%s",zSep);
917 output_quoted_string(p->out, azArg[i]);
918 }
919 }
920 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000921 break;
drh28bd4bc2000-06-15 15:57:22 +0000922 }
persicom1d0b8722002-04-18 02:53:04 +0000923 }
drh75897232000-05-29 14:26:00 +0000924 return 0;
925}
926
927/*
shane626a6e42009-10-22 17:30:15 +0000928** This is the callback routine that the SQLite library
929** invokes for each row of a query result.
930*/
931static int callback(void *pArg, int nArg, char **azArg, char **azCol){
932 /* since we don't have type info, call the shell_callback with a NULL value */
933 return shell_callback(pArg, nArg, azArg, azCol, NULL);
934}
935
936/*
drhdcd87a92014-08-18 13:45:42 +0000937** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +0000938** the name of the table given. Escape any quote characters in the
939** table name.
940*/
drhdcd87a92014-08-18 13:45:42 +0000941static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +0000942 int i, n;
943 int needQuote;
944 char *z;
945
946 if( p->zDestTable ){
947 free(p->zDestTable);
948 p->zDestTable = 0;
949 }
950 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000951 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000952 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000953 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000954 needQuote = 1;
955 if( zName[i]=='\'' ) n++;
956 }
957 }
958 if( needQuote ) n += 2;
959 z = p->zDestTable = malloc( n+1 );
960 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000961 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000962 exit(1);
963 }
964 n = 0;
965 if( needQuote ) z[n++] = '\'';
966 for(i=0; zName[i]; i++){
967 z[n++] = zName[i];
968 if( zName[i]=='\'' ) z[n++] = '\'';
969 }
970 if( needQuote ) z[n++] = '\'';
971 z[n] = 0;
972}
973
danielk19772a02e332004-06-05 08:04:36 +0000974/* zIn is either a pointer to a NULL-terminated string in memory obtained
975** from malloc(), or a NULL pointer. The string pointed to by zAppend is
976** added to zIn, and the result returned in memory obtained from malloc().
977** zIn, if it was not NULL, is freed.
978**
979** If the third argument, quote, is not '\0', then it is used as a
980** quote character for zAppend.
981*/
drhc28490c2006-10-26 14:25:58 +0000982static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000983 int len;
984 int i;
drh4f21c4a2008-12-10 22:15:00 +0000985 int nAppend = strlen30(zAppend);
986 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000987
988 len = nAppend+nIn+1;
989 if( quote ){
990 len += 2;
991 for(i=0; i<nAppend; i++){
992 if( zAppend[i]==quote ) len++;
993 }
994 }
995
996 zIn = (char *)realloc(zIn, len);
997 if( !zIn ){
998 return 0;
999 }
1000
1001 if( quote ){
1002 char *zCsr = &zIn[nIn];
1003 *zCsr++ = quote;
1004 for(i=0; i<nAppend; i++){
1005 *zCsr++ = zAppend[i];
1006 if( zAppend[i]==quote ) *zCsr++ = quote;
1007 }
1008 *zCsr++ = quote;
1009 *zCsr++ = '\0';
1010 assert( (zCsr-zIn)==len );
1011 }else{
1012 memcpy(&zIn[nIn], zAppend, nAppend);
1013 zIn[len-1] = '\0';
1014 }
1015
1016 return zIn;
1017}
1018
drhdd3d4592004-08-30 01:54:05 +00001019
1020/*
drhb21a8e42012-01-28 21:08:51 +00001021** Execute a query statement that will generate SQL output. Print
1022** the result columns, comma-separated, on a line and then add a
1023** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001024**
drhb21a8e42012-01-28 21:08:51 +00001025** If the number of columns is 1 and that column contains text "--"
1026** then write the semicolon on a separate line. That way, if a
1027** "--" comment occurs at the end of the statement, the comment
1028** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001029*/
drh157e29a2009-05-21 15:15:00 +00001030static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001031 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001032 const char *zSelect, /* SELECT statement to extract content */
1033 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001034){
drhdd3d4592004-08-30 01:54:05 +00001035 sqlite3_stmt *pSelect;
1036 int rc;
drhb21a8e42012-01-28 21:08:51 +00001037 int nResult;
1038 int i;
1039 const char *z;
drhc7181902014-02-27 15:04:13 +00001040 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001041 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001042 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001043 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001044 return rc;
1045 }
1046 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001047 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001048 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001049 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001050 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001051 zFirstRow = 0;
1052 }
drhb21a8e42012-01-28 21:08:51 +00001053 z = (const char*)sqlite3_column_text(pSelect, 0);
1054 fprintf(p->out, "%s", z);
1055 for(i=1; i<nResult; i++){
1056 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1057 }
1058 if( z==0 ) z = "";
1059 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1060 if( z[0] ){
1061 fprintf(p->out, "\n;\n");
1062 }else{
1063 fprintf(p->out, ";\n");
1064 }
drhdd3d4592004-08-30 01:54:05 +00001065 rc = sqlite3_step(pSelect);
1066 }
drh2f464a02011-10-13 00:41:49 +00001067 rc = sqlite3_finalize(pSelect);
1068 if( rc!=SQLITE_OK ){
1069 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001070 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001071 }
1072 return rc;
drhdd3d4592004-08-30 01:54:05 +00001073}
1074
shane626a6e42009-10-22 17:30:15 +00001075/*
1076** Allocate space and save off current error string.
1077*/
1078static char *save_err_msg(
1079 sqlite3 *db /* Database to query */
1080){
1081 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1082 char *zErrMsg = sqlite3_malloc(nErrMsg);
1083 if( zErrMsg ){
1084 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1085 }
1086 return zErrMsg;
1087}
1088
1089/*
shaneh642d8b82010-07-28 16:05:34 +00001090** Display memory stats.
1091*/
1092static int display_stats(
1093 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001094 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001095 int bReset /* True to reset the stats */
1096){
1097 int iCur;
1098 int iHiwtr;
1099
1100 if( pArg && pArg->out ){
1101
1102 iHiwtr = iCur = -1;
1103 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001104 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001105 iHiwtr = iCur = -1;
1106 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001107 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001108 if( pArg->shellFlgs & SHFLG_Pagecache ){
1109 iHiwtr = iCur = -1;
1110 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1111 fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1112 }
shaneh642d8b82010-07-28 16:05:34 +00001113 iHiwtr = iCur = -1;
1114 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1115 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001116 if( pArg->shellFlgs & SHFLG_Scratch ){
1117 iHiwtr = iCur = -1;
1118 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1119 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1120 }
shaneh642d8b82010-07-28 16:05:34 +00001121 iHiwtr = iCur = -1;
1122 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1123 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1124 iHiwtr = iCur = -1;
1125 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1126 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1127 iHiwtr = iCur = -1;
1128 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1129 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1130 iHiwtr = iCur = -1;
1131 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1132 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1133#ifdef YYTRACKMAXSTACKDEPTH
1134 iHiwtr = iCur = -1;
1135 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1136 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1137#endif
1138 }
1139
1140 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001141 if( pArg->shellFlgs & SHFLG_Lookaside ){
1142 iHiwtr = iCur = -1;
1143 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1144 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
1145 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1146 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1147 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1148 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1149 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1150 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1151 }
shaneh642d8b82010-07-28 16:05:34 +00001152 iHiwtr = iCur = -1;
1153 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001154 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1155 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1156 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1157 iHiwtr = iCur = -1;
1158 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1159 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001160 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001161 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1162 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1163 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001164 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1165 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1166 iHiwtr = iCur = -1;
1167 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1168 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1169 }
1170
1171 if( pArg && pArg->out && db && pArg->pStmt ){
1172 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1173 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1174 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1175 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1176 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1177 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001178 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1179 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001180 }
1181
1182 return 0;
1183}
1184
1185/*
dana98bf362013-11-13 18:35:01 +00001186** Parameter azArray points to a zero-terminated array of strings. zStr
1187** points to a single nul-terminated string. Return non-zero if zStr
1188** is equal, according to strcmp(), to any of the strings in the array.
1189** Otherwise, return zero.
1190*/
1191static int str_in_array(const char *zStr, const char **azArray){
1192 int i;
1193 for(i=0; azArray[i]; i++){
1194 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1195 }
1196 return 0;
1197}
1198
1199/*
1200** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001201** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001202** spaces each opcode should be indented before it is output.
1203**
1204** The indenting rules are:
1205**
1206** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1207** all opcodes that occur between the p2 jump destination and the opcode
1208** itself by 2 spaces.
1209**
drh01752bc2013-11-14 23:59:33 +00001210** * For each "Goto", if the jump destination is earlier in the program
1211** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001212** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001213** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001214** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001215** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001216*/
drhdcd87a92014-08-18 13:45:42 +00001217static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001218 const char *zSql; /* The text of the SQL statement */
1219 const char *z; /* Used to check if this is an EXPLAIN */
1220 int *abYield = 0; /* True if op is an OP_Yield */
1221 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001222 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001223
drh8ad0de32014-03-20 18:45:27 +00001224 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1225 "NextIfOpen", "PrevIfOpen", 0 };
drhb463fef2014-05-29 20:17:57 +00001226 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001227 const char *azGoto[] = { "Goto", 0 };
1228
1229 /* Try to figure out if this is really an EXPLAIN statement. If this
1230 ** cannot be verified, return early. */
1231 zSql = sqlite3_sql(pSql);
1232 if( zSql==0 ) return;
1233 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1234 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1235
1236 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1237 int i;
danc4650bb2013-11-18 08:41:06 +00001238 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001239 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001240
1241 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1242 ** p2 is an instruction address, set variable p2op to the index of that
1243 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1244 ** the current instruction is part of a sub-program generated by an
1245 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001246 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001247 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001248
1249 /* Grow the p->aiIndent array as required */
1250 if( iOp>=nAlloc ){
1251 nAlloc += 100;
1252 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1253 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1254 }
1255 abYield[iOp] = str_in_array(zOp, azYield);
1256 p->aiIndent[iOp] = 0;
1257 p->nIndent = iOp+1;
1258
1259 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001260 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001261 }
drhfe705102014-03-06 13:38:37 +00001262 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1263 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1264 ){
drhe73f0592014-01-21 22:25:45 +00001265 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001266 }
1267 }
1268
danc4650bb2013-11-18 08:41:06 +00001269 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001270 sqlite3_free(abYield);
1271 sqlite3_reset(pSql);
1272}
1273
1274/*
1275** Free the array allocated by explain_data_prepare().
1276*/
drhdcd87a92014-08-18 13:45:42 +00001277static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001278 sqlite3_free(p->aiIndent);
1279 p->aiIndent = 0;
1280 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001281 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001282}
1283
1284/*
shane626a6e42009-10-22 17:30:15 +00001285** Execute a statement or set of statements. Print
1286** any result rows/columns depending on the current mode
1287** set via the supplied callback.
1288**
1289** This is very similar to SQLite's built-in sqlite3_exec()
1290** function except it takes a slightly different callback
1291** and callback data argument.
1292*/
1293static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001294 sqlite3 *db, /* An open database */
1295 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001296 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001297 /* (not the same as sqlite3_exec) */
1298 ShellState *pArg, /* Pointer to ShellState */
1299 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001300){
dan4564ced2010-01-05 04:59:56 +00001301 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1302 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001303 int rc2;
dan4564ced2010-01-05 04:59:56 +00001304 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001305
1306 if( pzErrMsg ){
1307 *pzErrMsg = NULL;
1308 }
1309
shaneb9fc17d2009-10-22 21:23:35 +00001310 while( zSql[0] && (SQLITE_OK == rc) ){
1311 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1312 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001313 if( pzErrMsg ){
1314 *pzErrMsg = save_err_msg(db);
1315 }
1316 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001317 if( !pStmt ){
1318 /* this happens for a comment or white-space */
1319 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001320 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001321 continue;
1322 }
shane626a6e42009-10-22 17:30:15 +00001323
shaneh642d8b82010-07-28 16:05:34 +00001324 /* save off the prepared statment handle and reset row count */
1325 if( pArg ){
1326 pArg->pStmt = pStmt;
1327 pArg->cnt = 0;
1328 }
1329
shanehb7977c52010-01-18 18:17:10 +00001330 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001331 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001332 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001333 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001334 }
shanehb7977c52010-01-18 18:17:10 +00001335
drhefbf3b12014-02-28 20:47:24 +00001336 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1337 if( pArg && pArg->autoEQP ){
1338 sqlite3_stmt *pExplain;
1339 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
1340 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1341 if( rc==SQLITE_OK ){
1342 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1343 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1344 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1345 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1346 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1347 }
1348 }
1349 sqlite3_finalize(pExplain);
1350 sqlite3_free(zEQP);
1351 }
1352
drh7e02e5e2011-12-06 19:44:51 +00001353 /* Output TESTCTRL_EXPLAIN text of requested */
1354 if( pArg && pArg->mode==MODE_Explain ){
1355 const char *zExplain = 0;
1356 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1357 if( zExplain && zExplain[0] ){
1358 fprintf(pArg->out, "%s", zExplain);
1359 }
1360 }
1361
dana98bf362013-11-13 18:35:01 +00001362 /* If the shell is currently in ".explain" mode, gather the extra
1363 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001364 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001365 explain_data_prepare(pArg, pStmt);
1366 }
1367
shaneb9fc17d2009-10-22 21:23:35 +00001368 /* perform the first step. this will tell us if we
1369 ** have a result set or not and how wide it is.
1370 */
1371 rc = sqlite3_step(pStmt);
1372 /* if we have a result set... */
1373 if( SQLITE_ROW == rc ){
1374 /* if we have a callback... */
1375 if( xCallback ){
1376 /* allocate space for col name ptr, value ptr, and type */
1377 int nCol = sqlite3_column_count(pStmt);
1378 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1379 if( !pData ){
1380 rc = SQLITE_NOMEM;
1381 }else{
1382 char **azCols = (char **)pData; /* Names of result columns */
1383 char **azVals = &azCols[nCol]; /* Results */
1384 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001385 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001386 assert(sizeof(int) <= sizeof(char *));
1387 /* save off ptrs to column names */
1388 for(i=0; i<nCol; i++){
1389 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1390 }
shaneb9fc17d2009-10-22 21:23:35 +00001391 do{
1392 /* extract the data and data types */
1393 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001394 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001395 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001396 azVals[i] = "";
1397 }else{
1398 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1399 }
shaneb9fc17d2009-10-22 21:23:35 +00001400 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1401 rc = SQLITE_NOMEM;
1402 break; /* from for */
1403 }
1404 } /* end for */
1405
1406 /* if data and types extracted successfully... */
1407 if( SQLITE_ROW == rc ){
1408 /* call the supplied callback with the result row data */
1409 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1410 rc = SQLITE_ABORT;
1411 }else{
1412 rc = sqlite3_step(pStmt);
1413 }
1414 }
1415 } while( SQLITE_ROW == rc );
1416 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001417 }
1418 }else{
1419 do{
1420 rc = sqlite3_step(pStmt);
1421 } while( rc == SQLITE_ROW );
1422 }
1423 }
1424
dana98bf362013-11-13 18:35:01 +00001425 explain_data_delete(pArg);
1426
shaneh642d8b82010-07-28 16:05:34 +00001427 /* print usage stats if stats on */
1428 if( pArg && pArg->statsOn ){
1429 display_stats(db, pArg, 0);
1430 }
1431
dan4564ced2010-01-05 04:59:56 +00001432 /* Finalize the statement just executed. If this fails, save a
1433 ** copy of the error message. Otherwise, set zSql to point to the
1434 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001435 rc2 = sqlite3_finalize(pStmt);
1436 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001437 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001438 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001439 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001440 }else if( pzErrMsg ){
1441 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001442 }
shaneh642d8b82010-07-28 16:05:34 +00001443
1444 /* clear saved stmt handle */
1445 if( pArg ){
1446 pArg->pStmt = NULL;
1447 }
shane626a6e42009-10-22 17:30:15 +00001448 }
shaneb9fc17d2009-10-22 21:23:35 +00001449 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001450
1451 return rc;
1452}
1453
drhdd3d4592004-08-30 01:54:05 +00001454
drh33048c02001-10-01 14:29:22 +00001455/*
drh4c653a02000-06-07 01:27:47 +00001456** This is a different callback routine used for dumping the database.
1457** Each row received by this callback consists of a table name,
1458** the table type ("index" or "table") and SQL to create the table.
1459** This routine should print text sufficient to recreate the table.
1460*/
1461static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001462 int rc;
1463 const char *zTable;
1464 const char *zType;
1465 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001466 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001467 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001468
drh902b9ee2008-12-05 17:17:07 +00001469 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001470 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001471 zTable = azArg[0];
1472 zType = azArg[1];
1473 zSql = azArg[2];
1474
drh00b950d2005-09-11 02:03:03 +00001475 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001476 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001477 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001478 fprintf(p->out, "ANALYZE sqlite_master;\n");
1479 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1480 return 0;
drh45e29d82006-11-20 16:21:10 +00001481 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1482 char *zIns;
1483 if( !p->writableSchema ){
1484 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1485 p->writableSchema = 1;
1486 }
1487 zIns = sqlite3_mprintf(
1488 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1489 "VALUES('table','%q','%q',0,'%q');",
1490 zTable, zTable, zSql);
1491 fprintf(p->out, "%s\n", zIns);
1492 sqlite3_free(zIns);
1493 return 0;
drh00b950d2005-09-11 02:03:03 +00001494 }else{
1495 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001496 }
danielk19772a02e332004-06-05 08:04:36 +00001497
1498 if( strcmp(zType, "table")==0 ){
1499 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001500 char *zSelect = 0;
1501 char *zTableInfo = 0;
1502 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001503 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001504
1505 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1506 zTableInfo = appendText(zTableInfo, zTable, '"');
1507 zTableInfo = appendText(zTableInfo, ");", 0);
1508
drhc7181902014-02-27 15:04:13 +00001509 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001510 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001511 if( rc!=SQLITE_OK || !pTableInfo ){
1512 return 1;
1513 }
1514
1515 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001516 /* Always quote the table name, even if it appears to be pure ascii,
1517 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1518 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001519 if( zTmp ){
1520 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001521 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001522 }
1523 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1524 rc = sqlite3_step(pTableInfo);
1525 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001526 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001527 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001528 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001529 rc = sqlite3_step(pTableInfo);
1530 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001531 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001532 }else{
1533 zSelect = appendText(zSelect, ") ", 0);
1534 }
drh157e29a2009-05-21 15:15:00 +00001535 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001536 }
1537 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001538 if( rc!=SQLITE_OK || nRow==0 ){
1539 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001540 return 1;
1541 }
1542 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1543 zSelect = appendText(zSelect, zTable, '"');
1544
drh2f464a02011-10-13 00:41:49 +00001545 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001546 if( rc==SQLITE_CORRUPT ){
1547 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001548 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001549 }
drh85e72432012-04-11 11:38:53 +00001550 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001551 }
drh4c653a02000-06-07 01:27:47 +00001552 return 0;
1553}
1554
1555/*
drh45e29d82006-11-20 16:21:10 +00001556** Run zQuery. Use dump_callback() as the callback routine so that
1557** the contents of the query are output as SQL statements.
1558**
drhdd3d4592004-08-30 01:54:05 +00001559** If we get a SQLITE_CORRUPT error, rerun the query after appending
1560** "ORDER BY rowid DESC" to the end.
1561*/
1562static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001563 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001564 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001565){
1566 int rc;
drh2f464a02011-10-13 00:41:49 +00001567 char *zErr = 0;
1568 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001569 if( rc==SQLITE_CORRUPT ){
1570 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001571 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001572 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1573 if( zErr ){
1574 fprintf(p->out, "/****** %s ******/\n", zErr);
1575 sqlite3_free(zErr);
1576 zErr = 0;
1577 }
drhdd3d4592004-08-30 01:54:05 +00001578 zQ2 = malloc( len+100 );
1579 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001580 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001581 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1582 if( rc ){
1583 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1584 }else{
1585 rc = SQLITE_CORRUPT;
1586 }
1587 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001588 free(zQ2);
1589 }
1590 return rc;
1591}
1592
1593/*
drh75897232000-05-29 14:26:00 +00001594** Text of a help message
1595*/
persicom1d0b8722002-04-18 02:53:04 +00001596static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001597 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001598 ".bail on|off Stop after hitting an error. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001599 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001600 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001601 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001602 " If TABLE specified, only dump tables matching\n"
1603 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001604 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001605 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001606 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001607 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001608 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001609 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001610 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001611 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001612 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001613 ".indices ?TABLE? Show names of all indices\n"
1614 " If TABLE specified, only show indices for tables\n"
1615 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001616#ifdef SQLITE_ENABLE_IOTRACE
1617 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1618#endif
drh70df4fe2006-06-13 15:12:21 +00001619#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001620 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001621#endif
drh127f9d72010-02-23 01:47:00 +00001622 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001623 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001624 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001625 " column Left-aligned columns. (See .width)\n"
1626 " html HTML <table> code\n"
1627 " insert SQL insert statements for TABLE\n"
1628 " line One value per line\n"
1629 " list Values delimited by .separator string\n"
1630 " tabs Tab-separated values\n"
1631 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001632 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001633 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001634 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001635 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001636 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001637 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001638 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001639 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001640 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001641 ".save FILE Write in-memory database into FILE\n"
drh75897232000-05-29 14:26:00 +00001642 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001643 " If TABLE specified, only show tables matching\n"
1644 " LIKE pattern TABLE.\n"
drh6976c212014-07-24 12:09:47 +00001645 ".separator STRING ?NL? Change separator used by output mode and .import\n"
1646 " NL is the end-of-line mark for CSV\n"
drh62cdde52014-05-28 20:22:28 +00001647 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001648 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001649 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001650 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001651 ".tables ?TABLE? List names of tables\n"
1652 " If TABLE specified, only list tables matching\n"
1653 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001654 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001655 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001656 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001657 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001658 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001659 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001660;
1661
drhdaffd0e2001-04-11 14:28:42 +00001662/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001663static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001664/*
1665** Implementation of the "readfile(X)" SQL function. The entire content
1666** of the file named X is read and returned as a BLOB. NULL is returned
1667** if the file does not exist or is unreadable.
1668*/
1669static void readfileFunc(
1670 sqlite3_context *context,
1671 int argc,
1672 sqlite3_value **argv
1673){
1674 const char *zName;
1675 FILE *in;
1676 long nIn;
1677 void *pBuf;
1678
1679 zName = (const char*)sqlite3_value_text(argv[0]);
1680 if( zName==0 ) return;
1681 in = fopen(zName, "rb");
1682 if( in==0 ) return;
1683 fseek(in, 0, SEEK_END);
1684 nIn = ftell(in);
1685 rewind(in);
1686 pBuf = sqlite3_malloc( nIn );
1687 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1688 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1689 }else{
1690 sqlite3_free(pBuf);
1691 }
1692 fclose(in);
1693}
1694
1695/*
1696** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1697** is written into file X. The number of bytes written is returned. Or
1698** NULL is returned if something goes wrong, such as being unable to open
1699** file X for writing.
1700*/
1701static void writefileFunc(
1702 sqlite3_context *context,
1703 int argc,
1704 sqlite3_value **argv
1705){
1706 FILE *out;
1707 const char *z;
drhba5b0932014-07-24 12:39:59 +00001708 sqlite3_int64 rc;
1709 const char *zFile;
1710
1711 zFile = (const char*)sqlite3_value_text(argv[0]);
1712 if( zFile==0 ) return;
1713 out = fopen(zFile, "wb");
1714 if( out==0 ) return;
1715 z = (const char*)sqlite3_value_blob(argv[1]);
1716 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001717 rc = 0;
1718 }else{
drh490fe862014-08-11 14:21:32 +00001719 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001720 }
1721 fclose(out);
1722 sqlite3_result_int64(context, rc);
1723}
drhdaffd0e2001-04-11 14:28:42 +00001724
drh75897232000-05-29 14:26:00 +00001725/*
drh44c2eb12003-04-30 11:38:26 +00001726** Make sure the database is open. If it is not, then open it. If
1727** the database fails to open, print an error message and exit.
1728*/
drhdcd87a92014-08-18 13:45:42 +00001729static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001730 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001731 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001732 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001733 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001734 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1735 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1736 shellstaticFunc, 0, 0);
1737 }
1738 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001739 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001740 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001741 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001742 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001743 }
drhc2e87a32006-06-27 15:16:14 +00001744#ifndef SQLITE_OMIT_LOAD_EXTENSION
1745 sqlite3_enable_load_extension(p->db, 1);
1746#endif
drhba5b0932014-07-24 12:39:59 +00001747 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1748 readfileFunc, 0, 0);
1749 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1750 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001751 }
1752}
1753
1754/*
drhfeac5f82004-08-01 00:10:45 +00001755** Do C-language style dequoting.
1756**
1757** \t -> tab
1758** \n -> newline
1759** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001760** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001761** \NNN -> ascii character NNN in octal
1762** \\ -> backslash
1763*/
1764static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001765 int i, j;
1766 char c;
drhc2ce0be2014-05-29 12:36:14 +00001767 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001768 for(i=j=0; (c = z[i])!=0; i++, j++){
1769 if( c=='\\' ){
1770 c = z[++i];
1771 if( c=='n' ){
1772 c = '\n';
1773 }else if( c=='t' ){
1774 c = '\t';
1775 }else if( c=='r' ){
1776 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001777 }else if( c=='\\' ){
1778 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001779 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001780 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001781 if( z[i+1]>='0' && z[i+1]<='7' ){
1782 i++;
1783 c = (c<<3) + z[i] - '0';
1784 if( z[i+1]>='0' && z[i+1]<='7' ){
1785 i++;
1786 c = (c<<3) + z[i] - '0';
1787 }
1788 }
1789 }
1790 }
1791 z[j] = c;
1792 }
drhc2ce0be2014-05-29 12:36:14 +00001793 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001794}
1795
1796/*
drh348d19c2013-06-03 12:47:43 +00001797** Return the value of a hexadecimal digit. Return -1 if the input
1798** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001799*/
drh348d19c2013-06-03 12:47:43 +00001800static int hexDigitValue(char c){
1801 if( c>='0' && c<='9' ) return c - '0';
1802 if( c>='a' && c<='f' ) return c - 'a' + 10;
1803 if( c>='A' && c<='F' ) return c - 'A' + 10;
1804 return -1;
drhc28490c2006-10-26 14:25:58 +00001805}
1806
1807/*
drh7d9f3942013-04-03 01:26:54 +00001808** Interpret zArg as an integer value, possibly with suffixes.
1809*/
1810static sqlite3_int64 integerValue(const char *zArg){
1811 sqlite3_int64 v = 0;
1812 static const struct { char *zSuffix; int iMult; } aMult[] = {
1813 { "KiB", 1024 },
1814 { "MiB", 1024*1024 },
1815 { "GiB", 1024*1024*1024 },
1816 { "KB", 1000 },
1817 { "MB", 1000000 },
1818 { "GB", 1000000000 },
1819 { "K", 1000 },
1820 { "M", 1000000 },
1821 { "G", 1000000000 },
1822 };
1823 int i;
1824 int isNeg = 0;
1825 if( zArg[0]=='-' ){
1826 isNeg = 1;
1827 zArg++;
1828 }else if( zArg[0]=='+' ){
1829 zArg++;
1830 }
drh348d19c2013-06-03 12:47:43 +00001831 if( zArg[0]=='0' && zArg[1]=='x' ){
1832 int x;
1833 zArg += 2;
1834 while( (x = hexDigitValue(zArg[0]))>=0 ){
1835 v = (v<<4) + x;
1836 zArg++;
1837 }
1838 }else{
1839 while( IsDigit(zArg[0]) ){
1840 v = v*10 + zArg[0] - '0';
1841 zArg++;
1842 }
drh7d9f3942013-04-03 01:26:54 +00001843 }
drhc2bed0a2013-05-24 11:57:50 +00001844 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001845 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1846 v *= aMult[i].iMult;
1847 break;
1848 }
1849 }
1850 return isNeg? -v : v;
1851}
1852
1853/*
drh348d19c2013-06-03 12:47:43 +00001854** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1855** for TRUE and FALSE. Return the integer value if appropriate.
1856*/
1857static int booleanValue(char *zArg){
1858 int i;
1859 if( zArg[0]=='0' && zArg[1]=='x' ){
1860 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1861 }else{
1862 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1863 }
1864 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1865 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1866 return 1;
1867 }
1868 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1869 return 0;
1870 }
1871 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1872 zArg);
1873 return 0;
1874}
1875
1876/*
drh42f64e52012-04-04 16:56:23 +00001877** Close an output file, assuming it is not stderr or stdout
1878*/
1879static void output_file_close(FILE *f){
1880 if( f && f!=stdout && f!=stderr ) fclose(f);
1881}
1882
1883/*
1884** Try to open an output file. The names "stdout" and "stderr" are
1885** recognized and do the right thing. NULL is returned if the output
1886** filename is "off".
1887*/
1888static FILE *output_file_open(const char *zFile){
1889 FILE *f;
1890 if( strcmp(zFile,"stdout")==0 ){
1891 f = stdout;
1892 }else if( strcmp(zFile, "stderr")==0 ){
1893 f = stderr;
1894 }else if( strcmp(zFile, "off")==0 ){
1895 f = 0;
1896 }else{
1897 f = fopen(zFile, "wb");
1898 if( f==0 ){
1899 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1900 }
1901 }
1902 return f;
1903}
1904
1905/*
1906** A routine for handling output from sqlite3_trace().
1907*/
1908static void sql_trace_callback(void *pArg, const char *z){
1909 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00001910 if( f ){
1911 int i = (int)strlen(z);
1912 while( i>0 && z[i-1]==';' ){ i--; }
1913 fprintf(f, "%.*s;\n", i, z);
1914 }
drh42f64e52012-04-04 16:56:23 +00001915}
1916
1917/*
drhd8621b92012-04-17 09:09:33 +00001918** A no-op routine that runs with the ".breakpoint" doc-command. This is
1919** a useful spot to set a debugger breakpoint.
1920*/
1921static void test_breakpoint(void){
1922 static int nCall = 0;
1923 nCall++;
1924}
1925
1926/*
drhdb95f682013-06-26 22:46:00 +00001927** An object used to read a CSV file
1928*/
1929typedef struct CSVReader CSVReader;
1930struct CSVReader {
1931 const char *zFile; /* Name of the input file */
1932 FILE *in; /* Read the CSV text from this input stream */
1933 char *z; /* Accumulated text for a field */
1934 int n; /* Number of bytes in z */
1935 int nAlloc; /* Space allocated for z[] */
1936 int nLine; /* Current line number */
1937 int cTerm; /* Character that terminated the most recent field */
1938 int cSeparator; /* The separator character. (Usually ",") */
1939};
1940
1941/* Append a single byte to z[] */
1942static void csv_append_char(CSVReader *p, int c){
1943 if( p->n+1>=p->nAlloc ){
1944 p->nAlloc += p->nAlloc + 100;
1945 p->z = sqlite3_realloc(p->z, p->nAlloc);
1946 if( p->z==0 ){
1947 fprintf(stderr, "out of memory\n");
1948 exit(1);
1949 }
1950 }
1951 p->z[p->n++] = (char)c;
1952}
1953
1954/* Read a single field of CSV text. Compatible with rfc4180 and extended
1955** with the option of having a separator other than ",".
1956**
1957** + Input comes from p->in.
1958** + Store results in p->z of length p->n. Space to hold p->z comes
1959** from sqlite3_malloc().
1960** + Use p->cSep as the separator. The default is ",".
1961** + Keep track of the line number in p->nLine.
1962** + Store the character that terminates the field in p->cTerm. Store
1963** EOF on end-of-file.
1964** + Report syntax errors on stderr
1965*/
1966static char *csv_read_one_field(CSVReader *p){
drha81ad172013-12-11 14:00:04 +00001967 int c, pc, ppc;
drhdb95f682013-06-26 22:46:00 +00001968 int cSep = p->cSeparator;
1969 p->n = 0;
1970 c = fgetc(p->in);
1971 if( c==EOF || seenInterrupt ){
1972 p->cTerm = EOF;
1973 return 0;
1974 }
1975 if( c=='"' ){
1976 int startLine = p->nLine;
1977 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00001978 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00001979 while( 1 ){
1980 c = fgetc(p->in);
1981 if( c=='\n' ) p->nLine++;
1982 if( c==cQuote ){
1983 if( pc==cQuote ){
1984 pc = 0;
1985 continue;
1986 }
1987 }
1988 if( (c==cSep && pc==cQuote)
1989 || (c=='\n' && pc==cQuote)
drha81ad172013-12-11 14:00:04 +00001990 || (c=='\n' && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00001991 || (c==EOF && pc==cQuote)
1992 ){
1993 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00001994 p->cTerm = c;
1995 break;
1996 }
1997 if( pc==cQuote && c!='\r' ){
1998 fprintf(stderr, "%s:%d: unescaped %c character\n",
1999 p->zFile, p->nLine, cQuote);
2000 }
2001 if( c==EOF ){
2002 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2003 p->zFile, startLine, cQuote);
drhdb95f682013-06-26 22:46:00 +00002004 p->cTerm = EOF;
2005 break;
2006 }
2007 csv_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002008 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002009 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002010 }
drhdb95f682013-06-26 22:46:00 +00002011 }else{
drhd0a64dc2013-06-30 20:24:26 +00002012 while( c!=EOF && c!=cSep && c!='\n' ){
drhdb95f682013-06-26 22:46:00 +00002013 csv_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002014 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002015 }
2016 if( c=='\n' ){
2017 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002018 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002019 }
drhdb95f682013-06-26 22:46:00 +00002020 p->cTerm = c;
2021 }
drh8dd675e2013-07-12 21:09:24 +00002022 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002023 return p->z;
2024}
2025
2026/*
drh4bbcf102014-02-06 02:46:08 +00002027** Try to transfer data for table zTable. If an error is seen while
2028** moving forward, try to go backwards. The backwards movement won't
2029** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002030*/
mistachkine31ae902014-02-06 01:15:29 +00002031static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002032 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002033 sqlite3 *newDb,
2034 const char *zTable
2035){
2036 sqlite3_stmt *pQuery = 0;
2037 sqlite3_stmt *pInsert = 0;
2038 char *zQuery = 0;
2039 char *zInsert = 0;
2040 int rc;
2041 int i, j, n;
2042 int nTable = (int)strlen(zTable);
2043 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002044 int cnt = 0;
2045 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002046
2047 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2048 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2049 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002050 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002051 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2052 zQuery);
2053 goto end_data_xfer;
2054 }
2055 n = sqlite3_column_count(pQuery);
2056 zInsert = sqlite3_malloc(200 + nTable + n*3);
2057 if( zInsert==0 ){
2058 fprintf(stderr, "out of memory\n");
2059 goto end_data_xfer;
2060 }
2061 sqlite3_snprintf(200+nTable,zInsert,
2062 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2063 i = (int)strlen(zInsert);
2064 for(j=1; j<n; j++){
2065 memcpy(zInsert+i, ",?", 2);
2066 i += 2;
2067 }
2068 memcpy(zInsert+i, ");", 3);
2069 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2070 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002071 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002072 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2073 zQuery);
2074 goto end_data_xfer;
2075 }
2076 for(k=0; k<2; k++){
2077 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2078 for(i=0; i<n; i++){
2079 switch( sqlite3_column_type(pQuery, i) ){
2080 case SQLITE_NULL: {
2081 sqlite3_bind_null(pInsert, i+1);
2082 break;
2083 }
2084 case SQLITE_INTEGER: {
2085 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2086 break;
2087 }
2088 case SQLITE_FLOAT: {
2089 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2090 break;
2091 }
2092 case SQLITE_TEXT: {
2093 sqlite3_bind_text(pInsert, i+1,
2094 (const char*)sqlite3_column_text(pQuery,i),
2095 -1, SQLITE_STATIC);
2096 break;
2097 }
2098 case SQLITE_BLOB: {
2099 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2100 sqlite3_column_bytes(pQuery,i),
2101 SQLITE_STATIC);
2102 break;
2103 }
2104 }
2105 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002106 rc = sqlite3_step(pInsert);
2107 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2108 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2109 sqlite3_errmsg(newDb));
2110 }
drh3350ce92014-02-06 00:49:12 +00002111 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002112 cnt++;
2113 if( (cnt%spinRate)==0 ){
2114 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2115 fflush(stdout);
2116 }
drh3350ce92014-02-06 00:49:12 +00002117 } /* End while */
2118 if( rc==SQLITE_DONE ) break;
2119 sqlite3_finalize(pQuery);
2120 sqlite3_free(zQuery);
2121 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2122 zTable);
2123 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2124 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002125 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2126 break;
drh3350ce92014-02-06 00:49:12 +00002127 }
2128 } /* End for(k=0...) */
2129
2130end_data_xfer:
2131 sqlite3_finalize(pQuery);
2132 sqlite3_finalize(pInsert);
2133 sqlite3_free(zQuery);
2134 sqlite3_free(zInsert);
2135}
2136
2137
2138/*
2139** Try to transfer all rows of the schema that match zWhere. For
2140** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002141** If an error is encountered while moving forward through the
2142** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002143*/
mistachkine31ae902014-02-06 01:15:29 +00002144static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002145 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002146 sqlite3 *newDb,
2147 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002148 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002149){
2150 sqlite3_stmt *pQuery = 0;
2151 char *zQuery = 0;
2152 int rc;
2153 const unsigned char *zName;
2154 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002155 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002156
2157 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2158 " WHERE %s", zWhere);
2159 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2160 if( rc ){
2161 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2162 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2163 zQuery);
2164 goto end_schema_xfer;
2165 }
2166 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2167 zName = sqlite3_column_text(pQuery, 0);
2168 zSql = sqlite3_column_text(pQuery, 1);
2169 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002170 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2171 if( zErrMsg ){
2172 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2173 sqlite3_free(zErrMsg);
2174 zErrMsg = 0;
2175 }
drh3350ce92014-02-06 00:49:12 +00002176 if( xForEach ){
2177 xForEach(p, newDb, (const char*)zName);
2178 }
2179 printf("done\n");
2180 }
2181 if( rc!=SQLITE_DONE ){
2182 sqlite3_finalize(pQuery);
2183 sqlite3_free(zQuery);
2184 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2185 " WHERE %s ORDER BY rowid DESC", zWhere);
2186 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2187 if( rc ){
2188 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2189 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2190 zQuery);
2191 goto end_schema_xfer;
2192 }
2193 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2194 zName = sqlite3_column_text(pQuery, 0);
2195 zSql = sqlite3_column_text(pQuery, 1);
2196 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002197 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2198 if( zErrMsg ){
2199 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2200 sqlite3_free(zErrMsg);
2201 zErrMsg = 0;
2202 }
drh3350ce92014-02-06 00:49:12 +00002203 if( xForEach ){
2204 xForEach(p, newDb, (const char*)zName);
2205 }
2206 printf("done\n");
2207 }
2208 }
2209end_schema_xfer:
2210 sqlite3_finalize(pQuery);
2211 sqlite3_free(zQuery);
2212}
2213
2214/*
2215** Open a new database file named "zNewDb". Try to recover as much information
2216** as possible out of the main database (which might be corrupt) and write it
2217** into zNewDb.
2218*/
drhdcd87a92014-08-18 13:45:42 +00002219static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002220 int rc;
2221 sqlite3 *newDb = 0;
2222 if( access(zNewDb,0)==0 ){
2223 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2224 return;
2225 }
2226 rc = sqlite3_open(zNewDb, &newDb);
2227 if( rc ){
2228 fprintf(stderr, "Cannot create output database: %s\n",
2229 sqlite3_errmsg(newDb));
2230 }else{
drh54d0d2d2014-04-03 00:32:13 +00002231 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002232 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002233 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2234 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002235 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002236 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002237 }
2238 sqlite3_close(newDb);
2239}
2240
2241/*
drhc2ce0be2014-05-29 12:36:14 +00002242** Change the output file back to stdout
2243*/
drhdcd87a92014-08-18 13:45:42 +00002244static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002245 if( p->outfile[0]=='|' ){
2246 pclose(p->out);
2247 }else{
2248 output_file_close(p->out);
2249 }
2250 p->outfile[0] = 0;
2251 p->out = stdout;
2252}
2253
2254/*
drh75897232000-05-29 14:26:00 +00002255** If an input line begins with "." then invoke this routine to
2256** process that line.
drh67505e72002-04-19 12:34:06 +00002257**
drh47ad6842006-11-08 12:25:42 +00002258** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002259*/
drhdcd87a92014-08-18 13:45:42 +00002260static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002261 int i = 1;
2262 int nArg = 0;
2263 int n, c;
drh67505e72002-04-19 12:34:06 +00002264 int rc = 0;
drh75897232000-05-29 14:26:00 +00002265 char *azArg[50];
2266
2267 /* Parse the input line into tokens.
2268 */
2269 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002270 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002271 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002272 if( zLine[i]=='\'' || zLine[i]=='"' ){
2273 int delim = zLine[i++];
2274 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002275 while( zLine[i] && zLine[i]!=delim ){
2276 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2277 i++;
2278 }
drh75897232000-05-29 14:26:00 +00002279 if( zLine[i]==delim ){
2280 zLine[i++] = 0;
2281 }
drhfeac5f82004-08-01 00:10:45 +00002282 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002283 }else{
2284 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002285 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002286 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002287 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002288 }
2289 }
2290
2291 /* Process the input line.
2292 */
shane9bd1b442009-10-23 01:27:39 +00002293 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002294 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002295 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002296 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2297 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2298 ){
drhbc46f022013-01-23 18:53:23 +00002299 const char *zDestFile = 0;
2300 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002301 sqlite3 *pDest;
2302 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002303 int j;
2304 for(j=1; j<nArg; j++){
2305 const char *z = azArg[j];
2306 if( z[0]=='-' ){
2307 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002308 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002309 {
2310 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2311 return 1;
2312 }
2313 }else if( zDestFile==0 ){
2314 zDestFile = azArg[j];
2315 }else if( zDb==0 ){
2316 zDb = zDestFile;
2317 zDestFile = azArg[j];
2318 }else{
2319 fprintf(stderr, "too many arguments to .backup\n");
2320 return 1;
2321 }
drh9ff849f2009-02-04 20:55:57 +00002322 }
drhbc46f022013-01-23 18:53:23 +00002323 if( zDestFile==0 ){
2324 fprintf(stderr, "missing FILENAME argument on .backup\n");
2325 return 1;
2326 }
2327 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002328 rc = sqlite3_open(zDestFile, &pDest);
2329 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002330 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002331 sqlite3_close(pDest);
2332 return 1;
2333 }
drh05782482013-10-24 15:20:20 +00002334 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002335 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2336 if( pBackup==0 ){
2337 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2338 sqlite3_close(pDest);
2339 return 1;
2340 }
2341 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2342 sqlite3_backup_finish(pBackup);
2343 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002344 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002345 }else{
2346 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002347 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002348 }
2349 sqlite3_close(pDest);
2350 }else
2351
drhc2ce0be2014-05-29 12:36:14 +00002352 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2353 if( nArg==2 ){
2354 bail_on_error = booleanValue(azArg[1]);
2355 }else{
2356 fprintf(stderr, "Usage: .bail on|off\n");
2357 rc = 1;
2358 }
drhc49f44e2006-10-26 18:15:42 +00002359 }else
2360
drhd8621b92012-04-17 09:09:33 +00002361 /* The undocumented ".breakpoint" command causes a call to the no-op
2362 ** routine named test_breakpoint().
2363 */
2364 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2365 test_breakpoint();
2366 }else
2367
drhc2ce0be2014-05-29 12:36:14 +00002368 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2369 if( nArg==2 ){
2370 tryToClone(p, azArg[1]);
2371 }else{
2372 fprintf(stderr, "Usage: .clone FILENAME\n");
2373 rc = 1;
2374 }
mistachkine31ae902014-02-06 01:15:29 +00002375 }else
2376
drhc2ce0be2014-05-29 12:36:14 +00002377 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002378 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002379 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002380 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002381 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002382 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002383 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002384 data.colWidth[0] = 3;
2385 data.colWidth[1] = 15;
2386 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002387 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002388 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002389 if( zErrMsg ){
2390 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002391 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002392 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002393 }
2394 }else
2395
drhc2ce0be2014-05-29 12:36:14 +00002396 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002397 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002398 /* When playing back a "dump", the content might appear in an order
2399 ** which causes immediate foreign key constraints to be violated.
2400 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002401 if( nArg!=1 && nArg!=2 ){
2402 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2403 rc = 1;
2404 goto meta_command_exit;
2405 }
drhf1dfc4f2009-09-23 15:51:35 +00002406 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002407 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002408 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002409 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002410 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002411 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002412 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002413 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002414 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002415 );
2416 run_schema_dump_query(p,
2417 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002418 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002419 );
drh2f464a02011-10-13 00:41:49 +00002420 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002421 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002422 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002423 );
drh4c653a02000-06-07 01:27:47 +00002424 }else{
2425 int i;
drhdd3d4592004-08-30 01:54:05 +00002426 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002427 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002428 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002429 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002430 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002431 " AND sql NOT NULL");
2432 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002433 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002434 "WHERE sql NOT NULL"
2435 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002436 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002437 );
danielk1977bc6ada42004-06-30 08:20:16 +00002438 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002439 }
2440 }
drh45e29d82006-11-20 16:21:10 +00002441 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002442 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002443 p->writableSchema = 0;
2444 }
drh56197952011-10-13 16:30:13 +00002445 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2446 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002447 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002448 }else
drh75897232000-05-29 14:26:00 +00002449
drhc2ce0be2014-05-29 12:36:14 +00002450 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2451 if( nArg==2 ){
2452 p->echoOn = booleanValue(azArg[1]);
2453 }else{
2454 fprintf(stderr, "Usage: .echo on|off\n");
2455 rc = 1;
2456 }
drhdaffd0e2001-04-11 14:28:42 +00002457 }else
2458
drhc2ce0be2014-05-29 12:36:14 +00002459 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2460 if( nArg==2 ){
2461 p->autoEQP = booleanValue(azArg[1]);
2462 }else{
2463 fprintf(stderr, "Usage: .eqp on|off\n");
2464 rc = 1;
2465 }
drhefbf3b12014-02-28 20:47:24 +00002466 }else
2467
drhd3ac7d92013-01-25 18:33:43 +00002468 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002469 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002470 rc = 2;
drh75897232000-05-29 14:26:00 +00002471 }else
2472
drhc2ce0be2014-05-29 12:36:14 +00002473 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002474 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002475 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002476 if(!p->normalMode.valid) {
2477 p->normalMode.valid = 1;
2478 p->normalMode.mode = p->mode;
2479 p->normalMode.showHeader = p->showHeader;
2480 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002481 }
2482 /* We could put this code under the !p->explainValid
2483 ** condition so that it does not execute if we are already in
2484 ** explain mode. However, always executing it allows us an easy
2485 ** was to reset to explain mode in case the user previously
2486 ** did an .explain followed by a .width, .mode or .header
2487 ** command.
2488 */
danielk19770d78bae2008-01-03 07:09:48 +00002489 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002490 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002491 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002492 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002493 p->colWidth[1] = 13; /* opcode */
2494 p->colWidth[2] = 4; /* P1 */
2495 p->colWidth[3] = 4; /* P2 */
2496 p->colWidth[4] = 4; /* P3 */
2497 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002498 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002499 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002500 }else if (p->normalMode.valid) {
2501 p->normalMode.valid = 0;
2502 p->mode = p->normalMode.mode;
2503 p->showHeader = p->normalMode.showHeader;
2504 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002505 }
drh75897232000-05-29 14:26:00 +00002506 }else
2507
drhc1971542014-06-23 23:28:13 +00002508 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002509 ShellState data;
drhc1971542014-06-23 23:28:13 +00002510 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002511 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002512 if( nArg!=1 ){
2513 fprintf(stderr, "Usage: .fullschema\n");
2514 rc = 1;
2515 goto meta_command_exit;
2516 }
2517 open_db(p, 0);
2518 memcpy(&data, p, sizeof(data));
2519 data.showHeader = 0;
2520 data.mode = MODE_Semi;
2521 rc = sqlite3_exec(p->db,
2522 "SELECT sql FROM"
2523 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2524 " FROM sqlite_master UNION ALL"
2525 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002526 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002527 "ORDER BY rowid",
2528 callback, &data, &zErrMsg
2529 );
drh56f674c2014-07-18 14:43:29 +00002530 if( rc==SQLITE_OK ){
2531 sqlite3_stmt *pStmt;
2532 rc = sqlite3_prepare_v2(p->db,
2533 "SELECT rowid FROM sqlite_master"
2534 " WHERE name GLOB 'sqlite_stat[134]'",
2535 -1, &pStmt, 0);
2536 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2537 sqlite3_finalize(pStmt);
2538 }
2539 if( doStats==0 ){
2540 fprintf(p->out, "/* No STAT tables available */\n");
2541 }else{
2542 fprintf(p->out, "ANALYZE sqlite_master;\n");
2543 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2544 callback, &data, &zErrMsg);
2545 data.mode = MODE_Insert;
2546 data.zDestTable = "sqlite_stat1";
2547 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2548 shell_callback, &data,&zErrMsg);
2549 data.zDestTable = "sqlite_stat3";
2550 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2551 shell_callback, &data,&zErrMsg);
2552 data.zDestTable = "sqlite_stat4";
2553 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2554 shell_callback, &data, &zErrMsg);
2555 fprintf(p->out, "ANALYZE sqlite_master;\n");
2556 }
drhc1971542014-06-23 23:28:13 +00002557 }else
2558
drhc2ce0be2014-05-29 12:36:14 +00002559 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2560 if( nArg==2 ){
2561 p->showHeader = booleanValue(azArg[1]);
2562 }else{
2563 fprintf(stderr, "Usage: .headers on|off\n");
2564 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002565 }
drh75897232000-05-29 14:26:00 +00002566 }else
2567
drhc2ce0be2014-05-29 12:36:14 +00002568 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2569 fprintf(p->out, "%s", zHelp);
2570 }else
2571
2572 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002573 char *zTable; /* Insert data into this table */
2574 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002575 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002576 int nCol; /* Number of columns in the table */
2577 int nByte; /* Number of bytes in an SQL string */
2578 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002579 int needCommit; /* True to COMMIT or ROLLBACK at end */
drhfeac5f82004-08-01 00:10:45 +00002580 int nSep; /* Number of bytes in p->separator[] */
2581 char *zSql; /* An SQL statement */
drhdb95f682013-06-26 22:46:00 +00002582 CSVReader sCsv; /* Reader context */
drh5bde8162013-06-27 14:07:53 +00002583 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002584
drhc2ce0be2014-05-29 12:36:14 +00002585 if( nArg!=3 ){
2586 fprintf(stderr, "Usage: .import FILE TABLE\n");
2587 goto meta_command_exit;
2588 }
drh01f37542014-05-31 15:43:33 +00002589 zFile = azArg[1];
2590 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002591 seenInterrupt = 0;
2592 memset(&sCsv, 0, sizeof(sCsv));
drh05782482013-10-24 15:20:20 +00002593 open_db(p, 0);
drh4f21c4a2008-12-10 22:15:00 +00002594 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002595 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00002596 fprintf(stderr, "Error: non-null separator required for import\n");
2597 return 1;
drhfeac5f82004-08-01 00:10:45 +00002598 }
drhdb95f682013-06-26 22:46:00 +00002599 if( nSep>1 ){
2600 fprintf(stderr, "Error: multi-character separators not allowed"
2601 " for import\n");
2602 return 1;
2603 }
drh5bde8162013-06-27 14:07:53 +00002604 sCsv.zFile = zFile;
2605 sCsv.nLine = 1;
2606 if( sCsv.zFile[0]=='|' ){
2607 sCsv.in = popen(sCsv.zFile+1, "r");
2608 sCsv.zFile = "<pipe>";
2609 xCloser = pclose;
2610 }else{
2611 sCsv.in = fopen(sCsv.zFile, "rb");
2612 xCloser = fclose;
2613 }
drhdb95f682013-06-26 22:46:00 +00002614 if( sCsv.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002615 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002616 return 1;
2617 }
2618 sCsv.cSeparator = p->separator[0];
drh7b075e32011-09-28 01:10:00 +00002619 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002620 if( zSql==0 ){
2621 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002622 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002623 return 1;
2624 }
drh4f21c4a2008-12-10 22:15:00 +00002625 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002626 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
dan6a8ac852014-05-26 18:27:12 +00002627 csv_append_char(&sCsv, 0); /* To ensure sCsv.z is allocated */
drhdb95f682013-06-26 22:46:00 +00002628 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2629 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2630 char cSep = '(';
2631 while( csv_read_one_field(&sCsv) ){
2632 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
2633 cSep = ',';
2634 if( sCsv.cTerm!=sCsv.cSeparator ) break;
2635 }
drh5bde8162013-06-27 14:07:53 +00002636 if( cSep=='(' ){
2637 sqlite3_free(zCreate);
2638 sqlite3_free(sCsv.z);
2639 xCloser(sCsv.in);
2640 fprintf(stderr,"%s: empty file\n", sCsv.zFile);
2641 return 1;
2642 }
drhdb95f682013-06-26 22:46:00 +00002643 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2644 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2645 sqlite3_free(zCreate);
2646 if( rc ){
2647 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2648 sqlite3_errmsg(db));
2649 sqlite3_free(sCsv.z);
drh5bde8162013-06-27 14:07:53 +00002650 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002651 return 1;
2652 }
drhc7181902014-02-27 15:04:13 +00002653 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002654 }
drhfeac5f82004-08-01 00:10:45 +00002655 sqlite3_free(zSql);
2656 if( rc ){
shane916f9612009-10-23 00:37:15 +00002657 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002658 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
drh5bde8162013-06-27 14:07:53 +00002659 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002660 return 1;
drhfeac5f82004-08-01 00:10:45 +00002661 }
shane916f9612009-10-23 00:37:15 +00002662 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002663 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002664 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002665 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002666 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002667 if( zSql==0 ){
2668 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002669 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002670 return 1;
2671 }
drhdb95f682013-06-26 22:46:00 +00002672 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002673 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002674 for(i=1; i<nCol; i++){
2675 zSql[j++] = ',';
2676 zSql[j++] = '?';
2677 }
2678 zSql[j++] = ')';
2679 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00002680 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002681 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002682 if( rc ){
2683 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002684 if (pStmt) sqlite3_finalize(pStmt);
drh5bde8162013-06-27 14:07:53 +00002685 xCloser(sCsv.in);
drh47ad6842006-11-08 12:25:42 +00002686 return 1;
drhfeac5f82004-08-01 00:10:45 +00002687 }
drh2d463112013-08-06 14:36:36 +00002688 needCommit = sqlite3_get_autocommit(db);
2689 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00002690 do{
2691 int startLine = sCsv.nLine;
drhfeac5f82004-08-01 00:10:45 +00002692 for(i=0; i<nCol; i++){
drhdb95f682013-06-26 22:46:00 +00002693 char *z = csv_read_one_field(&sCsv);
2694 if( z==0 && i==0 ) break;
2695 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
2696 if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
2697 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2698 "filling the rest with NULL\n",
2699 sCsv.zFile, startLine, nCol, i+1);
2700 i++;
mistachkin6fe03382014-06-16 22:45:28 +00002701 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002702 }
drhfeac5f82004-08-01 00:10:45 +00002703 }
drhdb95f682013-06-26 22:46:00 +00002704 if( sCsv.cTerm==sCsv.cSeparator ){
2705 do{
2706 csv_read_one_field(&sCsv);
2707 i++;
2708 }while( sCsv.cTerm==sCsv.cSeparator );
2709 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2710 "extras ignored\n",
2711 sCsv.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002712 }
drhdb95f682013-06-26 22:46:00 +00002713 if( i>=nCol ){
2714 sqlite3_step(pStmt);
2715 rc = sqlite3_reset(pStmt);
2716 if( rc!=SQLITE_OK ){
2717 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
2718 sqlite3_errmsg(db));
2719 }
2720 }
2721 }while( sCsv.cTerm!=EOF );
2722
drh5bde8162013-06-27 14:07:53 +00002723 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002724 sqlite3_free(sCsv.z);
drhfeac5f82004-08-01 00:10:45 +00002725 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00002726 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002727 }else
2728
drhc2ce0be2014-05-29 12:36:14 +00002729 if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002730 ShellState data;
drh75897232000-05-29 14:26:00 +00002731 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002732 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00002733 memcpy(&data, p, sizeof(data));
2734 data.showHeader = 0;
2735 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002736 if( nArg==1 ){
2737 rc = sqlite3_exec(p->db,
2738 "SELECT name FROM sqlite_master "
2739 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2740 "UNION ALL "
2741 "SELECT name FROM sqlite_temp_master "
2742 "WHERE type='index' "
2743 "ORDER BY 1",
2744 callback, &data, &zErrMsg
2745 );
drhc2ce0be2014-05-29 12:36:14 +00002746 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00002747 zShellStatic = azArg[1];
2748 rc = sqlite3_exec(p->db,
2749 "SELECT name FROM sqlite_master "
2750 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2751 "UNION ALL "
2752 "SELECT name FROM sqlite_temp_master "
2753 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2754 "ORDER BY 1",
2755 callback, &data, &zErrMsg
2756 );
2757 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00002758 }else{
2759 fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
2760 rc = 1;
2761 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00002762 }
drh75897232000-05-29 14:26:00 +00002763 if( zErrMsg ){
2764 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002765 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002766 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002767 }else if( rc != SQLITE_OK ){
2768 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2769 rc = 1;
drh75897232000-05-29 14:26:00 +00002770 }
2771 }else
2772
drhae5e4452007-05-03 17:18:36 +00002773#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002774 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002775 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002776 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2777 iotrace = 0;
2778 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002779 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002780 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002781 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002782 iotrace = stdout;
2783 }else{
2784 iotrace = fopen(azArg[1], "w");
2785 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002786 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002787 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002788 rc = 1;
drhb0603412007-02-28 04:47:26 +00002789 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002790 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002791 }
2792 }
2793 }else
drhae5e4452007-05-03 17:18:36 +00002794#endif
drhb0603412007-02-28 04:47:26 +00002795
drh70df4fe2006-06-13 15:12:21 +00002796#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00002797 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00002798 const char *zFile, *zProc;
2799 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00002800 if( nArg<2 ){
2801 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
2802 rc = 1;
2803 goto meta_command_exit;
2804 }
drh1e397f82006-06-08 15:28:43 +00002805 zFile = azArg[1];
2806 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00002807 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00002808 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2809 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002810 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002811 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002812 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002813 }
2814 }else
drh70df4fe2006-06-13 15:12:21 +00002815#endif
drh1e397f82006-06-08 15:28:43 +00002816
drhc2ce0be2014-05-29 12:36:14 +00002817 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
2818 if( nArg!=2 ){
2819 fprintf(stderr, "Usage: .log FILENAME\n");
2820 rc = 1;
2821 }else{
2822 const char *zFile = azArg[1];
2823 output_file_close(p->pLog);
2824 p->pLog = output_file_open(zFile);
2825 }
drh127f9d72010-02-23 01:47:00 +00002826 }else
2827
drhc2ce0be2014-05-29 12:36:14 +00002828 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
2829 const char *zMode = nArg>=2 ? azArg[1] : "";
2830 int n2 = (int)strlen(zMode);
2831 int c2 = zMode[0];
2832 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002833 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00002834 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002835 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00002836 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002837 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00002838 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002839 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00002840 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002841 p->mode = MODE_Tcl;
mistachkin585dcb22012-12-04 00:23:43 +00002842 sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
drhc2ce0be2014-05-29 12:36:14 +00002843 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002844 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002845 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drh6976c212014-07-24 12:09:47 +00002846 sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n");
drhc2ce0be2014-05-29 12:36:14 +00002847 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002848 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002849 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drhc2ce0be2014-05-29 12:36:14 +00002850 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002851 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00002852 set_table_name(p, nArg>=3 ? azArg[2] : "table");
drhdaffd0e2001-04-11 14:28:42 +00002853 }else {
shane9bd1b442009-10-23 01:27:39 +00002854 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002855 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002856 rc = 1;
drh75897232000-05-29 14:26:00 +00002857 }
2858 }else
2859
drhc2ce0be2014-05-29 12:36:14 +00002860 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
2861 if( nArg==2 ){
2862 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2863 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
2864 }else{
2865 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00002866 rc = 1;
2867 }
2868 }else
2869
drh05782482013-10-24 15:20:20 +00002870 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
2871 sqlite3 *savedDb = p->db;
2872 const char *zSavedFilename = p->zDbFilename;
2873 char *zNewFilename = 0;
2874 p->db = 0;
2875 if( nArg>=2 ){
2876 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
2877 }
2878 open_db(p, 1);
2879 if( p->db!=0 ){
2880 sqlite3_close(savedDb);
2881 sqlite3_free(p->zFreeOnClose);
2882 p->zFreeOnClose = zNewFilename;
2883 }else{
2884 sqlite3_free(zNewFilename);
2885 p->db = savedDb;
2886 p->zDbFilename = zSavedFilename;
2887 }
2888 }else
2889
drhc2ce0be2014-05-29 12:36:14 +00002890 if( c=='o'
2891 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
2892 ){
2893 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
2894 if( nArg>2 ){
2895 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
2896 rc = 1;
2897 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00002898 }
drhc2ce0be2014-05-29 12:36:14 +00002899 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
2900 if( nArg<2 ){
2901 fprintf(stderr, "Usage: .once FILE\n");
2902 rc = 1;
2903 goto meta_command_exit;
2904 }
2905 p->outCount = 2;
2906 }else{
2907 p->outCount = 0;
2908 }
2909 output_reset(p);
2910 if( zFile[0]=='|' ){
2911 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00002912 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00002913 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00002914 p->out = stdout;
2915 rc = 1;
2916 }else{
drhc2ce0be2014-05-29 12:36:14 +00002917 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00002918 }
drh75897232000-05-29 14:26:00 +00002919 }else{
drhc2ce0be2014-05-29 12:36:14 +00002920 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00002921 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00002922 if( strcmp(zFile,"off")!=0 ){
2923 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002924 }
drh75897232000-05-29 14:26:00 +00002925 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002926 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002927 } else {
drhc2ce0be2014-05-29 12:36:14 +00002928 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00002929 }
2930 }
2931 }else
2932
drh078b1fd2012-09-21 13:40:02 +00002933 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2934 int i;
2935 for(i=1; i<nArg; i++){
2936 if( i>1 ) fprintf(p->out, " ");
2937 fprintf(p->out, "%s", azArg[i]);
2938 }
2939 fprintf(p->out, "\n");
2940 }else
2941
drhc2ce0be2014-05-29 12:36:14 +00002942 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002943 if( nArg >= 2) {
2944 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2945 }
2946 if( nArg >= 3) {
2947 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2948 }
2949 }else
2950
drhc2ce0be2014-05-29 12:36:14 +00002951 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002952 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002953 }else
2954
drhc2ce0be2014-05-29 12:36:14 +00002955 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
2956 FILE *alt;
2957 if( nArg!=2 ){
2958 fprintf(stderr, "Usage: .read FILE\n");
2959 rc = 1;
2960 goto meta_command_exit;
2961 }
2962 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002963 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002964 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2965 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002966 }else{
shane9bd1b442009-10-23 01:27:39 +00002967 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002968 fclose(alt);
2969 }
2970 }else
2971
drhc2ce0be2014-05-29 12:36:14 +00002972 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00002973 const char *zSrcFile;
2974 const char *zDb;
2975 sqlite3 *pSrc;
2976 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002977 int nTimeout = 0;
2978
drh9ff849f2009-02-04 20:55:57 +00002979 if( nArg==2 ){
2980 zSrcFile = azArg[1];
2981 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00002982 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00002983 zSrcFile = azArg[2];
2984 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00002985 }else{
2986 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
2987 rc = 1;
2988 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00002989 }
2990 rc = sqlite3_open(zSrcFile, &pSrc);
2991 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002992 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002993 sqlite3_close(pSrc);
2994 return 1;
2995 }
drh05782482013-10-24 15:20:20 +00002996 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002997 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2998 if( pBackup==0 ){
2999 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3000 sqlite3_close(pSrc);
3001 return 1;
3002 }
drhdc2c4912009-02-04 22:46:47 +00003003 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3004 || rc==SQLITE_BUSY ){
3005 if( rc==SQLITE_BUSY ){
3006 if( nTimeout++ >= 3 ) break;
3007 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003008 }
3009 }
3010 sqlite3_backup_finish(pBackup);
3011 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003012 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003013 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003014 fprintf(stderr, "Error: source database is busy\n");
3015 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003016 }else{
3017 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003018 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003019 }
3020 sqlite3_close(pSrc);
3021 }else
3022
drhc2ce0be2014-05-29 12:36:14 +00003023 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003024 ShellState data;
drh75897232000-05-29 14:26:00 +00003025 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003026 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003027 memcpy(&data, p, sizeof(data));
3028 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003029 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003030 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003031 int i;
drhf0693c82011-10-11 20:41:54 +00003032 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003033 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003034 char *new_argv[2], *new_colv[2];
3035 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3036 " type text,\n"
3037 " name text,\n"
3038 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003039 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003040 " sql text\n"
3041 ")";
3042 new_argv[1] = 0;
3043 new_colv[0] = "sql";
3044 new_colv[1] = 0;
3045 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003046 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003047 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003048 char *new_argv[2], *new_colv[2];
3049 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3050 " type text,\n"
3051 " name text,\n"
3052 " tbl_name text,\n"
3053 " rootpage integer,\n"
3054 " sql text\n"
3055 ")";
3056 new_argv[1] = 0;
3057 new_colv[0] = "sql";
3058 new_colv[1] = 0;
3059 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003060 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003061 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003062 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003063 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003064 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003065 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003066 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003067 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003068 "WHERE lower(tbl_name) LIKE shellstatic()"
3069 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003070 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003071 callback, &data, &zErrMsg);
3072 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003073 }
drhc2ce0be2014-05-29 12:36:14 +00003074 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003075 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003076 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003077 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003078 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003079 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003080 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003081 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003082 callback, &data, &zErrMsg
3083 );
drhc2ce0be2014-05-29 12:36:14 +00003084 }else{
3085 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3086 rc = 1;
3087 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003088 }
drh75897232000-05-29 14:26:00 +00003089 if( zErrMsg ){
3090 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003091 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003092 rc = 1;
3093 }else if( rc != SQLITE_OK ){
3094 fprintf(stderr,"Error: querying schema information\n");
3095 rc = 1;
3096 }else{
3097 rc = 0;
drh75897232000-05-29 14:26:00 +00003098 }
3099 }else
3100
drh340f5822013-06-27 13:01:21 +00003101#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003102 /* Undocumented commands for internal testing. Subject to change
3103 ** without notice. */
3104 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3105 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3106 int i, v;
3107 for(i=1; i<nArg; i++){
3108 v = booleanValue(azArg[i]);
3109 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3110 }
3111 }
3112 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3113 int i; sqlite3_int64 v;
3114 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003115 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003116 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003117 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003118 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003119 }
3120 }
3121 }else
drh340f5822013-06-27 13:01:21 +00003122#endif
drh348d19c2013-06-03 12:47:43 +00003123
drhc2ce0be2014-05-29 12:36:14 +00003124 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003125 if( nArg<2 || nArg>3 ){
3126 fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n");
drhc2ce0be2014-05-29 12:36:14 +00003127 rc = 1;
3128 }
drh6976c212014-07-24 12:09:47 +00003129 if( nArg>=2 ){
3130 sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]);
3131 }
3132 if( nArg>=3 ){
3133 sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]);
3134 }
drh75897232000-05-29 14:26:00 +00003135 }else
3136
drh62cdde52014-05-28 20:22:28 +00003137 if( c=='s'
3138 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003139 ){
3140 char *zCmd;
drh54027102014-08-06 14:36:53 +00003141 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003142 if( nArg<2 ){
3143 fprintf(stderr, "Usage: .system COMMAND\n");
3144 rc = 1;
3145 goto meta_command_exit;
3146 }
drhdcb3e3d2014-05-29 03:17:29 +00003147 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003148 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003149 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3150 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003151 }
drh54027102014-08-06 14:36:53 +00003152 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003153 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003154 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003155 }else
3156
drhc2ce0be2014-05-29 12:36:14 +00003157 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003158 int i;
drhc2ce0be2014-05-29 12:36:14 +00003159 if( nArg!=1 ){
3160 fprintf(stderr, "Usage: .show\n");
3161 rc = 1;
3162 goto meta_command_exit;
3163 }
persicom7e2dfdd2002-04-18 02:46:52 +00003164 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drhefbf3b12014-02-28 20:47:24 +00003165 fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003166 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00003167 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00003168 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00003169 fprintf(p->out,"%9.9s: ", "nullvalue");
3170 output_c_string(p->out, p->nullvalue);
3171 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00003172 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003173 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00003174 fprintf(p->out,"%9.9s: ", "separator");
3175 output_c_string(p->out, p->separator);
drh6976c212014-07-24 12:09:47 +00003176 fprintf(p->out," ");
3177 output_c_string(p->out, p->newline);
drhfeac5f82004-08-01 00:10:45 +00003178 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00003179 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00003180 fprintf(p->out,"%9.9s: ","width");
3181 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003182 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003183 }
drhfeac5f82004-08-01 00:10:45 +00003184 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003185 }else
3186
drhc2ce0be2014-05-29 12:36:14 +00003187 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3188 if( nArg==2 ){
3189 p->statsOn = booleanValue(azArg[1]);
3190 }else{
3191 fprintf(stderr, "Usage: .stats on|off\n");
3192 rc = 1;
3193 }
shaneh642d8b82010-07-28 16:05:34 +00003194 }else
3195
drhc2ce0be2014-05-29 12:36:14 +00003196 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003197 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003198 char **azResult;
drh98781232012-04-23 12:38:05 +00003199 int nRow, nAlloc;
3200 char *zSql = 0;
3201 int ii;
drh05782482013-10-24 15:20:20 +00003202 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003203 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3204 if( rc ) return rc;
3205 zSql = sqlite3_mprintf(
3206 "SELECT name FROM sqlite_master"
3207 " WHERE type IN ('table','view')"
3208 " AND name NOT LIKE 'sqlite_%%'"
3209 " AND name LIKE ?1");
3210 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3211 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3212 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3213 if( strcmp(zDbName,"temp")==0 ){
3214 zSql = sqlite3_mprintf(
3215 "%z UNION ALL "
3216 "SELECT 'temp.' || name FROM sqlite_temp_master"
3217 " WHERE type IN ('table','view')"
3218 " AND name NOT LIKE 'sqlite_%%'"
3219 " AND name LIKE ?1", zSql);
3220 }else{
3221 zSql = sqlite3_mprintf(
3222 "%z UNION ALL "
3223 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3224 " WHERE type IN ('table','view')"
3225 " AND name NOT LIKE 'sqlite_%%'"
3226 " AND name LIKE ?1", zSql, zDbName, zDbName);
3227 }
drha50da102000-08-08 20:19:09 +00003228 }
drh98781232012-04-23 12:38:05 +00003229 sqlite3_finalize(pStmt);
3230 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3231 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3232 sqlite3_free(zSql);
3233 if( rc ) return rc;
3234 nRow = nAlloc = 0;
3235 azResult = 0;
3236 if( nArg>1 ){
3237 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003238 }else{
drh98781232012-04-23 12:38:05 +00003239 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3240 }
3241 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3242 if( nRow>=nAlloc ){
3243 char **azNew;
3244 int n = nAlloc*2 + 10;
3245 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3246 if( azNew==0 ){
3247 fprintf(stderr, "Error: out of memory\n");
3248 break;
3249 }
3250 nAlloc = n;
3251 azResult = azNew;
3252 }
3253 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3254 if( azResult[nRow] ) nRow++;
3255 }
3256 sqlite3_finalize(pStmt);
3257 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003258 int len, maxlen = 0;
3259 int i, j;
3260 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003261 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003262 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003263 if( len>maxlen ) maxlen = len;
3264 }
3265 nPrintCol = 80/(maxlen+2);
3266 if( nPrintCol<1 ) nPrintCol = 1;
3267 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3268 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003269 for(j=i; j<nRow; j+=nPrintRow){
3270 char *zSp = j<nPrintRow ? "" : " ";
drh151b7d52013-05-06 20:28:54 +00003271 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
drhe3710332000-09-29 13:30:53 +00003272 }
drh151b7d52013-05-06 20:28:54 +00003273 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003274 }
3275 }
drh98781232012-04-23 12:38:05 +00003276 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3277 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003278 }else
3279
shaneh96887e12011-02-10 21:08:58 +00003280 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003281 static const struct {
3282 const char *zCtrlName; /* Name of a test-control option */
3283 int ctrlCode; /* Integer code for that option */
3284 } aCtrl[] = {
3285 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3286 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3287 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3288 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3289 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3290 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3291 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3292 { "assert", SQLITE_TESTCTRL_ASSERT },
3293 { "always", SQLITE_TESTCTRL_ALWAYS },
3294 { "reserve", SQLITE_TESTCTRL_RESERVE },
3295 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3296 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003297 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003298 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhd416fe72011-03-17 16:45:50 +00003299 };
shaneh96887e12011-02-10 21:08:58 +00003300 int testctrl = -1;
3301 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003302 int i, n;
drh05782482013-10-24 15:20:20 +00003303 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003304
drhd416fe72011-03-17 16:45:50 +00003305 /* convert testctrl text option to value. allow any unique prefix
3306 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003307 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003308 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003309 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3310 if( testctrl<0 ){
3311 testctrl = aCtrl[i].ctrlCode;
3312 }else{
drhb07028f2011-10-14 21:49:18 +00003313 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003314 testctrl = -1;
3315 break;
3316 }
3317 }
3318 }
drh348d19c2013-06-03 12:47:43 +00003319 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003320 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3321 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3322 }else{
3323 switch(testctrl){
3324
3325 /* sqlite3_test_control(int, db, int) */
3326 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3327 case SQLITE_TESTCTRL_RESERVE:
3328 if( nArg==3 ){
3329 int opt = (int)strtol(azArg[2], 0, 0);
3330 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003331 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003332 } else {
drhd416fe72011-03-17 16:45:50 +00003333 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3334 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003335 }
3336 break;
3337
3338 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003339 case SQLITE_TESTCTRL_PRNG_SAVE:
3340 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003341 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003342 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003343 if( nArg==2 ){
3344 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003345 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003346 } else {
3347 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3348 }
3349 break;
3350
3351 /* sqlite3_test_control(int, uint) */
3352 case SQLITE_TESTCTRL_PENDING_BYTE:
3353 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003354 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003355 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003356 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003357 } else {
drhd416fe72011-03-17 16:45:50 +00003358 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3359 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003360 }
3361 break;
3362
3363 /* sqlite3_test_control(int, int) */
3364 case SQLITE_TESTCTRL_ASSERT:
3365 case SQLITE_TESTCTRL_ALWAYS:
3366 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003367 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003368 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003369 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003370 } else {
drhd416fe72011-03-17 16:45:50 +00003371 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3372 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003373 }
3374 break;
3375
3376 /* sqlite3_test_control(int, char *) */
3377#ifdef SQLITE_N_KEYWORD
3378 case SQLITE_TESTCTRL_ISKEYWORD:
3379 if( nArg==3 ){
3380 const char *opt = azArg[2];
3381 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003382 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003383 } else {
drhd416fe72011-03-17 16:45:50 +00003384 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3385 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003386 }
3387 break;
3388#endif
3389
3390 case SQLITE_TESTCTRL_BITVEC_TEST:
3391 case SQLITE_TESTCTRL_FAULT_INSTALL:
3392 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3393 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3394 default:
drhd416fe72011-03-17 16:45:50 +00003395 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3396 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003397 break;
3398 }
3399 }
3400 }else
3401
drhc2ce0be2014-05-29 12:36:14 +00003402 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003403 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003404 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003405 }else
3406
drhc2ce0be2014-05-29 12:36:14 +00003407 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3408 if( nArg==2 ){
3409 enableTimer = booleanValue(azArg[1]);
3410 if( enableTimer && !HAS_TIMER ){
3411 fprintf(stderr, "Error: timer not available on this system.\n");
3412 enableTimer = 0;
3413 }
3414 }else{
3415 fprintf(stderr, "Usage: .timer on|off\n");
3416 rc = 1;
3417 }
shanehe2aa9d72009-11-06 17:20:17 +00003418 }else
3419
drhc2ce0be2014-05-29 12:36:14 +00003420 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003421 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00003422 output_file_close(p->traceOut);
drhc2ce0be2014-05-29 12:36:14 +00003423 if( nArg!=2 ){
3424 fprintf(stderr, "Usage: .trace FILE|off\n");
3425 rc = 1;
3426 goto meta_command_exit;
3427 }
drh42f64e52012-04-04 16:56:23 +00003428 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003429#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003430 if( p->traceOut==0 ){
3431 sqlite3_trace(p->db, 0, 0);
3432 }else{
3433 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3434 }
3435#endif
3436 }else
3437
drh9fd301b2011-06-03 13:28:22 +00003438 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003439 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003440 sqlite3_libversion(), sqlite3_sourceid());
3441 }else
3442
drhde60fc22011-12-14 17:53:36 +00003443 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3444 const char *zDbName = nArg==2 ? azArg[1] : "main";
3445 char *zVfsName = 0;
3446 if( p->db ){
3447 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3448 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003449 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003450 sqlite3_free(zVfsName);
3451 }
3452 }
3453 }else
3454
drhcef4fc82012-09-21 22:50:45 +00003455#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3456 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3457 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003458 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003459 }else
3460#endif
3461
drhc2ce0be2014-05-29 12:36:14 +00003462 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003463 int j;
drh43617e92006-03-06 20:55:46 +00003464 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003465 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003466 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003467 }
3468 }else
3469
3470 {
shane9bd1b442009-10-23 01:27:39 +00003471 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003472 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003473 rc = 1;
drh75897232000-05-29 14:26:00 +00003474 }
drh67505e72002-04-19 12:34:06 +00003475
drhc2ce0be2014-05-29 12:36:14 +00003476meta_command_exit:
3477 if( p->outCount ){
3478 p->outCount--;
3479 if( p->outCount==0 ) output_reset(p);
3480 }
drh67505e72002-04-19 12:34:06 +00003481 return rc;
drh75897232000-05-29 14:26:00 +00003482}
3483
drh67505e72002-04-19 12:34:06 +00003484/*
drh91a66392007-09-07 01:12:32 +00003485** Return TRUE if a semicolon occurs anywhere in the first N characters
3486** of string z[].
drh324ccef2003-02-05 14:06:20 +00003487*/
drh9f099fd2013-08-06 14:01:46 +00003488static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00003489 int i;
3490 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3491 return 0;
drh324ccef2003-02-05 14:06:20 +00003492}
3493
3494/*
drh70c7a4b2003-04-26 03:03:06 +00003495** Test to see if a line consists entirely of whitespace.
3496*/
3497static int _all_whitespace(const char *z){
3498 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00003499 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003500 if( *z=='/' && z[1]=='*' ){
3501 z += 2;
3502 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3503 if( *z==0 ) return 0;
3504 z++;
3505 continue;
3506 }
3507 if( *z=='-' && z[1]=='-' ){
3508 z += 2;
3509 while( *z && *z!='\n' ){ z++; }
3510 if( *z==0 ) return 1;
3511 continue;
3512 }
3513 return 0;
3514 }
3515 return 1;
3516}
3517
3518/*
drha9b17162003-04-29 18:01:28 +00003519** Return TRUE if the line typed in is an SQL command terminator other
3520** than a semi-colon. The SQL Server style "go" command is understood
3521** as is the Oracle "/".
3522*/
drh9f099fd2013-08-06 14:01:46 +00003523static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00003524 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00003525 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3526 return 1; /* Oracle */
3527 }
drhf0693c82011-10-11 20:41:54 +00003528 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00003529 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00003530 return 1; /* SQL Server */
3531 }
3532 return 0;
3533}
3534
3535/*
drh233a5312008-12-18 22:25:13 +00003536** Return true if zSql is a complete SQL statement. Return false if it
3537** ends in the middle of a string literal or C-style comment.
3538*/
drh9f099fd2013-08-06 14:01:46 +00003539static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00003540 int rc;
3541 if( zSql==0 ) return 1;
3542 zSql[nSql] = ';';
3543 zSql[nSql+1] = 0;
3544 rc = sqlite3_complete(zSql);
3545 zSql[nSql] = 0;
3546 return rc;
3547}
3548
3549/*
drh67505e72002-04-19 12:34:06 +00003550** Read input from *in and process it. If *in==0 then input
3551** is interactive - the user is typing it it. Otherwise, input
3552** is coming from a file or device. A prompt is issued and history
3553** is saved only if input is interactive. An interrupt signal will
3554** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00003555**
3556** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00003557*/
drhdcd87a92014-08-18 13:45:42 +00003558static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00003559 char *zLine = 0; /* A single input line */
3560 char *zSql = 0; /* Accumulated SQL text */
3561 int nLine; /* Length of current line */
3562 int nSql = 0; /* Bytes of zSql[] used */
3563 int nAlloc = 0; /* Allocated zSql[] space */
3564 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
3565 char *zErrMsg; /* Error message returned */
3566 int rc; /* Error code */
3567 int errCnt = 0; /* Number of errors seen */
3568 int lineno = 0; /* Current line number */
3569 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00003570
3571 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
3572 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00003573 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00003574 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00003575 /* End of input */
3576 if( stdin_is_interactive ) printf("\n");
3577 break;
drhc49f44e2006-10-26 18:15:42 +00003578 }
drh67505e72002-04-19 12:34:06 +00003579 if( seenInterrupt ){
3580 if( in!=0 ) break;
3581 seenInterrupt = 0;
3582 }
drhc28490c2006-10-26 14:25:58 +00003583 lineno++;
drh849a9d92013-12-21 15:46:06 +00003584 if( nSql==0 && _all_whitespace(zLine) ){
3585 if( p->echoOn ) printf("%s\n", zLine);
3586 continue;
3587 }
drh2af0b2d2002-02-21 02:25:02 +00003588 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00003589 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00003590 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00003591 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00003592 break;
3593 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00003594 errCnt++;
3595 }
drhdaffd0e2001-04-11 14:28:42 +00003596 continue;
3597 }
drh9f099fd2013-08-06 14:01:46 +00003598 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00003599 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00003600 }
drh9f099fd2013-08-06 14:01:46 +00003601 nLine = strlen30(zLine);
3602 if( nSql+nLine+2>=nAlloc ){
3603 nAlloc = nSql+nLine+100;
3604 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00003605 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00003606 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00003607 exit(1);
3608 }
drhdaffd0e2001-04-11 14:28:42 +00003609 }
drh9f099fd2013-08-06 14:01:46 +00003610 nSqlPrior = nSql;
3611 if( nSql==0 ){
3612 int i;
3613 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00003614 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00003615 memcpy(zSql, zLine+i, nLine+1-i);
3616 startline = lineno;
3617 nSql = nLine-i;
3618 }else{
3619 zSql[nSql++] = '\n';
3620 memcpy(zSql+nSql, zLine, nLine+1);
3621 nSql += nLine;
3622 }
3623 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00003624 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00003625 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00003626 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00003627 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00003628 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00003629 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00003630 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00003631 char zPrefix[100];
3632 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00003633 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00003634 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00003635 }else{
shane9bd1b442009-10-23 01:27:39 +00003636 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00003637 }
drh7f953e22002-07-13 17:33:45 +00003638 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00003639 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003640 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00003641 zErrMsg = 0;
3642 }else{
shaned2bed1c2009-10-21 03:56:54 +00003643 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00003644 }
drhc49f44e2006-10-26 18:15:42 +00003645 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00003646 }
drhdaffd0e2001-04-11 14:28:42 +00003647 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00003648 if( p->outCount ){
3649 output_reset(p);
3650 p->outCount = 0;
3651 }
drh9f099fd2013-08-06 14:01:46 +00003652 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00003653 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00003654 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00003655 }
3656 }
drh9f099fd2013-08-06 14:01:46 +00003657 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00003658 if( !_all_whitespace(zSql) ){
3659 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
3660 }
drhdaffd0e2001-04-11 14:28:42 +00003661 free(zSql);
3662 }
danielk19772ac27622007-07-03 05:31:16 +00003663 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00003664 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00003665}
3666
drh67505e72002-04-19 12:34:06 +00003667/*
3668** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00003669** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00003670*/
3671static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00003672 static char *home_dir = NULL;
3673 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00003674
drh83905c92012-06-21 13:00:37 +00003675#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00003676 {
3677 struct passwd *pwent;
3678 uid_t uid = getuid();
3679 if( (pwent=getpwuid(uid)) != NULL) {
3680 home_dir = pwent->pw_dir;
3681 }
drh67505e72002-04-19 12:34:06 +00003682 }
3683#endif
3684
chw65d3c132007-11-12 21:09:10 +00003685#if defined(_WIN32_WCE)
3686 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
3687 */
drh85e72432012-04-11 11:38:53 +00003688 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00003689#else
3690
drh83905c92012-06-21 13:00:37 +00003691#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00003692 if (!home_dir) {
3693 home_dir = getenv("USERPROFILE");
3694 }
3695#endif
3696
drh67505e72002-04-19 12:34:06 +00003697 if (!home_dir) {
3698 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00003699 }
3700
drh83905c92012-06-21 13:00:37 +00003701#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00003702 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00003703 char *zDrive, *zPath;
3704 int n;
3705 zDrive = getenv("HOMEDRIVE");
3706 zPath = getenv("HOMEPATH");
3707 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00003708 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00003709 home_dir = malloc( n );
3710 if( home_dir==0 ) return 0;
3711 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3712 return home_dir;
3713 }
3714 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00003715 }
3716#endif
3717
chw65d3c132007-11-12 21:09:10 +00003718#endif /* !_WIN32_WCE */
3719
drh67505e72002-04-19 12:34:06 +00003720 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00003721 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00003722 char *z = malloc( n );
3723 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00003724 home_dir = z;
3725 }
drhe98d4fa2002-04-21 19:06:22 +00003726
drh67505e72002-04-19 12:34:06 +00003727 return home_dir;
3728}
3729
3730/*
3731** Read input from the file given by sqliterc_override. Or if that
3732** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00003733**
3734** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00003735*/
shane9bd1b442009-10-23 01:27:39 +00003736static int process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00003737 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00003738 const char *sqliterc_override /* Name of config file. NULL to use default */
3739){
persicom7e2dfdd2002-04-18 02:46:52 +00003740 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00003741 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00003742 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003743 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00003744 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003745
3746 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00003747 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00003748 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00003749#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00003750 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00003751#endif
shane9bd1b442009-10-23 01:27:39 +00003752 return 1;
drhe98d4fa2002-04-21 19:06:22 +00003753 }
drh2f3de322012-06-27 16:41:31 +00003754 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00003755 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
3756 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003757 }
drha1f9b5e2004-02-14 16:31:02 +00003758 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00003759 if( in ){
drhc28490c2006-10-26 14:25:58 +00003760 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00003761 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00003762 }
shane9bd1b442009-10-23 01:27:39 +00003763 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00003764 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00003765 }
drh85e72432012-04-11 11:38:53 +00003766 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00003767 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00003768}
3769
drh67505e72002-04-19 12:34:06 +00003770/*
drhe1e38c42003-05-04 18:30:59 +00003771** Show available command line options
3772*/
3773static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00003774 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00003775 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003776 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00003777 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00003778 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00003779 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00003780 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00003781 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00003782#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3783 " -heap SIZE Size of heap for memsys3 or memsys5\n"
3784#endif
drhcc3b4f82012-02-07 14:13:50 +00003785 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00003786 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00003787 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003788 " -line set output mode to 'line'\n"
3789 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00003790 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00003791 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00003792#ifdef SQLITE_ENABLE_MULTIPLEX
3793 " -multiplex enable the multiplexor VFS\n"
3794#endif
drh6976c212014-07-24 12:09:47 +00003795 " -newline SEP set newline character(s) for CSV\n"
drh98d312f2012-10-25 15:23:14 +00003796 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00003797 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
3798 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
drh98d312f2012-10-25 15:23:14 +00003799 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00003800 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00003801 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00003802 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00003803#ifdef SQLITE_ENABLE_VFSTRACE
3804 " -vfstrace enable tracing of all VFS calls\n"
3805#endif
drhe1e38c42003-05-04 18:30:59 +00003806;
3807static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00003808 fprintf(stderr,
3809 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3810 "FILENAME is the name of an SQLite database. A new database is created\n"
3811 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00003812 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00003813 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00003814 }else{
3815 fprintf(stderr, "Use the -help option for additional information\n");
3816 }
3817 exit(1);
3818}
3819
3820/*
drh67505e72002-04-19 12:34:06 +00003821** Initialize the state information in data
3822*/
drhdcd87a92014-08-18 13:45:42 +00003823static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00003824 memset(data, 0, sizeof(*data));
3825 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00003826 memcpy(data->separator,"|", 2);
drh6976c212014-07-24 12:09:47 +00003827 memcpy(data->newline,"\r\n", 3);
persicom7e2dfdd2002-04-18 02:46:52 +00003828 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00003829 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00003830 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00003831 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00003832 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00003833 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3834 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00003835}
3836
drh98d312f2012-10-25 15:23:14 +00003837/*
drh5c7976f2014-02-10 19:59:27 +00003838** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00003839*/
3840#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00003841static void printBold(const char *zText){
3842 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
3843 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
3844 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
3845 SetConsoleTextAttribute(out,
3846 FOREGROUND_RED|FOREGROUND_INTENSITY
3847 );
3848 printf("%s", zText);
3849 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00003850}
3851#else
drh5c7976f2014-02-10 19:59:27 +00003852static void printBold(const char *zText){
3853 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00003854}
3855#endif
3856
3857/*
drh98d312f2012-10-25 15:23:14 +00003858** Get the argument to an --option. Throw an error and die if no argument
3859** is available.
3860*/
3861static char *cmdline_option_value(int argc, char **argv, int i){
3862 if( i==argc ){
3863 fprintf(stderr, "%s: Error: missing argument to %s\n",
3864 argv[0], argv[argc-1]);
3865 exit(1);
3866 }
3867 return argv[i];
3868}
3869
drh75897232000-05-29 14:26:00 +00003870int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003871 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00003872 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00003873 const char *zInitFile = 0;
3874 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003875 int i;
drhc28490c2006-10-26 14:25:58 +00003876 int rc = 0;
drhb3735912014-02-10 16:13:42 +00003877 int warnInmemoryDb = 0;
drh75897232000-05-29 14:26:00 +00003878
drh69b30ab2014-02-27 15:11:52 +00003879#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00003880 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
3881 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
3882 sqlite3_sourceid(), SQLITE_SOURCE_ID);
3883 exit(1);
3884 }
drhc7181902014-02-27 15:04:13 +00003885#endif
drhdaffd0e2001-04-11 14:28:42 +00003886 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003887 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003888 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003889
drh44c2eb12003-04-30 11:38:26 +00003890 /* Make sure we have a valid signal handler early, before anything
3891 ** else is done.
3892 */
drh4c504392000-10-16 22:06:40 +00003893#ifdef SIGINT
3894 signal(SIGINT, interrupt_handler);
3895#endif
drh44c2eb12003-04-30 11:38:26 +00003896
drh22fbcb82004-02-01 01:22:50 +00003897 /* Do an initial pass through the command-line argument to locate
3898 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00003899 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00003900 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003901 */
drh98d312f2012-10-25 15:23:14 +00003902 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00003903 char *z;
drhc28490c2006-10-26 14:25:58 +00003904 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003905 if( z[0]!='-' ){
3906 if( data.zDbFilename==0 ){
3907 data.zDbFilename = z;
3908 continue;
3909 }
3910 if( zFirstCmd==0 ){
3911 zFirstCmd = z;
3912 continue;
3913 }
3914 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
3915 fprintf(stderr,"Use -help for a list of options.\n");
3916 return 1;
3917 }
drhcc3b4f82012-02-07 14:13:50 +00003918 if( z[1]=='-' ) z++;
3919 if( strcmp(z,"-separator")==0
3920 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00003921 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00003922 || strcmp(z,"-cmd")==0
3923 ){
drh98d312f2012-10-25 15:23:14 +00003924 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003925 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00003926 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003927 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00003928 /* Need to check for batch mode here to so we can avoid printing
3929 ** informational messages (like from process_sqliterc) before
3930 ** we do the actual processing of arguments later in a second pass.
3931 */
shanef69573d2009-10-24 02:06:14 +00003932 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00003933 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00003934#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00003935 const char *zSize;
3936 sqlite3_int64 szHeap;
3937
drh98d312f2012-10-25 15:23:14 +00003938 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00003939 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00003940 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00003941 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3942#endif
drh44dec872014-08-30 15:49:25 +00003943 }else if( strcmp(z,"-scratch")==0 ){
3944 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00003945 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00003946 if( sz>400000 ) sz = 400000;
3947 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00003948 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00003949 if( n>10 ) n = 10;
3950 if( n<1 ) n = 1;
3951 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
3952 data.shellFlgs |= SHFLG_Scratch;
3953 }else if( strcmp(z,"-pagecache")==0 ){
3954 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00003955 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00003956 if( sz>70000 ) sz = 70000;
3957 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00003958 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00003959 if( n<10 ) n = 10;
3960 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
3961 data.shellFlgs |= SHFLG_Pagecache;
3962 }else if( strcmp(z,"-lookaside")==0 ){
3963 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00003964 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00003965 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00003966 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00003967 if( n<0 ) n = 0;
3968 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
3969 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00003970#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00003971 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00003972 extern int vfstrace_register(
3973 const char *zTraceName,
3974 const char *zOldVfsName,
3975 int (*xOut)(const char*,void*),
3976 void *pOutArg,
3977 int makeDefault
3978 );
drh2b625e22011-03-16 17:05:28 +00003979 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00003980#endif
drh6f25e892011-07-08 17:02:57 +00003981#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00003982 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00003983 extern int sqlite3_multiple_initialize(const char*,int);
3984 sqlite3_multiplex_initialize(0, 1);
3985#endif
drh7d9f3942013-04-03 01:26:54 +00003986 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00003987 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
3988 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00003989 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00003990 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00003991 if( pVfs ){
3992 sqlite3_vfs_register(pVfs, 1);
3993 }else{
3994 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3995 exit(1);
3996 }
drh44c2eb12003-04-30 11:38:26 +00003997 }
3998 }
drh98d312f2012-10-25 15:23:14 +00003999 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004000#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004001 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004002 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004003#else
shane86f5bdb2009-10-24 02:00:07 +00004004 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4005 return 1;
drh01b41712005-08-29 23:06:23 +00004006#endif
drhc7181902014-02-27 15:04:13 +00004007#ifdef SQLITE_SHELL_DBNAME_PROC
4008 { extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4009 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4010 warnInmemoryDb = 0; }
4011#endif
drh98d312f2012-10-25 15:23:14 +00004012 }
4013 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004014
drh44c2eb12003-04-30 11:38:26 +00004015 /* Go ahead and open the database file if it already exists. If the
4016 ** file does not exist, delay opening it. This prevents empty database
4017 ** files from being created if a user mistypes the database name argument
4018 ** to the sqlite command-line tool.
4019 */
drhc8d74412004-08-31 23:41:26 +00004020 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004021 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004022 }
4023
drh22fbcb82004-02-01 01:22:50 +00004024 /* Process the initialization file if there is one. If no -init option
4025 ** is given on the command line, look for a file named ~/.sqliterc and
4026 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004027 */
shane86f5bdb2009-10-24 02:00:07 +00004028 rc = process_sqliterc(&data,zInitFile);
4029 if( rc>0 ){
4030 return rc;
4031 }
drh44c2eb12003-04-30 11:38:26 +00004032
drh22fbcb82004-02-01 01:22:50 +00004033 /* Make a second pass through the command-line argument and set
4034 ** options. This second pass is delayed until after the initialization
4035 ** file is processed so that the command-line arguments will override
4036 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004037 */
drh98d312f2012-10-25 15:23:14 +00004038 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004039 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004040 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004041 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004042 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004043 i++;
4044 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004045 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004046 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004047 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004048 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004049 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004050 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004051 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004052 }else if( strcmp(z,"-csv")==0 ){
4053 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00004054 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00004055 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00004056 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00004057 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004058 }else if( strcmp(z,"-newline")==0 ){
4059 sqlite3_snprintf(sizeof(data.newline), data.newline,
4060 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004061 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00004062 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00004063 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004064 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004065 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004066 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004067 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004068 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004069 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004070 }else if( strcmp(z,"-eqp")==0 ){
4071 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004072 }else if( strcmp(z,"-stats")==0 ){
4073 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004074 }else if( strcmp(z,"-bail")==0 ){
4075 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004076 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004077 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004078 return 0;
drhc28490c2006-10-26 14:25:58 +00004079 }else if( strcmp(z,"-interactive")==0 ){
4080 stdin_is_interactive = 1;
4081 }else if( strcmp(z,"-batch")==0 ){
4082 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004083 }else if( strcmp(z,"-heap")==0 ){
4084 i++;
drh44dec872014-08-30 15:49:25 +00004085 }else if( strcmp(z,"-scratch")==0 ){
4086 i+=2;
4087 }else if( strcmp(z,"-pagecache")==0 ){
4088 i+=2;
4089 }else if( strcmp(z,"-lookaside")==0 ){
4090 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004091 }else if( strcmp(z,"-mmap")==0 ){
4092 i++;
drha7e61d82011-03-12 17:02:57 +00004093 }else if( strcmp(z,"-vfs")==0 ){
4094 i++;
drh6f25e892011-07-08 17:02:57 +00004095#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004096 }else if( strcmp(z,"-vfstrace")==0 ){
4097 i++;
drh6f25e892011-07-08 17:02:57 +00004098#endif
4099#ifdef SQLITE_ENABLE_MULTIPLEX
4100 }else if( strcmp(z,"-multiplex")==0 ){
4101 i++;
4102#endif
drhcc3b4f82012-02-07 14:13:50 +00004103 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004104 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004105 }else if( strcmp(z,"-cmd")==0 ){
4106 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004107 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004108 if( z[0]=='.' ){
4109 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004110 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004111 }else{
drh05782482013-10-24 15:20:20 +00004112 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004113 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4114 if( zErrMsg!=0 ){
4115 fprintf(stderr,"Error: %s\n", zErrMsg);
4116 if( bail_on_error ) return rc!=0 ? rc : 1;
4117 }else if( rc!=0 ){
4118 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4119 if( bail_on_error ) return rc;
4120 }
4121 }
drh1e5d0e92000-05-31 23:33:17 +00004122 }else{
shane86f5bdb2009-10-24 02:00:07 +00004123 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004124 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004125 return 1;
4126 }
4127 }
drh44c2eb12003-04-30 11:38:26 +00004128
drh22fbcb82004-02-01 01:22:50 +00004129 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00004130 /* Run just the command that follows the database name
4131 */
drh22fbcb82004-02-01 01:22:50 +00004132 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00004133 rc = do_meta_command(zFirstCmd, &data);
drh99b39082013-04-17 12:19:48 +00004134 if( rc==2 ) rc = 0;
drh6ff13852001-11-25 13:18:23 +00004135 }else{
drh05782482013-10-24 15:20:20 +00004136 open_db(&data, 0);
shane626a6e42009-10-22 17:30:15 +00004137 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00004138 if( zErrMsg!=0 ){
4139 fprintf(stderr,"Error: %s\n", zErrMsg);
4140 return rc!=0 ? rc : 1;
4141 }else if( rc!=0 ){
4142 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
4143 return rc;
drh6ff13852001-11-25 13:18:23 +00004144 }
drh75897232000-05-29 14:26:00 +00004145 }
4146 }else{
drh44c2eb12003-04-30 11:38:26 +00004147 /* Run commands received from standard input
4148 */
drhc28490c2006-10-26 14:25:58 +00004149 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004150 char *zHome;
4151 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004152 int nHistory;
drh75897232000-05-29 14:26:00 +00004153 printf(
drh743e0032011-12-12 16:51:50 +00004154 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004155 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004156 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004157 );
drhb3735912014-02-10 16:13:42 +00004158 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004159 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004160 printBold("transient in-memory database");
4161 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004162 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004163 }
drh67505e72002-04-19 12:34:06 +00004164 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004165 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004166 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004167 if( (zHistory = malloc(nHistory))!=0 ){
4168 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4169 }
drh67505e72002-04-19 12:34:06 +00004170 }
drhaaa21b42014-02-11 14:37:51 +00004171#if defined(HAVE_READLINE)
drh67505e72002-04-19 12:34:06 +00004172 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00004173#endif
drhc28490c2006-10-26 14:25:58 +00004174 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004175 if( zHistory ){
4176 stifle_history(100);
4177 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004178 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004179 }
drhdaffd0e2001-04-11 14:28:42 +00004180 }else{
drhc28490c2006-10-26 14:25:58 +00004181 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004182 }
4183 }
drh33048c02001-10-01 14:29:22 +00004184 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004185 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004186 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004187 }
drh05782482013-10-24 15:20:20 +00004188 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004189 return rc;
drh75897232000-05-29 14:26:00 +00004190}