blob: e5eb394ead0cb5e84e738129d3b5e51386fd20e8 [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>
mistachkin073664d2015-06-17 18:57:37 +0000104# define isatty(h) _isatty(h)
105# ifndef access
106# define access(f,m) _access((f),(m))
107# endif
108# undef popen
109# define popen _popen
110# undef pclose
111# define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
mistachkin073664d2015-06-17 18:57:37 +0000113 /* Make sure isatty() has a prototype. */
114 extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000115
mistachkin073664d2015-06-17 18:57:37 +0000116# if !defined(__RTP__) && !defined(_WRS_KERNEL)
117 /* popen and pclose are not C89 functions and so are
118 ** sometimes omitted from the <stdio.h> header */
119 extern FILE *popen(const char*,const char*);
120 extern int pclose(FILE*);
121# else
122# define SQLITE_OMIT_POPEN 1
123# endif
mistachkinf6418892013-08-28 01:54:12 +0000124#endif
drh53371f92013-07-25 17:07:03 +0000125
chw65d3c132007-11-12 21:09:10 +0000126#if defined(_WIN32_WCE)
127/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
128 * thus we always assume that we have a console. That can be
129 * overridden with the -batch command line option.
130 */
131#define isatty(x) 1
132#endif
133
drhf0693c82011-10-11 20:41:54 +0000134/* ctype macros that work with signed characters */
135#define IsSpace(X) isspace((unsigned char)X)
136#define IsDigit(X) isdigit((unsigned char)X)
137#define ToLower(X) (char)tolower((unsigned char)X)
138
drh047d4532015-01-18 20:30:23 +0000139/* On Windows, we normally run with output mode of TEXT so that \n characters
140** are automatically translated into \r\n. However, this behavior needs
141** to be disabled in some cases (ex: when generating CSV output and when
142** rendering quoted strings that contain \n characters). The following
143** routines take care of that.
144*/
145#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000146static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000147 fflush(out);
148 _setmode(_fileno(out), _O_BINARY);
149}
mistachkine4a0d792015-01-27 21:24:33 +0000150static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000151 fflush(out);
152 _setmode(_fileno(out), _O_TEXT);
153}
154#else
155# define setBinaryMode(X)
156# define setTextMode(X)
157#endif
158
drh43408312013-10-30 12:43:36 +0000159
160/* True if the timer is enabled */
161static int enableTimer = 0;
162
163/* Return the current wall-clock time */
164static sqlite3_int64 timeOfDay(void){
165 static sqlite3_vfs *clockVfs = 0;
166 sqlite3_int64 t;
167 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
168 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
169 clockVfs->xCurrentTimeInt64(clockVfs, &t);
170 }else{
171 double r;
172 clockVfs->xCurrentTime(clockVfs, &r);
173 t = (sqlite3_int64)(r*86400000.0);
174 }
175 return t;
176}
177
drh91eb93c2015-03-03 19:56:20 +0000178#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000179#include <sys/time.h>
180#include <sys/resource.h>
181
drh91eb93c2015-03-03 19:56:20 +0000182/* VxWorks does not support getrusage() as far as we can determine */
183#if defined(_WRS_KERNEL) || defined(__RTP__)
184struct rusage {
185 struct timeval ru_utime; /* user CPU time used */
186 struct timeval ru_stime; /* system CPU time used */
187};
188#define getrusage(A,B) memset(B,0,sizeof(*B))
189#endif
190
drhda108222009-02-25 19:07:24 +0000191/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000192static struct rusage sBegin; /* CPU time at start */
193static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000194
drhda108222009-02-25 19:07:24 +0000195/*
196** Begin timing an operation
197*/
198static void beginTimer(void){
199 if( enableTimer ){
200 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000201 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000202 }
203}
204
205/* Return the difference of two time_structs in seconds */
206static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
207 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
208 (double)(pEnd->tv_sec - pStart->tv_sec);
209}
210
211/*
212** Print the timing results.
213*/
214static void endTimer(void){
215 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000216 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000217 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000218 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000219 printf("Run Time: real %.3f user %f sys %f\n",
220 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000221 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
222 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
223 }
224}
shaneb320ccd2009-10-21 03:42:58 +0000225
drhda108222009-02-25 19:07:24 +0000226#define BEGIN_TIMER beginTimer()
227#define END_TIMER endTimer()
228#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000229
230#elif (defined(_WIN32) || defined(WIN32))
231
232#include <windows.h>
233
234/* Saved resource information for the beginning of an operation */
235static HANDLE hProcess;
236static FILETIME ftKernelBegin;
237static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000238static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000239typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
240 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000241static GETPROCTIMES getProcessTimesAddr = NULL;
242
shaneb320ccd2009-10-21 03:42:58 +0000243/*
244** Check to see if we have timer support. Return 1 if necessary
245** support found (or found previously).
246*/
247static int hasTimer(void){
248 if( getProcessTimesAddr ){
249 return 1;
250 } else {
drh4ace5362014-11-10 14:42:28 +0000251 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
252 ** versions. See if the version we are running on has it, and if it
253 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000254 */
255 hProcess = GetCurrentProcess();
256 if( hProcess ){
257 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
258 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000259 getProcessTimesAddr =
260 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000261 if( NULL != getProcessTimesAddr ){
262 return 1;
263 }
264 FreeLibrary(hinstLib);
265 }
266 }
267 }
268 return 0;
269}
270
271/*
272** Begin timing an operation
273*/
274static void beginTimer(void){
275 if( enableTimer && getProcessTimesAddr ){
276 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000277 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
278 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000279 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000280 }
281}
282
283/* Return the difference of two FILETIME structs in seconds */
284static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
285 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
286 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
287 return (double) ((i64End - i64Start) / 10000000.0);
288}
289
290/*
291** Print the timing results.
292*/
293static void endTimer(void){
294 if( enableTimer && getProcessTimesAddr){
295 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000296 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000297 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000298 printf("Run Time: real %.3f user %f sys %f\n",
299 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000300 timeDiff(&ftUserBegin, &ftUserEnd),
301 timeDiff(&ftKernelBegin, &ftKernelEnd));
302 }
303}
304
305#define BEGIN_TIMER beginTimer()
306#define END_TIMER endTimer()
307#define HAS_TIMER hasTimer()
308
drhda108222009-02-25 19:07:24 +0000309#else
310#define BEGIN_TIMER
311#define END_TIMER
312#define HAS_TIMER 0
313#endif
314
shanec0688ea2009-03-05 03:48:06 +0000315/*
316** Used to prevent warnings about unused parameters
317*/
318#define UNUSED_PARAMETER(x) (void)(x)
319
drhe91d16b2008-12-08 18:27:31 +0000320/*
drhc49f44e2006-10-26 18:15:42 +0000321** If the following flag is set, then command execution stops
322** at an error if we are not interactive.
323*/
324static int bail_on_error = 0;
325
326/*
drhc28490c2006-10-26 14:25:58 +0000327** Threat stdin as an interactive input if the following variable
328** is true. Otherwise, assume stdin is connected to a file or pipe.
329*/
330static int stdin_is_interactive = 1;
331
332/*
drh4c504392000-10-16 22:06:40 +0000333** The following is the open SQLite database. We make a pointer
334** to this database a static variable so that it can be accessed
335** by the SIGINT handler to interrupt database processing.
336*/
mistachkin8e189222015-04-19 21:43:16 +0000337static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000338
339/*
drh67505e72002-04-19 12:34:06 +0000340** True if an interrupt (Control-C) has been received.
341*/
drh43617e92006-03-06 20:55:46 +0000342static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000343
344/*
persicom7e2dfdd2002-04-18 02:46:52 +0000345** This is the name of our program. It is set in main(), used
346** in a number of other places, mostly for error messages.
347*/
348static char *Argv0;
349
350/*
351** Prompt strings. Initialized in main. Settable with
352** .prompt main continue
353*/
354static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
355static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
356
drhb0603412007-02-28 04:47:26 +0000357/*
358** Write I/O traces to the following stream.
359*/
rsebe0a9092007-07-30 18:24:38 +0000360#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000361static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000362#endif
drhb0603412007-02-28 04:47:26 +0000363
364/*
365** This routine works like printf in that its first argument is a
366** format string and subsequent arguments are values to be substituted
367** in place of % fields. The result of formatting this string
368** is written to iotrace.
369*/
rsebe0a9092007-07-30 18:24:38 +0000370#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000371static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000372 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000373 char *z;
drhb0603412007-02-28 04:47:26 +0000374 if( iotrace==0 ) return;
375 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000376 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000377 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000378 fprintf(iotrace, "%s", z);
379 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000380}
rsebe0a9092007-07-30 18:24:38 +0000381#endif
drhb0603412007-02-28 04:47:26 +0000382
drh44c2eb12003-04-30 11:38:26 +0000383
persicom7e2dfdd2002-04-18 02:46:52 +0000384/*
drh83965662003-04-17 02:54:13 +0000385** Determines if a string is a number of not.
386*/
danielk19772e588c72005-12-09 14:25:08 +0000387static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000388 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000389 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000390 return 0;
391 }
392 z++;
393 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000394 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000395 if( *z=='.' ){
396 z++;
drhf0693c82011-10-11 20:41:54 +0000397 if( !IsDigit(*z) ) return 0;
398 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000399 if( realnum ) *realnum = 1;
400 }
401 if( *z=='e' || *z=='E' ){
402 z++;
403 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000404 if( !IsDigit(*z) ) return 0;
405 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000406 if( realnum ) *realnum = 1;
407 }
408 return *z==0;
409}
drh83965662003-04-17 02:54:13 +0000410
411/*
danielk1977bc6ada42004-06-30 08:20:16 +0000412** A global char* and an SQL function to access its current value
413** from within an SQL statement. This program used to use the
414** sqlite_exec_printf() API to substitue a string into an SQL statement.
415** The correct way to do this with sqlite3 is to use the bind API, but
416** since the shell is built around the callback paradigm it would be a lot
417** of work. Instead just use this hack, which is quite harmless.
418*/
419static const char *zShellStatic = 0;
420static void shellstaticFunc(
421 sqlite3_context *context,
422 int argc,
423 sqlite3_value **argv
424){
425 assert( 0==argc );
426 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000427 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000428 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000429 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
430}
431
432
433/*
drhfeac5f82004-08-01 00:10:45 +0000434** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000435** the text in memory obtained from malloc() and returns a pointer
436** to the text. NULL is returned at end of file, or if malloc()
437** fails.
438**
drh9f099fd2013-08-06 14:01:46 +0000439** If zLine is not NULL then it is a malloced buffer returned from
440** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000441*/
drh9f099fd2013-08-06 14:01:46 +0000442static char *local_getline(char *zLine, FILE *in){
443 int nLine = zLine==0 ? 0 : 100;
444 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000445
drhb07028f2011-10-14 21:49:18 +0000446 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000447 if( n+100>nLine ){
448 nLine = nLine*2 + 100;
449 zLine = realloc(zLine, nLine);
450 if( zLine==0 ) return 0;
451 }
drhdaffd0e2001-04-11 14:28:42 +0000452 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000453 if( n==0 ){
454 free(zLine);
455 return 0;
456 }
457 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000458 break;
459 }
drh9f099fd2013-08-06 14:01:46 +0000460 while( zLine[n] ) n++;
461 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000462 n--;
shaneh13b36022009-12-17 21:07:15 +0000463 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000464 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000465 break;
drh8e7e7a22000-05-30 18:45:23 +0000466 }
467 }
drh8e7e7a22000-05-30 18:45:23 +0000468 return zLine;
469}
470
471/*
drhc28490c2006-10-26 14:25:58 +0000472** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000473**
drh9f099fd2013-08-06 14:01:46 +0000474** If in==0 then read from standard input and prompt before each line.
475** If isContinuation is true, then a continuation prompt is appropriate.
476** If isContinuation is zero, then the main prompt should be used.
477**
478** If zPrior is not NULL then it is a buffer from a prior call to this
479** routine that can be reused.
480**
481** The result is stored in space obtained from malloc() and must either
482** be freed by the caller or else passed back into this routine via the
483** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000484*/
drh9f099fd2013-08-06 14:01:46 +0000485static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000486 char *zPrompt;
487 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000488 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000489 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000490 }else{
drh9f099fd2013-08-06 14:01:46 +0000491 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000492#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000493 printf("%s", zPrompt);
494 fflush(stdout);
495 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000496#else
497 free(zPrior);
498 zResult = shell_readline(zPrompt);
499 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000500#endif
drh9f099fd2013-08-06 14:01:46 +0000501 }
drh8e7e7a22000-05-30 18:45:23 +0000502 return zResult;
503}
504
drhdcd87a92014-08-18 13:45:42 +0000505/*
506** Shell output mode information from before ".explain on",
507** saved so that it can be restored by ".explain off"
508*/
509typedef struct SavedModeInfo SavedModeInfo;
510struct SavedModeInfo {
511 int valid; /* Is there legit data in here? */
512 int mode; /* Mode prior to ".explain on" */
513 int showHeader; /* The ".header" setting prior to ".explain on" */
514 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000515};
drh45e29d82006-11-20 16:21:10 +0000516
drh8e7e7a22000-05-30 18:45:23 +0000517/*
drhdcd87a92014-08-18 13:45:42 +0000518** State information about the database connection is contained in an
519** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000520*/
drhdcd87a92014-08-18 13:45:42 +0000521typedef struct ShellState ShellState;
522struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000523 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000524 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000525 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000526 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000527 int scanstatsOn; /* True to display scan stats before each finalize */
drh9569f602015-04-16 15:05:04 +0000528 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000529 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000530 int cnt; /* Number of records displayed so far */
531 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000532 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000533 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000534 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000535 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000536 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000537 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000538 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000539 char colSeparator[20]; /* Column separator character for several modes */
540 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000541 int colWidth[100]; /* Requested width of each column when in column mode*/
542 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000543 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000544 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000545 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000546 char outfile[FILENAME_MAX]; /* Filename for *out */
547 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000548 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000549 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000550 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000551 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000552 int *aiIndent; /* Array of indents used in MODE_Explain */
553 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000554 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000555};
556
557/*
drh44dec872014-08-30 15:49:25 +0000558** These are the allowed shellFlgs values
559*/
560#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
561#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
562#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
563
564/*
drh75897232000-05-29 14:26:00 +0000565** These are the allowed modes.
566*/
drh967e8b72000-06-21 13:59:10 +0000567#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000568#define MODE_Column 1 /* One record per line in neat columns */
569#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000570#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
571#define MODE_Html 4 /* Generate an XHTML table */
572#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000573#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000574#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000575#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000576#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000577
drh66ce4d02008-02-15 17:38:06 +0000578static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000579 "line",
580 "column",
581 "list",
582 "semi",
583 "html",
drhfeac5f82004-08-01 00:10:45 +0000584 "insert",
585 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000586 "csv",
drh66ce4d02008-02-15 17:38:06 +0000587 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000588 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000589};
drh75897232000-05-29 14:26:00 +0000590
591/*
mistachkinfad42082014-07-24 22:13:12 +0000592** These are the column/row/line separators used by the various
593** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000594*/
mistachkinfad42082014-07-24 22:13:12 +0000595#define SEP_Column "|"
596#define SEP_Row "\n"
597#define SEP_Tab "\t"
598#define SEP_Space " "
599#define SEP_Comma ","
600#define SEP_CrLf "\r\n"
601#define SEP_Unit "\x1F"
602#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000603
604/*
drh75897232000-05-29 14:26:00 +0000605** Number of elements in an array
606*/
drh902b9ee2008-12-05 17:17:07 +0000607#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000608
609/*
drhea678832008-12-10 19:26:22 +0000610** Compute a string length that is limited to what can be stored in
611** lower 30 bits of a 32-bit signed integer.
612*/
drh4f21c4a2008-12-10 22:15:00 +0000613static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000614 const char *z2 = z;
615 while( *z2 ){ z2++; }
616 return 0x3fffffff & (int)(z2 - z);
617}
618
619/*
drh127f9d72010-02-23 01:47:00 +0000620** A callback for the sqlite3_log() interface.
621*/
622static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000623 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000624 if( p->pLog==0 ) return;
625 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
626 fflush(p->pLog);
627}
628
629/*
shane626a6e42009-10-22 17:30:15 +0000630** Output the given string as a hex-encoded blob (eg. X'1234' )
631*/
632static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
633 int i;
634 char *zBlob = (char *)pBlob;
635 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000636 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000637 fprintf(out,"'");
638}
639
640/*
drh28bd4bc2000-06-15 15:57:22 +0000641** Output the given string as a quoted string using SQL quoting conventions.
642*/
643static void output_quoted_string(FILE *out, const char *z){
644 int i;
645 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000646 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000647 for(i=0; z[i]; i++){
648 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000649 }
650 if( nSingle==0 ){
651 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000652 }else{
653 fprintf(out,"'");
654 while( *z ){
655 for(i=0; z[i] && z[i]!='\''; i++){}
656 if( i==0 ){
657 fprintf(out,"''");
658 z++;
659 }else if( z[i]=='\'' ){
660 fprintf(out,"%.*s''",i,z);
661 z += i+1;
662 }else{
drhcd7d2732002-02-26 23:24:26 +0000663 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000664 break;
665 }
666 }
drhcd7d2732002-02-26 23:24:26 +0000667 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000668 }
drh047d4532015-01-18 20:30:23 +0000669 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000670}
671
672/*
drhfeac5f82004-08-01 00:10:45 +0000673** Output the given string as a quoted according to C or TCL quoting rules.
674*/
675static void output_c_string(FILE *out, const char *z){
676 unsigned int c;
677 fputc('"', out);
678 while( (c = *(z++))!=0 ){
679 if( c=='\\' ){
680 fputc(c, out);
681 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000682 }else if( c=='"' ){
683 fputc('\\', out);
684 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000685 }else if( c=='\t' ){
686 fputc('\\', out);
687 fputc('t', out);
688 }else if( c=='\n' ){
689 fputc('\\', out);
690 fputc('n', out);
691 }else if( c=='\r' ){
692 fputc('\\', out);
693 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000694 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000695 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000696 }else{
697 fputc(c, out);
698 }
699 }
700 fputc('"', out);
701}
702
703/*
drhc08a4f12000-06-15 16:49:48 +0000704** Output the given string with characters that are special to
705** HTML escaped.
706*/
707static void output_html_string(FILE *out, const char *z){
708 int i;
drhc3d6ba42014-01-13 20:38:35 +0000709 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000710 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000711 for(i=0; z[i]
712 && z[i]!='<'
713 && z[i]!='&'
714 && z[i]!='>'
715 && z[i]!='\"'
716 && z[i]!='\'';
717 i++){}
drhc08a4f12000-06-15 16:49:48 +0000718 if( i>0 ){
719 fprintf(out,"%.*s",i,z);
720 }
721 if( z[i]=='<' ){
722 fprintf(out,"&lt;");
723 }else if( z[i]=='&' ){
724 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000725 }else if( z[i]=='>' ){
726 fprintf(out,"&gt;");
727 }else if( z[i]=='\"' ){
728 fprintf(out,"&quot;");
729 }else if( z[i]=='\'' ){
730 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000731 }else{
732 break;
733 }
734 z += i + 1;
735 }
736}
737
738/*
drhc49f44e2006-10-26 18:15:42 +0000739** If a field contains any character identified by a 1 in the following
740** array, then the string must be quoted for CSV.
741*/
742static const char needCsvQuote[] = {
743 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
744 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
745 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
746 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
747 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,
751 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
752 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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};
760
761/*
mistachkindd11f2d2014-12-11 04:49:46 +0000762** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000763** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000764** the null value. Strings are quoted if necessary. The separator
765** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000766*/
drhdcd87a92014-08-18 13:45:42 +0000767static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000768 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000769 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000770 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000771 }else{
drhc49f44e2006-10-26 18:15:42 +0000772 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000773 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000774 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000775 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000776 || (z[i]==p->colSeparator[0] &&
777 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000778 i = 0;
779 break;
780 }
781 }
782 if( i==0 ){
783 putc('"', out);
784 for(i=0; z[i]; i++){
785 if( z[i]=='"' ) putc('"', out);
786 putc(z[i], out);
787 }
788 putc('"', out);
789 }else{
790 fprintf(out, "%s", z);
791 }
drh8e64d1c2004-10-07 00:32:39 +0000792 }
793 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000794 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000795 }
796}
797
danielk19774af00c62005-01-23 23:43:21 +0000798#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000799/*
drh4c504392000-10-16 22:06:40 +0000800** This routine runs when the user presses Ctrl-C
801*/
802static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000803 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000804 seenInterrupt++;
805 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000806 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000807}
danielk19774af00c62005-01-23 23:43:21 +0000808#endif
drh4c504392000-10-16 22:06:40 +0000809
810/*
shane626a6e42009-10-22 17:30:15 +0000811** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000812** invokes for each row of a query result.
813*/
drh4ace5362014-11-10 14:42:28 +0000814static int shell_callback(
815 void *pArg,
816 int nArg, /* Number of result columns */
817 char **azArg, /* Text of each result column */
818 char **azCol, /* Column names */
819 int *aiType /* Column types */
820){
drh75897232000-05-29 14:26:00 +0000821 int i;
drhdcd87a92014-08-18 13:45:42 +0000822 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000823
drh75897232000-05-29 14:26:00 +0000824 switch( p->mode ){
825 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000826 int w = 5;
drh6a535342001-10-19 16:44:56 +0000827 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000828 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000829 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000830 if( len>w ) w = len;
831 }
mistachkin636bf9f2014-07-19 20:15:16 +0000832 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000833 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000834 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000835 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000836 }
837 break;
838 }
danielk19770d78bae2008-01-03 07:09:48 +0000839 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000840 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000841 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000842 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000843 int w, n;
844 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000845 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000846 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000847 w = 0;
drh75897232000-05-29 14:26:00 +0000848 }
drh078b1fd2012-09-21 13:40:02 +0000849 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000850 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000851 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000852 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000853 if( w<n ) w = n;
854 }
855 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000856 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000857 }
858 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000859 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000860 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
861 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000862 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000863 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
864 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000865 }
drha0c66f52000-07-29 13:20:21 +0000866 }
867 }
868 if( p->showHeader ){
869 for(i=0; i<nArg; i++){
870 int w;
871 if( i<ArraySize(p->actualWidth) ){
872 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000873 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000874 }else{
875 w = 10;
876 }
877 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
878 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000879 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000880 }
drh75897232000-05-29 14:26:00 +0000881 }
882 }
drh6a535342001-10-19 16:44:56 +0000883 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000884 for(i=0; i<nArg; i++){
885 int w;
drha0c66f52000-07-29 13:20:21 +0000886 if( i<ArraySize(p->actualWidth) ){
887 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000888 }else{
889 w = 10;
890 }
dana98bf362013-11-13 18:35:01 +0000891 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000892 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000893 }
dana98bf362013-11-13 18:35:01 +0000894 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000895 if( p->iIndent<p->nIndent ){
896 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000897 }
danc4650bb2013-11-18 08:41:06 +0000898 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000899 }
drh078b1fd2012-09-21 13:40:02 +0000900 if( w<0 ){
901 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000902 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000903 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000904 }else{
905 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000906 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000907 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000908 }
drh75897232000-05-29 14:26:00 +0000909 }
910 break;
911 }
drhe3710332000-09-29 13:30:53 +0000912 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000913 case MODE_List: {
914 if( p->cnt++==0 && p->showHeader ){
915 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000916 fprintf(p->out,"%s%s",azCol[i],
917 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000918 }
919 }
drh6a535342001-10-19 16:44:56 +0000920 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000921 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000922 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000923 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000924 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000925 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000926 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000927 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000928 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000929 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000930 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000931 }
drh75897232000-05-29 14:26:00 +0000932 }
933 break;
934 }
drh1e5d0e92000-05-31 23:33:17 +0000935 case MODE_Html: {
936 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000937 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000938 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000939 fprintf(p->out,"<TH>");
940 output_html_string(p->out, azCol[i]);
941 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000942 }
mihailim57c591a2008-06-23 21:26:05 +0000943 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000944 }
drh6a535342001-10-19 16:44:56 +0000945 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000946 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000947 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000948 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000949 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000950 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000951 }
mihailim57c591a2008-06-23 21:26:05 +0000952 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000953 break;
954 }
drhfeac5f82004-08-01 00:10:45 +0000955 case MODE_Tcl: {
956 if( p->cnt++==0 && p->showHeader ){
957 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000958 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000959 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000960 }
mistachkin636bf9f2014-07-19 20:15:16 +0000961 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000962 }
963 if( azArg==0 ) break;
964 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000965 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000966 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000967 }
mistachkin636bf9f2014-07-19 20:15:16 +0000968 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000969 break;
970 }
drh8e64d1c2004-10-07 00:32:39 +0000971 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000972 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000973 if( p->cnt++==0 && p->showHeader ){
974 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000975 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000976 }
mistachkine0d68852014-12-11 03:12:33 +0000977 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000978 }
drh40253262014-10-17 21:35:05 +0000979 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000980 for(i=0; i<nArg; i++){
981 output_csv(p, azArg[i], i<nArg-1);
982 }
mistachkine0d68852014-12-11 03:12:33 +0000983 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000984 }
drh047d4532015-01-18 20:30:23 +0000985 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000986 break;
987 }
drh28bd4bc2000-06-15 15:57:22 +0000988 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000989 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000990 if( azArg==0 ) break;
mistachkin151c75a2015-04-07 21:16:40 +0000991 fprintf(p->out,"INSERT INTO %s",p->zDestTable);
992 if( p->showHeader ){
993 fprintf(p->out,"(");
994 for(i=0; i<nArg; i++){
995 char *zSep = i>0 ? ",": "";
996 fprintf(p->out, "%s%s", zSep, azCol[i]);
997 }
998 fprintf(p->out,")");
999 }
1000 fprintf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001001 for(i=0; i<nArg; i++){
1002 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001003 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +00001004 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001005 }else if( aiType && aiType[i]==SQLITE_TEXT ){
1006 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1007 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001008 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1009 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +00001010 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001011 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1012 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1013 int nBlob = sqlite3_column_bytes(p->pStmt, i);
1014 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1015 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001016 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001017 fprintf(p->out,"%s%s",zSep, azArg[i]);
1018 }else{
1019 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1020 output_quoted_string(p->out, azArg[i]);
1021 }
1022 }
1023 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001024 break;
drh28bd4bc2000-06-15 15:57:22 +00001025 }
mistachkin636bf9f2014-07-19 20:15:16 +00001026 case MODE_Ascii: {
1027 if( p->cnt++==0 && p->showHeader ){
1028 for(i=0; i<nArg; i++){
1029 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
1030 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
1031 }
1032 fprintf(p->out, "%s", p->rowSeparator);
1033 }
1034 if( azArg==0 ) break;
1035 for(i=0; i<nArg; i++){
1036 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +00001037 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001038 }
1039 fprintf(p->out, "%s", p->rowSeparator);
1040 break;
1041 }
persicom1d0b8722002-04-18 02:53:04 +00001042 }
drh75897232000-05-29 14:26:00 +00001043 return 0;
1044}
1045
1046/*
shane626a6e42009-10-22 17:30:15 +00001047** This is the callback routine that the SQLite library
1048** invokes for each row of a query result.
1049*/
1050static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1051 /* since we don't have type info, call the shell_callback with a NULL value */
1052 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1053}
1054
1055/*
drhdcd87a92014-08-18 13:45:42 +00001056** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001057** the name of the table given. Escape any quote characters in the
1058** table name.
1059*/
drhdcd87a92014-08-18 13:45:42 +00001060static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001061 int i, n;
1062 int needQuote;
1063 char *z;
1064
1065 if( p->zDestTable ){
1066 free(p->zDestTable);
1067 p->zDestTable = 0;
1068 }
1069 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001070 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001071 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001072 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001073 needQuote = 1;
1074 if( zName[i]=='\'' ) n++;
1075 }
1076 }
1077 if( needQuote ) n += 2;
1078 z = p->zDestTable = malloc( n+1 );
1079 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001080 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001081 exit(1);
1082 }
1083 n = 0;
1084 if( needQuote ) z[n++] = '\'';
1085 for(i=0; zName[i]; i++){
1086 z[n++] = zName[i];
1087 if( zName[i]=='\'' ) z[n++] = '\'';
1088 }
1089 if( needQuote ) z[n++] = '\'';
1090 z[n] = 0;
1091}
1092
danielk19772a02e332004-06-05 08:04:36 +00001093/* zIn is either a pointer to a NULL-terminated string in memory obtained
1094** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1095** added to zIn, and the result returned in memory obtained from malloc().
1096** zIn, if it was not NULL, is freed.
1097**
1098** If the third argument, quote, is not '\0', then it is used as a
1099** quote character for zAppend.
1100*/
drhc28490c2006-10-26 14:25:58 +00001101static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001102 int len;
1103 int i;
drh4f21c4a2008-12-10 22:15:00 +00001104 int nAppend = strlen30(zAppend);
1105 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001106
1107 len = nAppend+nIn+1;
1108 if( quote ){
1109 len += 2;
1110 for(i=0; i<nAppend; i++){
1111 if( zAppend[i]==quote ) len++;
1112 }
1113 }
1114
1115 zIn = (char *)realloc(zIn, len);
1116 if( !zIn ){
1117 return 0;
1118 }
1119
1120 if( quote ){
1121 char *zCsr = &zIn[nIn];
1122 *zCsr++ = quote;
1123 for(i=0; i<nAppend; i++){
1124 *zCsr++ = zAppend[i];
1125 if( zAppend[i]==quote ) *zCsr++ = quote;
1126 }
1127 *zCsr++ = quote;
1128 *zCsr++ = '\0';
1129 assert( (zCsr-zIn)==len );
1130 }else{
1131 memcpy(&zIn[nIn], zAppend, nAppend);
1132 zIn[len-1] = '\0';
1133 }
1134
1135 return zIn;
1136}
1137
drhdd3d4592004-08-30 01:54:05 +00001138
1139/*
drhb21a8e42012-01-28 21:08:51 +00001140** Execute a query statement that will generate SQL output. Print
1141** the result columns, comma-separated, on a line and then add a
1142** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001143**
drhb21a8e42012-01-28 21:08:51 +00001144** If the number of columns is 1 and that column contains text "--"
1145** then write the semicolon on a separate line. That way, if a
1146** "--" comment occurs at the end of the statement, the comment
1147** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001148*/
drh157e29a2009-05-21 15:15:00 +00001149static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001150 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001151 const char *zSelect, /* SELECT statement to extract content */
1152 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001153){
drhdd3d4592004-08-30 01:54:05 +00001154 sqlite3_stmt *pSelect;
1155 int rc;
drhb21a8e42012-01-28 21:08:51 +00001156 int nResult;
1157 int i;
1158 const char *z;
drhc7181902014-02-27 15:04:13 +00001159 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001160 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001161 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001162 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001163 return rc;
1164 }
1165 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001166 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001167 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001168 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001169 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001170 zFirstRow = 0;
1171 }
drhb21a8e42012-01-28 21:08:51 +00001172 z = (const char*)sqlite3_column_text(pSelect, 0);
1173 fprintf(p->out, "%s", z);
1174 for(i=1; i<nResult; i++){
1175 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1176 }
1177 if( z==0 ) z = "";
1178 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1179 if( z[0] ){
1180 fprintf(p->out, "\n;\n");
1181 }else{
1182 fprintf(p->out, ";\n");
1183 }
drhdd3d4592004-08-30 01:54:05 +00001184 rc = sqlite3_step(pSelect);
1185 }
drh2f464a02011-10-13 00:41:49 +00001186 rc = sqlite3_finalize(pSelect);
1187 if( rc!=SQLITE_OK ){
1188 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001189 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001190 }
1191 return rc;
drhdd3d4592004-08-30 01:54:05 +00001192}
1193
shane626a6e42009-10-22 17:30:15 +00001194/*
1195** Allocate space and save off current error string.
1196*/
1197static char *save_err_msg(
1198 sqlite3 *db /* Database to query */
1199){
1200 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001201 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001202 if( zErrMsg ){
1203 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1204 }
1205 return zErrMsg;
1206}
1207
1208/*
shaneh642d8b82010-07-28 16:05:34 +00001209** Display memory stats.
1210*/
1211static int display_stats(
1212 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001213 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001214 int bReset /* True to reset the stats */
1215){
1216 int iCur;
1217 int iHiwtr;
1218
1219 if( pArg && pArg->out ){
1220
1221 iHiwtr = iCur = -1;
1222 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001223 fprintf(pArg->out,
1224 "Memory Used: %d (max %d) bytes\n",
1225 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001226 iHiwtr = iCur = -1;
1227 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001228 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1229 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001230 if( pArg->shellFlgs & SHFLG_Pagecache ){
1231 iHiwtr = iCur = -1;
1232 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001233 fprintf(pArg->out,
1234 "Number of Pcache Pages Used: %d (max %d) pages\n",
1235 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001236 }
shaneh642d8b82010-07-28 16:05:34 +00001237 iHiwtr = iCur = -1;
1238 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001239 fprintf(pArg->out,
1240 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1241 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001242 if( pArg->shellFlgs & SHFLG_Scratch ){
1243 iHiwtr = iCur = -1;
1244 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001245 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1246 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001247 }
shaneh642d8b82010-07-28 16:05:34 +00001248 iHiwtr = iCur = -1;
1249 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001250 fprintf(pArg->out,
1251 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1252 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001253 iHiwtr = iCur = -1;
1254 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001255 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1256 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001257 iHiwtr = iCur = -1;
1258 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001259 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1260 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001261 iHiwtr = iCur = -1;
1262 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001263 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1264 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001265#ifdef YYTRACKMAXSTACKDEPTH
1266 iHiwtr = iCur = -1;
1267 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001268 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1269 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001270#endif
1271 }
1272
1273 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001274 if( pArg->shellFlgs & SHFLG_Lookaside ){
1275 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001276 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1277 &iCur, &iHiwtr, bReset);
1278 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1279 iCur, iHiwtr);
1280 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1281 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001282 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001283 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1284 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001285 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001286 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1287 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001288 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1289 }
shaneh642d8b82010-07-28 16:05:34 +00001290 iHiwtr = iCur = -1;
1291 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001292 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1293 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001294 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1295 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1296 iHiwtr = iCur = -1;
1297 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1298 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001299 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001300 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1301 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1302 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001303 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001304 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001305 iHiwtr = iCur = -1;
1306 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001307 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001308 }
1309
1310 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001311 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1312 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001313 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1314 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1315 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001316 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001317 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001318 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1319 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001320 }
1321
dan5a790282015-08-07 20:06:14 +00001322 /* Do not remove this machine readable comment: extra-stats-output-here */
1323
shaneh642d8b82010-07-28 16:05:34 +00001324 return 0;
1325}
1326
1327/*
dan8d1edb92014-11-05 09:07:28 +00001328** Display scan stats.
1329*/
1330static void display_scanstats(
1331 sqlite3 *db, /* Database to query */
1332 ShellState *pArg /* Pointer to ShellState */
1333){
drhf5ed7ad2015-06-15 14:43:25 +00001334#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1335 UNUSED_PARAMETER(db);
1336 UNUSED_PARAMETER(pArg);
1337#else
drh15f23c22014-11-06 12:46:16 +00001338 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001339 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001340 mx = 0;
1341 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001342 double rEstLoop = 1.0;
1343 for(i=n=0; 1; i++){
1344 sqlite3_stmt *p = pArg->pStmt;
1345 sqlite3_int64 nLoop, nVisit;
1346 double rEst;
1347 int iSid;
1348 const char *zExplain;
1349 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1350 break;
1351 }
1352 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001353 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001354 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001355 if( n==0 ){
1356 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001357 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001358 }
drh42f30bc2014-11-06 12:08:21 +00001359 n++;
1360 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1361 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1362 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1363 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1364 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001365 fprintf(pArg->out,
1366 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001367 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001368 );
dan8d1edb92014-11-05 09:07:28 +00001369 }
dan8d1edb92014-11-05 09:07:28 +00001370 }
dan8d1edb92014-11-05 09:07:28 +00001371 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001372#endif
dan8d1edb92014-11-05 09:07:28 +00001373}
1374
1375/*
dana98bf362013-11-13 18:35:01 +00001376** Parameter azArray points to a zero-terminated array of strings. zStr
1377** points to a single nul-terminated string. Return non-zero if zStr
1378** is equal, according to strcmp(), to any of the strings in the array.
1379** Otherwise, return zero.
1380*/
1381static int str_in_array(const char *zStr, const char **azArray){
1382 int i;
1383 for(i=0; azArray[i]; i++){
1384 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1385 }
1386 return 0;
1387}
1388
1389/*
1390** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001391** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001392** spaces each opcode should be indented before it is output.
1393**
1394** The indenting rules are:
1395**
1396** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1397** all opcodes that occur between the p2 jump destination and the opcode
1398** itself by 2 spaces.
1399**
drh01752bc2013-11-14 23:59:33 +00001400** * For each "Goto", if the jump destination is earlier in the program
1401** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001402** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001403** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001404** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001405** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001406*/
drhdcd87a92014-08-18 13:45:42 +00001407static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001408 const char *zSql; /* The text of the SQL statement */
1409 const char *z; /* Used to check if this is an EXPLAIN */
1410 int *abYield = 0; /* True if op is an OP_Yield */
1411 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001412 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001413
drh8ad0de32014-03-20 18:45:27 +00001414 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1415 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001416 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1417 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001418 const char *azGoto[] = { "Goto", 0 };
1419
1420 /* Try to figure out if this is really an EXPLAIN statement. If this
1421 ** cannot be verified, return early. */
1422 zSql = sqlite3_sql(pSql);
1423 if( zSql==0 ) return;
1424 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1425 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1426
1427 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1428 int i;
danc4650bb2013-11-18 08:41:06 +00001429 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001430 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001431
1432 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1433 ** p2 is an instruction address, set variable p2op to the index of that
1434 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1435 ** the current instruction is part of a sub-program generated by an
1436 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001437 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001438 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001439
1440 /* Grow the p->aiIndent array as required */
1441 if( iOp>=nAlloc ){
1442 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001443 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1444 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001445 }
1446 abYield[iOp] = str_in_array(zOp, azYield);
1447 p->aiIndent[iOp] = 0;
1448 p->nIndent = iOp+1;
1449
1450 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001451 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001452 }
drhfe705102014-03-06 13:38:37 +00001453 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1454 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1455 ){
drhe73f0592014-01-21 22:25:45 +00001456 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001457 }
1458 }
1459
danc4650bb2013-11-18 08:41:06 +00001460 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001461 sqlite3_free(abYield);
1462 sqlite3_reset(pSql);
1463}
1464
1465/*
1466** Free the array allocated by explain_data_prepare().
1467*/
drhdcd87a92014-08-18 13:45:42 +00001468static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001469 sqlite3_free(p->aiIndent);
1470 p->aiIndent = 0;
1471 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001472 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001473}
1474
1475/*
shane626a6e42009-10-22 17:30:15 +00001476** Execute a statement or set of statements. Print
1477** any result rows/columns depending on the current mode
1478** set via the supplied callback.
1479**
1480** This is very similar to SQLite's built-in sqlite3_exec()
1481** function except it takes a slightly different callback
1482** and callback data argument.
1483*/
1484static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001485 sqlite3 *db, /* An open database */
1486 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001487 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001488 /* (not the same as sqlite3_exec) */
1489 ShellState *pArg, /* Pointer to ShellState */
1490 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001491){
dan4564ced2010-01-05 04:59:56 +00001492 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1493 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001494 int rc2;
dan4564ced2010-01-05 04:59:56 +00001495 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001496
1497 if( pzErrMsg ){
1498 *pzErrMsg = NULL;
1499 }
1500
shaneb9fc17d2009-10-22 21:23:35 +00001501 while( zSql[0] && (SQLITE_OK == rc) ){
1502 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1503 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001504 if( pzErrMsg ){
1505 *pzErrMsg = save_err_msg(db);
1506 }
1507 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001508 if( !pStmt ){
1509 /* this happens for a comment or white-space */
1510 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001511 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001512 continue;
1513 }
shane626a6e42009-10-22 17:30:15 +00001514
shaneh642d8b82010-07-28 16:05:34 +00001515 /* save off the prepared statment handle and reset row count */
1516 if( pArg ){
1517 pArg->pStmt = pStmt;
1518 pArg->cnt = 0;
1519 }
1520
shanehb7977c52010-01-18 18:17:10 +00001521 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001522 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001523 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001524 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001525 }
shanehb7977c52010-01-18 18:17:10 +00001526
drhefbf3b12014-02-28 20:47:24 +00001527 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1528 if( pArg && pArg->autoEQP ){
1529 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001530 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1531 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001532 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1533 if( rc==SQLITE_OK ){
1534 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1535 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1536 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1537 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1538 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1539 }
1540 }
1541 sqlite3_finalize(pExplain);
1542 sqlite3_free(zEQP);
1543 }
1544
dana98bf362013-11-13 18:35:01 +00001545 /* If the shell is currently in ".explain" mode, gather the extra
1546 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001547 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001548 explain_data_prepare(pArg, pStmt);
1549 }
1550
shaneb9fc17d2009-10-22 21:23:35 +00001551 /* perform the first step. this will tell us if we
1552 ** have a result set or not and how wide it is.
1553 */
1554 rc = sqlite3_step(pStmt);
1555 /* if we have a result set... */
1556 if( SQLITE_ROW == rc ){
1557 /* if we have a callback... */
1558 if( xCallback ){
1559 /* allocate space for col name ptr, value ptr, and type */
1560 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001561 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001562 if( !pData ){
1563 rc = SQLITE_NOMEM;
1564 }else{
1565 char **azCols = (char **)pData; /* Names of result columns */
1566 char **azVals = &azCols[nCol]; /* Results */
1567 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001568 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001569 assert(sizeof(int) <= sizeof(char *));
1570 /* save off ptrs to column names */
1571 for(i=0; i<nCol; i++){
1572 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1573 }
shaneb9fc17d2009-10-22 21:23:35 +00001574 do{
1575 /* extract the data and data types */
1576 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001577 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001578 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001579 azVals[i] = "";
1580 }else{
1581 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1582 }
shaneb9fc17d2009-10-22 21:23:35 +00001583 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1584 rc = SQLITE_NOMEM;
1585 break; /* from for */
1586 }
1587 } /* end for */
1588
1589 /* if data and types extracted successfully... */
1590 if( SQLITE_ROW == rc ){
1591 /* call the supplied callback with the result row data */
1592 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1593 rc = SQLITE_ABORT;
1594 }else{
1595 rc = sqlite3_step(pStmt);
1596 }
1597 }
1598 } while( SQLITE_ROW == rc );
1599 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001600 }
1601 }else{
1602 do{
1603 rc = sqlite3_step(pStmt);
1604 } while( rc == SQLITE_ROW );
1605 }
1606 }
1607
dana98bf362013-11-13 18:35:01 +00001608 explain_data_delete(pArg);
1609
shaneh642d8b82010-07-28 16:05:34 +00001610 /* print usage stats if stats on */
1611 if( pArg && pArg->statsOn ){
1612 display_stats(db, pArg, 0);
1613 }
1614
dan8d1edb92014-11-05 09:07:28 +00001615 /* print loop-counters if required */
1616 if( pArg && pArg->scanstatsOn ){
1617 display_scanstats(db, pArg);
1618 }
1619
dan4564ced2010-01-05 04:59:56 +00001620 /* Finalize the statement just executed. If this fails, save a
1621 ** copy of the error message. Otherwise, set zSql to point to the
1622 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001623 rc2 = sqlite3_finalize(pStmt);
1624 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001625 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001626 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001627 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001628 }else if( pzErrMsg ){
1629 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001630 }
shaneh642d8b82010-07-28 16:05:34 +00001631
1632 /* clear saved stmt handle */
1633 if( pArg ){
1634 pArg->pStmt = NULL;
1635 }
shane626a6e42009-10-22 17:30:15 +00001636 }
shaneb9fc17d2009-10-22 21:23:35 +00001637 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001638
1639 return rc;
1640}
1641
drhdd3d4592004-08-30 01:54:05 +00001642
drh33048c02001-10-01 14:29:22 +00001643/*
drh4c653a02000-06-07 01:27:47 +00001644** This is a different callback routine used for dumping the database.
1645** Each row received by this callback consists of a table name,
1646** the table type ("index" or "table") and SQL to create the table.
1647** This routine should print text sufficient to recreate the table.
1648*/
1649static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001650 int rc;
1651 const char *zTable;
1652 const char *zType;
1653 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001654 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001655 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001656
drh902b9ee2008-12-05 17:17:07 +00001657 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001658 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001659 zTable = azArg[0];
1660 zType = azArg[1];
1661 zSql = azArg[2];
1662
drh00b950d2005-09-11 02:03:03 +00001663 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001664 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001665 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001666 fprintf(p->out, "ANALYZE sqlite_master;\n");
1667 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1668 return 0;
drh45e29d82006-11-20 16:21:10 +00001669 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1670 char *zIns;
1671 if( !p->writableSchema ){
1672 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1673 p->writableSchema = 1;
1674 }
1675 zIns = sqlite3_mprintf(
1676 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1677 "VALUES('table','%q','%q',0,'%q');",
1678 zTable, zTable, zSql);
1679 fprintf(p->out, "%s\n", zIns);
1680 sqlite3_free(zIns);
1681 return 0;
drh00b950d2005-09-11 02:03:03 +00001682 }else{
1683 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001684 }
danielk19772a02e332004-06-05 08:04:36 +00001685
1686 if( strcmp(zType, "table")==0 ){
1687 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001688 char *zSelect = 0;
1689 char *zTableInfo = 0;
1690 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001691 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001692
1693 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1694 zTableInfo = appendText(zTableInfo, zTable, '"');
1695 zTableInfo = appendText(zTableInfo, ");", 0);
1696
drhc7181902014-02-27 15:04:13 +00001697 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001698 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001699 if( rc!=SQLITE_OK || !pTableInfo ){
1700 return 1;
1701 }
1702
1703 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001704 /* Always quote the table name, even if it appears to be pure ascii,
1705 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1706 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001707 if( zTmp ){
1708 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001709 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001710 }
1711 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1712 rc = sqlite3_step(pTableInfo);
1713 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001714 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001715 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001716 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001717 rc = sqlite3_step(pTableInfo);
1718 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001719 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001720 }else{
1721 zSelect = appendText(zSelect, ") ", 0);
1722 }
drh157e29a2009-05-21 15:15:00 +00001723 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001724 }
1725 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001726 if( rc!=SQLITE_OK || nRow==0 ){
1727 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001728 return 1;
1729 }
1730 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1731 zSelect = appendText(zSelect, zTable, '"');
1732
drh2f464a02011-10-13 00:41:49 +00001733 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001734 if( rc==SQLITE_CORRUPT ){
1735 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001736 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001737 }
drh85e72432012-04-11 11:38:53 +00001738 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001739 }
drh4c653a02000-06-07 01:27:47 +00001740 return 0;
1741}
1742
1743/*
drh45e29d82006-11-20 16:21:10 +00001744** Run zQuery. Use dump_callback() as the callback routine so that
1745** the contents of the query are output as SQL statements.
1746**
drhdd3d4592004-08-30 01:54:05 +00001747** If we get a SQLITE_CORRUPT error, rerun the query after appending
1748** "ORDER BY rowid DESC" to the end.
1749*/
1750static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001751 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001752 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001753){
1754 int rc;
drh2f464a02011-10-13 00:41:49 +00001755 char *zErr = 0;
1756 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001757 if( rc==SQLITE_CORRUPT ){
1758 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001759 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001760 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1761 if( zErr ){
1762 fprintf(p->out, "/****** %s ******/\n", zErr);
1763 sqlite3_free(zErr);
1764 zErr = 0;
1765 }
drhdd3d4592004-08-30 01:54:05 +00001766 zQ2 = malloc( len+100 );
1767 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001768 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001769 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1770 if( rc ){
1771 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1772 }else{
1773 rc = SQLITE_CORRUPT;
1774 }
1775 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001776 free(zQ2);
1777 }
1778 return rc;
1779}
1780
1781/*
drh75897232000-05-29 14:26:00 +00001782** Text of a help message
1783*/
persicom1d0b8722002-04-18 02:53:04 +00001784static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001785 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001786 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001787 ".binary on|off Turn binary output on or off. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001788 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001789 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001790 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001791 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001792 " If TABLE specified, only dump tables matching\n"
1793 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001794 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001795 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001796 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001797 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001798 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001799 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001800 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001801 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001802 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001803 ".indexes ?TABLE? Show names of all indexes\n"
1804 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001805 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001806#ifdef SQLITE_ENABLE_IOTRACE
1807 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1808#endif
drh1a513372015-05-02 17:40:23 +00001809 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001810#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001811 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001812#endif
drh127f9d72010-02-23 01:47:00 +00001813 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001814 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001815 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001816 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001817 " column Left-aligned columns. (See .width)\n"
1818 " html HTML <table> code\n"
1819 " insert SQL insert statements for TABLE\n"
1820 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001821 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001822 " tabs Tab-separated values\n"
1823 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001824 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001825 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001826 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001827 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001828 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001829 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001830 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001831 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001832 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001833 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001834 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001835 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001836 " If TABLE specified, only show tables matching\n"
1837 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001838 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1839 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001840 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001841 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001842 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001843 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001844 ".tables ?TABLE? List names of tables\n"
1845 " If TABLE specified, only list tables matching\n"
1846 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001847 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001848 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001849 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001850 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001851 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001852 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001853;
1854
drhdaffd0e2001-04-11 14:28:42 +00001855/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001856static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001857/*
1858** Implementation of the "readfile(X)" SQL function. The entire content
1859** of the file named X is read and returned as a BLOB. NULL is returned
1860** if the file does not exist or is unreadable.
1861*/
1862static void readfileFunc(
1863 sqlite3_context *context,
1864 int argc,
1865 sqlite3_value **argv
1866){
1867 const char *zName;
1868 FILE *in;
1869 long nIn;
1870 void *pBuf;
1871
drhf5ed7ad2015-06-15 14:43:25 +00001872 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00001873 zName = (const char*)sqlite3_value_text(argv[0]);
1874 if( zName==0 ) return;
1875 in = fopen(zName, "rb");
1876 if( in==0 ) return;
1877 fseek(in, 0, SEEK_END);
1878 nIn = ftell(in);
1879 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00001880 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00001881 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1882 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1883 }else{
1884 sqlite3_free(pBuf);
1885 }
1886 fclose(in);
1887}
1888
1889/*
1890** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1891** is written into file X. The number of bytes written is returned. Or
1892** NULL is returned if something goes wrong, such as being unable to open
1893** file X for writing.
1894*/
1895static void writefileFunc(
1896 sqlite3_context *context,
1897 int argc,
1898 sqlite3_value **argv
1899){
1900 FILE *out;
1901 const char *z;
drhba5b0932014-07-24 12:39:59 +00001902 sqlite3_int64 rc;
1903 const char *zFile;
1904
drhf5ed7ad2015-06-15 14:43:25 +00001905 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00001906 zFile = (const char*)sqlite3_value_text(argv[0]);
1907 if( zFile==0 ) return;
1908 out = fopen(zFile, "wb");
1909 if( out==0 ) return;
1910 z = (const char*)sqlite3_value_blob(argv[1]);
1911 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001912 rc = 0;
1913 }else{
drh490fe862014-08-11 14:21:32 +00001914 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001915 }
1916 fclose(out);
1917 sqlite3_result_int64(context, rc);
1918}
drhdaffd0e2001-04-11 14:28:42 +00001919
drh75897232000-05-29 14:26:00 +00001920/*
drh44c2eb12003-04-30 11:38:26 +00001921** Make sure the database is open. If it is not, then open it. If
1922** the database fails to open, print an error message and exit.
1923*/
drhdcd87a92014-08-18 13:45:42 +00001924static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001925 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001926 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001927 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00001928 globalDb = p->db;
1929 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
1930 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00001931 shellstaticFunc, 0, 0);
1932 }
mistachkin8e189222015-04-19 21:43:16 +00001933 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
shane86f5bdb2009-10-24 02:00:07 +00001934 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00001935 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00001936 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001937 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001938 }
drhc2e87a32006-06-27 15:16:14 +00001939#ifndef SQLITE_OMIT_LOAD_EXTENSION
1940 sqlite3_enable_load_extension(p->db, 1);
1941#endif
mistachkin8e189222015-04-19 21:43:16 +00001942 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001943 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00001944 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001945 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001946 }
1947}
1948
1949/*
drhfeac5f82004-08-01 00:10:45 +00001950** Do C-language style dequoting.
1951**
mistachkinf21979d2015-01-18 05:35:01 +00001952** \a -> alarm
1953** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00001954** \t -> tab
1955** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00001956** \v -> vertical tab
1957** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00001958** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00001959** \s -> space
drh4c56b992013-06-27 13:26:55 +00001960** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00001961** \' -> '
drhfeac5f82004-08-01 00:10:45 +00001962** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00001963** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00001964*/
1965static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001966 int i, j;
1967 char c;
drhc2ce0be2014-05-29 12:36:14 +00001968 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001969 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00001970 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00001971 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00001972 if( c=='a' ){
1973 c = '\a';
1974 }else if( c=='b' ){
1975 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00001976 }else if( c=='t' ){
1977 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00001978 }else if( c=='n' ){
1979 c = '\n';
1980 }else if( c=='v' ){
1981 c = '\v';
1982 }else if( c=='f' ){
1983 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00001984 }else if( c=='r' ){
1985 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00001986 }else if( c=='"' ){
1987 c = '"';
1988 }else if( c=='\'' ){
1989 c = '\'';
drh4c56b992013-06-27 13:26:55 +00001990 }else if( c=='\\' ){
1991 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001992 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001993 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001994 if( z[i+1]>='0' && z[i+1]<='7' ){
1995 i++;
1996 c = (c<<3) + z[i] - '0';
1997 if( z[i+1]>='0' && z[i+1]<='7' ){
1998 i++;
1999 c = (c<<3) + z[i] - '0';
2000 }
2001 }
2002 }
2003 }
2004 z[j] = c;
2005 }
drhc2ce0be2014-05-29 12:36:14 +00002006 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002007}
2008
2009/*
drh348d19c2013-06-03 12:47:43 +00002010** Return the value of a hexadecimal digit. Return -1 if the input
2011** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002012*/
drh348d19c2013-06-03 12:47:43 +00002013static int hexDigitValue(char c){
2014 if( c>='0' && c<='9' ) return c - '0';
2015 if( c>='a' && c<='f' ) return c - 'a' + 10;
2016 if( c>='A' && c<='F' ) return c - 'A' + 10;
2017 return -1;
drhc28490c2006-10-26 14:25:58 +00002018}
2019
2020/*
drh7d9f3942013-04-03 01:26:54 +00002021** Interpret zArg as an integer value, possibly with suffixes.
2022*/
2023static sqlite3_int64 integerValue(const char *zArg){
2024 sqlite3_int64 v = 0;
2025 static const struct { char *zSuffix; int iMult; } aMult[] = {
2026 { "KiB", 1024 },
2027 { "MiB", 1024*1024 },
2028 { "GiB", 1024*1024*1024 },
2029 { "KB", 1000 },
2030 { "MB", 1000000 },
2031 { "GB", 1000000000 },
2032 { "K", 1000 },
2033 { "M", 1000000 },
2034 { "G", 1000000000 },
2035 };
2036 int i;
2037 int isNeg = 0;
2038 if( zArg[0]=='-' ){
2039 isNeg = 1;
2040 zArg++;
2041 }else if( zArg[0]=='+' ){
2042 zArg++;
2043 }
drh348d19c2013-06-03 12:47:43 +00002044 if( zArg[0]=='0' && zArg[1]=='x' ){
2045 int x;
2046 zArg += 2;
2047 while( (x = hexDigitValue(zArg[0]))>=0 ){
2048 v = (v<<4) + x;
2049 zArg++;
2050 }
2051 }else{
2052 while( IsDigit(zArg[0]) ){
2053 v = v*10 + zArg[0] - '0';
2054 zArg++;
2055 }
drh7d9f3942013-04-03 01:26:54 +00002056 }
drhc2bed0a2013-05-24 11:57:50 +00002057 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002058 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2059 v *= aMult[i].iMult;
2060 break;
2061 }
2062 }
2063 return isNeg? -v : v;
2064}
2065
2066/*
drh348d19c2013-06-03 12:47:43 +00002067** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2068** for TRUE and FALSE. Return the integer value if appropriate.
2069*/
2070static int booleanValue(char *zArg){
2071 int i;
2072 if( zArg[0]=='0' && zArg[1]=='x' ){
2073 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2074 }else{
2075 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2076 }
2077 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2078 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2079 return 1;
2080 }
2081 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2082 return 0;
2083 }
2084 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2085 zArg);
2086 return 0;
2087}
2088
2089/*
drh42f64e52012-04-04 16:56:23 +00002090** Close an output file, assuming it is not stderr or stdout
2091*/
2092static void output_file_close(FILE *f){
2093 if( f && f!=stdout && f!=stderr ) fclose(f);
2094}
2095
2096/*
2097** Try to open an output file. The names "stdout" and "stderr" are
2098** recognized and do the right thing. NULL is returned if the output
2099** filename is "off".
2100*/
2101static FILE *output_file_open(const char *zFile){
2102 FILE *f;
2103 if( strcmp(zFile,"stdout")==0 ){
2104 f = stdout;
2105 }else if( strcmp(zFile, "stderr")==0 ){
2106 f = stderr;
2107 }else if( strcmp(zFile, "off")==0 ){
2108 f = 0;
2109 }else{
2110 f = fopen(zFile, "wb");
2111 if( f==0 ){
2112 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2113 }
2114 }
2115 return f;
2116}
2117
2118/*
2119** A routine for handling output from sqlite3_trace().
2120*/
2121static void sql_trace_callback(void *pArg, const char *z){
2122 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002123 if( f ){
2124 int i = (int)strlen(z);
2125 while( i>0 && z[i-1]==';' ){ i--; }
2126 fprintf(f, "%.*s;\n", i, z);
2127 }
drh42f64e52012-04-04 16:56:23 +00002128}
2129
2130/*
drhd8621b92012-04-17 09:09:33 +00002131** A no-op routine that runs with the ".breakpoint" doc-command. This is
2132** a useful spot to set a debugger breakpoint.
2133*/
2134static void test_breakpoint(void){
2135 static int nCall = 0;
2136 nCall++;
2137}
2138
2139/*
mistachkin636bf9f2014-07-19 20:15:16 +00002140** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002141*/
mistachkin636bf9f2014-07-19 20:15:16 +00002142typedef struct ImportCtx ImportCtx;
2143struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002144 const char *zFile; /* Name of the input file */
2145 FILE *in; /* Read the CSV text from this input stream */
2146 char *z; /* Accumulated text for a field */
2147 int n; /* Number of bytes in z */
2148 int nAlloc; /* Space allocated for z[] */
2149 int nLine; /* Current line number */
2150 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002151 int cColSep; /* The column separator character. (Usually ",") */
2152 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002153};
2154
2155/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002156static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002157 if( p->n+1>=p->nAlloc ){
2158 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002159 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002160 if( p->z==0 ){
2161 fprintf(stderr, "out of memory\n");
2162 exit(1);
2163 }
2164 }
2165 p->z[p->n++] = (char)c;
2166}
2167
2168/* Read a single field of CSV text. Compatible with rfc4180 and extended
2169** with the option of having a separator other than ",".
2170**
2171** + Input comes from p->in.
2172** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002173** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002174** + Use p->cSep as the column separator. The default is ",".
2175** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002176** + Keep track of the line number in p->nLine.
2177** + Store the character that terminates the field in p->cTerm. Store
2178** EOF on end-of-file.
2179** + Report syntax errors on stderr
2180*/
mistachkin44723ce2015-03-21 02:22:37 +00002181static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002182 int c;
2183 int cSep = p->cColSep;
2184 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002185 p->n = 0;
2186 c = fgetc(p->in);
2187 if( c==EOF || seenInterrupt ){
2188 p->cTerm = EOF;
2189 return 0;
2190 }
2191 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002192 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002193 int startLine = p->nLine;
2194 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002195 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002196 while( 1 ){
2197 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002198 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002199 if( c==cQuote ){
2200 if( pc==cQuote ){
2201 pc = 0;
2202 continue;
2203 }
2204 }
2205 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002206 || (c==rSep && pc==cQuote)
2207 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002208 || (c==EOF && pc==cQuote)
2209 ){
2210 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002211 p->cTerm = c;
2212 break;
2213 }
2214 if( pc==cQuote && c!='\r' ){
2215 fprintf(stderr, "%s:%d: unescaped %c character\n",
2216 p->zFile, p->nLine, cQuote);
2217 }
2218 if( c==EOF ){
2219 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2220 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002221 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002222 break;
2223 }
mistachkin636bf9f2014-07-19 20:15:16 +00002224 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002225 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002226 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002227 }
drhdb95f682013-06-26 22:46:00 +00002228 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002229 while( c!=EOF && c!=cSep && c!=rSep ){
2230 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002231 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002232 }
mistachkin636bf9f2014-07-19 20:15:16 +00002233 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002234 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002235 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002236 }
drhdb95f682013-06-26 22:46:00 +00002237 p->cTerm = c;
2238 }
drh8dd675e2013-07-12 21:09:24 +00002239 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002240 return p->z;
2241}
2242
mistachkin636bf9f2014-07-19 20:15:16 +00002243/* Read a single field of ASCII delimited text.
2244**
2245** + Input comes from p->in.
2246** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002247** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002248** + Use p->cSep as the column separator. The default is "\x1F".
2249** + Use p->rSep as the row separator. The default is "\x1E".
2250** + Keep track of the row number in p->nLine.
2251** + Store the character that terminates the field in p->cTerm. Store
2252** EOF on end-of-file.
2253** + Report syntax errors on stderr
2254*/
mistachkin44723ce2015-03-21 02:22:37 +00002255static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002256 int c;
2257 int cSep = p->cColSep;
2258 int rSep = p->cRowSep;
2259 p->n = 0;
2260 c = fgetc(p->in);
2261 if( c==EOF || seenInterrupt ){
2262 p->cTerm = EOF;
2263 return 0;
2264 }
2265 while( c!=EOF && c!=cSep && c!=rSep ){
2266 import_append_char(p, c);
2267 c = fgetc(p->in);
2268 }
2269 if( c==rSep ){
2270 p->nLine++;
2271 }
2272 p->cTerm = c;
2273 if( p->z ) p->z[p->n] = 0;
2274 return p->z;
2275}
2276
drhdb95f682013-06-26 22:46:00 +00002277/*
drh4bbcf102014-02-06 02:46:08 +00002278** Try to transfer data for table zTable. If an error is seen while
2279** moving forward, try to go backwards. The backwards movement won't
2280** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002281*/
mistachkine31ae902014-02-06 01:15:29 +00002282static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002283 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002284 sqlite3 *newDb,
2285 const char *zTable
2286){
2287 sqlite3_stmt *pQuery = 0;
2288 sqlite3_stmt *pInsert = 0;
2289 char *zQuery = 0;
2290 char *zInsert = 0;
2291 int rc;
2292 int i, j, n;
2293 int nTable = (int)strlen(zTable);
2294 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002295 int cnt = 0;
2296 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002297
2298 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2299 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2300 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002301 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002302 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2303 zQuery);
2304 goto end_data_xfer;
2305 }
2306 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002307 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002308 if( zInsert==0 ){
2309 fprintf(stderr, "out of memory\n");
2310 goto end_data_xfer;
2311 }
2312 sqlite3_snprintf(200+nTable,zInsert,
2313 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2314 i = (int)strlen(zInsert);
2315 for(j=1; j<n; j++){
2316 memcpy(zInsert+i, ",?", 2);
2317 i += 2;
2318 }
2319 memcpy(zInsert+i, ");", 3);
2320 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2321 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002322 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002323 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2324 zQuery);
2325 goto end_data_xfer;
2326 }
2327 for(k=0; k<2; k++){
2328 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2329 for(i=0; i<n; i++){
2330 switch( sqlite3_column_type(pQuery, i) ){
2331 case SQLITE_NULL: {
2332 sqlite3_bind_null(pInsert, i+1);
2333 break;
2334 }
2335 case SQLITE_INTEGER: {
2336 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2337 break;
2338 }
2339 case SQLITE_FLOAT: {
2340 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2341 break;
2342 }
2343 case SQLITE_TEXT: {
2344 sqlite3_bind_text(pInsert, i+1,
2345 (const char*)sqlite3_column_text(pQuery,i),
2346 -1, SQLITE_STATIC);
2347 break;
2348 }
2349 case SQLITE_BLOB: {
2350 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2351 sqlite3_column_bytes(pQuery,i),
2352 SQLITE_STATIC);
2353 break;
2354 }
2355 }
2356 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002357 rc = sqlite3_step(pInsert);
2358 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2359 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2360 sqlite3_errmsg(newDb));
2361 }
drh3350ce92014-02-06 00:49:12 +00002362 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002363 cnt++;
2364 if( (cnt%spinRate)==0 ){
2365 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2366 fflush(stdout);
2367 }
drh3350ce92014-02-06 00:49:12 +00002368 } /* End while */
2369 if( rc==SQLITE_DONE ) break;
2370 sqlite3_finalize(pQuery);
2371 sqlite3_free(zQuery);
2372 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2373 zTable);
2374 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2375 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002376 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2377 break;
drh3350ce92014-02-06 00:49:12 +00002378 }
2379 } /* End for(k=0...) */
2380
2381end_data_xfer:
2382 sqlite3_finalize(pQuery);
2383 sqlite3_finalize(pInsert);
2384 sqlite3_free(zQuery);
2385 sqlite3_free(zInsert);
2386}
2387
2388
2389/*
2390** Try to transfer all rows of the schema that match zWhere. For
2391** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002392** If an error is encountered while moving forward through the
2393** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002394*/
mistachkine31ae902014-02-06 01:15:29 +00002395static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002396 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002397 sqlite3 *newDb,
2398 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002399 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002400){
2401 sqlite3_stmt *pQuery = 0;
2402 char *zQuery = 0;
2403 int rc;
2404 const unsigned char *zName;
2405 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002406 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002407
2408 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2409 " WHERE %s", 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 if( rc!=SQLITE_DONE ){
2433 sqlite3_finalize(pQuery);
2434 sqlite3_free(zQuery);
2435 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2436 " WHERE %s ORDER BY rowid DESC", zWhere);
2437 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2438 if( rc ){
2439 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2440 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2441 zQuery);
2442 goto end_schema_xfer;
2443 }
2444 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2445 zName = sqlite3_column_text(pQuery, 0);
2446 zSql = sqlite3_column_text(pQuery, 1);
2447 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002448 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2449 if( zErrMsg ){
2450 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2451 sqlite3_free(zErrMsg);
2452 zErrMsg = 0;
2453 }
drh3350ce92014-02-06 00:49:12 +00002454 if( xForEach ){
2455 xForEach(p, newDb, (const char*)zName);
2456 }
2457 printf("done\n");
2458 }
2459 }
2460end_schema_xfer:
2461 sqlite3_finalize(pQuery);
2462 sqlite3_free(zQuery);
2463}
2464
2465/*
2466** Open a new database file named "zNewDb". Try to recover as much information
2467** as possible out of the main database (which might be corrupt) and write it
2468** into zNewDb.
2469*/
drhdcd87a92014-08-18 13:45:42 +00002470static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002471 int rc;
2472 sqlite3 *newDb = 0;
2473 if( access(zNewDb,0)==0 ){
2474 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2475 return;
2476 }
2477 rc = sqlite3_open(zNewDb, &newDb);
2478 if( rc ){
2479 fprintf(stderr, "Cannot create output database: %s\n",
2480 sqlite3_errmsg(newDb));
2481 }else{
drh54d0d2d2014-04-03 00:32:13 +00002482 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002483 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002484 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2485 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002486 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002487 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002488 }
2489 sqlite3_close(newDb);
2490}
2491
2492/*
drhc2ce0be2014-05-29 12:36:14 +00002493** Change the output file back to stdout
2494*/
drhdcd87a92014-08-18 13:45:42 +00002495static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002496 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002497#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002498 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002499#endif
drhc2ce0be2014-05-29 12:36:14 +00002500 }else{
2501 output_file_close(p->out);
2502 }
2503 p->outfile[0] = 0;
2504 p->out = stdout;
2505}
2506
2507/*
drhf7502f02015-02-06 14:19:44 +00002508** Run an SQL command and return the single integer result.
2509*/
2510static int db_int(ShellState *p, const char *zSql){
2511 sqlite3_stmt *pStmt;
2512 int res = 0;
2513 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2514 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2515 res = sqlite3_column_int(pStmt,0);
2516 }
2517 sqlite3_finalize(pStmt);
2518 return res;
2519}
2520
2521/*
2522** Convert a 2-byte or 4-byte big-endian integer into a native integer
2523*/
2524unsigned int get2byteInt(unsigned char *a){
2525 return (a[0]<<8) + a[1];
2526}
2527unsigned int get4byteInt(unsigned char *a){
2528 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2529}
2530
2531/*
2532** Implementation of the ".info" command.
2533**
2534** Return 1 on error, 2 to exit, and 0 otherwise.
2535*/
drh0e55db12015-02-06 14:51:13 +00002536static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002537 static const struct { const char *zName; int ofst; } aField[] = {
2538 { "file change counter:", 24 },
2539 { "database page count:", 28 },
2540 { "freelist page count:", 36 },
2541 { "schema cookie:", 40 },
2542 { "schema format:", 44 },
2543 { "default cache size:", 48 },
2544 { "autovacuum top root:", 52 },
2545 { "incremental vacuum:", 64 },
2546 { "text encoding:", 56 },
2547 { "user version:", 60 },
2548 { "application id:", 68 },
2549 { "software version:", 96 },
2550 };
drh0e55db12015-02-06 14:51:13 +00002551 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2552 { "number of tables:",
2553 "SELECT count(*) FROM %s WHERE type='table'" },
2554 { "number of indexes:",
2555 "SELECT count(*) FROM %s WHERE type='index'" },
2556 { "number of triggers:",
2557 "SELECT count(*) FROM %s WHERE type='trigger'" },
2558 { "number of views:",
2559 "SELECT count(*) FROM %s WHERE type='view'" },
2560 { "schema size:",
2561 "SELECT total(length(sql)) FROM %s" },
2562 };
2563 sqlite3_file *pFile;
2564 int i;
2565 char *zSchemaTab;
2566 char *zDb = nArg>=2 ? azArg[1] : "main";
2567 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002568 open_db(p, 0);
2569 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002570 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002571 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2572 return 1;
2573 }
2574 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2575 if( i!=SQLITE_OK ){
2576 fprintf(stderr, "unable to read database header\n");
2577 return 1;
2578 }
2579 i = get2byteInt(aHdr+16);
2580 if( i==1 ) i = 65536;
2581 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2582 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2583 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2584 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00002585 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00002586 int ofst = aField[i].ofst;
2587 unsigned int val = get4byteInt(aHdr + ofst);
2588 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2589 switch( ofst ){
2590 case 56: {
2591 if( val==1 ) fprintf(p->out, " (utf8)");
2592 if( val==2 ) fprintf(p->out, " (utf16le)");
2593 if( val==3 ) fprintf(p->out, " (utf16be)");
2594 }
2595 }
2596 fprintf(p->out, "\n");
2597 }
drh0e55db12015-02-06 14:51:13 +00002598 if( zDb==0 ){
2599 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2600 }else if( strcmp(zDb,"temp")==0 ){
2601 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2602 }else{
2603 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2604 }
drhf5ed7ad2015-06-15 14:43:25 +00002605 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00002606 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2607 int val = db_int(p, zSql);
2608 sqlite3_free(zSql);
2609 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2610 }
2611 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002612 return 0;
2613}
2614
2615
2616/*
drh75897232000-05-29 14:26:00 +00002617** If an input line begins with "." then invoke this routine to
2618** process that line.
drh67505e72002-04-19 12:34:06 +00002619**
drh47ad6842006-11-08 12:25:42 +00002620** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002621*/
drhdcd87a92014-08-18 13:45:42 +00002622static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002623 int h = 1;
drh75897232000-05-29 14:26:00 +00002624 int nArg = 0;
2625 int n, c;
drh67505e72002-04-19 12:34:06 +00002626 int rc = 0;
drh75897232000-05-29 14:26:00 +00002627 char *azArg[50];
2628
2629 /* Parse the input line into tokens.
2630 */
mistachkin8e189222015-04-19 21:43:16 +00002631 while( zLine[h] && nArg<ArraySize(azArg) ){
2632 while( IsSpace(zLine[h]) ){ h++; }
2633 if( zLine[h]==0 ) break;
2634 if( zLine[h]=='\'' || zLine[h]=='"' ){
2635 int delim = zLine[h++];
2636 azArg[nArg++] = &zLine[h];
2637 while( zLine[h] && zLine[h]!=delim ){
2638 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2639 h++;
drh4c56b992013-06-27 13:26:55 +00002640 }
mistachkin8e189222015-04-19 21:43:16 +00002641 if( zLine[h]==delim ){
2642 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002643 }
drhfeac5f82004-08-01 00:10:45 +00002644 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002645 }else{
mistachkin8e189222015-04-19 21:43:16 +00002646 azArg[nArg++] = &zLine[h];
2647 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2648 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002649 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002650 }
2651 }
2652
2653 /* Process the input line.
2654 */
shane9bd1b442009-10-23 01:27:39 +00002655 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002656 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002657 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002658 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2659 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2660 ){
drhbc46f022013-01-23 18:53:23 +00002661 const char *zDestFile = 0;
2662 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002663 sqlite3 *pDest;
2664 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002665 int j;
2666 for(j=1; j<nArg; j++){
2667 const char *z = azArg[j];
2668 if( z[0]=='-' ){
2669 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002670 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002671 {
2672 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2673 return 1;
2674 }
2675 }else if( zDestFile==0 ){
2676 zDestFile = azArg[j];
2677 }else if( zDb==0 ){
2678 zDb = zDestFile;
2679 zDestFile = azArg[j];
2680 }else{
2681 fprintf(stderr, "too many arguments to .backup\n");
2682 return 1;
2683 }
drh9ff849f2009-02-04 20:55:57 +00002684 }
drhbc46f022013-01-23 18:53:23 +00002685 if( zDestFile==0 ){
2686 fprintf(stderr, "missing FILENAME argument on .backup\n");
2687 return 1;
2688 }
2689 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002690 rc = sqlite3_open(zDestFile, &pDest);
2691 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002692 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002693 sqlite3_close(pDest);
2694 return 1;
2695 }
drh05782482013-10-24 15:20:20 +00002696 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002697 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2698 if( pBackup==0 ){
2699 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2700 sqlite3_close(pDest);
2701 return 1;
2702 }
2703 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2704 sqlite3_backup_finish(pBackup);
2705 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002706 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002707 }else{
2708 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002709 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002710 }
2711 sqlite3_close(pDest);
2712 }else
2713
drhc2ce0be2014-05-29 12:36:14 +00002714 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2715 if( nArg==2 ){
2716 bail_on_error = booleanValue(azArg[1]);
2717 }else{
2718 fprintf(stderr, "Usage: .bail on|off\n");
2719 rc = 1;
2720 }
drhc49f44e2006-10-26 18:15:42 +00002721 }else
2722
mistachkinf21979d2015-01-18 05:35:01 +00002723 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2724 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002725 if( booleanValue(azArg[1]) ){
2726 setBinaryMode(p->out);
2727 }else{
2728 setTextMode(p->out);
2729 }
mistachkinf21979d2015-01-18 05:35:01 +00002730 }else{
2731 fprintf(stderr, "Usage: .binary on|off\n");
2732 rc = 1;
2733 }
2734 }else
2735
drhd8621b92012-04-17 09:09:33 +00002736 /* The undocumented ".breakpoint" command causes a call to the no-op
2737 ** routine named test_breakpoint().
2738 */
2739 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2740 test_breakpoint();
2741 }else
2742
drhc2ce0be2014-05-29 12:36:14 +00002743 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2744 if( nArg==2 ){
2745 tryToClone(p, azArg[1]);
2746 }else{
2747 fprintf(stderr, "Usage: .clone FILENAME\n");
2748 rc = 1;
2749 }
mistachkine31ae902014-02-06 01:15:29 +00002750 }else
2751
drhc2ce0be2014-05-29 12:36:14 +00002752 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002753 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002754 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002755 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002756 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002757 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002758 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002759 data.colWidth[0] = 3;
2760 data.colWidth[1] = 15;
2761 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002762 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002763 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002764 if( zErrMsg ){
2765 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002766 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002767 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002768 }
2769 }else
2770
drh0e55db12015-02-06 14:51:13 +00002771 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2772 rc = shell_dbinfo_command(p, nArg, azArg);
2773 }else
2774
drhc2ce0be2014-05-29 12:36:14 +00002775 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002776 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002777 /* When playing back a "dump", the content might appear in an order
2778 ** which causes immediate foreign key constraints to be violated.
2779 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002780 if( nArg!=1 && nArg!=2 ){
2781 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2782 rc = 1;
2783 goto meta_command_exit;
2784 }
drhf1dfc4f2009-09-23 15:51:35 +00002785 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002786 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002787 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002788 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002789 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002790 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002791 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002792 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002793 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002794 );
2795 run_schema_dump_query(p,
2796 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002797 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002798 );
drh2f464a02011-10-13 00:41:49 +00002799 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002800 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002801 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002802 );
drh4c653a02000-06-07 01:27:47 +00002803 }else{
2804 int i;
drhdd3d4592004-08-30 01:54:05 +00002805 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002806 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002807 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002808 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002809 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002810 " AND sql NOT NULL");
2811 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002812 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002813 "WHERE sql NOT NULL"
2814 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002815 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002816 );
danielk1977bc6ada42004-06-30 08:20:16 +00002817 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002818 }
2819 }
drh45e29d82006-11-20 16:21:10 +00002820 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002821 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002822 p->writableSchema = 0;
2823 }
drh56197952011-10-13 16:30:13 +00002824 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2825 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002826 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002827 }else
drh75897232000-05-29 14:26:00 +00002828
drhc2ce0be2014-05-29 12:36:14 +00002829 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2830 if( nArg==2 ){
2831 p->echoOn = booleanValue(azArg[1]);
2832 }else{
2833 fprintf(stderr, "Usage: .echo on|off\n");
2834 rc = 1;
2835 }
drhdaffd0e2001-04-11 14:28:42 +00002836 }else
2837
drhc2ce0be2014-05-29 12:36:14 +00002838 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2839 if( nArg==2 ){
2840 p->autoEQP = booleanValue(azArg[1]);
2841 }else{
2842 fprintf(stderr, "Usage: .eqp on|off\n");
2843 rc = 1;
2844 }
drhefbf3b12014-02-28 20:47:24 +00002845 }else
2846
drhd3ac7d92013-01-25 18:33:43 +00002847 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002848 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002849 rc = 2;
drh75897232000-05-29 14:26:00 +00002850 }else
2851
drhc2ce0be2014-05-29 12:36:14 +00002852 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002853 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002854 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002855 if(!p->normalMode.valid) {
2856 p->normalMode.valid = 1;
2857 p->normalMode.mode = p->mode;
2858 p->normalMode.showHeader = p->showHeader;
2859 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002860 }
2861 /* We could put this code under the !p->explainValid
2862 ** condition so that it does not execute if we are already in
2863 ** explain mode. However, always executing it allows us an easy
2864 ** was to reset to explain mode in case the user previously
2865 ** did an .explain followed by a .width, .mode or .header
2866 ** command.
2867 */
danielk19770d78bae2008-01-03 07:09:48 +00002868 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002869 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002870 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002871 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002872 p->colWidth[1] = 13; /* opcode */
2873 p->colWidth[2] = 4; /* P1 */
2874 p->colWidth[3] = 4; /* P2 */
2875 p->colWidth[4] = 4; /* P3 */
2876 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002877 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002878 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002879 }else if (p->normalMode.valid) {
2880 p->normalMode.valid = 0;
2881 p->mode = p->normalMode.mode;
2882 p->showHeader = p->normalMode.showHeader;
2883 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002884 }
drh75897232000-05-29 14:26:00 +00002885 }else
2886
drhc1971542014-06-23 23:28:13 +00002887 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002888 ShellState data;
drhc1971542014-06-23 23:28:13 +00002889 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002890 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002891 if( nArg!=1 ){
2892 fprintf(stderr, "Usage: .fullschema\n");
2893 rc = 1;
2894 goto meta_command_exit;
2895 }
2896 open_db(p, 0);
2897 memcpy(&data, p, sizeof(data));
2898 data.showHeader = 0;
2899 data.mode = MODE_Semi;
2900 rc = sqlite3_exec(p->db,
2901 "SELECT sql FROM"
2902 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2903 " FROM sqlite_master UNION ALL"
2904 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002905 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002906 "ORDER BY rowid",
2907 callback, &data, &zErrMsg
2908 );
drh56f674c2014-07-18 14:43:29 +00002909 if( rc==SQLITE_OK ){
2910 sqlite3_stmt *pStmt;
2911 rc = sqlite3_prepare_v2(p->db,
2912 "SELECT rowid FROM sqlite_master"
2913 " WHERE name GLOB 'sqlite_stat[134]'",
2914 -1, &pStmt, 0);
2915 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2916 sqlite3_finalize(pStmt);
2917 }
2918 if( doStats==0 ){
2919 fprintf(p->out, "/* No STAT tables available */\n");
2920 }else{
2921 fprintf(p->out, "ANALYZE sqlite_master;\n");
2922 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2923 callback, &data, &zErrMsg);
2924 data.mode = MODE_Insert;
2925 data.zDestTable = "sqlite_stat1";
2926 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2927 shell_callback, &data,&zErrMsg);
2928 data.zDestTable = "sqlite_stat3";
2929 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2930 shell_callback, &data,&zErrMsg);
2931 data.zDestTable = "sqlite_stat4";
2932 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2933 shell_callback, &data, &zErrMsg);
2934 fprintf(p->out, "ANALYZE sqlite_master;\n");
2935 }
drhc1971542014-06-23 23:28:13 +00002936 }else
2937
drhc2ce0be2014-05-29 12:36:14 +00002938 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2939 if( nArg==2 ){
2940 p->showHeader = booleanValue(azArg[1]);
2941 }else{
2942 fprintf(stderr, "Usage: .headers on|off\n");
2943 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002944 }
drh75897232000-05-29 14:26:00 +00002945 }else
2946
drhc2ce0be2014-05-29 12:36:14 +00002947 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2948 fprintf(p->out, "%s", zHelp);
2949 }else
2950
2951 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002952 char *zTable; /* Insert data into this table */
2953 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002954 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002955 int nCol; /* Number of columns in the table */
2956 int nByte; /* Number of bytes in an SQL string */
2957 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002958 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002959 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002960 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002961 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00002962 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
2963 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00002964
drhc2ce0be2014-05-29 12:36:14 +00002965 if( nArg!=3 ){
2966 fprintf(stderr, "Usage: .import FILE TABLE\n");
2967 goto meta_command_exit;
2968 }
drh01f37542014-05-31 15:43:33 +00002969 zFile = azArg[1];
2970 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002971 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002972 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002973 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002974 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002975 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002976 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002977 return 1;
drhfeac5f82004-08-01 00:10:45 +00002978 }
drhdb95f682013-06-26 22:46:00 +00002979 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002980 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002981 " for import\n");
2982 return 1;
2983 }
mistachkin636bf9f2014-07-19 20:15:16 +00002984 nSep = strlen30(p->rowSeparator);
2985 if( nSep==0 ){
2986 fprintf(stderr, "Error: non-null row separator required for import\n");
2987 return 1;
2988 }
mistachkine0d68852014-12-11 03:12:33 +00002989 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2990 /* When importing CSV (only), if the row separator is set to the
2991 ** default output row separator, change it to the default input
2992 ** row separator. This avoids having to maintain different input
2993 ** and output row separators. */
2994 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2995 nSep = strlen30(p->rowSeparator);
2996 }
mistachkin636bf9f2014-07-19 20:15:16 +00002997 if( nSep>1 ){
2998 fprintf(stderr, "Error: multi-character row separators not allowed"
2999 " for import\n");
3000 return 1;
3001 }
3002 sCtx.zFile = zFile;
3003 sCtx.nLine = 1;
3004 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003005#ifdef SQLITE_OMIT_POPEN
mistachkinba132c72015-03-19 14:48:38 +00003006 fprintf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003007 return 1;
3008#else
mistachkin636bf9f2014-07-19 20:15:16 +00003009 sCtx.in = popen(sCtx.zFile+1, "r");
3010 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003011 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003012#endif
drh5bde8162013-06-27 14:07:53 +00003013 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003014 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003015 xCloser = fclose;
3016 }
mistachkin636bf9f2014-07-19 20:15:16 +00003017 if( p->mode==MODE_Ascii ){
3018 xRead = ascii_read_one_field;
3019 }else{
3020 xRead = csv_read_one_field;
3021 }
3022 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00003023 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003024 return 1;
3025 }
mistachkin636bf9f2014-07-19 20:15:16 +00003026 sCtx.cColSep = p->colSeparator[0];
3027 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003028 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003029 if( zSql==0 ){
3030 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003031 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003032 return 1;
3033 }
drh4f21c4a2008-12-10 22:15:00 +00003034 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003035 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003036 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003037 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003038 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3039 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003040 while( xRead(&sCtx) ){
3041 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003042 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003043 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003044 }
drh5bde8162013-06-27 14:07:53 +00003045 if( cSep=='(' ){
3046 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003047 sqlite3_free(sCtx.z);
3048 xCloser(sCtx.in);
3049 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003050 return 1;
3051 }
drhdb95f682013-06-26 22:46:00 +00003052 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3053 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3054 sqlite3_free(zCreate);
3055 if( rc ){
3056 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003057 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003058 sqlite3_free(sCtx.z);
3059 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003060 return 1;
3061 }
drhc7181902014-02-27 15:04:13 +00003062 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003063 }
drhfeac5f82004-08-01 00:10:45 +00003064 sqlite3_free(zSql);
3065 if( rc ){
shane916f9612009-10-23 00:37:15 +00003066 if (pStmt) sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003067 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003068 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003069 return 1;
drhfeac5f82004-08-01 00:10:45 +00003070 }
shane916f9612009-10-23 00:37:15 +00003071 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003072 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003073 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003074 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003075 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003076 if( zSql==0 ){
3077 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003078 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003079 return 1;
3080 }
drhdb95f682013-06-26 22:46:00 +00003081 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003082 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003083 for(i=1; i<nCol; i++){
3084 zSql[j++] = ',';
3085 zSql[j++] = '?';
3086 }
3087 zSql[j++] = ')';
3088 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003089 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003090 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003091 if( rc ){
mistachkin8e189222015-04-19 21:43:16 +00003092 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003093 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003094 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003095 return 1;
drhfeac5f82004-08-01 00:10:45 +00003096 }
mistachkin8e189222015-04-19 21:43:16 +00003097 needCommit = sqlite3_get_autocommit(p->db);
3098 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003099 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003100 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003101 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003102 char *z = xRead(&sCtx);
3103 /*
3104 ** Did we reach end-of-file before finding any columns?
3105 ** If so, stop instead of NULL filling the remaining columns.
3106 */
drhdb95f682013-06-26 22:46:00 +00003107 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003108 /*
3109 ** Did we reach end-of-file OR end-of-line before finding any
3110 ** columns in ASCII mode? If so, stop instead of NULL filling
3111 ** the remaining columns.
3112 */
3113 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003114 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003115 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003116 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3117 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003118 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003119 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003120 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003121 }
drhfeac5f82004-08-01 00:10:45 +00003122 }
mistachkin636bf9f2014-07-19 20:15:16 +00003123 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003124 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003125 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003126 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003127 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003128 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3129 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003130 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003131 }
drhdb95f682013-06-26 22:46:00 +00003132 if( i>=nCol ){
3133 sqlite3_step(pStmt);
3134 rc = sqlite3_reset(pStmt);
3135 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003136 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
mistachkin8e189222015-04-19 21:43:16 +00003137 sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003138 }
3139 }
mistachkin636bf9f2014-07-19 20:15:16 +00003140 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003141
mistachkin636bf9f2014-07-19 20:15:16 +00003142 xCloser(sCtx.in);
3143 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003144 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003145 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003146 }else
3147
drh0e55db12015-02-06 14:51:13 +00003148 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3149 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003150 ShellState data;
drh75897232000-05-29 14:26:00 +00003151 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003152 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003153 memcpy(&data, p, sizeof(data));
3154 data.showHeader = 0;
3155 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003156 if( nArg==1 ){
3157 rc = sqlite3_exec(p->db,
3158 "SELECT name FROM sqlite_master "
3159 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3160 "UNION ALL "
3161 "SELECT name FROM sqlite_temp_master "
3162 "WHERE type='index' "
3163 "ORDER BY 1",
3164 callback, &data, &zErrMsg
3165 );
drhc2ce0be2014-05-29 12:36:14 +00003166 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003167 zShellStatic = azArg[1];
3168 rc = sqlite3_exec(p->db,
3169 "SELECT name FROM sqlite_master "
3170 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3171 "UNION ALL "
3172 "SELECT name FROM sqlite_temp_master "
3173 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3174 "ORDER BY 1",
3175 callback, &data, &zErrMsg
3176 );
3177 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003178 }else{
drh0e55db12015-02-06 14:51:13 +00003179 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003180 rc = 1;
3181 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003182 }
drh75897232000-05-29 14:26:00 +00003183 if( zErrMsg ){
3184 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003185 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003186 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003187 }else if( rc != SQLITE_OK ){
3188 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3189 rc = 1;
drh75897232000-05-29 14:26:00 +00003190 }
3191 }else
3192
drhae5e4452007-05-03 17:18:36 +00003193#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003194 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003195 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003196 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3197 iotrace = 0;
3198 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003199 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003200 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003201 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003202 iotrace = stdout;
3203 }else{
3204 iotrace = fopen(azArg[1], "w");
3205 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003206 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003207 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003208 rc = 1;
drhb0603412007-02-28 04:47:26 +00003209 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003210 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003211 }
3212 }
3213 }else
drhae5e4452007-05-03 17:18:36 +00003214#endif
drh1a513372015-05-02 17:40:23 +00003215 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3216 static const struct {
3217 const char *zLimitName; /* Name of a limit */
3218 int limitCode; /* Integer code for that limit */
3219 } aLimit[] = {
3220 { "length", SQLITE_LIMIT_LENGTH },
3221 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3222 { "column", SQLITE_LIMIT_COLUMN },
3223 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3224 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3225 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3226 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3227 { "attached", SQLITE_LIMIT_ATTACHED },
3228 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3229 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3230 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3231 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3232 };
3233 int i, n2;
3234 open_db(p, 0);
3235 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003236 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003237 printf("%20s %d\n", aLimit[i].zLimitName,
3238 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3239 }
3240 }else if( nArg>3 ){
3241 fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
3242 rc = 1;
3243 goto meta_command_exit;
3244 }else{
3245 int iLimit = -1;
3246 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003247 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003248 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3249 if( iLimit<0 ){
3250 iLimit = i;
3251 }else{
3252 fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
3253 rc = 1;
3254 goto meta_command_exit;
3255 }
3256 }
3257 }
3258 if( iLimit<0 ){
3259 fprintf(stderr, "unknown limit: \"%s\"\n"
3260 "enter \".limits\" with no arguments for a list.\n",
3261 azArg[1]);
3262 rc = 1;
3263 goto meta_command_exit;
3264 }
3265 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003266 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3267 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003268 }
3269 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3270 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3271 }
3272 }else
drhb0603412007-02-28 04:47:26 +00003273
drh70df4fe2006-06-13 15:12:21 +00003274#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003275 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003276 const char *zFile, *zProc;
3277 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003278 if( nArg<2 ){
3279 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3280 rc = 1;
3281 goto meta_command_exit;
3282 }
drh1e397f82006-06-08 15:28:43 +00003283 zFile = azArg[1];
3284 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003285 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003286 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3287 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003288 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003289 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003290 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003291 }
3292 }else
drh70df4fe2006-06-13 15:12:21 +00003293#endif
drh1e397f82006-06-08 15:28:43 +00003294
drhc2ce0be2014-05-29 12:36:14 +00003295 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3296 if( nArg!=2 ){
3297 fprintf(stderr, "Usage: .log FILENAME\n");
3298 rc = 1;
3299 }else{
3300 const char *zFile = azArg[1];
3301 output_file_close(p->pLog);
3302 p->pLog = output_file_open(zFile);
3303 }
drh127f9d72010-02-23 01:47:00 +00003304 }else
3305
drhc2ce0be2014-05-29 12:36:14 +00003306 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3307 const char *zMode = nArg>=2 ? azArg[1] : "";
3308 int n2 = (int)strlen(zMode);
3309 int c2 = zMode[0];
3310 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003311 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003312 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003313 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003314 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003315 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003316 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003317 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003318 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003319 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003320 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003321 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003322 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003323 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003324 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003325 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003326 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003327 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003328 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003329 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003330 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003331 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3332 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003333 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3334 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003335 }else {
shane9bd1b442009-10-23 01:27:39 +00003336 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003337 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003338 rc = 1;
drh75897232000-05-29 14:26:00 +00003339 }
3340 }else
3341
drhc2ce0be2014-05-29 12:36:14 +00003342 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3343 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003344 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3345 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003346 }else{
3347 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003348 rc = 1;
3349 }
3350 }else
3351
drh05782482013-10-24 15:20:20 +00003352 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3353 sqlite3 *savedDb = p->db;
3354 const char *zSavedFilename = p->zDbFilename;
3355 char *zNewFilename = 0;
3356 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003357 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3358 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003359 open_db(p, 1);
3360 if( p->db!=0 ){
3361 sqlite3_close(savedDb);
3362 sqlite3_free(p->zFreeOnClose);
3363 p->zFreeOnClose = zNewFilename;
3364 }else{
3365 sqlite3_free(zNewFilename);
3366 p->db = savedDb;
3367 p->zDbFilename = zSavedFilename;
3368 }
3369 }else
3370
drhc2ce0be2014-05-29 12:36:14 +00003371 if( c=='o'
3372 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3373 ){
3374 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3375 if( nArg>2 ){
3376 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3377 rc = 1;
3378 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003379 }
drhc2ce0be2014-05-29 12:36:14 +00003380 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3381 if( nArg<2 ){
3382 fprintf(stderr, "Usage: .once FILE\n");
3383 rc = 1;
3384 goto meta_command_exit;
3385 }
3386 p->outCount = 2;
3387 }else{
3388 p->outCount = 0;
3389 }
3390 output_reset(p);
3391 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003392#ifdef SQLITE_OMIT_POPEN
3393 fprintf(stderr,"Error: pipes are not supported in this OS\n");
3394 rc = 1;
3395 p->out = stdout;
3396#else
drhc2ce0be2014-05-29 12:36:14 +00003397 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003398 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003399 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003400 p->out = stdout;
3401 rc = 1;
3402 }else{
drhc2ce0be2014-05-29 12:36:14 +00003403 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003404 }
drh8cd5b252015-03-02 22:06:43 +00003405#endif
drh75897232000-05-29 14:26:00 +00003406 }else{
drhc2ce0be2014-05-29 12:36:14 +00003407 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003408 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003409 if( strcmp(zFile,"off")!=0 ){
3410 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003411 }
drh75897232000-05-29 14:26:00 +00003412 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003413 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003414 } else {
drhc2ce0be2014-05-29 12:36:14 +00003415 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003416 }
3417 }
3418 }else
3419
drh078b1fd2012-09-21 13:40:02 +00003420 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3421 int i;
3422 for(i=1; i<nArg; i++){
3423 if( i>1 ) fprintf(p->out, " ");
3424 fprintf(p->out, "%s", azArg[i]);
3425 }
3426 fprintf(p->out, "\n");
3427 }else
3428
drhc2ce0be2014-05-29 12:36:14 +00003429 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003430 if( nArg >= 2) {
3431 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3432 }
3433 if( nArg >= 3) {
3434 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3435 }
3436 }else
3437
drhc2ce0be2014-05-29 12:36:14 +00003438 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003439 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003440 }else
3441
drhc2ce0be2014-05-29 12:36:14 +00003442 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3443 FILE *alt;
3444 if( nArg!=2 ){
3445 fprintf(stderr, "Usage: .read FILE\n");
3446 rc = 1;
3447 goto meta_command_exit;
3448 }
3449 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003450 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003451 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3452 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003453 }else{
shane9bd1b442009-10-23 01:27:39 +00003454 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003455 fclose(alt);
3456 }
3457 }else
3458
drhc2ce0be2014-05-29 12:36:14 +00003459 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003460 const char *zSrcFile;
3461 const char *zDb;
3462 sqlite3 *pSrc;
3463 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003464 int nTimeout = 0;
3465
drh9ff849f2009-02-04 20:55:57 +00003466 if( nArg==2 ){
3467 zSrcFile = azArg[1];
3468 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003469 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003470 zSrcFile = azArg[2];
3471 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003472 }else{
3473 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3474 rc = 1;
3475 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003476 }
3477 rc = sqlite3_open(zSrcFile, &pSrc);
3478 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003479 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003480 sqlite3_close(pSrc);
3481 return 1;
3482 }
drh05782482013-10-24 15:20:20 +00003483 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003484 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3485 if( pBackup==0 ){
3486 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3487 sqlite3_close(pSrc);
3488 return 1;
3489 }
drhdc2c4912009-02-04 22:46:47 +00003490 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3491 || rc==SQLITE_BUSY ){
3492 if( rc==SQLITE_BUSY ){
3493 if( nTimeout++ >= 3 ) break;
3494 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003495 }
3496 }
3497 sqlite3_backup_finish(pBackup);
3498 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003499 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003500 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003501 fprintf(stderr, "Error: source database is busy\n");
3502 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003503 }else{
3504 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003505 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003506 }
3507 sqlite3_close(pSrc);
3508 }else
3509
dan8d1edb92014-11-05 09:07:28 +00003510
3511 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3512 if( nArg==2 ){
3513 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003514#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3515 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3516#endif
dan8d1edb92014-11-05 09:07:28 +00003517 }else{
3518 fprintf(stderr, "Usage: .scanstats on|off\n");
3519 rc = 1;
3520 }
3521 }else
3522
drhc2ce0be2014-05-29 12:36:14 +00003523 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003524 ShellState data;
drh75897232000-05-29 14:26:00 +00003525 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003526 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003527 memcpy(&data, p, sizeof(data));
3528 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003529 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003530 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003531 int i;
drhf0693c82011-10-11 20:41:54 +00003532 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003533 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003534 char *new_argv[2], *new_colv[2];
3535 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3536 " type text,\n"
3537 " name text,\n"
3538 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003539 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003540 " sql text\n"
3541 ")";
3542 new_argv[1] = 0;
3543 new_colv[0] = "sql";
3544 new_colv[1] = 0;
3545 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003546 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003547 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003548 char *new_argv[2], *new_colv[2];
3549 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3550 " type text,\n"
3551 " name text,\n"
3552 " tbl_name text,\n"
3553 " rootpage integer,\n"
3554 " sql text\n"
3555 ")";
3556 new_argv[1] = 0;
3557 new_colv[0] = "sql";
3558 new_colv[1] = 0;
3559 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003560 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003561 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003562 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003563 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003564 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003565 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003566 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003567 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003568 "WHERE lower(tbl_name) LIKE shellstatic()"
3569 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003570 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003571 callback, &data, &zErrMsg);
3572 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003573 }
drhc2ce0be2014-05-29 12:36:14 +00003574 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003575 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003576 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003577 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003578 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003579 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003580 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003581 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003582 callback, &data, &zErrMsg
3583 );
drhc2ce0be2014-05-29 12:36:14 +00003584 }else{
3585 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3586 rc = 1;
3587 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003588 }
drh75897232000-05-29 14:26:00 +00003589 if( zErrMsg ){
3590 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003591 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003592 rc = 1;
3593 }else if( rc != SQLITE_OK ){
3594 fprintf(stderr,"Error: querying schema information\n");
3595 rc = 1;
3596 }else{
3597 rc = 0;
drh75897232000-05-29 14:26:00 +00003598 }
3599 }else
3600
drhabd4c722014-09-20 18:18:33 +00003601
3602#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3603 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3604 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003605 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003606 }else
3607#endif
3608
3609
drh340f5822013-06-27 13:01:21 +00003610#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003611 /* Undocumented commands for internal testing. Subject to change
3612 ** without notice. */
3613 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3614 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3615 int i, v;
3616 for(i=1; i<nArg; i++){
3617 v = booleanValue(azArg[i]);
3618 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3619 }
3620 }
3621 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3622 int i; sqlite3_int64 v;
3623 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003624 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003625 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003626 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003627 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003628 }
3629 }
3630 }else
drh340f5822013-06-27 13:01:21 +00003631#endif
drh348d19c2013-06-03 12:47:43 +00003632
drhc2ce0be2014-05-29 12:36:14 +00003633 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003634 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003635 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003636 rc = 1;
3637 }
drh6976c212014-07-24 12:09:47 +00003638 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003639 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003640 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003641 }
3642 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003643 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3644 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003645 }
drh75897232000-05-29 14:26:00 +00003646 }else
3647
drh62cdde52014-05-28 20:22:28 +00003648 if( c=='s'
3649 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003650 ){
3651 char *zCmd;
drh54027102014-08-06 14:36:53 +00003652 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003653 if( nArg<2 ){
3654 fprintf(stderr, "Usage: .system COMMAND\n");
3655 rc = 1;
3656 goto meta_command_exit;
3657 }
drhdcb3e3d2014-05-29 03:17:29 +00003658 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003659 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003660 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3661 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003662 }
drh54027102014-08-06 14:36:53 +00003663 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003664 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003665 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003666 }else
3667
drhc2ce0be2014-05-29 12:36:14 +00003668 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003669 int i;
drhc2ce0be2014-05-29 12:36:14 +00003670 if( nArg!=1 ){
3671 fprintf(stderr, "Usage: .show\n");
3672 rc = 1;
3673 goto meta_command_exit;
3674 }
mistachkin636bf9f2014-07-19 20:15:16 +00003675 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3676 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003677 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003678 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3679 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3680 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003681 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003682 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003683 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003684 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003685 fprintf(p->out,"%12.12s: ", "colseparator");
3686 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003687 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003688 fprintf(p->out,"%12.12s: ", "rowseparator");
3689 output_c_string(p->out, p->rowSeparator);
3690 fprintf(p->out, "\n");
3691 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3692 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003693 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003694 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003695 }
drhfeac5f82004-08-01 00:10:45 +00003696 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003697 }else
3698
drhc2ce0be2014-05-29 12:36:14 +00003699 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3700 if( nArg==2 ){
3701 p->statsOn = booleanValue(azArg[1]);
3702 }else{
3703 fprintf(stderr, "Usage: .stats on|off\n");
3704 rc = 1;
3705 }
shaneh642d8b82010-07-28 16:05:34 +00003706 }else
3707
drhc2ce0be2014-05-29 12:36:14 +00003708 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003709 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003710 char **azResult;
drh98781232012-04-23 12:38:05 +00003711 int nRow, nAlloc;
3712 char *zSql = 0;
3713 int ii;
drh05782482013-10-24 15:20:20 +00003714 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003715 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3716 if( rc ) return rc;
3717 zSql = sqlite3_mprintf(
3718 "SELECT name FROM sqlite_master"
3719 " WHERE type IN ('table','view')"
3720 " AND name NOT LIKE 'sqlite_%%'"
3721 " AND name LIKE ?1");
3722 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3723 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3724 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3725 if( strcmp(zDbName,"temp")==0 ){
3726 zSql = sqlite3_mprintf(
3727 "%z UNION ALL "
3728 "SELECT 'temp.' || name FROM sqlite_temp_master"
3729 " WHERE type IN ('table','view')"
3730 " AND name NOT LIKE 'sqlite_%%'"
3731 " AND name LIKE ?1", zSql);
3732 }else{
3733 zSql = sqlite3_mprintf(
3734 "%z UNION ALL "
3735 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3736 " WHERE type IN ('table','view')"
3737 " AND name NOT LIKE 'sqlite_%%'"
3738 " AND name LIKE ?1", zSql, zDbName, zDbName);
3739 }
drha50da102000-08-08 20:19:09 +00003740 }
drh98781232012-04-23 12:38:05 +00003741 sqlite3_finalize(pStmt);
3742 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3743 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3744 sqlite3_free(zSql);
3745 if( rc ) return rc;
3746 nRow = nAlloc = 0;
3747 azResult = 0;
3748 if( nArg>1 ){
3749 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003750 }else{
drh98781232012-04-23 12:38:05 +00003751 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3752 }
3753 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3754 if( nRow>=nAlloc ){
3755 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00003756 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00003757 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00003758 if( azNew==0 ){
3759 fprintf(stderr, "Error: out of memory\n");
3760 break;
3761 }
mistachkin8e189222015-04-19 21:43:16 +00003762 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00003763 azResult = azNew;
3764 }
3765 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3766 if( azResult[nRow] ) nRow++;
3767 }
3768 sqlite3_finalize(pStmt);
3769 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003770 int len, maxlen = 0;
3771 int i, j;
3772 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003773 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003774 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003775 if( len>maxlen ) maxlen = len;
3776 }
3777 nPrintCol = 80/(maxlen+2);
3778 if( nPrintCol<1 ) nPrintCol = 1;
3779 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3780 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003781 for(j=i; j<nRow; j+=nPrintRow){
3782 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003783 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003784 }
drh151b7d52013-05-06 20:28:54 +00003785 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003786 }
3787 }
drh98781232012-04-23 12:38:05 +00003788 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3789 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003790 }else
3791
shaneh96887e12011-02-10 21:08:58 +00003792 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003793 static const struct {
3794 const char *zCtrlName; /* Name of a test-control option */
3795 int ctrlCode; /* Integer code for that option */
3796 } aCtrl[] = {
3797 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3798 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3799 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3800 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3801 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3802 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3803 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3804 { "assert", SQLITE_TESTCTRL_ASSERT },
3805 { "always", SQLITE_TESTCTRL_ALWAYS },
3806 { "reserve", SQLITE_TESTCTRL_RESERVE },
3807 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3808 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003809 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003810 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003811 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003812 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003813 };
shaneh96887e12011-02-10 21:08:58 +00003814 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00003815 int rc2 = 0;
3816 int i, n2;
drh05782482013-10-24 15:20:20 +00003817 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003818
drhd416fe72011-03-17 16:45:50 +00003819 /* convert testctrl text option to value. allow any unique prefix
3820 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00003821 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003822 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00003823 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00003824 if( testctrl<0 ){
3825 testctrl = aCtrl[i].ctrlCode;
3826 }else{
drhb07028f2011-10-14 21:49:18 +00003827 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003828 testctrl = -1;
3829 break;
3830 }
3831 }
3832 }
drh348d19c2013-06-03 12:47:43 +00003833 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003834 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3835 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3836 }else{
3837 switch(testctrl){
3838
3839 /* sqlite3_test_control(int, db, int) */
3840 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3841 case SQLITE_TESTCTRL_RESERVE:
3842 if( nArg==3 ){
3843 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00003844 rc2 = sqlite3_test_control(testctrl, p->db, 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) */
drh2cf4acb2014-04-18 00:06:02 +00003853 case SQLITE_TESTCTRL_PRNG_SAVE:
3854 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003855 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003856 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003857 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00003858 rc2 = sqlite3_test_control(testctrl);
3859 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003860 } else {
3861 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3862 }
3863 break;
3864
3865 /* sqlite3_test_control(int, uint) */
3866 case SQLITE_TESTCTRL_PENDING_BYTE:
3867 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003868 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003869 rc2 = sqlite3_test_control(testctrl, opt);
3870 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003871 } else {
drhd416fe72011-03-17 16:45:50 +00003872 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3873 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003874 }
3875 break;
3876
3877 /* sqlite3_test_control(int, int) */
3878 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003879 case SQLITE_TESTCTRL_ALWAYS:
3880 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003881 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003882 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003883 rc2 = sqlite3_test_control(testctrl, opt);
3884 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003885 } else {
drhd416fe72011-03-17 16:45:50 +00003886 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3887 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003888 }
3889 break;
3890
3891 /* sqlite3_test_control(int, char *) */
3892#ifdef SQLITE_N_KEYWORD
3893 case SQLITE_TESTCTRL_ISKEYWORD:
3894 if( nArg==3 ){
3895 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00003896 rc2 = sqlite3_test_control(testctrl, opt);
3897 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003898 } else {
drhd416fe72011-03-17 16:45:50 +00003899 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3900 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003901 }
3902 break;
3903#endif
3904
drh1ffede82015-01-30 20:59:27 +00003905 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003906 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00003907 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003908 azArg[2],
drh8964b342015-01-29 17:54:52 +00003909 integerValue(azArg[3]),
3910 integerValue(azArg[4]));
mistachkin8e189222015-04-19 21:43:16 +00003911 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00003912 }else{
drh6f5a37a2015-03-27 02:27:20 +00003913 fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003914 }
3915 break;
3916
shaneh96887e12011-02-10 21:08:58 +00003917 case SQLITE_TESTCTRL_BITVEC_TEST:
3918 case SQLITE_TESTCTRL_FAULT_INSTALL:
3919 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3920 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3921 default:
drhd416fe72011-03-17 16:45:50 +00003922 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3923 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003924 break;
3925 }
3926 }
3927 }else
3928
drhc2ce0be2014-05-29 12:36:14 +00003929 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003930 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003931 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003932 }else
3933
drhc2ce0be2014-05-29 12:36:14 +00003934 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3935 if( nArg==2 ){
3936 enableTimer = booleanValue(azArg[1]);
3937 if( enableTimer && !HAS_TIMER ){
3938 fprintf(stderr, "Error: timer not available on this system.\n");
3939 enableTimer = 0;
3940 }
3941 }else{
3942 fprintf(stderr, "Usage: .timer on|off\n");
3943 rc = 1;
3944 }
shanehe2aa9d72009-11-06 17:20:17 +00003945 }else
3946
drhc2ce0be2014-05-29 12:36:14 +00003947 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003948 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003949 if( nArg!=2 ){
3950 fprintf(stderr, "Usage: .trace FILE|off\n");
3951 rc = 1;
3952 goto meta_command_exit;
3953 }
drh657b4a82015-03-19 13:30:41 +00003954 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00003955 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003956#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003957 if( p->traceOut==0 ){
3958 sqlite3_trace(p->db, 0, 0);
3959 }else{
3960 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3961 }
3962#endif
3963 }else
3964
drhf442e332014-09-10 19:01:14 +00003965#if SQLITE_USER_AUTHENTICATION
3966 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3967 if( nArg<2 ){
3968 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3969 rc = 1;
3970 goto meta_command_exit;
3971 }
drh7883ecf2014-09-11 16:19:31 +00003972 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003973 if( strcmp(azArg[1],"login")==0 ){
3974 if( nArg!=4 ){
3975 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3976 rc = 1;
3977 goto meta_command_exit;
3978 }
drhd39c40f2014-09-11 00:27:53 +00003979 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3980 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003981 if( rc ){
3982 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3983 rc = 1;
3984 }
3985 }else if( strcmp(azArg[1],"add")==0 ){
3986 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003987 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003988 rc = 1;
3989 goto meta_command_exit;
3990 }
drhd39c40f2014-09-11 00:27:53 +00003991 rc = sqlite3_user_add(p->db, azArg[2],
3992 azArg[3], (int)strlen(azArg[3]),
3993 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003994 if( rc ){
3995 fprintf(stderr, "User-Add failed: %d\n", rc);
3996 rc = 1;
3997 }
3998 }else if( strcmp(azArg[1],"edit")==0 ){
3999 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00004000 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004001 rc = 1;
4002 goto meta_command_exit;
4003 }
drhd39c40f2014-09-11 00:27:53 +00004004 rc = sqlite3_user_change(p->db, azArg[2],
4005 azArg[3], (int)strlen(azArg[3]),
4006 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004007 if( rc ){
4008 fprintf(stderr, "User-Edit failed: %d\n", rc);
4009 rc = 1;
4010 }
4011 }else if( strcmp(azArg[1],"delete")==0 ){
4012 if( nArg!=3 ){
4013 fprintf(stderr, "Usage: .user delete USER\n");
4014 rc = 1;
4015 goto meta_command_exit;
4016 }
4017 rc = sqlite3_user_delete(p->db, azArg[2]);
4018 if( rc ){
4019 fprintf(stderr, "User-Delete failed: %d\n", rc);
4020 rc = 1;
4021 }
4022 }else{
4023 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
4024 rc = 1;
4025 goto meta_command_exit;
4026 }
4027 }else
4028#endif /* SQLITE_USER_AUTHENTICATION */
4029
drh9fd301b2011-06-03 13:28:22 +00004030 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00004031 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004032 sqlite3_libversion(), sqlite3_sourceid());
4033 }else
4034
drhde60fc22011-12-14 17:53:36 +00004035 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4036 const char *zDbName = nArg==2 ? azArg[1] : "main";
4037 char *zVfsName = 0;
4038 if( p->db ){
4039 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4040 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00004041 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004042 sqlite3_free(zVfsName);
4043 }
4044 }
4045 }else
4046
drhcef4fc82012-09-21 22:50:45 +00004047#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4048 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4049 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004050 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004051 }else
4052#endif
4053
drhc2ce0be2014-05-29 12:36:14 +00004054 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004055 int j;
drh43617e92006-03-06 20:55:46 +00004056 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004057 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004058 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004059 }
4060 }else
4061
4062 {
shane9bd1b442009-10-23 01:27:39 +00004063 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004064 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004065 rc = 1;
drh75897232000-05-29 14:26:00 +00004066 }
drh67505e72002-04-19 12:34:06 +00004067
drhc2ce0be2014-05-29 12:36:14 +00004068meta_command_exit:
4069 if( p->outCount ){
4070 p->outCount--;
4071 if( p->outCount==0 ) output_reset(p);
4072 }
drh67505e72002-04-19 12:34:06 +00004073 return rc;
drh75897232000-05-29 14:26:00 +00004074}
4075
drh67505e72002-04-19 12:34:06 +00004076/*
drh91a66392007-09-07 01:12:32 +00004077** Return TRUE if a semicolon occurs anywhere in the first N characters
4078** of string z[].
drh324ccef2003-02-05 14:06:20 +00004079*/
drh9f099fd2013-08-06 14:01:46 +00004080static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004081 int i;
4082 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4083 return 0;
drh324ccef2003-02-05 14:06:20 +00004084}
4085
4086/*
drh70c7a4b2003-04-26 03:03:06 +00004087** Test to see if a line consists entirely of whitespace.
4088*/
4089static int _all_whitespace(const char *z){
4090 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004091 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004092 if( *z=='/' && z[1]=='*' ){
4093 z += 2;
4094 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4095 if( *z==0 ) return 0;
4096 z++;
4097 continue;
4098 }
4099 if( *z=='-' && z[1]=='-' ){
4100 z += 2;
4101 while( *z && *z!='\n' ){ z++; }
4102 if( *z==0 ) return 1;
4103 continue;
4104 }
4105 return 0;
4106 }
4107 return 1;
4108}
4109
4110/*
drha9b17162003-04-29 18:01:28 +00004111** Return TRUE if the line typed in is an SQL command terminator other
4112** than a semi-colon. The SQL Server style "go" command is understood
4113** as is the Oracle "/".
4114*/
drh9f099fd2013-08-06 14:01:46 +00004115static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004116 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004117 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4118 return 1; /* Oracle */
4119 }
drhf0693c82011-10-11 20:41:54 +00004120 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004121 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004122 return 1; /* SQL Server */
4123 }
4124 return 0;
4125}
4126
4127/*
drh233a5312008-12-18 22:25:13 +00004128** Return true if zSql is a complete SQL statement. Return false if it
4129** ends in the middle of a string literal or C-style comment.
4130*/
drh9f099fd2013-08-06 14:01:46 +00004131static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004132 int rc;
4133 if( zSql==0 ) return 1;
4134 zSql[nSql] = ';';
4135 zSql[nSql+1] = 0;
4136 rc = sqlite3_complete(zSql);
4137 zSql[nSql] = 0;
4138 return rc;
4139}
4140
4141/*
drh67505e72002-04-19 12:34:06 +00004142** Read input from *in and process it. If *in==0 then input
4143** is interactive - the user is typing it it. Otherwise, input
4144** is coming from a file or device. A prompt is issued and history
4145** is saved only if input is interactive. An interrupt signal will
4146** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004147**
4148** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004149*/
drhdcd87a92014-08-18 13:45:42 +00004150static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004151 char *zLine = 0; /* A single input line */
4152 char *zSql = 0; /* Accumulated SQL text */
4153 int nLine; /* Length of current line */
4154 int nSql = 0; /* Bytes of zSql[] used */
4155 int nAlloc = 0; /* Allocated zSql[] space */
4156 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4157 char *zErrMsg; /* Error message returned */
4158 int rc; /* Error code */
4159 int errCnt = 0; /* Number of errors seen */
4160 int lineno = 0; /* Current line number */
4161 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004162
4163 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4164 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004165 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004166 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004167 /* End of input */
4168 if( stdin_is_interactive ) printf("\n");
4169 break;
drhc49f44e2006-10-26 18:15:42 +00004170 }
drh67505e72002-04-19 12:34:06 +00004171 if( seenInterrupt ){
4172 if( in!=0 ) break;
4173 seenInterrupt = 0;
4174 }
drhc28490c2006-10-26 14:25:58 +00004175 lineno++;
drh849a9d92013-12-21 15:46:06 +00004176 if( nSql==0 && _all_whitespace(zLine) ){
4177 if( p->echoOn ) printf("%s\n", zLine);
4178 continue;
4179 }
drh2af0b2d2002-02-21 02:25:02 +00004180 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004181 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004182 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004183 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004184 break;
4185 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004186 errCnt++;
4187 }
drhdaffd0e2001-04-11 14:28:42 +00004188 continue;
4189 }
drh9f099fd2013-08-06 14:01:46 +00004190 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004191 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004192 }
drh9f099fd2013-08-06 14:01:46 +00004193 nLine = strlen30(zLine);
4194 if( nSql+nLine+2>=nAlloc ){
4195 nAlloc = nSql+nLine+100;
4196 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004197 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004198 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004199 exit(1);
4200 }
drhdaffd0e2001-04-11 14:28:42 +00004201 }
drh9f099fd2013-08-06 14:01:46 +00004202 nSqlPrior = nSql;
4203 if( nSql==0 ){
4204 int i;
4205 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004206 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004207 memcpy(zSql, zLine+i, nLine+1-i);
4208 startline = lineno;
4209 nSql = nLine-i;
4210 }else{
4211 zSql[nSql++] = '\n';
4212 memcpy(zSql+nSql, zLine, nLine+1);
4213 nSql += nLine;
4214 }
4215 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004216 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004217 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004218 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004219 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004220 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004221 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004222 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004223 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004224 char zPrefix[100];
4225 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004226 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004227 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004228 }else{
shane9bd1b442009-10-23 01:27:39 +00004229 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004230 }
drh7f953e22002-07-13 17:33:45 +00004231 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004232 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004233 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004234 zErrMsg = 0;
4235 }else{
shaned2bed1c2009-10-21 03:56:54 +00004236 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004237 }
drhc49f44e2006-10-26 18:15:42 +00004238 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004239 }
drhdaffd0e2001-04-11 14:28:42 +00004240 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004241 if( p->outCount ){
4242 output_reset(p);
4243 p->outCount = 0;
4244 }
drh9f099fd2013-08-06 14:01:46 +00004245 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004246 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004247 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004248 }
4249 }
drh9f099fd2013-08-06 14:01:46 +00004250 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004251 if( !_all_whitespace(zSql) ){
4252 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004253 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004254 }
drhdaffd0e2001-04-11 14:28:42 +00004255 }
drh1f9ca2c2015-08-25 16:57:52 +00004256 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00004257 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004258 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004259}
4260
drh67505e72002-04-19 12:34:06 +00004261/*
4262** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004263** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004264*/
4265static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004266 static char *home_dir = NULL;
4267 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004268
drh4ace5362014-11-10 14:42:28 +00004269#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4270 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004271 {
4272 struct passwd *pwent;
4273 uid_t uid = getuid();
4274 if( (pwent=getpwuid(uid)) != NULL) {
4275 home_dir = pwent->pw_dir;
4276 }
drh67505e72002-04-19 12:34:06 +00004277 }
4278#endif
4279
chw65d3c132007-11-12 21:09:10 +00004280#if defined(_WIN32_WCE)
4281 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4282 */
drh85e72432012-04-11 11:38:53 +00004283 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004284#else
4285
drh83905c92012-06-21 13:00:37 +00004286#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004287 if (!home_dir) {
4288 home_dir = getenv("USERPROFILE");
4289 }
4290#endif
4291
drh67505e72002-04-19 12:34:06 +00004292 if (!home_dir) {
4293 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004294 }
4295
drh83905c92012-06-21 13:00:37 +00004296#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004297 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004298 char *zDrive, *zPath;
4299 int n;
4300 zDrive = getenv("HOMEDRIVE");
4301 zPath = getenv("HOMEPATH");
4302 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004303 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004304 home_dir = malloc( n );
4305 if( home_dir==0 ) return 0;
4306 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4307 return home_dir;
4308 }
4309 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004310 }
4311#endif
4312
chw65d3c132007-11-12 21:09:10 +00004313#endif /* !_WIN32_WCE */
4314
drh67505e72002-04-19 12:34:06 +00004315 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004316 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004317 char *z = malloc( n );
4318 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004319 home_dir = z;
4320 }
drhe98d4fa2002-04-21 19:06:22 +00004321
drh67505e72002-04-19 12:34:06 +00004322 return home_dir;
4323}
4324
4325/*
4326** Read input from the file given by sqliterc_override. Or if that
4327** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004328**
4329** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004330*/
drh534f4df2015-02-28 14:03:35 +00004331static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004332 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004333 const char *sqliterc_override /* Name of config file. NULL to use default */
4334){
persicom7e2dfdd2002-04-18 02:46:52 +00004335 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004336 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004337 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004338 FILE *in = NULL;
4339
4340 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004341 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004342 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004343 fprintf(stderr, "-- warning: cannot find home directory;"
4344 " cannot read ~/.sqliterc\n");
4345 return;
drhe98d4fa2002-04-21 19:06:22 +00004346 }
drh2f3de322012-06-27 16:41:31 +00004347 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004348 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4349 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004350 }
drha1f9b5e2004-02-14 16:31:02 +00004351 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004352 if( in ){
drhc28490c2006-10-26 14:25:58 +00004353 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004354 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004355 }
drh534f4df2015-02-28 14:03:35 +00004356 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004357 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004358 }
drh85e72432012-04-11 11:38:53 +00004359 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004360}
4361
drh67505e72002-04-19 12:34:06 +00004362/*
drhe1e38c42003-05-04 18:30:59 +00004363** Show available command line options
4364*/
4365static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004366 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004367 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004368 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004369 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004370 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004371 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004372 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004373 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004374 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004375#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4376 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4377#endif
drhcc3b4f82012-02-07 14:13:50 +00004378 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004379 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004380 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004381 " -line set output mode to 'line'\n"
4382 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004383 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004384 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004385#ifdef SQLITE_ENABLE_MULTIPLEX
4386 " -multiplex enable the multiplexor VFS\n"
4387#endif
mistachkine0d68852014-12-11 03:12:33 +00004388 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004389 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004390 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4391 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004392 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004393 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004394 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004395 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004396#ifdef SQLITE_ENABLE_VFSTRACE
4397 " -vfstrace enable tracing of all VFS calls\n"
4398#endif
drhe1e38c42003-05-04 18:30:59 +00004399;
4400static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004401 fprintf(stderr,
4402 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4403 "FILENAME is the name of an SQLite database. A new database is created\n"
4404 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004405 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004406 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004407 }else{
4408 fprintf(stderr, "Use the -help option for additional information\n");
4409 }
4410 exit(1);
4411}
4412
4413/*
drh67505e72002-04-19 12:34:06 +00004414** Initialize the state information in data
4415*/
drhdcd87a92014-08-18 13:45:42 +00004416static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004417 memset(data, 0, sizeof(*data));
4418 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004419 memcpy(data->colSeparator,SEP_Column, 2);
4420 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004421 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004422 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004423 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004424 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004425 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004426 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4427 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004428}
4429
drh98d312f2012-10-25 15:23:14 +00004430/*
drh5c7976f2014-02-10 19:59:27 +00004431** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004432*/
4433#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004434static void printBold(const char *zText){
4435 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4436 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4437 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4438 SetConsoleTextAttribute(out,
4439 FOREGROUND_RED|FOREGROUND_INTENSITY
4440 );
4441 printf("%s", zText);
4442 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004443}
4444#else
drh5c7976f2014-02-10 19:59:27 +00004445static void printBold(const char *zText){
4446 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004447}
4448#endif
4449
4450/*
drh98d312f2012-10-25 15:23:14 +00004451** Get the argument to an --option. Throw an error and die if no argument
4452** is available.
4453*/
4454static char *cmdline_option_value(int argc, char **argv, int i){
4455 if( i==argc ){
4456 fprintf(stderr, "%s: Error: missing argument to %s\n",
4457 argv[0], argv[argc-1]);
4458 exit(1);
4459 }
4460 return argv[i];
4461}
4462
mistachkin44723ce2015-03-21 02:22:37 +00004463int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004464 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004465 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004466 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004467 int i;
drhc28490c2006-10-26 14:25:58 +00004468 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004469 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004470 int readStdin = 1;
4471 int nCmd = 0;
4472 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004473
drh69b30ab2014-02-27 15:11:52 +00004474#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004475 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4476 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4477 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4478 exit(1);
4479 }
drhc7181902014-02-27 15:04:13 +00004480#endif
drh047d4532015-01-18 20:30:23 +00004481 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004482 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004483 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004484 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004485 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004486
drh44c2eb12003-04-30 11:38:26 +00004487 /* Make sure we have a valid signal handler early, before anything
4488 ** else is done.
4489 */
drh4c504392000-10-16 22:06:40 +00004490#ifdef SIGINT
4491 signal(SIGINT, interrupt_handler);
4492#endif
drh44c2eb12003-04-30 11:38:26 +00004493
drhac5649a2014-11-28 13:35:03 +00004494#ifdef SQLITE_SHELL_DBNAME_PROC
4495 {
4496 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4497 ** of a C-function that will provide the name of the database file. Use
4498 ** this compile-time option to embed this shell program in larger
4499 ** applications. */
4500 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4501 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4502 warnInmemoryDb = 0;
4503 }
4504#endif
4505
drh22fbcb82004-02-01 01:22:50 +00004506 /* Do an initial pass through the command-line argument to locate
4507 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004508 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004509 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004510 */
drh98d312f2012-10-25 15:23:14 +00004511 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004512 char *z;
drhc28490c2006-10-26 14:25:58 +00004513 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004514 if( z[0]!='-' ){
4515 if( data.zDbFilename==0 ){
4516 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004517 }else{
4518 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4519 ** mean that nothing is read from stdin */
4520 readStdin = 0;
4521 nCmd++;
4522 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4523 if( azCmd==0 ){
4524 fprintf(stderr, "out of memory\n");
4525 exit(1);
4526 }
4527 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004528 }
drh98d312f2012-10-25 15:23:14 +00004529 }
drhcc3b4f82012-02-07 14:13:50 +00004530 if( z[1]=='-' ) z++;
4531 if( strcmp(z,"-separator")==0
4532 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004533 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004534 || strcmp(z,"-cmd")==0
4535 ){
drh98d312f2012-10-25 15:23:14 +00004536 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004537 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004538 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004539 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004540 /* Need to check for batch mode here to so we can avoid printing
4541 ** informational messages (like from process_sqliterc) before
4542 ** we do the actual processing of arguments later in a second pass.
4543 */
shanef69573d2009-10-24 02:06:14 +00004544 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004545 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004546#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004547 const char *zSize;
4548 sqlite3_int64 szHeap;
4549
drh98d312f2012-10-25 15:23:14 +00004550 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004551 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004552 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004553 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4554#endif
drh44dec872014-08-30 15:49:25 +00004555 }else if( strcmp(z,"-scratch")==0 ){
4556 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004557 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004558 if( sz>400000 ) sz = 400000;
4559 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004560 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004561 if( n>10 ) n = 10;
4562 if( n<1 ) n = 1;
4563 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4564 data.shellFlgs |= SHFLG_Scratch;
4565 }else if( strcmp(z,"-pagecache")==0 ){
4566 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004567 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004568 if( sz>70000 ) sz = 70000;
4569 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004570 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004571 if( n<10 ) n = 10;
4572 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4573 data.shellFlgs |= SHFLG_Pagecache;
4574 }else if( strcmp(z,"-lookaside")==0 ){
4575 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004576 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004577 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004578 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004579 if( n<0 ) n = 0;
4580 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4581 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004582#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004583 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004584 extern int vfstrace_register(
4585 const char *zTraceName,
4586 const char *zOldVfsName,
4587 int (*xOut)(const char*,void*),
4588 void *pOutArg,
4589 int makeDefault
4590 );
drh2b625e22011-03-16 17:05:28 +00004591 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004592#endif
drh6f25e892011-07-08 17:02:57 +00004593#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004594 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004595 extern int sqlite3_multiple_initialize(const char*,int);
4596 sqlite3_multiplex_initialize(0, 1);
4597#endif
drh7d9f3942013-04-03 01:26:54 +00004598 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004599 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4600 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004601 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004602 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004603 if( pVfs ){
4604 sqlite3_vfs_register(pVfs, 1);
4605 }else{
4606 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4607 exit(1);
4608 }
drh44c2eb12003-04-30 11:38:26 +00004609 }
4610 }
drh98d312f2012-10-25 15:23:14 +00004611 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004612#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004613 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004614 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004615#else
shane86f5bdb2009-10-24 02:00:07 +00004616 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4617 return 1;
drh01b41712005-08-29 23:06:23 +00004618#endif
drh98d312f2012-10-25 15:23:14 +00004619 }
4620 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004621
drh3be094d2015-08-29 19:03:33 +00004622#ifdef SQLITE_ENABLE_JSON1
4623 {
4624 extern int sqlite3_json_init(sqlite3*);
4625 sqlite3_auto_extension((void(*)(void))sqlite3_json_init);
4626 }
4627#endif
4628
drh44c2eb12003-04-30 11:38:26 +00004629 /* Go ahead and open the database file if it already exists. If the
4630 ** file does not exist, delay opening it. This prevents empty database
4631 ** files from being created if a user mistypes the database name argument
4632 ** to the sqlite command-line tool.
4633 */
drhc8d74412004-08-31 23:41:26 +00004634 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004635 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004636 }
4637
drh22fbcb82004-02-01 01:22:50 +00004638 /* Process the initialization file if there is one. If no -init option
4639 ** is given on the command line, look for a file named ~/.sqliterc and
4640 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004641 */
drh534f4df2015-02-28 14:03:35 +00004642 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004643
drh22fbcb82004-02-01 01:22:50 +00004644 /* Make a second pass through the command-line argument and set
4645 ** options. This second pass is delayed until after the initialization
4646 ** file is processed so that the command-line arguments will override
4647 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004648 */
drh98d312f2012-10-25 15:23:14 +00004649 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004650 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004651 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004652 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004653 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004654 i++;
4655 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004656 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004657 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004658 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004659 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004660 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004661 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004662 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004663 }else if( strcmp(z,"-csv")==0 ){
4664 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004665 memcpy(data.colSeparator,",",2);
4666 }else if( strcmp(z,"-ascii")==0 ){
4667 data.mode = MODE_Ascii;
4668 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004669 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004670 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004671 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004672 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004673 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4674 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004675 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004676 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004677 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004678 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004679 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004680 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004681 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004682 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004683 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004684 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004685 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004686 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004687 }else if( strcmp(z,"-eqp")==0 ){
4688 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004689 }else if( strcmp(z,"-stats")==0 ){
4690 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004691 }else if( strcmp(z,"-scanstats")==0 ){
4692 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004693 }else if( strcmp(z,"-backslash")==0 ){
4694 /* Undocumented command-line option: -backslash
4695 ** Causes C-style backslash escapes to be evaluated in SQL statements
4696 ** prior to sending the SQL into SQLite. Useful for injecting
4697 ** crazy bytes in the middle of SQL statements for testing and debugging.
4698 */
4699 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004700 }else if( strcmp(z,"-bail")==0 ){
4701 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004702 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004703 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004704 return 0;
drhc28490c2006-10-26 14:25:58 +00004705 }else if( strcmp(z,"-interactive")==0 ){
4706 stdin_is_interactive = 1;
4707 }else if( strcmp(z,"-batch")==0 ){
4708 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004709 }else if( strcmp(z,"-heap")==0 ){
4710 i++;
drh44dec872014-08-30 15:49:25 +00004711 }else if( strcmp(z,"-scratch")==0 ){
4712 i+=2;
4713 }else if( strcmp(z,"-pagecache")==0 ){
4714 i+=2;
4715 }else if( strcmp(z,"-lookaside")==0 ){
4716 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004717 }else if( strcmp(z,"-mmap")==0 ){
4718 i++;
drha7e61d82011-03-12 17:02:57 +00004719 }else if( strcmp(z,"-vfs")==0 ){
4720 i++;
drh6f25e892011-07-08 17:02:57 +00004721#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004722 }else if( strcmp(z,"-vfstrace")==0 ){
4723 i++;
drh6f25e892011-07-08 17:02:57 +00004724#endif
4725#ifdef SQLITE_ENABLE_MULTIPLEX
4726 }else if( strcmp(z,"-multiplex")==0 ){
4727 i++;
4728#endif
drhcc3b4f82012-02-07 14:13:50 +00004729 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004730 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004731 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004732 /* Run commands that follow -cmd first and separately from commands
4733 ** that simply appear on the command-line. This seems goofy. It would
4734 ** be better if all commands ran in the order that they appear. But
4735 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004736 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004737 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004738 if( z[0]=='.' ){
4739 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004740 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004741 }else{
drh05782482013-10-24 15:20:20 +00004742 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004743 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4744 if( zErrMsg!=0 ){
4745 fprintf(stderr,"Error: %s\n", zErrMsg);
4746 if( bail_on_error ) return rc!=0 ? rc : 1;
4747 }else if( rc!=0 ){
4748 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4749 if( bail_on_error ) return rc;
4750 }
4751 }
drh1e5d0e92000-05-31 23:33:17 +00004752 }else{
shane86f5bdb2009-10-24 02:00:07 +00004753 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004754 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004755 return 1;
4756 }
4757 }
drh44c2eb12003-04-30 11:38:26 +00004758
drhac5649a2014-11-28 13:35:03 +00004759 if( !readStdin ){
4760 /* Run all arguments that do not begin with '-' as if they were separate
4761 ** command-line inputs, except for the argToSkip argument which contains
4762 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004763 */
drhac5649a2014-11-28 13:35:03 +00004764 for(i=0; i<nCmd; i++){
4765 if( azCmd[i][0]=='.' ){
4766 rc = do_meta_command(azCmd[i], &data);
4767 if( rc ) return rc==2 ? 0 : rc;
4768 }else{
4769 open_db(&data, 0);
4770 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4771 if( zErrMsg!=0 ){
4772 fprintf(stderr,"Error: %s\n", zErrMsg);
4773 return rc!=0 ? rc : 1;
4774 }else if( rc!=0 ){
4775 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4776 return rc;
4777 }
drh6ff13852001-11-25 13:18:23 +00004778 }
drh75897232000-05-29 14:26:00 +00004779 }
drhac5649a2014-11-28 13:35:03 +00004780 free(azCmd);
drh75897232000-05-29 14:26:00 +00004781 }else{
drh44c2eb12003-04-30 11:38:26 +00004782 /* Run commands received from standard input
4783 */
drhc28490c2006-10-26 14:25:58 +00004784 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004785 char *zHome;
4786 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004787 int nHistory;
drh75897232000-05-29 14:26:00 +00004788 printf(
drh743e0032011-12-12 16:51:50 +00004789 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004790 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004791 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004792 );
drhb3735912014-02-10 16:13:42 +00004793 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004794 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004795 printBold("transient in-memory database");
4796 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004797 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004798 }
drh67505e72002-04-19 12:34:06 +00004799 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004800 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004801 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004802 if( (zHistory = malloc(nHistory))!=0 ){
4803 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4804 }
drh67505e72002-04-19 12:34:06 +00004805 }
drhf5ed7ad2015-06-15 14:43:25 +00004806 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00004807 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004808 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004809 shell_stifle_history(100);
4810 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004811 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004812 }
drhdaffd0e2001-04-11 14:28:42 +00004813 }else{
drhc28490c2006-10-26 14:25:58 +00004814 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004815 }
4816 }
drh33048c02001-10-01 14:29:22 +00004817 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004818 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004819 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004820 }
drh05782482013-10-24 15:20:20 +00004821 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004822 return rc;
drh75897232000-05-29 14:26:00 +00004823}