blob: 68478a19badc6587721f7520b140085ab7f24ff9 [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 */
drh33048c02001-10-01 14:29:22 +0000465 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000466 char separator[20]; /* Separator character for MODE_List */
drh6976c212014-07-24 12:09:47 +0000467 char newline[20]; /* Record separator in MODE_Csv */
drha0c66f52000-07-29 13:20:21 +0000468 int colWidth[100]; /* Requested width of each column when in column mode*/
469 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000470 char nullvalue[20]; /* The text to print when a NULL comes back from
471 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000472 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000473 char outfile[FILENAME_MAX]; /* Filename for *out */
474 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000475 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000476 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000477 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000478 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000479 int *aiIndent; /* Array of indents used in MODE_Explain */
480 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000481 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000482};
483
484/*
485** These are the allowed modes.
486*/
drh967e8b72000-06-21 13:59:10 +0000487#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000488#define MODE_Column 1 /* One record per line in neat columns */
489#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000490#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
491#define MODE_Html 4 /* Generate an XHTML table */
492#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000493#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000494#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000495#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000496
drh66ce4d02008-02-15 17:38:06 +0000497static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000498 "line",
499 "column",
500 "list",
501 "semi",
502 "html",
drhfeac5f82004-08-01 00:10:45 +0000503 "insert",
504 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000505 "csv",
drh66ce4d02008-02-15 17:38:06 +0000506 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000507};
drh75897232000-05-29 14:26:00 +0000508
509/*
510** Number of elements in an array
511*/
drh902b9ee2008-12-05 17:17:07 +0000512#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000513
514/*
drhea678832008-12-10 19:26:22 +0000515** Compute a string length that is limited to what can be stored in
516** lower 30 bits of a 32-bit signed integer.
517*/
drh4f21c4a2008-12-10 22:15:00 +0000518static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000519 const char *z2 = z;
520 while( *z2 ){ z2++; }
521 return 0x3fffffff & (int)(z2 - z);
522}
523
524/*
drh127f9d72010-02-23 01:47:00 +0000525** A callback for the sqlite3_log() interface.
526*/
527static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000528 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000529 if( p->pLog==0 ) return;
530 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
531 fflush(p->pLog);
532}
533
534/*
shane626a6e42009-10-22 17:30:15 +0000535** Output the given string as a hex-encoded blob (eg. X'1234' )
536*/
537static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
538 int i;
539 char *zBlob = (char *)pBlob;
540 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000541 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000542 fprintf(out,"'");
543}
544
545/*
drh28bd4bc2000-06-15 15:57:22 +0000546** Output the given string as a quoted string using SQL quoting conventions.
547*/
548static void output_quoted_string(FILE *out, const char *z){
549 int i;
550 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000551 for(i=0; z[i]; i++){
552 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000553 }
554 if( nSingle==0 ){
555 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000556 }else{
557 fprintf(out,"'");
558 while( *z ){
559 for(i=0; z[i] && z[i]!='\''; i++){}
560 if( i==0 ){
561 fprintf(out,"''");
562 z++;
563 }else if( z[i]=='\'' ){
564 fprintf(out,"%.*s''",i,z);
565 z += i+1;
566 }else{
drhcd7d2732002-02-26 23:24:26 +0000567 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000568 break;
569 }
570 }
drhcd7d2732002-02-26 23:24:26 +0000571 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000572 }
573}
574
575/*
drhfeac5f82004-08-01 00:10:45 +0000576** Output the given string as a quoted according to C or TCL quoting rules.
577*/
578static void output_c_string(FILE *out, const char *z){
579 unsigned int c;
580 fputc('"', out);
581 while( (c = *(z++))!=0 ){
582 if( c=='\\' ){
583 fputc(c, out);
584 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000585 }else if( c=='"' ){
586 fputc('\\', out);
587 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000588 }else if( c=='\t' ){
589 fputc('\\', out);
590 fputc('t', out);
591 }else if( c=='\n' ){
592 fputc('\\', out);
593 fputc('n', out);
594 }else if( c=='\r' ){
595 fputc('\\', out);
596 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000597 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000598 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000599 }else{
600 fputc(c, out);
601 }
602 }
603 fputc('"', out);
604}
605
606/*
drhc08a4f12000-06-15 16:49:48 +0000607** Output the given string with characters that are special to
608** HTML escaped.
609*/
610static void output_html_string(FILE *out, const char *z){
611 int i;
drhc3d6ba42014-01-13 20:38:35 +0000612 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000613 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000614 for(i=0; z[i]
615 && z[i]!='<'
616 && z[i]!='&'
617 && z[i]!='>'
618 && z[i]!='\"'
619 && z[i]!='\'';
620 i++){}
drhc08a4f12000-06-15 16:49:48 +0000621 if( i>0 ){
622 fprintf(out,"%.*s",i,z);
623 }
624 if( z[i]=='<' ){
625 fprintf(out,"&lt;");
626 }else if( z[i]=='&' ){
627 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000628 }else if( z[i]=='>' ){
629 fprintf(out,"&gt;");
630 }else if( z[i]=='\"' ){
631 fprintf(out,"&quot;");
632 }else if( z[i]=='\'' ){
633 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000634 }else{
635 break;
636 }
637 z += i + 1;
638 }
639}
640
641/*
drhc49f44e2006-10-26 18:15:42 +0000642** If a field contains any character identified by a 1 in the following
643** array, then the string must be quoted for CSV.
644*/
645static const char needCsvQuote[] = {
646 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
647 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
648 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
649 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
650 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
651 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
652 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
653 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
657 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
658 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
659 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
660 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
661 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
662};
663
664/*
drh8e64d1c2004-10-07 00:32:39 +0000665** Output a single term of CSV. Actually, p->separator is used for
666** the separator, which may or may not be a comma. p->nullvalue is
drh6976c212014-07-24 12:09:47 +0000667** the null value. Strings are quoted if necessary. The separator
668** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000669*/
drhdcd87a92014-08-18 13:45:42 +0000670static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000671 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000672 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000673 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000674 }else{
drhc49f44e2006-10-26 18:15:42 +0000675 int i;
drh4f21c4a2008-12-10 22:15:00 +0000676 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000677 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000678 if( needCsvQuote[((unsigned char*)z)[i]]
679 || (z[i]==p->separator[0] &&
680 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000681 i = 0;
682 break;
683 }
684 }
685 if( i==0 ){
686 putc('"', out);
687 for(i=0; z[i]; i++){
688 if( z[i]=='"' ) putc('"', out);
689 putc(z[i], out);
690 }
691 putc('"', out);
692 }else{
693 fprintf(out, "%s", z);
694 }
drh8e64d1c2004-10-07 00:32:39 +0000695 }
696 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000697 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000698 }
699}
700
danielk19774af00c62005-01-23 23:43:21 +0000701#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000702/*
drh4c504392000-10-16 22:06:40 +0000703** This routine runs when the user presses Ctrl-C
704*/
705static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000706 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000707 seenInterrupt++;
708 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000709 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000710}
danielk19774af00c62005-01-23 23:43:21 +0000711#endif
drh4c504392000-10-16 22:06:40 +0000712
713/*
shane626a6e42009-10-22 17:30:15 +0000714** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000715** invokes for each row of a query result.
716*/
shane626a6e42009-10-22 17:30:15 +0000717static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000718 int i;
drhdcd87a92014-08-18 13:45:42 +0000719 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000720
drh75897232000-05-29 14:26:00 +0000721 switch( p->mode ){
722 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000723 int w = 5;
drh6a535342001-10-19 16:44:56 +0000724 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000725 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000726 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000727 if( len>w ) w = len;
728 }
drh75897232000-05-29 14:26:00 +0000729 if( p->cnt++>0 ) fprintf(p->out,"\n");
730 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000731 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000732 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000733 }
734 break;
735 }
danielk19770d78bae2008-01-03 07:09:48 +0000736 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000737 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000738 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000739 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000740 int w, n;
741 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000742 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000743 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000744 w = 0;
drh75897232000-05-29 14:26:00 +0000745 }
drh078b1fd2012-09-21 13:40:02 +0000746 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000747 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000748 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000749 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000750 if( w<n ) w = n;
751 }
752 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000753 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000754 }
755 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000756 if( w<0 ){
757 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
758 }else{
759 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
760 }
drha0c66f52000-07-29 13:20:21 +0000761 }
762 }
763 if( p->showHeader ){
764 for(i=0; i<nArg; i++){
765 int w;
766 if( i<ArraySize(p->actualWidth) ){
767 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000768 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000769 }else{
770 w = 10;
771 }
772 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
773 "----------------------------------------------------------",
774 i==nArg-1 ? "\n": " ");
775 }
drh75897232000-05-29 14:26:00 +0000776 }
777 }
drh6a535342001-10-19 16:44:56 +0000778 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000779 for(i=0; i<nArg; i++){
780 int w;
drha0c66f52000-07-29 13:20:21 +0000781 if( i<ArraySize(p->actualWidth) ){
782 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000783 }else{
784 w = 10;
785 }
dana98bf362013-11-13 18:35:01 +0000786 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000787 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000788 }
dana98bf362013-11-13 18:35:01 +0000789 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000790 if( p->iIndent<p->nIndent ){
791 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000792 }
danc4650bb2013-11-18 08:41:06 +0000793 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000794 }
drh078b1fd2012-09-21 13:40:02 +0000795 if( w<0 ){
796 fprintf(p->out,"%*.*s%s",-w,-w,
797 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
798 }else{
799 fprintf(p->out,"%-*.*s%s",w,w,
800 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
801 }
drh75897232000-05-29 14:26:00 +0000802 }
803 break;
804 }
drhe3710332000-09-29 13:30:53 +0000805 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000806 case MODE_List: {
807 if( p->cnt++==0 && p->showHeader ){
808 for(i=0; i<nArg; i++){
809 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
810 }
811 }
drh6a535342001-10-19 16:44:56 +0000812 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000813 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000814 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000815 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000816 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000817 if( i<nArg-1 ){
818 fprintf(p->out, "%s", p->separator);
819 }else if( p->mode==MODE_Semi ){
820 fprintf(p->out, ";\n");
821 }else{
822 fprintf(p->out, "\n");
823 }
drh75897232000-05-29 14:26:00 +0000824 }
825 break;
826 }
drh1e5d0e92000-05-31 23:33:17 +0000827 case MODE_Html: {
828 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000829 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000830 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000831 fprintf(p->out,"<TH>");
832 output_html_string(p->out, azCol[i]);
833 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000834 }
mihailim57c591a2008-06-23 21:26:05 +0000835 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000836 }
drh6a535342001-10-19 16:44:56 +0000837 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000838 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000839 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000840 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000841 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000842 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000843 }
mihailim57c591a2008-06-23 21:26:05 +0000844 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000845 break;
846 }
drhfeac5f82004-08-01 00:10:45 +0000847 case MODE_Tcl: {
848 if( p->cnt++==0 && p->showHeader ){
849 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000850 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin585dcb22012-12-04 00:23:43 +0000851 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000852 }
853 fprintf(p->out,"\n");
854 }
855 if( azArg==0 ) break;
856 for(i=0; i<nArg; i++){
857 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mistachkin585dcb22012-12-04 00:23:43 +0000858 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000859 }
860 fprintf(p->out,"\n");
861 break;
862 }
drh8e64d1c2004-10-07 00:32:39 +0000863 case MODE_Csv: {
drh6976c212014-07-24 12:09:47 +0000864#if defined(WIN32) || defined(_WIN32)
865 fflush(p->out);
866 _setmode(_fileno(p->out), _O_BINARY);
867#endif
drh8e64d1c2004-10-07 00:32:39 +0000868 if( p->cnt++==0 && p->showHeader ){
869 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000870 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000871 }
drh6976c212014-07-24 12:09:47 +0000872 fprintf(p->out,"%s",p->newline);
drh8e64d1c2004-10-07 00:32:39 +0000873 }
drh6976c212014-07-24 12:09:47 +0000874 if( azArg>0 ){
875 for(i=0; i<nArg; i++){
876 output_csv(p, azArg[i], i<nArg-1);
877 }
878 fprintf(p->out,"%s",p->newline);
drh8e64d1c2004-10-07 00:32:39 +0000879 }
drh6976c212014-07-24 12:09:47 +0000880#if defined(WIN32) || defined(_WIN32)
881 fflush(p->out);
882 _setmode(_fileno(p->out), _O_TEXT);
883#endif
drh8e64d1c2004-10-07 00:32:39 +0000884 break;
885 }
drh28bd4bc2000-06-15 15:57:22 +0000886 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000887 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000888 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000889 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000890 for(i=0; i<nArg; i++){
891 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000892 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000893 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000894 }else if( aiType && aiType[i]==SQLITE_TEXT ){
895 if( zSep[0] ) fprintf(p->out,"%s",zSep);
896 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +0000897 }else if( aiType && (aiType[i]==SQLITE_INTEGER
898 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +0000899 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000900 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
901 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
902 int nBlob = sqlite3_column_bytes(p->pStmt, i);
903 if( zSep[0] ) fprintf(p->out,"%s",zSep);
904 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000905 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000906 fprintf(p->out,"%s%s",zSep, azArg[i]);
907 }else{
908 if( zSep[0] ) fprintf(p->out,"%s",zSep);
909 output_quoted_string(p->out, azArg[i]);
910 }
911 }
912 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000913 break;
drh28bd4bc2000-06-15 15:57:22 +0000914 }
persicom1d0b8722002-04-18 02:53:04 +0000915 }
drh75897232000-05-29 14:26:00 +0000916 return 0;
917}
918
919/*
shane626a6e42009-10-22 17:30:15 +0000920** This is the callback routine that the SQLite library
921** invokes for each row of a query result.
922*/
923static int callback(void *pArg, int nArg, char **azArg, char **azCol){
924 /* since we don't have type info, call the shell_callback with a NULL value */
925 return shell_callback(pArg, nArg, azArg, azCol, NULL);
926}
927
928/*
drhdcd87a92014-08-18 13:45:42 +0000929** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +0000930** the name of the table given. Escape any quote characters in the
931** table name.
932*/
drhdcd87a92014-08-18 13:45:42 +0000933static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +0000934 int i, n;
935 int needQuote;
936 char *z;
937
938 if( p->zDestTable ){
939 free(p->zDestTable);
940 p->zDestTable = 0;
941 }
942 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000943 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000944 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000945 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000946 needQuote = 1;
947 if( zName[i]=='\'' ) n++;
948 }
949 }
950 if( needQuote ) n += 2;
951 z = p->zDestTable = malloc( n+1 );
952 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000953 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000954 exit(1);
955 }
956 n = 0;
957 if( needQuote ) z[n++] = '\'';
958 for(i=0; zName[i]; i++){
959 z[n++] = zName[i];
960 if( zName[i]=='\'' ) z[n++] = '\'';
961 }
962 if( needQuote ) z[n++] = '\'';
963 z[n] = 0;
964}
965
danielk19772a02e332004-06-05 08:04:36 +0000966/* zIn is either a pointer to a NULL-terminated string in memory obtained
967** from malloc(), or a NULL pointer. The string pointed to by zAppend is
968** added to zIn, and the result returned in memory obtained from malloc().
969** zIn, if it was not NULL, is freed.
970**
971** If the third argument, quote, is not '\0', then it is used as a
972** quote character for zAppend.
973*/
drhc28490c2006-10-26 14:25:58 +0000974static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000975 int len;
976 int i;
drh4f21c4a2008-12-10 22:15:00 +0000977 int nAppend = strlen30(zAppend);
978 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000979
980 len = nAppend+nIn+1;
981 if( quote ){
982 len += 2;
983 for(i=0; i<nAppend; i++){
984 if( zAppend[i]==quote ) len++;
985 }
986 }
987
988 zIn = (char *)realloc(zIn, len);
989 if( !zIn ){
990 return 0;
991 }
992
993 if( quote ){
994 char *zCsr = &zIn[nIn];
995 *zCsr++ = quote;
996 for(i=0; i<nAppend; i++){
997 *zCsr++ = zAppend[i];
998 if( zAppend[i]==quote ) *zCsr++ = quote;
999 }
1000 *zCsr++ = quote;
1001 *zCsr++ = '\0';
1002 assert( (zCsr-zIn)==len );
1003 }else{
1004 memcpy(&zIn[nIn], zAppend, nAppend);
1005 zIn[len-1] = '\0';
1006 }
1007
1008 return zIn;
1009}
1010
drhdd3d4592004-08-30 01:54:05 +00001011
1012/*
drhb21a8e42012-01-28 21:08:51 +00001013** Execute a query statement that will generate SQL output. Print
1014** the result columns, comma-separated, on a line and then add a
1015** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001016**
drhb21a8e42012-01-28 21:08:51 +00001017** If the number of columns is 1 and that column contains text "--"
1018** then write the semicolon on a separate line. That way, if a
1019** "--" comment occurs at the end of the statement, the comment
1020** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001021*/
drh157e29a2009-05-21 15:15:00 +00001022static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001023 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001024 const char *zSelect, /* SELECT statement to extract content */
1025 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001026){
drhdd3d4592004-08-30 01:54:05 +00001027 sqlite3_stmt *pSelect;
1028 int rc;
drhb21a8e42012-01-28 21:08:51 +00001029 int nResult;
1030 int i;
1031 const char *z;
drhc7181902014-02-27 15:04:13 +00001032 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001033 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001034 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001035 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001036 return rc;
1037 }
1038 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001039 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001040 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001041 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001042 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001043 zFirstRow = 0;
1044 }
drhb21a8e42012-01-28 21:08:51 +00001045 z = (const char*)sqlite3_column_text(pSelect, 0);
1046 fprintf(p->out, "%s", z);
1047 for(i=1; i<nResult; i++){
1048 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1049 }
1050 if( z==0 ) z = "";
1051 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1052 if( z[0] ){
1053 fprintf(p->out, "\n;\n");
1054 }else{
1055 fprintf(p->out, ";\n");
1056 }
drhdd3d4592004-08-30 01:54:05 +00001057 rc = sqlite3_step(pSelect);
1058 }
drh2f464a02011-10-13 00:41:49 +00001059 rc = sqlite3_finalize(pSelect);
1060 if( rc!=SQLITE_OK ){
1061 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001062 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001063 }
1064 return rc;
drhdd3d4592004-08-30 01:54:05 +00001065}
1066
shane626a6e42009-10-22 17:30:15 +00001067/*
1068** Allocate space and save off current error string.
1069*/
1070static char *save_err_msg(
1071 sqlite3 *db /* Database to query */
1072){
1073 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1074 char *zErrMsg = sqlite3_malloc(nErrMsg);
1075 if( zErrMsg ){
1076 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1077 }
1078 return zErrMsg;
1079}
1080
1081/*
shaneh642d8b82010-07-28 16:05:34 +00001082** Display memory stats.
1083*/
1084static int display_stats(
1085 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001086 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001087 int bReset /* True to reset the stats */
1088){
1089 int iCur;
1090 int iHiwtr;
1091
1092 if( pArg && pArg->out ){
1093
1094 iHiwtr = iCur = -1;
1095 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001096 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001097 iHiwtr = iCur = -1;
1098 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001099 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001100/*
1101** Not currently used by the CLI.
1102** iHiwtr = iCur = -1;
1103** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1104** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1105*/
1106 iHiwtr = iCur = -1;
1107 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1108 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1109/*
1110** Not currently used by the CLI.
1111** iHiwtr = iCur = -1;
1112** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1113** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1114*/
1115 iHiwtr = iCur = -1;
1116 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1117 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1118 iHiwtr = iCur = -1;
1119 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1120 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1121 iHiwtr = iCur = -1;
1122 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1123 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1124 iHiwtr = iCur = -1;
1125 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1126 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1127#ifdef YYTRACKMAXSTACKDEPTH
1128 iHiwtr = iCur = -1;
1129 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1130 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1131#endif
1132 }
1133
1134 if( pArg && pArg->out && db ){
1135 iHiwtr = iCur = -1;
1136 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1137 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001138 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1139 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1140 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1141 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1142 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1143 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001144 iHiwtr = iCur = -1;
1145 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001146 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1147 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1148 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1149 iHiwtr = iCur = -1;
1150 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1151 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001152 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001153 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1154 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1155 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001156 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1157 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1158 iHiwtr = iCur = -1;
1159 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1160 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1161 }
1162
1163 if( pArg && pArg->out && db && pArg->pStmt ){
1164 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1165 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1166 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1167 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1168 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1169 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001170 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1171 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001172 }
1173
1174 return 0;
1175}
1176
1177/*
dana98bf362013-11-13 18:35:01 +00001178** Parameter azArray points to a zero-terminated array of strings. zStr
1179** points to a single nul-terminated string. Return non-zero if zStr
1180** is equal, according to strcmp(), to any of the strings in the array.
1181** Otherwise, return zero.
1182*/
1183static int str_in_array(const char *zStr, const char **azArray){
1184 int i;
1185 for(i=0; azArray[i]; i++){
1186 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1187 }
1188 return 0;
1189}
1190
1191/*
1192** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001193** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001194** spaces each opcode should be indented before it is output.
1195**
1196** The indenting rules are:
1197**
1198** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1199** all opcodes that occur between the p2 jump destination and the opcode
1200** itself by 2 spaces.
1201**
drh01752bc2013-11-14 23:59:33 +00001202** * For each "Goto", if the jump destination is earlier in the program
1203** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001204** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001205** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001206** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001207** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001208*/
drhdcd87a92014-08-18 13:45:42 +00001209static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001210 const char *zSql; /* The text of the SQL statement */
1211 const char *z; /* Used to check if this is an EXPLAIN */
1212 int *abYield = 0; /* True if op is an OP_Yield */
1213 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001214 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001215
drh8ad0de32014-03-20 18:45:27 +00001216 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1217 "NextIfOpen", "PrevIfOpen", 0 };
drhb463fef2014-05-29 20:17:57 +00001218 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001219 const char *azGoto[] = { "Goto", 0 };
1220
1221 /* Try to figure out if this is really an EXPLAIN statement. If this
1222 ** cannot be verified, return early. */
1223 zSql = sqlite3_sql(pSql);
1224 if( zSql==0 ) return;
1225 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1226 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1227
1228 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1229 int i;
danc4650bb2013-11-18 08:41:06 +00001230 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001231 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001232
1233 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1234 ** p2 is an instruction address, set variable p2op to the index of that
1235 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1236 ** the current instruction is part of a sub-program generated by an
1237 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001238 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001239 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001240
1241 /* Grow the p->aiIndent array as required */
1242 if( iOp>=nAlloc ){
1243 nAlloc += 100;
1244 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1245 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1246 }
1247 abYield[iOp] = str_in_array(zOp, azYield);
1248 p->aiIndent[iOp] = 0;
1249 p->nIndent = iOp+1;
1250
1251 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001252 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001253 }
drhfe705102014-03-06 13:38:37 +00001254 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1255 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1256 ){
drhe73f0592014-01-21 22:25:45 +00001257 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001258 }
1259 }
1260
danc4650bb2013-11-18 08:41:06 +00001261 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001262 sqlite3_free(abYield);
1263 sqlite3_reset(pSql);
1264}
1265
1266/*
1267** Free the array allocated by explain_data_prepare().
1268*/
drhdcd87a92014-08-18 13:45:42 +00001269static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001270 sqlite3_free(p->aiIndent);
1271 p->aiIndent = 0;
1272 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001273 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001274}
1275
1276/*
shane626a6e42009-10-22 17:30:15 +00001277** Execute a statement or set of statements. Print
1278** any result rows/columns depending on the current mode
1279** set via the supplied callback.
1280**
1281** This is very similar to SQLite's built-in sqlite3_exec()
1282** function except it takes a slightly different callback
1283** and callback data argument.
1284*/
1285static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001286 sqlite3 *db, /* An open database */
1287 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001288 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001289 /* (not the same as sqlite3_exec) */
1290 ShellState *pArg, /* Pointer to ShellState */
1291 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001292){
dan4564ced2010-01-05 04:59:56 +00001293 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1294 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001295 int rc2;
dan4564ced2010-01-05 04:59:56 +00001296 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001297
1298 if( pzErrMsg ){
1299 *pzErrMsg = NULL;
1300 }
1301
shaneb9fc17d2009-10-22 21:23:35 +00001302 while( zSql[0] && (SQLITE_OK == rc) ){
1303 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1304 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001305 if( pzErrMsg ){
1306 *pzErrMsg = save_err_msg(db);
1307 }
1308 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001309 if( !pStmt ){
1310 /* this happens for a comment or white-space */
1311 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001312 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001313 continue;
1314 }
shane626a6e42009-10-22 17:30:15 +00001315
shaneh642d8b82010-07-28 16:05:34 +00001316 /* save off the prepared statment handle and reset row count */
1317 if( pArg ){
1318 pArg->pStmt = pStmt;
1319 pArg->cnt = 0;
1320 }
1321
shanehb7977c52010-01-18 18:17:10 +00001322 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001323 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001324 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001325 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001326 }
shanehb7977c52010-01-18 18:17:10 +00001327
drhefbf3b12014-02-28 20:47:24 +00001328 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1329 if( pArg && pArg->autoEQP ){
1330 sqlite3_stmt *pExplain;
1331 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
1332 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1333 if( rc==SQLITE_OK ){
1334 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1335 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1336 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1337 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1338 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1339 }
1340 }
1341 sqlite3_finalize(pExplain);
1342 sqlite3_free(zEQP);
1343 }
1344
drh7e02e5e2011-12-06 19:44:51 +00001345 /* Output TESTCTRL_EXPLAIN text of requested */
1346 if( pArg && pArg->mode==MODE_Explain ){
1347 const char *zExplain = 0;
1348 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1349 if( zExplain && zExplain[0] ){
1350 fprintf(pArg->out, "%s", zExplain);
1351 }
1352 }
1353
dana98bf362013-11-13 18:35:01 +00001354 /* If the shell is currently in ".explain" mode, gather the extra
1355 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001356 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001357 explain_data_prepare(pArg, pStmt);
1358 }
1359
shaneb9fc17d2009-10-22 21:23:35 +00001360 /* perform the first step. this will tell us if we
1361 ** have a result set or not and how wide it is.
1362 */
1363 rc = sqlite3_step(pStmt);
1364 /* if we have a result set... */
1365 if( SQLITE_ROW == rc ){
1366 /* if we have a callback... */
1367 if( xCallback ){
1368 /* allocate space for col name ptr, value ptr, and type */
1369 int nCol = sqlite3_column_count(pStmt);
1370 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1371 if( !pData ){
1372 rc = SQLITE_NOMEM;
1373 }else{
1374 char **azCols = (char **)pData; /* Names of result columns */
1375 char **azVals = &azCols[nCol]; /* Results */
1376 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001377 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001378 assert(sizeof(int) <= sizeof(char *));
1379 /* save off ptrs to column names */
1380 for(i=0; i<nCol; i++){
1381 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1382 }
shaneb9fc17d2009-10-22 21:23:35 +00001383 do{
1384 /* extract the data and data types */
1385 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001386 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001387 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001388 azVals[i] = "";
1389 }else{
1390 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1391 }
shaneb9fc17d2009-10-22 21:23:35 +00001392 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1393 rc = SQLITE_NOMEM;
1394 break; /* from for */
1395 }
1396 } /* end for */
1397
1398 /* if data and types extracted successfully... */
1399 if( SQLITE_ROW == rc ){
1400 /* call the supplied callback with the result row data */
1401 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1402 rc = SQLITE_ABORT;
1403 }else{
1404 rc = sqlite3_step(pStmt);
1405 }
1406 }
1407 } while( SQLITE_ROW == rc );
1408 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001409 }
1410 }else{
1411 do{
1412 rc = sqlite3_step(pStmt);
1413 } while( rc == SQLITE_ROW );
1414 }
1415 }
1416
dana98bf362013-11-13 18:35:01 +00001417 explain_data_delete(pArg);
1418
shaneh642d8b82010-07-28 16:05:34 +00001419 /* print usage stats if stats on */
1420 if( pArg && pArg->statsOn ){
1421 display_stats(db, pArg, 0);
1422 }
1423
dan4564ced2010-01-05 04:59:56 +00001424 /* Finalize the statement just executed. If this fails, save a
1425 ** copy of the error message. Otherwise, set zSql to point to the
1426 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001427 rc2 = sqlite3_finalize(pStmt);
1428 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001429 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001430 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001431 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001432 }else if( pzErrMsg ){
1433 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001434 }
shaneh642d8b82010-07-28 16:05:34 +00001435
1436 /* clear saved stmt handle */
1437 if( pArg ){
1438 pArg->pStmt = NULL;
1439 }
shane626a6e42009-10-22 17:30:15 +00001440 }
shaneb9fc17d2009-10-22 21:23:35 +00001441 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001442
1443 return rc;
1444}
1445
drhdd3d4592004-08-30 01:54:05 +00001446
drh33048c02001-10-01 14:29:22 +00001447/*
drh4c653a02000-06-07 01:27:47 +00001448** This is a different callback routine used for dumping the database.
1449** Each row received by this callback consists of a table name,
1450** the table type ("index" or "table") and SQL to create the table.
1451** This routine should print text sufficient to recreate the table.
1452*/
1453static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001454 int rc;
1455 const char *zTable;
1456 const char *zType;
1457 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001458 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001459 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001460
drh902b9ee2008-12-05 17:17:07 +00001461 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001462 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001463 zTable = azArg[0];
1464 zType = azArg[1];
1465 zSql = azArg[2];
1466
drh00b950d2005-09-11 02:03:03 +00001467 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001468 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001469 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001470 fprintf(p->out, "ANALYZE sqlite_master;\n");
1471 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1472 return 0;
drh45e29d82006-11-20 16:21:10 +00001473 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1474 char *zIns;
1475 if( !p->writableSchema ){
1476 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1477 p->writableSchema = 1;
1478 }
1479 zIns = sqlite3_mprintf(
1480 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1481 "VALUES('table','%q','%q',0,'%q');",
1482 zTable, zTable, zSql);
1483 fprintf(p->out, "%s\n", zIns);
1484 sqlite3_free(zIns);
1485 return 0;
drh00b950d2005-09-11 02:03:03 +00001486 }else{
1487 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001488 }
danielk19772a02e332004-06-05 08:04:36 +00001489
1490 if( strcmp(zType, "table")==0 ){
1491 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001492 char *zSelect = 0;
1493 char *zTableInfo = 0;
1494 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001495 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001496
1497 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1498 zTableInfo = appendText(zTableInfo, zTable, '"');
1499 zTableInfo = appendText(zTableInfo, ");", 0);
1500
drhc7181902014-02-27 15:04:13 +00001501 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001502 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001503 if( rc!=SQLITE_OK || !pTableInfo ){
1504 return 1;
1505 }
1506
1507 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001508 /* Always quote the table name, even if it appears to be pure ascii,
1509 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1510 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001511 if( zTmp ){
1512 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001513 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001514 }
1515 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1516 rc = sqlite3_step(pTableInfo);
1517 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001518 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001519 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001520 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001521 rc = sqlite3_step(pTableInfo);
1522 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001523 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001524 }else{
1525 zSelect = appendText(zSelect, ") ", 0);
1526 }
drh157e29a2009-05-21 15:15:00 +00001527 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001528 }
1529 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001530 if( rc!=SQLITE_OK || nRow==0 ){
1531 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001532 return 1;
1533 }
1534 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1535 zSelect = appendText(zSelect, zTable, '"');
1536
drh2f464a02011-10-13 00:41:49 +00001537 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001538 if( rc==SQLITE_CORRUPT ){
1539 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001540 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001541 }
drh85e72432012-04-11 11:38:53 +00001542 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001543 }
drh4c653a02000-06-07 01:27:47 +00001544 return 0;
1545}
1546
1547/*
drh45e29d82006-11-20 16:21:10 +00001548** Run zQuery. Use dump_callback() as the callback routine so that
1549** the contents of the query are output as SQL statements.
1550**
drhdd3d4592004-08-30 01:54:05 +00001551** If we get a SQLITE_CORRUPT error, rerun the query after appending
1552** "ORDER BY rowid DESC" to the end.
1553*/
1554static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001555 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001556 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001557){
1558 int rc;
drh2f464a02011-10-13 00:41:49 +00001559 char *zErr = 0;
1560 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001561 if( rc==SQLITE_CORRUPT ){
1562 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001563 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001564 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1565 if( zErr ){
1566 fprintf(p->out, "/****** %s ******/\n", zErr);
1567 sqlite3_free(zErr);
1568 zErr = 0;
1569 }
drhdd3d4592004-08-30 01:54:05 +00001570 zQ2 = malloc( len+100 );
1571 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001572 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001573 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1574 if( rc ){
1575 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1576 }else{
1577 rc = SQLITE_CORRUPT;
1578 }
1579 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001580 free(zQ2);
1581 }
1582 return rc;
1583}
1584
1585/*
drh75897232000-05-29 14:26:00 +00001586** Text of a help message
1587*/
persicom1d0b8722002-04-18 02:53:04 +00001588static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001589 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001590 ".bail on|off Stop after hitting an error. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001591 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001592 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001593 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001594 " If TABLE specified, only dump tables matching\n"
1595 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001596 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001597 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001598 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001599 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001600 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001601 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001602 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001603 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001604 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001605 ".indices ?TABLE? Show names of all indices\n"
1606 " If TABLE specified, only show indices for tables\n"
1607 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001608#ifdef SQLITE_ENABLE_IOTRACE
1609 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1610#endif
drh70df4fe2006-06-13 15:12:21 +00001611#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001612 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001613#endif
drh127f9d72010-02-23 01:47:00 +00001614 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001615 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001616 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001617 " column Left-aligned columns. (See .width)\n"
1618 " html HTML <table> code\n"
1619 " insert SQL insert statements for TABLE\n"
1620 " line One value per line\n"
1621 " list Values delimited by .separator string\n"
1622 " tabs Tab-separated values\n"
1623 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001624 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001625 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001626 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001627 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001628 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001629 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001630 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001631 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001632 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001633 ".save FILE Write in-memory database into FILE\n"
drh75897232000-05-29 14:26:00 +00001634 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001635 " If TABLE specified, only show tables matching\n"
1636 " LIKE pattern TABLE.\n"
drh6976c212014-07-24 12:09:47 +00001637 ".separator STRING ?NL? Change separator used by output mode and .import\n"
1638 " NL is the end-of-line mark for CSV\n"
drh62cdde52014-05-28 20:22:28 +00001639 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001640 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001641 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001642 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001643 ".tables ?TABLE? List names of tables\n"
1644 " If TABLE specified, only list tables matching\n"
1645 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001646 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001647 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001648 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001649 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001650 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001651 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001652;
1653
drhdaffd0e2001-04-11 14:28:42 +00001654/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001655static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001656/*
1657** Implementation of the "readfile(X)" SQL function. The entire content
1658** of the file named X is read and returned as a BLOB. NULL is returned
1659** if the file does not exist or is unreadable.
1660*/
1661static void readfileFunc(
1662 sqlite3_context *context,
1663 int argc,
1664 sqlite3_value **argv
1665){
1666 const char *zName;
1667 FILE *in;
1668 long nIn;
1669 void *pBuf;
1670
1671 zName = (const char*)sqlite3_value_text(argv[0]);
1672 if( zName==0 ) return;
1673 in = fopen(zName, "rb");
1674 if( in==0 ) return;
1675 fseek(in, 0, SEEK_END);
1676 nIn = ftell(in);
1677 rewind(in);
1678 pBuf = sqlite3_malloc( nIn );
1679 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1680 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1681 }else{
1682 sqlite3_free(pBuf);
1683 }
1684 fclose(in);
1685}
1686
1687/*
1688** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1689** is written into file X. The number of bytes written is returned. Or
1690** NULL is returned if something goes wrong, such as being unable to open
1691** file X for writing.
1692*/
1693static void writefileFunc(
1694 sqlite3_context *context,
1695 int argc,
1696 sqlite3_value **argv
1697){
1698 FILE *out;
1699 const char *z;
drhba5b0932014-07-24 12:39:59 +00001700 sqlite3_int64 rc;
1701 const char *zFile;
1702
1703 zFile = (const char*)sqlite3_value_text(argv[0]);
1704 if( zFile==0 ) return;
1705 out = fopen(zFile, "wb");
1706 if( out==0 ) return;
1707 z = (const char*)sqlite3_value_blob(argv[1]);
1708 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001709 rc = 0;
1710 }else{
drh490fe862014-08-11 14:21:32 +00001711 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001712 }
1713 fclose(out);
1714 sqlite3_result_int64(context, rc);
1715}
drhdaffd0e2001-04-11 14:28:42 +00001716
drh75897232000-05-29 14:26:00 +00001717/*
drh44c2eb12003-04-30 11:38:26 +00001718** Make sure the database is open. If it is not, then open it. If
1719** the database fails to open, print an error message and exit.
1720*/
drhdcd87a92014-08-18 13:45:42 +00001721static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001722 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001723 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001724 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001725 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001726 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1727 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1728 shellstaticFunc, 0, 0);
1729 }
1730 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001731 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001732 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001733 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001734 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001735 }
drhc2e87a32006-06-27 15:16:14 +00001736#ifndef SQLITE_OMIT_LOAD_EXTENSION
1737 sqlite3_enable_load_extension(p->db, 1);
1738#endif
drhba5b0932014-07-24 12:39:59 +00001739 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1740 readfileFunc, 0, 0);
1741 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1742 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001743 }
1744}
1745
1746/*
drhfeac5f82004-08-01 00:10:45 +00001747** Do C-language style dequoting.
1748**
1749** \t -> tab
1750** \n -> newline
1751** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001752** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001753** \NNN -> ascii character NNN in octal
1754** \\ -> backslash
1755*/
1756static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001757 int i, j;
1758 char c;
drhc2ce0be2014-05-29 12:36:14 +00001759 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001760 for(i=j=0; (c = z[i])!=0; i++, j++){
1761 if( c=='\\' ){
1762 c = z[++i];
1763 if( c=='n' ){
1764 c = '\n';
1765 }else if( c=='t' ){
1766 c = '\t';
1767 }else if( c=='r' ){
1768 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001769 }else if( c=='\\' ){
1770 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001771 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001772 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001773 if( z[i+1]>='0' && z[i+1]<='7' ){
1774 i++;
1775 c = (c<<3) + z[i] - '0';
1776 if( z[i+1]>='0' && z[i+1]<='7' ){
1777 i++;
1778 c = (c<<3) + z[i] - '0';
1779 }
1780 }
1781 }
1782 }
1783 z[j] = c;
1784 }
drhc2ce0be2014-05-29 12:36:14 +00001785 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001786}
1787
1788/*
drh348d19c2013-06-03 12:47:43 +00001789** Return the value of a hexadecimal digit. Return -1 if the input
1790** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001791*/
drh348d19c2013-06-03 12:47:43 +00001792static int hexDigitValue(char c){
1793 if( c>='0' && c<='9' ) return c - '0';
1794 if( c>='a' && c<='f' ) return c - 'a' + 10;
1795 if( c>='A' && c<='F' ) return c - 'A' + 10;
1796 return -1;
drhc28490c2006-10-26 14:25:58 +00001797}
1798
1799/*
drh7d9f3942013-04-03 01:26:54 +00001800** Interpret zArg as an integer value, possibly with suffixes.
1801*/
1802static sqlite3_int64 integerValue(const char *zArg){
1803 sqlite3_int64 v = 0;
1804 static const struct { char *zSuffix; int iMult; } aMult[] = {
1805 { "KiB", 1024 },
1806 { "MiB", 1024*1024 },
1807 { "GiB", 1024*1024*1024 },
1808 { "KB", 1000 },
1809 { "MB", 1000000 },
1810 { "GB", 1000000000 },
1811 { "K", 1000 },
1812 { "M", 1000000 },
1813 { "G", 1000000000 },
1814 };
1815 int i;
1816 int isNeg = 0;
1817 if( zArg[0]=='-' ){
1818 isNeg = 1;
1819 zArg++;
1820 }else if( zArg[0]=='+' ){
1821 zArg++;
1822 }
drh348d19c2013-06-03 12:47:43 +00001823 if( zArg[0]=='0' && zArg[1]=='x' ){
1824 int x;
1825 zArg += 2;
1826 while( (x = hexDigitValue(zArg[0]))>=0 ){
1827 v = (v<<4) + x;
1828 zArg++;
1829 }
1830 }else{
1831 while( IsDigit(zArg[0]) ){
1832 v = v*10 + zArg[0] - '0';
1833 zArg++;
1834 }
drh7d9f3942013-04-03 01:26:54 +00001835 }
drhc2bed0a2013-05-24 11:57:50 +00001836 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001837 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1838 v *= aMult[i].iMult;
1839 break;
1840 }
1841 }
1842 return isNeg? -v : v;
1843}
1844
1845/*
drh348d19c2013-06-03 12:47:43 +00001846** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1847** for TRUE and FALSE. Return the integer value if appropriate.
1848*/
1849static int booleanValue(char *zArg){
1850 int i;
1851 if( zArg[0]=='0' && zArg[1]=='x' ){
1852 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1853 }else{
1854 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1855 }
1856 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1857 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1858 return 1;
1859 }
1860 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1861 return 0;
1862 }
1863 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1864 zArg);
1865 return 0;
1866}
1867
1868/*
drh42f64e52012-04-04 16:56:23 +00001869** Close an output file, assuming it is not stderr or stdout
1870*/
1871static void output_file_close(FILE *f){
1872 if( f && f!=stdout && f!=stderr ) fclose(f);
1873}
1874
1875/*
1876** Try to open an output file. The names "stdout" and "stderr" are
1877** recognized and do the right thing. NULL is returned if the output
1878** filename is "off".
1879*/
1880static FILE *output_file_open(const char *zFile){
1881 FILE *f;
1882 if( strcmp(zFile,"stdout")==0 ){
1883 f = stdout;
1884 }else if( strcmp(zFile, "stderr")==0 ){
1885 f = stderr;
1886 }else if( strcmp(zFile, "off")==0 ){
1887 f = 0;
1888 }else{
1889 f = fopen(zFile, "wb");
1890 if( f==0 ){
1891 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1892 }
1893 }
1894 return f;
1895}
1896
1897/*
1898** A routine for handling output from sqlite3_trace().
1899*/
1900static void sql_trace_callback(void *pArg, const char *z){
1901 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00001902 if( f ){
1903 int i = (int)strlen(z);
1904 while( i>0 && z[i-1]==';' ){ i--; }
1905 fprintf(f, "%.*s;\n", i, z);
1906 }
drh42f64e52012-04-04 16:56:23 +00001907}
1908
1909/*
drhd8621b92012-04-17 09:09:33 +00001910** A no-op routine that runs with the ".breakpoint" doc-command. This is
1911** a useful spot to set a debugger breakpoint.
1912*/
1913static void test_breakpoint(void){
1914 static int nCall = 0;
1915 nCall++;
1916}
1917
1918/*
drhdb95f682013-06-26 22:46:00 +00001919** An object used to read a CSV file
1920*/
1921typedef struct CSVReader CSVReader;
1922struct CSVReader {
1923 const char *zFile; /* Name of the input file */
1924 FILE *in; /* Read the CSV text from this input stream */
1925 char *z; /* Accumulated text for a field */
1926 int n; /* Number of bytes in z */
1927 int nAlloc; /* Space allocated for z[] */
1928 int nLine; /* Current line number */
1929 int cTerm; /* Character that terminated the most recent field */
1930 int cSeparator; /* The separator character. (Usually ",") */
1931};
1932
1933/* Append a single byte to z[] */
1934static void csv_append_char(CSVReader *p, int c){
1935 if( p->n+1>=p->nAlloc ){
1936 p->nAlloc += p->nAlloc + 100;
1937 p->z = sqlite3_realloc(p->z, p->nAlloc);
1938 if( p->z==0 ){
1939 fprintf(stderr, "out of memory\n");
1940 exit(1);
1941 }
1942 }
1943 p->z[p->n++] = (char)c;
1944}
1945
1946/* Read a single field of CSV text. Compatible with rfc4180 and extended
1947** with the option of having a separator other than ",".
1948**
1949** + Input comes from p->in.
1950** + Store results in p->z of length p->n. Space to hold p->z comes
1951** from sqlite3_malloc().
1952** + Use p->cSep as the separator. The default is ",".
1953** + Keep track of the line number in p->nLine.
1954** + Store the character that terminates the field in p->cTerm. Store
1955** EOF on end-of-file.
1956** + Report syntax errors on stderr
1957*/
1958static char *csv_read_one_field(CSVReader *p){
drha81ad172013-12-11 14:00:04 +00001959 int c, pc, ppc;
drhdb95f682013-06-26 22:46:00 +00001960 int cSep = p->cSeparator;
1961 p->n = 0;
1962 c = fgetc(p->in);
1963 if( c==EOF || seenInterrupt ){
1964 p->cTerm = EOF;
1965 return 0;
1966 }
1967 if( c=='"' ){
1968 int startLine = p->nLine;
1969 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00001970 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00001971 while( 1 ){
1972 c = fgetc(p->in);
1973 if( c=='\n' ) p->nLine++;
1974 if( c==cQuote ){
1975 if( pc==cQuote ){
1976 pc = 0;
1977 continue;
1978 }
1979 }
1980 if( (c==cSep && pc==cQuote)
1981 || (c=='\n' && pc==cQuote)
drha81ad172013-12-11 14:00:04 +00001982 || (c=='\n' && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00001983 || (c==EOF && pc==cQuote)
1984 ){
1985 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00001986 p->cTerm = c;
1987 break;
1988 }
1989 if( pc==cQuote && c!='\r' ){
1990 fprintf(stderr, "%s:%d: unescaped %c character\n",
1991 p->zFile, p->nLine, cQuote);
1992 }
1993 if( c==EOF ){
1994 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
1995 p->zFile, startLine, cQuote);
drhdb95f682013-06-26 22:46:00 +00001996 p->cTerm = EOF;
1997 break;
1998 }
1999 csv_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002000 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002001 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002002 }
drhdb95f682013-06-26 22:46:00 +00002003 }else{
drhd0a64dc2013-06-30 20:24:26 +00002004 while( c!=EOF && c!=cSep && c!='\n' ){
drhdb95f682013-06-26 22:46:00 +00002005 csv_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002006 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002007 }
2008 if( c=='\n' ){
2009 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002010 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002011 }
drhdb95f682013-06-26 22:46:00 +00002012 p->cTerm = c;
2013 }
drh8dd675e2013-07-12 21:09:24 +00002014 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002015 return p->z;
2016}
2017
2018/*
drh4bbcf102014-02-06 02:46:08 +00002019** Try to transfer data for table zTable. If an error is seen while
2020** moving forward, try to go backwards. The backwards movement won't
2021** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002022*/
mistachkine31ae902014-02-06 01:15:29 +00002023static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002024 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002025 sqlite3 *newDb,
2026 const char *zTable
2027){
2028 sqlite3_stmt *pQuery = 0;
2029 sqlite3_stmt *pInsert = 0;
2030 char *zQuery = 0;
2031 char *zInsert = 0;
2032 int rc;
2033 int i, j, n;
2034 int nTable = (int)strlen(zTable);
2035 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002036 int cnt = 0;
2037 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002038
2039 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2040 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2041 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002042 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002043 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2044 zQuery);
2045 goto end_data_xfer;
2046 }
2047 n = sqlite3_column_count(pQuery);
2048 zInsert = sqlite3_malloc(200 + nTable + n*3);
2049 if( zInsert==0 ){
2050 fprintf(stderr, "out of memory\n");
2051 goto end_data_xfer;
2052 }
2053 sqlite3_snprintf(200+nTable,zInsert,
2054 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2055 i = (int)strlen(zInsert);
2056 for(j=1; j<n; j++){
2057 memcpy(zInsert+i, ",?", 2);
2058 i += 2;
2059 }
2060 memcpy(zInsert+i, ");", 3);
2061 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2062 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002063 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002064 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2065 zQuery);
2066 goto end_data_xfer;
2067 }
2068 for(k=0; k<2; k++){
2069 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2070 for(i=0; i<n; i++){
2071 switch( sqlite3_column_type(pQuery, i) ){
2072 case SQLITE_NULL: {
2073 sqlite3_bind_null(pInsert, i+1);
2074 break;
2075 }
2076 case SQLITE_INTEGER: {
2077 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2078 break;
2079 }
2080 case SQLITE_FLOAT: {
2081 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2082 break;
2083 }
2084 case SQLITE_TEXT: {
2085 sqlite3_bind_text(pInsert, i+1,
2086 (const char*)sqlite3_column_text(pQuery,i),
2087 -1, SQLITE_STATIC);
2088 break;
2089 }
2090 case SQLITE_BLOB: {
2091 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2092 sqlite3_column_bytes(pQuery,i),
2093 SQLITE_STATIC);
2094 break;
2095 }
2096 }
2097 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002098 rc = sqlite3_step(pInsert);
2099 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2100 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2101 sqlite3_errmsg(newDb));
2102 }
drh3350ce92014-02-06 00:49:12 +00002103 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002104 cnt++;
2105 if( (cnt%spinRate)==0 ){
2106 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2107 fflush(stdout);
2108 }
drh3350ce92014-02-06 00:49:12 +00002109 } /* End while */
2110 if( rc==SQLITE_DONE ) break;
2111 sqlite3_finalize(pQuery);
2112 sqlite3_free(zQuery);
2113 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2114 zTable);
2115 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2116 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002117 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2118 break;
drh3350ce92014-02-06 00:49:12 +00002119 }
2120 } /* End for(k=0...) */
2121
2122end_data_xfer:
2123 sqlite3_finalize(pQuery);
2124 sqlite3_finalize(pInsert);
2125 sqlite3_free(zQuery);
2126 sqlite3_free(zInsert);
2127}
2128
2129
2130/*
2131** Try to transfer all rows of the schema that match zWhere. For
2132** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002133** If an error is encountered while moving forward through the
2134** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002135*/
mistachkine31ae902014-02-06 01:15:29 +00002136static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002137 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002138 sqlite3 *newDb,
2139 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002140 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002141){
2142 sqlite3_stmt *pQuery = 0;
2143 char *zQuery = 0;
2144 int rc;
2145 const unsigned char *zName;
2146 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002147 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002148
2149 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2150 " WHERE %s", zWhere);
2151 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2152 if( rc ){
2153 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2154 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2155 zQuery);
2156 goto end_schema_xfer;
2157 }
2158 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2159 zName = sqlite3_column_text(pQuery, 0);
2160 zSql = sqlite3_column_text(pQuery, 1);
2161 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002162 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2163 if( zErrMsg ){
2164 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2165 sqlite3_free(zErrMsg);
2166 zErrMsg = 0;
2167 }
drh3350ce92014-02-06 00:49:12 +00002168 if( xForEach ){
2169 xForEach(p, newDb, (const char*)zName);
2170 }
2171 printf("done\n");
2172 }
2173 if( rc!=SQLITE_DONE ){
2174 sqlite3_finalize(pQuery);
2175 sqlite3_free(zQuery);
2176 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2177 " WHERE %s ORDER BY rowid DESC", zWhere);
2178 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2179 if( rc ){
2180 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2181 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2182 zQuery);
2183 goto end_schema_xfer;
2184 }
2185 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2186 zName = sqlite3_column_text(pQuery, 0);
2187 zSql = sqlite3_column_text(pQuery, 1);
2188 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002189 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2190 if( zErrMsg ){
2191 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2192 sqlite3_free(zErrMsg);
2193 zErrMsg = 0;
2194 }
drh3350ce92014-02-06 00:49:12 +00002195 if( xForEach ){
2196 xForEach(p, newDb, (const char*)zName);
2197 }
2198 printf("done\n");
2199 }
2200 }
2201end_schema_xfer:
2202 sqlite3_finalize(pQuery);
2203 sqlite3_free(zQuery);
2204}
2205
2206/*
2207** Open a new database file named "zNewDb". Try to recover as much information
2208** as possible out of the main database (which might be corrupt) and write it
2209** into zNewDb.
2210*/
drhdcd87a92014-08-18 13:45:42 +00002211static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002212 int rc;
2213 sqlite3 *newDb = 0;
2214 if( access(zNewDb,0)==0 ){
2215 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2216 return;
2217 }
2218 rc = sqlite3_open(zNewDb, &newDb);
2219 if( rc ){
2220 fprintf(stderr, "Cannot create output database: %s\n",
2221 sqlite3_errmsg(newDb));
2222 }else{
drh54d0d2d2014-04-03 00:32:13 +00002223 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002224 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002225 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2226 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002227 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002228 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002229 }
2230 sqlite3_close(newDb);
2231}
2232
2233/*
drhc2ce0be2014-05-29 12:36:14 +00002234** Change the output file back to stdout
2235*/
drhdcd87a92014-08-18 13:45:42 +00002236static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002237 if( p->outfile[0]=='|' ){
2238 pclose(p->out);
2239 }else{
2240 output_file_close(p->out);
2241 }
2242 p->outfile[0] = 0;
2243 p->out = stdout;
2244}
2245
2246/*
drh75897232000-05-29 14:26:00 +00002247** If an input line begins with "." then invoke this routine to
2248** process that line.
drh67505e72002-04-19 12:34:06 +00002249**
drh47ad6842006-11-08 12:25:42 +00002250** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002251*/
drhdcd87a92014-08-18 13:45:42 +00002252static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002253 int i = 1;
2254 int nArg = 0;
2255 int n, c;
drh67505e72002-04-19 12:34:06 +00002256 int rc = 0;
drh75897232000-05-29 14:26:00 +00002257 char *azArg[50];
2258
2259 /* Parse the input line into tokens.
2260 */
2261 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002262 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002263 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002264 if( zLine[i]=='\'' || zLine[i]=='"' ){
2265 int delim = zLine[i++];
2266 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002267 while( zLine[i] && zLine[i]!=delim ){
2268 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2269 i++;
2270 }
drh75897232000-05-29 14:26:00 +00002271 if( zLine[i]==delim ){
2272 zLine[i++] = 0;
2273 }
drhfeac5f82004-08-01 00:10:45 +00002274 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002275 }else{
2276 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002277 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002278 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002279 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002280 }
2281 }
2282
2283 /* Process the input line.
2284 */
shane9bd1b442009-10-23 01:27:39 +00002285 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002286 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002287 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002288 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2289 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2290 ){
drhbc46f022013-01-23 18:53:23 +00002291 const char *zDestFile = 0;
2292 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002293 sqlite3 *pDest;
2294 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002295 int j;
2296 for(j=1; j<nArg; j++){
2297 const char *z = azArg[j];
2298 if( z[0]=='-' ){
2299 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002300 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002301 {
2302 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2303 return 1;
2304 }
2305 }else if( zDestFile==0 ){
2306 zDestFile = azArg[j];
2307 }else if( zDb==0 ){
2308 zDb = zDestFile;
2309 zDestFile = azArg[j];
2310 }else{
2311 fprintf(stderr, "too many arguments to .backup\n");
2312 return 1;
2313 }
drh9ff849f2009-02-04 20:55:57 +00002314 }
drhbc46f022013-01-23 18:53:23 +00002315 if( zDestFile==0 ){
2316 fprintf(stderr, "missing FILENAME argument on .backup\n");
2317 return 1;
2318 }
2319 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002320 rc = sqlite3_open(zDestFile, &pDest);
2321 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002322 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002323 sqlite3_close(pDest);
2324 return 1;
2325 }
drh05782482013-10-24 15:20:20 +00002326 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002327 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2328 if( pBackup==0 ){
2329 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2330 sqlite3_close(pDest);
2331 return 1;
2332 }
2333 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2334 sqlite3_backup_finish(pBackup);
2335 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002336 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002337 }else{
2338 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002339 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002340 }
2341 sqlite3_close(pDest);
2342 }else
2343
drhc2ce0be2014-05-29 12:36:14 +00002344 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2345 if( nArg==2 ){
2346 bail_on_error = booleanValue(azArg[1]);
2347 }else{
2348 fprintf(stderr, "Usage: .bail on|off\n");
2349 rc = 1;
2350 }
drhc49f44e2006-10-26 18:15:42 +00002351 }else
2352
drhd8621b92012-04-17 09:09:33 +00002353 /* The undocumented ".breakpoint" command causes a call to the no-op
2354 ** routine named test_breakpoint().
2355 */
2356 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2357 test_breakpoint();
2358 }else
2359
drhc2ce0be2014-05-29 12:36:14 +00002360 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2361 if( nArg==2 ){
2362 tryToClone(p, azArg[1]);
2363 }else{
2364 fprintf(stderr, "Usage: .clone FILENAME\n");
2365 rc = 1;
2366 }
mistachkine31ae902014-02-06 01:15:29 +00002367 }else
2368
drhc2ce0be2014-05-29 12:36:14 +00002369 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002370 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002371 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002372 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002373 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002374 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002375 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002376 data.colWidth[0] = 3;
2377 data.colWidth[1] = 15;
2378 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002379 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002380 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002381 if( zErrMsg ){
2382 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002383 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002384 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002385 }
2386 }else
2387
drhc2ce0be2014-05-29 12:36:14 +00002388 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002389 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002390 /* When playing back a "dump", the content might appear in an order
2391 ** which causes immediate foreign key constraints to be violated.
2392 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002393 if( nArg!=1 && nArg!=2 ){
2394 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2395 rc = 1;
2396 goto meta_command_exit;
2397 }
drhf1dfc4f2009-09-23 15:51:35 +00002398 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002399 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002400 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002401 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002402 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002403 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002404 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002405 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002406 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002407 );
2408 run_schema_dump_query(p,
2409 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002410 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002411 );
drh2f464a02011-10-13 00:41:49 +00002412 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002413 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002414 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002415 );
drh4c653a02000-06-07 01:27:47 +00002416 }else{
2417 int i;
drhdd3d4592004-08-30 01:54:05 +00002418 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002419 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002420 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002421 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002422 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002423 " AND sql NOT NULL");
2424 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002425 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002426 "WHERE sql NOT NULL"
2427 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002428 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002429 );
danielk1977bc6ada42004-06-30 08:20:16 +00002430 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002431 }
2432 }
drh45e29d82006-11-20 16:21:10 +00002433 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002434 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002435 p->writableSchema = 0;
2436 }
drh56197952011-10-13 16:30:13 +00002437 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2438 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002439 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002440 }else
drh75897232000-05-29 14:26:00 +00002441
drhc2ce0be2014-05-29 12:36:14 +00002442 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2443 if( nArg==2 ){
2444 p->echoOn = booleanValue(azArg[1]);
2445 }else{
2446 fprintf(stderr, "Usage: .echo on|off\n");
2447 rc = 1;
2448 }
drhdaffd0e2001-04-11 14:28:42 +00002449 }else
2450
drhc2ce0be2014-05-29 12:36:14 +00002451 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2452 if( nArg==2 ){
2453 p->autoEQP = booleanValue(azArg[1]);
2454 }else{
2455 fprintf(stderr, "Usage: .eqp on|off\n");
2456 rc = 1;
2457 }
drhefbf3b12014-02-28 20:47:24 +00002458 }else
2459
drhd3ac7d92013-01-25 18:33:43 +00002460 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002461 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002462 rc = 2;
drh75897232000-05-29 14:26:00 +00002463 }else
2464
drhc2ce0be2014-05-29 12:36:14 +00002465 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002466 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002467 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002468 if(!p->normalMode.valid) {
2469 p->normalMode.valid = 1;
2470 p->normalMode.mode = p->mode;
2471 p->normalMode.showHeader = p->showHeader;
2472 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002473 }
2474 /* We could put this code under the !p->explainValid
2475 ** condition so that it does not execute if we are already in
2476 ** explain mode. However, always executing it allows us an easy
2477 ** was to reset to explain mode in case the user previously
2478 ** did an .explain followed by a .width, .mode or .header
2479 ** command.
2480 */
danielk19770d78bae2008-01-03 07:09:48 +00002481 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002482 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002483 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002484 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002485 p->colWidth[1] = 13; /* opcode */
2486 p->colWidth[2] = 4; /* P1 */
2487 p->colWidth[3] = 4; /* P2 */
2488 p->colWidth[4] = 4; /* P3 */
2489 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002490 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002491 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002492 }else if (p->normalMode.valid) {
2493 p->normalMode.valid = 0;
2494 p->mode = p->normalMode.mode;
2495 p->showHeader = p->normalMode.showHeader;
2496 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002497 }
drh75897232000-05-29 14:26:00 +00002498 }else
2499
drhc1971542014-06-23 23:28:13 +00002500 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002501 ShellState data;
drhc1971542014-06-23 23:28:13 +00002502 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002503 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002504 if( nArg!=1 ){
2505 fprintf(stderr, "Usage: .fullschema\n");
2506 rc = 1;
2507 goto meta_command_exit;
2508 }
2509 open_db(p, 0);
2510 memcpy(&data, p, sizeof(data));
2511 data.showHeader = 0;
2512 data.mode = MODE_Semi;
2513 rc = sqlite3_exec(p->db,
2514 "SELECT sql FROM"
2515 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2516 " FROM sqlite_master UNION ALL"
2517 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002518 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002519 "ORDER BY rowid",
2520 callback, &data, &zErrMsg
2521 );
drh56f674c2014-07-18 14:43:29 +00002522 if( rc==SQLITE_OK ){
2523 sqlite3_stmt *pStmt;
2524 rc = sqlite3_prepare_v2(p->db,
2525 "SELECT rowid FROM sqlite_master"
2526 " WHERE name GLOB 'sqlite_stat[134]'",
2527 -1, &pStmt, 0);
2528 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2529 sqlite3_finalize(pStmt);
2530 }
2531 if( doStats==0 ){
2532 fprintf(p->out, "/* No STAT tables available */\n");
2533 }else{
2534 fprintf(p->out, "ANALYZE sqlite_master;\n");
2535 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2536 callback, &data, &zErrMsg);
2537 data.mode = MODE_Insert;
2538 data.zDestTable = "sqlite_stat1";
2539 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2540 shell_callback, &data,&zErrMsg);
2541 data.zDestTable = "sqlite_stat3";
2542 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2543 shell_callback, &data,&zErrMsg);
2544 data.zDestTable = "sqlite_stat4";
2545 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2546 shell_callback, &data, &zErrMsg);
2547 fprintf(p->out, "ANALYZE sqlite_master;\n");
2548 }
drhc1971542014-06-23 23:28:13 +00002549 }else
2550
drhc2ce0be2014-05-29 12:36:14 +00002551 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2552 if( nArg==2 ){
2553 p->showHeader = booleanValue(azArg[1]);
2554 }else{
2555 fprintf(stderr, "Usage: .headers on|off\n");
2556 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002557 }
drh75897232000-05-29 14:26:00 +00002558 }else
2559
drhc2ce0be2014-05-29 12:36:14 +00002560 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2561 fprintf(p->out, "%s", zHelp);
2562 }else
2563
2564 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002565 char *zTable; /* Insert data into this table */
2566 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002567 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002568 int nCol; /* Number of columns in the table */
2569 int nByte; /* Number of bytes in an SQL string */
2570 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002571 int needCommit; /* True to COMMIT or ROLLBACK at end */
drhfeac5f82004-08-01 00:10:45 +00002572 int nSep; /* Number of bytes in p->separator[] */
2573 char *zSql; /* An SQL statement */
drhdb95f682013-06-26 22:46:00 +00002574 CSVReader sCsv; /* Reader context */
drh5bde8162013-06-27 14:07:53 +00002575 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002576
drhc2ce0be2014-05-29 12:36:14 +00002577 if( nArg!=3 ){
2578 fprintf(stderr, "Usage: .import FILE TABLE\n");
2579 goto meta_command_exit;
2580 }
drh01f37542014-05-31 15:43:33 +00002581 zFile = azArg[1];
2582 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002583 seenInterrupt = 0;
2584 memset(&sCsv, 0, sizeof(sCsv));
drh05782482013-10-24 15:20:20 +00002585 open_db(p, 0);
drh4f21c4a2008-12-10 22:15:00 +00002586 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002587 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00002588 fprintf(stderr, "Error: non-null separator required for import\n");
2589 return 1;
drhfeac5f82004-08-01 00:10:45 +00002590 }
drhdb95f682013-06-26 22:46:00 +00002591 if( nSep>1 ){
2592 fprintf(stderr, "Error: multi-character separators not allowed"
2593 " for import\n");
2594 return 1;
2595 }
drh5bde8162013-06-27 14:07:53 +00002596 sCsv.zFile = zFile;
2597 sCsv.nLine = 1;
2598 if( sCsv.zFile[0]=='|' ){
2599 sCsv.in = popen(sCsv.zFile+1, "r");
2600 sCsv.zFile = "<pipe>";
2601 xCloser = pclose;
2602 }else{
2603 sCsv.in = fopen(sCsv.zFile, "rb");
2604 xCloser = fclose;
2605 }
drhdb95f682013-06-26 22:46:00 +00002606 if( sCsv.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002607 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002608 return 1;
2609 }
2610 sCsv.cSeparator = p->separator[0];
drh7b075e32011-09-28 01:10:00 +00002611 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002612 if( zSql==0 ){
2613 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002614 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002615 return 1;
2616 }
drh4f21c4a2008-12-10 22:15:00 +00002617 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002618 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
dan6a8ac852014-05-26 18:27:12 +00002619 csv_append_char(&sCsv, 0); /* To ensure sCsv.z is allocated */
drhdb95f682013-06-26 22:46:00 +00002620 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2621 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2622 char cSep = '(';
2623 while( csv_read_one_field(&sCsv) ){
2624 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
2625 cSep = ',';
2626 if( sCsv.cTerm!=sCsv.cSeparator ) break;
2627 }
drh5bde8162013-06-27 14:07:53 +00002628 if( cSep=='(' ){
2629 sqlite3_free(zCreate);
2630 sqlite3_free(sCsv.z);
2631 xCloser(sCsv.in);
2632 fprintf(stderr,"%s: empty file\n", sCsv.zFile);
2633 return 1;
2634 }
drhdb95f682013-06-26 22:46:00 +00002635 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2636 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2637 sqlite3_free(zCreate);
2638 if( rc ){
2639 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2640 sqlite3_errmsg(db));
2641 sqlite3_free(sCsv.z);
drh5bde8162013-06-27 14:07:53 +00002642 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002643 return 1;
2644 }
drhc7181902014-02-27 15:04:13 +00002645 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002646 }
drhfeac5f82004-08-01 00:10:45 +00002647 sqlite3_free(zSql);
2648 if( rc ){
shane916f9612009-10-23 00:37:15 +00002649 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002650 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
drh5bde8162013-06-27 14:07:53 +00002651 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002652 return 1;
drhfeac5f82004-08-01 00:10:45 +00002653 }
shane916f9612009-10-23 00:37:15 +00002654 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002655 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002656 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002657 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002658 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002659 if( zSql==0 ){
2660 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002661 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002662 return 1;
2663 }
drhdb95f682013-06-26 22:46:00 +00002664 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002665 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002666 for(i=1; i<nCol; i++){
2667 zSql[j++] = ',';
2668 zSql[j++] = '?';
2669 }
2670 zSql[j++] = ')';
2671 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00002672 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002673 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002674 if( rc ){
2675 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002676 if (pStmt) sqlite3_finalize(pStmt);
drh5bde8162013-06-27 14:07:53 +00002677 xCloser(sCsv.in);
drh47ad6842006-11-08 12:25:42 +00002678 return 1;
drhfeac5f82004-08-01 00:10:45 +00002679 }
drh2d463112013-08-06 14:36:36 +00002680 needCommit = sqlite3_get_autocommit(db);
2681 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00002682 do{
2683 int startLine = sCsv.nLine;
drhfeac5f82004-08-01 00:10:45 +00002684 for(i=0; i<nCol; i++){
drhdb95f682013-06-26 22:46:00 +00002685 char *z = csv_read_one_field(&sCsv);
2686 if( z==0 && i==0 ) break;
2687 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
2688 if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
2689 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2690 "filling the rest with NULL\n",
2691 sCsv.zFile, startLine, nCol, i+1);
2692 i++;
mistachkin6fe03382014-06-16 22:45:28 +00002693 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002694 }
drhfeac5f82004-08-01 00:10:45 +00002695 }
drhdb95f682013-06-26 22:46:00 +00002696 if( sCsv.cTerm==sCsv.cSeparator ){
2697 do{
2698 csv_read_one_field(&sCsv);
2699 i++;
2700 }while( sCsv.cTerm==sCsv.cSeparator );
2701 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2702 "extras ignored\n",
2703 sCsv.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002704 }
drhdb95f682013-06-26 22:46:00 +00002705 if( i>=nCol ){
2706 sqlite3_step(pStmt);
2707 rc = sqlite3_reset(pStmt);
2708 if( rc!=SQLITE_OK ){
2709 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
2710 sqlite3_errmsg(db));
2711 }
2712 }
2713 }while( sCsv.cTerm!=EOF );
2714
drh5bde8162013-06-27 14:07:53 +00002715 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002716 sqlite3_free(sCsv.z);
drhfeac5f82004-08-01 00:10:45 +00002717 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00002718 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002719 }else
2720
drhc2ce0be2014-05-29 12:36:14 +00002721 if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002722 ShellState data;
drh75897232000-05-29 14:26:00 +00002723 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002724 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00002725 memcpy(&data, p, sizeof(data));
2726 data.showHeader = 0;
2727 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002728 if( nArg==1 ){
2729 rc = sqlite3_exec(p->db,
2730 "SELECT name FROM sqlite_master "
2731 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2732 "UNION ALL "
2733 "SELECT name FROM sqlite_temp_master "
2734 "WHERE type='index' "
2735 "ORDER BY 1",
2736 callback, &data, &zErrMsg
2737 );
drhc2ce0be2014-05-29 12:36:14 +00002738 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00002739 zShellStatic = azArg[1];
2740 rc = sqlite3_exec(p->db,
2741 "SELECT name FROM sqlite_master "
2742 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2743 "UNION ALL "
2744 "SELECT name FROM sqlite_temp_master "
2745 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2746 "ORDER BY 1",
2747 callback, &data, &zErrMsg
2748 );
2749 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00002750 }else{
2751 fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
2752 rc = 1;
2753 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00002754 }
drh75897232000-05-29 14:26:00 +00002755 if( zErrMsg ){
2756 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002757 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002758 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002759 }else if( rc != SQLITE_OK ){
2760 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2761 rc = 1;
drh75897232000-05-29 14:26:00 +00002762 }
2763 }else
2764
drhae5e4452007-05-03 17:18:36 +00002765#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002766 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002767 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002768 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2769 iotrace = 0;
2770 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002771 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002772 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002773 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002774 iotrace = stdout;
2775 }else{
2776 iotrace = fopen(azArg[1], "w");
2777 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002778 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002779 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002780 rc = 1;
drhb0603412007-02-28 04:47:26 +00002781 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002782 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002783 }
2784 }
2785 }else
drhae5e4452007-05-03 17:18:36 +00002786#endif
drhb0603412007-02-28 04:47:26 +00002787
drh70df4fe2006-06-13 15:12:21 +00002788#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00002789 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00002790 const char *zFile, *zProc;
2791 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00002792 if( nArg<2 ){
2793 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
2794 rc = 1;
2795 goto meta_command_exit;
2796 }
drh1e397f82006-06-08 15:28:43 +00002797 zFile = azArg[1];
2798 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00002799 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00002800 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2801 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002802 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002803 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002804 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002805 }
2806 }else
drh70df4fe2006-06-13 15:12:21 +00002807#endif
drh1e397f82006-06-08 15:28:43 +00002808
drhc2ce0be2014-05-29 12:36:14 +00002809 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
2810 if( nArg!=2 ){
2811 fprintf(stderr, "Usage: .log FILENAME\n");
2812 rc = 1;
2813 }else{
2814 const char *zFile = azArg[1];
2815 output_file_close(p->pLog);
2816 p->pLog = output_file_open(zFile);
2817 }
drh127f9d72010-02-23 01:47:00 +00002818 }else
2819
drhc2ce0be2014-05-29 12:36:14 +00002820 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
2821 const char *zMode = nArg>=2 ? azArg[1] : "";
2822 int n2 = (int)strlen(zMode);
2823 int c2 = zMode[0];
2824 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002825 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00002826 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002827 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00002828 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002829 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00002830 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002831 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00002832 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002833 p->mode = MODE_Tcl;
mistachkin585dcb22012-12-04 00:23:43 +00002834 sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
drhc2ce0be2014-05-29 12:36:14 +00002835 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002836 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002837 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drh6976c212014-07-24 12:09:47 +00002838 sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n");
drhc2ce0be2014-05-29 12:36:14 +00002839 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002840 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002841 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drhc2ce0be2014-05-29 12:36:14 +00002842 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002843 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00002844 set_table_name(p, nArg>=3 ? azArg[2] : "table");
drhdaffd0e2001-04-11 14:28:42 +00002845 }else {
shane9bd1b442009-10-23 01:27:39 +00002846 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002847 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002848 rc = 1;
drh75897232000-05-29 14:26:00 +00002849 }
2850 }else
2851
drhc2ce0be2014-05-29 12:36:14 +00002852 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
2853 if( nArg==2 ){
2854 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2855 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
2856 }else{
2857 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00002858 rc = 1;
2859 }
2860 }else
2861
drh05782482013-10-24 15:20:20 +00002862 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
2863 sqlite3 *savedDb = p->db;
2864 const char *zSavedFilename = p->zDbFilename;
2865 char *zNewFilename = 0;
2866 p->db = 0;
2867 if( nArg>=2 ){
2868 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
2869 }
2870 open_db(p, 1);
2871 if( p->db!=0 ){
2872 sqlite3_close(savedDb);
2873 sqlite3_free(p->zFreeOnClose);
2874 p->zFreeOnClose = zNewFilename;
2875 }else{
2876 sqlite3_free(zNewFilename);
2877 p->db = savedDb;
2878 p->zDbFilename = zSavedFilename;
2879 }
2880 }else
2881
drhc2ce0be2014-05-29 12:36:14 +00002882 if( c=='o'
2883 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
2884 ){
2885 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
2886 if( nArg>2 ){
2887 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
2888 rc = 1;
2889 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00002890 }
drhc2ce0be2014-05-29 12:36:14 +00002891 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
2892 if( nArg<2 ){
2893 fprintf(stderr, "Usage: .once FILE\n");
2894 rc = 1;
2895 goto meta_command_exit;
2896 }
2897 p->outCount = 2;
2898 }else{
2899 p->outCount = 0;
2900 }
2901 output_reset(p);
2902 if( zFile[0]=='|' ){
2903 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00002904 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00002905 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00002906 p->out = stdout;
2907 rc = 1;
2908 }else{
drhc2ce0be2014-05-29 12:36:14 +00002909 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00002910 }
drh75897232000-05-29 14:26:00 +00002911 }else{
drhc2ce0be2014-05-29 12:36:14 +00002912 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00002913 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00002914 if( strcmp(zFile,"off")!=0 ){
2915 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002916 }
drh75897232000-05-29 14:26:00 +00002917 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002918 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002919 } else {
drhc2ce0be2014-05-29 12:36:14 +00002920 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00002921 }
2922 }
2923 }else
2924
drh078b1fd2012-09-21 13:40:02 +00002925 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2926 int i;
2927 for(i=1; i<nArg; i++){
2928 if( i>1 ) fprintf(p->out, " ");
2929 fprintf(p->out, "%s", azArg[i]);
2930 }
2931 fprintf(p->out, "\n");
2932 }else
2933
drhc2ce0be2014-05-29 12:36:14 +00002934 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002935 if( nArg >= 2) {
2936 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2937 }
2938 if( nArg >= 3) {
2939 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2940 }
2941 }else
2942
drhc2ce0be2014-05-29 12:36:14 +00002943 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00002944 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002945 }else
2946
drhc2ce0be2014-05-29 12:36:14 +00002947 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
2948 FILE *alt;
2949 if( nArg!=2 ){
2950 fprintf(stderr, "Usage: .read FILE\n");
2951 rc = 1;
2952 goto meta_command_exit;
2953 }
2954 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002955 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002956 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2957 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002958 }else{
shane9bd1b442009-10-23 01:27:39 +00002959 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002960 fclose(alt);
2961 }
2962 }else
2963
drhc2ce0be2014-05-29 12:36:14 +00002964 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00002965 const char *zSrcFile;
2966 const char *zDb;
2967 sqlite3 *pSrc;
2968 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002969 int nTimeout = 0;
2970
drh9ff849f2009-02-04 20:55:57 +00002971 if( nArg==2 ){
2972 zSrcFile = azArg[1];
2973 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00002974 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00002975 zSrcFile = azArg[2];
2976 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00002977 }else{
2978 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
2979 rc = 1;
2980 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00002981 }
2982 rc = sqlite3_open(zSrcFile, &pSrc);
2983 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002984 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002985 sqlite3_close(pSrc);
2986 return 1;
2987 }
drh05782482013-10-24 15:20:20 +00002988 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002989 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2990 if( pBackup==0 ){
2991 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2992 sqlite3_close(pSrc);
2993 return 1;
2994 }
drhdc2c4912009-02-04 22:46:47 +00002995 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2996 || rc==SQLITE_BUSY ){
2997 if( rc==SQLITE_BUSY ){
2998 if( nTimeout++ >= 3 ) break;
2999 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003000 }
3001 }
3002 sqlite3_backup_finish(pBackup);
3003 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003004 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003005 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003006 fprintf(stderr, "Error: source database is busy\n");
3007 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003008 }else{
3009 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003010 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003011 }
3012 sqlite3_close(pSrc);
3013 }else
3014
drhc2ce0be2014-05-29 12:36:14 +00003015 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003016 ShellState data;
drh75897232000-05-29 14:26:00 +00003017 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003018 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003019 memcpy(&data, p, sizeof(data));
3020 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003021 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003022 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003023 int i;
drhf0693c82011-10-11 20:41:54 +00003024 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003025 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003026 char *new_argv[2], *new_colv[2];
3027 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3028 " type text,\n"
3029 " name text,\n"
3030 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003031 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003032 " sql text\n"
3033 ")";
3034 new_argv[1] = 0;
3035 new_colv[0] = "sql";
3036 new_colv[1] = 0;
3037 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003038 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003039 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003040 char *new_argv[2], *new_colv[2];
3041 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3042 " type text,\n"
3043 " name text,\n"
3044 " tbl_name text,\n"
3045 " rootpage integer,\n"
3046 " sql text\n"
3047 ")";
3048 new_argv[1] = 0;
3049 new_colv[0] = "sql";
3050 new_colv[1] = 0;
3051 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003052 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003053 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003054 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003055 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003056 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003057 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003058 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003059 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003060 "WHERE lower(tbl_name) LIKE shellstatic()"
3061 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003062 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003063 callback, &data, &zErrMsg);
3064 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003065 }
drhc2ce0be2014-05-29 12:36:14 +00003066 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003067 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003068 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003069 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003070 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003071 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003072 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003073 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003074 callback, &data, &zErrMsg
3075 );
drhc2ce0be2014-05-29 12:36:14 +00003076 }else{
3077 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3078 rc = 1;
3079 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003080 }
drh75897232000-05-29 14:26:00 +00003081 if( zErrMsg ){
3082 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003083 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003084 rc = 1;
3085 }else if( rc != SQLITE_OK ){
3086 fprintf(stderr,"Error: querying schema information\n");
3087 rc = 1;
3088 }else{
3089 rc = 0;
drh75897232000-05-29 14:26:00 +00003090 }
3091 }else
3092
drh340f5822013-06-27 13:01:21 +00003093#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003094 /* Undocumented commands for internal testing. Subject to change
3095 ** without notice. */
3096 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3097 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3098 int i, v;
3099 for(i=1; i<nArg; i++){
3100 v = booleanValue(azArg[i]);
3101 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3102 }
3103 }
3104 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3105 int i; sqlite3_int64 v;
3106 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003107 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003108 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003109 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003110 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003111 }
3112 }
3113 }else
drh340f5822013-06-27 13:01:21 +00003114#endif
drh348d19c2013-06-03 12:47:43 +00003115
drhc2ce0be2014-05-29 12:36:14 +00003116 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003117 if( nArg<2 || nArg>3 ){
3118 fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n");
drhc2ce0be2014-05-29 12:36:14 +00003119 rc = 1;
3120 }
drh6976c212014-07-24 12:09:47 +00003121 if( nArg>=2 ){
3122 sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]);
3123 }
3124 if( nArg>=3 ){
3125 sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]);
3126 }
drh75897232000-05-29 14:26:00 +00003127 }else
3128
drh62cdde52014-05-28 20:22:28 +00003129 if( c=='s'
3130 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003131 ){
3132 char *zCmd;
drh54027102014-08-06 14:36:53 +00003133 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003134 if( nArg<2 ){
3135 fprintf(stderr, "Usage: .system COMMAND\n");
3136 rc = 1;
3137 goto meta_command_exit;
3138 }
drhdcb3e3d2014-05-29 03:17:29 +00003139 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003140 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003141 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3142 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003143 }
drh54027102014-08-06 14:36:53 +00003144 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003145 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003146 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003147 }else
3148
drhc2ce0be2014-05-29 12:36:14 +00003149 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003150 int i;
drhc2ce0be2014-05-29 12:36:14 +00003151 if( nArg!=1 ){
3152 fprintf(stderr, "Usage: .show\n");
3153 rc = 1;
3154 goto meta_command_exit;
3155 }
persicom7e2dfdd2002-04-18 02:46:52 +00003156 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drhefbf3b12014-02-28 20:47:24 +00003157 fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003158 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00003159 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00003160 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00003161 fprintf(p->out,"%9.9s: ", "nullvalue");
3162 output_c_string(p->out, p->nullvalue);
3163 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00003164 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003165 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00003166 fprintf(p->out,"%9.9s: ", "separator");
3167 output_c_string(p->out, p->separator);
drh6976c212014-07-24 12:09:47 +00003168 fprintf(p->out," ");
3169 output_c_string(p->out, p->newline);
drhfeac5f82004-08-01 00:10:45 +00003170 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00003171 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00003172 fprintf(p->out,"%9.9s: ","width");
3173 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003174 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003175 }
drhfeac5f82004-08-01 00:10:45 +00003176 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003177 }else
3178
drhc2ce0be2014-05-29 12:36:14 +00003179 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3180 if( nArg==2 ){
3181 p->statsOn = booleanValue(azArg[1]);
3182 }else{
3183 fprintf(stderr, "Usage: .stats on|off\n");
3184 rc = 1;
3185 }
shaneh642d8b82010-07-28 16:05:34 +00003186 }else
3187
drhc2ce0be2014-05-29 12:36:14 +00003188 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003189 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003190 char **azResult;
drh98781232012-04-23 12:38:05 +00003191 int nRow, nAlloc;
3192 char *zSql = 0;
3193 int ii;
drh05782482013-10-24 15:20:20 +00003194 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003195 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3196 if( rc ) return rc;
3197 zSql = sqlite3_mprintf(
3198 "SELECT name FROM sqlite_master"
3199 " WHERE type IN ('table','view')"
3200 " AND name NOT LIKE 'sqlite_%%'"
3201 " AND name LIKE ?1");
3202 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3203 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3204 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3205 if( strcmp(zDbName,"temp")==0 ){
3206 zSql = sqlite3_mprintf(
3207 "%z UNION ALL "
3208 "SELECT 'temp.' || name FROM sqlite_temp_master"
3209 " WHERE type IN ('table','view')"
3210 " AND name NOT LIKE 'sqlite_%%'"
3211 " AND name LIKE ?1", zSql);
3212 }else{
3213 zSql = sqlite3_mprintf(
3214 "%z UNION ALL "
3215 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3216 " WHERE type IN ('table','view')"
3217 " AND name NOT LIKE 'sqlite_%%'"
3218 " AND name LIKE ?1", zSql, zDbName, zDbName);
3219 }
drha50da102000-08-08 20:19:09 +00003220 }
drh98781232012-04-23 12:38:05 +00003221 sqlite3_finalize(pStmt);
3222 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3223 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3224 sqlite3_free(zSql);
3225 if( rc ) return rc;
3226 nRow = nAlloc = 0;
3227 azResult = 0;
3228 if( nArg>1 ){
3229 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003230 }else{
drh98781232012-04-23 12:38:05 +00003231 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3232 }
3233 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3234 if( nRow>=nAlloc ){
3235 char **azNew;
3236 int n = nAlloc*2 + 10;
3237 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3238 if( azNew==0 ){
3239 fprintf(stderr, "Error: out of memory\n");
3240 break;
3241 }
3242 nAlloc = n;
3243 azResult = azNew;
3244 }
3245 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3246 if( azResult[nRow] ) nRow++;
3247 }
3248 sqlite3_finalize(pStmt);
3249 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003250 int len, maxlen = 0;
3251 int i, j;
3252 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003253 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003254 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003255 if( len>maxlen ) maxlen = len;
3256 }
3257 nPrintCol = 80/(maxlen+2);
3258 if( nPrintCol<1 ) nPrintCol = 1;
3259 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3260 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003261 for(j=i; j<nRow; j+=nPrintRow){
3262 char *zSp = j<nPrintRow ? "" : " ";
drh151b7d52013-05-06 20:28:54 +00003263 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
drhe3710332000-09-29 13:30:53 +00003264 }
drh151b7d52013-05-06 20:28:54 +00003265 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003266 }
3267 }
drh98781232012-04-23 12:38:05 +00003268 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3269 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003270 }else
3271
shaneh96887e12011-02-10 21:08:58 +00003272 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003273 static const struct {
3274 const char *zCtrlName; /* Name of a test-control option */
3275 int ctrlCode; /* Integer code for that option */
3276 } aCtrl[] = {
3277 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3278 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3279 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3280 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3281 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3282 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3283 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3284 { "assert", SQLITE_TESTCTRL_ASSERT },
3285 { "always", SQLITE_TESTCTRL_ALWAYS },
3286 { "reserve", SQLITE_TESTCTRL_RESERVE },
3287 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3288 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003289 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003290 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhd416fe72011-03-17 16:45:50 +00003291 };
shaneh96887e12011-02-10 21:08:58 +00003292 int testctrl = -1;
3293 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003294 int i, n;
drh05782482013-10-24 15:20:20 +00003295 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003296
drhd416fe72011-03-17 16:45:50 +00003297 /* convert testctrl text option to value. allow any unique prefix
3298 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003299 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003300 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003301 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3302 if( testctrl<0 ){
3303 testctrl = aCtrl[i].ctrlCode;
3304 }else{
drhb07028f2011-10-14 21:49:18 +00003305 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003306 testctrl = -1;
3307 break;
3308 }
3309 }
3310 }
drh348d19c2013-06-03 12:47:43 +00003311 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003312 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3313 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3314 }else{
3315 switch(testctrl){
3316
3317 /* sqlite3_test_control(int, db, int) */
3318 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3319 case SQLITE_TESTCTRL_RESERVE:
3320 if( nArg==3 ){
3321 int opt = (int)strtol(azArg[2], 0, 0);
3322 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003323 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003324 } else {
drhd416fe72011-03-17 16:45:50 +00003325 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3326 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003327 }
3328 break;
3329
3330 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003331 case SQLITE_TESTCTRL_PRNG_SAVE:
3332 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003333 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003334 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003335 if( nArg==2 ){
3336 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003337 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003338 } else {
3339 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3340 }
3341 break;
3342
3343 /* sqlite3_test_control(int, uint) */
3344 case SQLITE_TESTCTRL_PENDING_BYTE:
3345 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003346 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003347 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003348 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003349 } else {
drhd416fe72011-03-17 16:45:50 +00003350 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3351 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003352 }
3353 break;
3354
3355 /* sqlite3_test_control(int, int) */
3356 case SQLITE_TESTCTRL_ASSERT:
3357 case SQLITE_TESTCTRL_ALWAYS:
3358 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003359 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003360 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003361 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003362 } else {
drhd416fe72011-03-17 16:45:50 +00003363 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3364 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003365 }
3366 break;
3367
3368 /* sqlite3_test_control(int, char *) */
3369#ifdef SQLITE_N_KEYWORD
3370 case SQLITE_TESTCTRL_ISKEYWORD:
3371 if( nArg==3 ){
3372 const char *opt = azArg[2];
3373 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003374 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003375 } else {
drhd416fe72011-03-17 16:45:50 +00003376 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3377 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003378 }
3379 break;
3380#endif
3381
3382 case SQLITE_TESTCTRL_BITVEC_TEST:
3383 case SQLITE_TESTCTRL_FAULT_INSTALL:
3384 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3385 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3386 default:
drhd416fe72011-03-17 16:45:50 +00003387 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3388 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003389 break;
3390 }
3391 }
3392 }else
3393
drhc2ce0be2014-05-29 12:36:14 +00003394 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003395 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003396 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003397 }else
3398
drhc2ce0be2014-05-29 12:36:14 +00003399 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3400 if( nArg==2 ){
3401 enableTimer = booleanValue(azArg[1]);
3402 if( enableTimer && !HAS_TIMER ){
3403 fprintf(stderr, "Error: timer not available on this system.\n");
3404 enableTimer = 0;
3405 }
3406 }else{
3407 fprintf(stderr, "Usage: .timer on|off\n");
3408 rc = 1;
3409 }
shanehe2aa9d72009-11-06 17:20:17 +00003410 }else
3411
drhc2ce0be2014-05-29 12:36:14 +00003412 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003413 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00003414 output_file_close(p->traceOut);
drhc2ce0be2014-05-29 12:36:14 +00003415 if( nArg!=2 ){
3416 fprintf(stderr, "Usage: .trace FILE|off\n");
3417 rc = 1;
3418 goto meta_command_exit;
3419 }
drh42f64e52012-04-04 16:56:23 +00003420 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003421#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003422 if( p->traceOut==0 ){
3423 sqlite3_trace(p->db, 0, 0);
3424 }else{
3425 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3426 }
3427#endif
3428 }else
3429
drh9fd301b2011-06-03 13:28:22 +00003430 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003431 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003432 sqlite3_libversion(), sqlite3_sourceid());
3433 }else
3434
drhde60fc22011-12-14 17:53:36 +00003435 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3436 const char *zDbName = nArg==2 ? azArg[1] : "main";
3437 char *zVfsName = 0;
3438 if( p->db ){
3439 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3440 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003441 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003442 sqlite3_free(zVfsName);
3443 }
3444 }
3445 }else
3446
drhcef4fc82012-09-21 22:50:45 +00003447#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3448 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3449 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003450 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003451 }else
3452#endif
3453
drhc2ce0be2014-05-29 12:36:14 +00003454 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003455 int j;
drh43617e92006-03-06 20:55:46 +00003456 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003457 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003458 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003459 }
3460 }else
3461
3462 {
shane9bd1b442009-10-23 01:27:39 +00003463 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003464 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003465 rc = 1;
drh75897232000-05-29 14:26:00 +00003466 }
drh67505e72002-04-19 12:34:06 +00003467
drhc2ce0be2014-05-29 12:36:14 +00003468meta_command_exit:
3469 if( p->outCount ){
3470 p->outCount--;
3471 if( p->outCount==0 ) output_reset(p);
3472 }
drh67505e72002-04-19 12:34:06 +00003473 return rc;
drh75897232000-05-29 14:26:00 +00003474}
3475
drh67505e72002-04-19 12:34:06 +00003476/*
drh91a66392007-09-07 01:12:32 +00003477** Return TRUE if a semicolon occurs anywhere in the first N characters
3478** of string z[].
drh324ccef2003-02-05 14:06:20 +00003479*/
drh9f099fd2013-08-06 14:01:46 +00003480static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00003481 int i;
3482 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3483 return 0;
drh324ccef2003-02-05 14:06:20 +00003484}
3485
3486/*
drh70c7a4b2003-04-26 03:03:06 +00003487** Test to see if a line consists entirely of whitespace.
3488*/
3489static int _all_whitespace(const char *z){
3490 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00003491 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003492 if( *z=='/' && z[1]=='*' ){
3493 z += 2;
3494 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3495 if( *z==0 ) return 0;
3496 z++;
3497 continue;
3498 }
3499 if( *z=='-' && z[1]=='-' ){
3500 z += 2;
3501 while( *z && *z!='\n' ){ z++; }
3502 if( *z==0 ) return 1;
3503 continue;
3504 }
3505 return 0;
3506 }
3507 return 1;
3508}
3509
3510/*
drha9b17162003-04-29 18:01:28 +00003511** Return TRUE if the line typed in is an SQL command terminator other
3512** than a semi-colon. The SQL Server style "go" command is understood
3513** as is the Oracle "/".
3514*/
drh9f099fd2013-08-06 14:01:46 +00003515static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00003516 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00003517 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3518 return 1; /* Oracle */
3519 }
drhf0693c82011-10-11 20:41:54 +00003520 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00003521 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00003522 return 1; /* SQL Server */
3523 }
3524 return 0;
3525}
3526
3527/*
drh233a5312008-12-18 22:25:13 +00003528** Return true if zSql is a complete SQL statement. Return false if it
3529** ends in the middle of a string literal or C-style comment.
3530*/
drh9f099fd2013-08-06 14:01:46 +00003531static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00003532 int rc;
3533 if( zSql==0 ) return 1;
3534 zSql[nSql] = ';';
3535 zSql[nSql+1] = 0;
3536 rc = sqlite3_complete(zSql);
3537 zSql[nSql] = 0;
3538 return rc;
3539}
3540
3541/*
drh67505e72002-04-19 12:34:06 +00003542** Read input from *in and process it. If *in==0 then input
3543** is interactive - the user is typing it it. Otherwise, input
3544** is coming from a file or device. A prompt is issued and history
3545** is saved only if input is interactive. An interrupt signal will
3546** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00003547**
3548** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00003549*/
drhdcd87a92014-08-18 13:45:42 +00003550static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00003551 char *zLine = 0; /* A single input line */
3552 char *zSql = 0; /* Accumulated SQL text */
3553 int nLine; /* Length of current line */
3554 int nSql = 0; /* Bytes of zSql[] used */
3555 int nAlloc = 0; /* Allocated zSql[] space */
3556 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
3557 char *zErrMsg; /* Error message returned */
3558 int rc; /* Error code */
3559 int errCnt = 0; /* Number of errors seen */
3560 int lineno = 0; /* Current line number */
3561 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00003562
3563 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
3564 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00003565 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00003566 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00003567 /* End of input */
3568 if( stdin_is_interactive ) printf("\n");
3569 break;
drhc49f44e2006-10-26 18:15:42 +00003570 }
drh67505e72002-04-19 12:34:06 +00003571 if( seenInterrupt ){
3572 if( in!=0 ) break;
3573 seenInterrupt = 0;
3574 }
drhc28490c2006-10-26 14:25:58 +00003575 lineno++;
drh849a9d92013-12-21 15:46:06 +00003576 if( nSql==0 && _all_whitespace(zLine) ){
3577 if( p->echoOn ) printf("%s\n", zLine);
3578 continue;
3579 }
drh2af0b2d2002-02-21 02:25:02 +00003580 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00003581 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00003582 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00003583 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00003584 break;
3585 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00003586 errCnt++;
3587 }
drhdaffd0e2001-04-11 14:28:42 +00003588 continue;
3589 }
drh9f099fd2013-08-06 14:01:46 +00003590 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00003591 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00003592 }
drh9f099fd2013-08-06 14:01:46 +00003593 nLine = strlen30(zLine);
3594 if( nSql+nLine+2>=nAlloc ){
3595 nAlloc = nSql+nLine+100;
3596 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00003597 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00003598 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00003599 exit(1);
3600 }
drhdaffd0e2001-04-11 14:28:42 +00003601 }
drh9f099fd2013-08-06 14:01:46 +00003602 nSqlPrior = nSql;
3603 if( nSql==0 ){
3604 int i;
3605 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00003606 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00003607 memcpy(zSql, zLine+i, nLine+1-i);
3608 startline = lineno;
3609 nSql = nLine-i;
3610 }else{
3611 zSql[nSql++] = '\n';
3612 memcpy(zSql+nSql, zLine, nLine+1);
3613 nSql += nLine;
3614 }
3615 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00003616 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00003617 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00003618 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00003619 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00003620 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00003621 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00003622 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00003623 char zPrefix[100];
3624 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00003625 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00003626 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00003627 }else{
shane9bd1b442009-10-23 01:27:39 +00003628 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00003629 }
drh7f953e22002-07-13 17:33:45 +00003630 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00003631 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003632 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00003633 zErrMsg = 0;
3634 }else{
shaned2bed1c2009-10-21 03:56:54 +00003635 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00003636 }
drhc49f44e2006-10-26 18:15:42 +00003637 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00003638 }
drhdaffd0e2001-04-11 14:28:42 +00003639 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00003640 if( p->outCount ){
3641 output_reset(p);
3642 p->outCount = 0;
3643 }
drh9f099fd2013-08-06 14:01:46 +00003644 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00003645 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00003646 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00003647 }
3648 }
drh9f099fd2013-08-06 14:01:46 +00003649 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00003650 if( !_all_whitespace(zSql) ){
3651 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
3652 }
drhdaffd0e2001-04-11 14:28:42 +00003653 free(zSql);
3654 }
danielk19772ac27622007-07-03 05:31:16 +00003655 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00003656 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00003657}
3658
drh67505e72002-04-19 12:34:06 +00003659/*
3660** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00003661** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00003662*/
3663static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00003664 static char *home_dir = NULL;
3665 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00003666
drh83905c92012-06-21 13:00:37 +00003667#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00003668 {
3669 struct passwd *pwent;
3670 uid_t uid = getuid();
3671 if( (pwent=getpwuid(uid)) != NULL) {
3672 home_dir = pwent->pw_dir;
3673 }
drh67505e72002-04-19 12:34:06 +00003674 }
3675#endif
3676
chw65d3c132007-11-12 21:09:10 +00003677#if defined(_WIN32_WCE)
3678 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
3679 */
drh85e72432012-04-11 11:38:53 +00003680 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00003681#else
3682
drh83905c92012-06-21 13:00:37 +00003683#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00003684 if (!home_dir) {
3685 home_dir = getenv("USERPROFILE");
3686 }
3687#endif
3688
drh67505e72002-04-19 12:34:06 +00003689 if (!home_dir) {
3690 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00003691 }
3692
drh83905c92012-06-21 13:00:37 +00003693#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00003694 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00003695 char *zDrive, *zPath;
3696 int n;
3697 zDrive = getenv("HOMEDRIVE");
3698 zPath = getenv("HOMEPATH");
3699 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00003700 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00003701 home_dir = malloc( n );
3702 if( home_dir==0 ) return 0;
3703 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3704 return home_dir;
3705 }
3706 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00003707 }
3708#endif
3709
chw65d3c132007-11-12 21:09:10 +00003710#endif /* !_WIN32_WCE */
3711
drh67505e72002-04-19 12:34:06 +00003712 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00003713 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00003714 char *z = malloc( n );
3715 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00003716 home_dir = z;
3717 }
drhe98d4fa2002-04-21 19:06:22 +00003718
drh67505e72002-04-19 12:34:06 +00003719 return home_dir;
3720}
3721
3722/*
3723** Read input from the file given by sqliterc_override. Or if that
3724** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00003725**
3726** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00003727*/
shane9bd1b442009-10-23 01:27:39 +00003728static int process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00003729 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00003730 const char *sqliterc_override /* Name of config file. NULL to use default */
3731){
persicom7e2dfdd2002-04-18 02:46:52 +00003732 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00003733 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00003734 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003735 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00003736 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003737
3738 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00003739 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00003740 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00003741#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00003742 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00003743#endif
shane9bd1b442009-10-23 01:27:39 +00003744 return 1;
drhe98d4fa2002-04-21 19:06:22 +00003745 }
drh2f3de322012-06-27 16:41:31 +00003746 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00003747 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
3748 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003749 }
drha1f9b5e2004-02-14 16:31:02 +00003750 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00003751 if( in ){
drhc28490c2006-10-26 14:25:58 +00003752 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00003753 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00003754 }
shane9bd1b442009-10-23 01:27:39 +00003755 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00003756 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00003757 }
drh85e72432012-04-11 11:38:53 +00003758 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00003759 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00003760}
3761
drh67505e72002-04-19 12:34:06 +00003762/*
drhe1e38c42003-05-04 18:30:59 +00003763** Show available command line options
3764*/
3765static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00003766 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00003767 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003768 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00003769 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00003770 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00003771 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00003772 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00003773 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00003774#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3775 " -heap SIZE Size of heap for memsys3 or memsys5\n"
3776#endif
drhcc3b4f82012-02-07 14:13:50 +00003777 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00003778 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00003779 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003780 " -line set output mode to 'line'\n"
3781 " -list set output mode to 'list'\n"
drh7d9f3942013-04-03 01:26:54 +00003782 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00003783#ifdef SQLITE_ENABLE_MULTIPLEX
3784 " -multiplex enable the multiplexor VFS\n"
3785#endif
drh6976c212014-07-24 12:09:47 +00003786 " -newline SEP set newline character(s) for CSV\n"
drh98d312f2012-10-25 15:23:14 +00003787 " -nullvalue TEXT set text string for NULL values. Default ''\n"
3788 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00003789 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00003790 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00003791 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00003792#ifdef SQLITE_ENABLE_VFSTRACE
3793 " -vfstrace enable tracing of all VFS calls\n"
3794#endif
drhe1e38c42003-05-04 18:30:59 +00003795;
3796static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00003797 fprintf(stderr,
3798 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3799 "FILENAME is the name of an SQLite database. A new database is created\n"
3800 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00003801 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00003802 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00003803 }else{
3804 fprintf(stderr, "Use the -help option for additional information\n");
3805 }
3806 exit(1);
3807}
3808
3809/*
drh67505e72002-04-19 12:34:06 +00003810** Initialize the state information in data
3811*/
drhdcd87a92014-08-18 13:45:42 +00003812static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00003813 memset(data, 0, sizeof(*data));
3814 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00003815 memcpy(data->separator,"|", 2);
drh6976c212014-07-24 12:09:47 +00003816 memcpy(data->newline,"\r\n", 3);
persicom7e2dfdd2002-04-18 02:46:52 +00003817 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00003818 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00003819 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00003820 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3821 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00003822 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00003823}
3824
drh98d312f2012-10-25 15:23:14 +00003825/*
drh5c7976f2014-02-10 19:59:27 +00003826** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00003827*/
3828#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00003829static void printBold(const char *zText){
3830 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
3831 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
3832 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
3833 SetConsoleTextAttribute(out,
3834 FOREGROUND_RED|FOREGROUND_INTENSITY
3835 );
3836 printf("%s", zText);
3837 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00003838}
3839#else
drh5c7976f2014-02-10 19:59:27 +00003840static void printBold(const char *zText){
3841 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00003842}
3843#endif
3844
3845/*
drh98d312f2012-10-25 15:23:14 +00003846** Get the argument to an --option. Throw an error and die if no argument
3847** is available.
3848*/
3849static char *cmdline_option_value(int argc, char **argv, int i){
3850 if( i==argc ){
3851 fprintf(stderr, "%s: Error: missing argument to %s\n",
3852 argv[0], argv[argc-1]);
3853 exit(1);
3854 }
3855 return argv[i];
3856}
3857
drh75897232000-05-29 14:26:00 +00003858int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003859 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00003860 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00003861 const char *zInitFile = 0;
3862 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003863 int i;
drhc28490c2006-10-26 14:25:58 +00003864 int rc = 0;
drhb3735912014-02-10 16:13:42 +00003865 int warnInmemoryDb = 0;
drh75897232000-05-29 14:26:00 +00003866
drh69b30ab2014-02-27 15:11:52 +00003867#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00003868 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
3869 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
3870 sqlite3_sourceid(), SQLITE_SOURCE_ID);
3871 exit(1);
3872 }
drhc7181902014-02-27 15:04:13 +00003873#endif
drhdaffd0e2001-04-11 14:28:42 +00003874 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003875 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003876 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003877
drh44c2eb12003-04-30 11:38:26 +00003878 /* Make sure we have a valid signal handler early, before anything
3879 ** else is done.
3880 */
drh4c504392000-10-16 22:06:40 +00003881#ifdef SIGINT
3882 signal(SIGINT, interrupt_handler);
3883#endif
drh44c2eb12003-04-30 11:38:26 +00003884
drh22fbcb82004-02-01 01:22:50 +00003885 /* Do an initial pass through the command-line argument to locate
3886 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00003887 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00003888 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003889 */
drh98d312f2012-10-25 15:23:14 +00003890 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00003891 char *z;
drhc28490c2006-10-26 14:25:58 +00003892 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003893 if( z[0]!='-' ){
3894 if( data.zDbFilename==0 ){
3895 data.zDbFilename = z;
3896 continue;
3897 }
3898 if( zFirstCmd==0 ){
3899 zFirstCmd = z;
3900 continue;
3901 }
3902 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
3903 fprintf(stderr,"Use -help for a list of options.\n");
3904 return 1;
3905 }
drhcc3b4f82012-02-07 14:13:50 +00003906 if( z[1]=='-' ) z++;
3907 if( strcmp(z,"-separator")==0
3908 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00003909 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00003910 || strcmp(z,"-cmd")==0
3911 ){
drh98d312f2012-10-25 15:23:14 +00003912 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003913 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00003914 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003915 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00003916 /* Need to check for batch mode here to so we can avoid printing
3917 ** informational messages (like from process_sqliterc) before
3918 ** we do the actual processing of arguments later in a second pass.
3919 */
shanef69573d2009-10-24 02:06:14 +00003920 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00003921 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00003922#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00003923 const char *zSize;
3924 sqlite3_int64 szHeap;
3925
drh98d312f2012-10-25 15:23:14 +00003926 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00003927 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00003928 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00003929 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3930#endif
drh97ae8ff2011-03-16 16:56:29 +00003931#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00003932 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00003933 extern int vfstrace_register(
3934 const char *zTraceName,
3935 const char *zOldVfsName,
3936 int (*xOut)(const char*,void*),
3937 void *pOutArg,
3938 int makeDefault
3939 );
drh2b625e22011-03-16 17:05:28 +00003940 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00003941#endif
drh6f25e892011-07-08 17:02:57 +00003942#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00003943 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00003944 extern int sqlite3_multiple_initialize(const char*,int);
3945 sqlite3_multiplex_initialize(0, 1);
3946#endif
drh7d9f3942013-04-03 01:26:54 +00003947 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00003948 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
3949 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00003950 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00003951 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00003952 if( pVfs ){
3953 sqlite3_vfs_register(pVfs, 1);
3954 }else{
3955 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3956 exit(1);
3957 }
drh44c2eb12003-04-30 11:38:26 +00003958 }
3959 }
drh98d312f2012-10-25 15:23:14 +00003960 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00003961#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003962 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00003963 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00003964#else
shane86f5bdb2009-10-24 02:00:07 +00003965 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3966 return 1;
drh01b41712005-08-29 23:06:23 +00003967#endif
drhc7181902014-02-27 15:04:13 +00003968#ifdef SQLITE_SHELL_DBNAME_PROC
3969 { extern void SQLITE_SHELL_DBNAME_PROC(const char**);
3970 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
3971 warnInmemoryDb = 0; }
3972#endif
drh98d312f2012-10-25 15:23:14 +00003973 }
3974 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00003975
drh44c2eb12003-04-30 11:38:26 +00003976 /* Go ahead and open the database file if it already exists. If the
3977 ** file does not exist, delay opening it. This prevents empty database
3978 ** files from being created if a user mistypes the database name argument
3979 ** to the sqlite command-line tool.
3980 */
drhc8d74412004-08-31 23:41:26 +00003981 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00003982 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00003983 }
3984
drh22fbcb82004-02-01 01:22:50 +00003985 /* Process the initialization file if there is one. If no -init option
3986 ** is given on the command line, look for a file named ~/.sqliterc and
3987 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003988 */
shane86f5bdb2009-10-24 02:00:07 +00003989 rc = process_sqliterc(&data,zInitFile);
3990 if( rc>0 ){
3991 return rc;
3992 }
drh44c2eb12003-04-30 11:38:26 +00003993
drh22fbcb82004-02-01 01:22:50 +00003994 /* Make a second pass through the command-line argument and set
3995 ** options. This second pass is delayed until after the initialization
3996 ** file is processed so that the command-line arguments will override
3997 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003998 */
drh98d312f2012-10-25 15:23:14 +00003999 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004000 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004001 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004002 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004003 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004004 i++;
4005 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004006 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004007 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004008 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004009 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004010 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004011 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004012 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004013 }else if( strcmp(z,"-csv")==0 ){
4014 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00004015 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00004016 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00004017 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00004018 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004019 }else if( strcmp(z,"-newline")==0 ){
4020 sqlite3_snprintf(sizeof(data.newline), data.newline,
4021 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004022 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00004023 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00004024 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004025 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004026 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004027 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004028 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004029 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004030 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004031 }else if( strcmp(z,"-eqp")==0 ){
4032 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004033 }else if( strcmp(z,"-stats")==0 ){
4034 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004035 }else if( strcmp(z,"-bail")==0 ){
4036 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004037 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004038 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004039 return 0;
drhc28490c2006-10-26 14:25:58 +00004040 }else if( strcmp(z,"-interactive")==0 ){
4041 stdin_is_interactive = 1;
4042 }else if( strcmp(z,"-batch")==0 ){
4043 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004044 }else if( strcmp(z,"-heap")==0 ){
4045 i++;
drh7d9f3942013-04-03 01:26:54 +00004046 }else if( strcmp(z,"-mmap")==0 ){
4047 i++;
drha7e61d82011-03-12 17:02:57 +00004048 }else if( strcmp(z,"-vfs")==0 ){
4049 i++;
drh6f25e892011-07-08 17:02:57 +00004050#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004051 }else if( strcmp(z,"-vfstrace")==0 ){
4052 i++;
drh6f25e892011-07-08 17:02:57 +00004053#endif
4054#ifdef SQLITE_ENABLE_MULTIPLEX
4055 }else if( strcmp(z,"-multiplex")==0 ){
4056 i++;
4057#endif
drhcc3b4f82012-02-07 14:13:50 +00004058 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004059 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004060 }else if( strcmp(z,"-cmd")==0 ){
4061 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004062 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004063 if( z[0]=='.' ){
4064 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004065 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004066 }else{
drh05782482013-10-24 15:20:20 +00004067 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004068 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4069 if( zErrMsg!=0 ){
4070 fprintf(stderr,"Error: %s\n", zErrMsg);
4071 if( bail_on_error ) return rc!=0 ? rc : 1;
4072 }else if( rc!=0 ){
4073 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4074 if( bail_on_error ) return rc;
4075 }
4076 }
drh1e5d0e92000-05-31 23:33:17 +00004077 }else{
shane86f5bdb2009-10-24 02:00:07 +00004078 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004079 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004080 return 1;
4081 }
4082 }
drh44c2eb12003-04-30 11:38:26 +00004083
drh22fbcb82004-02-01 01:22:50 +00004084 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00004085 /* Run just the command that follows the database name
4086 */
drh22fbcb82004-02-01 01:22:50 +00004087 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00004088 rc = do_meta_command(zFirstCmd, &data);
drh99b39082013-04-17 12:19:48 +00004089 if( rc==2 ) rc = 0;
drh6ff13852001-11-25 13:18:23 +00004090 }else{
drh05782482013-10-24 15:20:20 +00004091 open_db(&data, 0);
shane626a6e42009-10-22 17:30:15 +00004092 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00004093 if( zErrMsg!=0 ){
4094 fprintf(stderr,"Error: %s\n", zErrMsg);
4095 return rc!=0 ? rc : 1;
4096 }else if( rc!=0 ){
4097 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
4098 return rc;
drh6ff13852001-11-25 13:18:23 +00004099 }
drh75897232000-05-29 14:26:00 +00004100 }
4101 }else{
drh44c2eb12003-04-30 11:38:26 +00004102 /* Run commands received from standard input
4103 */
drhc28490c2006-10-26 14:25:58 +00004104 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004105 char *zHome;
4106 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004107 int nHistory;
drh75897232000-05-29 14:26:00 +00004108 printf(
drh743e0032011-12-12 16:51:50 +00004109 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004110 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004111 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004112 );
drhb3735912014-02-10 16:13:42 +00004113 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004114 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004115 printBold("transient in-memory database");
4116 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004117 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004118 }
drh67505e72002-04-19 12:34:06 +00004119 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004120 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004121 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004122 if( (zHistory = malloc(nHistory))!=0 ){
4123 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4124 }
drh67505e72002-04-19 12:34:06 +00004125 }
drhaaa21b42014-02-11 14:37:51 +00004126#if defined(HAVE_READLINE)
drh67505e72002-04-19 12:34:06 +00004127 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00004128#endif
drhc28490c2006-10-26 14:25:58 +00004129 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004130 if( zHistory ){
4131 stifle_history(100);
4132 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004133 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004134 }
drhdaffd0e2001-04-11 14:28:42 +00004135 }else{
drhc28490c2006-10-26 14:25:58 +00004136 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004137 }
4138 }
drh33048c02001-10-01 14:29:22 +00004139 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004140 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004141 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004142 }
drh05782482013-10-24 15:20:20 +00004143 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004144 return rc;
drh75897232000-05-29 14:26:00 +00004145}