blob: d097e913a3b43cc2466522f83218fa07d75b411b [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
1322 return 0;
1323}
1324
1325/*
dan8d1edb92014-11-05 09:07:28 +00001326** Display scan stats.
1327*/
1328static void display_scanstats(
1329 sqlite3 *db, /* Database to query */
1330 ShellState *pArg /* Pointer to ShellState */
1331){
drhf5ed7ad2015-06-15 14:43:25 +00001332#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1333 UNUSED_PARAMETER(db);
1334 UNUSED_PARAMETER(pArg);
1335#else
drh15f23c22014-11-06 12:46:16 +00001336 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001337 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001338 mx = 0;
1339 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001340 double rEstLoop = 1.0;
1341 for(i=n=0; 1; i++){
1342 sqlite3_stmt *p = pArg->pStmt;
1343 sqlite3_int64 nLoop, nVisit;
1344 double rEst;
1345 int iSid;
1346 const char *zExplain;
1347 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1348 break;
1349 }
1350 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001351 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001352 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001353 if( n==0 ){
1354 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001355 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001356 }
drh42f30bc2014-11-06 12:08:21 +00001357 n++;
1358 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1359 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1360 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1361 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1362 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001363 fprintf(pArg->out,
1364 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001365 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001366 );
dan8d1edb92014-11-05 09:07:28 +00001367 }
dan8d1edb92014-11-05 09:07:28 +00001368 }
dan8d1edb92014-11-05 09:07:28 +00001369 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001370#endif
dan8d1edb92014-11-05 09:07:28 +00001371}
1372
1373/*
dana98bf362013-11-13 18:35:01 +00001374** Parameter azArray points to a zero-terminated array of strings. zStr
1375** points to a single nul-terminated string. Return non-zero if zStr
1376** is equal, according to strcmp(), to any of the strings in the array.
1377** Otherwise, return zero.
1378*/
1379static int str_in_array(const char *zStr, const char **azArray){
1380 int i;
1381 for(i=0; azArray[i]; i++){
1382 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1383 }
1384 return 0;
1385}
1386
1387/*
1388** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001389** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001390** spaces each opcode should be indented before it is output.
1391**
1392** The indenting rules are:
1393**
1394** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1395** all opcodes that occur between the p2 jump destination and the opcode
1396** itself by 2 spaces.
1397**
drh01752bc2013-11-14 23:59:33 +00001398** * For each "Goto", if the jump destination is earlier in the program
1399** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001400** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001401** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001402** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001403** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001404*/
drhdcd87a92014-08-18 13:45:42 +00001405static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001406 const char *zSql; /* The text of the SQL statement */
1407 const char *z; /* Used to check if this is an EXPLAIN */
1408 int *abYield = 0; /* True if op is an OP_Yield */
1409 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001410 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001411
drh8ad0de32014-03-20 18:45:27 +00001412 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1413 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001414 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1415 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001416 const char *azGoto[] = { "Goto", 0 };
1417
1418 /* Try to figure out if this is really an EXPLAIN statement. If this
1419 ** cannot be verified, return early. */
1420 zSql = sqlite3_sql(pSql);
1421 if( zSql==0 ) return;
1422 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1423 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1424
1425 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1426 int i;
danc4650bb2013-11-18 08:41:06 +00001427 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001428 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001429
1430 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1431 ** p2 is an instruction address, set variable p2op to the index of that
1432 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1433 ** the current instruction is part of a sub-program generated by an
1434 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001435 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001436 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001437
1438 /* Grow the p->aiIndent array as required */
1439 if( iOp>=nAlloc ){
1440 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001441 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1442 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001443 }
1444 abYield[iOp] = str_in_array(zOp, azYield);
1445 p->aiIndent[iOp] = 0;
1446 p->nIndent = iOp+1;
1447
1448 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001449 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001450 }
drhfe705102014-03-06 13:38:37 +00001451 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1452 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1453 ){
drhe73f0592014-01-21 22:25:45 +00001454 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001455 }
1456 }
1457
danc4650bb2013-11-18 08:41:06 +00001458 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001459 sqlite3_free(abYield);
1460 sqlite3_reset(pSql);
1461}
1462
1463/*
1464** Free the array allocated by explain_data_prepare().
1465*/
drhdcd87a92014-08-18 13:45:42 +00001466static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001467 sqlite3_free(p->aiIndent);
1468 p->aiIndent = 0;
1469 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001470 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001471}
1472
1473/*
shane626a6e42009-10-22 17:30:15 +00001474** Execute a statement or set of statements. Print
1475** any result rows/columns depending on the current mode
1476** set via the supplied callback.
1477**
1478** This is very similar to SQLite's built-in sqlite3_exec()
1479** function except it takes a slightly different callback
1480** and callback data argument.
1481*/
1482static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001483 sqlite3 *db, /* An open database */
1484 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001485 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001486 /* (not the same as sqlite3_exec) */
1487 ShellState *pArg, /* Pointer to ShellState */
1488 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001489){
dan4564ced2010-01-05 04:59:56 +00001490 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1491 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001492 int rc2;
dan4564ced2010-01-05 04:59:56 +00001493 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001494
1495 if( pzErrMsg ){
1496 *pzErrMsg = NULL;
1497 }
1498
shaneb9fc17d2009-10-22 21:23:35 +00001499 while( zSql[0] && (SQLITE_OK == rc) ){
1500 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1501 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001502 if( pzErrMsg ){
1503 *pzErrMsg = save_err_msg(db);
1504 }
1505 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001506 if( !pStmt ){
1507 /* this happens for a comment or white-space */
1508 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001509 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001510 continue;
1511 }
shane626a6e42009-10-22 17:30:15 +00001512
shaneh642d8b82010-07-28 16:05:34 +00001513 /* save off the prepared statment handle and reset row count */
1514 if( pArg ){
1515 pArg->pStmt = pStmt;
1516 pArg->cnt = 0;
1517 }
1518
shanehb7977c52010-01-18 18:17:10 +00001519 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001520 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001521 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001522 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001523 }
shanehb7977c52010-01-18 18:17:10 +00001524
drhefbf3b12014-02-28 20:47:24 +00001525 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1526 if( pArg && pArg->autoEQP ){
1527 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001528 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1529 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001530 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1531 if( rc==SQLITE_OK ){
1532 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1533 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1534 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1535 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1536 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1537 }
1538 }
1539 sqlite3_finalize(pExplain);
1540 sqlite3_free(zEQP);
1541 }
1542
dana98bf362013-11-13 18:35:01 +00001543 /* If the shell is currently in ".explain" mode, gather the extra
1544 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001545 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001546 explain_data_prepare(pArg, pStmt);
1547 }
1548
shaneb9fc17d2009-10-22 21:23:35 +00001549 /* perform the first step. this will tell us if we
1550 ** have a result set or not and how wide it is.
1551 */
1552 rc = sqlite3_step(pStmt);
1553 /* if we have a result set... */
1554 if( SQLITE_ROW == rc ){
1555 /* if we have a callback... */
1556 if( xCallback ){
1557 /* allocate space for col name ptr, value ptr, and type */
1558 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001559 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001560 if( !pData ){
1561 rc = SQLITE_NOMEM;
1562 }else{
1563 char **azCols = (char **)pData; /* Names of result columns */
1564 char **azVals = &azCols[nCol]; /* Results */
1565 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001566 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001567 assert(sizeof(int) <= sizeof(char *));
1568 /* save off ptrs to column names */
1569 for(i=0; i<nCol; i++){
1570 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1571 }
shaneb9fc17d2009-10-22 21:23:35 +00001572 do{
1573 /* extract the data and data types */
1574 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001575 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001576 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001577 azVals[i] = "";
1578 }else{
1579 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1580 }
shaneb9fc17d2009-10-22 21:23:35 +00001581 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1582 rc = SQLITE_NOMEM;
1583 break; /* from for */
1584 }
1585 } /* end for */
1586
1587 /* if data and types extracted successfully... */
1588 if( SQLITE_ROW == rc ){
1589 /* call the supplied callback with the result row data */
1590 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1591 rc = SQLITE_ABORT;
1592 }else{
1593 rc = sqlite3_step(pStmt);
1594 }
1595 }
1596 } while( SQLITE_ROW == rc );
1597 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001598 }
1599 }else{
1600 do{
1601 rc = sqlite3_step(pStmt);
1602 } while( rc == SQLITE_ROW );
1603 }
1604 }
1605
dana98bf362013-11-13 18:35:01 +00001606 explain_data_delete(pArg);
1607
shaneh642d8b82010-07-28 16:05:34 +00001608 /* print usage stats if stats on */
1609 if( pArg && pArg->statsOn ){
1610 display_stats(db, pArg, 0);
1611 }
1612
dan8d1edb92014-11-05 09:07:28 +00001613 /* print loop-counters if required */
1614 if( pArg && pArg->scanstatsOn ){
1615 display_scanstats(db, pArg);
1616 }
1617
dan4564ced2010-01-05 04:59:56 +00001618 /* Finalize the statement just executed. If this fails, save a
1619 ** copy of the error message. Otherwise, set zSql to point to the
1620 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001621 rc2 = sqlite3_finalize(pStmt);
1622 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001623 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001624 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001625 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001626 }else if( pzErrMsg ){
1627 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001628 }
shaneh642d8b82010-07-28 16:05:34 +00001629
1630 /* clear saved stmt handle */
1631 if( pArg ){
1632 pArg->pStmt = NULL;
1633 }
shane626a6e42009-10-22 17:30:15 +00001634 }
shaneb9fc17d2009-10-22 21:23:35 +00001635 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001636
1637 return rc;
1638}
1639
drhdd3d4592004-08-30 01:54:05 +00001640
drh33048c02001-10-01 14:29:22 +00001641/*
drh4c653a02000-06-07 01:27:47 +00001642** This is a different callback routine used for dumping the database.
1643** Each row received by this callback consists of a table name,
1644** the table type ("index" or "table") and SQL to create the table.
1645** This routine should print text sufficient to recreate the table.
1646*/
1647static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001648 int rc;
1649 const char *zTable;
1650 const char *zType;
1651 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001652 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001653 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001654
drh902b9ee2008-12-05 17:17:07 +00001655 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001656 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001657 zTable = azArg[0];
1658 zType = azArg[1];
1659 zSql = azArg[2];
1660
drh00b950d2005-09-11 02:03:03 +00001661 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001662 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001663 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001664 fprintf(p->out, "ANALYZE sqlite_master;\n");
1665 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1666 return 0;
drh45e29d82006-11-20 16:21:10 +00001667 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1668 char *zIns;
1669 if( !p->writableSchema ){
1670 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1671 p->writableSchema = 1;
1672 }
1673 zIns = sqlite3_mprintf(
1674 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1675 "VALUES('table','%q','%q',0,'%q');",
1676 zTable, zTable, zSql);
1677 fprintf(p->out, "%s\n", zIns);
1678 sqlite3_free(zIns);
1679 return 0;
drh00b950d2005-09-11 02:03:03 +00001680 }else{
1681 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001682 }
danielk19772a02e332004-06-05 08:04:36 +00001683
1684 if( strcmp(zType, "table")==0 ){
1685 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001686 char *zSelect = 0;
1687 char *zTableInfo = 0;
1688 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001689 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001690
1691 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1692 zTableInfo = appendText(zTableInfo, zTable, '"');
1693 zTableInfo = appendText(zTableInfo, ");", 0);
1694
drhc7181902014-02-27 15:04:13 +00001695 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001696 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001697 if( rc!=SQLITE_OK || !pTableInfo ){
1698 return 1;
1699 }
1700
1701 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001702 /* Always quote the table name, even if it appears to be pure ascii,
1703 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1704 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001705 if( zTmp ){
1706 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001707 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001708 }
1709 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1710 rc = sqlite3_step(pTableInfo);
1711 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001712 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001713 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001714 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001715 rc = sqlite3_step(pTableInfo);
1716 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001717 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001718 }else{
1719 zSelect = appendText(zSelect, ") ", 0);
1720 }
drh157e29a2009-05-21 15:15:00 +00001721 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001722 }
1723 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001724 if( rc!=SQLITE_OK || nRow==0 ){
1725 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001726 return 1;
1727 }
1728 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1729 zSelect = appendText(zSelect, zTable, '"');
1730
drh2f464a02011-10-13 00:41:49 +00001731 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001732 if( rc==SQLITE_CORRUPT ){
1733 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001734 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001735 }
drh85e72432012-04-11 11:38:53 +00001736 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001737 }
drh4c653a02000-06-07 01:27:47 +00001738 return 0;
1739}
1740
1741/*
drh45e29d82006-11-20 16:21:10 +00001742** Run zQuery. Use dump_callback() as the callback routine so that
1743** the contents of the query are output as SQL statements.
1744**
drhdd3d4592004-08-30 01:54:05 +00001745** If we get a SQLITE_CORRUPT error, rerun the query after appending
1746** "ORDER BY rowid DESC" to the end.
1747*/
1748static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001749 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001750 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001751){
1752 int rc;
drh2f464a02011-10-13 00:41:49 +00001753 char *zErr = 0;
1754 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001755 if( rc==SQLITE_CORRUPT ){
1756 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001757 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001758 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1759 if( zErr ){
1760 fprintf(p->out, "/****** %s ******/\n", zErr);
1761 sqlite3_free(zErr);
1762 zErr = 0;
1763 }
drhdd3d4592004-08-30 01:54:05 +00001764 zQ2 = malloc( len+100 );
1765 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001766 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001767 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1768 if( rc ){
1769 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1770 }else{
1771 rc = SQLITE_CORRUPT;
1772 }
1773 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001774 free(zQ2);
1775 }
1776 return rc;
1777}
1778
1779/*
drh75897232000-05-29 14:26:00 +00001780** Text of a help message
1781*/
persicom1d0b8722002-04-18 02:53:04 +00001782static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001783 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001784 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001785 ".binary on|off Turn binary output on or off. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001786 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001787 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001788 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001789 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001790 " If TABLE specified, only dump tables matching\n"
1791 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001792 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001793 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001794 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001795 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001796 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001797 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001798 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001799 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001800 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001801 ".indexes ?TABLE? Show names of all indexes\n"
1802 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001803 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001804#ifdef SQLITE_ENABLE_IOTRACE
1805 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1806#endif
drh1a513372015-05-02 17:40:23 +00001807 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001808#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001809 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001810#endif
drh127f9d72010-02-23 01:47:00 +00001811 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001812 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001813 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001814 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001815 " column Left-aligned columns. (See .width)\n"
1816 " html HTML <table> code\n"
1817 " insert SQL insert statements for TABLE\n"
1818 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001819 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001820 " tabs Tab-separated values\n"
1821 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001822 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001823 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001824 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001825 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001826 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001827 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001828 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001829 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001830 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001831 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001832 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001833 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001834 " If TABLE specified, only show tables matching\n"
1835 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001836 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1837 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001838 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001839 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001840 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001841 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001842 ".tables ?TABLE? List names of tables\n"
1843 " If TABLE specified, only list tables matching\n"
1844 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001845 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001846 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001847 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001848 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001849 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001850 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001851;
1852
drhdaffd0e2001-04-11 14:28:42 +00001853/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001854static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001855/*
1856** Implementation of the "readfile(X)" SQL function. The entire content
1857** of the file named X is read and returned as a BLOB. NULL is returned
1858** if the file does not exist or is unreadable.
1859*/
1860static void readfileFunc(
1861 sqlite3_context *context,
1862 int argc,
1863 sqlite3_value **argv
1864){
1865 const char *zName;
1866 FILE *in;
1867 long nIn;
1868 void *pBuf;
1869
drhf5ed7ad2015-06-15 14:43:25 +00001870 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00001871 zName = (const char*)sqlite3_value_text(argv[0]);
1872 if( zName==0 ) return;
1873 in = fopen(zName, "rb");
1874 if( in==0 ) return;
1875 fseek(in, 0, SEEK_END);
1876 nIn = ftell(in);
1877 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00001878 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00001879 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1880 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1881 }else{
1882 sqlite3_free(pBuf);
1883 }
1884 fclose(in);
1885}
1886
1887/*
1888** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1889** is written into file X. The number of bytes written is returned. Or
1890** NULL is returned if something goes wrong, such as being unable to open
1891** file X for writing.
1892*/
1893static void writefileFunc(
1894 sqlite3_context *context,
1895 int argc,
1896 sqlite3_value **argv
1897){
1898 FILE *out;
1899 const char *z;
drhba5b0932014-07-24 12:39:59 +00001900 sqlite3_int64 rc;
1901 const char *zFile;
1902
drhf5ed7ad2015-06-15 14:43:25 +00001903 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00001904 zFile = (const char*)sqlite3_value_text(argv[0]);
1905 if( zFile==0 ) return;
1906 out = fopen(zFile, "wb");
1907 if( out==0 ) return;
1908 z = (const char*)sqlite3_value_blob(argv[1]);
1909 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001910 rc = 0;
1911 }else{
drh490fe862014-08-11 14:21:32 +00001912 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001913 }
1914 fclose(out);
1915 sqlite3_result_int64(context, rc);
1916}
drhdaffd0e2001-04-11 14:28:42 +00001917
drh75897232000-05-29 14:26:00 +00001918/*
drh44c2eb12003-04-30 11:38:26 +00001919** Make sure the database is open. If it is not, then open it. If
1920** the database fails to open, print an error message and exit.
1921*/
drhdcd87a92014-08-18 13:45:42 +00001922static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001923 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001924 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001925 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00001926 globalDb = p->db;
1927 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
1928 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00001929 shellstaticFunc, 0, 0);
1930 }
mistachkin8e189222015-04-19 21:43:16 +00001931 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
shane86f5bdb2009-10-24 02:00:07 +00001932 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00001933 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00001934 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001935 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001936 }
drhc2e87a32006-06-27 15:16:14 +00001937#ifndef SQLITE_OMIT_LOAD_EXTENSION
1938 sqlite3_enable_load_extension(p->db, 1);
1939#endif
mistachkin8e189222015-04-19 21:43:16 +00001940 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001941 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00001942 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001943 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001944 }
1945}
1946
1947/*
drhfeac5f82004-08-01 00:10:45 +00001948** Do C-language style dequoting.
1949**
mistachkinf21979d2015-01-18 05:35:01 +00001950** \a -> alarm
1951** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00001952** \t -> tab
1953** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00001954** \v -> vertical tab
1955** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00001956** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00001957** \s -> space
drh4c56b992013-06-27 13:26:55 +00001958** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00001959** \' -> '
drhfeac5f82004-08-01 00:10:45 +00001960** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00001961** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00001962*/
1963static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001964 int i, j;
1965 char c;
drhc2ce0be2014-05-29 12:36:14 +00001966 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001967 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00001968 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00001969 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00001970 if( c=='a' ){
1971 c = '\a';
1972 }else if( c=='b' ){
1973 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00001974 }else if( c=='t' ){
1975 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00001976 }else if( c=='n' ){
1977 c = '\n';
1978 }else if( c=='v' ){
1979 c = '\v';
1980 }else if( c=='f' ){
1981 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00001982 }else if( c=='r' ){
1983 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00001984 }else if( c=='"' ){
1985 c = '"';
1986 }else if( c=='\'' ){
1987 c = '\'';
drh4c56b992013-06-27 13:26:55 +00001988 }else if( c=='\\' ){
1989 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001990 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001991 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001992 if( z[i+1]>='0' && z[i+1]<='7' ){
1993 i++;
1994 c = (c<<3) + z[i] - '0';
1995 if( z[i+1]>='0' && z[i+1]<='7' ){
1996 i++;
1997 c = (c<<3) + z[i] - '0';
1998 }
1999 }
2000 }
2001 }
2002 z[j] = c;
2003 }
drhc2ce0be2014-05-29 12:36:14 +00002004 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002005}
2006
2007/*
drh348d19c2013-06-03 12:47:43 +00002008** Return the value of a hexadecimal digit. Return -1 if the input
2009** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002010*/
drh348d19c2013-06-03 12:47:43 +00002011static int hexDigitValue(char c){
2012 if( c>='0' && c<='9' ) return c - '0';
2013 if( c>='a' && c<='f' ) return c - 'a' + 10;
2014 if( c>='A' && c<='F' ) return c - 'A' + 10;
2015 return -1;
drhc28490c2006-10-26 14:25:58 +00002016}
2017
2018/*
drh7d9f3942013-04-03 01:26:54 +00002019** Interpret zArg as an integer value, possibly with suffixes.
2020*/
2021static sqlite3_int64 integerValue(const char *zArg){
2022 sqlite3_int64 v = 0;
2023 static const struct { char *zSuffix; int iMult; } aMult[] = {
2024 { "KiB", 1024 },
2025 { "MiB", 1024*1024 },
2026 { "GiB", 1024*1024*1024 },
2027 { "KB", 1000 },
2028 { "MB", 1000000 },
2029 { "GB", 1000000000 },
2030 { "K", 1000 },
2031 { "M", 1000000 },
2032 { "G", 1000000000 },
2033 };
2034 int i;
2035 int isNeg = 0;
2036 if( zArg[0]=='-' ){
2037 isNeg = 1;
2038 zArg++;
2039 }else if( zArg[0]=='+' ){
2040 zArg++;
2041 }
drh348d19c2013-06-03 12:47:43 +00002042 if( zArg[0]=='0' && zArg[1]=='x' ){
2043 int x;
2044 zArg += 2;
2045 while( (x = hexDigitValue(zArg[0]))>=0 ){
2046 v = (v<<4) + x;
2047 zArg++;
2048 }
2049 }else{
2050 while( IsDigit(zArg[0]) ){
2051 v = v*10 + zArg[0] - '0';
2052 zArg++;
2053 }
drh7d9f3942013-04-03 01:26:54 +00002054 }
drhc2bed0a2013-05-24 11:57:50 +00002055 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002056 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2057 v *= aMult[i].iMult;
2058 break;
2059 }
2060 }
2061 return isNeg? -v : v;
2062}
2063
2064/*
drh348d19c2013-06-03 12:47:43 +00002065** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2066** for TRUE and FALSE. Return the integer value if appropriate.
2067*/
2068static int booleanValue(char *zArg){
2069 int i;
2070 if( zArg[0]=='0' && zArg[1]=='x' ){
2071 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2072 }else{
2073 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2074 }
2075 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2076 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2077 return 1;
2078 }
2079 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2080 return 0;
2081 }
2082 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2083 zArg);
2084 return 0;
2085}
2086
2087/*
drh42f64e52012-04-04 16:56:23 +00002088** Close an output file, assuming it is not stderr or stdout
2089*/
2090static void output_file_close(FILE *f){
2091 if( f && f!=stdout && f!=stderr ) fclose(f);
2092}
2093
2094/*
2095** Try to open an output file. The names "stdout" and "stderr" are
2096** recognized and do the right thing. NULL is returned if the output
2097** filename is "off".
2098*/
2099static FILE *output_file_open(const char *zFile){
2100 FILE *f;
2101 if( strcmp(zFile,"stdout")==0 ){
2102 f = stdout;
2103 }else if( strcmp(zFile, "stderr")==0 ){
2104 f = stderr;
2105 }else if( strcmp(zFile, "off")==0 ){
2106 f = 0;
2107 }else{
2108 f = fopen(zFile, "wb");
2109 if( f==0 ){
2110 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2111 }
2112 }
2113 return f;
2114}
2115
2116/*
2117** A routine for handling output from sqlite3_trace().
2118*/
2119static void sql_trace_callback(void *pArg, const char *z){
2120 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002121 if( f ){
2122 int i = (int)strlen(z);
2123 while( i>0 && z[i-1]==';' ){ i--; }
2124 fprintf(f, "%.*s;\n", i, z);
2125 }
drh42f64e52012-04-04 16:56:23 +00002126}
2127
2128/*
drhd8621b92012-04-17 09:09:33 +00002129** A no-op routine that runs with the ".breakpoint" doc-command. This is
2130** a useful spot to set a debugger breakpoint.
2131*/
2132static void test_breakpoint(void){
2133 static int nCall = 0;
2134 nCall++;
2135}
2136
2137/*
mistachkin636bf9f2014-07-19 20:15:16 +00002138** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002139*/
mistachkin636bf9f2014-07-19 20:15:16 +00002140typedef struct ImportCtx ImportCtx;
2141struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002142 const char *zFile; /* Name of the input file */
2143 FILE *in; /* Read the CSV text from this input stream */
2144 char *z; /* Accumulated text for a field */
2145 int n; /* Number of bytes in z */
2146 int nAlloc; /* Space allocated for z[] */
2147 int nLine; /* Current line number */
2148 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002149 int cColSep; /* The column separator character. (Usually ",") */
2150 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002151};
2152
2153/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002154static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002155 if( p->n+1>=p->nAlloc ){
2156 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002157 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002158 if( p->z==0 ){
2159 fprintf(stderr, "out of memory\n");
2160 exit(1);
2161 }
2162 }
2163 p->z[p->n++] = (char)c;
2164}
2165
2166/* Read a single field of CSV text. Compatible with rfc4180 and extended
2167** with the option of having a separator other than ",".
2168**
2169** + Input comes from p->in.
2170** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002171** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002172** + Use p->cSep as the column separator. The default is ",".
2173** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002174** + Keep track of the line number in p->nLine.
2175** + Store the character that terminates the field in p->cTerm. Store
2176** EOF on end-of-file.
2177** + Report syntax errors on stderr
2178*/
mistachkin44723ce2015-03-21 02:22:37 +00002179static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002180 int c;
2181 int cSep = p->cColSep;
2182 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002183 p->n = 0;
2184 c = fgetc(p->in);
2185 if( c==EOF || seenInterrupt ){
2186 p->cTerm = EOF;
2187 return 0;
2188 }
2189 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002190 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002191 int startLine = p->nLine;
2192 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002193 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002194 while( 1 ){
2195 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002196 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002197 if( c==cQuote ){
2198 if( pc==cQuote ){
2199 pc = 0;
2200 continue;
2201 }
2202 }
2203 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002204 || (c==rSep && pc==cQuote)
2205 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002206 || (c==EOF && pc==cQuote)
2207 ){
2208 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002209 p->cTerm = c;
2210 break;
2211 }
2212 if( pc==cQuote && c!='\r' ){
2213 fprintf(stderr, "%s:%d: unescaped %c character\n",
2214 p->zFile, p->nLine, cQuote);
2215 }
2216 if( c==EOF ){
2217 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2218 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002219 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002220 break;
2221 }
mistachkin636bf9f2014-07-19 20:15:16 +00002222 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002223 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002224 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002225 }
drhdb95f682013-06-26 22:46:00 +00002226 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002227 while( c!=EOF && c!=cSep && c!=rSep ){
2228 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002229 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002230 }
mistachkin636bf9f2014-07-19 20:15:16 +00002231 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002232 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002233 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002234 }
drhdb95f682013-06-26 22:46:00 +00002235 p->cTerm = c;
2236 }
drh8dd675e2013-07-12 21:09:24 +00002237 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002238 return p->z;
2239}
2240
mistachkin636bf9f2014-07-19 20:15:16 +00002241/* Read a single field of ASCII delimited text.
2242**
2243** + Input comes from p->in.
2244** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002245** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002246** + Use p->cSep as the column separator. The default is "\x1F".
2247** + Use p->rSep as the row separator. The default is "\x1E".
2248** + Keep track of the row number in p->nLine.
2249** + Store the character that terminates the field in p->cTerm. Store
2250** EOF on end-of-file.
2251** + Report syntax errors on stderr
2252*/
mistachkin44723ce2015-03-21 02:22:37 +00002253static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002254 int c;
2255 int cSep = p->cColSep;
2256 int rSep = p->cRowSep;
2257 p->n = 0;
2258 c = fgetc(p->in);
2259 if( c==EOF || seenInterrupt ){
2260 p->cTerm = EOF;
2261 return 0;
2262 }
2263 while( c!=EOF && c!=cSep && c!=rSep ){
2264 import_append_char(p, c);
2265 c = fgetc(p->in);
2266 }
2267 if( c==rSep ){
2268 p->nLine++;
2269 }
2270 p->cTerm = c;
2271 if( p->z ) p->z[p->n] = 0;
2272 return p->z;
2273}
2274
drhdb95f682013-06-26 22:46:00 +00002275/*
drh4bbcf102014-02-06 02:46:08 +00002276** Try to transfer data for table zTable. If an error is seen while
2277** moving forward, try to go backwards. The backwards movement won't
2278** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002279*/
mistachkine31ae902014-02-06 01:15:29 +00002280static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002281 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002282 sqlite3 *newDb,
2283 const char *zTable
2284){
2285 sqlite3_stmt *pQuery = 0;
2286 sqlite3_stmt *pInsert = 0;
2287 char *zQuery = 0;
2288 char *zInsert = 0;
2289 int rc;
2290 int i, j, n;
2291 int nTable = (int)strlen(zTable);
2292 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002293 int cnt = 0;
2294 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002295
2296 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2297 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2298 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002299 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002300 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2301 zQuery);
2302 goto end_data_xfer;
2303 }
2304 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002305 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002306 if( zInsert==0 ){
2307 fprintf(stderr, "out of memory\n");
2308 goto end_data_xfer;
2309 }
2310 sqlite3_snprintf(200+nTable,zInsert,
2311 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2312 i = (int)strlen(zInsert);
2313 for(j=1; j<n; j++){
2314 memcpy(zInsert+i, ",?", 2);
2315 i += 2;
2316 }
2317 memcpy(zInsert+i, ");", 3);
2318 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2319 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002320 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002321 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2322 zQuery);
2323 goto end_data_xfer;
2324 }
2325 for(k=0; k<2; k++){
2326 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2327 for(i=0; i<n; i++){
2328 switch( sqlite3_column_type(pQuery, i) ){
2329 case SQLITE_NULL: {
2330 sqlite3_bind_null(pInsert, i+1);
2331 break;
2332 }
2333 case SQLITE_INTEGER: {
2334 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2335 break;
2336 }
2337 case SQLITE_FLOAT: {
2338 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2339 break;
2340 }
2341 case SQLITE_TEXT: {
2342 sqlite3_bind_text(pInsert, i+1,
2343 (const char*)sqlite3_column_text(pQuery,i),
2344 -1, SQLITE_STATIC);
2345 break;
2346 }
2347 case SQLITE_BLOB: {
2348 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2349 sqlite3_column_bytes(pQuery,i),
2350 SQLITE_STATIC);
2351 break;
2352 }
2353 }
2354 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002355 rc = sqlite3_step(pInsert);
2356 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2357 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2358 sqlite3_errmsg(newDb));
2359 }
drh3350ce92014-02-06 00:49:12 +00002360 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002361 cnt++;
2362 if( (cnt%spinRate)==0 ){
2363 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2364 fflush(stdout);
2365 }
drh3350ce92014-02-06 00:49:12 +00002366 } /* End while */
2367 if( rc==SQLITE_DONE ) break;
2368 sqlite3_finalize(pQuery);
2369 sqlite3_free(zQuery);
2370 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2371 zTable);
2372 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2373 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002374 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2375 break;
drh3350ce92014-02-06 00:49:12 +00002376 }
2377 } /* End for(k=0...) */
2378
2379end_data_xfer:
2380 sqlite3_finalize(pQuery);
2381 sqlite3_finalize(pInsert);
2382 sqlite3_free(zQuery);
2383 sqlite3_free(zInsert);
2384}
2385
2386
2387/*
2388** Try to transfer all rows of the schema that match zWhere. For
2389** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002390** If an error is encountered while moving forward through the
2391** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002392*/
mistachkine31ae902014-02-06 01:15:29 +00002393static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002394 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002395 sqlite3 *newDb,
2396 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002397 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002398){
2399 sqlite3_stmt *pQuery = 0;
2400 char *zQuery = 0;
2401 int rc;
2402 const unsigned char *zName;
2403 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002404 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002405
2406 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2407 " WHERE %s", zWhere);
2408 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2409 if( rc ){
2410 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2411 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2412 zQuery);
2413 goto end_schema_xfer;
2414 }
2415 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2416 zName = sqlite3_column_text(pQuery, 0);
2417 zSql = sqlite3_column_text(pQuery, 1);
2418 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002419 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2420 if( zErrMsg ){
2421 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2422 sqlite3_free(zErrMsg);
2423 zErrMsg = 0;
2424 }
drh3350ce92014-02-06 00:49:12 +00002425 if( xForEach ){
2426 xForEach(p, newDb, (const char*)zName);
2427 }
2428 printf("done\n");
2429 }
2430 if( rc!=SQLITE_DONE ){
2431 sqlite3_finalize(pQuery);
2432 sqlite3_free(zQuery);
2433 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2434 " WHERE %s ORDER BY rowid DESC", zWhere);
2435 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2436 if( rc ){
2437 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2438 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2439 zQuery);
2440 goto end_schema_xfer;
2441 }
2442 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2443 zName = sqlite3_column_text(pQuery, 0);
2444 zSql = sqlite3_column_text(pQuery, 1);
2445 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002446 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2447 if( zErrMsg ){
2448 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2449 sqlite3_free(zErrMsg);
2450 zErrMsg = 0;
2451 }
drh3350ce92014-02-06 00:49:12 +00002452 if( xForEach ){
2453 xForEach(p, newDb, (const char*)zName);
2454 }
2455 printf("done\n");
2456 }
2457 }
2458end_schema_xfer:
2459 sqlite3_finalize(pQuery);
2460 sqlite3_free(zQuery);
2461}
2462
2463/*
2464** Open a new database file named "zNewDb". Try to recover as much information
2465** as possible out of the main database (which might be corrupt) and write it
2466** into zNewDb.
2467*/
drhdcd87a92014-08-18 13:45:42 +00002468static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002469 int rc;
2470 sqlite3 *newDb = 0;
2471 if( access(zNewDb,0)==0 ){
2472 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2473 return;
2474 }
2475 rc = sqlite3_open(zNewDb, &newDb);
2476 if( rc ){
2477 fprintf(stderr, "Cannot create output database: %s\n",
2478 sqlite3_errmsg(newDb));
2479 }else{
drh54d0d2d2014-04-03 00:32:13 +00002480 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002481 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002482 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2483 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002484 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002485 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002486 }
2487 sqlite3_close(newDb);
2488}
2489
2490/*
drhc2ce0be2014-05-29 12:36:14 +00002491** Change the output file back to stdout
2492*/
drhdcd87a92014-08-18 13:45:42 +00002493static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002494 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002495#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002496 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002497#endif
drhc2ce0be2014-05-29 12:36:14 +00002498 }else{
2499 output_file_close(p->out);
2500 }
2501 p->outfile[0] = 0;
2502 p->out = stdout;
2503}
2504
2505/*
drhf7502f02015-02-06 14:19:44 +00002506** Run an SQL command and return the single integer result.
2507*/
2508static int db_int(ShellState *p, const char *zSql){
2509 sqlite3_stmt *pStmt;
2510 int res = 0;
2511 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2512 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2513 res = sqlite3_column_int(pStmt,0);
2514 }
2515 sqlite3_finalize(pStmt);
2516 return res;
2517}
2518
2519/*
2520** Convert a 2-byte or 4-byte big-endian integer into a native integer
2521*/
2522unsigned int get2byteInt(unsigned char *a){
2523 return (a[0]<<8) + a[1];
2524}
2525unsigned int get4byteInt(unsigned char *a){
2526 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2527}
2528
2529/*
2530** Implementation of the ".info" command.
2531**
2532** Return 1 on error, 2 to exit, and 0 otherwise.
2533*/
drh0e55db12015-02-06 14:51:13 +00002534static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002535 static const struct { const char *zName; int ofst; } aField[] = {
2536 { "file change counter:", 24 },
2537 { "database page count:", 28 },
2538 { "freelist page count:", 36 },
2539 { "schema cookie:", 40 },
2540 { "schema format:", 44 },
2541 { "default cache size:", 48 },
2542 { "autovacuum top root:", 52 },
2543 { "incremental vacuum:", 64 },
2544 { "text encoding:", 56 },
2545 { "user version:", 60 },
2546 { "application id:", 68 },
2547 { "software version:", 96 },
2548 };
drh0e55db12015-02-06 14:51:13 +00002549 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2550 { "number of tables:",
2551 "SELECT count(*) FROM %s WHERE type='table'" },
2552 { "number of indexes:",
2553 "SELECT count(*) FROM %s WHERE type='index'" },
2554 { "number of triggers:",
2555 "SELECT count(*) FROM %s WHERE type='trigger'" },
2556 { "number of views:",
2557 "SELECT count(*) FROM %s WHERE type='view'" },
2558 { "schema size:",
2559 "SELECT total(length(sql)) FROM %s" },
2560 };
2561 sqlite3_file *pFile;
2562 int i;
2563 char *zSchemaTab;
2564 char *zDb = nArg>=2 ? azArg[1] : "main";
2565 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002566 open_db(p, 0);
2567 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002568 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002569 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2570 return 1;
2571 }
2572 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2573 if( i!=SQLITE_OK ){
2574 fprintf(stderr, "unable to read database header\n");
2575 return 1;
2576 }
2577 i = get2byteInt(aHdr+16);
2578 if( i==1 ) i = 65536;
2579 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2580 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2581 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2582 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00002583 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00002584 int ofst = aField[i].ofst;
2585 unsigned int val = get4byteInt(aHdr + ofst);
2586 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2587 switch( ofst ){
2588 case 56: {
2589 if( val==1 ) fprintf(p->out, " (utf8)");
2590 if( val==2 ) fprintf(p->out, " (utf16le)");
2591 if( val==3 ) fprintf(p->out, " (utf16be)");
2592 }
2593 }
2594 fprintf(p->out, "\n");
2595 }
drh0e55db12015-02-06 14:51:13 +00002596 if( zDb==0 ){
2597 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2598 }else if( strcmp(zDb,"temp")==0 ){
2599 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2600 }else{
2601 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2602 }
drhf5ed7ad2015-06-15 14:43:25 +00002603 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00002604 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2605 int val = db_int(p, zSql);
2606 sqlite3_free(zSql);
2607 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2608 }
2609 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002610 return 0;
2611}
2612
2613
2614/*
drh75897232000-05-29 14:26:00 +00002615** If an input line begins with "." then invoke this routine to
2616** process that line.
drh67505e72002-04-19 12:34:06 +00002617**
drh47ad6842006-11-08 12:25:42 +00002618** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002619*/
drhdcd87a92014-08-18 13:45:42 +00002620static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002621 int h = 1;
drh75897232000-05-29 14:26:00 +00002622 int nArg = 0;
2623 int n, c;
drh67505e72002-04-19 12:34:06 +00002624 int rc = 0;
drh75897232000-05-29 14:26:00 +00002625 char *azArg[50];
2626
2627 /* Parse the input line into tokens.
2628 */
mistachkin8e189222015-04-19 21:43:16 +00002629 while( zLine[h] && nArg<ArraySize(azArg) ){
2630 while( IsSpace(zLine[h]) ){ h++; }
2631 if( zLine[h]==0 ) break;
2632 if( zLine[h]=='\'' || zLine[h]=='"' ){
2633 int delim = zLine[h++];
2634 azArg[nArg++] = &zLine[h];
2635 while( zLine[h] && zLine[h]!=delim ){
2636 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2637 h++;
drh4c56b992013-06-27 13:26:55 +00002638 }
mistachkin8e189222015-04-19 21:43:16 +00002639 if( zLine[h]==delim ){
2640 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002641 }
drhfeac5f82004-08-01 00:10:45 +00002642 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002643 }else{
mistachkin8e189222015-04-19 21:43:16 +00002644 azArg[nArg++] = &zLine[h];
2645 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2646 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002647 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002648 }
2649 }
2650
2651 /* Process the input line.
2652 */
shane9bd1b442009-10-23 01:27:39 +00002653 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002654 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002655 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002656 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2657 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2658 ){
drhbc46f022013-01-23 18:53:23 +00002659 const char *zDestFile = 0;
2660 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002661 sqlite3 *pDest;
2662 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002663 int j;
2664 for(j=1; j<nArg; j++){
2665 const char *z = azArg[j];
2666 if( z[0]=='-' ){
2667 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002668 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002669 {
2670 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2671 return 1;
2672 }
2673 }else if( zDestFile==0 ){
2674 zDestFile = azArg[j];
2675 }else if( zDb==0 ){
2676 zDb = zDestFile;
2677 zDestFile = azArg[j];
2678 }else{
2679 fprintf(stderr, "too many arguments to .backup\n");
2680 return 1;
2681 }
drh9ff849f2009-02-04 20:55:57 +00002682 }
drhbc46f022013-01-23 18:53:23 +00002683 if( zDestFile==0 ){
2684 fprintf(stderr, "missing FILENAME argument on .backup\n");
2685 return 1;
2686 }
2687 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002688 rc = sqlite3_open(zDestFile, &pDest);
2689 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002690 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002691 sqlite3_close(pDest);
2692 return 1;
2693 }
drh05782482013-10-24 15:20:20 +00002694 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002695 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2696 if( pBackup==0 ){
2697 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2698 sqlite3_close(pDest);
2699 return 1;
2700 }
2701 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2702 sqlite3_backup_finish(pBackup);
2703 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002704 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002705 }else{
2706 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002707 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002708 }
2709 sqlite3_close(pDest);
2710 }else
2711
drhc2ce0be2014-05-29 12:36:14 +00002712 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2713 if( nArg==2 ){
2714 bail_on_error = booleanValue(azArg[1]);
2715 }else{
2716 fprintf(stderr, "Usage: .bail on|off\n");
2717 rc = 1;
2718 }
drhc49f44e2006-10-26 18:15:42 +00002719 }else
2720
mistachkinf21979d2015-01-18 05:35:01 +00002721 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2722 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002723 if( booleanValue(azArg[1]) ){
2724 setBinaryMode(p->out);
2725 }else{
2726 setTextMode(p->out);
2727 }
mistachkinf21979d2015-01-18 05:35:01 +00002728 }else{
2729 fprintf(stderr, "Usage: .binary on|off\n");
2730 rc = 1;
2731 }
2732 }else
2733
drhd8621b92012-04-17 09:09:33 +00002734 /* The undocumented ".breakpoint" command causes a call to the no-op
2735 ** routine named test_breakpoint().
2736 */
2737 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2738 test_breakpoint();
2739 }else
2740
drhc2ce0be2014-05-29 12:36:14 +00002741 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2742 if( nArg==2 ){
2743 tryToClone(p, azArg[1]);
2744 }else{
2745 fprintf(stderr, "Usage: .clone FILENAME\n");
2746 rc = 1;
2747 }
mistachkine31ae902014-02-06 01:15:29 +00002748 }else
2749
drhc2ce0be2014-05-29 12:36:14 +00002750 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002751 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002752 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002753 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002754 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002755 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002756 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002757 data.colWidth[0] = 3;
2758 data.colWidth[1] = 15;
2759 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002760 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002761 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002762 if( zErrMsg ){
2763 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002764 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002765 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002766 }
2767 }else
2768
drh0e55db12015-02-06 14:51:13 +00002769 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2770 rc = shell_dbinfo_command(p, nArg, azArg);
2771 }else
2772
drhc2ce0be2014-05-29 12:36:14 +00002773 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002774 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002775 /* When playing back a "dump", the content might appear in an order
2776 ** which causes immediate foreign key constraints to be violated.
2777 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002778 if( nArg!=1 && nArg!=2 ){
2779 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2780 rc = 1;
2781 goto meta_command_exit;
2782 }
drhf1dfc4f2009-09-23 15:51:35 +00002783 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002784 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002785 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002786 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002787 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002788 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002789 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002790 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002791 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002792 );
2793 run_schema_dump_query(p,
2794 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002795 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002796 );
drh2f464a02011-10-13 00:41:49 +00002797 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002798 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002799 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002800 );
drh4c653a02000-06-07 01:27:47 +00002801 }else{
2802 int i;
drhdd3d4592004-08-30 01:54:05 +00002803 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002804 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002805 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002806 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002807 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002808 " AND sql NOT NULL");
2809 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002810 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002811 "WHERE sql NOT NULL"
2812 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002813 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002814 );
danielk1977bc6ada42004-06-30 08:20:16 +00002815 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002816 }
2817 }
drh45e29d82006-11-20 16:21:10 +00002818 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002819 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002820 p->writableSchema = 0;
2821 }
drh56197952011-10-13 16:30:13 +00002822 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2823 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002824 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002825 }else
drh75897232000-05-29 14:26:00 +00002826
drhc2ce0be2014-05-29 12:36:14 +00002827 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2828 if( nArg==2 ){
2829 p->echoOn = booleanValue(azArg[1]);
2830 }else{
2831 fprintf(stderr, "Usage: .echo on|off\n");
2832 rc = 1;
2833 }
drhdaffd0e2001-04-11 14:28:42 +00002834 }else
2835
drhc2ce0be2014-05-29 12:36:14 +00002836 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2837 if( nArg==2 ){
2838 p->autoEQP = booleanValue(azArg[1]);
2839 }else{
2840 fprintf(stderr, "Usage: .eqp on|off\n");
2841 rc = 1;
2842 }
drhefbf3b12014-02-28 20:47:24 +00002843 }else
2844
drhd3ac7d92013-01-25 18:33:43 +00002845 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002846 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002847 rc = 2;
drh75897232000-05-29 14:26:00 +00002848 }else
2849
drhc2ce0be2014-05-29 12:36:14 +00002850 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002851 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002852 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002853 if(!p->normalMode.valid) {
2854 p->normalMode.valid = 1;
2855 p->normalMode.mode = p->mode;
2856 p->normalMode.showHeader = p->showHeader;
2857 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002858 }
2859 /* We could put this code under the !p->explainValid
2860 ** condition so that it does not execute if we are already in
2861 ** explain mode. However, always executing it allows us an easy
2862 ** was to reset to explain mode in case the user previously
2863 ** did an .explain followed by a .width, .mode or .header
2864 ** command.
2865 */
danielk19770d78bae2008-01-03 07:09:48 +00002866 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002867 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002868 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002869 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002870 p->colWidth[1] = 13; /* opcode */
2871 p->colWidth[2] = 4; /* P1 */
2872 p->colWidth[3] = 4; /* P2 */
2873 p->colWidth[4] = 4; /* P3 */
2874 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002875 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002876 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002877 }else if (p->normalMode.valid) {
2878 p->normalMode.valid = 0;
2879 p->mode = p->normalMode.mode;
2880 p->showHeader = p->normalMode.showHeader;
2881 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002882 }
drh75897232000-05-29 14:26:00 +00002883 }else
2884
drhc1971542014-06-23 23:28:13 +00002885 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002886 ShellState data;
drhc1971542014-06-23 23:28:13 +00002887 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002888 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002889 if( nArg!=1 ){
2890 fprintf(stderr, "Usage: .fullschema\n");
2891 rc = 1;
2892 goto meta_command_exit;
2893 }
2894 open_db(p, 0);
2895 memcpy(&data, p, sizeof(data));
2896 data.showHeader = 0;
2897 data.mode = MODE_Semi;
2898 rc = sqlite3_exec(p->db,
2899 "SELECT sql FROM"
2900 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2901 " FROM sqlite_master UNION ALL"
2902 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002903 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002904 "ORDER BY rowid",
2905 callback, &data, &zErrMsg
2906 );
drh56f674c2014-07-18 14:43:29 +00002907 if( rc==SQLITE_OK ){
2908 sqlite3_stmt *pStmt;
2909 rc = sqlite3_prepare_v2(p->db,
2910 "SELECT rowid FROM sqlite_master"
2911 " WHERE name GLOB 'sqlite_stat[134]'",
2912 -1, &pStmt, 0);
2913 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2914 sqlite3_finalize(pStmt);
2915 }
2916 if( doStats==0 ){
2917 fprintf(p->out, "/* No STAT tables available */\n");
2918 }else{
2919 fprintf(p->out, "ANALYZE sqlite_master;\n");
2920 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2921 callback, &data, &zErrMsg);
2922 data.mode = MODE_Insert;
2923 data.zDestTable = "sqlite_stat1";
2924 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2925 shell_callback, &data,&zErrMsg);
2926 data.zDestTable = "sqlite_stat3";
2927 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2928 shell_callback, &data,&zErrMsg);
2929 data.zDestTable = "sqlite_stat4";
2930 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2931 shell_callback, &data, &zErrMsg);
2932 fprintf(p->out, "ANALYZE sqlite_master;\n");
2933 }
drhc1971542014-06-23 23:28:13 +00002934 }else
2935
drhc2ce0be2014-05-29 12:36:14 +00002936 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2937 if( nArg==2 ){
2938 p->showHeader = booleanValue(azArg[1]);
2939 }else{
2940 fprintf(stderr, "Usage: .headers on|off\n");
2941 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002942 }
drh75897232000-05-29 14:26:00 +00002943 }else
2944
drhc2ce0be2014-05-29 12:36:14 +00002945 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2946 fprintf(p->out, "%s", zHelp);
2947 }else
2948
2949 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002950 char *zTable; /* Insert data into this table */
2951 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002952 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002953 int nCol; /* Number of columns in the table */
2954 int nByte; /* Number of bytes in an SQL string */
2955 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002956 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002957 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002958 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002959 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00002960 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
2961 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00002962
drhc2ce0be2014-05-29 12:36:14 +00002963 if( nArg!=3 ){
2964 fprintf(stderr, "Usage: .import FILE TABLE\n");
2965 goto meta_command_exit;
2966 }
drh01f37542014-05-31 15:43:33 +00002967 zFile = azArg[1];
2968 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002969 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002970 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002971 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002972 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002973 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002974 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002975 return 1;
drhfeac5f82004-08-01 00:10:45 +00002976 }
drhdb95f682013-06-26 22:46:00 +00002977 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002978 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002979 " for import\n");
2980 return 1;
2981 }
mistachkin636bf9f2014-07-19 20:15:16 +00002982 nSep = strlen30(p->rowSeparator);
2983 if( nSep==0 ){
2984 fprintf(stderr, "Error: non-null row separator required for import\n");
2985 return 1;
2986 }
mistachkine0d68852014-12-11 03:12:33 +00002987 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2988 /* When importing CSV (only), if the row separator is set to the
2989 ** default output row separator, change it to the default input
2990 ** row separator. This avoids having to maintain different input
2991 ** and output row separators. */
2992 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2993 nSep = strlen30(p->rowSeparator);
2994 }
mistachkin636bf9f2014-07-19 20:15:16 +00002995 if( nSep>1 ){
2996 fprintf(stderr, "Error: multi-character row separators not allowed"
2997 " for import\n");
2998 return 1;
2999 }
3000 sCtx.zFile = zFile;
3001 sCtx.nLine = 1;
3002 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003003#ifdef SQLITE_OMIT_POPEN
mistachkinba132c72015-03-19 14:48:38 +00003004 fprintf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003005 return 1;
3006#else
mistachkin636bf9f2014-07-19 20:15:16 +00003007 sCtx.in = popen(sCtx.zFile+1, "r");
3008 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003009 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003010#endif
drh5bde8162013-06-27 14:07:53 +00003011 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003012 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003013 xCloser = fclose;
3014 }
mistachkin636bf9f2014-07-19 20:15:16 +00003015 if( p->mode==MODE_Ascii ){
3016 xRead = ascii_read_one_field;
3017 }else{
3018 xRead = csv_read_one_field;
3019 }
3020 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00003021 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003022 return 1;
3023 }
mistachkin636bf9f2014-07-19 20:15:16 +00003024 sCtx.cColSep = p->colSeparator[0];
3025 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003026 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003027 if( zSql==0 ){
3028 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003029 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003030 return 1;
3031 }
drh4f21c4a2008-12-10 22:15:00 +00003032 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003033 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003034 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003035 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003036 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3037 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003038 while( xRead(&sCtx) ){
3039 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003040 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003041 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003042 }
drh5bde8162013-06-27 14:07:53 +00003043 if( cSep=='(' ){
3044 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003045 sqlite3_free(sCtx.z);
3046 xCloser(sCtx.in);
3047 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003048 return 1;
3049 }
drhdb95f682013-06-26 22:46:00 +00003050 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3051 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3052 sqlite3_free(zCreate);
3053 if( rc ){
3054 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003055 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003056 sqlite3_free(sCtx.z);
3057 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003058 return 1;
3059 }
drhc7181902014-02-27 15:04:13 +00003060 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003061 }
drhfeac5f82004-08-01 00:10:45 +00003062 sqlite3_free(zSql);
3063 if( rc ){
shane916f9612009-10-23 00:37:15 +00003064 if (pStmt) sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003065 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003066 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003067 return 1;
drhfeac5f82004-08-01 00:10:45 +00003068 }
shane916f9612009-10-23 00:37:15 +00003069 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003070 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003071 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003072 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003073 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003074 if( zSql==0 ){
3075 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003076 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003077 return 1;
3078 }
drhdb95f682013-06-26 22:46:00 +00003079 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003080 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003081 for(i=1; i<nCol; i++){
3082 zSql[j++] = ',';
3083 zSql[j++] = '?';
3084 }
3085 zSql[j++] = ')';
3086 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003087 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003088 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003089 if( rc ){
mistachkin8e189222015-04-19 21:43:16 +00003090 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003091 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003092 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003093 return 1;
drhfeac5f82004-08-01 00:10:45 +00003094 }
mistachkin8e189222015-04-19 21:43:16 +00003095 needCommit = sqlite3_get_autocommit(p->db);
3096 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003097 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003098 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003099 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003100 char *z = xRead(&sCtx);
3101 /*
3102 ** Did we reach end-of-file before finding any columns?
3103 ** If so, stop instead of NULL filling the remaining columns.
3104 */
drhdb95f682013-06-26 22:46:00 +00003105 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003106 /*
3107 ** Did we reach end-of-file OR end-of-line before finding any
3108 ** columns in ASCII mode? If so, stop instead of NULL filling
3109 ** the remaining columns.
3110 */
3111 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003112 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003113 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003114 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3115 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003116 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003117 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003118 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003119 }
drhfeac5f82004-08-01 00:10:45 +00003120 }
mistachkin636bf9f2014-07-19 20:15:16 +00003121 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003122 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003123 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003124 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003125 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003126 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3127 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003128 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003129 }
drhdb95f682013-06-26 22:46:00 +00003130 if( i>=nCol ){
3131 sqlite3_step(pStmt);
3132 rc = sqlite3_reset(pStmt);
3133 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003134 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
mistachkin8e189222015-04-19 21:43:16 +00003135 sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003136 }
3137 }
mistachkin636bf9f2014-07-19 20:15:16 +00003138 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003139
mistachkin636bf9f2014-07-19 20:15:16 +00003140 xCloser(sCtx.in);
3141 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003142 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003143 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003144 }else
3145
drh0e55db12015-02-06 14:51:13 +00003146 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3147 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003148 ShellState data;
drh75897232000-05-29 14:26:00 +00003149 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003150 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003151 memcpy(&data, p, sizeof(data));
3152 data.showHeader = 0;
3153 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003154 if( nArg==1 ){
3155 rc = sqlite3_exec(p->db,
3156 "SELECT name FROM sqlite_master "
3157 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3158 "UNION ALL "
3159 "SELECT name FROM sqlite_temp_master "
3160 "WHERE type='index' "
3161 "ORDER BY 1",
3162 callback, &data, &zErrMsg
3163 );
drhc2ce0be2014-05-29 12:36:14 +00003164 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003165 zShellStatic = azArg[1];
3166 rc = sqlite3_exec(p->db,
3167 "SELECT name FROM sqlite_master "
3168 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3169 "UNION ALL "
3170 "SELECT name FROM sqlite_temp_master "
3171 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3172 "ORDER BY 1",
3173 callback, &data, &zErrMsg
3174 );
3175 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003176 }else{
drh0e55db12015-02-06 14:51:13 +00003177 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003178 rc = 1;
3179 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003180 }
drh75897232000-05-29 14:26:00 +00003181 if( zErrMsg ){
3182 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003183 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003184 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003185 }else if( rc != SQLITE_OK ){
3186 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3187 rc = 1;
drh75897232000-05-29 14:26:00 +00003188 }
3189 }else
3190
drhae5e4452007-05-03 17:18:36 +00003191#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003192 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003193 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003194 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3195 iotrace = 0;
3196 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003197 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003198 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003199 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003200 iotrace = stdout;
3201 }else{
3202 iotrace = fopen(azArg[1], "w");
3203 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003204 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003205 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003206 rc = 1;
drhb0603412007-02-28 04:47:26 +00003207 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003208 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003209 }
3210 }
3211 }else
drhae5e4452007-05-03 17:18:36 +00003212#endif
drh1a513372015-05-02 17:40:23 +00003213 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3214 static const struct {
3215 const char *zLimitName; /* Name of a limit */
3216 int limitCode; /* Integer code for that limit */
3217 } aLimit[] = {
3218 { "length", SQLITE_LIMIT_LENGTH },
3219 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3220 { "column", SQLITE_LIMIT_COLUMN },
3221 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3222 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3223 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3224 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3225 { "attached", SQLITE_LIMIT_ATTACHED },
3226 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3227 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3228 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3229 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3230 };
3231 int i, n2;
3232 open_db(p, 0);
3233 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003234 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003235 printf("%20s %d\n", aLimit[i].zLimitName,
3236 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3237 }
3238 }else if( nArg>3 ){
3239 fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
3240 rc = 1;
3241 goto meta_command_exit;
3242 }else{
3243 int iLimit = -1;
3244 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003245 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003246 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3247 if( iLimit<0 ){
3248 iLimit = i;
3249 }else{
3250 fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
3251 rc = 1;
3252 goto meta_command_exit;
3253 }
3254 }
3255 }
3256 if( iLimit<0 ){
3257 fprintf(stderr, "unknown limit: \"%s\"\n"
3258 "enter \".limits\" with no arguments for a list.\n",
3259 azArg[1]);
3260 rc = 1;
3261 goto meta_command_exit;
3262 }
3263 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003264 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3265 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003266 }
3267 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3268 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3269 }
3270 }else
drhb0603412007-02-28 04:47:26 +00003271
drh70df4fe2006-06-13 15:12:21 +00003272#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003273 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003274 const char *zFile, *zProc;
3275 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003276 if( nArg<2 ){
3277 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3278 rc = 1;
3279 goto meta_command_exit;
3280 }
drh1e397f82006-06-08 15:28:43 +00003281 zFile = azArg[1];
3282 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003283 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003284 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3285 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003286 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003287 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003288 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003289 }
3290 }else
drh70df4fe2006-06-13 15:12:21 +00003291#endif
drh1e397f82006-06-08 15:28:43 +00003292
drhc2ce0be2014-05-29 12:36:14 +00003293 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3294 if( nArg!=2 ){
3295 fprintf(stderr, "Usage: .log FILENAME\n");
3296 rc = 1;
3297 }else{
3298 const char *zFile = azArg[1];
3299 output_file_close(p->pLog);
3300 p->pLog = output_file_open(zFile);
3301 }
drh127f9d72010-02-23 01:47:00 +00003302 }else
3303
drhc2ce0be2014-05-29 12:36:14 +00003304 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3305 const char *zMode = nArg>=2 ? azArg[1] : "";
3306 int n2 = (int)strlen(zMode);
3307 int c2 = zMode[0];
3308 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003309 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003310 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003311 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003312 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003313 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003314 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003315 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003316 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003317 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003318 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003319 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003320 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003321 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003322 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003323 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003324 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003325 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003326 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003327 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003328 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003329 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3330 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003331 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3332 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003333 }else {
shane9bd1b442009-10-23 01:27:39 +00003334 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003335 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003336 rc = 1;
drh75897232000-05-29 14:26:00 +00003337 }
3338 }else
3339
drhc2ce0be2014-05-29 12:36:14 +00003340 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3341 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003342 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3343 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003344 }else{
3345 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003346 rc = 1;
3347 }
3348 }else
3349
drh05782482013-10-24 15:20:20 +00003350 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3351 sqlite3 *savedDb = p->db;
3352 const char *zSavedFilename = p->zDbFilename;
3353 char *zNewFilename = 0;
3354 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003355 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3356 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003357 open_db(p, 1);
3358 if( p->db!=0 ){
3359 sqlite3_close(savedDb);
3360 sqlite3_free(p->zFreeOnClose);
3361 p->zFreeOnClose = zNewFilename;
3362 }else{
3363 sqlite3_free(zNewFilename);
3364 p->db = savedDb;
3365 p->zDbFilename = zSavedFilename;
3366 }
3367 }else
3368
drhc2ce0be2014-05-29 12:36:14 +00003369 if( c=='o'
3370 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3371 ){
3372 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3373 if( nArg>2 ){
3374 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3375 rc = 1;
3376 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003377 }
drhc2ce0be2014-05-29 12:36:14 +00003378 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3379 if( nArg<2 ){
3380 fprintf(stderr, "Usage: .once FILE\n");
3381 rc = 1;
3382 goto meta_command_exit;
3383 }
3384 p->outCount = 2;
3385 }else{
3386 p->outCount = 0;
3387 }
3388 output_reset(p);
3389 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003390#ifdef SQLITE_OMIT_POPEN
3391 fprintf(stderr,"Error: pipes are not supported in this OS\n");
3392 rc = 1;
3393 p->out = stdout;
3394#else
drhc2ce0be2014-05-29 12:36:14 +00003395 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003396 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003397 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003398 p->out = stdout;
3399 rc = 1;
3400 }else{
drhc2ce0be2014-05-29 12:36:14 +00003401 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003402 }
drh8cd5b252015-03-02 22:06:43 +00003403#endif
drh75897232000-05-29 14:26:00 +00003404 }else{
drhc2ce0be2014-05-29 12:36:14 +00003405 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003406 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003407 if( strcmp(zFile,"off")!=0 ){
3408 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003409 }
drh75897232000-05-29 14:26:00 +00003410 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003411 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003412 } else {
drhc2ce0be2014-05-29 12:36:14 +00003413 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003414 }
3415 }
3416 }else
3417
drh078b1fd2012-09-21 13:40:02 +00003418 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3419 int i;
3420 for(i=1; i<nArg; i++){
3421 if( i>1 ) fprintf(p->out, " ");
3422 fprintf(p->out, "%s", azArg[i]);
3423 }
3424 fprintf(p->out, "\n");
3425 }else
3426
drhc2ce0be2014-05-29 12:36:14 +00003427 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003428 if( nArg >= 2) {
3429 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3430 }
3431 if( nArg >= 3) {
3432 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3433 }
3434 }else
3435
drhc2ce0be2014-05-29 12:36:14 +00003436 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003437 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003438 }else
3439
drhc2ce0be2014-05-29 12:36:14 +00003440 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3441 FILE *alt;
3442 if( nArg!=2 ){
3443 fprintf(stderr, "Usage: .read FILE\n");
3444 rc = 1;
3445 goto meta_command_exit;
3446 }
3447 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003448 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003449 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3450 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003451 }else{
shane9bd1b442009-10-23 01:27:39 +00003452 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003453 fclose(alt);
3454 }
3455 }else
3456
drhc2ce0be2014-05-29 12:36:14 +00003457 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003458 const char *zSrcFile;
3459 const char *zDb;
3460 sqlite3 *pSrc;
3461 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003462 int nTimeout = 0;
3463
drh9ff849f2009-02-04 20:55:57 +00003464 if( nArg==2 ){
3465 zSrcFile = azArg[1];
3466 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003467 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003468 zSrcFile = azArg[2];
3469 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003470 }else{
3471 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3472 rc = 1;
3473 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003474 }
3475 rc = sqlite3_open(zSrcFile, &pSrc);
3476 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003477 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003478 sqlite3_close(pSrc);
3479 return 1;
3480 }
drh05782482013-10-24 15:20:20 +00003481 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003482 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3483 if( pBackup==0 ){
3484 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3485 sqlite3_close(pSrc);
3486 return 1;
3487 }
drhdc2c4912009-02-04 22:46:47 +00003488 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3489 || rc==SQLITE_BUSY ){
3490 if( rc==SQLITE_BUSY ){
3491 if( nTimeout++ >= 3 ) break;
3492 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003493 }
3494 }
3495 sqlite3_backup_finish(pBackup);
3496 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003497 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003498 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003499 fprintf(stderr, "Error: source database is busy\n");
3500 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003501 }else{
3502 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003503 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003504 }
3505 sqlite3_close(pSrc);
3506 }else
3507
dan8d1edb92014-11-05 09:07:28 +00003508
3509 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3510 if( nArg==2 ){
3511 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003512#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3513 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3514#endif
dan8d1edb92014-11-05 09:07:28 +00003515 }else{
3516 fprintf(stderr, "Usage: .scanstats on|off\n");
3517 rc = 1;
3518 }
3519 }else
3520
drhc2ce0be2014-05-29 12:36:14 +00003521 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003522 ShellState data;
drh75897232000-05-29 14:26:00 +00003523 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003524 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003525 memcpy(&data, p, sizeof(data));
3526 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003527 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003528 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003529 int i;
drhf0693c82011-10-11 20:41:54 +00003530 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003531 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003532 char *new_argv[2], *new_colv[2];
3533 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3534 " type text,\n"
3535 " name text,\n"
3536 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003537 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003538 " sql text\n"
3539 ")";
3540 new_argv[1] = 0;
3541 new_colv[0] = "sql";
3542 new_colv[1] = 0;
3543 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003544 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003545 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003546 char *new_argv[2], *new_colv[2];
3547 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3548 " type text,\n"
3549 " name text,\n"
3550 " tbl_name text,\n"
3551 " rootpage integer,\n"
3552 " sql text\n"
3553 ")";
3554 new_argv[1] = 0;
3555 new_colv[0] = "sql";
3556 new_colv[1] = 0;
3557 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003558 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003559 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003560 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003561 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003562 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003563 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003564 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003565 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003566 "WHERE lower(tbl_name) LIKE shellstatic()"
3567 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003568 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003569 callback, &data, &zErrMsg);
3570 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003571 }
drhc2ce0be2014-05-29 12:36:14 +00003572 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003573 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003574 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003575 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003576 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003577 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003578 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003579 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003580 callback, &data, &zErrMsg
3581 );
drhc2ce0be2014-05-29 12:36:14 +00003582 }else{
3583 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3584 rc = 1;
3585 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003586 }
drh75897232000-05-29 14:26:00 +00003587 if( zErrMsg ){
3588 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003589 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003590 rc = 1;
3591 }else if( rc != SQLITE_OK ){
3592 fprintf(stderr,"Error: querying schema information\n");
3593 rc = 1;
3594 }else{
3595 rc = 0;
drh75897232000-05-29 14:26:00 +00003596 }
3597 }else
3598
drhabd4c722014-09-20 18:18:33 +00003599
3600#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3601 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3602 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003603 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003604 }else
3605#endif
3606
3607
drh340f5822013-06-27 13:01:21 +00003608#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003609 /* Undocumented commands for internal testing. Subject to change
3610 ** without notice. */
3611 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3612 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3613 int i, v;
3614 for(i=1; i<nArg; i++){
3615 v = booleanValue(azArg[i]);
3616 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3617 }
3618 }
3619 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3620 int i; sqlite3_int64 v;
3621 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003622 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003623 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003624 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003625 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003626 }
3627 }
3628 }else
drh340f5822013-06-27 13:01:21 +00003629#endif
drh348d19c2013-06-03 12:47:43 +00003630
drhc2ce0be2014-05-29 12:36:14 +00003631 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003632 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003633 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003634 rc = 1;
3635 }
drh6976c212014-07-24 12:09:47 +00003636 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003637 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003638 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003639 }
3640 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003641 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3642 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003643 }
drh75897232000-05-29 14:26:00 +00003644 }else
3645
drh62cdde52014-05-28 20:22:28 +00003646 if( c=='s'
3647 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003648 ){
3649 char *zCmd;
drh54027102014-08-06 14:36:53 +00003650 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003651 if( nArg<2 ){
3652 fprintf(stderr, "Usage: .system COMMAND\n");
3653 rc = 1;
3654 goto meta_command_exit;
3655 }
drhdcb3e3d2014-05-29 03:17:29 +00003656 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003657 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003658 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3659 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003660 }
drh54027102014-08-06 14:36:53 +00003661 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003662 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003663 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003664 }else
3665
drhc2ce0be2014-05-29 12:36:14 +00003666 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003667 int i;
drhc2ce0be2014-05-29 12:36:14 +00003668 if( nArg!=1 ){
3669 fprintf(stderr, "Usage: .show\n");
3670 rc = 1;
3671 goto meta_command_exit;
3672 }
mistachkin636bf9f2014-07-19 20:15:16 +00003673 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3674 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003675 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003676 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3677 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3678 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003679 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003680 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003681 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003682 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003683 fprintf(p->out,"%12.12s: ", "colseparator");
3684 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003685 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003686 fprintf(p->out,"%12.12s: ", "rowseparator");
3687 output_c_string(p->out, p->rowSeparator);
3688 fprintf(p->out, "\n");
3689 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3690 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003691 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003692 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003693 }
drhfeac5f82004-08-01 00:10:45 +00003694 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003695 }else
3696
drhc2ce0be2014-05-29 12:36:14 +00003697 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3698 if( nArg==2 ){
3699 p->statsOn = booleanValue(azArg[1]);
3700 }else{
3701 fprintf(stderr, "Usage: .stats on|off\n");
3702 rc = 1;
3703 }
shaneh642d8b82010-07-28 16:05:34 +00003704 }else
3705
drhc2ce0be2014-05-29 12:36:14 +00003706 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003707 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003708 char **azResult;
drh98781232012-04-23 12:38:05 +00003709 int nRow, nAlloc;
3710 char *zSql = 0;
3711 int ii;
drh05782482013-10-24 15:20:20 +00003712 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003713 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3714 if( rc ) return rc;
3715 zSql = sqlite3_mprintf(
3716 "SELECT name FROM sqlite_master"
3717 " WHERE type IN ('table','view')"
3718 " AND name NOT LIKE 'sqlite_%%'"
3719 " AND name LIKE ?1");
3720 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3721 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3722 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3723 if( strcmp(zDbName,"temp")==0 ){
3724 zSql = sqlite3_mprintf(
3725 "%z UNION ALL "
3726 "SELECT 'temp.' || name FROM sqlite_temp_master"
3727 " WHERE type IN ('table','view')"
3728 " AND name NOT LIKE 'sqlite_%%'"
3729 " AND name LIKE ?1", zSql);
3730 }else{
3731 zSql = sqlite3_mprintf(
3732 "%z UNION ALL "
3733 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3734 " WHERE type IN ('table','view')"
3735 " AND name NOT LIKE 'sqlite_%%'"
3736 " AND name LIKE ?1", zSql, zDbName, zDbName);
3737 }
drha50da102000-08-08 20:19:09 +00003738 }
drh98781232012-04-23 12:38:05 +00003739 sqlite3_finalize(pStmt);
3740 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3741 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3742 sqlite3_free(zSql);
3743 if( rc ) return rc;
3744 nRow = nAlloc = 0;
3745 azResult = 0;
3746 if( nArg>1 ){
3747 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003748 }else{
drh98781232012-04-23 12:38:05 +00003749 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3750 }
3751 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3752 if( nRow>=nAlloc ){
3753 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00003754 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00003755 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00003756 if( azNew==0 ){
3757 fprintf(stderr, "Error: out of memory\n");
3758 break;
3759 }
mistachkin8e189222015-04-19 21:43:16 +00003760 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00003761 azResult = azNew;
3762 }
3763 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3764 if( azResult[nRow] ) nRow++;
3765 }
3766 sqlite3_finalize(pStmt);
3767 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003768 int len, maxlen = 0;
3769 int i, j;
3770 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003771 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003772 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003773 if( len>maxlen ) maxlen = len;
3774 }
3775 nPrintCol = 80/(maxlen+2);
3776 if( nPrintCol<1 ) nPrintCol = 1;
3777 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3778 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003779 for(j=i; j<nRow; j+=nPrintRow){
3780 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003781 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003782 }
drh151b7d52013-05-06 20:28:54 +00003783 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003784 }
3785 }
drh98781232012-04-23 12:38:05 +00003786 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3787 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003788 }else
3789
shaneh96887e12011-02-10 21:08:58 +00003790 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003791 static const struct {
3792 const char *zCtrlName; /* Name of a test-control option */
3793 int ctrlCode; /* Integer code for that option */
3794 } aCtrl[] = {
3795 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3796 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3797 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3798 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3799 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3800 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3801 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3802 { "assert", SQLITE_TESTCTRL_ASSERT },
3803 { "always", SQLITE_TESTCTRL_ALWAYS },
3804 { "reserve", SQLITE_TESTCTRL_RESERVE },
3805 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3806 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003807 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003808 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003809 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003810 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003811 };
shaneh96887e12011-02-10 21:08:58 +00003812 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00003813 int rc2 = 0;
3814 int i, n2;
drh05782482013-10-24 15:20:20 +00003815 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003816
drhd416fe72011-03-17 16:45:50 +00003817 /* convert testctrl text option to value. allow any unique prefix
3818 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00003819 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003820 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00003821 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00003822 if( testctrl<0 ){
3823 testctrl = aCtrl[i].ctrlCode;
3824 }else{
drhb07028f2011-10-14 21:49:18 +00003825 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003826 testctrl = -1;
3827 break;
3828 }
3829 }
3830 }
drh348d19c2013-06-03 12:47:43 +00003831 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003832 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3833 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3834 }else{
3835 switch(testctrl){
3836
3837 /* sqlite3_test_control(int, db, int) */
3838 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3839 case SQLITE_TESTCTRL_RESERVE:
3840 if( nArg==3 ){
3841 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00003842 rc2 = sqlite3_test_control(testctrl, p->db, opt);
3843 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003844 } else {
drhd416fe72011-03-17 16:45:50 +00003845 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3846 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003847 }
3848 break;
3849
3850 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003851 case SQLITE_TESTCTRL_PRNG_SAVE:
3852 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003853 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003854 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003855 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00003856 rc2 = sqlite3_test_control(testctrl);
3857 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003858 } else {
3859 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3860 }
3861 break;
3862
3863 /* sqlite3_test_control(int, uint) */
3864 case SQLITE_TESTCTRL_PENDING_BYTE:
3865 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003866 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003867 rc2 = sqlite3_test_control(testctrl, opt);
3868 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003869 } else {
drhd416fe72011-03-17 16:45:50 +00003870 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3871 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003872 }
3873 break;
3874
3875 /* sqlite3_test_control(int, int) */
3876 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003877 case SQLITE_TESTCTRL_ALWAYS:
3878 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003879 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003880 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003881 rc2 = sqlite3_test_control(testctrl, opt);
3882 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003883 } else {
drhd416fe72011-03-17 16:45:50 +00003884 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3885 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003886 }
3887 break;
3888
3889 /* sqlite3_test_control(int, char *) */
3890#ifdef SQLITE_N_KEYWORD
3891 case SQLITE_TESTCTRL_ISKEYWORD:
3892 if( nArg==3 ){
3893 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00003894 rc2 = sqlite3_test_control(testctrl, opt);
3895 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003896 } else {
drhd416fe72011-03-17 16:45:50 +00003897 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3898 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003899 }
3900 break;
3901#endif
3902
drh1ffede82015-01-30 20:59:27 +00003903 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003904 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00003905 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003906 azArg[2],
drh8964b342015-01-29 17:54:52 +00003907 integerValue(azArg[3]),
3908 integerValue(azArg[4]));
mistachkin8e189222015-04-19 21:43:16 +00003909 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00003910 }else{
drh6f5a37a2015-03-27 02:27:20 +00003911 fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003912 }
3913 break;
3914
shaneh96887e12011-02-10 21:08:58 +00003915 case SQLITE_TESTCTRL_BITVEC_TEST:
3916 case SQLITE_TESTCTRL_FAULT_INSTALL:
3917 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3918 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3919 default:
drhd416fe72011-03-17 16:45:50 +00003920 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3921 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003922 break;
3923 }
3924 }
3925 }else
3926
drhc2ce0be2014-05-29 12:36:14 +00003927 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003928 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003929 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003930 }else
3931
drhc2ce0be2014-05-29 12:36:14 +00003932 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3933 if( nArg==2 ){
3934 enableTimer = booleanValue(azArg[1]);
3935 if( enableTimer && !HAS_TIMER ){
3936 fprintf(stderr, "Error: timer not available on this system.\n");
3937 enableTimer = 0;
3938 }
3939 }else{
3940 fprintf(stderr, "Usage: .timer on|off\n");
3941 rc = 1;
3942 }
shanehe2aa9d72009-11-06 17:20:17 +00003943 }else
3944
drhc2ce0be2014-05-29 12:36:14 +00003945 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003946 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003947 if( nArg!=2 ){
3948 fprintf(stderr, "Usage: .trace FILE|off\n");
3949 rc = 1;
3950 goto meta_command_exit;
3951 }
drh657b4a82015-03-19 13:30:41 +00003952 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00003953 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003954#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003955 if( p->traceOut==0 ){
3956 sqlite3_trace(p->db, 0, 0);
3957 }else{
3958 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3959 }
3960#endif
3961 }else
3962
drhf442e332014-09-10 19:01:14 +00003963#if SQLITE_USER_AUTHENTICATION
3964 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3965 if( nArg<2 ){
3966 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3967 rc = 1;
3968 goto meta_command_exit;
3969 }
drh7883ecf2014-09-11 16:19:31 +00003970 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003971 if( strcmp(azArg[1],"login")==0 ){
3972 if( nArg!=4 ){
3973 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3974 rc = 1;
3975 goto meta_command_exit;
3976 }
drhd39c40f2014-09-11 00:27:53 +00003977 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3978 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003979 if( rc ){
3980 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3981 rc = 1;
3982 }
3983 }else if( strcmp(azArg[1],"add")==0 ){
3984 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003985 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003986 rc = 1;
3987 goto meta_command_exit;
3988 }
drhd39c40f2014-09-11 00:27:53 +00003989 rc = sqlite3_user_add(p->db, azArg[2],
3990 azArg[3], (int)strlen(azArg[3]),
3991 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003992 if( rc ){
3993 fprintf(stderr, "User-Add failed: %d\n", rc);
3994 rc = 1;
3995 }
3996 }else if( strcmp(azArg[1],"edit")==0 ){
3997 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003998 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003999 rc = 1;
4000 goto meta_command_exit;
4001 }
drhd39c40f2014-09-11 00:27:53 +00004002 rc = sqlite3_user_change(p->db, azArg[2],
4003 azArg[3], (int)strlen(azArg[3]),
4004 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004005 if( rc ){
4006 fprintf(stderr, "User-Edit failed: %d\n", rc);
4007 rc = 1;
4008 }
4009 }else if( strcmp(azArg[1],"delete")==0 ){
4010 if( nArg!=3 ){
4011 fprintf(stderr, "Usage: .user delete USER\n");
4012 rc = 1;
4013 goto meta_command_exit;
4014 }
4015 rc = sqlite3_user_delete(p->db, azArg[2]);
4016 if( rc ){
4017 fprintf(stderr, "User-Delete failed: %d\n", rc);
4018 rc = 1;
4019 }
4020 }else{
4021 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
4022 rc = 1;
4023 goto meta_command_exit;
4024 }
4025 }else
4026#endif /* SQLITE_USER_AUTHENTICATION */
4027
drh9fd301b2011-06-03 13:28:22 +00004028 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00004029 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004030 sqlite3_libversion(), sqlite3_sourceid());
4031 }else
4032
drhde60fc22011-12-14 17:53:36 +00004033 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4034 const char *zDbName = nArg==2 ? azArg[1] : "main";
4035 char *zVfsName = 0;
4036 if( p->db ){
4037 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4038 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00004039 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004040 sqlite3_free(zVfsName);
4041 }
4042 }
4043 }else
4044
drhcef4fc82012-09-21 22:50:45 +00004045#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4046 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4047 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004048 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004049 }else
4050#endif
4051
drhc2ce0be2014-05-29 12:36:14 +00004052 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004053 int j;
drh43617e92006-03-06 20:55:46 +00004054 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004055 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004056 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004057 }
4058 }else
4059
4060 {
shane9bd1b442009-10-23 01:27:39 +00004061 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004062 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004063 rc = 1;
drh75897232000-05-29 14:26:00 +00004064 }
drh67505e72002-04-19 12:34:06 +00004065
drhc2ce0be2014-05-29 12:36:14 +00004066meta_command_exit:
4067 if( p->outCount ){
4068 p->outCount--;
4069 if( p->outCount==0 ) output_reset(p);
4070 }
drh67505e72002-04-19 12:34:06 +00004071 return rc;
drh75897232000-05-29 14:26:00 +00004072}
4073
drh67505e72002-04-19 12:34:06 +00004074/*
drh91a66392007-09-07 01:12:32 +00004075** Return TRUE if a semicolon occurs anywhere in the first N characters
4076** of string z[].
drh324ccef2003-02-05 14:06:20 +00004077*/
drh9f099fd2013-08-06 14:01:46 +00004078static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004079 int i;
4080 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4081 return 0;
drh324ccef2003-02-05 14:06:20 +00004082}
4083
4084/*
drh70c7a4b2003-04-26 03:03:06 +00004085** Test to see if a line consists entirely of whitespace.
4086*/
4087static int _all_whitespace(const char *z){
4088 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004089 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004090 if( *z=='/' && z[1]=='*' ){
4091 z += 2;
4092 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4093 if( *z==0 ) return 0;
4094 z++;
4095 continue;
4096 }
4097 if( *z=='-' && z[1]=='-' ){
4098 z += 2;
4099 while( *z && *z!='\n' ){ z++; }
4100 if( *z==0 ) return 1;
4101 continue;
4102 }
4103 return 0;
4104 }
4105 return 1;
4106}
4107
4108/*
drha9b17162003-04-29 18:01:28 +00004109** Return TRUE if the line typed in is an SQL command terminator other
4110** than a semi-colon. The SQL Server style "go" command is understood
4111** as is the Oracle "/".
4112*/
drh9f099fd2013-08-06 14:01:46 +00004113static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004114 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004115 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4116 return 1; /* Oracle */
4117 }
drhf0693c82011-10-11 20:41:54 +00004118 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004119 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004120 return 1; /* SQL Server */
4121 }
4122 return 0;
4123}
4124
4125/*
drh233a5312008-12-18 22:25:13 +00004126** Return true if zSql is a complete SQL statement. Return false if it
4127** ends in the middle of a string literal or C-style comment.
4128*/
drh9f099fd2013-08-06 14:01:46 +00004129static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004130 int rc;
4131 if( zSql==0 ) return 1;
4132 zSql[nSql] = ';';
4133 zSql[nSql+1] = 0;
4134 rc = sqlite3_complete(zSql);
4135 zSql[nSql] = 0;
4136 return rc;
4137}
4138
4139/*
drh67505e72002-04-19 12:34:06 +00004140** Read input from *in and process it. If *in==0 then input
4141** is interactive - the user is typing it it. Otherwise, input
4142** is coming from a file or device. A prompt is issued and history
4143** is saved only if input is interactive. An interrupt signal will
4144** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004145**
4146** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004147*/
drhdcd87a92014-08-18 13:45:42 +00004148static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004149 char *zLine = 0; /* A single input line */
4150 char *zSql = 0; /* Accumulated SQL text */
4151 int nLine; /* Length of current line */
4152 int nSql = 0; /* Bytes of zSql[] used */
4153 int nAlloc = 0; /* Allocated zSql[] space */
4154 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4155 char *zErrMsg; /* Error message returned */
4156 int rc; /* Error code */
4157 int errCnt = 0; /* Number of errors seen */
4158 int lineno = 0; /* Current line number */
4159 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004160
4161 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4162 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004163 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004164 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004165 /* End of input */
4166 if( stdin_is_interactive ) printf("\n");
4167 break;
drhc49f44e2006-10-26 18:15:42 +00004168 }
drh67505e72002-04-19 12:34:06 +00004169 if( seenInterrupt ){
4170 if( in!=0 ) break;
4171 seenInterrupt = 0;
4172 }
drhc28490c2006-10-26 14:25:58 +00004173 lineno++;
drh849a9d92013-12-21 15:46:06 +00004174 if( nSql==0 && _all_whitespace(zLine) ){
4175 if( p->echoOn ) printf("%s\n", zLine);
4176 continue;
4177 }
drh2af0b2d2002-02-21 02:25:02 +00004178 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004179 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004180 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004181 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004182 break;
4183 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004184 errCnt++;
4185 }
drhdaffd0e2001-04-11 14:28:42 +00004186 continue;
4187 }
drh9f099fd2013-08-06 14:01:46 +00004188 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004189 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004190 }
drh9f099fd2013-08-06 14:01:46 +00004191 nLine = strlen30(zLine);
4192 if( nSql+nLine+2>=nAlloc ){
4193 nAlloc = nSql+nLine+100;
4194 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004195 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004196 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004197 exit(1);
4198 }
drhdaffd0e2001-04-11 14:28:42 +00004199 }
drh9f099fd2013-08-06 14:01:46 +00004200 nSqlPrior = nSql;
4201 if( nSql==0 ){
4202 int i;
4203 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004204 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004205 memcpy(zSql, zLine+i, nLine+1-i);
4206 startline = lineno;
4207 nSql = nLine-i;
4208 }else{
4209 zSql[nSql++] = '\n';
4210 memcpy(zSql+nSql, zLine, nLine+1);
4211 nSql += nLine;
4212 }
4213 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004214 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004215 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004216 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004217 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004218 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004219 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004220 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004221 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004222 char zPrefix[100];
4223 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004224 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004225 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004226 }else{
shane9bd1b442009-10-23 01:27:39 +00004227 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004228 }
drh7f953e22002-07-13 17:33:45 +00004229 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004230 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004231 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004232 zErrMsg = 0;
4233 }else{
shaned2bed1c2009-10-21 03:56:54 +00004234 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004235 }
drhc49f44e2006-10-26 18:15:42 +00004236 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004237 }
drhdaffd0e2001-04-11 14:28:42 +00004238 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004239 if( p->outCount ){
4240 output_reset(p);
4241 p->outCount = 0;
4242 }
drh9f099fd2013-08-06 14:01:46 +00004243 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004244 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004245 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004246 }
4247 }
drh9f099fd2013-08-06 14:01:46 +00004248 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004249 if( !_all_whitespace(zSql) ){
4250 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004251 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004252 }
drhdaffd0e2001-04-11 14:28:42 +00004253 free(zSql);
4254 }
danielk19772ac27622007-07-03 05:31:16 +00004255 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004256 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004257}
4258
drh67505e72002-04-19 12:34:06 +00004259/*
4260** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004261** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004262*/
4263static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004264 static char *home_dir = NULL;
4265 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004266
drh4ace5362014-11-10 14:42:28 +00004267#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4268 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004269 {
4270 struct passwd *pwent;
4271 uid_t uid = getuid();
4272 if( (pwent=getpwuid(uid)) != NULL) {
4273 home_dir = pwent->pw_dir;
4274 }
drh67505e72002-04-19 12:34:06 +00004275 }
4276#endif
4277
chw65d3c132007-11-12 21:09:10 +00004278#if defined(_WIN32_WCE)
4279 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4280 */
drh85e72432012-04-11 11:38:53 +00004281 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004282#else
4283
drh83905c92012-06-21 13:00:37 +00004284#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004285 if (!home_dir) {
4286 home_dir = getenv("USERPROFILE");
4287 }
4288#endif
4289
drh67505e72002-04-19 12:34:06 +00004290 if (!home_dir) {
4291 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004292 }
4293
drh83905c92012-06-21 13:00:37 +00004294#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004295 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004296 char *zDrive, *zPath;
4297 int n;
4298 zDrive = getenv("HOMEDRIVE");
4299 zPath = getenv("HOMEPATH");
4300 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004301 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004302 home_dir = malloc( n );
4303 if( home_dir==0 ) return 0;
4304 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4305 return home_dir;
4306 }
4307 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004308 }
4309#endif
4310
chw65d3c132007-11-12 21:09:10 +00004311#endif /* !_WIN32_WCE */
4312
drh67505e72002-04-19 12:34:06 +00004313 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004314 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004315 char *z = malloc( n );
4316 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004317 home_dir = z;
4318 }
drhe98d4fa2002-04-21 19:06:22 +00004319
drh67505e72002-04-19 12:34:06 +00004320 return home_dir;
4321}
4322
4323/*
4324** Read input from the file given by sqliterc_override. Or if that
4325** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004326**
4327** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004328*/
drh534f4df2015-02-28 14:03:35 +00004329static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004330 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004331 const char *sqliterc_override /* Name of config file. NULL to use default */
4332){
persicom7e2dfdd2002-04-18 02:46:52 +00004333 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004334 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004335 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004336 FILE *in = NULL;
4337
4338 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004339 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004340 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004341 fprintf(stderr, "-- warning: cannot find home directory;"
4342 " cannot read ~/.sqliterc\n");
4343 return;
drhe98d4fa2002-04-21 19:06:22 +00004344 }
drh2f3de322012-06-27 16:41:31 +00004345 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004346 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4347 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004348 }
drha1f9b5e2004-02-14 16:31:02 +00004349 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004350 if( in ){
drhc28490c2006-10-26 14:25:58 +00004351 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004352 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004353 }
drh534f4df2015-02-28 14:03:35 +00004354 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004355 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004356 }
drh85e72432012-04-11 11:38:53 +00004357 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004358}
4359
drh67505e72002-04-19 12:34:06 +00004360/*
drhe1e38c42003-05-04 18:30:59 +00004361** Show available command line options
4362*/
4363static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004364 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004365 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004366 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004367 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004368 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004369 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004370 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004371 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004372 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004373#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4374 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4375#endif
drhcc3b4f82012-02-07 14:13:50 +00004376 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004377 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004378 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004379 " -line set output mode to 'line'\n"
4380 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004381 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004382 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004383#ifdef SQLITE_ENABLE_MULTIPLEX
4384 " -multiplex enable the multiplexor VFS\n"
4385#endif
mistachkine0d68852014-12-11 03:12:33 +00004386 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004387 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004388 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4389 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004390 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004391 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004392 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004393 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004394#ifdef SQLITE_ENABLE_VFSTRACE
4395 " -vfstrace enable tracing of all VFS calls\n"
4396#endif
drhe1e38c42003-05-04 18:30:59 +00004397;
4398static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004399 fprintf(stderr,
4400 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4401 "FILENAME is the name of an SQLite database. A new database is created\n"
4402 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004403 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004404 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004405 }else{
4406 fprintf(stderr, "Use the -help option for additional information\n");
4407 }
4408 exit(1);
4409}
4410
4411/*
drh67505e72002-04-19 12:34:06 +00004412** Initialize the state information in data
4413*/
drhdcd87a92014-08-18 13:45:42 +00004414static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004415 memset(data, 0, sizeof(*data));
4416 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004417 memcpy(data->colSeparator,SEP_Column, 2);
4418 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004419 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004420 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004421 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004422 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004423 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004424 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4425 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004426}
4427
drh98d312f2012-10-25 15:23:14 +00004428/*
drh5c7976f2014-02-10 19:59:27 +00004429** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004430*/
4431#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004432static void printBold(const char *zText){
4433 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4434 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4435 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4436 SetConsoleTextAttribute(out,
4437 FOREGROUND_RED|FOREGROUND_INTENSITY
4438 );
4439 printf("%s", zText);
4440 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004441}
4442#else
drh5c7976f2014-02-10 19:59:27 +00004443static void printBold(const char *zText){
4444 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004445}
4446#endif
4447
4448/*
drh98d312f2012-10-25 15:23:14 +00004449** Get the argument to an --option. Throw an error and die if no argument
4450** is available.
4451*/
4452static char *cmdline_option_value(int argc, char **argv, int i){
4453 if( i==argc ){
4454 fprintf(stderr, "%s: Error: missing argument to %s\n",
4455 argv[0], argv[argc-1]);
4456 exit(1);
4457 }
4458 return argv[i];
4459}
4460
mistachkin44723ce2015-03-21 02:22:37 +00004461int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004462 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004463 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004464 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004465 int i;
drhc28490c2006-10-26 14:25:58 +00004466 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004467 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004468 int readStdin = 1;
4469 int nCmd = 0;
4470 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004471
drh69b30ab2014-02-27 15:11:52 +00004472#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004473 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4474 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4475 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4476 exit(1);
4477 }
drhc7181902014-02-27 15:04:13 +00004478#endif
drh047d4532015-01-18 20:30:23 +00004479 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004480 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004481 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004482 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004483 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004484
drh44c2eb12003-04-30 11:38:26 +00004485 /* Make sure we have a valid signal handler early, before anything
4486 ** else is done.
4487 */
drh4c504392000-10-16 22:06:40 +00004488#ifdef SIGINT
4489 signal(SIGINT, interrupt_handler);
4490#endif
drh44c2eb12003-04-30 11:38:26 +00004491
drhac5649a2014-11-28 13:35:03 +00004492#ifdef SQLITE_SHELL_DBNAME_PROC
4493 {
4494 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4495 ** of a C-function that will provide the name of the database file. Use
4496 ** this compile-time option to embed this shell program in larger
4497 ** applications. */
4498 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4499 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4500 warnInmemoryDb = 0;
4501 }
4502#endif
4503
drh22fbcb82004-02-01 01:22:50 +00004504 /* Do an initial pass through the command-line argument to locate
4505 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004506 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004507 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004508 */
drh98d312f2012-10-25 15:23:14 +00004509 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004510 char *z;
drhc28490c2006-10-26 14:25:58 +00004511 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004512 if( z[0]!='-' ){
4513 if( data.zDbFilename==0 ){
4514 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004515 }else{
4516 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4517 ** mean that nothing is read from stdin */
4518 readStdin = 0;
4519 nCmd++;
4520 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4521 if( azCmd==0 ){
4522 fprintf(stderr, "out of memory\n");
4523 exit(1);
4524 }
4525 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004526 }
drh98d312f2012-10-25 15:23:14 +00004527 }
drhcc3b4f82012-02-07 14:13:50 +00004528 if( z[1]=='-' ) z++;
4529 if( strcmp(z,"-separator")==0
4530 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004531 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004532 || strcmp(z,"-cmd")==0
4533 ){
drh98d312f2012-10-25 15:23:14 +00004534 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004535 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004536 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004537 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004538 /* Need to check for batch mode here to so we can avoid printing
4539 ** informational messages (like from process_sqliterc) before
4540 ** we do the actual processing of arguments later in a second pass.
4541 */
shanef69573d2009-10-24 02:06:14 +00004542 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004543 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004544#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004545 const char *zSize;
4546 sqlite3_int64 szHeap;
4547
drh98d312f2012-10-25 15:23:14 +00004548 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004549 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004550 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004551 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4552#endif
drh44dec872014-08-30 15:49:25 +00004553 }else if( strcmp(z,"-scratch")==0 ){
4554 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004555 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004556 if( sz>400000 ) sz = 400000;
4557 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004558 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004559 if( n>10 ) n = 10;
4560 if( n<1 ) n = 1;
4561 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4562 data.shellFlgs |= SHFLG_Scratch;
4563 }else if( strcmp(z,"-pagecache")==0 ){
4564 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004565 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004566 if( sz>70000 ) sz = 70000;
4567 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004568 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004569 if( n<10 ) n = 10;
4570 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4571 data.shellFlgs |= SHFLG_Pagecache;
4572 }else if( strcmp(z,"-lookaside")==0 ){
4573 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004574 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004575 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004576 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004577 if( n<0 ) n = 0;
4578 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4579 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004580#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004581 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004582 extern int vfstrace_register(
4583 const char *zTraceName,
4584 const char *zOldVfsName,
4585 int (*xOut)(const char*,void*),
4586 void *pOutArg,
4587 int makeDefault
4588 );
drh2b625e22011-03-16 17:05:28 +00004589 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004590#endif
drh6f25e892011-07-08 17:02:57 +00004591#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004592 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004593 extern int sqlite3_multiple_initialize(const char*,int);
4594 sqlite3_multiplex_initialize(0, 1);
4595#endif
drh7d9f3942013-04-03 01:26:54 +00004596 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004597 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4598 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004599 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004600 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004601 if( pVfs ){
4602 sqlite3_vfs_register(pVfs, 1);
4603 }else{
4604 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4605 exit(1);
4606 }
drh44c2eb12003-04-30 11:38:26 +00004607 }
4608 }
drh98d312f2012-10-25 15:23:14 +00004609 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004610#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004611 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004612 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004613#else
shane86f5bdb2009-10-24 02:00:07 +00004614 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4615 return 1;
drh01b41712005-08-29 23:06:23 +00004616#endif
drh98d312f2012-10-25 15:23:14 +00004617 }
4618 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004619
drh44c2eb12003-04-30 11:38:26 +00004620 /* Go ahead and open the database file if it already exists. If the
4621 ** file does not exist, delay opening it. This prevents empty database
4622 ** files from being created if a user mistypes the database name argument
4623 ** to the sqlite command-line tool.
4624 */
drhc8d74412004-08-31 23:41:26 +00004625 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004626 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004627 }
4628
drh22fbcb82004-02-01 01:22:50 +00004629 /* Process the initialization file if there is one. If no -init option
4630 ** is given on the command line, look for a file named ~/.sqliterc and
4631 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004632 */
drh534f4df2015-02-28 14:03:35 +00004633 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004634
drh22fbcb82004-02-01 01:22:50 +00004635 /* Make a second pass through the command-line argument and set
4636 ** options. This second pass is delayed until after the initialization
4637 ** file is processed so that the command-line arguments will override
4638 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004639 */
drh98d312f2012-10-25 15:23:14 +00004640 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004641 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004642 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004643 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004644 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004645 i++;
4646 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004647 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004648 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004649 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004650 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004651 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004652 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004653 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004654 }else if( strcmp(z,"-csv")==0 ){
4655 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004656 memcpy(data.colSeparator,",",2);
4657 }else if( strcmp(z,"-ascii")==0 ){
4658 data.mode = MODE_Ascii;
4659 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004660 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004661 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004662 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004663 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004664 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4665 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004666 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004667 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004668 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004669 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004670 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004671 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004672 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004673 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004674 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004675 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004676 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004677 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004678 }else if( strcmp(z,"-eqp")==0 ){
4679 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004680 }else if( strcmp(z,"-stats")==0 ){
4681 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004682 }else if( strcmp(z,"-scanstats")==0 ){
4683 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004684 }else if( strcmp(z,"-backslash")==0 ){
4685 /* Undocumented command-line option: -backslash
4686 ** Causes C-style backslash escapes to be evaluated in SQL statements
4687 ** prior to sending the SQL into SQLite. Useful for injecting
4688 ** crazy bytes in the middle of SQL statements for testing and debugging.
4689 */
4690 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004691 }else if( strcmp(z,"-bail")==0 ){
4692 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004693 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004694 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004695 return 0;
drhc28490c2006-10-26 14:25:58 +00004696 }else if( strcmp(z,"-interactive")==0 ){
4697 stdin_is_interactive = 1;
4698 }else if( strcmp(z,"-batch")==0 ){
4699 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004700 }else if( strcmp(z,"-heap")==0 ){
4701 i++;
drh44dec872014-08-30 15:49:25 +00004702 }else if( strcmp(z,"-scratch")==0 ){
4703 i+=2;
4704 }else if( strcmp(z,"-pagecache")==0 ){
4705 i+=2;
4706 }else if( strcmp(z,"-lookaside")==0 ){
4707 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004708 }else if( strcmp(z,"-mmap")==0 ){
4709 i++;
drha7e61d82011-03-12 17:02:57 +00004710 }else if( strcmp(z,"-vfs")==0 ){
4711 i++;
drh6f25e892011-07-08 17:02:57 +00004712#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004713 }else if( strcmp(z,"-vfstrace")==0 ){
4714 i++;
drh6f25e892011-07-08 17:02:57 +00004715#endif
4716#ifdef SQLITE_ENABLE_MULTIPLEX
4717 }else if( strcmp(z,"-multiplex")==0 ){
4718 i++;
4719#endif
drhcc3b4f82012-02-07 14:13:50 +00004720 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004721 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004722 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004723 /* Run commands that follow -cmd first and separately from commands
4724 ** that simply appear on the command-line. This seems goofy. It would
4725 ** be better if all commands ran in the order that they appear. But
4726 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004727 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004728 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004729 if( z[0]=='.' ){
4730 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004731 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004732 }else{
drh05782482013-10-24 15:20:20 +00004733 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004734 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4735 if( zErrMsg!=0 ){
4736 fprintf(stderr,"Error: %s\n", zErrMsg);
4737 if( bail_on_error ) return rc!=0 ? rc : 1;
4738 }else if( rc!=0 ){
4739 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4740 if( bail_on_error ) return rc;
4741 }
4742 }
drh1e5d0e92000-05-31 23:33:17 +00004743 }else{
shane86f5bdb2009-10-24 02:00:07 +00004744 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004745 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004746 return 1;
4747 }
4748 }
drh44c2eb12003-04-30 11:38:26 +00004749
drhac5649a2014-11-28 13:35:03 +00004750 if( !readStdin ){
4751 /* Run all arguments that do not begin with '-' as if they were separate
4752 ** command-line inputs, except for the argToSkip argument which contains
4753 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004754 */
drhac5649a2014-11-28 13:35:03 +00004755 for(i=0; i<nCmd; i++){
4756 if( azCmd[i][0]=='.' ){
4757 rc = do_meta_command(azCmd[i], &data);
4758 if( rc ) return rc==2 ? 0 : rc;
4759 }else{
4760 open_db(&data, 0);
4761 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4762 if( zErrMsg!=0 ){
4763 fprintf(stderr,"Error: %s\n", zErrMsg);
4764 return rc!=0 ? rc : 1;
4765 }else if( rc!=0 ){
4766 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4767 return rc;
4768 }
drh6ff13852001-11-25 13:18:23 +00004769 }
drh75897232000-05-29 14:26:00 +00004770 }
drhac5649a2014-11-28 13:35:03 +00004771 free(azCmd);
drh75897232000-05-29 14:26:00 +00004772 }else{
drh44c2eb12003-04-30 11:38:26 +00004773 /* Run commands received from standard input
4774 */
drhc28490c2006-10-26 14:25:58 +00004775 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004776 char *zHome;
4777 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004778 int nHistory;
drh75897232000-05-29 14:26:00 +00004779 printf(
drh743e0032011-12-12 16:51:50 +00004780 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004781 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004782 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004783 );
drhb3735912014-02-10 16:13:42 +00004784 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004785 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004786 printBold("transient in-memory database");
4787 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004788 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004789 }
drh67505e72002-04-19 12:34:06 +00004790 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004791 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004792 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004793 if( (zHistory = malloc(nHistory))!=0 ){
4794 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4795 }
drh67505e72002-04-19 12:34:06 +00004796 }
drhf5ed7ad2015-06-15 14:43:25 +00004797 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00004798 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004799 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004800 shell_stifle_history(100);
4801 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004802 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004803 }
drhdaffd0e2001-04-11 14:28:42 +00004804 }else{
drhc28490c2006-10-26 14:25:58 +00004805 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004806 }
4807 }
drh33048c02001-10-01 14:29:22 +00004808 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004809 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004810 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004811 }
drh05782482013-10-24 15:20:20 +00004812 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004813 return rc;
drh75897232000-05-29 14:26:00 +00004814}