blob: 278a633741fd314e31e2273d9ff7daccd13302c3 [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/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
93# define shell_read_history(X)
94# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
shane18e526c2008-12-10 22:30:24 +0000104#define isatty(h) _isatty(h)
drh07901eb2014-02-28 19:37:45 +0000105#ifndef access
106# define access(f,m) _access((f),(m))
107#endif
drh67ceaa62012-08-27 21:19:03 +0000108#undef popen
drh53371f92013-07-25 17:07:03 +0000109#define popen _popen
drh67ceaa62012-08-27 21:19:03 +0000110#undef pclose
drh12cd6cf2013-06-29 15:40:22 +0000111#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
drh4328c8b2003-04-26 02:50:11 +0000113/* Make sure isatty() has a prototype.
114*/
drhb2acc3b2011-10-13 16:36:29 +0000115extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000116
drh8cd5b252015-03-02 22:06:43 +0000117#if !defined(__RTP__) && !defined(_WRS_KERNEL)
118 /* popen and pclose are not C89 functions and so are sometimes omitted from
119 ** the <stdio.h> header */
120 extern FILE *popen(const char*,const char*);
121 extern int pclose(FILE*);
122#else
123# define SQLITE_OMIT_POPEN 1
124#endif
125
mistachkinf6418892013-08-28 01:54:12 +0000126#endif
drh53371f92013-07-25 17:07:03 +0000127
chw65d3c132007-11-12 21:09:10 +0000128#if defined(_WIN32_WCE)
129/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
130 * thus we always assume that we have a console. That can be
131 * overridden with the -batch command line option.
132 */
133#define isatty(x) 1
134#endif
135
drhf0693c82011-10-11 20:41:54 +0000136/* ctype macros that work with signed characters */
137#define IsSpace(X) isspace((unsigned char)X)
138#define IsDigit(X) isdigit((unsigned char)X)
139#define ToLower(X) (char)tolower((unsigned char)X)
140
drh047d4532015-01-18 20:30:23 +0000141/* On Windows, we normally run with output mode of TEXT so that \n characters
142** are automatically translated into \r\n. However, this behavior needs
143** to be disabled in some cases (ex: when generating CSV output and when
144** rendering quoted strings that contain \n characters). The following
145** routines take care of that.
146*/
147#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000148static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000149 fflush(out);
150 _setmode(_fileno(out), _O_BINARY);
151}
mistachkine4a0d792015-01-27 21:24:33 +0000152static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000153 fflush(out);
154 _setmode(_fileno(out), _O_TEXT);
155}
156#else
157# define setBinaryMode(X)
158# define setTextMode(X)
159#endif
160
drh43408312013-10-30 12:43:36 +0000161
162/* True if the timer is enabled */
163static int enableTimer = 0;
164
165/* Return the current wall-clock time */
166static sqlite3_int64 timeOfDay(void){
167 static sqlite3_vfs *clockVfs = 0;
168 sqlite3_int64 t;
169 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
170 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
171 clockVfs->xCurrentTimeInt64(clockVfs, &t);
172 }else{
173 double r;
174 clockVfs->xCurrentTime(clockVfs, &r);
175 t = (sqlite3_int64)(r*86400000.0);
176 }
177 return t;
178}
179
drh91eb93c2015-03-03 19:56:20 +0000180#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000181#include <sys/time.h>
182#include <sys/resource.h>
183
drh91eb93c2015-03-03 19:56:20 +0000184/* VxWorks does not support getrusage() as far as we can determine */
185#if defined(_WRS_KERNEL) || defined(__RTP__)
186struct rusage {
187 struct timeval ru_utime; /* user CPU time used */
188 struct timeval ru_stime; /* system CPU time used */
189};
190#define getrusage(A,B) memset(B,0,sizeof(*B))
191#endif
192
drhda108222009-02-25 19:07:24 +0000193/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000194static struct rusage sBegin; /* CPU time at start */
195static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000196
drhda108222009-02-25 19:07:24 +0000197/*
198** Begin timing an operation
199*/
200static void beginTimer(void){
201 if( enableTimer ){
202 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000203 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000204 }
205}
206
207/* Return the difference of two time_structs in seconds */
208static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
209 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
210 (double)(pEnd->tv_sec - pStart->tv_sec);
211}
212
213/*
214** Print the timing results.
215*/
216static void endTimer(void){
217 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000218 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000219 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000220 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000221 printf("Run Time: real %.3f user %f sys %f\n",
222 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000223 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
224 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
225 }
226}
shaneb320ccd2009-10-21 03:42:58 +0000227
drhda108222009-02-25 19:07:24 +0000228#define BEGIN_TIMER beginTimer()
229#define END_TIMER endTimer()
230#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000231
232#elif (defined(_WIN32) || defined(WIN32))
233
234#include <windows.h>
235
236/* Saved resource information for the beginning of an operation */
237static HANDLE hProcess;
238static FILETIME ftKernelBegin;
239static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000240static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000241typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
242 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000243static GETPROCTIMES getProcessTimesAddr = NULL;
244
shaneb320ccd2009-10-21 03:42:58 +0000245/*
246** Check to see if we have timer support. Return 1 if necessary
247** support found (or found previously).
248*/
249static int hasTimer(void){
250 if( getProcessTimesAddr ){
251 return 1;
252 } else {
drh4ace5362014-11-10 14:42:28 +0000253 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
254 ** versions. See if the version we are running on has it, and if it
255 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000256 */
257 hProcess = GetCurrentProcess();
258 if( hProcess ){
259 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
260 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000261 getProcessTimesAddr =
262 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000263 if( NULL != getProcessTimesAddr ){
264 return 1;
265 }
266 FreeLibrary(hinstLib);
267 }
268 }
269 }
270 return 0;
271}
272
273/*
274** Begin timing an operation
275*/
276static void beginTimer(void){
277 if( enableTimer && getProcessTimesAddr ){
278 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000279 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
280 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000281 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000282 }
283}
284
285/* Return the difference of two FILETIME structs in seconds */
286static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
287 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
288 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
289 return (double) ((i64End - i64Start) / 10000000.0);
290}
291
292/*
293** Print the timing results.
294*/
295static void endTimer(void){
296 if( enableTimer && getProcessTimesAddr){
297 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000298 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000299 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000300 printf("Run Time: real %.3f user %f sys %f\n",
301 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000302 timeDiff(&ftUserBegin, &ftUserEnd),
303 timeDiff(&ftKernelBegin, &ftKernelEnd));
304 }
305}
306
307#define BEGIN_TIMER beginTimer()
308#define END_TIMER endTimer()
309#define HAS_TIMER hasTimer()
310
drhda108222009-02-25 19:07:24 +0000311#else
312#define BEGIN_TIMER
313#define END_TIMER
314#define HAS_TIMER 0
315#endif
316
shanec0688ea2009-03-05 03:48:06 +0000317/*
318** Used to prevent warnings about unused parameters
319*/
320#define UNUSED_PARAMETER(x) (void)(x)
321
drhe91d16b2008-12-08 18:27:31 +0000322/*
drhc49f44e2006-10-26 18:15:42 +0000323** If the following flag is set, then command execution stops
324** at an error if we are not interactive.
325*/
326static int bail_on_error = 0;
327
328/*
drhc28490c2006-10-26 14:25:58 +0000329** Threat stdin as an interactive input if the following variable
330** is true. Otherwise, assume stdin is connected to a file or pipe.
331*/
332static int stdin_is_interactive = 1;
333
334/*
drh4c504392000-10-16 22:06:40 +0000335** The following is the open SQLite database. We make a pointer
336** to this database a static variable so that it can be accessed
337** by the SIGINT handler to interrupt database processing.
338*/
mistachkin8e189222015-04-19 21:43:16 +0000339static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000340
341/*
drh67505e72002-04-19 12:34:06 +0000342** True if an interrupt (Control-C) has been received.
343*/
drh43617e92006-03-06 20:55:46 +0000344static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000345
346/*
persicom7e2dfdd2002-04-18 02:46:52 +0000347** This is the name of our program. It is set in main(), used
348** in a number of other places, mostly for error messages.
349*/
350static char *Argv0;
351
352/*
353** Prompt strings. Initialized in main. Settable with
354** .prompt main continue
355*/
356static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
357static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
358
drhb0603412007-02-28 04:47:26 +0000359/*
360** Write I/O traces to the following stream.
361*/
rsebe0a9092007-07-30 18:24:38 +0000362#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000363static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000364#endif
drhb0603412007-02-28 04:47:26 +0000365
366/*
367** This routine works like printf in that its first argument is a
368** format string and subsequent arguments are values to be substituted
369** in place of % fields. The result of formatting this string
370** is written to iotrace.
371*/
rsebe0a9092007-07-30 18:24:38 +0000372#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000373static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000374 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000375 char *z;
drhb0603412007-02-28 04:47:26 +0000376 if( iotrace==0 ) return;
377 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000378 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000379 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000380 fprintf(iotrace, "%s", z);
381 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000382}
rsebe0a9092007-07-30 18:24:38 +0000383#endif
drhb0603412007-02-28 04:47:26 +0000384
drh44c2eb12003-04-30 11:38:26 +0000385
persicom7e2dfdd2002-04-18 02:46:52 +0000386/*
drh83965662003-04-17 02:54:13 +0000387** Determines if a string is a number of not.
388*/
danielk19772e588c72005-12-09 14:25:08 +0000389static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000390 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000391 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000392 return 0;
393 }
394 z++;
395 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000396 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000397 if( *z=='.' ){
398 z++;
drhf0693c82011-10-11 20:41:54 +0000399 if( !IsDigit(*z) ) return 0;
400 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000401 if( realnum ) *realnum = 1;
402 }
403 if( *z=='e' || *z=='E' ){
404 z++;
405 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000406 if( !IsDigit(*z) ) return 0;
407 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000408 if( realnum ) *realnum = 1;
409 }
410 return *z==0;
411}
drh83965662003-04-17 02:54:13 +0000412
413/*
danielk1977bc6ada42004-06-30 08:20:16 +0000414** A global char* and an SQL function to access its current value
415** from within an SQL statement. This program used to use the
416** sqlite_exec_printf() API to substitue a string into an SQL statement.
417** The correct way to do this with sqlite3 is to use the bind API, but
418** since the shell is built around the callback paradigm it would be a lot
419** of work. Instead just use this hack, which is quite harmless.
420*/
421static const char *zShellStatic = 0;
422static void shellstaticFunc(
423 sqlite3_context *context,
424 int argc,
425 sqlite3_value **argv
426){
427 assert( 0==argc );
428 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000429 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000430 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000431 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
432}
433
434
435/*
drhfeac5f82004-08-01 00:10:45 +0000436** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000437** the text in memory obtained from malloc() and returns a pointer
438** to the text. NULL is returned at end of file, or if malloc()
439** fails.
440**
drh9f099fd2013-08-06 14:01:46 +0000441** If zLine is not NULL then it is a malloced buffer returned from
442** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000443*/
drh9f099fd2013-08-06 14:01:46 +0000444static char *local_getline(char *zLine, FILE *in){
445 int nLine = zLine==0 ? 0 : 100;
446 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000447
drhb07028f2011-10-14 21:49:18 +0000448 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000449 if( n+100>nLine ){
450 nLine = nLine*2 + 100;
451 zLine = realloc(zLine, nLine);
452 if( zLine==0 ) return 0;
453 }
drhdaffd0e2001-04-11 14:28:42 +0000454 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000455 if( n==0 ){
456 free(zLine);
457 return 0;
458 }
459 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000460 break;
461 }
drh9f099fd2013-08-06 14:01:46 +0000462 while( zLine[n] ) n++;
463 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000464 n--;
shaneh13b36022009-12-17 21:07:15 +0000465 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000466 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000467 break;
drh8e7e7a22000-05-30 18:45:23 +0000468 }
469 }
drh8e7e7a22000-05-30 18:45:23 +0000470 return zLine;
471}
472
473/*
drhc28490c2006-10-26 14:25:58 +0000474** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000475**
drh9f099fd2013-08-06 14:01:46 +0000476** If in==0 then read from standard input and prompt before each line.
477** If isContinuation is true, then a continuation prompt is appropriate.
478** If isContinuation is zero, then the main prompt should be used.
479**
480** If zPrior is not NULL then it is a buffer from a prior call to this
481** routine that can be reused.
482**
483** The result is stored in space obtained from malloc() and must either
484** be freed by the caller or else passed back into this routine via the
485** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000486*/
drh9f099fd2013-08-06 14:01:46 +0000487static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000488 char *zPrompt;
489 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000490 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000491 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000492 }else{
drh9f099fd2013-08-06 14:01:46 +0000493 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000494#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000495 printf("%s", zPrompt);
496 fflush(stdout);
497 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000498#else
499 free(zPrior);
500 zResult = shell_readline(zPrompt);
501 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000502#endif
drh9f099fd2013-08-06 14:01:46 +0000503 }
drh8e7e7a22000-05-30 18:45:23 +0000504 return zResult;
505}
506
drhdcd87a92014-08-18 13:45:42 +0000507/*
508** Shell output mode information from before ".explain on",
509** saved so that it can be restored by ".explain off"
510*/
511typedef struct SavedModeInfo SavedModeInfo;
512struct SavedModeInfo {
513 int valid; /* Is there legit data in here? */
514 int mode; /* Mode prior to ".explain on" */
515 int showHeader; /* The ".header" setting prior to ".explain on" */
516 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000517};
drh45e29d82006-11-20 16:21:10 +0000518
drh8e7e7a22000-05-30 18:45:23 +0000519/*
drhdcd87a92014-08-18 13:45:42 +0000520** State information about the database connection is contained in an
521** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000522*/
drhdcd87a92014-08-18 13:45:42 +0000523typedef struct ShellState ShellState;
524struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000525 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000526 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000527 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000528 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000529 int scanstatsOn; /* True to display scan stats before each finalize */
drh9569f602015-04-16 15:05:04 +0000530 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000531 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000532 int cnt; /* Number of records displayed so far */
533 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000534 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000535 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000536 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000537 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000538 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000539 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000540 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000541 char colSeparator[20]; /* Column separator character for several modes */
542 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000543 int colWidth[100]; /* Requested width of each column when in column mode*/
544 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000545 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000546 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000547 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000548 char outfile[FILENAME_MAX]; /* Filename for *out */
549 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000550 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000551 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000552 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000553 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000554 int *aiIndent; /* Array of indents used in MODE_Explain */
555 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000556 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000557};
558
559/*
drh44dec872014-08-30 15:49:25 +0000560** These are the allowed shellFlgs values
561*/
562#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
563#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
564#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
565
566/*
drh75897232000-05-29 14:26:00 +0000567** These are the allowed modes.
568*/
drh967e8b72000-06-21 13:59:10 +0000569#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000570#define MODE_Column 1 /* One record per line in neat columns */
571#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000572#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
573#define MODE_Html 4 /* Generate an XHTML table */
574#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000575#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000576#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000577#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000578#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000579
drh66ce4d02008-02-15 17:38:06 +0000580static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000581 "line",
582 "column",
583 "list",
584 "semi",
585 "html",
drhfeac5f82004-08-01 00:10:45 +0000586 "insert",
587 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000588 "csv",
drh66ce4d02008-02-15 17:38:06 +0000589 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000590 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000591};
drh75897232000-05-29 14:26:00 +0000592
593/*
mistachkinfad42082014-07-24 22:13:12 +0000594** These are the column/row/line separators used by the various
595** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000596*/
mistachkinfad42082014-07-24 22:13:12 +0000597#define SEP_Column "|"
598#define SEP_Row "\n"
599#define SEP_Tab "\t"
600#define SEP_Space " "
601#define SEP_Comma ","
602#define SEP_CrLf "\r\n"
603#define SEP_Unit "\x1F"
604#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000605
606/*
drh75897232000-05-29 14:26:00 +0000607** Number of elements in an array
608*/
drh902b9ee2008-12-05 17:17:07 +0000609#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000610
611/*
drhea678832008-12-10 19:26:22 +0000612** Compute a string length that is limited to what can be stored in
613** lower 30 bits of a 32-bit signed integer.
614*/
drh4f21c4a2008-12-10 22:15:00 +0000615static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000616 const char *z2 = z;
617 while( *z2 ){ z2++; }
618 return 0x3fffffff & (int)(z2 - z);
619}
620
621/*
drh127f9d72010-02-23 01:47:00 +0000622** A callback for the sqlite3_log() interface.
623*/
624static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000625 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000626 if( p->pLog==0 ) return;
627 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
628 fflush(p->pLog);
629}
630
631/*
shane626a6e42009-10-22 17:30:15 +0000632** Output the given string as a hex-encoded blob (eg. X'1234' )
633*/
634static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
635 int i;
636 char *zBlob = (char *)pBlob;
637 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000638 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000639 fprintf(out,"'");
640}
641
642/*
drh28bd4bc2000-06-15 15:57:22 +0000643** Output the given string as a quoted string using SQL quoting conventions.
644*/
645static void output_quoted_string(FILE *out, const char *z){
646 int i;
647 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000648 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000649 for(i=0; z[i]; i++){
650 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000651 }
652 if( nSingle==0 ){
653 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000654 }else{
655 fprintf(out,"'");
656 while( *z ){
657 for(i=0; z[i] && z[i]!='\''; i++){}
658 if( i==0 ){
659 fprintf(out,"''");
660 z++;
661 }else if( z[i]=='\'' ){
662 fprintf(out,"%.*s''",i,z);
663 z += i+1;
664 }else{
drhcd7d2732002-02-26 23:24:26 +0000665 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000666 break;
667 }
668 }
drhcd7d2732002-02-26 23:24:26 +0000669 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000670 }
drh047d4532015-01-18 20:30:23 +0000671 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000672}
673
674/*
drhfeac5f82004-08-01 00:10:45 +0000675** Output the given string as a quoted according to C or TCL quoting rules.
676*/
677static void output_c_string(FILE *out, const char *z){
678 unsigned int c;
679 fputc('"', out);
680 while( (c = *(z++))!=0 ){
681 if( c=='\\' ){
682 fputc(c, out);
683 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000684 }else if( c=='"' ){
685 fputc('\\', out);
686 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000687 }else if( c=='\t' ){
688 fputc('\\', out);
689 fputc('t', out);
690 }else if( c=='\n' ){
691 fputc('\\', out);
692 fputc('n', out);
693 }else if( c=='\r' ){
694 fputc('\\', out);
695 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000696 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000697 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000698 }else{
699 fputc(c, out);
700 }
701 }
702 fputc('"', out);
703}
704
705/*
drhc08a4f12000-06-15 16:49:48 +0000706** Output the given string with characters that are special to
707** HTML escaped.
708*/
709static void output_html_string(FILE *out, const char *z){
710 int i;
drhc3d6ba42014-01-13 20:38:35 +0000711 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000712 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000713 for(i=0; z[i]
714 && z[i]!='<'
715 && z[i]!='&'
716 && z[i]!='>'
717 && z[i]!='\"'
718 && z[i]!='\'';
719 i++){}
drhc08a4f12000-06-15 16:49:48 +0000720 if( i>0 ){
721 fprintf(out,"%.*s",i,z);
722 }
723 if( z[i]=='<' ){
724 fprintf(out,"&lt;");
725 }else if( z[i]=='&' ){
726 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000727 }else if( z[i]=='>' ){
728 fprintf(out,"&gt;");
729 }else if( z[i]=='\"' ){
730 fprintf(out,"&quot;");
731 }else if( z[i]=='\'' ){
732 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000733 }else{
734 break;
735 }
736 z += i + 1;
737 }
738}
739
740/*
drhc49f44e2006-10-26 18:15:42 +0000741** If a field contains any character identified by a 1 in the following
742** array, then the string must be quoted for CSV.
743*/
744static const char needCsvQuote[] = {
745 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
746 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
747 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
748 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
749 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
750 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
751 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
752 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
753 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
754 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
755 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
756 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
757 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
758 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
759 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
760 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
761};
762
763/*
mistachkindd11f2d2014-12-11 04:49:46 +0000764** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000765** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000766** the null value. Strings are quoted if necessary. The separator
767** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000768*/
drhdcd87a92014-08-18 13:45:42 +0000769static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000770 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000771 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000772 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000773 }else{
drhc49f44e2006-10-26 18:15:42 +0000774 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000775 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000776 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000777 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000778 || (z[i]==p->colSeparator[0] &&
779 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000780 i = 0;
781 break;
782 }
783 }
784 if( i==0 ){
785 putc('"', out);
786 for(i=0; z[i]; i++){
787 if( z[i]=='"' ) putc('"', out);
788 putc(z[i], out);
789 }
790 putc('"', out);
791 }else{
792 fprintf(out, "%s", z);
793 }
drh8e64d1c2004-10-07 00:32:39 +0000794 }
795 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000796 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000797 }
798}
799
danielk19774af00c62005-01-23 23:43:21 +0000800#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000801/*
drh4c504392000-10-16 22:06:40 +0000802** This routine runs when the user presses Ctrl-C
803*/
804static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000805 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000806 seenInterrupt++;
807 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000808 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000809}
danielk19774af00c62005-01-23 23:43:21 +0000810#endif
drh4c504392000-10-16 22:06:40 +0000811
812/*
shane626a6e42009-10-22 17:30:15 +0000813** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000814** invokes for each row of a query result.
815*/
drh4ace5362014-11-10 14:42:28 +0000816static int shell_callback(
817 void *pArg,
818 int nArg, /* Number of result columns */
819 char **azArg, /* Text of each result column */
820 char **azCol, /* Column names */
821 int *aiType /* Column types */
822){
drh75897232000-05-29 14:26:00 +0000823 int i;
drhdcd87a92014-08-18 13:45:42 +0000824 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000825
drh75897232000-05-29 14:26:00 +0000826 switch( p->mode ){
827 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000828 int w = 5;
drh6a535342001-10-19 16:44:56 +0000829 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000830 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000831 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000832 if( len>w ) w = len;
833 }
mistachkin636bf9f2014-07-19 20:15:16 +0000834 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000835 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000836 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000837 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000838 }
839 break;
840 }
danielk19770d78bae2008-01-03 07:09:48 +0000841 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000842 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000843 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000844 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000845 int w, n;
846 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000847 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000848 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000849 w = 0;
drh75897232000-05-29 14:26:00 +0000850 }
drh078b1fd2012-09-21 13:40:02 +0000851 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000852 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000853 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000854 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000855 if( w<n ) w = n;
856 }
857 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000858 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000859 }
860 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000861 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000862 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
863 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000864 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000865 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
866 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000867 }
drha0c66f52000-07-29 13:20:21 +0000868 }
869 }
870 if( p->showHeader ){
871 for(i=0; i<nArg; i++){
872 int w;
873 if( i<ArraySize(p->actualWidth) ){
874 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000875 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000876 }else{
877 w = 10;
878 }
879 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
880 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000881 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000882 }
drh75897232000-05-29 14:26:00 +0000883 }
884 }
drh6a535342001-10-19 16:44:56 +0000885 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000886 for(i=0; i<nArg; i++){
887 int w;
drha0c66f52000-07-29 13:20:21 +0000888 if( i<ArraySize(p->actualWidth) ){
889 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000890 }else{
891 w = 10;
892 }
dana98bf362013-11-13 18:35:01 +0000893 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000894 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000895 }
dana98bf362013-11-13 18:35:01 +0000896 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000897 if( p->iIndent<p->nIndent ){
898 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000899 }
danc4650bb2013-11-18 08:41:06 +0000900 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000901 }
drh078b1fd2012-09-21 13:40:02 +0000902 if( w<0 ){
903 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000904 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000905 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000906 }else{
907 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000908 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000909 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000910 }
drh75897232000-05-29 14:26:00 +0000911 }
912 break;
913 }
drhe3710332000-09-29 13:30:53 +0000914 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000915 case MODE_List: {
916 if( p->cnt++==0 && p->showHeader ){
917 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000918 fprintf(p->out,"%s%s",azCol[i],
919 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000920 }
921 }
drh6a535342001-10-19 16:44:56 +0000922 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000923 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000924 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000925 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000926 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000927 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000928 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000929 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000930 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000931 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000932 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000933 }
drh75897232000-05-29 14:26:00 +0000934 }
935 break;
936 }
drh1e5d0e92000-05-31 23:33:17 +0000937 case MODE_Html: {
938 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000939 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000940 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000941 fprintf(p->out,"<TH>");
942 output_html_string(p->out, azCol[i]);
943 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000944 }
mihailim57c591a2008-06-23 21:26:05 +0000945 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000946 }
drh6a535342001-10-19 16:44:56 +0000947 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000948 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000949 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000950 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000951 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000952 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000953 }
mihailim57c591a2008-06-23 21:26:05 +0000954 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000955 break;
956 }
drhfeac5f82004-08-01 00:10:45 +0000957 case MODE_Tcl: {
958 if( p->cnt++==0 && p->showHeader ){
959 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000960 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000961 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000962 }
mistachkin636bf9f2014-07-19 20:15:16 +0000963 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000964 }
965 if( azArg==0 ) break;
966 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000967 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000968 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000969 }
mistachkin636bf9f2014-07-19 20:15:16 +0000970 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000971 break;
972 }
drh8e64d1c2004-10-07 00:32:39 +0000973 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000974 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000975 if( p->cnt++==0 && p->showHeader ){
976 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000977 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000978 }
mistachkine0d68852014-12-11 03:12:33 +0000979 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000980 }
drh40253262014-10-17 21:35:05 +0000981 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000982 for(i=0; i<nArg; i++){
983 output_csv(p, azArg[i], i<nArg-1);
984 }
mistachkine0d68852014-12-11 03:12:33 +0000985 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000986 }
drh047d4532015-01-18 20:30:23 +0000987 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000988 break;
989 }
drh28bd4bc2000-06-15 15:57:22 +0000990 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000991 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000992 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000993 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000994 for(i=0; i<nArg; i++){
995 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000996 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000997 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000998 }else if( aiType && aiType[i]==SQLITE_TEXT ){
999 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1000 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001001 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1002 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +00001003 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001004 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1005 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1006 int nBlob = sqlite3_column_bytes(p->pStmt, i);
1007 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1008 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001009 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001010 fprintf(p->out,"%s%s",zSep, azArg[i]);
1011 }else{
1012 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1013 output_quoted_string(p->out, azArg[i]);
1014 }
1015 }
1016 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001017 break;
drh28bd4bc2000-06-15 15:57:22 +00001018 }
mistachkin636bf9f2014-07-19 20:15:16 +00001019 case MODE_Ascii: {
1020 if( p->cnt++==0 && p->showHeader ){
1021 for(i=0; i<nArg; i++){
1022 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
1023 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
1024 }
1025 fprintf(p->out, "%s", p->rowSeparator);
1026 }
1027 if( azArg==0 ) break;
1028 for(i=0; i<nArg; i++){
1029 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +00001030 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001031 }
1032 fprintf(p->out, "%s", p->rowSeparator);
1033 break;
1034 }
persicom1d0b8722002-04-18 02:53:04 +00001035 }
drh75897232000-05-29 14:26:00 +00001036 return 0;
1037}
1038
1039/*
shane626a6e42009-10-22 17:30:15 +00001040** This is the callback routine that the SQLite library
1041** invokes for each row of a query result.
1042*/
1043static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1044 /* since we don't have type info, call the shell_callback with a NULL value */
1045 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1046}
1047
1048/*
drhdcd87a92014-08-18 13:45:42 +00001049** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001050** the name of the table given. Escape any quote characters in the
1051** table name.
1052*/
drhdcd87a92014-08-18 13:45:42 +00001053static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001054 int i, n;
1055 int needQuote;
1056 char *z;
1057
1058 if( p->zDestTable ){
1059 free(p->zDestTable);
1060 p->zDestTable = 0;
1061 }
1062 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001063 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001064 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001065 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001066 needQuote = 1;
1067 if( zName[i]=='\'' ) n++;
1068 }
1069 }
1070 if( needQuote ) n += 2;
1071 z = p->zDestTable = malloc( n+1 );
1072 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001073 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001074 exit(1);
1075 }
1076 n = 0;
1077 if( needQuote ) z[n++] = '\'';
1078 for(i=0; zName[i]; i++){
1079 z[n++] = zName[i];
1080 if( zName[i]=='\'' ) z[n++] = '\'';
1081 }
1082 if( needQuote ) z[n++] = '\'';
1083 z[n] = 0;
1084}
1085
danielk19772a02e332004-06-05 08:04:36 +00001086/* zIn is either a pointer to a NULL-terminated string in memory obtained
1087** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1088** added to zIn, and the result returned in memory obtained from malloc().
1089** zIn, if it was not NULL, is freed.
1090**
1091** If the third argument, quote, is not '\0', then it is used as a
1092** quote character for zAppend.
1093*/
drhc28490c2006-10-26 14:25:58 +00001094static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001095 int len;
1096 int i;
drh4f21c4a2008-12-10 22:15:00 +00001097 int nAppend = strlen30(zAppend);
1098 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001099
1100 len = nAppend+nIn+1;
1101 if( quote ){
1102 len += 2;
1103 for(i=0; i<nAppend; i++){
1104 if( zAppend[i]==quote ) len++;
1105 }
1106 }
1107
1108 zIn = (char *)realloc(zIn, len);
1109 if( !zIn ){
1110 return 0;
1111 }
1112
1113 if( quote ){
1114 char *zCsr = &zIn[nIn];
1115 *zCsr++ = quote;
1116 for(i=0; i<nAppend; i++){
1117 *zCsr++ = zAppend[i];
1118 if( zAppend[i]==quote ) *zCsr++ = quote;
1119 }
1120 *zCsr++ = quote;
1121 *zCsr++ = '\0';
1122 assert( (zCsr-zIn)==len );
1123 }else{
1124 memcpy(&zIn[nIn], zAppend, nAppend);
1125 zIn[len-1] = '\0';
1126 }
1127
1128 return zIn;
1129}
1130
drhdd3d4592004-08-30 01:54:05 +00001131
1132/*
drhb21a8e42012-01-28 21:08:51 +00001133** Execute a query statement that will generate SQL output. Print
1134** the result columns, comma-separated, on a line and then add a
1135** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001136**
drhb21a8e42012-01-28 21:08:51 +00001137** If the number of columns is 1 and that column contains text "--"
1138** then write the semicolon on a separate line. That way, if a
1139** "--" comment occurs at the end of the statement, the comment
1140** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001141*/
drh157e29a2009-05-21 15:15:00 +00001142static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001143 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001144 const char *zSelect, /* SELECT statement to extract content */
1145 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001146){
drhdd3d4592004-08-30 01:54:05 +00001147 sqlite3_stmt *pSelect;
1148 int rc;
drhb21a8e42012-01-28 21:08:51 +00001149 int nResult;
1150 int i;
1151 const char *z;
drhc7181902014-02-27 15:04:13 +00001152 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001153 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001154 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001155 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001156 return rc;
1157 }
1158 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001159 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001160 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001161 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001162 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001163 zFirstRow = 0;
1164 }
drhb21a8e42012-01-28 21:08:51 +00001165 z = (const char*)sqlite3_column_text(pSelect, 0);
1166 fprintf(p->out, "%s", z);
1167 for(i=1; i<nResult; i++){
1168 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1169 }
1170 if( z==0 ) z = "";
1171 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1172 if( z[0] ){
1173 fprintf(p->out, "\n;\n");
1174 }else{
1175 fprintf(p->out, ";\n");
1176 }
drhdd3d4592004-08-30 01:54:05 +00001177 rc = sqlite3_step(pSelect);
1178 }
drh2f464a02011-10-13 00:41:49 +00001179 rc = sqlite3_finalize(pSelect);
1180 if( rc!=SQLITE_OK ){
1181 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001182 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001183 }
1184 return rc;
drhdd3d4592004-08-30 01:54:05 +00001185}
1186
shane626a6e42009-10-22 17:30:15 +00001187/*
1188** Allocate space and save off current error string.
1189*/
1190static char *save_err_msg(
1191 sqlite3 *db /* Database to query */
1192){
1193 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001194 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001195 if( zErrMsg ){
1196 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1197 }
1198 return zErrMsg;
1199}
1200
1201/*
shaneh642d8b82010-07-28 16:05:34 +00001202** Display memory stats.
1203*/
1204static int display_stats(
1205 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001206 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001207 int bReset /* True to reset the stats */
1208){
1209 int iCur;
1210 int iHiwtr;
1211
1212 if( pArg && pArg->out ){
1213
1214 iHiwtr = iCur = -1;
1215 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001216 fprintf(pArg->out,
1217 "Memory Used: %d (max %d) bytes\n",
1218 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001219 iHiwtr = iCur = -1;
1220 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001221 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1222 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001223 if( pArg->shellFlgs & SHFLG_Pagecache ){
1224 iHiwtr = iCur = -1;
1225 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001226 fprintf(pArg->out,
1227 "Number of Pcache Pages Used: %d (max %d) pages\n",
1228 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001229 }
shaneh642d8b82010-07-28 16:05:34 +00001230 iHiwtr = iCur = -1;
1231 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001232 fprintf(pArg->out,
1233 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1234 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001235 if( pArg->shellFlgs & SHFLG_Scratch ){
1236 iHiwtr = iCur = -1;
1237 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001238 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1239 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001240 }
shaneh642d8b82010-07-28 16:05:34 +00001241 iHiwtr = iCur = -1;
1242 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001243 fprintf(pArg->out,
1244 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1245 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001246 iHiwtr = iCur = -1;
1247 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001248 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1249 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001250 iHiwtr = iCur = -1;
1251 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001252 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1253 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001254 iHiwtr = iCur = -1;
1255 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001256 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1257 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001258#ifdef YYTRACKMAXSTACKDEPTH
1259 iHiwtr = iCur = -1;
1260 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001261 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1262 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001263#endif
1264 }
1265
1266 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001267 if( pArg->shellFlgs & SHFLG_Lookaside ){
1268 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001269 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1270 &iCur, &iHiwtr, bReset);
1271 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1272 iCur, iHiwtr);
1273 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1274 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001275 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001276 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1277 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001278 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001279 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1280 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001281 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1282 }
shaneh642d8b82010-07-28 16:05:34 +00001283 iHiwtr = iCur = -1;
1284 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001285 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1286 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001287 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1288 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1289 iHiwtr = iCur = -1;
1290 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1291 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001292 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001293 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1294 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1295 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001296 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001297 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001298 iHiwtr = iCur = -1;
1299 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001300 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001301 }
1302
1303 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001304 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1305 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001306 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1307 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1308 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001309 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001310 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001311 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1312 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001313 }
1314
1315 return 0;
1316}
1317
1318/*
dan8d1edb92014-11-05 09:07:28 +00001319** Display scan stats.
1320*/
1321static void display_scanstats(
1322 sqlite3 *db, /* Database to query */
1323 ShellState *pArg /* Pointer to ShellState */
1324){
1325#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001326 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001327 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001328 mx = 0;
1329 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001330 double rEstLoop = 1.0;
1331 for(i=n=0; 1; i++){
1332 sqlite3_stmt *p = pArg->pStmt;
1333 sqlite3_int64 nLoop, nVisit;
1334 double rEst;
1335 int iSid;
1336 const char *zExplain;
1337 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1338 break;
1339 }
1340 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001341 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001342 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001343 if( n==0 ){
1344 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001345 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001346 }
drh42f30bc2014-11-06 12:08:21 +00001347 n++;
1348 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1349 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1350 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1351 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1352 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001353 fprintf(pArg->out,
1354 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001355 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001356 );
dan8d1edb92014-11-05 09:07:28 +00001357 }
dan8d1edb92014-11-05 09:07:28 +00001358 }
dan8d1edb92014-11-05 09:07:28 +00001359 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001360#endif
dan8d1edb92014-11-05 09:07:28 +00001361}
1362
1363/*
dana98bf362013-11-13 18:35:01 +00001364** Parameter azArray points to a zero-terminated array of strings. zStr
1365** points to a single nul-terminated string. Return non-zero if zStr
1366** is equal, according to strcmp(), to any of the strings in the array.
1367** Otherwise, return zero.
1368*/
1369static int str_in_array(const char *zStr, const char **azArray){
1370 int i;
1371 for(i=0; azArray[i]; i++){
1372 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1373 }
1374 return 0;
1375}
1376
1377/*
1378** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001379** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001380** spaces each opcode should be indented before it is output.
1381**
1382** The indenting rules are:
1383**
1384** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1385** all opcodes that occur between the p2 jump destination and the opcode
1386** itself by 2 spaces.
1387**
drh01752bc2013-11-14 23:59:33 +00001388** * For each "Goto", if the jump destination is earlier in the program
1389** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001390** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001391** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001392** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001393** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001394*/
drhdcd87a92014-08-18 13:45:42 +00001395static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001396 const char *zSql; /* The text of the SQL statement */
1397 const char *z; /* Used to check if this is an EXPLAIN */
1398 int *abYield = 0; /* True if op is an OP_Yield */
1399 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001400 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001401
drh8ad0de32014-03-20 18:45:27 +00001402 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1403 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001404 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1405 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001406 const char *azGoto[] = { "Goto", 0 };
1407
1408 /* Try to figure out if this is really an EXPLAIN statement. If this
1409 ** cannot be verified, return early. */
1410 zSql = sqlite3_sql(pSql);
1411 if( zSql==0 ) return;
1412 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1413 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1414
1415 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1416 int i;
danc4650bb2013-11-18 08:41:06 +00001417 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001418 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001419
1420 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1421 ** p2 is an instruction address, set variable p2op to the index of that
1422 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1423 ** the current instruction is part of a sub-program generated by an
1424 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001425 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001426 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001427
1428 /* Grow the p->aiIndent array as required */
1429 if( iOp>=nAlloc ){
1430 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001431 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1432 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001433 }
1434 abYield[iOp] = str_in_array(zOp, azYield);
1435 p->aiIndent[iOp] = 0;
1436 p->nIndent = iOp+1;
1437
1438 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001439 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001440 }
drhfe705102014-03-06 13:38:37 +00001441 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1442 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1443 ){
drhe73f0592014-01-21 22:25:45 +00001444 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001445 }
1446 }
1447
danc4650bb2013-11-18 08:41:06 +00001448 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001449 sqlite3_free(abYield);
1450 sqlite3_reset(pSql);
1451}
1452
1453/*
1454** Free the array allocated by explain_data_prepare().
1455*/
drhdcd87a92014-08-18 13:45:42 +00001456static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001457 sqlite3_free(p->aiIndent);
1458 p->aiIndent = 0;
1459 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001460 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001461}
1462
1463/*
shane626a6e42009-10-22 17:30:15 +00001464** Execute a statement or set of statements. Print
1465** any result rows/columns depending on the current mode
1466** set via the supplied callback.
1467**
1468** This is very similar to SQLite's built-in sqlite3_exec()
1469** function except it takes a slightly different callback
1470** and callback data argument.
1471*/
1472static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001473 sqlite3 *db, /* An open database */
1474 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001475 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001476 /* (not the same as sqlite3_exec) */
1477 ShellState *pArg, /* Pointer to ShellState */
1478 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001479){
dan4564ced2010-01-05 04:59:56 +00001480 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1481 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001482 int rc2;
dan4564ced2010-01-05 04:59:56 +00001483 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001484
1485 if( pzErrMsg ){
1486 *pzErrMsg = NULL;
1487 }
1488
shaneb9fc17d2009-10-22 21:23:35 +00001489 while( zSql[0] && (SQLITE_OK == rc) ){
1490 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1491 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001492 if( pzErrMsg ){
1493 *pzErrMsg = save_err_msg(db);
1494 }
1495 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001496 if( !pStmt ){
1497 /* this happens for a comment or white-space */
1498 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001499 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001500 continue;
1501 }
shane626a6e42009-10-22 17:30:15 +00001502
shaneh642d8b82010-07-28 16:05:34 +00001503 /* save off the prepared statment handle and reset row count */
1504 if( pArg ){
1505 pArg->pStmt = pStmt;
1506 pArg->cnt = 0;
1507 }
1508
shanehb7977c52010-01-18 18:17:10 +00001509 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001510 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001511 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001512 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001513 }
shanehb7977c52010-01-18 18:17:10 +00001514
drhefbf3b12014-02-28 20:47:24 +00001515 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1516 if( pArg && pArg->autoEQP ){
1517 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001518 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1519 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001520 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1521 if( rc==SQLITE_OK ){
1522 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1523 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1524 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1525 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1526 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1527 }
1528 }
1529 sqlite3_finalize(pExplain);
1530 sqlite3_free(zEQP);
1531 }
1532
dana98bf362013-11-13 18:35:01 +00001533 /* If the shell is currently in ".explain" mode, gather the extra
1534 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001535 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001536 explain_data_prepare(pArg, pStmt);
1537 }
1538
shaneb9fc17d2009-10-22 21:23:35 +00001539 /* perform the first step. this will tell us if we
1540 ** have a result set or not and how wide it is.
1541 */
1542 rc = sqlite3_step(pStmt);
1543 /* if we have a result set... */
1544 if( SQLITE_ROW == rc ){
1545 /* if we have a callback... */
1546 if( xCallback ){
1547 /* allocate space for col name ptr, value ptr, and type */
1548 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001549 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001550 if( !pData ){
1551 rc = SQLITE_NOMEM;
1552 }else{
1553 char **azCols = (char **)pData; /* Names of result columns */
1554 char **azVals = &azCols[nCol]; /* Results */
1555 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001556 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001557 assert(sizeof(int) <= sizeof(char *));
1558 /* save off ptrs to column names */
1559 for(i=0; i<nCol; i++){
1560 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1561 }
shaneb9fc17d2009-10-22 21:23:35 +00001562 do{
1563 /* extract the data and data types */
1564 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001565 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001566 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001567 azVals[i] = "";
1568 }else{
1569 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1570 }
shaneb9fc17d2009-10-22 21:23:35 +00001571 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1572 rc = SQLITE_NOMEM;
1573 break; /* from for */
1574 }
1575 } /* end for */
1576
1577 /* if data and types extracted successfully... */
1578 if( SQLITE_ROW == rc ){
1579 /* call the supplied callback with the result row data */
1580 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1581 rc = SQLITE_ABORT;
1582 }else{
1583 rc = sqlite3_step(pStmt);
1584 }
1585 }
1586 } while( SQLITE_ROW == rc );
1587 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001588 }
1589 }else{
1590 do{
1591 rc = sqlite3_step(pStmt);
1592 } while( rc == SQLITE_ROW );
1593 }
1594 }
1595
dana98bf362013-11-13 18:35:01 +00001596 explain_data_delete(pArg);
1597
shaneh642d8b82010-07-28 16:05:34 +00001598 /* print usage stats if stats on */
1599 if( pArg && pArg->statsOn ){
1600 display_stats(db, pArg, 0);
1601 }
1602
dan8d1edb92014-11-05 09:07:28 +00001603 /* print loop-counters if required */
1604 if( pArg && pArg->scanstatsOn ){
1605 display_scanstats(db, pArg);
1606 }
1607
dan4564ced2010-01-05 04:59:56 +00001608 /* Finalize the statement just executed. If this fails, save a
1609 ** copy of the error message. Otherwise, set zSql to point to the
1610 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001611 rc2 = sqlite3_finalize(pStmt);
1612 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001613 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001614 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001615 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001616 }else if( pzErrMsg ){
1617 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001618 }
shaneh642d8b82010-07-28 16:05:34 +00001619
1620 /* clear saved stmt handle */
1621 if( pArg ){
1622 pArg->pStmt = NULL;
1623 }
shane626a6e42009-10-22 17:30:15 +00001624 }
shaneb9fc17d2009-10-22 21:23:35 +00001625 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001626
1627 return rc;
1628}
1629
drhdd3d4592004-08-30 01:54:05 +00001630
drh33048c02001-10-01 14:29:22 +00001631/*
drh4c653a02000-06-07 01:27:47 +00001632** This is a different callback routine used for dumping the database.
1633** Each row received by this callback consists of a table name,
1634** the table type ("index" or "table") and SQL to create the table.
1635** This routine should print text sufficient to recreate the table.
1636*/
1637static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001638 int rc;
1639 const char *zTable;
1640 const char *zType;
1641 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001642 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001643 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001644
drh902b9ee2008-12-05 17:17:07 +00001645 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001646 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001647 zTable = azArg[0];
1648 zType = azArg[1];
1649 zSql = azArg[2];
1650
drh00b950d2005-09-11 02:03:03 +00001651 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001652 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001653 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001654 fprintf(p->out, "ANALYZE sqlite_master;\n");
1655 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1656 return 0;
drh45e29d82006-11-20 16:21:10 +00001657 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1658 char *zIns;
1659 if( !p->writableSchema ){
1660 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1661 p->writableSchema = 1;
1662 }
1663 zIns = sqlite3_mprintf(
1664 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1665 "VALUES('table','%q','%q',0,'%q');",
1666 zTable, zTable, zSql);
1667 fprintf(p->out, "%s\n", zIns);
1668 sqlite3_free(zIns);
1669 return 0;
drh00b950d2005-09-11 02:03:03 +00001670 }else{
1671 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001672 }
danielk19772a02e332004-06-05 08:04:36 +00001673
1674 if( strcmp(zType, "table")==0 ){
1675 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001676 char *zSelect = 0;
1677 char *zTableInfo = 0;
1678 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001679 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001680
1681 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1682 zTableInfo = appendText(zTableInfo, zTable, '"');
1683 zTableInfo = appendText(zTableInfo, ");", 0);
1684
drhc7181902014-02-27 15:04:13 +00001685 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001686 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001687 if( rc!=SQLITE_OK || !pTableInfo ){
1688 return 1;
1689 }
1690
1691 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001692 /* Always quote the table name, even if it appears to be pure ascii,
1693 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1694 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001695 if( zTmp ){
1696 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001697 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001698 }
1699 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1700 rc = sqlite3_step(pTableInfo);
1701 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001702 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001703 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001704 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001705 rc = sqlite3_step(pTableInfo);
1706 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001707 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001708 }else{
1709 zSelect = appendText(zSelect, ") ", 0);
1710 }
drh157e29a2009-05-21 15:15:00 +00001711 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001712 }
1713 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001714 if( rc!=SQLITE_OK || nRow==0 ){
1715 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001716 return 1;
1717 }
1718 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1719 zSelect = appendText(zSelect, zTable, '"');
1720
drh2f464a02011-10-13 00:41:49 +00001721 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001722 if( rc==SQLITE_CORRUPT ){
1723 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001724 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001725 }
drh85e72432012-04-11 11:38:53 +00001726 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001727 }
drh4c653a02000-06-07 01:27:47 +00001728 return 0;
1729}
1730
1731/*
drh45e29d82006-11-20 16:21:10 +00001732** Run zQuery. Use dump_callback() as the callback routine so that
1733** the contents of the query are output as SQL statements.
1734**
drhdd3d4592004-08-30 01:54:05 +00001735** If we get a SQLITE_CORRUPT error, rerun the query after appending
1736** "ORDER BY rowid DESC" to the end.
1737*/
1738static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001739 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001740 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001741){
1742 int rc;
drh2f464a02011-10-13 00:41:49 +00001743 char *zErr = 0;
1744 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001745 if( rc==SQLITE_CORRUPT ){
1746 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001747 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001748 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1749 if( zErr ){
1750 fprintf(p->out, "/****** %s ******/\n", zErr);
1751 sqlite3_free(zErr);
1752 zErr = 0;
1753 }
drhdd3d4592004-08-30 01:54:05 +00001754 zQ2 = malloc( len+100 );
1755 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001756 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001757 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1758 if( rc ){
1759 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1760 }else{
1761 rc = SQLITE_CORRUPT;
1762 }
1763 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001764 free(zQ2);
1765 }
1766 return rc;
1767}
1768
1769/*
drh75897232000-05-29 14:26:00 +00001770** Text of a help message
1771*/
persicom1d0b8722002-04-18 02:53:04 +00001772static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001773 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001774 ".bail on|off Stop after hitting an error. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001775 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001776 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001777 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001778 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001779 " If TABLE specified, only dump tables matching\n"
1780 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001781 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001782 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001783 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001784 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001785 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001786 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001787 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001788 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001789 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001790 ".indexes ?TABLE? Show names of all indexes\n"
1791 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001792 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001793#ifdef SQLITE_ENABLE_IOTRACE
1794 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1795#endif
drh1a513372015-05-02 17:40:23 +00001796 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001797#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001798 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001799#endif
drh127f9d72010-02-23 01:47:00 +00001800 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001801 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001802 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001803 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001804 " column Left-aligned columns. (See .width)\n"
1805 " html HTML <table> code\n"
1806 " insert SQL insert statements for TABLE\n"
1807 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001808 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001809 " tabs Tab-separated values\n"
1810 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001811 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001812 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001813 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001814 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001815 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001816 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001817 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001818 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001819 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001820 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001821 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001822 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001823 " If TABLE specified, only show tables matching\n"
1824 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001825 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1826 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001827 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001828 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001829 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001830 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001831 ".tables ?TABLE? List names of tables\n"
1832 " If TABLE specified, only list tables matching\n"
1833 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001834 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001835 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001836 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001837 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001838 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001839 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001840;
1841
drhdaffd0e2001-04-11 14:28:42 +00001842/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001843static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001844/*
1845** Implementation of the "readfile(X)" SQL function. The entire content
1846** of the file named X is read and returned as a BLOB. NULL is returned
1847** if the file does not exist or is unreadable.
1848*/
1849static void readfileFunc(
1850 sqlite3_context *context,
1851 int argc,
1852 sqlite3_value **argv
1853){
1854 const char *zName;
1855 FILE *in;
1856 long nIn;
1857 void *pBuf;
1858
1859 zName = (const char*)sqlite3_value_text(argv[0]);
1860 if( zName==0 ) return;
1861 in = fopen(zName, "rb");
1862 if( in==0 ) return;
1863 fseek(in, 0, SEEK_END);
1864 nIn = ftell(in);
1865 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00001866 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00001867 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1868 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1869 }else{
1870 sqlite3_free(pBuf);
1871 }
1872 fclose(in);
1873}
1874
1875/*
1876** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1877** is written into file X. The number of bytes written is returned. Or
1878** NULL is returned if something goes wrong, such as being unable to open
1879** file X for writing.
1880*/
1881static void writefileFunc(
1882 sqlite3_context *context,
1883 int argc,
1884 sqlite3_value **argv
1885){
1886 FILE *out;
1887 const char *z;
drhba5b0932014-07-24 12:39:59 +00001888 sqlite3_int64 rc;
1889 const char *zFile;
1890
1891 zFile = (const char*)sqlite3_value_text(argv[0]);
1892 if( zFile==0 ) return;
1893 out = fopen(zFile, "wb");
1894 if( out==0 ) return;
1895 z = (const char*)sqlite3_value_blob(argv[1]);
1896 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001897 rc = 0;
1898 }else{
drh490fe862014-08-11 14:21:32 +00001899 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001900 }
1901 fclose(out);
1902 sqlite3_result_int64(context, rc);
1903}
drhdaffd0e2001-04-11 14:28:42 +00001904
drh75897232000-05-29 14:26:00 +00001905/*
drh44c2eb12003-04-30 11:38:26 +00001906** Make sure the database is open. If it is not, then open it. If
1907** the database fails to open, print an error message and exit.
1908*/
drhdcd87a92014-08-18 13:45:42 +00001909static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001910 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001911 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001912 sqlite3_open(p->zDbFilename, &p->db);
drh6296a2a2015-04-30 20:35:33 +00001913#ifdef SQLITE_ENABLE_STAT_VTAB
drh06d83372015-04-28 12:27:22 +00001914 if( p->db ){
1915 int sqlite3_dbstat_register(sqlite3*);
1916 sqlite3_dbstat_register(p->db);
1917 }
1918#endif
mistachkin8e189222015-04-19 21:43:16 +00001919 globalDb = p->db;
1920 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
1921 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00001922 shellstaticFunc, 0, 0);
1923 }
mistachkin8e189222015-04-19 21:43:16 +00001924 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
shane86f5bdb2009-10-24 02:00:07 +00001925 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00001926 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00001927 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001928 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001929 }
drhc2e87a32006-06-27 15:16:14 +00001930#ifndef SQLITE_OMIT_LOAD_EXTENSION
1931 sqlite3_enable_load_extension(p->db, 1);
1932#endif
mistachkin8e189222015-04-19 21:43:16 +00001933 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001934 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00001935 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001936 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001937 }
1938}
1939
1940/*
drhfeac5f82004-08-01 00:10:45 +00001941** Do C-language style dequoting.
1942**
1943** \t -> tab
1944** \n -> newline
1945** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001946** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001947** \NNN -> ascii character NNN in octal
1948** \\ -> backslash
1949*/
1950static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001951 int i, j;
1952 char c;
drhc2ce0be2014-05-29 12:36:14 +00001953 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001954 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00001955 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00001956 c = z[++i];
1957 if( c=='n' ){
1958 c = '\n';
1959 }else if( c=='t' ){
1960 c = '\t';
1961 }else if( c=='r' ){
1962 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001963 }else if( c=='\\' ){
1964 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001965 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001966 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001967 if( z[i+1]>='0' && z[i+1]<='7' ){
1968 i++;
1969 c = (c<<3) + z[i] - '0';
1970 if( z[i+1]>='0' && z[i+1]<='7' ){
1971 i++;
1972 c = (c<<3) + z[i] - '0';
1973 }
1974 }
1975 }
1976 }
1977 z[j] = c;
1978 }
drhc2ce0be2014-05-29 12:36:14 +00001979 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001980}
1981
1982/*
drh348d19c2013-06-03 12:47:43 +00001983** Return the value of a hexadecimal digit. Return -1 if the input
1984** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001985*/
drh348d19c2013-06-03 12:47:43 +00001986static int hexDigitValue(char c){
1987 if( c>='0' && c<='9' ) return c - '0';
1988 if( c>='a' && c<='f' ) return c - 'a' + 10;
1989 if( c>='A' && c<='F' ) return c - 'A' + 10;
1990 return -1;
drhc28490c2006-10-26 14:25:58 +00001991}
1992
1993/*
drh7d9f3942013-04-03 01:26:54 +00001994** Interpret zArg as an integer value, possibly with suffixes.
1995*/
1996static sqlite3_int64 integerValue(const char *zArg){
1997 sqlite3_int64 v = 0;
1998 static const struct { char *zSuffix; int iMult; } aMult[] = {
1999 { "KiB", 1024 },
2000 { "MiB", 1024*1024 },
2001 { "GiB", 1024*1024*1024 },
2002 { "KB", 1000 },
2003 { "MB", 1000000 },
2004 { "GB", 1000000000 },
2005 { "K", 1000 },
2006 { "M", 1000000 },
2007 { "G", 1000000000 },
2008 };
2009 int i;
2010 int isNeg = 0;
2011 if( zArg[0]=='-' ){
2012 isNeg = 1;
2013 zArg++;
2014 }else if( zArg[0]=='+' ){
2015 zArg++;
2016 }
drh348d19c2013-06-03 12:47:43 +00002017 if( zArg[0]=='0' && zArg[1]=='x' ){
2018 int x;
2019 zArg += 2;
2020 while( (x = hexDigitValue(zArg[0]))>=0 ){
2021 v = (v<<4) + x;
2022 zArg++;
2023 }
2024 }else{
2025 while( IsDigit(zArg[0]) ){
2026 v = v*10 + zArg[0] - '0';
2027 zArg++;
2028 }
drh7d9f3942013-04-03 01:26:54 +00002029 }
drhc2bed0a2013-05-24 11:57:50 +00002030 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002031 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2032 v *= aMult[i].iMult;
2033 break;
2034 }
2035 }
2036 return isNeg? -v : v;
2037}
2038
2039/*
drh348d19c2013-06-03 12:47:43 +00002040** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2041** for TRUE and FALSE. Return the integer value if appropriate.
2042*/
2043static int booleanValue(char *zArg){
2044 int i;
2045 if( zArg[0]=='0' && zArg[1]=='x' ){
2046 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2047 }else{
2048 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2049 }
2050 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2051 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2052 return 1;
2053 }
2054 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2055 return 0;
2056 }
2057 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2058 zArg);
2059 return 0;
2060}
2061
2062/*
drh42f64e52012-04-04 16:56:23 +00002063** Close an output file, assuming it is not stderr or stdout
2064*/
2065static void output_file_close(FILE *f){
2066 if( f && f!=stdout && f!=stderr ) fclose(f);
2067}
2068
2069/*
2070** Try to open an output file. The names "stdout" and "stderr" are
2071** recognized and do the right thing. NULL is returned if the output
2072** filename is "off".
2073*/
2074static FILE *output_file_open(const char *zFile){
2075 FILE *f;
2076 if( strcmp(zFile,"stdout")==0 ){
2077 f = stdout;
2078 }else if( strcmp(zFile, "stderr")==0 ){
2079 f = stderr;
2080 }else if( strcmp(zFile, "off")==0 ){
2081 f = 0;
2082 }else{
2083 f = fopen(zFile, "wb");
2084 if( f==0 ){
2085 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2086 }
2087 }
2088 return f;
2089}
2090
2091/*
2092** A routine for handling output from sqlite3_trace().
2093*/
2094static void sql_trace_callback(void *pArg, const char *z){
2095 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002096 if( f ){
2097 int i = (int)strlen(z);
2098 while( i>0 && z[i-1]==';' ){ i--; }
2099 fprintf(f, "%.*s;\n", i, z);
2100 }
drh42f64e52012-04-04 16:56:23 +00002101}
2102
2103/*
drhd8621b92012-04-17 09:09:33 +00002104** A no-op routine that runs with the ".breakpoint" doc-command. This is
2105** a useful spot to set a debugger breakpoint.
2106*/
2107static void test_breakpoint(void){
2108 static int nCall = 0;
2109 nCall++;
2110}
2111
2112/*
mistachkin636bf9f2014-07-19 20:15:16 +00002113** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002114*/
mistachkin636bf9f2014-07-19 20:15:16 +00002115typedef struct ImportCtx ImportCtx;
2116struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002117 const char *zFile; /* Name of the input file */
2118 FILE *in; /* Read the CSV text from this input stream */
2119 char *z; /* Accumulated text for a field */
2120 int n; /* Number of bytes in z */
2121 int nAlloc; /* Space allocated for z[] */
2122 int nLine; /* Current line number */
2123 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002124 int cColSep; /* The column separator character. (Usually ",") */
2125 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002126};
2127
2128/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002129static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002130 if( p->n+1>=p->nAlloc ){
2131 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002132 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002133 if( p->z==0 ){
2134 fprintf(stderr, "out of memory\n");
2135 exit(1);
2136 }
2137 }
2138 p->z[p->n++] = (char)c;
2139}
2140
2141/* Read a single field of CSV text. Compatible with rfc4180 and extended
2142** with the option of having a separator other than ",".
2143**
2144** + Input comes from p->in.
2145** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002146** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002147** + Use p->cSep as the column separator. The default is ",".
2148** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002149** + Keep track of the line number in p->nLine.
2150** + Store the character that terminates the field in p->cTerm. Store
2151** EOF on end-of-file.
2152** + Report syntax errors on stderr
2153*/
mistachkin44723ce2015-03-21 02:22:37 +00002154static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002155 int c;
2156 int cSep = p->cColSep;
2157 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002158 p->n = 0;
2159 c = fgetc(p->in);
2160 if( c==EOF || seenInterrupt ){
2161 p->cTerm = EOF;
2162 return 0;
2163 }
2164 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002165 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002166 int startLine = p->nLine;
2167 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002168 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002169 while( 1 ){
2170 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002171 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002172 if( c==cQuote ){
2173 if( pc==cQuote ){
2174 pc = 0;
2175 continue;
2176 }
2177 }
2178 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002179 || (c==rSep && pc==cQuote)
2180 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002181 || (c==EOF && pc==cQuote)
2182 ){
2183 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002184 p->cTerm = c;
2185 break;
2186 }
2187 if( pc==cQuote && c!='\r' ){
2188 fprintf(stderr, "%s:%d: unescaped %c character\n",
2189 p->zFile, p->nLine, cQuote);
2190 }
2191 if( c==EOF ){
2192 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2193 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002194 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002195 break;
2196 }
mistachkin636bf9f2014-07-19 20:15:16 +00002197 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002198 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002199 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002200 }
drhdb95f682013-06-26 22:46:00 +00002201 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002202 while( c!=EOF && c!=cSep && c!=rSep ){
2203 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002204 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002205 }
mistachkin636bf9f2014-07-19 20:15:16 +00002206 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002207 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002208 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002209 }
drhdb95f682013-06-26 22:46:00 +00002210 p->cTerm = c;
2211 }
drh8dd675e2013-07-12 21:09:24 +00002212 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002213 return p->z;
2214}
2215
mistachkin636bf9f2014-07-19 20:15:16 +00002216/* Read a single field of ASCII delimited text.
2217**
2218** + Input comes from p->in.
2219** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002220** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002221** + Use p->cSep as the column separator. The default is "\x1F".
2222** + Use p->rSep as the row separator. The default is "\x1E".
2223** + Keep track of the row number in p->nLine.
2224** + Store the character that terminates the field in p->cTerm. Store
2225** EOF on end-of-file.
2226** + Report syntax errors on stderr
2227*/
mistachkin44723ce2015-03-21 02:22:37 +00002228static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002229 int c;
2230 int cSep = p->cColSep;
2231 int rSep = p->cRowSep;
2232 p->n = 0;
2233 c = fgetc(p->in);
2234 if( c==EOF || seenInterrupt ){
2235 p->cTerm = EOF;
2236 return 0;
2237 }
2238 while( c!=EOF && c!=cSep && c!=rSep ){
2239 import_append_char(p, c);
2240 c = fgetc(p->in);
2241 }
2242 if( c==rSep ){
2243 p->nLine++;
2244 }
2245 p->cTerm = c;
2246 if( p->z ) p->z[p->n] = 0;
2247 return p->z;
2248}
2249
drhdb95f682013-06-26 22:46:00 +00002250/*
drh4bbcf102014-02-06 02:46:08 +00002251** Try to transfer data for table zTable. If an error is seen while
2252** moving forward, try to go backwards. The backwards movement won't
2253** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002254*/
mistachkine31ae902014-02-06 01:15:29 +00002255static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002256 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002257 sqlite3 *newDb,
2258 const char *zTable
2259){
2260 sqlite3_stmt *pQuery = 0;
2261 sqlite3_stmt *pInsert = 0;
2262 char *zQuery = 0;
2263 char *zInsert = 0;
2264 int rc;
2265 int i, j, n;
2266 int nTable = (int)strlen(zTable);
2267 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002268 int cnt = 0;
2269 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002270
2271 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2272 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2273 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002274 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002275 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2276 zQuery);
2277 goto end_data_xfer;
2278 }
2279 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002280 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002281 if( zInsert==0 ){
2282 fprintf(stderr, "out of memory\n");
2283 goto end_data_xfer;
2284 }
2285 sqlite3_snprintf(200+nTable,zInsert,
2286 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2287 i = (int)strlen(zInsert);
2288 for(j=1; j<n; j++){
2289 memcpy(zInsert+i, ",?", 2);
2290 i += 2;
2291 }
2292 memcpy(zInsert+i, ");", 3);
2293 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2294 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002295 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002296 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2297 zQuery);
2298 goto end_data_xfer;
2299 }
2300 for(k=0; k<2; k++){
2301 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2302 for(i=0; i<n; i++){
2303 switch( sqlite3_column_type(pQuery, i) ){
2304 case SQLITE_NULL: {
2305 sqlite3_bind_null(pInsert, i+1);
2306 break;
2307 }
2308 case SQLITE_INTEGER: {
2309 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2310 break;
2311 }
2312 case SQLITE_FLOAT: {
2313 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2314 break;
2315 }
2316 case SQLITE_TEXT: {
2317 sqlite3_bind_text(pInsert, i+1,
2318 (const char*)sqlite3_column_text(pQuery,i),
2319 -1, SQLITE_STATIC);
2320 break;
2321 }
2322 case SQLITE_BLOB: {
2323 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2324 sqlite3_column_bytes(pQuery,i),
2325 SQLITE_STATIC);
2326 break;
2327 }
2328 }
2329 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002330 rc = sqlite3_step(pInsert);
2331 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2332 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2333 sqlite3_errmsg(newDb));
2334 }
drh3350ce92014-02-06 00:49:12 +00002335 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002336 cnt++;
2337 if( (cnt%spinRate)==0 ){
2338 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2339 fflush(stdout);
2340 }
drh3350ce92014-02-06 00:49:12 +00002341 } /* End while */
2342 if( rc==SQLITE_DONE ) break;
2343 sqlite3_finalize(pQuery);
2344 sqlite3_free(zQuery);
2345 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2346 zTable);
2347 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2348 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002349 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2350 break;
drh3350ce92014-02-06 00:49:12 +00002351 }
2352 } /* End for(k=0...) */
2353
2354end_data_xfer:
2355 sqlite3_finalize(pQuery);
2356 sqlite3_finalize(pInsert);
2357 sqlite3_free(zQuery);
2358 sqlite3_free(zInsert);
2359}
2360
2361
2362/*
2363** Try to transfer all rows of the schema that match zWhere. For
2364** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002365** If an error is encountered while moving forward through the
2366** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002367*/
mistachkine31ae902014-02-06 01:15:29 +00002368static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002369 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002370 sqlite3 *newDb,
2371 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002372 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002373){
2374 sqlite3_stmt *pQuery = 0;
2375 char *zQuery = 0;
2376 int rc;
2377 const unsigned char *zName;
2378 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002379 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002380
2381 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2382 " WHERE %s", zWhere);
2383 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2384 if( rc ){
2385 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2386 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2387 zQuery);
2388 goto end_schema_xfer;
2389 }
2390 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2391 zName = sqlite3_column_text(pQuery, 0);
2392 zSql = sqlite3_column_text(pQuery, 1);
2393 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002394 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2395 if( zErrMsg ){
2396 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2397 sqlite3_free(zErrMsg);
2398 zErrMsg = 0;
2399 }
drh3350ce92014-02-06 00:49:12 +00002400 if( xForEach ){
2401 xForEach(p, newDb, (const char*)zName);
2402 }
2403 printf("done\n");
2404 }
2405 if( rc!=SQLITE_DONE ){
2406 sqlite3_finalize(pQuery);
2407 sqlite3_free(zQuery);
2408 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2409 " WHERE %s ORDER BY rowid DESC", zWhere);
2410 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2411 if( rc ){
2412 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2413 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2414 zQuery);
2415 goto end_schema_xfer;
2416 }
2417 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2418 zName = sqlite3_column_text(pQuery, 0);
2419 zSql = sqlite3_column_text(pQuery, 1);
2420 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002421 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2422 if( zErrMsg ){
2423 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2424 sqlite3_free(zErrMsg);
2425 zErrMsg = 0;
2426 }
drh3350ce92014-02-06 00:49:12 +00002427 if( xForEach ){
2428 xForEach(p, newDb, (const char*)zName);
2429 }
2430 printf("done\n");
2431 }
2432 }
2433end_schema_xfer:
2434 sqlite3_finalize(pQuery);
2435 sqlite3_free(zQuery);
2436}
2437
2438/*
2439** Open a new database file named "zNewDb". Try to recover as much information
2440** as possible out of the main database (which might be corrupt) and write it
2441** into zNewDb.
2442*/
drhdcd87a92014-08-18 13:45:42 +00002443static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002444 int rc;
2445 sqlite3 *newDb = 0;
2446 if( access(zNewDb,0)==0 ){
2447 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2448 return;
2449 }
2450 rc = sqlite3_open(zNewDb, &newDb);
2451 if( rc ){
2452 fprintf(stderr, "Cannot create output database: %s\n",
2453 sqlite3_errmsg(newDb));
2454 }else{
drh54d0d2d2014-04-03 00:32:13 +00002455 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002456 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002457 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2458 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002459 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002460 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002461 }
2462 sqlite3_close(newDb);
2463}
2464
2465/*
drhc2ce0be2014-05-29 12:36:14 +00002466** Change the output file back to stdout
2467*/
drhdcd87a92014-08-18 13:45:42 +00002468static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002469 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002470#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002471 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002472#endif
drhc2ce0be2014-05-29 12:36:14 +00002473 }else{
2474 output_file_close(p->out);
2475 }
2476 p->outfile[0] = 0;
2477 p->out = stdout;
2478}
2479
2480/*
drhf7502f02015-02-06 14:19:44 +00002481** Run an SQL command and return the single integer result.
2482*/
2483static int db_int(ShellState *p, const char *zSql){
2484 sqlite3_stmt *pStmt;
2485 int res = 0;
2486 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2487 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2488 res = sqlite3_column_int(pStmt,0);
2489 }
2490 sqlite3_finalize(pStmt);
2491 return res;
2492}
2493
2494/*
2495** Convert a 2-byte or 4-byte big-endian integer into a native integer
2496*/
2497unsigned int get2byteInt(unsigned char *a){
2498 return (a[0]<<8) + a[1];
2499}
2500unsigned int get4byteInt(unsigned char *a){
2501 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2502}
2503
2504/*
2505** Implementation of the ".info" command.
2506**
2507** Return 1 on error, 2 to exit, and 0 otherwise.
2508*/
drh0e55db12015-02-06 14:51:13 +00002509static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002510 static const struct { const char *zName; int ofst; } aField[] = {
2511 { "file change counter:", 24 },
2512 { "database page count:", 28 },
2513 { "freelist page count:", 36 },
2514 { "schema cookie:", 40 },
2515 { "schema format:", 44 },
2516 { "default cache size:", 48 },
2517 { "autovacuum top root:", 52 },
2518 { "incremental vacuum:", 64 },
2519 { "text encoding:", 56 },
2520 { "user version:", 60 },
2521 { "application id:", 68 },
2522 { "software version:", 96 },
2523 };
drh0e55db12015-02-06 14:51:13 +00002524 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2525 { "number of tables:",
2526 "SELECT count(*) FROM %s WHERE type='table'" },
2527 { "number of indexes:",
2528 "SELECT count(*) FROM %s WHERE type='index'" },
2529 { "number of triggers:",
2530 "SELECT count(*) FROM %s WHERE type='trigger'" },
2531 { "number of views:",
2532 "SELECT count(*) FROM %s WHERE type='view'" },
2533 { "schema size:",
2534 "SELECT total(length(sql)) FROM %s" },
2535 };
2536 sqlite3_file *pFile;
2537 int i;
2538 char *zSchemaTab;
2539 char *zDb = nArg>=2 ? azArg[1] : "main";
2540 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002541 open_db(p, 0);
2542 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002543 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002544 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2545 return 1;
2546 }
2547 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2548 if( i!=SQLITE_OK ){
2549 fprintf(stderr, "unable to read database header\n");
2550 return 1;
2551 }
2552 i = get2byteInt(aHdr+16);
2553 if( i==1 ) i = 65536;
2554 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2555 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2556 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2557 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2558 for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
2559 int ofst = aField[i].ofst;
2560 unsigned int val = get4byteInt(aHdr + ofst);
2561 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2562 switch( ofst ){
2563 case 56: {
2564 if( val==1 ) fprintf(p->out, " (utf8)");
2565 if( val==2 ) fprintf(p->out, " (utf16le)");
2566 if( val==3 ) fprintf(p->out, " (utf16be)");
2567 }
2568 }
2569 fprintf(p->out, "\n");
2570 }
drh0e55db12015-02-06 14:51:13 +00002571 if( zDb==0 ){
2572 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2573 }else if( strcmp(zDb,"temp")==0 ){
2574 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2575 }else{
2576 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2577 }
2578 for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
2579 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2580 int val = db_int(p, zSql);
2581 sqlite3_free(zSql);
2582 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2583 }
2584 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002585 return 0;
2586}
2587
2588
2589/*
drh75897232000-05-29 14:26:00 +00002590** If an input line begins with "." then invoke this routine to
2591** process that line.
drh67505e72002-04-19 12:34:06 +00002592**
drh47ad6842006-11-08 12:25:42 +00002593** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002594*/
drhdcd87a92014-08-18 13:45:42 +00002595static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002596 int h = 1;
drh75897232000-05-29 14:26:00 +00002597 int nArg = 0;
2598 int n, c;
drh67505e72002-04-19 12:34:06 +00002599 int rc = 0;
drh75897232000-05-29 14:26:00 +00002600 char *azArg[50];
2601
2602 /* Parse the input line into tokens.
2603 */
mistachkin8e189222015-04-19 21:43:16 +00002604 while( zLine[h] && nArg<ArraySize(azArg) ){
2605 while( IsSpace(zLine[h]) ){ h++; }
2606 if( zLine[h]==0 ) break;
2607 if( zLine[h]=='\'' || zLine[h]=='"' ){
2608 int delim = zLine[h++];
2609 azArg[nArg++] = &zLine[h];
2610 while( zLine[h] && zLine[h]!=delim ){
2611 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2612 h++;
drh4c56b992013-06-27 13:26:55 +00002613 }
mistachkin8e189222015-04-19 21:43:16 +00002614 if( zLine[h]==delim ){
2615 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002616 }
drhfeac5f82004-08-01 00:10:45 +00002617 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002618 }else{
mistachkin8e189222015-04-19 21:43:16 +00002619 azArg[nArg++] = &zLine[h];
2620 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2621 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002622 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002623 }
2624 }
2625
2626 /* Process the input line.
2627 */
shane9bd1b442009-10-23 01:27:39 +00002628 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002629 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002630 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002631 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2632 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2633 ){
drhbc46f022013-01-23 18:53:23 +00002634 const char *zDestFile = 0;
2635 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002636 sqlite3 *pDest;
2637 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002638 int j;
2639 for(j=1; j<nArg; j++){
2640 const char *z = azArg[j];
2641 if( z[0]=='-' ){
2642 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002643 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002644 {
2645 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2646 return 1;
2647 }
2648 }else if( zDestFile==0 ){
2649 zDestFile = azArg[j];
2650 }else if( zDb==0 ){
2651 zDb = zDestFile;
2652 zDestFile = azArg[j];
2653 }else{
2654 fprintf(stderr, "too many arguments to .backup\n");
2655 return 1;
2656 }
drh9ff849f2009-02-04 20:55:57 +00002657 }
drhbc46f022013-01-23 18:53:23 +00002658 if( zDestFile==0 ){
2659 fprintf(stderr, "missing FILENAME argument on .backup\n");
2660 return 1;
2661 }
2662 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002663 rc = sqlite3_open(zDestFile, &pDest);
2664 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002665 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002666 sqlite3_close(pDest);
2667 return 1;
2668 }
drh05782482013-10-24 15:20:20 +00002669 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002670 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2671 if( pBackup==0 ){
2672 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2673 sqlite3_close(pDest);
2674 return 1;
2675 }
2676 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2677 sqlite3_backup_finish(pBackup);
2678 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002679 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002680 }else{
2681 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002682 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002683 }
2684 sqlite3_close(pDest);
2685 }else
2686
drhc2ce0be2014-05-29 12:36:14 +00002687 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2688 if( nArg==2 ){
2689 bail_on_error = booleanValue(azArg[1]);
2690 }else{
2691 fprintf(stderr, "Usage: .bail on|off\n");
2692 rc = 1;
2693 }
drhc49f44e2006-10-26 18:15:42 +00002694 }else
2695
drhd8621b92012-04-17 09:09:33 +00002696 /* The undocumented ".breakpoint" command causes a call to the no-op
2697 ** routine named test_breakpoint().
2698 */
2699 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2700 test_breakpoint();
2701 }else
2702
drhc2ce0be2014-05-29 12:36:14 +00002703 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2704 if( nArg==2 ){
2705 tryToClone(p, azArg[1]);
2706 }else{
2707 fprintf(stderr, "Usage: .clone FILENAME\n");
2708 rc = 1;
2709 }
mistachkine31ae902014-02-06 01:15:29 +00002710 }else
2711
drhc2ce0be2014-05-29 12:36:14 +00002712 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002713 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002714 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002715 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002716 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002717 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002718 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002719 data.colWidth[0] = 3;
2720 data.colWidth[1] = 15;
2721 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002722 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002723 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002724 if( zErrMsg ){
2725 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002726 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002727 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002728 }
2729 }else
2730
drh0e55db12015-02-06 14:51:13 +00002731 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2732 rc = shell_dbinfo_command(p, nArg, azArg);
2733 }else
2734
drhc2ce0be2014-05-29 12:36:14 +00002735 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002736 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002737 /* When playing back a "dump", the content might appear in an order
2738 ** which causes immediate foreign key constraints to be violated.
2739 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002740 if( nArg!=1 && nArg!=2 ){
2741 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2742 rc = 1;
2743 goto meta_command_exit;
2744 }
drhf1dfc4f2009-09-23 15:51:35 +00002745 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002746 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002747 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002748 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002749 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002750 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002751 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002752 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002753 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002754 );
2755 run_schema_dump_query(p,
2756 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002757 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002758 );
drh2f464a02011-10-13 00:41:49 +00002759 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002760 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002761 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002762 );
drh4c653a02000-06-07 01:27:47 +00002763 }else{
2764 int i;
drhdd3d4592004-08-30 01:54:05 +00002765 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002766 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002767 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002768 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002769 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002770 " AND sql NOT NULL");
2771 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002772 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002773 "WHERE sql NOT NULL"
2774 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002775 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002776 );
danielk1977bc6ada42004-06-30 08:20:16 +00002777 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002778 }
2779 }
drh45e29d82006-11-20 16:21:10 +00002780 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002781 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002782 p->writableSchema = 0;
2783 }
drh56197952011-10-13 16:30:13 +00002784 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2785 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002786 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002787 }else
drh75897232000-05-29 14:26:00 +00002788
drhc2ce0be2014-05-29 12:36:14 +00002789 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2790 if( nArg==2 ){
2791 p->echoOn = booleanValue(azArg[1]);
2792 }else{
2793 fprintf(stderr, "Usage: .echo on|off\n");
2794 rc = 1;
2795 }
drhdaffd0e2001-04-11 14:28:42 +00002796 }else
2797
drhc2ce0be2014-05-29 12:36:14 +00002798 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2799 if( nArg==2 ){
2800 p->autoEQP = booleanValue(azArg[1]);
2801 }else{
2802 fprintf(stderr, "Usage: .eqp on|off\n");
2803 rc = 1;
2804 }
drhefbf3b12014-02-28 20:47:24 +00002805 }else
2806
drhd3ac7d92013-01-25 18:33:43 +00002807 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002808 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002809 rc = 2;
drh75897232000-05-29 14:26:00 +00002810 }else
2811
drhc2ce0be2014-05-29 12:36:14 +00002812 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002813 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002814 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002815 if(!p->normalMode.valid) {
2816 p->normalMode.valid = 1;
2817 p->normalMode.mode = p->mode;
2818 p->normalMode.showHeader = p->showHeader;
2819 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002820 }
2821 /* We could put this code under the !p->explainValid
2822 ** condition so that it does not execute if we are already in
2823 ** explain mode. However, always executing it allows us an easy
2824 ** was to reset to explain mode in case the user previously
2825 ** did an .explain followed by a .width, .mode or .header
2826 ** command.
2827 */
danielk19770d78bae2008-01-03 07:09:48 +00002828 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002829 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002830 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002831 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002832 p->colWidth[1] = 13; /* opcode */
2833 p->colWidth[2] = 4; /* P1 */
2834 p->colWidth[3] = 4; /* P2 */
2835 p->colWidth[4] = 4; /* P3 */
2836 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002837 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002838 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002839 }else if (p->normalMode.valid) {
2840 p->normalMode.valid = 0;
2841 p->mode = p->normalMode.mode;
2842 p->showHeader = p->normalMode.showHeader;
2843 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002844 }
drh75897232000-05-29 14:26:00 +00002845 }else
2846
drhc1971542014-06-23 23:28:13 +00002847 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002848 ShellState data;
drhc1971542014-06-23 23:28:13 +00002849 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002850 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002851 if( nArg!=1 ){
2852 fprintf(stderr, "Usage: .fullschema\n");
2853 rc = 1;
2854 goto meta_command_exit;
2855 }
2856 open_db(p, 0);
2857 memcpy(&data, p, sizeof(data));
2858 data.showHeader = 0;
2859 data.mode = MODE_Semi;
2860 rc = sqlite3_exec(p->db,
2861 "SELECT sql FROM"
2862 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2863 " FROM sqlite_master UNION ALL"
2864 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002865 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002866 "ORDER BY rowid",
2867 callback, &data, &zErrMsg
2868 );
drh56f674c2014-07-18 14:43:29 +00002869 if( rc==SQLITE_OK ){
2870 sqlite3_stmt *pStmt;
2871 rc = sqlite3_prepare_v2(p->db,
2872 "SELECT rowid FROM sqlite_master"
2873 " WHERE name GLOB 'sqlite_stat[134]'",
2874 -1, &pStmt, 0);
2875 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2876 sqlite3_finalize(pStmt);
2877 }
2878 if( doStats==0 ){
2879 fprintf(p->out, "/* No STAT tables available */\n");
2880 }else{
2881 fprintf(p->out, "ANALYZE sqlite_master;\n");
2882 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2883 callback, &data, &zErrMsg);
2884 data.mode = MODE_Insert;
2885 data.zDestTable = "sqlite_stat1";
2886 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2887 shell_callback, &data,&zErrMsg);
2888 data.zDestTable = "sqlite_stat3";
2889 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2890 shell_callback, &data,&zErrMsg);
2891 data.zDestTable = "sqlite_stat4";
2892 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2893 shell_callback, &data, &zErrMsg);
2894 fprintf(p->out, "ANALYZE sqlite_master;\n");
2895 }
drhc1971542014-06-23 23:28:13 +00002896 }else
2897
drhc2ce0be2014-05-29 12:36:14 +00002898 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2899 if( nArg==2 ){
2900 p->showHeader = booleanValue(azArg[1]);
2901 }else{
2902 fprintf(stderr, "Usage: .headers on|off\n");
2903 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002904 }
drh75897232000-05-29 14:26:00 +00002905 }else
2906
drhc2ce0be2014-05-29 12:36:14 +00002907 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2908 fprintf(p->out, "%s", zHelp);
2909 }else
2910
2911 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002912 char *zTable; /* Insert data into this table */
2913 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002914 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002915 int nCol; /* Number of columns in the table */
2916 int nByte; /* Number of bytes in an SQL string */
2917 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002918 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002919 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002920 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002921 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00002922 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
2923 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00002924
drhc2ce0be2014-05-29 12:36:14 +00002925 if( nArg!=3 ){
2926 fprintf(stderr, "Usage: .import FILE TABLE\n");
2927 goto meta_command_exit;
2928 }
drh01f37542014-05-31 15:43:33 +00002929 zFile = azArg[1];
2930 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002931 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002932 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002933 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002934 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002935 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002936 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002937 return 1;
drhfeac5f82004-08-01 00:10:45 +00002938 }
drhdb95f682013-06-26 22:46:00 +00002939 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002940 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002941 " for import\n");
2942 return 1;
2943 }
mistachkin636bf9f2014-07-19 20:15:16 +00002944 nSep = strlen30(p->rowSeparator);
2945 if( nSep==0 ){
2946 fprintf(stderr, "Error: non-null row separator required for import\n");
2947 return 1;
2948 }
mistachkine0d68852014-12-11 03:12:33 +00002949 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2950 /* When importing CSV (only), if the row separator is set to the
2951 ** default output row separator, change it to the default input
2952 ** row separator. This avoids having to maintain different input
2953 ** and output row separators. */
2954 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2955 nSep = strlen30(p->rowSeparator);
2956 }
mistachkin636bf9f2014-07-19 20:15:16 +00002957 if( nSep>1 ){
2958 fprintf(stderr, "Error: multi-character row separators not allowed"
2959 " for import\n");
2960 return 1;
2961 }
2962 sCtx.zFile = zFile;
2963 sCtx.nLine = 1;
2964 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002965#ifdef SQLITE_OMIT_POPEN
mistachkinba132c72015-03-19 14:48:38 +00002966 fprintf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00002967 return 1;
2968#else
mistachkin636bf9f2014-07-19 20:15:16 +00002969 sCtx.in = popen(sCtx.zFile+1, "r");
2970 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00002971 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00002972#endif
drh5bde8162013-06-27 14:07:53 +00002973 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002974 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00002975 xCloser = fclose;
2976 }
mistachkin636bf9f2014-07-19 20:15:16 +00002977 if( p->mode==MODE_Ascii ){
2978 xRead = ascii_read_one_field;
2979 }else{
2980 xRead = csv_read_one_field;
2981 }
2982 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002983 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002984 return 1;
2985 }
mistachkin636bf9f2014-07-19 20:15:16 +00002986 sCtx.cColSep = p->colSeparator[0];
2987 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00002988 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002989 if( zSql==0 ){
2990 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002991 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002992 return 1;
2993 }
drh4f21c4a2008-12-10 22:15:00 +00002994 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002995 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002996 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00002997 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00002998 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2999 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003000 while( xRead(&sCtx) ){
3001 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003002 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003003 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003004 }
drh5bde8162013-06-27 14:07:53 +00003005 if( cSep=='(' ){
3006 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003007 sqlite3_free(sCtx.z);
3008 xCloser(sCtx.in);
3009 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003010 return 1;
3011 }
drhdb95f682013-06-26 22:46:00 +00003012 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3013 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3014 sqlite3_free(zCreate);
3015 if( rc ){
3016 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003017 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003018 sqlite3_free(sCtx.z);
3019 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003020 return 1;
3021 }
drhc7181902014-02-27 15:04:13 +00003022 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003023 }
drhfeac5f82004-08-01 00:10:45 +00003024 sqlite3_free(zSql);
3025 if( rc ){
shane916f9612009-10-23 00:37:15 +00003026 if (pStmt) sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003027 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003028 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003029 return 1;
drhfeac5f82004-08-01 00:10:45 +00003030 }
shane916f9612009-10-23 00:37:15 +00003031 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003032 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003033 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003034 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003035 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003036 if( zSql==0 ){
3037 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003038 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003039 return 1;
3040 }
drhdb95f682013-06-26 22:46:00 +00003041 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003042 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003043 for(i=1; i<nCol; i++){
3044 zSql[j++] = ',';
3045 zSql[j++] = '?';
3046 }
3047 zSql[j++] = ')';
3048 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003049 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003050 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003051 if( rc ){
mistachkin8e189222015-04-19 21:43:16 +00003052 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003053 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003054 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003055 return 1;
drhfeac5f82004-08-01 00:10:45 +00003056 }
mistachkin8e189222015-04-19 21:43:16 +00003057 needCommit = sqlite3_get_autocommit(p->db);
3058 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003059 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003060 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003061 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003062 char *z = xRead(&sCtx);
3063 /*
3064 ** Did we reach end-of-file before finding any columns?
3065 ** If so, stop instead of NULL filling the remaining columns.
3066 */
drhdb95f682013-06-26 22:46:00 +00003067 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003068 /*
3069 ** Did we reach end-of-file OR end-of-line before finding any
3070 ** columns in ASCII mode? If so, stop instead of NULL filling
3071 ** the remaining columns.
3072 */
3073 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003074 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003075 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003076 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3077 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003078 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003079 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003080 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003081 }
drhfeac5f82004-08-01 00:10:45 +00003082 }
mistachkin636bf9f2014-07-19 20:15:16 +00003083 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003084 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003085 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003086 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003087 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003088 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3089 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003090 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003091 }
drhdb95f682013-06-26 22:46:00 +00003092 if( i>=nCol ){
3093 sqlite3_step(pStmt);
3094 rc = sqlite3_reset(pStmt);
3095 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003096 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
mistachkin8e189222015-04-19 21:43:16 +00003097 sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003098 }
3099 }
mistachkin636bf9f2014-07-19 20:15:16 +00003100 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003101
mistachkin636bf9f2014-07-19 20:15:16 +00003102 xCloser(sCtx.in);
3103 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003104 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003105 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003106 }else
3107
drh0e55db12015-02-06 14:51:13 +00003108 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3109 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003110 ShellState data;
drh75897232000-05-29 14:26:00 +00003111 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003112 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003113 memcpy(&data, p, sizeof(data));
3114 data.showHeader = 0;
3115 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003116 if( nArg==1 ){
3117 rc = sqlite3_exec(p->db,
3118 "SELECT name FROM sqlite_master "
3119 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3120 "UNION ALL "
3121 "SELECT name FROM sqlite_temp_master "
3122 "WHERE type='index' "
3123 "ORDER BY 1",
3124 callback, &data, &zErrMsg
3125 );
drhc2ce0be2014-05-29 12:36:14 +00003126 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003127 zShellStatic = azArg[1];
3128 rc = sqlite3_exec(p->db,
3129 "SELECT name FROM sqlite_master "
3130 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3131 "UNION ALL "
3132 "SELECT name FROM sqlite_temp_master "
3133 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3134 "ORDER BY 1",
3135 callback, &data, &zErrMsg
3136 );
3137 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003138 }else{
drh0e55db12015-02-06 14:51:13 +00003139 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003140 rc = 1;
3141 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003142 }
drh75897232000-05-29 14:26:00 +00003143 if( zErrMsg ){
3144 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003145 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003146 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003147 }else if( rc != SQLITE_OK ){
3148 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3149 rc = 1;
drh75897232000-05-29 14:26:00 +00003150 }
3151 }else
3152
drhae5e4452007-05-03 17:18:36 +00003153#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003154 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003155 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003156 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3157 iotrace = 0;
3158 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003159 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003160 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003161 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003162 iotrace = stdout;
3163 }else{
3164 iotrace = fopen(azArg[1], "w");
3165 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003166 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003167 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003168 rc = 1;
drhb0603412007-02-28 04:47:26 +00003169 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003170 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003171 }
3172 }
3173 }else
drhae5e4452007-05-03 17:18:36 +00003174#endif
drh1a513372015-05-02 17:40:23 +00003175 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3176 static const struct {
3177 const char *zLimitName; /* Name of a limit */
3178 int limitCode; /* Integer code for that limit */
3179 } aLimit[] = {
3180 { "length", SQLITE_LIMIT_LENGTH },
3181 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3182 { "column", SQLITE_LIMIT_COLUMN },
3183 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3184 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3185 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3186 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3187 { "attached", SQLITE_LIMIT_ATTACHED },
3188 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3189 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3190 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3191 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
drhb092b032015-05-02 18:25:25 +00003192 { "printf_width", SQLITE_LIMIT_PRINTF_WIDTH },
drh1a513372015-05-02 17:40:23 +00003193 };
3194 int i, n2;
3195 open_db(p, 0);
3196 if( nArg==1 ){
3197 for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
3198 printf("%20s %d\n", aLimit[i].zLimitName,
3199 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3200 }
3201 }else if( nArg>3 ){
3202 fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
3203 rc = 1;
3204 goto meta_command_exit;
3205 }else{
3206 int iLimit = -1;
3207 n2 = strlen30(azArg[1]);
3208 for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
3209 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3210 if( iLimit<0 ){
3211 iLimit = i;
3212 }else{
3213 fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
3214 rc = 1;
3215 goto meta_command_exit;
3216 }
3217 }
3218 }
3219 if( iLimit<0 ){
3220 fprintf(stderr, "unknown limit: \"%s\"\n"
3221 "enter \".limits\" with no arguments for a list.\n",
3222 azArg[1]);
3223 rc = 1;
3224 goto meta_command_exit;
3225 }
3226 if( nArg==3 ){
3227 sqlite3_limit(p->db, aLimit[iLimit].limitCode, integerValue(azArg[2]));
3228 }
3229 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3230 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3231 }
3232 }else
drhb0603412007-02-28 04:47:26 +00003233
drh70df4fe2006-06-13 15:12:21 +00003234#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003235 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003236 const char *zFile, *zProc;
3237 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003238 if( nArg<2 ){
3239 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3240 rc = 1;
3241 goto meta_command_exit;
3242 }
drh1e397f82006-06-08 15:28:43 +00003243 zFile = azArg[1];
3244 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003245 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003246 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3247 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003248 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003249 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003250 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003251 }
3252 }else
drh70df4fe2006-06-13 15:12:21 +00003253#endif
drh1e397f82006-06-08 15:28:43 +00003254
drhc2ce0be2014-05-29 12:36:14 +00003255 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3256 if( nArg!=2 ){
3257 fprintf(stderr, "Usage: .log FILENAME\n");
3258 rc = 1;
3259 }else{
3260 const char *zFile = azArg[1];
3261 output_file_close(p->pLog);
3262 p->pLog = output_file_open(zFile);
3263 }
drh127f9d72010-02-23 01:47:00 +00003264 }else
3265
drhc2ce0be2014-05-29 12:36:14 +00003266 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3267 const char *zMode = nArg>=2 ? azArg[1] : "";
3268 int n2 = (int)strlen(zMode);
3269 int c2 = zMode[0];
3270 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003271 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003272 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003273 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003274 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003275 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003276 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003277 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003278 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003279 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003280 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003281 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003282 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003283 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003284 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003285 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003286 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003287 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003288 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003289 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003290 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003291 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3292 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003293 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3294 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003295 }else {
shane9bd1b442009-10-23 01:27:39 +00003296 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003297 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003298 rc = 1;
drh75897232000-05-29 14:26:00 +00003299 }
3300 }else
3301
drhc2ce0be2014-05-29 12:36:14 +00003302 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3303 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003304 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3305 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003306 }else{
3307 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003308 rc = 1;
3309 }
3310 }else
3311
drh05782482013-10-24 15:20:20 +00003312 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3313 sqlite3 *savedDb = p->db;
3314 const char *zSavedFilename = p->zDbFilename;
3315 char *zNewFilename = 0;
3316 p->db = 0;
3317 if( nArg>=2 ){
3318 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3319 }
3320 open_db(p, 1);
3321 if( p->db!=0 ){
3322 sqlite3_close(savedDb);
3323 sqlite3_free(p->zFreeOnClose);
3324 p->zFreeOnClose = zNewFilename;
3325 }else{
3326 sqlite3_free(zNewFilename);
3327 p->db = savedDb;
3328 p->zDbFilename = zSavedFilename;
3329 }
3330 }else
3331
drhc2ce0be2014-05-29 12:36:14 +00003332 if( c=='o'
3333 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3334 ){
3335 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3336 if( nArg>2 ){
3337 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3338 rc = 1;
3339 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003340 }
drhc2ce0be2014-05-29 12:36:14 +00003341 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3342 if( nArg<2 ){
3343 fprintf(stderr, "Usage: .once FILE\n");
3344 rc = 1;
3345 goto meta_command_exit;
3346 }
3347 p->outCount = 2;
3348 }else{
3349 p->outCount = 0;
3350 }
3351 output_reset(p);
3352 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003353#ifdef SQLITE_OMIT_POPEN
3354 fprintf(stderr,"Error: pipes are not supported in this OS\n");
3355 rc = 1;
3356 p->out = stdout;
3357#else
drhc2ce0be2014-05-29 12:36:14 +00003358 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003359 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003360 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003361 p->out = stdout;
3362 rc = 1;
3363 }else{
drhc2ce0be2014-05-29 12:36:14 +00003364 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003365 }
drh8cd5b252015-03-02 22:06:43 +00003366#endif
drh75897232000-05-29 14:26:00 +00003367 }else{
drhc2ce0be2014-05-29 12:36:14 +00003368 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003369 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003370 if( strcmp(zFile,"off")!=0 ){
3371 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003372 }
drh75897232000-05-29 14:26:00 +00003373 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003374 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003375 } else {
drhc2ce0be2014-05-29 12:36:14 +00003376 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003377 }
3378 }
3379 }else
3380
drh078b1fd2012-09-21 13:40:02 +00003381 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3382 int i;
3383 for(i=1; i<nArg; i++){
3384 if( i>1 ) fprintf(p->out, " ");
3385 fprintf(p->out, "%s", azArg[i]);
3386 }
3387 fprintf(p->out, "\n");
3388 }else
3389
drhc2ce0be2014-05-29 12:36:14 +00003390 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003391 if( nArg >= 2) {
3392 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3393 }
3394 if( nArg >= 3) {
3395 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3396 }
3397 }else
3398
drhc2ce0be2014-05-29 12:36:14 +00003399 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003400 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003401 }else
3402
drhc2ce0be2014-05-29 12:36:14 +00003403 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3404 FILE *alt;
3405 if( nArg!=2 ){
3406 fprintf(stderr, "Usage: .read FILE\n");
3407 rc = 1;
3408 goto meta_command_exit;
3409 }
3410 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003411 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003412 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3413 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003414 }else{
shane9bd1b442009-10-23 01:27:39 +00003415 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003416 fclose(alt);
3417 }
3418 }else
3419
drhc2ce0be2014-05-29 12:36:14 +00003420 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003421 const char *zSrcFile;
3422 const char *zDb;
3423 sqlite3 *pSrc;
3424 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003425 int nTimeout = 0;
3426
drh9ff849f2009-02-04 20:55:57 +00003427 if( nArg==2 ){
3428 zSrcFile = azArg[1];
3429 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003430 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003431 zSrcFile = azArg[2];
3432 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003433 }else{
3434 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3435 rc = 1;
3436 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003437 }
3438 rc = sqlite3_open(zSrcFile, &pSrc);
3439 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003440 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003441 sqlite3_close(pSrc);
3442 return 1;
3443 }
drh05782482013-10-24 15:20:20 +00003444 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003445 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3446 if( pBackup==0 ){
3447 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3448 sqlite3_close(pSrc);
3449 return 1;
3450 }
drhdc2c4912009-02-04 22:46:47 +00003451 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3452 || rc==SQLITE_BUSY ){
3453 if( rc==SQLITE_BUSY ){
3454 if( nTimeout++ >= 3 ) break;
3455 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003456 }
3457 }
3458 sqlite3_backup_finish(pBackup);
3459 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003460 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003461 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003462 fprintf(stderr, "Error: source database is busy\n");
3463 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003464 }else{
3465 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003466 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003467 }
3468 sqlite3_close(pSrc);
3469 }else
3470
dan8d1edb92014-11-05 09:07:28 +00003471
3472 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3473 if( nArg==2 ){
3474 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003475#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3476 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3477#endif
dan8d1edb92014-11-05 09:07:28 +00003478 }else{
3479 fprintf(stderr, "Usage: .scanstats on|off\n");
3480 rc = 1;
3481 }
3482 }else
3483
drhc2ce0be2014-05-29 12:36:14 +00003484 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003485 ShellState data;
drh75897232000-05-29 14:26:00 +00003486 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003487 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003488 memcpy(&data, p, sizeof(data));
3489 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003490 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003491 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003492 int i;
drhf0693c82011-10-11 20:41:54 +00003493 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003494 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003495 char *new_argv[2], *new_colv[2];
3496 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3497 " type text,\n"
3498 " name text,\n"
3499 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003500 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003501 " sql text\n"
3502 ")";
3503 new_argv[1] = 0;
3504 new_colv[0] = "sql";
3505 new_colv[1] = 0;
3506 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003507 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003508 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003509 char *new_argv[2], *new_colv[2];
3510 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3511 " type text,\n"
3512 " name text,\n"
3513 " tbl_name text,\n"
3514 " rootpage integer,\n"
3515 " sql text\n"
3516 ")";
3517 new_argv[1] = 0;
3518 new_colv[0] = "sql";
3519 new_colv[1] = 0;
3520 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003521 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003522 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003523 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003524 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003525 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003526 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003527 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003528 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003529 "WHERE lower(tbl_name) LIKE shellstatic()"
3530 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003531 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003532 callback, &data, &zErrMsg);
3533 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003534 }
drhc2ce0be2014-05-29 12:36:14 +00003535 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003536 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003537 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003538 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003539 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003540 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003541 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003542 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003543 callback, &data, &zErrMsg
3544 );
drhc2ce0be2014-05-29 12:36:14 +00003545 }else{
3546 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3547 rc = 1;
3548 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003549 }
drh75897232000-05-29 14:26:00 +00003550 if( zErrMsg ){
3551 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003552 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003553 rc = 1;
3554 }else if( rc != SQLITE_OK ){
3555 fprintf(stderr,"Error: querying schema information\n");
3556 rc = 1;
3557 }else{
3558 rc = 0;
drh75897232000-05-29 14:26:00 +00003559 }
3560 }else
3561
drhabd4c722014-09-20 18:18:33 +00003562
3563#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3564 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3565 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003566 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003567 }else
3568#endif
3569
3570
drh340f5822013-06-27 13:01:21 +00003571#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003572 /* Undocumented commands for internal testing. Subject to change
3573 ** without notice. */
3574 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3575 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3576 int i, v;
3577 for(i=1; i<nArg; i++){
3578 v = booleanValue(azArg[i]);
3579 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3580 }
3581 }
3582 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3583 int i; sqlite3_int64 v;
3584 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003585 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003586 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003587 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003588 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003589 }
3590 }
3591 }else
drh340f5822013-06-27 13:01:21 +00003592#endif
drh348d19c2013-06-03 12:47:43 +00003593
drhc2ce0be2014-05-29 12:36:14 +00003594 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003595 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003596 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003597 rc = 1;
3598 }
drh6976c212014-07-24 12:09:47 +00003599 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003600 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003601 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003602 }
3603 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003604 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3605 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003606 }
drh75897232000-05-29 14:26:00 +00003607 }else
3608
drh62cdde52014-05-28 20:22:28 +00003609 if( c=='s'
3610 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003611 ){
3612 char *zCmd;
drh54027102014-08-06 14:36:53 +00003613 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003614 if( nArg<2 ){
3615 fprintf(stderr, "Usage: .system COMMAND\n");
3616 rc = 1;
3617 goto meta_command_exit;
3618 }
drhdcb3e3d2014-05-29 03:17:29 +00003619 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003620 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003621 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3622 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003623 }
drh54027102014-08-06 14:36:53 +00003624 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003625 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003626 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003627 }else
3628
drhc2ce0be2014-05-29 12:36:14 +00003629 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003630 int i;
drhc2ce0be2014-05-29 12:36:14 +00003631 if( nArg!=1 ){
3632 fprintf(stderr, "Usage: .show\n");
3633 rc = 1;
3634 goto meta_command_exit;
3635 }
mistachkin636bf9f2014-07-19 20:15:16 +00003636 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3637 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003638 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003639 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3640 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3641 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003642 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003643 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003644 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003645 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003646 fprintf(p->out,"%12.12s: ", "colseparator");
3647 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003648 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003649 fprintf(p->out,"%12.12s: ", "rowseparator");
3650 output_c_string(p->out, p->rowSeparator);
3651 fprintf(p->out, "\n");
3652 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3653 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003654 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003655 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003656 }
drhfeac5f82004-08-01 00:10:45 +00003657 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003658 }else
3659
drhc2ce0be2014-05-29 12:36:14 +00003660 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3661 if( nArg==2 ){
3662 p->statsOn = booleanValue(azArg[1]);
3663 }else{
3664 fprintf(stderr, "Usage: .stats on|off\n");
3665 rc = 1;
3666 }
shaneh642d8b82010-07-28 16:05:34 +00003667 }else
3668
drhc2ce0be2014-05-29 12:36:14 +00003669 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003670 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003671 char **azResult;
drh98781232012-04-23 12:38:05 +00003672 int nRow, nAlloc;
3673 char *zSql = 0;
3674 int ii;
drh05782482013-10-24 15:20:20 +00003675 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003676 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3677 if( rc ) return rc;
3678 zSql = sqlite3_mprintf(
3679 "SELECT name FROM sqlite_master"
3680 " WHERE type IN ('table','view')"
3681 " AND name NOT LIKE 'sqlite_%%'"
3682 " AND name LIKE ?1");
3683 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3684 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3685 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3686 if( strcmp(zDbName,"temp")==0 ){
3687 zSql = sqlite3_mprintf(
3688 "%z UNION ALL "
3689 "SELECT 'temp.' || name FROM sqlite_temp_master"
3690 " WHERE type IN ('table','view')"
3691 " AND name NOT LIKE 'sqlite_%%'"
3692 " AND name LIKE ?1", zSql);
3693 }else{
3694 zSql = sqlite3_mprintf(
3695 "%z UNION ALL "
3696 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3697 " WHERE type IN ('table','view')"
3698 " AND name NOT LIKE 'sqlite_%%'"
3699 " AND name LIKE ?1", zSql, zDbName, zDbName);
3700 }
drha50da102000-08-08 20:19:09 +00003701 }
drh98781232012-04-23 12:38:05 +00003702 sqlite3_finalize(pStmt);
3703 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3704 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3705 sqlite3_free(zSql);
3706 if( rc ) return rc;
3707 nRow = nAlloc = 0;
3708 azResult = 0;
3709 if( nArg>1 ){
3710 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003711 }else{
drh98781232012-04-23 12:38:05 +00003712 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3713 }
3714 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3715 if( nRow>=nAlloc ){
3716 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00003717 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00003718 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00003719 if( azNew==0 ){
3720 fprintf(stderr, "Error: out of memory\n");
3721 break;
3722 }
mistachkin8e189222015-04-19 21:43:16 +00003723 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00003724 azResult = azNew;
3725 }
3726 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3727 if( azResult[nRow] ) nRow++;
3728 }
3729 sqlite3_finalize(pStmt);
3730 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003731 int len, maxlen = 0;
3732 int i, j;
3733 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003734 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003735 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003736 if( len>maxlen ) maxlen = len;
3737 }
3738 nPrintCol = 80/(maxlen+2);
3739 if( nPrintCol<1 ) nPrintCol = 1;
3740 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3741 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003742 for(j=i; j<nRow; j+=nPrintRow){
3743 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003744 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003745 }
drh151b7d52013-05-06 20:28:54 +00003746 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003747 }
3748 }
drh98781232012-04-23 12:38:05 +00003749 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3750 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003751 }else
3752
shaneh96887e12011-02-10 21:08:58 +00003753 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003754 static const struct {
3755 const char *zCtrlName; /* Name of a test-control option */
3756 int ctrlCode; /* Integer code for that option */
3757 } aCtrl[] = {
3758 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3759 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3760 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3761 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3762 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3763 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3764 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3765 { "assert", SQLITE_TESTCTRL_ASSERT },
3766 { "always", SQLITE_TESTCTRL_ALWAYS },
3767 { "reserve", SQLITE_TESTCTRL_RESERVE },
3768 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3769 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003770 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003771 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003772 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003773 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003774 };
shaneh96887e12011-02-10 21:08:58 +00003775 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00003776 int rc2 = 0;
3777 int i, n2;
drh05782482013-10-24 15:20:20 +00003778 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003779
drhd416fe72011-03-17 16:45:50 +00003780 /* convert testctrl text option to value. allow any unique prefix
3781 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00003782 n2 = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003783 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
mistachkin8e189222015-04-19 21:43:16 +00003784 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00003785 if( testctrl<0 ){
3786 testctrl = aCtrl[i].ctrlCode;
3787 }else{
drhb07028f2011-10-14 21:49:18 +00003788 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003789 testctrl = -1;
3790 break;
3791 }
3792 }
3793 }
drh348d19c2013-06-03 12:47:43 +00003794 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003795 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3796 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3797 }else{
3798 switch(testctrl){
3799
3800 /* sqlite3_test_control(int, db, int) */
3801 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3802 case SQLITE_TESTCTRL_RESERVE:
3803 if( nArg==3 ){
3804 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00003805 rc2 = sqlite3_test_control(testctrl, p->db, opt);
3806 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003807 } else {
drhd416fe72011-03-17 16:45:50 +00003808 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3809 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003810 }
3811 break;
3812
3813 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003814 case SQLITE_TESTCTRL_PRNG_SAVE:
3815 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003816 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003817 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003818 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00003819 rc2 = sqlite3_test_control(testctrl);
3820 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003821 } else {
3822 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3823 }
3824 break;
3825
3826 /* sqlite3_test_control(int, uint) */
3827 case SQLITE_TESTCTRL_PENDING_BYTE:
3828 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003829 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003830 rc2 = sqlite3_test_control(testctrl, opt);
3831 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003832 } else {
drhd416fe72011-03-17 16:45:50 +00003833 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3834 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003835 }
3836 break;
3837
3838 /* sqlite3_test_control(int, int) */
3839 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003840 case SQLITE_TESTCTRL_ALWAYS:
3841 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003842 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003843 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003844 rc2 = sqlite3_test_control(testctrl, opt);
3845 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003846 } else {
drhd416fe72011-03-17 16:45:50 +00003847 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3848 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003849 }
3850 break;
3851
3852 /* sqlite3_test_control(int, char *) */
3853#ifdef SQLITE_N_KEYWORD
3854 case SQLITE_TESTCTRL_ISKEYWORD:
3855 if( nArg==3 ){
3856 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00003857 rc2 = sqlite3_test_control(testctrl, opt);
3858 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003859 } else {
drhd416fe72011-03-17 16:45:50 +00003860 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3861 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003862 }
3863 break;
3864#endif
3865
drh1ffede82015-01-30 20:59:27 +00003866 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003867 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00003868 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003869 azArg[2],
drh8964b342015-01-29 17:54:52 +00003870 integerValue(azArg[3]),
3871 integerValue(azArg[4]));
mistachkin8e189222015-04-19 21:43:16 +00003872 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00003873 }else{
drh6f5a37a2015-03-27 02:27:20 +00003874 fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003875 }
3876 break;
3877
shaneh96887e12011-02-10 21:08:58 +00003878 case SQLITE_TESTCTRL_BITVEC_TEST:
3879 case SQLITE_TESTCTRL_FAULT_INSTALL:
3880 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3881 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3882 default:
drhd416fe72011-03-17 16:45:50 +00003883 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3884 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003885 break;
3886 }
3887 }
3888 }else
3889
drhc2ce0be2014-05-29 12:36:14 +00003890 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003891 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003892 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003893 }else
3894
drhc2ce0be2014-05-29 12:36:14 +00003895 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3896 if( nArg==2 ){
3897 enableTimer = booleanValue(azArg[1]);
3898 if( enableTimer && !HAS_TIMER ){
3899 fprintf(stderr, "Error: timer not available on this system.\n");
3900 enableTimer = 0;
3901 }
3902 }else{
3903 fprintf(stderr, "Usage: .timer on|off\n");
3904 rc = 1;
3905 }
shanehe2aa9d72009-11-06 17:20:17 +00003906 }else
3907
drhc2ce0be2014-05-29 12:36:14 +00003908 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003909 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003910 if( nArg!=2 ){
3911 fprintf(stderr, "Usage: .trace FILE|off\n");
3912 rc = 1;
3913 goto meta_command_exit;
3914 }
drh657b4a82015-03-19 13:30:41 +00003915 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00003916 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003917#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003918 if( p->traceOut==0 ){
3919 sqlite3_trace(p->db, 0, 0);
3920 }else{
3921 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3922 }
3923#endif
3924 }else
3925
drhf442e332014-09-10 19:01:14 +00003926#if SQLITE_USER_AUTHENTICATION
3927 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3928 if( nArg<2 ){
3929 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3930 rc = 1;
3931 goto meta_command_exit;
3932 }
drh7883ecf2014-09-11 16:19:31 +00003933 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003934 if( strcmp(azArg[1],"login")==0 ){
3935 if( nArg!=4 ){
3936 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3937 rc = 1;
3938 goto meta_command_exit;
3939 }
drhd39c40f2014-09-11 00:27:53 +00003940 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3941 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003942 if( rc ){
3943 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3944 rc = 1;
3945 }
3946 }else if( strcmp(azArg[1],"add")==0 ){
3947 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003948 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003949 rc = 1;
3950 goto meta_command_exit;
3951 }
drhd39c40f2014-09-11 00:27:53 +00003952 rc = sqlite3_user_add(p->db, azArg[2],
3953 azArg[3], (int)strlen(azArg[3]),
3954 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003955 if( rc ){
3956 fprintf(stderr, "User-Add failed: %d\n", rc);
3957 rc = 1;
3958 }
3959 }else if( strcmp(azArg[1],"edit")==0 ){
3960 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003961 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003962 rc = 1;
3963 goto meta_command_exit;
3964 }
drhd39c40f2014-09-11 00:27:53 +00003965 rc = sqlite3_user_change(p->db, azArg[2],
3966 azArg[3], (int)strlen(azArg[3]),
3967 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003968 if( rc ){
3969 fprintf(stderr, "User-Edit failed: %d\n", rc);
3970 rc = 1;
3971 }
3972 }else if( strcmp(azArg[1],"delete")==0 ){
3973 if( nArg!=3 ){
3974 fprintf(stderr, "Usage: .user delete USER\n");
3975 rc = 1;
3976 goto meta_command_exit;
3977 }
3978 rc = sqlite3_user_delete(p->db, azArg[2]);
3979 if( rc ){
3980 fprintf(stderr, "User-Delete failed: %d\n", rc);
3981 rc = 1;
3982 }
3983 }else{
3984 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
3985 rc = 1;
3986 goto meta_command_exit;
3987 }
3988 }else
3989#endif /* SQLITE_USER_AUTHENTICATION */
3990
drh9fd301b2011-06-03 13:28:22 +00003991 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003992 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003993 sqlite3_libversion(), sqlite3_sourceid());
3994 }else
3995
drhde60fc22011-12-14 17:53:36 +00003996 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3997 const char *zDbName = nArg==2 ? azArg[1] : "main";
3998 char *zVfsName = 0;
3999 if( p->db ){
4000 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4001 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00004002 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004003 sqlite3_free(zVfsName);
4004 }
4005 }
4006 }else
4007
drhcef4fc82012-09-21 22:50:45 +00004008#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4009 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4010 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004011 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004012 }else
4013#endif
4014
drhc2ce0be2014-05-29 12:36:14 +00004015 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004016 int j;
drh43617e92006-03-06 20:55:46 +00004017 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004018 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004019 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004020 }
4021 }else
4022
4023 {
shane9bd1b442009-10-23 01:27:39 +00004024 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004025 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004026 rc = 1;
drh75897232000-05-29 14:26:00 +00004027 }
drh67505e72002-04-19 12:34:06 +00004028
drhc2ce0be2014-05-29 12:36:14 +00004029meta_command_exit:
4030 if( p->outCount ){
4031 p->outCount--;
4032 if( p->outCount==0 ) output_reset(p);
4033 }
drh67505e72002-04-19 12:34:06 +00004034 return rc;
drh75897232000-05-29 14:26:00 +00004035}
4036
drh67505e72002-04-19 12:34:06 +00004037/*
drh91a66392007-09-07 01:12:32 +00004038** Return TRUE if a semicolon occurs anywhere in the first N characters
4039** of string z[].
drh324ccef2003-02-05 14:06:20 +00004040*/
drh9f099fd2013-08-06 14:01:46 +00004041static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004042 int i;
4043 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4044 return 0;
drh324ccef2003-02-05 14:06:20 +00004045}
4046
4047/*
drh70c7a4b2003-04-26 03:03:06 +00004048** Test to see if a line consists entirely of whitespace.
4049*/
4050static int _all_whitespace(const char *z){
4051 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004052 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004053 if( *z=='/' && z[1]=='*' ){
4054 z += 2;
4055 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4056 if( *z==0 ) return 0;
4057 z++;
4058 continue;
4059 }
4060 if( *z=='-' && z[1]=='-' ){
4061 z += 2;
4062 while( *z && *z!='\n' ){ z++; }
4063 if( *z==0 ) return 1;
4064 continue;
4065 }
4066 return 0;
4067 }
4068 return 1;
4069}
4070
4071/*
drha9b17162003-04-29 18:01:28 +00004072** Return TRUE if the line typed in is an SQL command terminator other
4073** than a semi-colon. The SQL Server style "go" command is understood
4074** as is the Oracle "/".
4075*/
drh9f099fd2013-08-06 14:01:46 +00004076static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004077 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004078 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4079 return 1; /* Oracle */
4080 }
drhf0693c82011-10-11 20:41:54 +00004081 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004082 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004083 return 1; /* SQL Server */
4084 }
4085 return 0;
4086}
4087
4088/*
drh233a5312008-12-18 22:25:13 +00004089** Return true if zSql is a complete SQL statement. Return false if it
4090** ends in the middle of a string literal or C-style comment.
4091*/
drh9f099fd2013-08-06 14:01:46 +00004092static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004093 int rc;
4094 if( zSql==0 ) return 1;
4095 zSql[nSql] = ';';
4096 zSql[nSql+1] = 0;
4097 rc = sqlite3_complete(zSql);
4098 zSql[nSql] = 0;
4099 return rc;
4100}
4101
4102/*
drh67505e72002-04-19 12:34:06 +00004103** Read input from *in and process it. If *in==0 then input
4104** is interactive - the user is typing it it. Otherwise, input
4105** is coming from a file or device. A prompt is issued and history
4106** is saved only if input is interactive. An interrupt signal will
4107** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004108**
4109** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004110*/
drhdcd87a92014-08-18 13:45:42 +00004111static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004112 char *zLine = 0; /* A single input line */
4113 char *zSql = 0; /* Accumulated SQL text */
4114 int nLine; /* Length of current line */
4115 int nSql = 0; /* Bytes of zSql[] used */
4116 int nAlloc = 0; /* Allocated zSql[] space */
4117 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4118 char *zErrMsg; /* Error message returned */
4119 int rc; /* Error code */
4120 int errCnt = 0; /* Number of errors seen */
4121 int lineno = 0; /* Current line number */
4122 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004123
4124 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4125 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004126 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004127 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004128 /* End of input */
4129 if( stdin_is_interactive ) printf("\n");
4130 break;
drhc49f44e2006-10-26 18:15:42 +00004131 }
drh67505e72002-04-19 12:34:06 +00004132 if( seenInterrupt ){
4133 if( in!=0 ) break;
4134 seenInterrupt = 0;
4135 }
drhc28490c2006-10-26 14:25:58 +00004136 lineno++;
drh849a9d92013-12-21 15:46:06 +00004137 if( nSql==0 && _all_whitespace(zLine) ){
4138 if( p->echoOn ) printf("%s\n", zLine);
4139 continue;
4140 }
drh2af0b2d2002-02-21 02:25:02 +00004141 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004142 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004143 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004144 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004145 break;
4146 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004147 errCnt++;
4148 }
drhdaffd0e2001-04-11 14:28:42 +00004149 continue;
4150 }
drh9f099fd2013-08-06 14:01:46 +00004151 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004152 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004153 }
drh9f099fd2013-08-06 14:01:46 +00004154 nLine = strlen30(zLine);
4155 if( nSql+nLine+2>=nAlloc ){
4156 nAlloc = nSql+nLine+100;
4157 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004158 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004159 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004160 exit(1);
4161 }
drhdaffd0e2001-04-11 14:28:42 +00004162 }
drh9f099fd2013-08-06 14:01:46 +00004163 nSqlPrior = nSql;
4164 if( nSql==0 ){
4165 int i;
4166 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004167 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004168 memcpy(zSql, zLine+i, nLine+1-i);
4169 startline = lineno;
4170 nSql = nLine-i;
4171 }else{
4172 zSql[nSql++] = '\n';
4173 memcpy(zSql+nSql, zLine, nLine+1);
4174 nSql += nLine;
4175 }
4176 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004177 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004178 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004179 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004180 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004181 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004182 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004183 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004184 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004185 char zPrefix[100];
4186 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004187 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004188 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004189 }else{
shane9bd1b442009-10-23 01:27:39 +00004190 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004191 }
drh7f953e22002-07-13 17:33:45 +00004192 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004193 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004194 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004195 zErrMsg = 0;
4196 }else{
shaned2bed1c2009-10-21 03:56:54 +00004197 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004198 }
drhc49f44e2006-10-26 18:15:42 +00004199 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004200 }
drhdaffd0e2001-04-11 14:28:42 +00004201 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004202 if( p->outCount ){
4203 output_reset(p);
4204 p->outCount = 0;
4205 }
drh9f099fd2013-08-06 14:01:46 +00004206 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004207 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004208 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004209 }
4210 }
drh9f099fd2013-08-06 14:01:46 +00004211 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004212 if( !_all_whitespace(zSql) ){
4213 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004214 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004215 }
drhdaffd0e2001-04-11 14:28:42 +00004216 free(zSql);
4217 }
danielk19772ac27622007-07-03 05:31:16 +00004218 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004219 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004220}
4221
drh67505e72002-04-19 12:34:06 +00004222/*
4223** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004224** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004225*/
4226static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004227 static char *home_dir = NULL;
4228 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004229
drh4ace5362014-11-10 14:42:28 +00004230#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4231 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004232 {
4233 struct passwd *pwent;
4234 uid_t uid = getuid();
4235 if( (pwent=getpwuid(uid)) != NULL) {
4236 home_dir = pwent->pw_dir;
4237 }
drh67505e72002-04-19 12:34:06 +00004238 }
4239#endif
4240
chw65d3c132007-11-12 21:09:10 +00004241#if defined(_WIN32_WCE)
4242 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4243 */
drh85e72432012-04-11 11:38:53 +00004244 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004245#else
4246
drh83905c92012-06-21 13:00:37 +00004247#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004248 if (!home_dir) {
4249 home_dir = getenv("USERPROFILE");
4250 }
4251#endif
4252
drh67505e72002-04-19 12:34:06 +00004253 if (!home_dir) {
4254 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004255 }
4256
drh83905c92012-06-21 13:00:37 +00004257#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004258 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004259 char *zDrive, *zPath;
4260 int n;
4261 zDrive = getenv("HOMEDRIVE");
4262 zPath = getenv("HOMEPATH");
4263 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004264 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004265 home_dir = malloc( n );
4266 if( home_dir==0 ) return 0;
4267 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4268 return home_dir;
4269 }
4270 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004271 }
4272#endif
4273
chw65d3c132007-11-12 21:09:10 +00004274#endif /* !_WIN32_WCE */
4275
drh67505e72002-04-19 12:34:06 +00004276 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004277 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004278 char *z = malloc( n );
4279 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004280 home_dir = z;
4281 }
drhe98d4fa2002-04-21 19:06:22 +00004282
drh67505e72002-04-19 12:34:06 +00004283 return home_dir;
4284}
4285
4286/*
4287** Read input from the file given by sqliterc_override. Or if that
4288** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004289**
4290** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004291*/
drh534f4df2015-02-28 14:03:35 +00004292static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004293 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004294 const char *sqliterc_override /* Name of config file. NULL to use default */
4295){
persicom7e2dfdd2002-04-18 02:46:52 +00004296 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004297 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004298 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004299 FILE *in = NULL;
4300
4301 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004302 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004303 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004304 fprintf(stderr, "-- warning: cannot find home directory;"
4305 " cannot read ~/.sqliterc\n");
4306 return;
drhe98d4fa2002-04-21 19:06:22 +00004307 }
drh2f3de322012-06-27 16:41:31 +00004308 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004309 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4310 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004311 }
drha1f9b5e2004-02-14 16:31:02 +00004312 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004313 if( in ){
drhc28490c2006-10-26 14:25:58 +00004314 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004315 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004316 }
drh534f4df2015-02-28 14:03:35 +00004317 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004318 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004319 }
drh85e72432012-04-11 11:38:53 +00004320 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004321}
4322
drh67505e72002-04-19 12:34:06 +00004323/*
drhe1e38c42003-05-04 18:30:59 +00004324** Show available command line options
4325*/
4326static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004327 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004328 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004329 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004330 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004331 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004332 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004333 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004334 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004335 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004336#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4337 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4338#endif
drhcc3b4f82012-02-07 14:13:50 +00004339 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004340 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004341 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004342 " -line set output mode to 'line'\n"
4343 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004344 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004345 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004346#ifdef SQLITE_ENABLE_MULTIPLEX
4347 " -multiplex enable the multiplexor VFS\n"
4348#endif
mistachkine0d68852014-12-11 03:12:33 +00004349 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004350 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004351 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4352 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004353 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004354 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004355 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004356 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004357#ifdef SQLITE_ENABLE_VFSTRACE
4358 " -vfstrace enable tracing of all VFS calls\n"
4359#endif
drhe1e38c42003-05-04 18:30:59 +00004360;
4361static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004362 fprintf(stderr,
4363 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4364 "FILENAME is the name of an SQLite database. A new database is created\n"
4365 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004366 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004367 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004368 }else{
4369 fprintf(stderr, "Use the -help option for additional information\n");
4370 }
4371 exit(1);
4372}
4373
4374/*
drh67505e72002-04-19 12:34:06 +00004375** Initialize the state information in data
4376*/
drhdcd87a92014-08-18 13:45:42 +00004377static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004378 memset(data, 0, sizeof(*data));
4379 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004380 memcpy(data->colSeparator,SEP_Column, 2);
4381 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004382 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004383 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004384 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004385 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004386 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004387 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4388 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004389}
4390
drh98d312f2012-10-25 15:23:14 +00004391/*
drh5c7976f2014-02-10 19:59:27 +00004392** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004393*/
4394#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004395static void printBold(const char *zText){
4396 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4397 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4398 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4399 SetConsoleTextAttribute(out,
4400 FOREGROUND_RED|FOREGROUND_INTENSITY
4401 );
4402 printf("%s", zText);
4403 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004404}
4405#else
drh5c7976f2014-02-10 19:59:27 +00004406static void printBold(const char *zText){
4407 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004408}
4409#endif
4410
4411/*
drh98d312f2012-10-25 15:23:14 +00004412** Get the argument to an --option. Throw an error and die if no argument
4413** is available.
4414*/
4415static char *cmdline_option_value(int argc, char **argv, int i){
4416 if( i==argc ){
4417 fprintf(stderr, "%s: Error: missing argument to %s\n",
4418 argv[0], argv[argc-1]);
4419 exit(1);
4420 }
4421 return argv[i];
4422}
4423
mistachkin44723ce2015-03-21 02:22:37 +00004424int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004425 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004426 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004427 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004428 int i;
drhc28490c2006-10-26 14:25:58 +00004429 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004430 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004431 int readStdin = 1;
4432 int nCmd = 0;
4433 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004434
drh69b30ab2014-02-27 15:11:52 +00004435#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004436 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4437 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4438 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4439 exit(1);
4440 }
drhc7181902014-02-27 15:04:13 +00004441#endif
drh047d4532015-01-18 20:30:23 +00004442 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004443 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004444 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004445 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004446 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004447
drh44c2eb12003-04-30 11:38:26 +00004448 /* Make sure we have a valid signal handler early, before anything
4449 ** else is done.
4450 */
drh4c504392000-10-16 22:06:40 +00004451#ifdef SIGINT
4452 signal(SIGINT, interrupt_handler);
4453#endif
drh44c2eb12003-04-30 11:38:26 +00004454
drhac5649a2014-11-28 13:35:03 +00004455#ifdef SQLITE_SHELL_DBNAME_PROC
4456 {
4457 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4458 ** of a C-function that will provide the name of the database file. Use
4459 ** this compile-time option to embed this shell program in larger
4460 ** applications. */
4461 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4462 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4463 warnInmemoryDb = 0;
4464 }
4465#endif
4466
drh22fbcb82004-02-01 01:22:50 +00004467 /* Do an initial pass through the command-line argument to locate
4468 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004469 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004470 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004471 */
drh98d312f2012-10-25 15:23:14 +00004472 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004473 char *z;
drhc28490c2006-10-26 14:25:58 +00004474 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004475 if( z[0]!='-' ){
4476 if( data.zDbFilename==0 ){
4477 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004478 }else{
4479 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4480 ** mean that nothing is read from stdin */
4481 readStdin = 0;
4482 nCmd++;
4483 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4484 if( azCmd==0 ){
4485 fprintf(stderr, "out of memory\n");
4486 exit(1);
4487 }
4488 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004489 }
drh98d312f2012-10-25 15:23:14 +00004490 }
drhcc3b4f82012-02-07 14:13:50 +00004491 if( z[1]=='-' ) z++;
4492 if( strcmp(z,"-separator")==0
4493 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004494 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004495 || strcmp(z,"-cmd")==0
4496 ){
drh98d312f2012-10-25 15:23:14 +00004497 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004498 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004499 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004500 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004501 /* Need to check for batch mode here to so we can avoid printing
4502 ** informational messages (like from process_sqliterc) before
4503 ** we do the actual processing of arguments later in a second pass.
4504 */
shanef69573d2009-10-24 02:06:14 +00004505 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004506 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004507#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004508 const char *zSize;
4509 sqlite3_int64 szHeap;
4510
drh98d312f2012-10-25 15:23:14 +00004511 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004512 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004513 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004514 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4515#endif
drh44dec872014-08-30 15:49:25 +00004516 }else if( strcmp(z,"-scratch")==0 ){
4517 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004518 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004519 if( sz>400000 ) sz = 400000;
4520 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004521 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004522 if( n>10 ) n = 10;
4523 if( n<1 ) n = 1;
4524 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4525 data.shellFlgs |= SHFLG_Scratch;
4526 }else if( strcmp(z,"-pagecache")==0 ){
4527 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004528 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004529 if( sz>70000 ) sz = 70000;
4530 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004531 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004532 if( n<10 ) n = 10;
4533 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4534 data.shellFlgs |= SHFLG_Pagecache;
4535 }else if( strcmp(z,"-lookaside")==0 ){
4536 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004537 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004538 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004539 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004540 if( n<0 ) n = 0;
4541 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4542 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004543#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004544 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004545 extern int vfstrace_register(
4546 const char *zTraceName,
4547 const char *zOldVfsName,
4548 int (*xOut)(const char*,void*),
4549 void *pOutArg,
4550 int makeDefault
4551 );
drh2b625e22011-03-16 17:05:28 +00004552 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004553#endif
drh6f25e892011-07-08 17:02:57 +00004554#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004555 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004556 extern int sqlite3_multiple_initialize(const char*,int);
4557 sqlite3_multiplex_initialize(0, 1);
4558#endif
drh7d9f3942013-04-03 01:26:54 +00004559 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004560 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4561 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004562 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004563 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004564 if( pVfs ){
4565 sqlite3_vfs_register(pVfs, 1);
4566 }else{
4567 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4568 exit(1);
4569 }
drh44c2eb12003-04-30 11:38:26 +00004570 }
4571 }
drh98d312f2012-10-25 15:23:14 +00004572 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004573#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004574 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004575 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004576#else
shane86f5bdb2009-10-24 02:00:07 +00004577 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4578 return 1;
drh01b41712005-08-29 23:06:23 +00004579#endif
drh98d312f2012-10-25 15:23:14 +00004580 }
4581 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004582
drh44c2eb12003-04-30 11:38:26 +00004583 /* Go ahead and open the database file if it already exists. If the
4584 ** file does not exist, delay opening it. This prevents empty database
4585 ** files from being created if a user mistypes the database name argument
4586 ** to the sqlite command-line tool.
4587 */
drhc8d74412004-08-31 23:41:26 +00004588 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004589 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004590 }
4591
drh22fbcb82004-02-01 01:22:50 +00004592 /* Process the initialization file if there is one. If no -init option
4593 ** is given on the command line, look for a file named ~/.sqliterc and
4594 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004595 */
drh534f4df2015-02-28 14:03:35 +00004596 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004597
drh22fbcb82004-02-01 01:22:50 +00004598 /* Make a second pass through the command-line argument and set
4599 ** options. This second pass is delayed until after the initialization
4600 ** file is processed so that the command-line arguments will override
4601 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004602 */
drh98d312f2012-10-25 15:23:14 +00004603 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004604 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004605 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004606 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004607 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004608 i++;
4609 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004610 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004611 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004612 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004613 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004614 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004615 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004616 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004617 }else if( strcmp(z,"-csv")==0 ){
4618 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004619 memcpy(data.colSeparator,",",2);
4620 }else if( strcmp(z,"-ascii")==0 ){
4621 data.mode = MODE_Ascii;
4622 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004623 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004624 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004625 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004626 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004627 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4628 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004629 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004630 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004631 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004632 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004633 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004634 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004635 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004636 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004637 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004638 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004639 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004640 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004641 }else if( strcmp(z,"-eqp")==0 ){
4642 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004643 }else if( strcmp(z,"-stats")==0 ){
4644 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004645 }else if( strcmp(z,"-scanstats")==0 ){
4646 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004647 }else if( strcmp(z,"-backslash")==0 ){
4648 /* Undocumented command-line option: -backslash
4649 ** Causes C-style backslash escapes to be evaluated in SQL statements
4650 ** prior to sending the SQL into SQLite. Useful for injecting
4651 ** crazy bytes in the middle of SQL statements for testing and debugging.
4652 */
4653 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004654 }else if( strcmp(z,"-bail")==0 ){
4655 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004656 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004657 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004658 return 0;
drhc28490c2006-10-26 14:25:58 +00004659 }else if( strcmp(z,"-interactive")==0 ){
4660 stdin_is_interactive = 1;
4661 }else if( strcmp(z,"-batch")==0 ){
4662 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004663 }else if( strcmp(z,"-heap")==0 ){
4664 i++;
drh44dec872014-08-30 15:49:25 +00004665 }else if( strcmp(z,"-scratch")==0 ){
4666 i+=2;
4667 }else if( strcmp(z,"-pagecache")==0 ){
4668 i+=2;
4669 }else if( strcmp(z,"-lookaside")==0 ){
4670 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004671 }else if( strcmp(z,"-mmap")==0 ){
4672 i++;
drha7e61d82011-03-12 17:02:57 +00004673 }else if( strcmp(z,"-vfs")==0 ){
4674 i++;
drh6f25e892011-07-08 17:02:57 +00004675#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004676 }else if( strcmp(z,"-vfstrace")==0 ){
4677 i++;
drh6f25e892011-07-08 17:02:57 +00004678#endif
4679#ifdef SQLITE_ENABLE_MULTIPLEX
4680 }else if( strcmp(z,"-multiplex")==0 ){
4681 i++;
4682#endif
drhcc3b4f82012-02-07 14:13:50 +00004683 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004684 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004685 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004686 /* Run commands that follow -cmd first and separately from commands
4687 ** that simply appear on the command-line. This seems goofy. It would
4688 ** be better if all commands ran in the order that they appear. But
4689 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004690 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004691 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004692 if( z[0]=='.' ){
4693 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004694 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004695 }else{
drh05782482013-10-24 15:20:20 +00004696 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004697 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4698 if( zErrMsg!=0 ){
4699 fprintf(stderr,"Error: %s\n", zErrMsg);
4700 if( bail_on_error ) return rc!=0 ? rc : 1;
4701 }else if( rc!=0 ){
4702 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4703 if( bail_on_error ) return rc;
4704 }
4705 }
drh1e5d0e92000-05-31 23:33:17 +00004706 }else{
shane86f5bdb2009-10-24 02:00:07 +00004707 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004708 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004709 return 1;
4710 }
4711 }
drh44c2eb12003-04-30 11:38:26 +00004712
drhac5649a2014-11-28 13:35:03 +00004713 if( !readStdin ){
4714 /* Run all arguments that do not begin with '-' as if they were separate
4715 ** command-line inputs, except for the argToSkip argument which contains
4716 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004717 */
drhac5649a2014-11-28 13:35:03 +00004718 for(i=0; i<nCmd; i++){
4719 if( azCmd[i][0]=='.' ){
4720 rc = do_meta_command(azCmd[i], &data);
4721 if( rc ) return rc==2 ? 0 : rc;
4722 }else{
4723 open_db(&data, 0);
4724 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4725 if( zErrMsg!=0 ){
4726 fprintf(stderr,"Error: %s\n", zErrMsg);
4727 return rc!=0 ? rc : 1;
4728 }else if( rc!=0 ){
4729 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4730 return rc;
4731 }
drh6ff13852001-11-25 13:18:23 +00004732 }
drh75897232000-05-29 14:26:00 +00004733 }
drhac5649a2014-11-28 13:35:03 +00004734 free(azCmd);
drh75897232000-05-29 14:26:00 +00004735 }else{
drh44c2eb12003-04-30 11:38:26 +00004736 /* Run commands received from standard input
4737 */
drhc28490c2006-10-26 14:25:58 +00004738 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004739 char *zHome;
4740 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004741 int nHistory;
drh75897232000-05-29 14:26:00 +00004742 printf(
drh743e0032011-12-12 16:51:50 +00004743 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004744 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004745 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004746 );
drhb3735912014-02-10 16:13:42 +00004747 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004748 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004749 printBold("transient in-memory database");
4750 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004751 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004752 }
drh67505e72002-04-19 12:34:06 +00004753 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004754 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004755 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004756 if( (zHistory = malloc(nHistory))!=0 ){
4757 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4758 }
drh67505e72002-04-19 12:34:06 +00004759 }
danfd34d6d2015-02-25 10:54:53 +00004760 if( zHistory ) shell_read_history(zHistory);
drhc28490c2006-10-26 14:25:58 +00004761 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004762 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004763 shell_stifle_history(100);
4764 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004765 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004766 }
drhdaffd0e2001-04-11 14:28:42 +00004767 }else{
drhc28490c2006-10-26 14:25:58 +00004768 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004769 }
4770 }
drh33048c02001-10-01 14:29:22 +00004771 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004772 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004773 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004774 }
drh05782482013-10-24 15:20:20 +00004775 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004776 return rc;
drh75897232000-05-29 14:26:00 +00004777}