blob: 4860a02eebc21e77841d2b9b828d37eeae63041c [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
93# define shell_read_history(X)
94# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
shane18e526c2008-12-10 22:30:24 +0000104#define isatty(h) _isatty(h)
drh07901eb2014-02-28 19:37:45 +0000105#ifndef access
106# define access(f,m) _access((f),(m))
107#endif
drh67ceaa62012-08-27 21:19:03 +0000108#undef popen
drh53371f92013-07-25 17:07:03 +0000109#define popen _popen
drh67ceaa62012-08-27 21:19:03 +0000110#undef pclose
drh12cd6cf2013-06-29 15:40:22 +0000111#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
drh4328c8b2003-04-26 02:50:11 +0000113/* Make sure isatty() has a prototype.
114*/
drhb2acc3b2011-10-13 16:36:29 +0000115extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000116
drh8cd5b252015-03-02 22:06:43 +0000117#if !defined(__RTP__) && !defined(_WRS_KERNEL)
118 /* popen and pclose are not C89 functions and so are sometimes omitted from
119 ** the <stdio.h> header */
120 extern FILE *popen(const char*,const char*);
121 extern int pclose(FILE*);
122#else
123# define SQLITE_OMIT_POPEN 1
124#endif
125
mistachkinf6418892013-08-28 01:54:12 +0000126#endif
drh53371f92013-07-25 17:07:03 +0000127
chw65d3c132007-11-12 21:09:10 +0000128#if defined(_WIN32_WCE)
129/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
130 * thus we always assume that we have a console. That can be
131 * overridden with the -batch command line option.
132 */
133#define isatty(x) 1
134#endif
135
drhf0693c82011-10-11 20:41:54 +0000136/* ctype macros that work with signed characters */
137#define IsSpace(X) isspace((unsigned char)X)
138#define IsDigit(X) isdigit((unsigned char)X)
139#define ToLower(X) (char)tolower((unsigned char)X)
140
drh047d4532015-01-18 20:30:23 +0000141/* On Windows, we normally run with output mode of TEXT so that \n characters
142** are automatically translated into \r\n. However, this behavior needs
143** to be disabled in some cases (ex: when generating CSV output and when
144** rendering quoted strings that contain \n characters). The following
145** routines take care of that.
146*/
147#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000148static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000149 fflush(out);
150 _setmode(_fileno(out), _O_BINARY);
151}
mistachkine4a0d792015-01-27 21:24:33 +0000152static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000153 fflush(out);
154 _setmode(_fileno(out), _O_TEXT);
155}
156#else
157# define setBinaryMode(X)
158# define setTextMode(X)
159#endif
160
drh43408312013-10-30 12:43:36 +0000161
162/* True if the timer is enabled */
163static int enableTimer = 0;
164
165/* Return the current wall-clock time */
166static sqlite3_int64 timeOfDay(void){
167 static sqlite3_vfs *clockVfs = 0;
168 sqlite3_int64 t;
169 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
170 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
171 clockVfs->xCurrentTimeInt64(clockVfs, &t);
172 }else{
173 double r;
174 clockVfs->xCurrentTime(clockVfs, &r);
175 t = (sqlite3_int64)(r*86400000.0);
176 }
177 return t;
178}
179
drh91eb93c2015-03-03 19:56:20 +0000180#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000181#include <sys/time.h>
182#include <sys/resource.h>
183
drh91eb93c2015-03-03 19:56:20 +0000184/* VxWorks does not support getrusage() as far as we can determine */
185#if defined(_WRS_KERNEL) || defined(__RTP__)
186struct rusage {
187 struct timeval ru_utime; /* user CPU time used */
188 struct timeval ru_stime; /* system CPU time used */
189};
190#define getrusage(A,B) memset(B,0,sizeof(*B))
191#endif
192
drhda108222009-02-25 19:07:24 +0000193/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000194static struct rusage sBegin; /* CPU time at start */
195static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000196
drhda108222009-02-25 19:07:24 +0000197/*
198** Begin timing an operation
199*/
200static void beginTimer(void){
201 if( enableTimer ){
202 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000203 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000204 }
205}
206
207/* Return the difference of two time_structs in seconds */
208static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
209 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
210 (double)(pEnd->tv_sec - pStart->tv_sec);
211}
212
213/*
214** Print the timing results.
215*/
216static void endTimer(void){
217 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000218 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000219 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000220 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000221 printf("Run Time: real %.3f user %f sys %f\n",
222 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000223 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
224 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
225 }
226}
shaneb320ccd2009-10-21 03:42:58 +0000227
drhda108222009-02-25 19:07:24 +0000228#define BEGIN_TIMER beginTimer()
229#define END_TIMER endTimer()
230#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000231
232#elif (defined(_WIN32) || defined(WIN32))
233
234#include <windows.h>
235
236/* Saved resource information for the beginning of an operation */
237static HANDLE hProcess;
238static FILETIME ftKernelBegin;
239static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000240static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000241typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
242 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000243static GETPROCTIMES getProcessTimesAddr = NULL;
244
shaneb320ccd2009-10-21 03:42:58 +0000245/*
246** Check to see if we have timer support. Return 1 if necessary
247** support found (or found previously).
248*/
249static int hasTimer(void){
250 if( getProcessTimesAddr ){
251 return 1;
252 } else {
drh4ace5362014-11-10 14:42:28 +0000253 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
254 ** versions. See if the version we are running on has it, and if it
255 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000256 */
257 hProcess = GetCurrentProcess();
258 if( hProcess ){
259 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
260 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000261 getProcessTimesAddr =
262 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000263 if( NULL != getProcessTimesAddr ){
264 return 1;
265 }
266 FreeLibrary(hinstLib);
267 }
268 }
269 }
270 return 0;
271}
272
273/*
274** Begin timing an operation
275*/
276static void beginTimer(void){
277 if( enableTimer && getProcessTimesAddr ){
278 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000279 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
280 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000281 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000282 }
283}
284
285/* Return the difference of two FILETIME structs in seconds */
286static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
287 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
288 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
289 return (double) ((i64End - i64Start) / 10000000.0);
290}
291
292/*
293** Print the timing results.
294*/
295static void endTimer(void){
296 if( enableTimer && getProcessTimesAddr){
297 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000298 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000299 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000300 printf("Run Time: real %.3f user %f sys %f\n",
301 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000302 timeDiff(&ftUserBegin, &ftUserEnd),
303 timeDiff(&ftKernelBegin, &ftKernelEnd));
304 }
305}
306
307#define BEGIN_TIMER beginTimer()
308#define END_TIMER endTimer()
309#define HAS_TIMER hasTimer()
310
drhda108222009-02-25 19:07:24 +0000311#else
312#define BEGIN_TIMER
313#define END_TIMER
314#define HAS_TIMER 0
315#endif
316
shanec0688ea2009-03-05 03:48:06 +0000317/*
318** Used to prevent warnings about unused parameters
319*/
320#define UNUSED_PARAMETER(x) (void)(x)
321
drhe91d16b2008-12-08 18:27:31 +0000322/*
drhc49f44e2006-10-26 18:15:42 +0000323** If the following flag is set, then command execution stops
324** at an error if we are not interactive.
325*/
326static int bail_on_error = 0;
327
328/*
drhc28490c2006-10-26 14:25:58 +0000329** Threat stdin as an interactive input if the following variable
330** is true. Otherwise, assume stdin is connected to a file or pipe.
331*/
332static int stdin_is_interactive = 1;
333
334/*
drh4c504392000-10-16 22:06:40 +0000335** The following is the open SQLite database. We make a pointer
336** to this database a static variable so that it can be accessed
337** by the SIGINT handler to interrupt database processing.
338*/
danielk197792f9a1b2004-06-19 09:08:16 +0000339static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000340
341/*
drh67505e72002-04-19 12:34:06 +0000342** True if an interrupt (Control-C) has been received.
343*/
drh43617e92006-03-06 20:55:46 +0000344static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000345
346/*
persicom7e2dfdd2002-04-18 02:46:52 +0000347** This is the name of our program. It is set in main(), used
348** in a number of other places, mostly for error messages.
349*/
350static char *Argv0;
351
352/*
353** Prompt strings. Initialized in main. Settable with
354** .prompt main continue
355*/
356static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
357static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
358
drhb0603412007-02-28 04:47:26 +0000359/*
360** Write I/O traces to the following stream.
361*/
rsebe0a9092007-07-30 18:24:38 +0000362#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000363static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000364#endif
drhb0603412007-02-28 04:47:26 +0000365
366/*
367** This routine works like printf in that its first argument is a
368** format string and subsequent arguments are values to be substituted
369** in place of % fields. The result of formatting this string
370** is written to iotrace.
371*/
rsebe0a9092007-07-30 18:24:38 +0000372#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000373static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000374 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000375 char *z;
drhb0603412007-02-28 04:47:26 +0000376 if( iotrace==0 ) return;
377 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000378 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000379 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000380 fprintf(iotrace, "%s", z);
381 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000382}
rsebe0a9092007-07-30 18:24:38 +0000383#endif
drhb0603412007-02-28 04:47:26 +0000384
drh44c2eb12003-04-30 11:38:26 +0000385
persicom7e2dfdd2002-04-18 02:46:52 +0000386/*
drh83965662003-04-17 02:54:13 +0000387** Determines if a string is a number of not.
388*/
danielk19772e588c72005-12-09 14:25:08 +0000389static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000390 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000391 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000392 return 0;
393 }
394 z++;
395 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000396 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000397 if( *z=='.' ){
398 z++;
drhf0693c82011-10-11 20:41:54 +0000399 if( !IsDigit(*z) ) return 0;
400 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000401 if( realnum ) *realnum = 1;
402 }
403 if( *z=='e' || *z=='E' ){
404 z++;
405 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000406 if( !IsDigit(*z) ) return 0;
407 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000408 if( realnum ) *realnum = 1;
409 }
410 return *z==0;
411}
drh83965662003-04-17 02:54:13 +0000412
413/*
danielk1977bc6ada42004-06-30 08:20:16 +0000414** A global char* and an SQL function to access its current value
415** from within an SQL statement. This program used to use the
416** sqlite_exec_printf() API to substitue a string into an SQL statement.
417** The correct way to do this with sqlite3 is to use the bind API, but
418** since the shell is built around the callback paradigm it would be a lot
419** of work. Instead just use this hack, which is quite harmless.
420*/
421static const char *zShellStatic = 0;
422static void shellstaticFunc(
423 sqlite3_context *context,
424 int argc,
425 sqlite3_value **argv
426){
427 assert( 0==argc );
428 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000429 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000430 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000431 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
432}
433
434
435/*
drhfeac5f82004-08-01 00:10:45 +0000436** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000437** the text in memory obtained from malloc() and returns a pointer
438** to the text. NULL is returned at end of file, or if malloc()
439** fails.
440**
drh9f099fd2013-08-06 14:01:46 +0000441** If zLine is not NULL then it is a malloced buffer returned from
442** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000443*/
drh9f099fd2013-08-06 14:01:46 +0000444static char *local_getline(char *zLine, FILE *in){
445 int nLine = zLine==0 ? 0 : 100;
446 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000447
drhb07028f2011-10-14 21:49:18 +0000448 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000449 if( n+100>nLine ){
450 nLine = nLine*2 + 100;
451 zLine = realloc(zLine, nLine);
452 if( zLine==0 ) return 0;
453 }
drhdaffd0e2001-04-11 14:28:42 +0000454 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000455 if( n==0 ){
456 free(zLine);
457 return 0;
458 }
459 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000460 break;
461 }
drh9f099fd2013-08-06 14:01:46 +0000462 while( zLine[n] ) n++;
463 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000464 n--;
shaneh13b36022009-12-17 21:07:15 +0000465 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000466 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000467 break;
drh8e7e7a22000-05-30 18:45:23 +0000468 }
469 }
drh8e7e7a22000-05-30 18:45:23 +0000470 return zLine;
471}
472
473/*
drhc28490c2006-10-26 14:25:58 +0000474** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000475**
drh9f099fd2013-08-06 14:01:46 +0000476** If in==0 then read from standard input and prompt before each line.
477** If isContinuation is true, then a continuation prompt is appropriate.
478** If isContinuation is zero, then the main prompt should be used.
479**
480** If zPrior is not NULL then it is a buffer from a prior call to this
481** routine that can be reused.
482**
483** The result is stored in space obtained from malloc() and must either
484** be freed by the caller or else passed back into this routine via the
485** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000486*/
drh9f099fd2013-08-06 14:01:46 +0000487static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000488 char *zPrompt;
489 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000490 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000491 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000492 }else{
drh9f099fd2013-08-06 14:01:46 +0000493 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000494#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000495 printf("%s", zPrompt);
496 fflush(stdout);
497 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000498#else
499 free(zPrior);
500 zResult = shell_readline(zPrompt);
501 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000502#endif
drh9f099fd2013-08-06 14:01:46 +0000503 }
drh8e7e7a22000-05-30 18:45:23 +0000504 return zResult;
505}
506
drhdcd87a92014-08-18 13:45:42 +0000507/*
508** Shell output mode information from before ".explain on",
509** saved so that it can be restored by ".explain off"
510*/
511typedef struct SavedModeInfo SavedModeInfo;
512struct SavedModeInfo {
513 int valid; /* Is there legit data in here? */
514 int mode; /* Mode prior to ".explain on" */
515 int showHeader; /* The ".header" setting prior to ".explain on" */
516 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000517};
drh45e29d82006-11-20 16:21:10 +0000518
drh8e7e7a22000-05-30 18:45:23 +0000519/*
drhdcd87a92014-08-18 13:45:42 +0000520** State information about the database connection is contained in an
521** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000522*/
drhdcd87a92014-08-18 13:45:42 +0000523typedef struct ShellState ShellState;
524struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000525 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000526 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000527 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000528 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000529 int scanstatsOn; /* True to display scan stats before each finalize */
drhc2ce0be2014-05-29 12:36:14 +0000530 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000531 int cnt; /* Number of records displayed so far */
532 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000533 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000534 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000535 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000536 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000537 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000538 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000539 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000540 char colSeparator[20]; /* Column separator character for several modes */
541 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000542 int colWidth[100]; /* Requested width of each column when in column mode*/
543 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000544 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000545 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000546 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000547 char outfile[FILENAME_MAX]; /* Filename for *out */
548 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000549 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000550 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000551 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000552 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000553 int *aiIndent; /* Array of indents used in MODE_Explain */
554 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000555 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000556};
557
558/*
drh44dec872014-08-30 15:49:25 +0000559** These are the allowed shellFlgs values
560*/
561#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
562#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
563#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
564
565/*
drh75897232000-05-29 14:26:00 +0000566** These are the allowed modes.
567*/
drh967e8b72000-06-21 13:59:10 +0000568#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000569#define MODE_Column 1 /* One record per line in neat columns */
570#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000571#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
572#define MODE_Html 4 /* Generate an XHTML table */
573#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000574#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000575#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000576#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000577#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000578
drh66ce4d02008-02-15 17:38:06 +0000579static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000580 "line",
581 "column",
582 "list",
583 "semi",
584 "html",
drhfeac5f82004-08-01 00:10:45 +0000585 "insert",
586 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000587 "csv",
drh66ce4d02008-02-15 17:38:06 +0000588 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000589 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000590};
drh75897232000-05-29 14:26:00 +0000591
592/*
mistachkinfad42082014-07-24 22:13:12 +0000593** These are the column/row/line separators used by the various
594** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000595*/
mistachkinfad42082014-07-24 22:13:12 +0000596#define SEP_Column "|"
597#define SEP_Row "\n"
598#define SEP_Tab "\t"
599#define SEP_Space " "
600#define SEP_Comma ","
601#define SEP_CrLf "\r\n"
602#define SEP_Unit "\x1F"
603#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000604
605/*
drh75897232000-05-29 14:26:00 +0000606** Number of elements in an array
607*/
drh902b9ee2008-12-05 17:17:07 +0000608#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000609
610/*
drhea678832008-12-10 19:26:22 +0000611** Compute a string length that is limited to what can be stored in
612** lower 30 bits of a 32-bit signed integer.
613*/
drh4f21c4a2008-12-10 22:15:00 +0000614static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000615 const char *z2 = z;
616 while( *z2 ){ z2++; }
617 return 0x3fffffff & (int)(z2 - z);
618}
619
620/*
drh127f9d72010-02-23 01:47:00 +0000621** A callback for the sqlite3_log() interface.
622*/
623static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000624 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000625 if( p->pLog==0 ) return;
626 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
627 fflush(p->pLog);
628}
629
630/*
shane626a6e42009-10-22 17:30:15 +0000631** Output the given string as a hex-encoded blob (eg. X'1234' )
632*/
633static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
634 int i;
635 char *zBlob = (char *)pBlob;
636 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000637 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000638 fprintf(out,"'");
639}
640
641/*
drh28bd4bc2000-06-15 15:57:22 +0000642** Output the given string as a quoted string using SQL quoting conventions.
643*/
644static void output_quoted_string(FILE *out, const char *z){
645 int i;
646 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000647 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000648 for(i=0; z[i]; i++){
649 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000650 }
651 if( nSingle==0 ){
652 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000653 }else{
654 fprintf(out,"'");
655 while( *z ){
656 for(i=0; z[i] && z[i]!='\''; i++){}
657 if( i==0 ){
658 fprintf(out,"''");
659 z++;
660 }else if( z[i]=='\'' ){
661 fprintf(out,"%.*s''",i,z);
662 z += i+1;
663 }else{
drhcd7d2732002-02-26 23:24:26 +0000664 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000665 break;
666 }
667 }
drhcd7d2732002-02-26 23:24:26 +0000668 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000669 }
drh047d4532015-01-18 20:30:23 +0000670 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000671}
672
673/*
drhfeac5f82004-08-01 00:10:45 +0000674** Output the given string as a quoted according to C or TCL quoting rules.
675*/
676static void output_c_string(FILE *out, const char *z){
677 unsigned int c;
678 fputc('"', out);
679 while( (c = *(z++))!=0 ){
680 if( c=='\\' ){
681 fputc(c, out);
682 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000683 }else if( c=='"' ){
684 fputc('\\', out);
685 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000686 }else if( c=='\t' ){
687 fputc('\\', out);
688 fputc('t', out);
689 }else if( c=='\n' ){
690 fputc('\\', out);
691 fputc('n', out);
692 }else if( c=='\r' ){
693 fputc('\\', out);
694 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000695 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000696 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000697 }else{
698 fputc(c, out);
699 }
700 }
701 fputc('"', out);
702}
703
704/*
drhc08a4f12000-06-15 16:49:48 +0000705** Output the given string with characters that are special to
706** HTML escaped.
707*/
708static void output_html_string(FILE *out, const char *z){
709 int i;
drhc3d6ba42014-01-13 20:38:35 +0000710 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000711 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000712 for(i=0; z[i]
713 && z[i]!='<'
714 && z[i]!='&'
715 && z[i]!='>'
716 && z[i]!='\"'
717 && z[i]!='\'';
718 i++){}
drhc08a4f12000-06-15 16:49:48 +0000719 if( i>0 ){
720 fprintf(out,"%.*s",i,z);
721 }
722 if( z[i]=='<' ){
723 fprintf(out,"&lt;");
724 }else if( z[i]=='&' ){
725 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000726 }else if( z[i]=='>' ){
727 fprintf(out,"&gt;");
728 }else if( z[i]=='\"' ){
729 fprintf(out,"&quot;");
730 }else if( z[i]=='\'' ){
731 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000732 }else{
733 break;
734 }
735 z += i + 1;
736 }
737}
738
739/*
drhc49f44e2006-10-26 18:15:42 +0000740** If a field contains any character identified by a 1 in the following
741** array, then the string must be quoted for CSV.
742*/
743static const char needCsvQuote[] = {
744 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
745 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
746 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
751 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
760};
761
762/*
mistachkindd11f2d2014-12-11 04:49:46 +0000763** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000764** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000765** the null value. Strings are quoted if necessary. The separator
766** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000767*/
drhdcd87a92014-08-18 13:45:42 +0000768static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000769 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000770 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000771 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000772 }else{
drhc49f44e2006-10-26 18:15:42 +0000773 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000774 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000775 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000776 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000777 || (z[i]==p->colSeparator[0] &&
778 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000779 i = 0;
780 break;
781 }
782 }
783 if( i==0 ){
784 putc('"', out);
785 for(i=0; z[i]; i++){
786 if( z[i]=='"' ) putc('"', out);
787 putc(z[i], out);
788 }
789 putc('"', out);
790 }else{
791 fprintf(out, "%s", z);
792 }
drh8e64d1c2004-10-07 00:32:39 +0000793 }
794 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000795 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000796 }
797}
798
danielk19774af00c62005-01-23 23:43:21 +0000799#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000800/*
drh4c504392000-10-16 22:06:40 +0000801** This routine runs when the user presses Ctrl-C
802*/
803static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000804 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000805 seenInterrupt++;
806 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000807 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000808}
danielk19774af00c62005-01-23 23:43:21 +0000809#endif
drh4c504392000-10-16 22:06:40 +0000810
811/*
shane626a6e42009-10-22 17:30:15 +0000812** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000813** invokes for each row of a query result.
814*/
drh4ace5362014-11-10 14:42:28 +0000815static int shell_callback(
816 void *pArg,
817 int nArg, /* Number of result columns */
818 char **azArg, /* Text of each result column */
819 char **azCol, /* Column names */
820 int *aiType /* Column types */
821){
drh75897232000-05-29 14:26:00 +0000822 int i;
drhdcd87a92014-08-18 13:45:42 +0000823 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000824
drh75897232000-05-29 14:26:00 +0000825 switch( p->mode ){
826 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000827 int w = 5;
drh6a535342001-10-19 16:44:56 +0000828 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000829 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000830 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000831 if( len>w ) w = len;
832 }
mistachkin636bf9f2014-07-19 20:15:16 +0000833 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000834 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000835 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000836 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000837 }
838 break;
839 }
danielk19770d78bae2008-01-03 07:09:48 +0000840 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000841 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000842 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000843 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000844 int w, n;
845 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000846 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000847 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000848 w = 0;
drh75897232000-05-29 14:26:00 +0000849 }
drh078b1fd2012-09-21 13:40:02 +0000850 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000851 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000852 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000853 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000854 if( w<n ) w = n;
855 }
856 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000857 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000858 }
859 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000860 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000861 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
862 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000863 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000864 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
865 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000866 }
drha0c66f52000-07-29 13:20:21 +0000867 }
868 }
869 if( p->showHeader ){
870 for(i=0; i<nArg; i++){
871 int w;
872 if( i<ArraySize(p->actualWidth) ){
873 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000874 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000875 }else{
876 w = 10;
877 }
878 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
879 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000880 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000881 }
drh75897232000-05-29 14:26:00 +0000882 }
883 }
drh6a535342001-10-19 16:44:56 +0000884 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000885 for(i=0; i<nArg; i++){
886 int w;
drha0c66f52000-07-29 13:20:21 +0000887 if( i<ArraySize(p->actualWidth) ){
888 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000889 }else{
890 w = 10;
891 }
dana98bf362013-11-13 18:35:01 +0000892 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000893 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000894 }
dana98bf362013-11-13 18:35:01 +0000895 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000896 if( p->iIndent<p->nIndent ){
897 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000898 }
danc4650bb2013-11-18 08:41:06 +0000899 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000900 }
drh078b1fd2012-09-21 13:40:02 +0000901 if( w<0 ){
902 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000903 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000904 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000905 }else{
906 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000907 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000908 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000909 }
drh75897232000-05-29 14:26:00 +0000910 }
911 break;
912 }
drhe3710332000-09-29 13:30:53 +0000913 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000914 case MODE_List: {
915 if( p->cnt++==0 && p->showHeader ){
916 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000917 fprintf(p->out,"%s%s",azCol[i],
918 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000919 }
920 }
drh6a535342001-10-19 16:44:56 +0000921 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000922 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000923 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000924 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000925 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000926 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000927 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000928 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000929 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000930 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000931 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000932 }
drh75897232000-05-29 14:26:00 +0000933 }
934 break;
935 }
drh1e5d0e92000-05-31 23:33:17 +0000936 case MODE_Html: {
937 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000938 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000939 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000940 fprintf(p->out,"<TH>");
941 output_html_string(p->out, azCol[i]);
942 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000943 }
mihailim57c591a2008-06-23 21:26:05 +0000944 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000945 }
drh6a535342001-10-19 16:44:56 +0000946 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000947 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000948 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000949 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000950 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000951 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000952 }
mihailim57c591a2008-06-23 21:26:05 +0000953 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000954 break;
955 }
drhfeac5f82004-08-01 00:10:45 +0000956 case MODE_Tcl: {
957 if( p->cnt++==0 && p->showHeader ){
958 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000959 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000960 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000961 }
mistachkin636bf9f2014-07-19 20:15:16 +0000962 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000963 }
964 if( azArg==0 ) break;
965 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000966 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000967 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000968 }
mistachkin636bf9f2014-07-19 20:15:16 +0000969 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000970 break;
971 }
drh8e64d1c2004-10-07 00:32:39 +0000972 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000973 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000974 if( p->cnt++==0 && p->showHeader ){
975 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000976 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000977 }
mistachkine0d68852014-12-11 03:12:33 +0000978 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000979 }
drh40253262014-10-17 21:35:05 +0000980 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000981 for(i=0; i<nArg; i++){
982 output_csv(p, azArg[i], i<nArg-1);
983 }
mistachkine0d68852014-12-11 03:12:33 +0000984 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000985 }
drh047d4532015-01-18 20:30:23 +0000986 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000987 break;
988 }
drh28bd4bc2000-06-15 15:57:22 +0000989 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000990 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000991 if( azArg==0 ) break;
mistachkin151c75a2015-04-07 21:16:40 +0000992 fprintf(p->out,"INSERT INTO %s",p->zDestTable);
993 if( p->showHeader ){
994 fprintf(p->out,"(");
995 for(i=0; i<nArg; i++){
996 char *zSep = i>0 ? ",": "";
997 fprintf(p->out, "%s%s", zSep, azCol[i]);
998 }
999 fprintf(p->out,")");
1000 }
1001 fprintf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001002 for(i=0; i<nArg; i++){
1003 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001004 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +00001005 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001006 }else if( aiType && aiType[i]==SQLITE_TEXT ){
1007 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1008 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001009 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1010 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +00001011 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001012 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1013 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1014 int nBlob = sqlite3_column_bytes(p->pStmt, i);
1015 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1016 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001017 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001018 fprintf(p->out,"%s%s",zSep, azArg[i]);
1019 }else{
1020 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1021 output_quoted_string(p->out, azArg[i]);
1022 }
1023 }
1024 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001025 break;
drh28bd4bc2000-06-15 15:57:22 +00001026 }
mistachkin636bf9f2014-07-19 20:15:16 +00001027 case MODE_Ascii: {
1028 if( p->cnt++==0 && p->showHeader ){
1029 for(i=0; i<nArg; i++){
1030 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
1031 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
1032 }
1033 fprintf(p->out, "%s", p->rowSeparator);
1034 }
1035 if( azArg==0 ) break;
1036 for(i=0; i<nArg; i++){
1037 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +00001038 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001039 }
1040 fprintf(p->out, "%s", p->rowSeparator);
1041 break;
1042 }
persicom1d0b8722002-04-18 02:53:04 +00001043 }
drh75897232000-05-29 14:26:00 +00001044 return 0;
1045}
1046
1047/*
shane626a6e42009-10-22 17:30:15 +00001048** This is the callback routine that the SQLite library
1049** invokes for each row of a query result.
1050*/
1051static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1052 /* since we don't have type info, call the shell_callback with a NULL value */
1053 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1054}
1055
1056/*
drhdcd87a92014-08-18 13:45:42 +00001057** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001058** the name of the table given. Escape any quote characters in the
1059** table name.
1060*/
drhdcd87a92014-08-18 13:45:42 +00001061static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001062 int i, n;
1063 int needQuote;
1064 char *z;
1065
1066 if( p->zDestTable ){
1067 free(p->zDestTable);
1068 p->zDestTable = 0;
1069 }
1070 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001071 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001072 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001073 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001074 needQuote = 1;
1075 if( zName[i]=='\'' ) n++;
1076 }
1077 }
1078 if( needQuote ) n += 2;
1079 z = p->zDestTable = malloc( n+1 );
1080 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001081 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001082 exit(1);
1083 }
1084 n = 0;
1085 if( needQuote ) z[n++] = '\'';
1086 for(i=0; zName[i]; i++){
1087 z[n++] = zName[i];
1088 if( zName[i]=='\'' ) z[n++] = '\'';
1089 }
1090 if( needQuote ) z[n++] = '\'';
1091 z[n] = 0;
1092}
1093
danielk19772a02e332004-06-05 08:04:36 +00001094/* zIn is either a pointer to a NULL-terminated string in memory obtained
1095** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1096** added to zIn, and the result returned in memory obtained from malloc().
1097** zIn, if it was not NULL, is freed.
1098**
1099** If the third argument, quote, is not '\0', then it is used as a
1100** quote character for zAppend.
1101*/
drhc28490c2006-10-26 14:25:58 +00001102static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001103 int len;
1104 int i;
drh4f21c4a2008-12-10 22:15:00 +00001105 int nAppend = strlen30(zAppend);
1106 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001107
1108 len = nAppend+nIn+1;
1109 if( quote ){
1110 len += 2;
1111 for(i=0; i<nAppend; i++){
1112 if( zAppend[i]==quote ) len++;
1113 }
1114 }
1115
1116 zIn = (char *)realloc(zIn, len);
1117 if( !zIn ){
1118 return 0;
1119 }
1120
1121 if( quote ){
1122 char *zCsr = &zIn[nIn];
1123 *zCsr++ = quote;
1124 for(i=0; i<nAppend; i++){
1125 *zCsr++ = zAppend[i];
1126 if( zAppend[i]==quote ) *zCsr++ = quote;
1127 }
1128 *zCsr++ = quote;
1129 *zCsr++ = '\0';
1130 assert( (zCsr-zIn)==len );
1131 }else{
1132 memcpy(&zIn[nIn], zAppend, nAppend);
1133 zIn[len-1] = '\0';
1134 }
1135
1136 return zIn;
1137}
1138
drhdd3d4592004-08-30 01:54:05 +00001139
1140/*
drhb21a8e42012-01-28 21:08:51 +00001141** Execute a query statement that will generate SQL output. Print
1142** the result columns, comma-separated, on a line and then add a
1143** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001144**
drhb21a8e42012-01-28 21:08:51 +00001145** If the number of columns is 1 and that column contains text "--"
1146** then write the semicolon on a separate line. That way, if a
1147** "--" comment occurs at the end of the statement, the comment
1148** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001149*/
drh157e29a2009-05-21 15:15:00 +00001150static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001151 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001152 const char *zSelect, /* SELECT statement to extract content */
1153 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001154){
drhdd3d4592004-08-30 01:54:05 +00001155 sqlite3_stmt *pSelect;
1156 int rc;
drhb21a8e42012-01-28 21:08:51 +00001157 int nResult;
1158 int i;
1159 const char *z;
drhc7181902014-02-27 15:04:13 +00001160 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001161 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001162 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001163 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001164 return rc;
1165 }
1166 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001167 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001168 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001169 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001170 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001171 zFirstRow = 0;
1172 }
drhb21a8e42012-01-28 21:08:51 +00001173 z = (const char*)sqlite3_column_text(pSelect, 0);
1174 fprintf(p->out, "%s", z);
1175 for(i=1; i<nResult; i++){
1176 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1177 }
1178 if( z==0 ) z = "";
1179 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1180 if( z[0] ){
1181 fprintf(p->out, "\n;\n");
1182 }else{
1183 fprintf(p->out, ";\n");
1184 }
drhdd3d4592004-08-30 01:54:05 +00001185 rc = sqlite3_step(pSelect);
1186 }
drh2f464a02011-10-13 00:41:49 +00001187 rc = sqlite3_finalize(pSelect);
1188 if( rc!=SQLITE_OK ){
1189 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001190 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001191 }
1192 return rc;
drhdd3d4592004-08-30 01:54:05 +00001193}
1194
shane626a6e42009-10-22 17:30:15 +00001195/*
1196** Allocate space and save off current error string.
1197*/
1198static char *save_err_msg(
1199 sqlite3 *db /* Database to query */
1200){
1201 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1202 char *zErrMsg = sqlite3_malloc(nErrMsg);
1203 if( zErrMsg ){
1204 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1205 }
1206 return zErrMsg;
1207}
1208
1209/*
shaneh642d8b82010-07-28 16:05:34 +00001210** Display memory stats.
1211*/
1212static int display_stats(
1213 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001214 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001215 int bReset /* True to reset the stats */
1216){
1217 int iCur;
1218 int iHiwtr;
1219
1220 if( pArg && pArg->out ){
1221
1222 iHiwtr = iCur = -1;
1223 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001224 fprintf(pArg->out,
1225 "Memory Used: %d (max %d) bytes\n",
1226 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001227 iHiwtr = iCur = -1;
1228 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001229 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1230 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001231 if( pArg->shellFlgs & SHFLG_Pagecache ){
1232 iHiwtr = iCur = -1;
1233 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001234 fprintf(pArg->out,
1235 "Number of Pcache Pages Used: %d (max %d) pages\n",
1236 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001237 }
shaneh642d8b82010-07-28 16:05:34 +00001238 iHiwtr = iCur = -1;
1239 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001240 fprintf(pArg->out,
1241 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1242 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001243 if( pArg->shellFlgs & SHFLG_Scratch ){
1244 iHiwtr = iCur = -1;
1245 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001246 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1247 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001248 }
shaneh642d8b82010-07-28 16:05:34 +00001249 iHiwtr = iCur = -1;
1250 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001251 fprintf(pArg->out,
1252 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1253 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001254 iHiwtr = iCur = -1;
1255 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001256 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1257 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001258 iHiwtr = iCur = -1;
1259 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001260 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1261 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001262 iHiwtr = iCur = -1;
1263 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001264 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1265 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001266#ifdef YYTRACKMAXSTACKDEPTH
1267 iHiwtr = iCur = -1;
1268 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001269 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1270 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001271#endif
1272 }
1273
1274 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001275 if( pArg->shellFlgs & SHFLG_Lookaside ){
1276 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001277 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1278 &iCur, &iHiwtr, bReset);
1279 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1280 iCur, iHiwtr);
1281 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1282 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001283 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001284 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1285 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001286 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001287 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1288 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001289 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1290 }
shaneh642d8b82010-07-28 16:05:34 +00001291 iHiwtr = iCur = -1;
1292 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001293 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1294 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001295 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1296 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1297 iHiwtr = iCur = -1;
1298 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1299 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001300 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001301 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1302 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1303 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001304 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001305 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001306 iHiwtr = iCur = -1;
1307 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001308 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001309 }
1310
1311 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001312 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1313 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001314 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1315 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1316 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001317 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001318 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001319 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1320 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001321 }
1322
1323 return 0;
1324}
1325
1326/*
dan8d1edb92014-11-05 09:07:28 +00001327** Display scan stats.
1328*/
1329static void display_scanstats(
1330 sqlite3 *db, /* Database to query */
1331 ShellState *pArg /* Pointer to ShellState */
1332){
1333#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001334 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001335 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001336 mx = 0;
1337 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001338 double rEstLoop = 1.0;
1339 for(i=n=0; 1; i++){
1340 sqlite3_stmt *p = pArg->pStmt;
1341 sqlite3_int64 nLoop, nVisit;
1342 double rEst;
1343 int iSid;
1344 const char *zExplain;
1345 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1346 break;
1347 }
1348 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001349 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001350 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001351 if( n==0 ){
1352 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001353 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001354 }
drh42f30bc2014-11-06 12:08:21 +00001355 n++;
1356 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1357 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1358 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1359 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1360 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001361 fprintf(pArg->out,
1362 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001363 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001364 );
dan8d1edb92014-11-05 09:07:28 +00001365 }
dan8d1edb92014-11-05 09:07:28 +00001366 }
dan8d1edb92014-11-05 09:07:28 +00001367 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001368#endif
dan8d1edb92014-11-05 09:07:28 +00001369}
1370
1371/*
dana98bf362013-11-13 18:35:01 +00001372** Parameter azArray points to a zero-terminated array of strings. zStr
1373** points to a single nul-terminated string. Return non-zero if zStr
1374** is equal, according to strcmp(), to any of the strings in the array.
1375** Otherwise, return zero.
1376*/
1377static int str_in_array(const char *zStr, const char **azArray){
1378 int i;
1379 for(i=0; azArray[i]; i++){
1380 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1381 }
1382 return 0;
1383}
1384
1385/*
1386** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001387** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001388** spaces each opcode should be indented before it is output.
1389**
1390** The indenting rules are:
1391**
1392** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1393** all opcodes that occur between the p2 jump destination and the opcode
1394** itself by 2 spaces.
1395**
drh01752bc2013-11-14 23:59:33 +00001396** * For each "Goto", if the jump destination is earlier in the program
1397** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001398** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001399** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001400** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001401** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001402*/
drhdcd87a92014-08-18 13:45:42 +00001403static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001404 const char *zSql; /* The text of the SQL statement */
1405 const char *z; /* Used to check if this is an EXPLAIN */
1406 int *abYield = 0; /* True if op is an OP_Yield */
1407 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001408 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001409
drh8ad0de32014-03-20 18:45:27 +00001410 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1411 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001412 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1413 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001414 const char *azGoto[] = { "Goto", 0 };
1415
1416 /* Try to figure out if this is really an EXPLAIN statement. If this
1417 ** cannot be verified, return early. */
1418 zSql = sqlite3_sql(pSql);
1419 if( zSql==0 ) return;
1420 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1421 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1422
1423 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1424 int i;
danc4650bb2013-11-18 08:41:06 +00001425 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001426 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001427
1428 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1429 ** p2 is an instruction address, set variable p2op to the index of that
1430 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1431 ** the current instruction is part of a sub-program generated by an
1432 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001433 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001434 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001435
1436 /* Grow the p->aiIndent array as required */
1437 if( iOp>=nAlloc ){
1438 nAlloc += 100;
1439 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1440 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1441 }
1442 abYield[iOp] = str_in_array(zOp, azYield);
1443 p->aiIndent[iOp] = 0;
1444 p->nIndent = iOp+1;
1445
1446 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001447 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001448 }
drhfe705102014-03-06 13:38:37 +00001449 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1450 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1451 ){
drhe73f0592014-01-21 22:25:45 +00001452 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001453 }
1454 }
1455
danc4650bb2013-11-18 08:41:06 +00001456 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001457 sqlite3_free(abYield);
1458 sqlite3_reset(pSql);
1459}
1460
1461/*
1462** Free the array allocated by explain_data_prepare().
1463*/
drhdcd87a92014-08-18 13:45:42 +00001464static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001465 sqlite3_free(p->aiIndent);
1466 p->aiIndent = 0;
1467 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001468 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001469}
1470
1471/*
shane626a6e42009-10-22 17:30:15 +00001472** Execute a statement or set of statements. Print
1473** any result rows/columns depending on the current mode
1474** set via the supplied callback.
1475**
1476** This is very similar to SQLite's built-in sqlite3_exec()
1477** function except it takes a slightly different callback
1478** and callback data argument.
1479*/
1480static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001481 sqlite3 *db, /* An open database */
1482 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001483 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001484 /* (not the same as sqlite3_exec) */
1485 ShellState *pArg, /* Pointer to ShellState */
1486 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001487){
dan4564ced2010-01-05 04:59:56 +00001488 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1489 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001490 int rc2;
dan4564ced2010-01-05 04:59:56 +00001491 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001492
1493 if( pzErrMsg ){
1494 *pzErrMsg = NULL;
1495 }
1496
shaneb9fc17d2009-10-22 21:23:35 +00001497 while( zSql[0] && (SQLITE_OK == rc) ){
1498 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1499 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001500 if( pzErrMsg ){
1501 *pzErrMsg = save_err_msg(db);
1502 }
1503 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001504 if( !pStmt ){
1505 /* this happens for a comment or white-space */
1506 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001507 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001508 continue;
1509 }
shane626a6e42009-10-22 17:30:15 +00001510
shaneh642d8b82010-07-28 16:05:34 +00001511 /* save off the prepared statment handle and reset row count */
1512 if( pArg ){
1513 pArg->pStmt = pStmt;
1514 pArg->cnt = 0;
1515 }
1516
shanehb7977c52010-01-18 18:17:10 +00001517 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001518 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001519 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001520 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001521 }
shanehb7977c52010-01-18 18:17:10 +00001522
drhefbf3b12014-02-28 20:47:24 +00001523 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1524 if( pArg && pArg->autoEQP ){
1525 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001526 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1527 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001528 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1529 if( rc==SQLITE_OK ){
1530 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1531 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1532 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1533 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1534 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1535 }
1536 }
1537 sqlite3_finalize(pExplain);
1538 sqlite3_free(zEQP);
1539 }
1540
dana98bf362013-11-13 18:35:01 +00001541 /* If the shell is currently in ".explain" mode, gather the extra
1542 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001543 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001544 explain_data_prepare(pArg, pStmt);
1545 }
1546
shaneb9fc17d2009-10-22 21:23:35 +00001547 /* perform the first step. this will tell us if we
1548 ** have a result set or not and how wide it is.
1549 */
1550 rc = sqlite3_step(pStmt);
1551 /* if we have a result set... */
1552 if( SQLITE_ROW == rc ){
1553 /* if we have a callback... */
1554 if( xCallback ){
1555 /* allocate space for col name ptr, value ptr, and type */
1556 int nCol = sqlite3_column_count(pStmt);
1557 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1558 if( !pData ){
1559 rc = SQLITE_NOMEM;
1560 }else{
1561 char **azCols = (char **)pData; /* Names of result columns */
1562 char **azVals = &azCols[nCol]; /* Results */
1563 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001564 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001565 assert(sizeof(int) <= sizeof(char *));
1566 /* save off ptrs to column names */
1567 for(i=0; i<nCol; i++){
1568 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1569 }
shaneb9fc17d2009-10-22 21:23:35 +00001570 do{
1571 /* extract the data and data types */
1572 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001573 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001574 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001575 azVals[i] = "";
1576 }else{
1577 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1578 }
shaneb9fc17d2009-10-22 21:23:35 +00001579 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1580 rc = SQLITE_NOMEM;
1581 break; /* from for */
1582 }
1583 } /* end for */
1584
1585 /* if data and types extracted successfully... */
1586 if( SQLITE_ROW == rc ){
1587 /* call the supplied callback with the result row data */
1588 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1589 rc = SQLITE_ABORT;
1590 }else{
1591 rc = sqlite3_step(pStmt);
1592 }
1593 }
1594 } while( SQLITE_ROW == rc );
1595 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001596 }
1597 }else{
1598 do{
1599 rc = sqlite3_step(pStmt);
1600 } while( rc == SQLITE_ROW );
1601 }
1602 }
1603
dana98bf362013-11-13 18:35:01 +00001604 explain_data_delete(pArg);
1605
shaneh642d8b82010-07-28 16:05:34 +00001606 /* print usage stats if stats on */
1607 if( pArg && pArg->statsOn ){
1608 display_stats(db, pArg, 0);
1609 }
1610
dan8d1edb92014-11-05 09:07:28 +00001611 /* print loop-counters if required */
1612 if( pArg && pArg->scanstatsOn ){
1613 display_scanstats(db, pArg);
1614 }
1615
dan4564ced2010-01-05 04:59:56 +00001616 /* Finalize the statement just executed. If this fails, save a
1617 ** copy of the error message. Otherwise, set zSql to point to the
1618 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001619 rc2 = sqlite3_finalize(pStmt);
1620 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001621 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001622 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001623 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001624 }else if( pzErrMsg ){
1625 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001626 }
shaneh642d8b82010-07-28 16:05:34 +00001627
1628 /* clear saved stmt handle */
1629 if( pArg ){
1630 pArg->pStmt = NULL;
1631 }
shane626a6e42009-10-22 17:30:15 +00001632 }
shaneb9fc17d2009-10-22 21:23:35 +00001633 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001634
1635 return rc;
1636}
1637
drhdd3d4592004-08-30 01:54:05 +00001638
drh33048c02001-10-01 14:29:22 +00001639/*
drh4c653a02000-06-07 01:27:47 +00001640** This is a different callback routine used for dumping the database.
1641** Each row received by this callback consists of a table name,
1642** the table type ("index" or "table") and SQL to create the table.
1643** This routine should print text sufficient to recreate the table.
1644*/
1645static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001646 int rc;
1647 const char *zTable;
1648 const char *zType;
1649 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001650 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001651 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001652
drh902b9ee2008-12-05 17:17:07 +00001653 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001654 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001655 zTable = azArg[0];
1656 zType = azArg[1];
1657 zSql = azArg[2];
1658
drh00b950d2005-09-11 02:03:03 +00001659 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001660 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001661 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001662 fprintf(p->out, "ANALYZE sqlite_master;\n");
1663 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1664 return 0;
drh45e29d82006-11-20 16:21:10 +00001665 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1666 char *zIns;
1667 if( !p->writableSchema ){
1668 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1669 p->writableSchema = 1;
1670 }
1671 zIns = sqlite3_mprintf(
1672 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1673 "VALUES('table','%q','%q',0,'%q');",
1674 zTable, zTable, zSql);
1675 fprintf(p->out, "%s\n", zIns);
1676 sqlite3_free(zIns);
1677 return 0;
drh00b950d2005-09-11 02:03:03 +00001678 }else{
1679 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001680 }
danielk19772a02e332004-06-05 08:04:36 +00001681
1682 if( strcmp(zType, "table")==0 ){
1683 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001684 char *zSelect = 0;
1685 char *zTableInfo = 0;
1686 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001687 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001688
1689 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1690 zTableInfo = appendText(zTableInfo, zTable, '"');
1691 zTableInfo = appendText(zTableInfo, ");", 0);
1692
drhc7181902014-02-27 15:04:13 +00001693 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001694 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001695 if( rc!=SQLITE_OK || !pTableInfo ){
1696 return 1;
1697 }
1698
1699 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001700 /* Always quote the table name, even if it appears to be pure ascii,
1701 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1702 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001703 if( zTmp ){
1704 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001705 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001706 }
1707 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1708 rc = sqlite3_step(pTableInfo);
1709 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001710 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001711 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001712 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001713 rc = sqlite3_step(pTableInfo);
1714 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001715 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001716 }else{
1717 zSelect = appendText(zSelect, ") ", 0);
1718 }
drh157e29a2009-05-21 15:15:00 +00001719 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001720 }
1721 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001722 if( rc!=SQLITE_OK || nRow==0 ){
1723 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001724 return 1;
1725 }
1726 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1727 zSelect = appendText(zSelect, zTable, '"');
1728
drh2f464a02011-10-13 00:41:49 +00001729 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001730 if( rc==SQLITE_CORRUPT ){
1731 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001732 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001733 }
drh85e72432012-04-11 11:38:53 +00001734 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001735 }
drh4c653a02000-06-07 01:27:47 +00001736 return 0;
1737}
1738
1739/*
drh45e29d82006-11-20 16:21:10 +00001740** Run zQuery. Use dump_callback() as the callback routine so that
1741** the contents of the query are output as SQL statements.
1742**
drhdd3d4592004-08-30 01:54:05 +00001743** If we get a SQLITE_CORRUPT error, rerun the query after appending
1744** "ORDER BY rowid DESC" to the end.
1745*/
1746static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001747 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001748 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001749){
1750 int rc;
drh2f464a02011-10-13 00:41:49 +00001751 char *zErr = 0;
1752 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001753 if( rc==SQLITE_CORRUPT ){
1754 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001755 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001756 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1757 if( zErr ){
1758 fprintf(p->out, "/****** %s ******/\n", zErr);
1759 sqlite3_free(zErr);
1760 zErr = 0;
1761 }
drhdd3d4592004-08-30 01:54:05 +00001762 zQ2 = malloc( len+100 );
1763 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001764 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001765 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1766 if( rc ){
1767 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1768 }else{
1769 rc = SQLITE_CORRUPT;
1770 }
1771 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001772 free(zQ2);
1773 }
1774 return rc;
1775}
1776
1777/*
drh75897232000-05-29 14:26:00 +00001778** Text of a help message
1779*/
persicom1d0b8722002-04-18 02:53:04 +00001780static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001781 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001782 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001783 ".binary on|off Turn binary output on or off. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001784 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001785 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001786 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001787 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001788 " If TABLE specified, only dump tables matching\n"
1789 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001790 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001791 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001792 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001793 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001794 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001795 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001796 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001797 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001798 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001799 ".indexes ?TABLE? Show names of all indexes\n"
1800 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001801 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001802#ifdef SQLITE_ENABLE_IOTRACE
1803 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1804#endif
drh70df4fe2006-06-13 15:12:21 +00001805#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001806 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001807#endif
drh127f9d72010-02-23 01:47:00 +00001808 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001809 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001810 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001811 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001812 " column Left-aligned columns. (See .width)\n"
1813 " html HTML <table> code\n"
1814 " insert SQL insert statements for TABLE\n"
1815 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001816 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001817 " tabs Tab-separated values\n"
1818 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001819 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001820 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001821 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001822 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001823 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001824 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001825 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001826 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001827 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001828 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001829 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001830 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001831 " If TABLE specified, only show tables matching\n"
1832 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001833 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1834 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001835 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001836 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001837 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001838 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001839 ".tables ?TABLE? List names of tables\n"
1840 " If TABLE specified, only list tables matching\n"
1841 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001842 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001843 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001844 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001845 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001846 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001847 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001848;
1849
drhdaffd0e2001-04-11 14:28:42 +00001850/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001851static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001852/*
1853** Implementation of the "readfile(X)" SQL function. The entire content
1854** of the file named X is read and returned as a BLOB. NULL is returned
1855** if the file does not exist or is unreadable.
1856*/
1857static void readfileFunc(
1858 sqlite3_context *context,
1859 int argc,
1860 sqlite3_value **argv
1861){
1862 const char *zName;
1863 FILE *in;
1864 long nIn;
1865 void *pBuf;
1866
1867 zName = (const char*)sqlite3_value_text(argv[0]);
1868 if( zName==0 ) return;
1869 in = fopen(zName, "rb");
1870 if( in==0 ) return;
1871 fseek(in, 0, SEEK_END);
1872 nIn = ftell(in);
1873 rewind(in);
1874 pBuf = sqlite3_malloc( nIn );
1875 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1876 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1877 }else{
1878 sqlite3_free(pBuf);
1879 }
1880 fclose(in);
1881}
1882
1883/*
1884** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1885** is written into file X. The number of bytes written is returned. Or
1886** NULL is returned if something goes wrong, such as being unable to open
1887** file X for writing.
1888*/
1889static void writefileFunc(
1890 sqlite3_context *context,
1891 int argc,
1892 sqlite3_value **argv
1893){
1894 FILE *out;
1895 const char *z;
drhba5b0932014-07-24 12:39:59 +00001896 sqlite3_int64 rc;
1897 const char *zFile;
1898
1899 zFile = (const char*)sqlite3_value_text(argv[0]);
1900 if( zFile==0 ) return;
1901 out = fopen(zFile, "wb");
1902 if( out==0 ) return;
1903 z = (const char*)sqlite3_value_blob(argv[1]);
1904 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001905 rc = 0;
1906 }else{
drh490fe862014-08-11 14:21:32 +00001907 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001908 }
1909 fclose(out);
1910 sqlite3_result_int64(context, rc);
1911}
drhdaffd0e2001-04-11 14:28:42 +00001912
drh75897232000-05-29 14:26:00 +00001913/*
drh44c2eb12003-04-30 11:38:26 +00001914** Make sure the database is open. If it is not, then open it. If
1915** the database fails to open, print an error message and exit.
1916*/
drhdcd87a92014-08-18 13:45:42 +00001917static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001918 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001919 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001920 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001921 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001922 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1923 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1924 shellstaticFunc, 0, 0);
1925 }
1926 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001927 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001928 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001929 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001930 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001931 }
drhc2e87a32006-06-27 15:16:14 +00001932#ifndef SQLITE_OMIT_LOAD_EXTENSION
1933 sqlite3_enable_load_extension(p->db, 1);
1934#endif
drhba5b0932014-07-24 12:39:59 +00001935 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1936 readfileFunc, 0, 0);
1937 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1938 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001939 }
1940}
1941
1942/*
drhfeac5f82004-08-01 00:10:45 +00001943** Do C-language style dequoting.
1944**
mistachkinf21979d2015-01-18 05:35:01 +00001945** \a -> alarm
1946** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00001947** \t -> tab
1948** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00001949** \v -> vertical tab
1950** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00001951** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00001952** \s -> space
drh4c56b992013-06-27 13:26:55 +00001953** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00001954** \' -> '
drhfeac5f82004-08-01 00:10:45 +00001955** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00001956** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00001957*/
1958static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001959 int i, j;
1960 char c;
drhc2ce0be2014-05-29 12:36:14 +00001961 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001962 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00001963 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00001964 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00001965 if( c=='a' ){
1966 c = '\a';
1967 }else if( c=='b' ){
1968 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00001969 }else if( c=='t' ){
1970 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00001971 }else if( c=='n' ){
1972 c = '\n';
1973 }else if( c=='v' ){
1974 c = '\v';
1975 }else if( c=='f' ){
1976 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00001977 }else if( c=='r' ){
1978 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00001979 }else if( c=='"' ){
1980 c = '"';
1981 }else if( c=='\'' ){
1982 c = '\'';
drh4c56b992013-06-27 13:26:55 +00001983 }else if( c=='\\' ){
1984 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001985 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001986 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001987 if( z[i+1]>='0' && z[i+1]<='7' ){
1988 i++;
1989 c = (c<<3) + z[i] - '0';
1990 if( z[i+1]>='0' && z[i+1]<='7' ){
1991 i++;
1992 c = (c<<3) + z[i] - '0';
1993 }
1994 }
1995 }
1996 }
1997 z[j] = c;
1998 }
drhc2ce0be2014-05-29 12:36:14 +00001999 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002000}
2001
2002/*
drh348d19c2013-06-03 12:47:43 +00002003** Return the value of a hexadecimal digit. Return -1 if the input
2004** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002005*/
drh348d19c2013-06-03 12:47:43 +00002006static int hexDigitValue(char c){
2007 if( c>='0' && c<='9' ) return c - '0';
2008 if( c>='a' && c<='f' ) return c - 'a' + 10;
2009 if( c>='A' && c<='F' ) return c - 'A' + 10;
2010 return -1;
drhc28490c2006-10-26 14:25:58 +00002011}
2012
2013/*
drh7d9f3942013-04-03 01:26:54 +00002014** Interpret zArg as an integer value, possibly with suffixes.
2015*/
2016static sqlite3_int64 integerValue(const char *zArg){
2017 sqlite3_int64 v = 0;
2018 static const struct { char *zSuffix; int iMult; } aMult[] = {
2019 { "KiB", 1024 },
2020 { "MiB", 1024*1024 },
2021 { "GiB", 1024*1024*1024 },
2022 { "KB", 1000 },
2023 { "MB", 1000000 },
2024 { "GB", 1000000000 },
2025 { "K", 1000 },
2026 { "M", 1000000 },
2027 { "G", 1000000000 },
2028 };
2029 int i;
2030 int isNeg = 0;
2031 if( zArg[0]=='-' ){
2032 isNeg = 1;
2033 zArg++;
2034 }else if( zArg[0]=='+' ){
2035 zArg++;
2036 }
drh348d19c2013-06-03 12:47:43 +00002037 if( zArg[0]=='0' && zArg[1]=='x' ){
2038 int x;
2039 zArg += 2;
2040 while( (x = hexDigitValue(zArg[0]))>=0 ){
2041 v = (v<<4) + x;
2042 zArg++;
2043 }
2044 }else{
2045 while( IsDigit(zArg[0]) ){
2046 v = v*10 + zArg[0] - '0';
2047 zArg++;
2048 }
drh7d9f3942013-04-03 01:26:54 +00002049 }
drhc2bed0a2013-05-24 11:57:50 +00002050 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002051 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2052 v *= aMult[i].iMult;
2053 break;
2054 }
2055 }
2056 return isNeg? -v : v;
2057}
2058
2059/*
drh348d19c2013-06-03 12:47:43 +00002060** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2061** for TRUE and FALSE. Return the integer value if appropriate.
2062*/
2063static int booleanValue(char *zArg){
2064 int i;
2065 if( zArg[0]=='0' && zArg[1]=='x' ){
2066 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2067 }else{
2068 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2069 }
2070 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2071 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2072 return 1;
2073 }
2074 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2075 return 0;
2076 }
2077 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2078 zArg);
2079 return 0;
2080}
2081
2082/*
drh42f64e52012-04-04 16:56:23 +00002083** Close an output file, assuming it is not stderr or stdout
2084*/
2085static void output_file_close(FILE *f){
2086 if( f && f!=stdout && f!=stderr ) fclose(f);
2087}
2088
2089/*
2090** Try to open an output file. The names "stdout" and "stderr" are
2091** recognized and do the right thing. NULL is returned if the output
2092** filename is "off".
2093*/
2094static FILE *output_file_open(const char *zFile){
2095 FILE *f;
2096 if( strcmp(zFile,"stdout")==0 ){
2097 f = stdout;
2098 }else if( strcmp(zFile, "stderr")==0 ){
2099 f = stderr;
2100 }else if( strcmp(zFile, "off")==0 ){
2101 f = 0;
2102 }else{
2103 f = fopen(zFile, "wb");
2104 if( f==0 ){
2105 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2106 }
2107 }
2108 return f;
2109}
2110
2111/*
2112** A routine for handling output from sqlite3_trace().
2113*/
2114static void sql_trace_callback(void *pArg, const char *z){
2115 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002116 if( f ){
2117 int i = (int)strlen(z);
2118 while( i>0 && z[i-1]==';' ){ i--; }
2119 fprintf(f, "%.*s;\n", i, z);
2120 }
drh42f64e52012-04-04 16:56:23 +00002121}
2122
2123/*
drhd8621b92012-04-17 09:09:33 +00002124** A no-op routine that runs with the ".breakpoint" doc-command. This is
2125** a useful spot to set a debugger breakpoint.
2126*/
2127static void test_breakpoint(void){
2128 static int nCall = 0;
2129 nCall++;
2130}
2131
2132/*
mistachkin636bf9f2014-07-19 20:15:16 +00002133** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002134*/
mistachkin636bf9f2014-07-19 20:15:16 +00002135typedef struct ImportCtx ImportCtx;
2136struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002137 const char *zFile; /* Name of the input file */
2138 FILE *in; /* Read the CSV text from this input stream */
2139 char *z; /* Accumulated text for a field */
2140 int n; /* Number of bytes in z */
2141 int nAlloc; /* Space allocated for z[] */
2142 int nLine; /* Current line number */
2143 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002144 int cColSep; /* The column separator character. (Usually ",") */
2145 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002146};
2147
2148/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002149static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002150 if( p->n+1>=p->nAlloc ){
2151 p->nAlloc += p->nAlloc + 100;
2152 p->z = sqlite3_realloc(p->z, p->nAlloc);
2153 if( p->z==0 ){
2154 fprintf(stderr, "out of memory\n");
2155 exit(1);
2156 }
2157 }
2158 p->z[p->n++] = (char)c;
2159}
2160
2161/* Read a single field of CSV text. Compatible with rfc4180 and extended
2162** with the option of having a separator other than ",".
2163**
2164** + Input comes from p->in.
2165** + Store results in p->z of length p->n. Space to hold p->z comes
2166** from sqlite3_malloc().
mistachkin636bf9f2014-07-19 20:15:16 +00002167** + Use p->cSep as the column separator. The default is ",".
2168** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002169** + Keep track of the line number in p->nLine.
2170** + Store the character that terminates the field in p->cTerm. Store
2171** EOF on end-of-file.
2172** + Report syntax errors on stderr
2173*/
mistachkin44723ce2015-03-21 02:22:37 +00002174static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002175 int c;
2176 int cSep = p->cColSep;
2177 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002178 p->n = 0;
2179 c = fgetc(p->in);
2180 if( c==EOF || seenInterrupt ){
2181 p->cTerm = EOF;
2182 return 0;
2183 }
2184 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002185 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002186 int startLine = p->nLine;
2187 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002188 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002189 while( 1 ){
2190 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002191 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002192 if( c==cQuote ){
2193 if( pc==cQuote ){
2194 pc = 0;
2195 continue;
2196 }
2197 }
2198 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002199 || (c==rSep && pc==cQuote)
2200 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002201 || (c==EOF && pc==cQuote)
2202 ){
2203 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002204 p->cTerm = c;
2205 break;
2206 }
2207 if( pc==cQuote && c!='\r' ){
2208 fprintf(stderr, "%s:%d: unescaped %c character\n",
2209 p->zFile, p->nLine, cQuote);
2210 }
2211 if( c==EOF ){
2212 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2213 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002214 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002215 break;
2216 }
mistachkin636bf9f2014-07-19 20:15:16 +00002217 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002218 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002219 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002220 }
drhdb95f682013-06-26 22:46:00 +00002221 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002222 while( c!=EOF && c!=cSep && c!=rSep ){
2223 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002224 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002225 }
mistachkin636bf9f2014-07-19 20:15:16 +00002226 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002227 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002228 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002229 }
drhdb95f682013-06-26 22:46:00 +00002230 p->cTerm = c;
2231 }
drh8dd675e2013-07-12 21:09:24 +00002232 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002233 return p->z;
2234}
2235
mistachkin636bf9f2014-07-19 20:15:16 +00002236/* Read a single field of ASCII delimited text.
2237**
2238** + Input comes from p->in.
2239** + Store results in p->z of length p->n. Space to hold p->z comes
2240** from sqlite3_malloc().
2241** + Use p->cSep as the column separator. The default is "\x1F".
2242** + Use p->rSep as the row separator. The default is "\x1E".
2243** + Keep track of the row number in p->nLine.
2244** + Store the character that terminates the field in p->cTerm. Store
2245** EOF on end-of-file.
2246** + Report syntax errors on stderr
2247*/
mistachkin44723ce2015-03-21 02:22:37 +00002248static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002249 int c;
2250 int cSep = p->cColSep;
2251 int rSep = p->cRowSep;
2252 p->n = 0;
2253 c = fgetc(p->in);
2254 if( c==EOF || seenInterrupt ){
2255 p->cTerm = EOF;
2256 return 0;
2257 }
2258 while( c!=EOF && c!=cSep && c!=rSep ){
2259 import_append_char(p, c);
2260 c = fgetc(p->in);
2261 }
2262 if( c==rSep ){
2263 p->nLine++;
2264 }
2265 p->cTerm = c;
2266 if( p->z ) p->z[p->n] = 0;
2267 return p->z;
2268}
2269
drhdb95f682013-06-26 22:46:00 +00002270/*
drh4bbcf102014-02-06 02:46:08 +00002271** Try to transfer data for table zTable. If an error is seen while
2272** moving forward, try to go backwards. The backwards movement won't
2273** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002274*/
mistachkine31ae902014-02-06 01:15:29 +00002275static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002276 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002277 sqlite3 *newDb,
2278 const char *zTable
2279){
2280 sqlite3_stmt *pQuery = 0;
2281 sqlite3_stmt *pInsert = 0;
2282 char *zQuery = 0;
2283 char *zInsert = 0;
2284 int rc;
2285 int i, j, n;
2286 int nTable = (int)strlen(zTable);
2287 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002288 int cnt = 0;
2289 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002290
2291 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2292 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2293 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002294 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002295 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2296 zQuery);
2297 goto end_data_xfer;
2298 }
2299 n = sqlite3_column_count(pQuery);
2300 zInsert = sqlite3_malloc(200 + nTable + n*3);
2301 if( zInsert==0 ){
2302 fprintf(stderr, "out of memory\n");
2303 goto end_data_xfer;
2304 }
2305 sqlite3_snprintf(200+nTable,zInsert,
2306 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2307 i = (int)strlen(zInsert);
2308 for(j=1; j<n; j++){
2309 memcpy(zInsert+i, ",?", 2);
2310 i += 2;
2311 }
2312 memcpy(zInsert+i, ");", 3);
2313 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2314 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002315 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002316 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2317 zQuery);
2318 goto end_data_xfer;
2319 }
2320 for(k=0; k<2; k++){
2321 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2322 for(i=0; i<n; i++){
2323 switch( sqlite3_column_type(pQuery, i) ){
2324 case SQLITE_NULL: {
2325 sqlite3_bind_null(pInsert, i+1);
2326 break;
2327 }
2328 case SQLITE_INTEGER: {
2329 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2330 break;
2331 }
2332 case SQLITE_FLOAT: {
2333 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2334 break;
2335 }
2336 case SQLITE_TEXT: {
2337 sqlite3_bind_text(pInsert, i+1,
2338 (const char*)sqlite3_column_text(pQuery,i),
2339 -1, SQLITE_STATIC);
2340 break;
2341 }
2342 case SQLITE_BLOB: {
2343 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2344 sqlite3_column_bytes(pQuery,i),
2345 SQLITE_STATIC);
2346 break;
2347 }
2348 }
2349 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002350 rc = sqlite3_step(pInsert);
2351 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2352 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2353 sqlite3_errmsg(newDb));
2354 }
drh3350ce92014-02-06 00:49:12 +00002355 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002356 cnt++;
2357 if( (cnt%spinRate)==0 ){
2358 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2359 fflush(stdout);
2360 }
drh3350ce92014-02-06 00:49:12 +00002361 } /* End while */
2362 if( rc==SQLITE_DONE ) break;
2363 sqlite3_finalize(pQuery);
2364 sqlite3_free(zQuery);
2365 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2366 zTable);
2367 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2368 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002369 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2370 break;
drh3350ce92014-02-06 00:49:12 +00002371 }
2372 } /* End for(k=0...) */
2373
2374end_data_xfer:
2375 sqlite3_finalize(pQuery);
2376 sqlite3_finalize(pInsert);
2377 sqlite3_free(zQuery);
2378 sqlite3_free(zInsert);
2379}
2380
2381
2382/*
2383** Try to transfer all rows of the schema that match zWhere. For
2384** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002385** If an error is encountered while moving forward through the
2386** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002387*/
mistachkine31ae902014-02-06 01:15:29 +00002388static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002389 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002390 sqlite3 *newDb,
2391 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002392 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002393){
2394 sqlite3_stmt *pQuery = 0;
2395 char *zQuery = 0;
2396 int rc;
2397 const unsigned char *zName;
2398 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002399 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002400
2401 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2402 " WHERE %s", zWhere);
2403 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2404 if( rc ){
2405 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2406 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2407 zQuery);
2408 goto end_schema_xfer;
2409 }
2410 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2411 zName = sqlite3_column_text(pQuery, 0);
2412 zSql = sqlite3_column_text(pQuery, 1);
2413 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002414 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2415 if( zErrMsg ){
2416 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2417 sqlite3_free(zErrMsg);
2418 zErrMsg = 0;
2419 }
drh3350ce92014-02-06 00:49:12 +00002420 if( xForEach ){
2421 xForEach(p, newDb, (const char*)zName);
2422 }
2423 printf("done\n");
2424 }
2425 if( rc!=SQLITE_DONE ){
2426 sqlite3_finalize(pQuery);
2427 sqlite3_free(zQuery);
2428 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2429 " WHERE %s ORDER BY rowid DESC", zWhere);
2430 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2431 if( rc ){
2432 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2433 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2434 zQuery);
2435 goto end_schema_xfer;
2436 }
2437 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2438 zName = sqlite3_column_text(pQuery, 0);
2439 zSql = sqlite3_column_text(pQuery, 1);
2440 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002441 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2442 if( zErrMsg ){
2443 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2444 sqlite3_free(zErrMsg);
2445 zErrMsg = 0;
2446 }
drh3350ce92014-02-06 00:49:12 +00002447 if( xForEach ){
2448 xForEach(p, newDb, (const char*)zName);
2449 }
2450 printf("done\n");
2451 }
2452 }
2453end_schema_xfer:
2454 sqlite3_finalize(pQuery);
2455 sqlite3_free(zQuery);
2456}
2457
2458/*
2459** Open a new database file named "zNewDb". Try to recover as much information
2460** as possible out of the main database (which might be corrupt) and write it
2461** into zNewDb.
2462*/
drhdcd87a92014-08-18 13:45:42 +00002463static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002464 int rc;
2465 sqlite3 *newDb = 0;
2466 if( access(zNewDb,0)==0 ){
2467 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2468 return;
2469 }
2470 rc = sqlite3_open(zNewDb, &newDb);
2471 if( rc ){
2472 fprintf(stderr, "Cannot create output database: %s\n",
2473 sqlite3_errmsg(newDb));
2474 }else{
drh54d0d2d2014-04-03 00:32:13 +00002475 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002476 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002477 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2478 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002479 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002480 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002481 }
2482 sqlite3_close(newDb);
2483}
2484
2485/*
drhc2ce0be2014-05-29 12:36:14 +00002486** Change the output file back to stdout
2487*/
drhdcd87a92014-08-18 13:45:42 +00002488static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002489 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002490#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002491 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002492#endif
drhc2ce0be2014-05-29 12:36:14 +00002493 }else{
2494 output_file_close(p->out);
2495 }
2496 p->outfile[0] = 0;
2497 p->out = stdout;
2498}
2499
2500/*
drhf7502f02015-02-06 14:19:44 +00002501** Run an SQL command and return the single integer result.
2502*/
2503static int db_int(ShellState *p, const char *zSql){
2504 sqlite3_stmt *pStmt;
2505 int res = 0;
2506 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2507 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2508 res = sqlite3_column_int(pStmt,0);
2509 }
2510 sqlite3_finalize(pStmt);
2511 return res;
2512}
2513
2514/*
2515** Convert a 2-byte or 4-byte big-endian integer into a native integer
2516*/
2517unsigned int get2byteInt(unsigned char *a){
2518 return (a[0]<<8) + a[1];
2519}
2520unsigned int get4byteInt(unsigned char *a){
2521 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2522}
2523
2524/*
2525** Implementation of the ".info" command.
2526**
2527** Return 1 on error, 2 to exit, and 0 otherwise.
2528*/
drh0e55db12015-02-06 14:51:13 +00002529static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002530 static const struct { const char *zName; int ofst; } aField[] = {
2531 { "file change counter:", 24 },
2532 { "database page count:", 28 },
2533 { "freelist page count:", 36 },
2534 { "schema cookie:", 40 },
2535 { "schema format:", 44 },
2536 { "default cache size:", 48 },
2537 { "autovacuum top root:", 52 },
2538 { "incremental vacuum:", 64 },
2539 { "text encoding:", 56 },
2540 { "user version:", 60 },
2541 { "application id:", 68 },
2542 { "software version:", 96 },
2543 };
drh0e55db12015-02-06 14:51:13 +00002544 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2545 { "number of tables:",
2546 "SELECT count(*) FROM %s WHERE type='table'" },
2547 { "number of indexes:",
2548 "SELECT count(*) FROM %s WHERE type='index'" },
2549 { "number of triggers:",
2550 "SELECT count(*) FROM %s WHERE type='trigger'" },
2551 { "number of views:",
2552 "SELECT count(*) FROM %s WHERE type='view'" },
2553 { "schema size:",
2554 "SELECT total(length(sql)) FROM %s" },
2555 };
2556 sqlite3_file *pFile;
2557 int i;
2558 char *zSchemaTab;
2559 char *zDb = nArg>=2 ? azArg[1] : "main";
2560 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002561 open_db(p, 0);
2562 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002563 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002564 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2565 return 1;
2566 }
2567 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2568 if( i!=SQLITE_OK ){
2569 fprintf(stderr, "unable to read database header\n");
2570 return 1;
2571 }
2572 i = get2byteInt(aHdr+16);
2573 if( i==1 ) i = 65536;
2574 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2575 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2576 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2577 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2578 for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
2579 int ofst = aField[i].ofst;
2580 unsigned int val = get4byteInt(aHdr + ofst);
2581 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2582 switch( ofst ){
2583 case 56: {
2584 if( val==1 ) fprintf(p->out, " (utf8)");
2585 if( val==2 ) fprintf(p->out, " (utf16le)");
2586 if( val==3 ) fprintf(p->out, " (utf16be)");
2587 }
2588 }
2589 fprintf(p->out, "\n");
2590 }
drh0e55db12015-02-06 14:51:13 +00002591 if( zDb==0 ){
2592 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2593 }else if( strcmp(zDb,"temp")==0 ){
2594 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2595 }else{
2596 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2597 }
2598 for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
2599 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2600 int val = db_int(p, zSql);
2601 sqlite3_free(zSql);
2602 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2603 }
2604 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002605 return 0;
2606}
2607
2608
2609/*
drh75897232000-05-29 14:26:00 +00002610** If an input line begins with "." then invoke this routine to
2611** process that line.
drh67505e72002-04-19 12:34:06 +00002612**
drh47ad6842006-11-08 12:25:42 +00002613** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002614*/
drhdcd87a92014-08-18 13:45:42 +00002615static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002616 int i = 1;
2617 int nArg = 0;
2618 int n, c;
drh67505e72002-04-19 12:34:06 +00002619 int rc = 0;
drh75897232000-05-29 14:26:00 +00002620 char *azArg[50];
2621
2622 /* Parse the input line into tokens.
2623 */
2624 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002625 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002626 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002627 if( zLine[i]=='\'' || zLine[i]=='"' ){
2628 int delim = zLine[i++];
2629 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002630 while( zLine[i] && zLine[i]!=delim ){
2631 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2632 i++;
2633 }
drh75897232000-05-29 14:26:00 +00002634 if( zLine[i]==delim ){
2635 zLine[i++] = 0;
2636 }
drhfeac5f82004-08-01 00:10:45 +00002637 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002638 }else{
2639 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002640 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002641 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002642 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002643 }
2644 }
2645
2646 /* Process the input line.
2647 */
shane9bd1b442009-10-23 01:27:39 +00002648 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002649 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002650 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002651 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2652 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2653 ){
drhbc46f022013-01-23 18:53:23 +00002654 const char *zDestFile = 0;
2655 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002656 sqlite3 *pDest;
2657 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002658 int j;
2659 for(j=1; j<nArg; j++){
2660 const char *z = azArg[j];
2661 if( z[0]=='-' ){
2662 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002663 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002664 {
2665 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2666 return 1;
2667 }
2668 }else if( zDestFile==0 ){
2669 zDestFile = azArg[j];
2670 }else if( zDb==0 ){
2671 zDb = zDestFile;
2672 zDestFile = azArg[j];
2673 }else{
2674 fprintf(stderr, "too many arguments to .backup\n");
2675 return 1;
2676 }
drh9ff849f2009-02-04 20:55:57 +00002677 }
drhbc46f022013-01-23 18:53:23 +00002678 if( zDestFile==0 ){
2679 fprintf(stderr, "missing FILENAME argument on .backup\n");
2680 return 1;
2681 }
2682 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002683 rc = sqlite3_open(zDestFile, &pDest);
2684 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002685 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002686 sqlite3_close(pDest);
2687 return 1;
2688 }
drh05782482013-10-24 15:20:20 +00002689 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002690 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2691 if( pBackup==0 ){
2692 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2693 sqlite3_close(pDest);
2694 return 1;
2695 }
2696 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2697 sqlite3_backup_finish(pBackup);
2698 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002699 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002700 }else{
2701 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002702 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002703 }
2704 sqlite3_close(pDest);
2705 }else
2706
drhc2ce0be2014-05-29 12:36:14 +00002707 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2708 if( nArg==2 ){
2709 bail_on_error = booleanValue(azArg[1]);
2710 }else{
2711 fprintf(stderr, "Usage: .bail on|off\n");
2712 rc = 1;
2713 }
drhc49f44e2006-10-26 18:15:42 +00002714 }else
2715
mistachkinf21979d2015-01-18 05:35:01 +00002716 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2717 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002718 if( booleanValue(azArg[1]) ){
2719 setBinaryMode(p->out);
2720 }else{
2721 setTextMode(p->out);
2722 }
mistachkinf21979d2015-01-18 05:35:01 +00002723 }else{
2724 fprintf(stderr, "Usage: .binary on|off\n");
2725 rc = 1;
2726 }
2727 }else
2728
drhd8621b92012-04-17 09:09:33 +00002729 /* The undocumented ".breakpoint" command causes a call to the no-op
2730 ** routine named test_breakpoint().
2731 */
2732 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2733 test_breakpoint();
2734 }else
2735
drhc2ce0be2014-05-29 12:36:14 +00002736 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2737 if( nArg==2 ){
2738 tryToClone(p, azArg[1]);
2739 }else{
2740 fprintf(stderr, "Usage: .clone FILENAME\n");
2741 rc = 1;
2742 }
mistachkine31ae902014-02-06 01:15:29 +00002743 }else
2744
drhc2ce0be2014-05-29 12:36:14 +00002745 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002746 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002747 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002748 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002749 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002750 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002751 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002752 data.colWidth[0] = 3;
2753 data.colWidth[1] = 15;
2754 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002755 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002756 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002757 if( zErrMsg ){
2758 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002759 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002760 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002761 }
2762 }else
2763
drh0e55db12015-02-06 14:51:13 +00002764 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2765 rc = shell_dbinfo_command(p, nArg, azArg);
2766 }else
2767
drhc2ce0be2014-05-29 12:36:14 +00002768 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002769 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002770 /* When playing back a "dump", the content might appear in an order
2771 ** which causes immediate foreign key constraints to be violated.
2772 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002773 if( nArg!=1 && nArg!=2 ){
2774 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2775 rc = 1;
2776 goto meta_command_exit;
2777 }
drhf1dfc4f2009-09-23 15:51:35 +00002778 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002779 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002780 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002781 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002782 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002783 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002784 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002785 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002786 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002787 );
2788 run_schema_dump_query(p,
2789 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002790 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002791 );
drh2f464a02011-10-13 00:41:49 +00002792 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002793 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002794 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002795 );
drh4c653a02000-06-07 01:27:47 +00002796 }else{
2797 int i;
drhdd3d4592004-08-30 01:54:05 +00002798 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002799 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002800 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002801 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002802 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002803 " AND sql NOT NULL");
2804 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002805 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002806 "WHERE sql NOT NULL"
2807 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002808 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002809 );
danielk1977bc6ada42004-06-30 08:20:16 +00002810 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002811 }
2812 }
drh45e29d82006-11-20 16:21:10 +00002813 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002814 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002815 p->writableSchema = 0;
2816 }
drh56197952011-10-13 16:30:13 +00002817 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2818 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002819 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002820 }else
drh75897232000-05-29 14:26:00 +00002821
drhc2ce0be2014-05-29 12:36:14 +00002822 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2823 if( nArg==2 ){
2824 p->echoOn = booleanValue(azArg[1]);
2825 }else{
2826 fprintf(stderr, "Usage: .echo on|off\n");
2827 rc = 1;
2828 }
drhdaffd0e2001-04-11 14:28:42 +00002829 }else
2830
drhc2ce0be2014-05-29 12:36:14 +00002831 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2832 if( nArg==2 ){
2833 p->autoEQP = booleanValue(azArg[1]);
2834 }else{
2835 fprintf(stderr, "Usage: .eqp on|off\n");
2836 rc = 1;
2837 }
drhefbf3b12014-02-28 20:47:24 +00002838 }else
2839
drhd3ac7d92013-01-25 18:33:43 +00002840 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002841 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002842 rc = 2;
drh75897232000-05-29 14:26:00 +00002843 }else
2844
drhc2ce0be2014-05-29 12:36:14 +00002845 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002846 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002847 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002848 if(!p->normalMode.valid) {
2849 p->normalMode.valid = 1;
2850 p->normalMode.mode = p->mode;
2851 p->normalMode.showHeader = p->showHeader;
2852 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002853 }
2854 /* We could put this code under the !p->explainValid
2855 ** condition so that it does not execute if we are already in
2856 ** explain mode. However, always executing it allows us an easy
2857 ** was to reset to explain mode in case the user previously
2858 ** did an .explain followed by a .width, .mode or .header
2859 ** command.
2860 */
danielk19770d78bae2008-01-03 07:09:48 +00002861 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002862 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002863 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002864 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002865 p->colWidth[1] = 13; /* opcode */
2866 p->colWidth[2] = 4; /* P1 */
2867 p->colWidth[3] = 4; /* P2 */
2868 p->colWidth[4] = 4; /* P3 */
2869 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002870 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002871 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002872 }else if (p->normalMode.valid) {
2873 p->normalMode.valid = 0;
2874 p->mode = p->normalMode.mode;
2875 p->showHeader = p->normalMode.showHeader;
2876 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002877 }
drh75897232000-05-29 14:26:00 +00002878 }else
2879
drhc1971542014-06-23 23:28:13 +00002880 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002881 ShellState data;
drhc1971542014-06-23 23:28:13 +00002882 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002883 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002884 if( nArg!=1 ){
2885 fprintf(stderr, "Usage: .fullschema\n");
2886 rc = 1;
2887 goto meta_command_exit;
2888 }
2889 open_db(p, 0);
2890 memcpy(&data, p, sizeof(data));
2891 data.showHeader = 0;
2892 data.mode = MODE_Semi;
2893 rc = sqlite3_exec(p->db,
2894 "SELECT sql FROM"
2895 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2896 " FROM sqlite_master UNION ALL"
2897 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002898 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002899 "ORDER BY rowid",
2900 callback, &data, &zErrMsg
2901 );
drh56f674c2014-07-18 14:43:29 +00002902 if( rc==SQLITE_OK ){
2903 sqlite3_stmt *pStmt;
2904 rc = sqlite3_prepare_v2(p->db,
2905 "SELECT rowid FROM sqlite_master"
2906 " WHERE name GLOB 'sqlite_stat[134]'",
2907 -1, &pStmt, 0);
2908 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2909 sqlite3_finalize(pStmt);
2910 }
2911 if( doStats==0 ){
2912 fprintf(p->out, "/* No STAT tables available */\n");
2913 }else{
2914 fprintf(p->out, "ANALYZE sqlite_master;\n");
2915 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2916 callback, &data, &zErrMsg);
2917 data.mode = MODE_Insert;
2918 data.zDestTable = "sqlite_stat1";
2919 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2920 shell_callback, &data,&zErrMsg);
2921 data.zDestTable = "sqlite_stat3";
2922 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2923 shell_callback, &data,&zErrMsg);
2924 data.zDestTable = "sqlite_stat4";
2925 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2926 shell_callback, &data, &zErrMsg);
2927 fprintf(p->out, "ANALYZE sqlite_master;\n");
2928 }
drhc1971542014-06-23 23:28:13 +00002929 }else
2930
drhc2ce0be2014-05-29 12:36:14 +00002931 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2932 if( nArg==2 ){
2933 p->showHeader = booleanValue(azArg[1]);
2934 }else{
2935 fprintf(stderr, "Usage: .headers on|off\n");
2936 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002937 }
drh75897232000-05-29 14:26:00 +00002938 }else
2939
drhc2ce0be2014-05-29 12:36:14 +00002940 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2941 fprintf(p->out, "%s", zHelp);
2942 }else
2943
2944 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002945 char *zTable; /* Insert data into this table */
2946 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002947 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002948 int nCol; /* Number of columns in the table */
2949 int nByte; /* Number of bytes in an SQL string */
2950 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002951 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002952 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002953 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002954 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00002955 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
2956 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00002957
drhc2ce0be2014-05-29 12:36:14 +00002958 if( nArg!=3 ){
2959 fprintf(stderr, "Usage: .import FILE TABLE\n");
2960 goto meta_command_exit;
2961 }
drh01f37542014-05-31 15:43:33 +00002962 zFile = azArg[1];
2963 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002964 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002965 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002966 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002967 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002968 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002969 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002970 return 1;
drhfeac5f82004-08-01 00:10:45 +00002971 }
drhdb95f682013-06-26 22:46:00 +00002972 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002973 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002974 " for import\n");
2975 return 1;
2976 }
mistachkin636bf9f2014-07-19 20:15:16 +00002977 nSep = strlen30(p->rowSeparator);
2978 if( nSep==0 ){
2979 fprintf(stderr, "Error: non-null row separator required for import\n");
2980 return 1;
2981 }
mistachkine0d68852014-12-11 03:12:33 +00002982 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2983 /* When importing CSV (only), if the row separator is set to the
2984 ** default output row separator, change it to the default input
2985 ** row separator. This avoids having to maintain different input
2986 ** and output row separators. */
2987 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2988 nSep = strlen30(p->rowSeparator);
2989 }
mistachkin636bf9f2014-07-19 20:15:16 +00002990 if( nSep>1 ){
2991 fprintf(stderr, "Error: multi-character row separators not allowed"
2992 " for import\n");
2993 return 1;
2994 }
2995 sCtx.zFile = zFile;
2996 sCtx.nLine = 1;
2997 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002998#ifdef SQLITE_OMIT_POPEN
mistachkinba132c72015-03-19 14:48:38 +00002999 fprintf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003000 return 1;
3001#else
mistachkin636bf9f2014-07-19 20:15:16 +00003002 sCtx.in = popen(sCtx.zFile+1, "r");
3003 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003004 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003005#endif
drh5bde8162013-06-27 14:07:53 +00003006 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003007 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003008 xCloser = fclose;
3009 }
mistachkin636bf9f2014-07-19 20:15:16 +00003010 if( p->mode==MODE_Ascii ){
3011 xRead = ascii_read_one_field;
3012 }else{
3013 xRead = csv_read_one_field;
3014 }
3015 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00003016 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003017 return 1;
3018 }
mistachkin636bf9f2014-07-19 20:15:16 +00003019 sCtx.cColSep = p->colSeparator[0];
3020 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003021 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003022 if( zSql==0 ){
3023 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003024 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003025 return 1;
3026 }
drh4f21c4a2008-12-10 22:15:00 +00003027 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003028 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003029 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
drhdb95f682013-06-26 22:46:00 +00003030 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
3031 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3032 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003033 while( xRead(&sCtx) ){
3034 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003035 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003036 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003037 }
drh5bde8162013-06-27 14:07:53 +00003038 if( cSep=='(' ){
3039 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003040 sqlite3_free(sCtx.z);
3041 xCloser(sCtx.in);
3042 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003043 return 1;
3044 }
drhdb95f682013-06-26 22:46:00 +00003045 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3046 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3047 sqlite3_free(zCreate);
3048 if( rc ){
3049 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
3050 sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00003051 sqlite3_free(sCtx.z);
3052 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003053 return 1;
3054 }
drhc7181902014-02-27 15:04:13 +00003055 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003056 }
drhfeac5f82004-08-01 00:10:45 +00003057 sqlite3_free(zSql);
3058 if( rc ){
shane916f9612009-10-23 00:37:15 +00003059 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003060 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00003061 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003062 return 1;
drhfeac5f82004-08-01 00:10:45 +00003063 }
shane916f9612009-10-23 00:37:15 +00003064 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003065 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003066 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003067 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00003068 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003069 if( zSql==0 ){
3070 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003071 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003072 return 1;
3073 }
drhdb95f682013-06-26 22:46:00 +00003074 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003075 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003076 for(i=1; i<nCol; i++){
3077 zSql[j++] = ',';
3078 zSql[j++] = '?';
3079 }
3080 zSql[j++] = ')';
3081 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003082 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003083 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003084 if( rc ){
3085 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00003086 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003087 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003088 return 1;
drhfeac5f82004-08-01 00:10:45 +00003089 }
drh2d463112013-08-06 14:36:36 +00003090 needCommit = sqlite3_get_autocommit(db);
3091 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003092 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003093 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003094 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003095 char *z = xRead(&sCtx);
3096 /*
3097 ** Did we reach end-of-file before finding any columns?
3098 ** If so, stop instead of NULL filling the remaining columns.
3099 */
drhdb95f682013-06-26 22:46:00 +00003100 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003101 /*
3102 ** Did we reach end-of-file OR end-of-line before finding any
3103 ** columns in ASCII mode? If so, stop instead of NULL filling
3104 ** the remaining columns.
3105 */
3106 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003107 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003108 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003109 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3110 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003111 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003112 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003113 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003114 }
drhfeac5f82004-08-01 00:10:45 +00003115 }
mistachkin636bf9f2014-07-19 20:15:16 +00003116 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003117 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003118 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003119 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003120 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003121 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3122 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003123 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003124 }
drhdb95f682013-06-26 22:46:00 +00003125 if( i>=nCol ){
3126 sqlite3_step(pStmt);
3127 rc = sqlite3_reset(pStmt);
3128 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003129 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
drhdb95f682013-06-26 22:46:00 +00003130 sqlite3_errmsg(db));
3131 }
3132 }
mistachkin636bf9f2014-07-19 20:15:16 +00003133 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003134
mistachkin636bf9f2014-07-19 20:15:16 +00003135 xCloser(sCtx.in);
3136 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003137 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00003138 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003139 }else
3140
drh0e55db12015-02-06 14:51:13 +00003141 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3142 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003143 ShellState data;
drh75897232000-05-29 14:26:00 +00003144 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003145 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003146 memcpy(&data, p, sizeof(data));
3147 data.showHeader = 0;
3148 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003149 if( nArg==1 ){
3150 rc = sqlite3_exec(p->db,
3151 "SELECT name FROM sqlite_master "
3152 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3153 "UNION ALL "
3154 "SELECT name FROM sqlite_temp_master "
3155 "WHERE type='index' "
3156 "ORDER BY 1",
3157 callback, &data, &zErrMsg
3158 );
drhc2ce0be2014-05-29 12:36:14 +00003159 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003160 zShellStatic = azArg[1];
3161 rc = sqlite3_exec(p->db,
3162 "SELECT name FROM sqlite_master "
3163 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3164 "UNION ALL "
3165 "SELECT name FROM sqlite_temp_master "
3166 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3167 "ORDER BY 1",
3168 callback, &data, &zErrMsg
3169 );
3170 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003171 }else{
drh0e55db12015-02-06 14:51:13 +00003172 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003173 rc = 1;
3174 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003175 }
drh75897232000-05-29 14:26:00 +00003176 if( zErrMsg ){
3177 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003178 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003179 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003180 }else if( rc != SQLITE_OK ){
3181 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3182 rc = 1;
drh75897232000-05-29 14:26:00 +00003183 }
3184 }else
3185
drhae5e4452007-05-03 17:18:36 +00003186#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003187 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003188 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003189 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3190 iotrace = 0;
3191 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003192 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003193 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003194 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003195 iotrace = stdout;
3196 }else{
3197 iotrace = fopen(azArg[1], "w");
3198 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003199 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003200 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003201 rc = 1;
drhb0603412007-02-28 04:47:26 +00003202 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003203 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003204 }
3205 }
3206 }else
drhae5e4452007-05-03 17:18:36 +00003207#endif
drhb0603412007-02-28 04:47:26 +00003208
drh70df4fe2006-06-13 15:12:21 +00003209#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003210 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003211 const char *zFile, *zProc;
3212 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003213 if( nArg<2 ){
3214 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3215 rc = 1;
3216 goto meta_command_exit;
3217 }
drh1e397f82006-06-08 15:28:43 +00003218 zFile = azArg[1];
3219 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003220 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003221 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3222 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003223 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003224 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003225 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003226 }
3227 }else
drh70df4fe2006-06-13 15:12:21 +00003228#endif
drh1e397f82006-06-08 15:28:43 +00003229
drhc2ce0be2014-05-29 12:36:14 +00003230 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3231 if( nArg!=2 ){
3232 fprintf(stderr, "Usage: .log FILENAME\n");
3233 rc = 1;
3234 }else{
3235 const char *zFile = azArg[1];
3236 output_file_close(p->pLog);
3237 p->pLog = output_file_open(zFile);
3238 }
drh127f9d72010-02-23 01:47:00 +00003239 }else
3240
drhc2ce0be2014-05-29 12:36:14 +00003241 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3242 const char *zMode = nArg>=2 ? azArg[1] : "";
3243 int n2 = (int)strlen(zMode);
3244 int c2 = zMode[0];
3245 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003246 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003247 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003248 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003249 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003250 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003251 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003252 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003253 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003254 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003255 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003256 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003257 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003258 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003259 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003260 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003261 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003262 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003263 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003264 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003265 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003266 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3267 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003268 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3269 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003270 }else {
shane9bd1b442009-10-23 01:27:39 +00003271 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003272 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003273 rc = 1;
drh75897232000-05-29 14:26:00 +00003274 }
3275 }else
3276
drhc2ce0be2014-05-29 12:36:14 +00003277 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3278 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003279 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3280 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003281 }else{
3282 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003283 rc = 1;
3284 }
3285 }else
3286
drh05782482013-10-24 15:20:20 +00003287 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3288 sqlite3 *savedDb = p->db;
3289 const char *zSavedFilename = p->zDbFilename;
3290 char *zNewFilename = 0;
3291 p->db = 0;
3292 if( nArg>=2 ){
3293 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3294 }
3295 open_db(p, 1);
3296 if( p->db!=0 ){
3297 sqlite3_close(savedDb);
3298 sqlite3_free(p->zFreeOnClose);
3299 p->zFreeOnClose = zNewFilename;
3300 }else{
3301 sqlite3_free(zNewFilename);
3302 p->db = savedDb;
3303 p->zDbFilename = zSavedFilename;
3304 }
3305 }else
3306
drhc2ce0be2014-05-29 12:36:14 +00003307 if( c=='o'
3308 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3309 ){
3310 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3311 if( nArg>2 ){
3312 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3313 rc = 1;
3314 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003315 }
drhc2ce0be2014-05-29 12:36:14 +00003316 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3317 if( nArg<2 ){
3318 fprintf(stderr, "Usage: .once FILE\n");
3319 rc = 1;
3320 goto meta_command_exit;
3321 }
3322 p->outCount = 2;
3323 }else{
3324 p->outCount = 0;
3325 }
3326 output_reset(p);
3327 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003328#ifdef SQLITE_OMIT_POPEN
3329 fprintf(stderr,"Error: pipes are not supported in this OS\n");
3330 rc = 1;
3331 p->out = stdout;
3332#else
drhc2ce0be2014-05-29 12:36:14 +00003333 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003334 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003335 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003336 p->out = stdout;
3337 rc = 1;
3338 }else{
drhc2ce0be2014-05-29 12:36:14 +00003339 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003340 }
drh8cd5b252015-03-02 22:06:43 +00003341#endif
drh75897232000-05-29 14:26:00 +00003342 }else{
drhc2ce0be2014-05-29 12:36:14 +00003343 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003344 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003345 if( strcmp(zFile,"off")!=0 ){
3346 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003347 }
drh75897232000-05-29 14:26:00 +00003348 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003349 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003350 } else {
drhc2ce0be2014-05-29 12:36:14 +00003351 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003352 }
3353 }
3354 }else
3355
drh078b1fd2012-09-21 13:40:02 +00003356 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3357 int i;
3358 for(i=1; i<nArg; i++){
3359 if( i>1 ) fprintf(p->out, " ");
3360 fprintf(p->out, "%s", azArg[i]);
3361 }
3362 fprintf(p->out, "\n");
3363 }else
3364
drhc2ce0be2014-05-29 12:36:14 +00003365 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003366 if( nArg >= 2) {
3367 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3368 }
3369 if( nArg >= 3) {
3370 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3371 }
3372 }else
3373
drhc2ce0be2014-05-29 12:36:14 +00003374 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003375 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003376 }else
3377
drhc2ce0be2014-05-29 12:36:14 +00003378 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3379 FILE *alt;
3380 if( nArg!=2 ){
3381 fprintf(stderr, "Usage: .read FILE\n");
3382 rc = 1;
3383 goto meta_command_exit;
3384 }
3385 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003386 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003387 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3388 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003389 }else{
shane9bd1b442009-10-23 01:27:39 +00003390 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003391 fclose(alt);
3392 }
3393 }else
3394
drhc2ce0be2014-05-29 12:36:14 +00003395 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003396 const char *zSrcFile;
3397 const char *zDb;
3398 sqlite3 *pSrc;
3399 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003400 int nTimeout = 0;
3401
drh9ff849f2009-02-04 20:55:57 +00003402 if( nArg==2 ){
3403 zSrcFile = azArg[1];
3404 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003405 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003406 zSrcFile = azArg[2];
3407 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003408 }else{
3409 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3410 rc = 1;
3411 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003412 }
3413 rc = sqlite3_open(zSrcFile, &pSrc);
3414 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003415 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003416 sqlite3_close(pSrc);
3417 return 1;
3418 }
drh05782482013-10-24 15:20:20 +00003419 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003420 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3421 if( pBackup==0 ){
3422 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3423 sqlite3_close(pSrc);
3424 return 1;
3425 }
drhdc2c4912009-02-04 22:46:47 +00003426 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3427 || rc==SQLITE_BUSY ){
3428 if( rc==SQLITE_BUSY ){
3429 if( nTimeout++ >= 3 ) break;
3430 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003431 }
3432 }
3433 sqlite3_backup_finish(pBackup);
3434 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003435 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003436 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003437 fprintf(stderr, "Error: source database is busy\n");
3438 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003439 }else{
3440 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003441 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003442 }
3443 sqlite3_close(pSrc);
3444 }else
3445
dan8d1edb92014-11-05 09:07:28 +00003446
3447 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3448 if( nArg==2 ){
3449 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003450#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3451 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3452#endif
dan8d1edb92014-11-05 09:07:28 +00003453 }else{
3454 fprintf(stderr, "Usage: .scanstats on|off\n");
3455 rc = 1;
3456 }
3457 }else
3458
drhc2ce0be2014-05-29 12:36:14 +00003459 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003460 ShellState data;
drh75897232000-05-29 14:26:00 +00003461 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003462 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003463 memcpy(&data, p, sizeof(data));
3464 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003465 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003466 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003467 int i;
drhf0693c82011-10-11 20:41:54 +00003468 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003469 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003470 char *new_argv[2], *new_colv[2];
3471 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3472 " type text,\n"
3473 " name text,\n"
3474 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003475 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003476 " sql text\n"
3477 ")";
3478 new_argv[1] = 0;
3479 new_colv[0] = "sql";
3480 new_colv[1] = 0;
3481 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003482 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003483 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003484 char *new_argv[2], *new_colv[2];
3485 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3486 " type text,\n"
3487 " name text,\n"
3488 " tbl_name text,\n"
3489 " rootpage integer,\n"
3490 " sql text\n"
3491 ")";
3492 new_argv[1] = 0;
3493 new_colv[0] = "sql";
3494 new_colv[1] = 0;
3495 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003496 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003497 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003498 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003499 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003500 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003501 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003502 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003503 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003504 "WHERE lower(tbl_name) LIKE shellstatic()"
3505 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003506 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003507 callback, &data, &zErrMsg);
3508 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003509 }
drhc2ce0be2014-05-29 12:36:14 +00003510 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003511 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003512 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003513 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003514 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003515 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003516 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003517 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003518 callback, &data, &zErrMsg
3519 );
drhc2ce0be2014-05-29 12:36:14 +00003520 }else{
3521 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3522 rc = 1;
3523 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003524 }
drh75897232000-05-29 14:26:00 +00003525 if( zErrMsg ){
3526 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003527 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003528 rc = 1;
3529 }else if( rc != SQLITE_OK ){
3530 fprintf(stderr,"Error: querying schema information\n");
3531 rc = 1;
3532 }else{
3533 rc = 0;
drh75897232000-05-29 14:26:00 +00003534 }
3535 }else
3536
drhabd4c722014-09-20 18:18:33 +00003537
3538#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3539 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3540 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003541 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003542 }else
3543#endif
3544
3545
drh340f5822013-06-27 13:01:21 +00003546#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003547 /* Undocumented commands for internal testing. Subject to change
3548 ** without notice. */
3549 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3550 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3551 int i, v;
3552 for(i=1; i<nArg; i++){
3553 v = booleanValue(azArg[i]);
3554 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3555 }
3556 }
3557 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3558 int i; sqlite3_int64 v;
3559 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003560 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003561 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003562 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003563 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003564 }
3565 }
3566 }else
drh340f5822013-06-27 13:01:21 +00003567#endif
drh348d19c2013-06-03 12:47:43 +00003568
drhc2ce0be2014-05-29 12:36:14 +00003569 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003570 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003571 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003572 rc = 1;
3573 }
drh6976c212014-07-24 12:09:47 +00003574 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003575 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003576 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003577 }
3578 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003579 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3580 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003581 }
drh75897232000-05-29 14:26:00 +00003582 }else
3583
drh62cdde52014-05-28 20:22:28 +00003584 if( c=='s'
3585 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003586 ){
3587 char *zCmd;
drh54027102014-08-06 14:36:53 +00003588 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003589 if( nArg<2 ){
3590 fprintf(stderr, "Usage: .system COMMAND\n");
3591 rc = 1;
3592 goto meta_command_exit;
3593 }
drhdcb3e3d2014-05-29 03:17:29 +00003594 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003595 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003596 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3597 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003598 }
drh54027102014-08-06 14:36:53 +00003599 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003600 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003601 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003602 }else
3603
drhc2ce0be2014-05-29 12:36:14 +00003604 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003605 int i;
drhc2ce0be2014-05-29 12:36:14 +00003606 if( nArg!=1 ){
3607 fprintf(stderr, "Usage: .show\n");
3608 rc = 1;
3609 goto meta_command_exit;
3610 }
mistachkin636bf9f2014-07-19 20:15:16 +00003611 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3612 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003613 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003614 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3615 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3616 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003617 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003618 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003619 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003620 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003621 fprintf(p->out,"%12.12s: ", "colseparator");
3622 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003623 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003624 fprintf(p->out,"%12.12s: ", "rowseparator");
3625 output_c_string(p->out, p->rowSeparator);
3626 fprintf(p->out, "\n");
3627 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3628 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003629 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003630 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003631 }
drhfeac5f82004-08-01 00:10:45 +00003632 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003633 }else
3634
drhc2ce0be2014-05-29 12:36:14 +00003635 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3636 if( nArg==2 ){
3637 p->statsOn = booleanValue(azArg[1]);
3638 }else{
3639 fprintf(stderr, "Usage: .stats on|off\n");
3640 rc = 1;
3641 }
shaneh642d8b82010-07-28 16:05:34 +00003642 }else
3643
drhc2ce0be2014-05-29 12:36:14 +00003644 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003645 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003646 char **azResult;
drh98781232012-04-23 12:38:05 +00003647 int nRow, nAlloc;
3648 char *zSql = 0;
3649 int ii;
drh05782482013-10-24 15:20:20 +00003650 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003651 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3652 if( rc ) return rc;
3653 zSql = sqlite3_mprintf(
3654 "SELECT name FROM sqlite_master"
3655 " WHERE type IN ('table','view')"
3656 " AND name NOT LIKE 'sqlite_%%'"
3657 " AND name LIKE ?1");
3658 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3659 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3660 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3661 if( strcmp(zDbName,"temp")==0 ){
3662 zSql = sqlite3_mprintf(
3663 "%z UNION ALL "
3664 "SELECT 'temp.' || name FROM sqlite_temp_master"
3665 " WHERE type IN ('table','view')"
3666 " AND name NOT LIKE 'sqlite_%%'"
3667 " AND name LIKE ?1", zSql);
3668 }else{
3669 zSql = sqlite3_mprintf(
3670 "%z UNION ALL "
3671 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3672 " WHERE type IN ('table','view')"
3673 " AND name NOT LIKE 'sqlite_%%'"
3674 " AND name LIKE ?1", zSql, zDbName, zDbName);
3675 }
drha50da102000-08-08 20:19:09 +00003676 }
drh98781232012-04-23 12:38:05 +00003677 sqlite3_finalize(pStmt);
3678 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3679 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3680 sqlite3_free(zSql);
3681 if( rc ) return rc;
3682 nRow = nAlloc = 0;
3683 azResult = 0;
3684 if( nArg>1 ){
3685 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003686 }else{
drh98781232012-04-23 12:38:05 +00003687 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3688 }
3689 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3690 if( nRow>=nAlloc ){
3691 char **azNew;
3692 int n = nAlloc*2 + 10;
3693 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3694 if( azNew==0 ){
3695 fprintf(stderr, "Error: out of memory\n");
3696 break;
3697 }
3698 nAlloc = n;
3699 azResult = azNew;
3700 }
3701 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3702 if( azResult[nRow] ) nRow++;
3703 }
3704 sqlite3_finalize(pStmt);
3705 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003706 int len, maxlen = 0;
3707 int i, j;
3708 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003709 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003710 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003711 if( len>maxlen ) maxlen = len;
3712 }
3713 nPrintCol = 80/(maxlen+2);
3714 if( nPrintCol<1 ) nPrintCol = 1;
3715 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3716 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003717 for(j=i; j<nRow; j+=nPrintRow){
3718 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003719 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003720 }
drh151b7d52013-05-06 20:28:54 +00003721 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003722 }
3723 }
drh98781232012-04-23 12:38:05 +00003724 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3725 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003726 }else
3727
shaneh96887e12011-02-10 21:08:58 +00003728 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003729 static const struct {
3730 const char *zCtrlName; /* Name of a test-control option */
3731 int ctrlCode; /* Integer code for that option */
3732 } aCtrl[] = {
3733 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3734 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3735 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3736 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3737 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3738 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3739 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3740 { "assert", SQLITE_TESTCTRL_ASSERT },
3741 { "always", SQLITE_TESTCTRL_ALWAYS },
3742 { "reserve", SQLITE_TESTCTRL_RESERVE },
3743 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3744 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003745 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003746 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003747 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003748 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003749 };
shaneh96887e12011-02-10 21:08:58 +00003750 int testctrl = -1;
3751 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003752 int i, n;
drh05782482013-10-24 15:20:20 +00003753 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003754
drhd416fe72011-03-17 16:45:50 +00003755 /* convert testctrl text option to value. allow any unique prefix
3756 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003757 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003758 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003759 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3760 if( testctrl<0 ){
3761 testctrl = aCtrl[i].ctrlCode;
3762 }else{
drhb07028f2011-10-14 21:49:18 +00003763 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003764 testctrl = -1;
3765 break;
3766 }
3767 }
3768 }
drh348d19c2013-06-03 12:47:43 +00003769 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003770 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3771 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3772 }else{
3773 switch(testctrl){
3774
3775 /* sqlite3_test_control(int, db, int) */
3776 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3777 case SQLITE_TESTCTRL_RESERVE:
3778 if( nArg==3 ){
3779 int opt = (int)strtol(azArg[2], 0, 0);
3780 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003781 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003782 } else {
drhd416fe72011-03-17 16:45:50 +00003783 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3784 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003785 }
3786 break;
3787
3788 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003789 case SQLITE_TESTCTRL_PRNG_SAVE:
3790 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003791 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003792 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003793 if( nArg==2 ){
3794 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003795 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003796 } else {
3797 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3798 }
3799 break;
3800
3801 /* sqlite3_test_control(int, uint) */
3802 case SQLITE_TESTCTRL_PENDING_BYTE:
3803 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003804 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003805 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003806 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003807 } else {
drhd416fe72011-03-17 16:45:50 +00003808 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3809 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003810 }
3811 break;
3812
3813 /* sqlite3_test_control(int, int) */
3814 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003815 case SQLITE_TESTCTRL_ALWAYS:
3816 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003817 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003818 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003819 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003820 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003821 } else {
drhd416fe72011-03-17 16:45:50 +00003822 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3823 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003824 }
3825 break;
3826
3827 /* sqlite3_test_control(int, char *) */
3828#ifdef SQLITE_N_KEYWORD
3829 case SQLITE_TESTCTRL_ISKEYWORD:
3830 if( nArg==3 ){
3831 const char *opt = azArg[2];
3832 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003833 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003834 } else {
drhd416fe72011-03-17 16:45:50 +00003835 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3836 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003837 }
3838 break;
3839#endif
3840
drh1ffede82015-01-30 20:59:27 +00003841 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003842 if( nArg==5 ){
3843 rc = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003844 azArg[2],
drh8964b342015-01-29 17:54:52 +00003845 integerValue(azArg[3]),
3846 integerValue(azArg[4]));
drh6f5a37a2015-03-27 02:27:20 +00003847 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
drh8964b342015-01-29 17:54:52 +00003848 }else{
drh6f5a37a2015-03-27 02:27:20 +00003849 fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003850 }
3851 break;
3852
shaneh96887e12011-02-10 21:08:58 +00003853 case SQLITE_TESTCTRL_BITVEC_TEST:
3854 case SQLITE_TESTCTRL_FAULT_INSTALL:
3855 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3856 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3857 default:
drhd416fe72011-03-17 16:45:50 +00003858 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3859 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003860 break;
3861 }
3862 }
3863 }else
3864
drhc2ce0be2014-05-29 12:36:14 +00003865 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003866 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003867 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003868 }else
3869
drhc2ce0be2014-05-29 12:36:14 +00003870 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3871 if( nArg==2 ){
3872 enableTimer = booleanValue(azArg[1]);
3873 if( enableTimer && !HAS_TIMER ){
3874 fprintf(stderr, "Error: timer not available on this system.\n");
3875 enableTimer = 0;
3876 }
3877 }else{
3878 fprintf(stderr, "Usage: .timer on|off\n");
3879 rc = 1;
3880 }
shanehe2aa9d72009-11-06 17:20:17 +00003881 }else
3882
drhc2ce0be2014-05-29 12:36:14 +00003883 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003884 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003885 if( nArg!=2 ){
3886 fprintf(stderr, "Usage: .trace FILE|off\n");
3887 rc = 1;
3888 goto meta_command_exit;
3889 }
drh657b4a82015-03-19 13:30:41 +00003890 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00003891 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003892#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003893 if( p->traceOut==0 ){
3894 sqlite3_trace(p->db, 0, 0);
3895 }else{
3896 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3897 }
3898#endif
3899 }else
3900
drhf442e332014-09-10 19:01:14 +00003901#if SQLITE_USER_AUTHENTICATION
3902 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3903 if( nArg<2 ){
3904 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3905 rc = 1;
3906 goto meta_command_exit;
3907 }
drh7883ecf2014-09-11 16:19:31 +00003908 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003909 if( strcmp(azArg[1],"login")==0 ){
3910 if( nArg!=4 ){
3911 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3912 rc = 1;
3913 goto meta_command_exit;
3914 }
drhd39c40f2014-09-11 00:27:53 +00003915 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3916 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003917 if( rc ){
3918 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3919 rc = 1;
3920 }
3921 }else if( strcmp(azArg[1],"add")==0 ){
3922 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003923 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003924 rc = 1;
3925 goto meta_command_exit;
3926 }
drhd39c40f2014-09-11 00:27:53 +00003927 rc = sqlite3_user_add(p->db, azArg[2],
3928 azArg[3], (int)strlen(azArg[3]),
3929 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003930 if( rc ){
3931 fprintf(stderr, "User-Add failed: %d\n", rc);
3932 rc = 1;
3933 }
3934 }else if( strcmp(azArg[1],"edit")==0 ){
3935 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003936 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003937 rc = 1;
3938 goto meta_command_exit;
3939 }
drhd39c40f2014-09-11 00:27:53 +00003940 rc = sqlite3_user_change(p->db, azArg[2],
3941 azArg[3], (int)strlen(azArg[3]),
3942 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003943 if( rc ){
3944 fprintf(stderr, "User-Edit failed: %d\n", rc);
3945 rc = 1;
3946 }
3947 }else if( strcmp(azArg[1],"delete")==0 ){
3948 if( nArg!=3 ){
3949 fprintf(stderr, "Usage: .user delete USER\n");
3950 rc = 1;
3951 goto meta_command_exit;
3952 }
3953 rc = sqlite3_user_delete(p->db, azArg[2]);
3954 if( rc ){
3955 fprintf(stderr, "User-Delete failed: %d\n", rc);
3956 rc = 1;
3957 }
3958 }else{
3959 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
3960 rc = 1;
3961 goto meta_command_exit;
3962 }
3963 }else
3964#endif /* SQLITE_USER_AUTHENTICATION */
3965
drh9fd301b2011-06-03 13:28:22 +00003966 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003967 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003968 sqlite3_libversion(), sqlite3_sourceid());
3969 }else
3970
drhde60fc22011-12-14 17:53:36 +00003971 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3972 const char *zDbName = nArg==2 ? azArg[1] : "main";
3973 char *zVfsName = 0;
3974 if( p->db ){
3975 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3976 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003977 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003978 sqlite3_free(zVfsName);
3979 }
3980 }
3981 }else
3982
drhcef4fc82012-09-21 22:50:45 +00003983#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3984 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3985 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003986 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003987 }else
3988#endif
3989
drhc2ce0be2014-05-29 12:36:14 +00003990 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003991 int j;
drh43617e92006-03-06 20:55:46 +00003992 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003993 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003994 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003995 }
3996 }else
3997
3998 {
shane9bd1b442009-10-23 01:27:39 +00003999 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004000 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004001 rc = 1;
drh75897232000-05-29 14:26:00 +00004002 }
drh67505e72002-04-19 12:34:06 +00004003
drhc2ce0be2014-05-29 12:36:14 +00004004meta_command_exit:
4005 if( p->outCount ){
4006 p->outCount--;
4007 if( p->outCount==0 ) output_reset(p);
4008 }
drh67505e72002-04-19 12:34:06 +00004009 return rc;
drh75897232000-05-29 14:26:00 +00004010}
4011
drh67505e72002-04-19 12:34:06 +00004012/*
drh91a66392007-09-07 01:12:32 +00004013** Return TRUE if a semicolon occurs anywhere in the first N characters
4014** of string z[].
drh324ccef2003-02-05 14:06:20 +00004015*/
drh9f099fd2013-08-06 14:01:46 +00004016static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004017 int i;
4018 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4019 return 0;
drh324ccef2003-02-05 14:06:20 +00004020}
4021
4022/*
drh70c7a4b2003-04-26 03:03:06 +00004023** Test to see if a line consists entirely of whitespace.
4024*/
4025static int _all_whitespace(const char *z){
4026 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004027 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004028 if( *z=='/' && z[1]=='*' ){
4029 z += 2;
4030 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4031 if( *z==0 ) return 0;
4032 z++;
4033 continue;
4034 }
4035 if( *z=='-' && z[1]=='-' ){
4036 z += 2;
4037 while( *z && *z!='\n' ){ z++; }
4038 if( *z==0 ) return 1;
4039 continue;
4040 }
4041 return 0;
4042 }
4043 return 1;
4044}
4045
4046/*
drha9b17162003-04-29 18:01:28 +00004047** Return TRUE if the line typed in is an SQL command terminator other
4048** than a semi-colon. The SQL Server style "go" command is understood
4049** as is the Oracle "/".
4050*/
drh9f099fd2013-08-06 14:01:46 +00004051static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004052 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004053 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4054 return 1; /* Oracle */
4055 }
drhf0693c82011-10-11 20:41:54 +00004056 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004057 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004058 return 1; /* SQL Server */
4059 }
4060 return 0;
4061}
4062
4063/*
drh233a5312008-12-18 22:25:13 +00004064** Return true if zSql is a complete SQL statement. Return false if it
4065** ends in the middle of a string literal or C-style comment.
4066*/
drh9f099fd2013-08-06 14:01:46 +00004067static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004068 int rc;
4069 if( zSql==0 ) return 1;
4070 zSql[nSql] = ';';
4071 zSql[nSql+1] = 0;
4072 rc = sqlite3_complete(zSql);
4073 zSql[nSql] = 0;
4074 return rc;
4075}
4076
4077/*
drh67505e72002-04-19 12:34:06 +00004078** Read input from *in and process it. If *in==0 then input
4079** is interactive - the user is typing it it. Otherwise, input
4080** is coming from a file or device. A prompt is issued and history
4081** is saved only if input is interactive. An interrupt signal will
4082** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004083**
4084** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004085*/
drhdcd87a92014-08-18 13:45:42 +00004086static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004087 char *zLine = 0; /* A single input line */
4088 char *zSql = 0; /* Accumulated SQL text */
4089 int nLine; /* Length of current line */
4090 int nSql = 0; /* Bytes of zSql[] used */
4091 int nAlloc = 0; /* Allocated zSql[] space */
4092 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4093 char *zErrMsg; /* Error message returned */
4094 int rc; /* Error code */
4095 int errCnt = 0; /* Number of errors seen */
4096 int lineno = 0; /* Current line number */
4097 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004098
4099 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4100 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004101 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004102 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004103 /* End of input */
4104 if( stdin_is_interactive ) printf("\n");
4105 break;
drhc49f44e2006-10-26 18:15:42 +00004106 }
drh67505e72002-04-19 12:34:06 +00004107 if( seenInterrupt ){
4108 if( in!=0 ) break;
4109 seenInterrupt = 0;
4110 }
drhc28490c2006-10-26 14:25:58 +00004111 lineno++;
drh849a9d92013-12-21 15:46:06 +00004112 if( nSql==0 && _all_whitespace(zLine) ){
4113 if( p->echoOn ) printf("%s\n", zLine);
4114 continue;
4115 }
drh2af0b2d2002-02-21 02:25:02 +00004116 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004117 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004118 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004119 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004120 break;
4121 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004122 errCnt++;
4123 }
drhdaffd0e2001-04-11 14:28:42 +00004124 continue;
4125 }
drh9f099fd2013-08-06 14:01:46 +00004126 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004127 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004128 }
drh9f099fd2013-08-06 14:01:46 +00004129 nLine = strlen30(zLine);
4130 if( nSql+nLine+2>=nAlloc ){
4131 nAlloc = nSql+nLine+100;
4132 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004133 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004134 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004135 exit(1);
4136 }
drhdaffd0e2001-04-11 14:28:42 +00004137 }
drh9f099fd2013-08-06 14:01:46 +00004138 nSqlPrior = nSql;
4139 if( nSql==0 ){
4140 int i;
4141 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004142 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004143 memcpy(zSql, zLine+i, nLine+1-i);
4144 startline = lineno;
4145 nSql = nLine-i;
4146 }else{
4147 zSql[nSql++] = '\n';
4148 memcpy(zSql+nSql, zLine, nLine+1);
4149 nSql += nLine;
4150 }
4151 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004152 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004153 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004154 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00004155 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004156 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004157 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004158 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004159 char zPrefix[100];
4160 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004161 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004162 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004163 }else{
shane9bd1b442009-10-23 01:27:39 +00004164 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004165 }
drh7f953e22002-07-13 17:33:45 +00004166 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004167 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004168 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004169 zErrMsg = 0;
4170 }else{
shaned2bed1c2009-10-21 03:56:54 +00004171 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004172 }
drhc49f44e2006-10-26 18:15:42 +00004173 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004174 }
drhdaffd0e2001-04-11 14:28:42 +00004175 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004176 if( p->outCount ){
4177 output_reset(p);
4178 p->outCount = 0;
4179 }
drh9f099fd2013-08-06 14:01:46 +00004180 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004181 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004182 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004183 }
4184 }
drh9f099fd2013-08-06 14:01:46 +00004185 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004186 if( !_all_whitespace(zSql) ){
4187 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004188 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004189 }
drhdaffd0e2001-04-11 14:28:42 +00004190 free(zSql);
4191 }
danielk19772ac27622007-07-03 05:31:16 +00004192 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004193 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004194}
4195
drh67505e72002-04-19 12:34:06 +00004196/*
4197** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004198** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004199*/
4200static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004201 static char *home_dir = NULL;
4202 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004203
drh4ace5362014-11-10 14:42:28 +00004204#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4205 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004206 {
4207 struct passwd *pwent;
4208 uid_t uid = getuid();
4209 if( (pwent=getpwuid(uid)) != NULL) {
4210 home_dir = pwent->pw_dir;
4211 }
drh67505e72002-04-19 12:34:06 +00004212 }
4213#endif
4214
chw65d3c132007-11-12 21:09:10 +00004215#if defined(_WIN32_WCE)
4216 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4217 */
drh85e72432012-04-11 11:38:53 +00004218 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004219#else
4220
drh83905c92012-06-21 13:00:37 +00004221#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004222 if (!home_dir) {
4223 home_dir = getenv("USERPROFILE");
4224 }
4225#endif
4226
drh67505e72002-04-19 12:34:06 +00004227 if (!home_dir) {
4228 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004229 }
4230
drh83905c92012-06-21 13:00:37 +00004231#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004232 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004233 char *zDrive, *zPath;
4234 int n;
4235 zDrive = getenv("HOMEDRIVE");
4236 zPath = getenv("HOMEPATH");
4237 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004238 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004239 home_dir = malloc( n );
4240 if( home_dir==0 ) return 0;
4241 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4242 return home_dir;
4243 }
4244 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004245 }
4246#endif
4247
chw65d3c132007-11-12 21:09:10 +00004248#endif /* !_WIN32_WCE */
4249
drh67505e72002-04-19 12:34:06 +00004250 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004251 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004252 char *z = malloc( n );
4253 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004254 home_dir = z;
4255 }
drhe98d4fa2002-04-21 19:06:22 +00004256
drh67505e72002-04-19 12:34:06 +00004257 return home_dir;
4258}
4259
4260/*
4261** Read input from the file given by sqliterc_override. Or if that
4262** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004263**
4264** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004265*/
drh534f4df2015-02-28 14:03:35 +00004266static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004267 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004268 const char *sqliterc_override /* Name of config file. NULL to use default */
4269){
persicom7e2dfdd2002-04-18 02:46:52 +00004270 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004271 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004272 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004273 FILE *in = NULL;
4274
4275 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004276 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004277 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004278 fprintf(stderr, "-- warning: cannot find home directory;"
4279 " cannot read ~/.sqliterc\n");
4280 return;
drhe98d4fa2002-04-21 19:06:22 +00004281 }
drh2f3de322012-06-27 16:41:31 +00004282 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004283 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4284 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004285 }
drha1f9b5e2004-02-14 16:31:02 +00004286 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004287 if( in ){
drhc28490c2006-10-26 14:25:58 +00004288 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004289 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004290 }
drh534f4df2015-02-28 14:03:35 +00004291 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004292 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004293 }
drh85e72432012-04-11 11:38:53 +00004294 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004295}
4296
drh67505e72002-04-19 12:34:06 +00004297/*
drhe1e38c42003-05-04 18:30:59 +00004298** Show available command line options
4299*/
4300static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004301 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004302 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004303 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004304 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004305 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004306 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004307 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004308 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004309 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004310#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4311 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4312#endif
drhcc3b4f82012-02-07 14:13:50 +00004313 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004314 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004315 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004316 " -line set output mode to 'line'\n"
4317 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004318 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004319 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004320#ifdef SQLITE_ENABLE_MULTIPLEX
4321 " -multiplex enable the multiplexor VFS\n"
4322#endif
mistachkine0d68852014-12-11 03:12:33 +00004323 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004324 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004325 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4326 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004327 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004328 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004329 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004330 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004331#ifdef SQLITE_ENABLE_VFSTRACE
4332 " -vfstrace enable tracing of all VFS calls\n"
4333#endif
drhe1e38c42003-05-04 18:30:59 +00004334;
4335static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004336 fprintf(stderr,
4337 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4338 "FILENAME is the name of an SQLite database. A new database is created\n"
4339 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004340 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004341 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004342 }else{
4343 fprintf(stderr, "Use the -help option for additional information\n");
4344 }
4345 exit(1);
4346}
4347
4348/*
drh67505e72002-04-19 12:34:06 +00004349** Initialize the state information in data
4350*/
drhdcd87a92014-08-18 13:45:42 +00004351static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004352 memset(data, 0, sizeof(*data));
4353 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004354 memcpy(data->colSeparator,SEP_Column, 2);
4355 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004356 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004357 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004358 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004359 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004360 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004361 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4362 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004363}
4364
drh98d312f2012-10-25 15:23:14 +00004365/*
drh5c7976f2014-02-10 19:59:27 +00004366** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004367*/
4368#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004369static void printBold(const char *zText){
4370 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4371 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4372 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4373 SetConsoleTextAttribute(out,
4374 FOREGROUND_RED|FOREGROUND_INTENSITY
4375 );
4376 printf("%s", zText);
4377 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004378}
4379#else
drh5c7976f2014-02-10 19:59:27 +00004380static void printBold(const char *zText){
4381 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004382}
4383#endif
4384
4385/*
drh98d312f2012-10-25 15:23:14 +00004386** Get the argument to an --option. Throw an error and die if no argument
4387** is available.
4388*/
4389static char *cmdline_option_value(int argc, char **argv, int i){
4390 if( i==argc ){
4391 fprintf(stderr, "%s: Error: missing argument to %s\n",
4392 argv[0], argv[argc-1]);
4393 exit(1);
4394 }
4395 return argv[i];
4396}
4397
mistachkin44723ce2015-03-21 02:22:37 +00004398int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004399 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004400 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004401 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004402 int i;
drhc28490c2006-10-26 14:25:58 +00004403 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004404 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004405 int readStdin = 1;
4406 int nCmd = 0;
4407 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004408
drh69b30ab2014-02-27 15:11:52 +00004409#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004410 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4411 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4412 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4413 exit(1);
4414 }
drhc7181902014-02-27 15:04:13 +00004415#endif
drh047d4532015-01-18 20:30:23 +00004416 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004417 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004418 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004419 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004420 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004421
drh44c2eb12003-04-30 11:38:26 +00004422 /* Make sure we have a valid signal handler early, before anything
4423 ** else is done.
4424 */
drh4c504392000-10-16 22:06:40 +00004425#ifdef SIGINT
4426 signal(SIGINT, interrupt_handler);
4427#endif
drh44c2eb12003-04-30 11:38:26 +00004428
drhac5649a2014-11-28 13:35:03 +00004429#ifdef SQLITE_SHELL_DBNAME_PROC
4430 {
4431 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4432 ** of a C-function that will provide the name of the database file. Use
4433 ** this compile-time option to embed this shell program in larger
4434 ** applications. */
4435 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4436 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4437 warnInmemoryDb = 0;
4438 }
4439#endif
4440
drh22fbcb82004-02-01 01:22:50 +00004441 /* Do an initial pass through the command-line argument to locate
4442 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004443 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004444 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004445 */
drh98d312f2012-10-25 15:23:14 +00004446 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004447 char *z;
drhc28490c2006-10-26 14:25:58 +00004448 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004449 if( z[0]!='-' ){
4450 if( data.zDbFilename==0 ){
4451 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004452 }else{
4453 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4454 ** mean that nothing is read from stdin */
4455 readStdin = 0;
4456 nCmd++;
4457 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4458 if( azCmd==0 ){
4459 fprintf(stderr, "out of memory\n");
4460 exit(1);
4461 }
4462 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004463 }
drh98d312f2012-10-25 15:23:14 +00004464 }
drhcc3b4f82012-02-07 14:13:50 +00004465 if( z[1]=='-' ) z++;
4466 if( strcmp(z,"-separator")==0
4467 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004468 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004469 || strcmp(z,"-cmd")==0
4470 ){
drh98d312f2012-10-25 15:23:14 +00004471 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004472 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004473 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004474 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004475 /* Need to check for batch mode here to so we can avoid printing
4476 ** informational messages (like from process_sqliterc) before
4477 ** we do the actual processing of arguments later in a second pass.
4478 */
shanef69573d2009-10-24 02:06:14 +00004479 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004480 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004481#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004482 const char *zSize;
4483 sqlite3_int64 szHeap;
4484
drh98d312f2012-10-25 15:23:14 +00004485 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004486 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004487 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004488 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4489#endif
drh44dec872014-08-30 15:49:25 +00004490 }else if( strcmp(z,"-scratch")==0 ){
4491 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004492 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004493 if( sz>400000 ) sz = 400000;
4494 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004495 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004496 if( n>10 ) n = 10;
4497 if( n<1 ) n = 1;
4498 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4499 data.shellFlgs |= SHFLG_Scratch;
4500 }else if( strcmp(z,"-pagecache")==0 ){
4501 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004502 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004503 if( sz>70000 ) sz = 70000;
4504 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004505 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004506 if( n<10 ) n = 10;
4507 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4508 data.shellFlgs |= SHFLG_Pagecache;
4509 }else if( strcmp(z,"-lookaside")==0 ){
4510 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004511 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004512 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004513 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004514 if( n<0 ) n = 0;
4515 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4516 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004517#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004518 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004519 extern int vfstrace_register(
4520 const char *zTraceName,
4521 const char *zOldVfsName,
4522 int (*xOut)(const char*,void*),
4523 void *pOutArg,
4524 int makeDefault
4525 );
drh2b625e22011-03-16 17:05:28 +00004526 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004527#endif
drh6f25e892011-07-08 17:02:57 +00004528#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004529 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004530 extern int sqlite3_multiple_initialize(const char*,int);
4531 sqlite3_multiplex_initialize(0, 1);
4532#endif
drh7d9f3942013-04-03 01:26:54 +00004533 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004534 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4535 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004536 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004537 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004538 if( pVfs ){
4539 sqlite3_vfs_register(pVfs, 1);
4540 }else{
4541 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4542 exit(1);
4543 }
drh44c2eb12003-04-30 11:38:26 +00004544 }
4545 }
drh98d312f2012-10-25 15:23:14 +00004546 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004547#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004548 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004549 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004550#else
shane86f5bdb2009-10-24 02:00:07 +00004551 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4552 return 1;
drh01b41712005-08-29 23:06:23 +00004553#endif
drh98d312f2012-10-25 15:23:14 +00004554 }
4555 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004556
drh44c2eb12003-04-30 11:38:26 +00004557 /* Go ahead and open the database file if it already exists. If the
4558 ** file does not exist, delay opening it. This prevents empty database
4559 ** files from being created if a user mistypes the database name argument
4560 ** to the sqlite command-line tool.
4561 */
drhc8d74412004-08-31 23:41:26 +00004562 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004563 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004564 }
4565
drh22fbcb82004-02-01 01:22:50 +00004566 /* Process the initialization file if there is one. If no -init option
4567 ** is given on the command line, look for a file named ~/.sqliterc and
4568 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004569 */
drh534f4df2015-02-28 14:03:35 +00004570 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004571
drh22fbcb82004-02-01 01:22:50 +00004572 /* Make a second pass through the command-line argument and set
4573 ** options. This second pass is delayed until after the initialization
4574 ** file is processed so that the command-line arguments will override
4575 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004576 */
drh98d312f2012-10-25 15:23:14 +00004577 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004578 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004579 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004580 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004581 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004582 i++;
4583 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004584 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004585 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004586 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004587 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004588 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004589 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004590 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004591 }else if( strcmp(z,"-csv")==0 ){
4592 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004593 memcpy(data.colSeparator,",",2);
4594 }else if( strcmp(z,"-ascii")==0 ){
4595 data.mode = MODE_Ascii;
4596 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004597 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004598 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004599 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004600 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004601 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4602 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004603 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004604 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004605 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004606 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004607 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004608 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004609 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004610 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004611 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004612 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004613 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004614 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004615 }else if( strcmp(z,"-eqp")==0 ){
4616 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004617 }else if( strcmp(z,"-stats")==0 ){
4618 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004619 }else if( strcmp(z,"-scanstats")==0 ){
4620 data.scanstatsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004621 }else if( strcmp(z,"-bail")==0 ){
4622 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004623 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004624 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004625 return 0;
drhc28490c2006-10-26 14:25:58 +00004626 }else if( strcmp(z,"-interactive")==0 ){
4627 stdin_is_interactive = 1;
4628 }else if( strcmp(z,"-batch")==0 ){
4629 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004630 }else if( strcmp(z,"-heap")==0 ){
4631 i++;
drh44dec872014-08-30 15:49:25 +00004632 }else if( strcmp(z,"-scratch")==0 ){
4633 i+=2;
4634 }else if( strcmp(z,"-pagecache")==0 ){
4635 i+=2;
4636 }else if( strcmp(z,"-lookaside")==0 ){
4637 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004638 }else if( strcmp(z,"-mmap")==0 ){
4639 i++;
drha7e61d82011-03-12 17:02:57 +00004640 }else if( strcmp(z,"-vfs")==0 ){
4641 i++;
drh6f25e892011-07-08 17:02:57 +00004642#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004643 }else if( strcmp(z,"-vfstrace")==0 ){
4644 i++;
drh6f25e892011-07-08 17:02:57 +00004645#endif
4646#ifdef SQLITE_ENABLE_MULTIPLEX
4647 }else if( strcmp(z,"-multiplex")==0 ){
4648 i++;
4649#endif
drhcc3b4f82012-02-07 14:13:50 +00004650 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004651 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004652 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004653 /* Run commands that follow -cmd first and separately from commands
4654 ** that simply appear on the command-line. This seems goofy. It would
4655 ** be better if all commands ran in the order that they appear. But
4656 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004657 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004658 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004659 if( z[0]=='.' ){
4660 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004661 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004662 }else{
drh05782482013-10-24 15:20:20 +00004663 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004664 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4665 if( zErrMsg!=0 ){
4666 fprintf(stderr,"Error: %s\n", zErrMsg);
4667 if( bail_on_error ) return rc!=0 ? rc : 1;
4668 }else if( rc!=0 ){
4669 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4670 if( bail_on_error ) return rc;
4671 }
4672 }
drh1e5d0e92000-05-31 23:33:17 +00004673 }else{
shane86f5bdb2009-10-24 02:00:07 +00004674 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004675 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004676 return 1;
4677 }
4678 }
drh44c2eb12003-04-30 11:38:26 +00004679
drhac5649a2014-11-28 13:35:03 +00004680 if( !readStdin ){
4681 /* Run all arguments that do not begin with '-' as if they were separate
4682 ** command-line inputs, except for the argToSkip argument which contains
4683 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004684 */
drhac5649a2014-11-28 13:35:03 +00004685 for(i=0; i<nCmd; i++){
4686 if( azCmd[i][0]=='.' ){
4687 rc = do_meta_command(azCmd[i], &data);
4688 if( rc ) return rc==2 ? 0 : rc;
4689 }else{
4690 open_db(&data, 0);
4691 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4692 if( zErrMsg!=0 ){
4693 fprintf(stderr,"Error: %s\n", zErrMsg);
4694 return rc!=0 ? rc : 1;
4695 }else if( rc!=0 ){
4696 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4697 return rc;
4698 }
drh6ff13852001-11-25 13:18:23 +00004699 }
drh75897232000-05-29 14:26:00 +00004700 }
drhac5649a2014-11-28 13:35:03 +00004701 free(azCmd);
drh75897232000-05-29 14:26:00 +00004702 }else{
drh44c2eb12003-04-30 11:38:26 +00004703 /* Run commands received from standard input
4704 */
drhc28490c2006-10-26 14:25:58 +00004705 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004706 char *zHome;
4707 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004708 int nHistory;
drh75897232000-05-29 14:26:00 +00004709 printf(
drh743e0032011-12-12 16:51:50 +00004710 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004711 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004712 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004713 );
drhb3735912014-02-10 16:13:42 +00004714 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004715 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004716 printBold("transient in-memory database");
4717 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004718 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004719 }
drh67505e72002-04-19 12:34:06 +00004720 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004721 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004722 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004723 if( (zHistory = malloc(nHistory))!=0 ){
4724 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4725 }
drh67505e72002-04-19 12:34:06 +00004726 }
danfd34d6d2015-02-25 10:54:53 +00004727 if( zHistory ) shell_read_history(zHistory);
drhc28490c2006-10-26 14:25:58 +00004728 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004729 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004730 shell_stifle_history(100);
4731 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004732 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004733 }
drhdaffd0e2001-04-11 14:28:42 +00004734 }else{
drhc28490c2006-10-26 14:25:58 +00004735 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004736 }
4737 }
drh33048c02001-10-01 14:29:22 +00004738 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004739 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004740 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004741 }
drh05782482013-10-24 15:20:20 +00004742 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004743 return rc;
drh75897232000-05-29 14:26:00 +00004744}