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