blob: 7db8dbda0ae52718842803e6ad795b467920e76f [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;
mistachkin151c75a2015-04-07 21:16:40 +0000993 fprintf(p->out,"INSERT INTO %s",p->zDestTable);
994 if( p->showHeader ){
995 fprintf(p->out,"(");
996 for(i=0; i<nArg; i++){
997 char *zSep = i>0 ? ",": "";
998 fprintf(p->out, "%s%s", zSep, azCol[i]);
999 }
1000 fprintf(p->out,")");
1001 }
1002 fprintf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001003 for(i=0; i<nArg; i++){
1004 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001005 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +00001006 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001007 }else if( aiType && aiType[i]==SQLITE_TEXT ){
1008 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1009 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001010 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1011 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +00001012 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001013 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1014 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1015 int nBlob = sqlite3_column_bytes(p->pStmt, i);
1016 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1017 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001018 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001019 fprintf(p->out,"%s%s",zSep, azArg[i]);
1020 }else{
1021 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1022 output_quoted_string(p->out, azArg[i]);
1023 }
1024 }
1025 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001026 break;
drh28bd4bc2000-06-15 15:57:22 +00001027 }
mistachkin636bf9f2014-07-19 20:15:16 +00001028 case MODE_Ascii: {
1029 if( p->cnt++==0 && p->showHeader ){
1030 for(i=0; i<nArg; i++){
1031 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
1032 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
1033 }
1034 fprintf(p->out, "%s", p->rowSeparator);
1035 }
1036 if( azArg==0 ) break;
1037 for(i=0; i<nArg; i++){
1038 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +00001039 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001040 }
1041 fprintf(p->out, "%s", p->rowSeparator);
1042 break;
1043 }
persicom1d0b8722002-04-18 02:53:04 +00001044 }
drh75897232000-05-29 14:26:00 +00001045 return 0;
1046}
1047
1048/*
shane626a6e42009-10-22 17:30:15 +00001049** This is the callback routine that the SQLite library
1050** invokes for each row of a query result.
1051*/
1052static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1053 /* since we don't have type info, call the shell_callback with a NULL value */
1054 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1055}
1056
1057/*
drhdcd87a92014-08-18 13:45:42 +00001058** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001059** the name of the table given. Escape any quote characters in the
1060** table name.
1061*/
drhdcd87a92014-08-18 13:45:42 +00001062static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001063 int i, n;
1064 int needQuote;
1065 char *z;
1066
1067 if( p->zDestTable ){
1068 free(p->zDestTable);
1069 p->zDestTable = 0;
1070 }
1071 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001072 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001073 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001074 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001075 needQuote = 1;
1076 if( zName[i]=='\'' ) n++;
1077 }
1078 }
1079 if( needQuote ) n += 2;
1080 z = p->zDestTable = malloc( n+1 );
1081 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001082 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001083 exit(1);
1084 }
1085 n = 0;
1086 if( needQuote ) z[n++] = '\'';
1087 for(i=0; zName[i]; i++){
1088 z[n++] = zName[i];
1089 if( zName[i]=='\'' ) z[n++] = '\'';
1090 }
1091 if( needQuote ) z[n++] = '\'';
1092 z[n] = 0;
1093}
1094
danielk19772a02e332004-06-05 08:04:36 +00001095/* zIn is either a pointer to a NULL-terminated string in memory obtained
1096** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1097** added to zIn, and the result returned in memory obtained from malloc().
1098** zIn, if it was not NULL, is freed.
1099**
1100** If the third argument, quote, is not '\0', then it is used as a
1101** quote character for zAppend.
1102*/
drhc28490c2006-10-26 14:25:58 +00001103static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001104 int len;
1105 int i;
drh4f21c4a2008-12-10 22:15:00 +00001106 int nAppend = strlen30(zAppend);
1107 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001108
1109 len = nAppend+nIn+1;
1110 if( quote ){
1111 len += 2;
1112 for(i=0; i<nAppend; i++){
1113 if( zAppend[i]==quote ) len++;
1114 }
1115 }
1116
1117 zIn = (char *)realloc(zIn, len);
1118 if( !zIn ){
1119 return 0;
1120 }
1121
1122 if( quote ){
1123 char *zCsr = &zIn[nIn];
1124 *zCsr++ = quote;
1125 for(i=0; i<nAppend; i++){
1126 *zCsr++ = zAppend[i];
1127 if( zAppend[i]==quote ) *zCsr++ = quote;
1128 }
1129 *zCsr++ = quote;
1130 *zCsr++ = '\0';
1131 assert( (zCsr-zIn)==len );
1132 }else{
1133 memcpy(&zIn[nIn], zAppend, nAppend);
1134 zIn[len-1] = '\0';
1135 }
1136
1137 return zIn;
1138}
1139
drhdd3d4592004-08-30 01:54:05 +00001140
1141/*
drhb21a8e42012-01-28 21:08:51 +00001142** Execute a query statement that will generate SQL output. Print
1143** the result columns, comma-separated, on a line and then add a
1144** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001145**
drhb21a8e42012-01-28 21:08:51 +00001146** If the number of columns is 1 and that column contains text "--"
1147** then write the semicolon on a separate line. That way, if a
1148** "--" comment occurs at the end of the statement, the comment
1149** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001150*/
drh157e29a2009-05-21 15:15:00 +00001151static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001152 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001153 const char *zSelect, /* SELECT statement to extract content */
1154 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001155){
drhdd3d4592004-08-30 01:54:05 +00001156 sqlite3_stmt *pSelect;
1157 int rc;
drhb21a8e42012-01-28 21:08:51 +00001158 int nResult;
1159 int i;
1160 const char *z;
drhc7181902014-02-27 15:04:13 +00001161 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001162 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001163 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001164 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001165 return rc;
1166 }
1167 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001168 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001169 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001170 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001171 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001172 zFirstRow = 0;
1173 }
drhb21a8e42012-01-28 21:08:51 +00001174 z = (const char*)sqlite3_column_text(pSelect, 0);
1175 fprintf(p->out, "%s", z);
1176 for(i=1; i<nResult; i++){
1177 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1178 }
1179 if( z==0 ) z = "";
1180 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1181 if( z[0] ){
1182 fprintf(p->out, "\n;\n");
1183 }else{
1184 fprintf(p->out, ";\n");
1185 }
drhdd3d4592004-08-30 01:54:05 +00001186 rc = sqlite3_step(pSelect);
1187 }
drh2f464a02011-10-13 00:41:49 +00001188 rc = sqlite3_finalize(pSelect);
1189 if( rc!=SQLITE_OK ){
1190 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001191 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001192 }
1193 return rc;
drhdd3d4592004-08-30 01:54:05 +00001194}
1195
shane626a6e42009-10-22 17:30:15 +00001196/*
1197** Allocate space and save off current error string.
1198*/
1199static char *save_err_msg(
1200 sqlite3 *db /* Database to query */
1201){
1202 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001203 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001204 if( zErrMsg ){
1205 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1206 }
1207 return zErrMsg;
1208}
1209
1210/*
shaneh642d8b82010-07-28 16:05:34 +00001211** Display memory stats.
1212*/
1213static int display_stats(
1214 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001215 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001216 int bReset /* True to reset the stats */
1217){
1218 int iCur;
1219 int iHiwtr;
1220
1221 if( pArg && pArg->out ){
1222
1223 iHiwtr = iCur = -1;
1224 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001225 fprintf(pArg->out,
1226 "Memory Used: %d (max %d) bytes\n",
1227 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001228 iHiwtr = iCur = -1;
1229 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001230 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1231 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001232 if( pArg->shellFlgs & SHFLG_Pagecache ){
1233 iHiwtr = iCur = -1;
1234 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001235 fprintf(pArg->out,
1236 "Number of Pcache Pages Used: %d (max %d) pages\n",
1237 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001238 }
shaneh642d8b82010-07-28 16:05:34 +00001239 iHiwtr = iCur = -1;
1240 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001241 fprintf(pArg->out,
1242 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1243 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001244 if( pArg->shellFlgs & SHFLG_Scratch ){
1245 iHiwtr = iCur = -1;
1246 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001247 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1248 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001249 }
shaneh642d8b82010-07-28 16:05:34 +00001250 iHiwtr = iCur = -1;
1251 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001252 fprintf(pArg->out,
1253 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1254 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001255 iHiwtr = iCur = -1;
1256 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001257 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1258 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001259 iHiwtr = iCur = -1;
1260 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001261 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1262 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001263 iHiwtr = iCur = -1;
1264 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001265 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1266 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001267#ifdef YYTRACKMAXSTACKDEPTH
1268 iHiwtr = iCur = -1;
1269 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001270 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1271 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001272#endif
1273 }
1274
1275 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001276 if( pArg->shellFlgs & SHFLG_Lookaside ){
1277 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001278 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1279 &iCur, &iHiwtr, bReset);
1280 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1281 iCur, iHiwtr);
1282 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1283 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001284 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001285 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1286 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001287 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001288 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1289 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001290 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1291 }
shaneh642d8b82010-07-28 16:05:34 +00001292 iHiwtr = iCur = -1;
1293 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001294 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1295 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001296 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1297 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1298 iHiwtr = iCur = -1;
1299 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1300 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001301 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001302 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1303 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1304 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001305 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001306 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001307 iHiwtr = iCur = -1;
1308 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001309 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001310 }
1311
1312 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001313 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1314 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001315 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1316 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1317 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001318 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001319 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001320 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1321 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001322 }
1323
1324 return 0;
1325}
1326
1327/*
dan8d1edb92014-11-05 09:07:28 +00001328** Display scan stats.
1329*/
1330static void display_scanstats(
1331 sqlite3 *db, /* Database to query */
1332 ShellState *pArg /* Pointer to ShellState */
1333){
1334#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001335 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001336 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001337 mx = 0;
1338 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001339 double rEstLoop = 1.0;
1340 for(i=n=0; 1; i++){
1341 sqlite3_stmt *p = pArg->pStmt;
1342 sqlite3_int64 nLoop, nVisit;
1343 double rEst;
1344 int iSid;
1345 const char *zExplain;
1346 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1347 break;
1348 }
1349 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001350 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001351 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001352 if( n==0 ){
1353 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001354 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001355 }
drh42f30bc2014-11-06 12:08:21 +00001356 n++;
1357 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1358 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1359 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1360 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1361 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001362 fprintf(pArg->out,
1363 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001364 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001365 );
dan8d1edb92014-11-05 09:07:28 +00001366 }
dan8d1edb92014-11-05 09:07:28 +00001367 }
dan8d1edb92014-11-05 09:07:28 +00001368 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001369#endif
dan8d1edb92014-11-05 09:07:28 +00001370}
1371
1372/*
dana98bf362013-11-13 18:35:01 +00001373** Parameter azArray points to a zero-terminated array of strings. zStr
1374** points to a single nul-terminated string. Return non-zero if zStr
1375** is equal, according to strcmp(), to any of the strings in the array.
1376** Otherwise, return zero.
1377*/
1378static int str_in_array(const char *zStr, const char **azArray){
1379 int i;
1380 for(i=0; azArray[i]; i++){
1381 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1382 }
1383 return 0;
1384}
1385
1386/*
1387** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001388** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001389** spaces each opcode should be indented before it is output.
1390**
1391** The indenting rules are:
1392**
1393** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1394** all opcodes that occur between the p2 jump destination and the opcode
1395** itself by 2 spaces.
1396**
drh01752bc2013-11-14 23:59:33 +00001397** * For each "Goto", if the jump destination is earlier in the program
1398** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001399** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001400** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001401** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001402** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001403*/
drhdcd87a92014-08-18 13:45:42 +00001404static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001405 const char *zSql; /* The text of the SQL statement */
1406 const char *z; /* Used to check if this is an EXPLAIN */
1407 int *abYield = 0; /* True if op is an OP_Yield */
1408 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001409 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001410
drh8ad0de32014-03-20 18:45:27 +00001411 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1412 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001413 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1414 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001415 const char *azGoto[] = { "Goto", 0 };
1416
1417 /* Try to figure out if this is really an EXPLAIN statement. If this
1418 ** cannot be verified, return early. */
1419 zSql = sqlite3_sql(pSql);
1420 if( zSql==0 ) return;
1421 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1422 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1423
1424 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1425 int i;
danc4650bb2013-11-18 08:41:06 +00001426 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001427 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001428
1429 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1430 ** p2 is an instruction address, set variable p2op to the index of that
1431 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1432 ** the current instruction is part of a sub-program generated by an
1433 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001434 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001435 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001436
1437 /* Grow the p->aiIndent array as required */
1438 if( iOp>=nAlloc ){
1439 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001440 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1441 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001442 }
1443 abYield[iOp] = str_in_array(zOp, azYield);
1444 p->aiIndent[iOp] = 0;
1445 p->nIndent = iOp+1;
1446
1447 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001448 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001449 }
drhfe705102014-03-06 13:38:37 +00001450 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1451 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1452 ){
drhe73f0592014-01-21 22:25:45 +00001453 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001454 }
1455 }
1456
danc4650bb2013-11-18 08:41:06 +00001457 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001458 sqlite3_free(abYield);
1459 sqlite3_reset(pSql);
1460}
1461
1462/*
1463** Free the array allocated by explain_data_prepare().
1464*/
drhdcd87a92014-08-18 13:45:42 +00001465static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001466 sqlite3_free(p->aiIndent);
1467 p->aiIndent = 0;
1468 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001469 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001470}
1471
1472/*
shane626a6e42009-10-22 17:30:15 +00001473** Execute a statement or set of statements. Print
1474** any result rows/columns depending on the current mode
1475** set via the supplied callback.
1476**
1477** This is very similar to SQLite's built-in sqlite3_exec()
1478** function except it takes a slightly different callback
1479** and callback data argument.
1480*/
1481static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001482 sqlite3 *db, /* An open database */
1483 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001484 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001485 /* (not the same as sqlite3_exec) */
1486 ShellState *pArg, /* Pointer to ShellState */
1487 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001488){
dan4564ced2010-01-05 04:59:56 +00001489 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1490 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001491 int rc2;
dan4564ced2010-01-05 04:59:56 +00001492 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001493
1494 if( pzErrMsg ){
1495 *pzErrMsg = NULL;
1496 }
1497
shaneb9fc17d2009-10-22 21:23:35 +00001498 while( zSql[0] && (SQLITE_OK == rc) ){
1499 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1500 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001501 if( pzErrMsg ){
1502 *pzErrMsg = save_err_msg(db);
1503 }
1504 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001505 if( !pStmt ){
1506 /* this happens for a comment or white-space */
1507 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001508 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001509 continue;
1510 }
shane626a6e42009-10-22 17:30:15 +00001511
shaneh642d8b82010-07-28 16:05:34 +00001512 /* save off the prepared statment handle and reset row count */
1513 if( pArg ){
1514 pArg->pStmt = pStmt;
1515 pArg->cnt = 0;
1516 }
1517
shanehb7977c52010-01-18 18:17:10 +00001518 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001519 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001520 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001521 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001522 }
shanehb7977c52010-01-18 18:17:10 +00001523
drhefbf3b12014-02-28 20:47:24 +00001524 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1525 if( pArg && pArg->autoEQP ){
1526 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001527 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1528 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001529 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1530 if( rc==SQLITE_OK ){
1531 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1532 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1533 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1534 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1535 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1536 }
1537 }
1538 sqlite3_finalize(pExplain);
1539 sqlite3_free(zEQP);
1540 }
1541
dana98bf362013-11-13 18:35:01 +00001542 /* If the shell is currently in ".explain" mode, gather the extra
1543 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001544 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001545 explain_data_prepare(pArg, pStmt);
1546 }
1547
shaneb9fc17d2009-10-22 21:23:35 +00001548 /* perform the first step. this will tell us if we
1549 ** have a result set or not and how wide it is.
1550 */
1551 rc = sqlite3_step(pStmt);
1552 /* if we have a result set... */
1553 if( SQLITE_ROW == rc ){
1554 /* if we have a callback... */
1555 if( xCallback ){
1556 /* allocate space for col name ptr, value ptr, and type */
1557 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001558 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001559 if( !pData ){
1560 rc = SQLITE_NOMEM;
1561 }else{
1562 char **azCols = (char **)pData; /* Names of result columns */
1563 char **azVals = &azCols[nCol]; /* Results */
1564 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001565 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001566 assert(sizeof(int) <= sizeof(char *));
1567 /* save off ptrs to column names */
1568 for(i=0; i<nCol; i++){
1569 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1570 }
shaneb9fc17d2009-10-22 21:23:35 +00001571 do{
1572 /* extract the data and data types */
1573 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001574 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001575 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001576 azVals[i] = "";
1577 }else{
1578 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1579 }
shaneb9fc17d2009-10-22 21:23:35 +00001580 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1581 rc = SQLITE_NOMEM;
1582 break; /* from for */
1583 }
1584 } /* end for */
1585
1586 /* if data and types extracted successfully... */
1587 if( SQLITE_ROW == rc ){
1588 /* call the supplied callback with the result row data */
1589 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1590 rc = SQLITE_ABORT;
1591 }else{
1592 rc = sqlite3_step(pStmt);
1593 }
1594 }
1595 } while( SQLITE_ROW == rc );
1596 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001597 }
1598 }else{
1599 do{
1600 rc = sqlite3_step(pStmt);
1601 } while( rc == SQLITE_ROW );
1602 }
1603 }
1604
dana98bf362013-11-13 18:35:01 +00001605 explain_data_delete(pArg);
1606
shaneh642d8b82010-07-28 16:05:34 +00001607 /* print usage stats if stats on */
1608 if( pArg && pArg->statsOn ){
1609 display_stats(db, pArg, 0);
1610 }
1611
dan8d1edb92014-11-05 09:07:28 +00001612 /* print loop-counters if required */
1613 if( pArg && pArg->scanstatsOn ){
1614 display_scanstats(db, pArg);
1615 }
1616
dan4564ced2010-01-05 04:59:56 +00001617 /* Finalize the statement just executed. If this fails, save a
1618 ** copy of the error message. Otherwise, set zSql to point to the
1619 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001620 rc2 = sqlite3_finalize(pStmt);
1621 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001622 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001623 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001624 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001625 }else if( pzErrMsg ){
1626 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001627 }
shaneh642d8b82010-07-28 16:05:34 +00001628
1629 /* clear saved stmt handle */
1630 if( pArg ){
1631 pArg->pStmt = NULL;
1632 }
shane626a6e42009-10-22 17:30:15 +00001633 }
shaneb9fc17d2009-10-22 21:23:35 +00001634 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001635
1636 return rc;
1637}
1638
drhdd3d4592004-08-30 01:54:05 +00001639
drh33048c02001-10-01 14:29:22 +00001640/*
drh4c653a02000-06-07 01:27:47 +00001641** This is a different callback routine used for dumping the database.
1642** Each row received by this callback consists of a table name,
1643** the table type ("index" or "table") and SQL to create the table.
1644** This routine should print text sufficient to recreate the table.
1645*/
1646static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001647 int rc;
1648 const char *zTable;
1649 const char *zType;
1650 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001651 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001652 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001653
drh902b9ee2008-12-05 17:17:07 +00001654 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001655 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001656 zTable = azArg[0];
1657 zType = azArg[1];
1658 zSql = azArg[2];
1659
drh00b950d2005-09-11 02:03:03 +00001660 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001661 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001662 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001663 fprintf(p->out, "ANALYZE sqlite_master;\n");
1664 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1665 return 0;
drh45e29d82006-11-20 16:21:10 +00001666 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1667 char *zIns;
1668 if( !p->writableSchema ){
1669 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1670 p->writableSchema = 1;
1671 }
1672 zIns = sqlite3_mprintf(
1673 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1674 "VALUES('table','%q','%q',0,'%q');",
1675 zTable, zTable, zSql);
1676 fprintf(p->out, "%s\n", zIns);
1677 sqlite3_free(zIns);
1678 return 0;
drh00b950d2005-09-11 02:03:03 +00001679 }else{
1680 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001681 }
danielk19772a02e332004-06-05 08:04:36 +00001682
1683 if( strcmp(zType, "table")==0 ){
1684 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001685 char *zSelect = 0;
1686 char *zTableInfo = 0;
1687 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001688 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001689
1690 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1691 zTableInfo = appendText(zTableInfo, zTable, '"');
1692 zTableInfo = appendText(zTableInfo, ");", 0);
1693
drhc7181902014-02-27 15:04:13 +00001694 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001695 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001696 if( rc!=SQLITE_OK || !pTableInfo ){
1697 return 1;
1698 }
1699
1700 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001701 /* Always quote the table name, even if it appears to be pure ascii,
1702 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1703 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001704 if( zTmp ){
1705 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001706 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001707 }
1708 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1709 rc = sqlite3_step(pTableInfo);
1710 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001711 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001712 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001713 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001714 rc = sqlite3_step(pTableInfo);
1715 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001716 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001717 }else{
1718 zSelect = appendText(zSelect, ") ", 0);
1719 }
drh157e29a2009-05-21 15:15:00 +00001720 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001721 }
1722 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001723 if( rc!=SQLITE_OK || nRow==0 ){
1724 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001725 return 1;
1726 }
1727 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1728 zSelect = appendText(zSelect, zTable, '"');
1729
drh2f464a02011-10-13 00:41:49 +00001730 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001731 if( rc==SQLITE_CORRUPT ){
1732 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001733 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001734 }
drh85e72432012-04-11 11:38:53 +00001735 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001736 }
drh4c653a02000-06-07 01:27:47 +00001737 return 0;
1738}
1739
1740/*
drh45e29d82006-11-20 16:21:10 +00001741** Run zQuery. Use dump_callback() as the callback routine so that
1742** the contents of the query are output as SQL statements.
1743**
drhdd3d4592004-08-30 01:54:05 +00001744** If we get a SQLITE_CORRUPT error, rerun the query after appending
1745** "ORDER BY rowid DESC" to the end.
1746*/
1747static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001748 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001749 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001750){
1751 int rc;
drh2f464a02011-10-13 00:41:49 +00001752 char *zErr = 0;
1753 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001754 if( rc==SQLITE_CORRUPT ){
1755 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001756 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001757 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1758 if( zErr ){
1759 fprintf(p->out, "/****** %s ******/\n", zErr);
1760 sqlite3_free(zErr);
1761 zErr = 0;
1762 }
drhdd3d4592004-08-30 01:54:05 +00001763 zQ2 = malloc( len+100 );
1764 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001765 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001766 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1767 if( rc ){
1768 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1769 }else{
1770 rc = SQLITE_CORRUPT;
1771 }
1772 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001773 free(zQ2);
1774 }
1775 return rc;
1776}
1777
1778/*
drh75897232000-05-29 14:26:00 +00001779** Text of a help message
1780*/
persicom1d0b8722002-04-18 02:53:04 +00001781static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001782 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001783 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001784 ".binary on|off Turn binary output on or off. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001785 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001786 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001787 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001788 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001789 " If TABLE specified, only dump tables matching\n"
1790 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001791 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001792 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001793 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001794 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001795 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001796 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001797 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001798 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001799 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001800 ".indexes ?TABLE? Show names of all indexes\n"
1801 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001802 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001803#ifdef SQLITE_ENABLE_IOTRACE
1804 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1805#endif
drh1a513372015-05-02 17:40:23 +00001806 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001807#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001808 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001809#endif
drh127f9d72010-02-23 01:47:00 +00001810 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001811 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001812 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001813 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001814 " column Left-aligned columns. (See .width)\n"
1815 " html HTML <table> code\n"
1816 " insert SQL insert statements for TABLE\n"
1817 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001818 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001819 " tabs Tab-separated values\n"
1820 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001821 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001822 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001823 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001824 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001825 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001826 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001827 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001828 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001829 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001830 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001831 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001832 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001833 " If TABLE specified, only show tables matching\n"
1834 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001835 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1836 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001837 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001838 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001839 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001840 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001841 ".tables ?TABLE? List names of tables\n"
1842 " If TABLE specified, only list tables matching\n"
1843 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001844 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001845 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001846 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001847 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001848 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001849 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001850;
1851
drhdaffd0e2001-04-11 14:28:42 +00001852/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001853static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001854/*
1855** Implementation of the "readfile(X)" SQL function. The entire content
1856** of the file named X is read and returned as a BLOB. NULL is returned
1857** if the file does not exist or is unreadable.
1858*/
1859static void readfileFunc(
1860 sqlite3_context *context,
1861 int argc,
1862 sqlite3_value **argv
1863){
1864 const char *zName;
1865 FILE *in;
1866 long nIn;
1867 void *pBuf;
1868
1869 zName = (const char*)sqlite3_value_text(argv[0]);
1870 if( zName==0 ) return;
1871 in = fopen(zName, "rb");
1872 if( in==0 ) return;
1873 fseek(in, 0, SEEK_END);
1874 nIn = ftell(in);
1875 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00001876 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00001877 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1878 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1879 }else{
1880 sqlite3_free(pBuf);
1881 }
1882 fclose(in);
1883}
1884
1885/*
1886** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1887** is written into file X. The number of bytes written is returned. Or
1888** NULL is returned if something goes wrong, such as being unable to open
1889** file X for writing.
1890*/
1891static void writefileFunc(
1892 sqlite3_context *context,
1893 int argc,
1894 sqlite3_value **argv
1895){
1896 FILE *out;
1897 const char *z;
drhba5b0932014-07-24 12:39:59 +00001898 sqlite3_int64 rc;
1899 const char *zFile;
1900
1901 zFile = (const char*)sqlite3_value_text(argv[0]);
1902 if( zFile==0 ) return;
1903 out = fopen(zFile, "wb");
1904 if( out==0 ) return;
1905 z = (const char*)sqlite3_value_blob(argv[1]);
1906 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001907 rc = 0;
1908 }else{
drh490fe862014-08-11 14:21:32 +00001909 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001910 }
1911 fclose(out);
1912 sqlite3_result_int64(context, rc);
1913}
drhdaffd0e2001-04-11 14:28:42 +00001914
drh75897232000-05-29 14:26:00 +00001915/*
drh44c2eb12003-04-30 11:38:26 +00001916** Make sure the database is open. If it is not, then open it. If
1917** the database fails to open, print an error message and exit.
1918*/
drhdcd87a92014-08-18 13:45:42 +00001919static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001920 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001921 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001922 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00001923 globalDb = p->db;
1924 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
1925 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00001926 shellstaticFunc, 0, 0);
1927 }
mistachkin8e189222015-04-19 21:43:16 +00001928 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
shane86f5bdb2009-10-24 02:00:07 +00001929 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00001930 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00001931 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001932 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001933 }
drhc2e87a32006-06-27 15:16:14 +00001934#ifndef SQLITE_OMIT_LOAD_EXTENSION
1935 sqlite3_enable_load_extension(p->db, 1);
1936#endif
mistachkin8e189222015-04-19 21:43:16 +00001937 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001938 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00001939 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001940 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001941 }
1942}
1943
1944/*
drhfeac5f82004-08-01 00:10:45 +00001945** Do C-language style dequoting.
1946**
mistachkinf21979d2015-01-18 05:35:01 +00001947** \a -> alarm
1948** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00001949** \t -> tab
1950** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00001951** \v -> vertical tab
1952** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00001953** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00001954** \s -> space
drh4c56b992013-06-27 13:26:55 +00001955** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00001956** \' -> '
drhfeac5f82004-08-01 00:10:45 +00001957** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00001958** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00001959*/
1960static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001961 int i, j;
1962 char c;
drhc2ce0be2014-05-29 12:36:14 +00001963 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001964 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00001965 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00001966 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00001967 if( c=='a' ){
1968 c = '\a';
1969 }else if( c=='b' ){
1970 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00001971 }else if( c=='t' ){
1972 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00001973 }else if( c=='n' ){
1974 c = '\n';
1975 }else if( c=='v' ){
1976 c = '\v';
1977 }else if( c=='f' ){
1978 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00001979 }else if( c=='r' ){
1980 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00001981 }else if( c=='"' ){
1982 c = '"';
1983 }else if( c=='\'' ){
1984 c = '\'';
drh4c56b992013-06-27 13:26:55 +00001985 }else if( c=='\\' ){
1986 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001987 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001988 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001989 if( z[i+1]>='0' && z[i+1]<='7' ){
1990 i++;
1991 c = (c<<3) + z[i] - '0';
1992 if( z[i+1]>='0' && z[i+1]<='7' ){
1993 i++;
1994 c = (c<<3) + z[i] - '0';
1995 }
1996 }
1997 }
1998 }
1999 z[j] = c;
2000 }
drhc2ce0be2014-05-29 12:36:14 +00002001 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002002}
2003
2004/*
drh348d19c2013-06-03 12:47:43 +00002005** Return the value of a hexadecimal digit. Return -1 if the input
2006** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002007*/
drh348d19c2013-06-03 12:47:43 +00002008static int hexDigitValue(char c){
2009 if( c>='0' && c<='9' ) return c - '0';
2010 if( c>='a' && c<='f' ) return c - 'a' + 10;
2011 if( c>='A' && c<='F' ) return c - 'A' + 10;
2012 return -1;
drhc28490c2006-10-26 14:25:58 +00002013}
2014
2015/*
drh7d9f3942013-04-03 01:26:54 +00002016** Interpret zArg as an integer value, possibly with suffixes.
2017*/
2018static sqlite3_int64 integerValue(const char *zArg){
2019 sqlite3_int64 v = 0;
2020 static const struct { char *zSuffix; int iMult; } aMult[] = {
2021 { "KiB", 1024 },
2022 { "MiB", 1024*1024 },
2023 { "GiB", 1024*1024*1024 },
2024 { "KB", 1000 },
2025 { "MB", 1000000 },
2026 { "GB", 1000000000 },
2027 { "K", 1000 },
2028 { "M", 1000000 },
2029 { "G", 1000000000 },
2030 };
2031 int i;
2032 int isNeg = 0;
2033 if( zArg[0]=='-' ){
2034 isNeg = 1;
2035 zArg++;
2036 }else if( zArg[0]=='+' ){
2037 zArg++;
2038 }
drh348d19c2013-06-03 12:47:43 +00002039 if( zArg[0]=='0' && zArg[1]=='x' ){
2040 int x;
2041 zArg += 2;
2042 while( (x = hexDigitValue(zArg[0]))>=0 ){
2043 v = (v<<4) + x;
2044 zArg++;
2045 }
2046 }else{
2047 while( IsDigit(zArg[0]) ){
2048 v = v*10 + zArg[0] - '0';
2049 zArg++;
2050 }
drh7d9f3942013-04-03 01:26:54 +00002051 }
drhc2bed0a2013-05-24 11:57:50 +00002052 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002053 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2054 v *= aMult[i].iMult;
2055 break;
2056 }
2057 }
2058 return isNeg? -v : v;
2059}
2060
2061/*
drh348d19c2013-06-03 12:47:43 +00002062** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2063** for TRUE and FALSE. Return the integer value if appropriate.
2064*/
2065static int booleanValue(char *zArg){
2066 int i;
2067 if( zArg[0]=='0' && zArg[1]=='x' ){
2068 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2069 }else{
2070 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2071 }
2072 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2073 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2074 return 1;
2075 }
2076 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2077 return 0;
2078 }
2079 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2080 zArg);
2081 return 0;
2082}
2083
2084/*
drh42f64e52012-04-04 16:56:23 +00002085** Close an output file, assuming it is not stderr or stdout
2086*/
2087static void output_file_close(FILE *f){
2088 if( f && f!=stdout && f!=stderr ) fclose(f);
2089}
2090
2091/*
2092** Try to open an output file. The names "stdout" and "stderr" are
2093** recognized and do the right thing. NULL is returned if the output
2094** filename is "off".
2095*/
2096static FILE *output_file_open(const char *zFile){
2097 FILE *f;
2098 if( strcmp(zFile,"stdout")==0 ){
2099 f = stdout;
2100 }else if( strcmp(zFile, "stderr")==0 ){
2101 f = stderr;
2102 }else if( strcmp(zFile, "off")==0 ){
2103 f = 0;
2104 }else{
2105 f = fopen(zFile, "wb");
2106 if( f==0 ){
2107 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2108 }
2109 }
2110 return f;
2111}
2112
2113/*
2114** A routine for handling output from sqlite3_trace().
2115*/
2116static void sql_trace_callback(void *pArg, const char *z){
2117 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002118 if( f ){
2119 int i = (int)strlen(z);
2120 while( i>0 && z[i-1]==';' ){ i--; }
2121 fprintf(f, "%.*s;\n", i, z);
2122 }
drh42f64e52012-04-04 16:56:23 +00002123}
2124
2125/*
drhd8621b92012-04-17 09:09:33 +00002126** A no-op routine that runs with the ".breakpoint" doc-command. This is
2127** a useful spot to set a debugger breakpoint.
2128*/
2129static void test_breakpoint(void){
2130 static int nCall = 0;
2131 nCall++;
2132}
2133
2134/*
mistachkin636bf9f2014-07-19 20:15:16 +00002135** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002136*/
mistachkin636bf9f2014-07-19 20:15:16 +00002137typedef struct ImportCtx ImportCtx;
2138struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002139 const char *zFile; /* Name of the input file */
2140 FILE *in; /* Read the CSV text from this input stream */
2141 char *z; /* Accumulated text for a field */
2142 int n; /* Number of bytes in z */
2143 int nAlloc; /* Space allocated for z[] */
2144 int nLine; /* Current line number */
2145 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002146 int cColSep; /* The column separator character. (Usually ",") */
2147 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002148};
2149
2150/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002151static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002152 if( p->n+1>=p->nAlloc ){
2153 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002154 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002155 if( p->z==0 ){
2156 fprintf(stderr, "out of memory\n");
2157 exit(1);
2158 }
2159 }
2160 p->z[p->n++] = (char)c;
2161}
2162
2163/* Read a single field of CSV text. Compatible with rfc4180 and extended
2164** with the option of having a separator other than ",".
2165**
2166** + Input comes from p->in.
2167** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002168** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002169** + Use p->cSep as the column separator. The default is ",".
2170** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002171** + Keep track of the line number in p->nLine.
2172** + Store the character that terminates the field in p->cTerm. Store
2173** EOF on end-of-file.
2174** + Report syntax errors on stderr
2175*/
mistachkin44723ce2015-03-21 02:22:37 +00002176static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002177 int c;
2178 int cSep = p->cColSep;
2179 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002180 p->n = 0;
2181 c = fgetc(p->in);
2182 if( c==EOF || seenInterrupt ){
2183 p->cTerm = EOF;
2184 return 0;
2185 }
2186 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002187 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002188 int startLine = p->nLine;
2189 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002190 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002191 while( 1 ){
2192 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002193 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002194 if( c==cQuote ){
2195 if( pc==cQuote ){
2196 pc = 0;
2197 continue;
2198 }
2199 }
2200 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002201 || (c==rSep && pc==cQuote)
2202 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002203 || (c==EOF && pc==cQuote)
2204 ){
2205 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002206 p->cTerm = c;
2207 break;
2208 }
2209 if( pc==cQuote && c!='\r' ){
2210 fprintf(stderr, "%s:%d: unescaped %c character\n",
2211 p->zFile, p->nLine, cQuote);
2212 }
2213 if( c==EOF ){
2214 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2215 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002216 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002217 break;
2218 }
mistachkin636bf9f2014-07-19 20:15:16 +00002219 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002220 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002221 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002222 }
drhdb95f682013-06-26 22:46:00 +00002223 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002224 while( c!=EOF && c!=cSep && c!=rSep ){
2225 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002226 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002227 }
mistachkin636bf9f2014-07-19 20:15:16 +00002228 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002229 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002230 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002231 }
drhdb95f682013-06-26 22:46:00 +00002232 p->cTerm = c;
2233 }
drh8dd675e2013-07-12 21:09:24 +00002234 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002235 return p->z;
2236}
2237
mistachkin636bf9f2014-07-19 20:15:16 +00002238/* Read a single field of ASCII delimited text.
2239**
2240** + Input comes from p->in.
2241** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002242** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002243** + Use p->cSep as the column separator. The default is "\x1F".
2244** + Use p->rSep as the row separator. The default is "\x1E".
2245** + Keep track of the row number in p->nLine.
2246** + Store the character that terminates the field in p->cTerm. Store
2247** EOF on end-of-file.
2248** + Report syntax errors on stderr
2249*/
mistachkin44723ce2015-03-21 02:22:37 +00002250static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002251 int c;
2252 int cSep = p->cColSep;
2253 int rSep = p->cRowSep;
2254 p->n = 0;
2255 c = fgetc(p->in);
2256 if( c==EOF || seenInterrupt ){
2257 p->cTerm = EOF;
2258 return 0;
2259 }
2260 while( c!=EOF && c!=cSep && c!=rSep ){
2261 import_append_char(p, c);
2262 c = fgetc(p->in);
2263 }
2264 if( c==rSep ){
2265 p->nLine++;
2266 }
2267 p->cTerm = c;
2268 if( p->z ) p->z[p->n] = 0;
2269 return p->z;
2270}
2271
drhdb95f682013-06-26 22:46:00 +00002272/*
drh4bbcf102014-02-06 02:46:08 +00002273** Try to transfer data for table zTable. If an error is seen while
2274** moving forward, try to go backwards. The backwards movement won't
2275** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002276*/
mistachkine31ae902014-02-06 01:15:29 +00002277static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002278 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002279 sqlite3 *newDb,
2280 const char *zTable
2281){
2282 sqlite3_stmt *pQuery = 0;
2283 sqlite3_stmt *pInsert = 0;
2284 char *zQuery = 0;
2285 char *zInsert = 0;
2286 int rc;
2287 int i, j, n;
2288 int nTable = (int)strlen(zTable);
2289 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002290 int cnt = 0;
2291 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002292
2293 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2294 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2295 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002296 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002297 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2298 zQuery);
2299 goto end_data_xfer;
2300 }
2301 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002302 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002303 if( zInsert==0 ){
2304 fprintf(stderr, "out of memory\n");
2305 goto end_data_xfer;
2306 }
2307 sqlite3_snprintf(200+nTable,zInsert,
2308 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2309 i = (int)strlen(zInsert);
2310 for(j=1; j<n; j++){
2311 memcpy(zInsert+i, ",?", 2);
2312 i += 2;
2313 }
2314 memcpy(zInsert+i, ");", 3);
2315 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2316 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002317 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002318 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2319 zQuery);
2320 goto end_data_xfer;
2321 }
2322 for(k=0; k<2; k++){
2323 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2324 for(i=0; i<n; i++){
2325 switch( sqlite3_column_type(pQuery, i) ){
2326 case SQLITE_NULL: {
2327 sqlite3_bind_null(pInsert, i+1);
2328 break;
2329 }
2330 case SQLITE_INTEGER: {
2331 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2332 break;
2333 }
2334 case SQLITE_FLOAT: {
2335 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2336 break;
2337 }
2338 case SQLITE_TEXT: {
2339 sqlite3_bind_text(pInsert, i+1,
2340 (const char*)sqlite3_column_text(pQuery,i),
2341 -1, SQLITE_STATIC);
2342 break;
2343 }
2344 case SQLITE_BLOB: {
2345 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2346 sqlite3_column_bytes(pQuery,i),
2347 SQLITE_STATIC);
2348 break;
2349 }
2350 }
2351 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002352 rc = sqlite3_step(pInsert);
2353 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2354 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2355 sqlite3_errmsg(newDb));
2356 }
drh3350ce92014-02-06 00:49:12 +00002357 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002358 cnt++;
2359 if( (cnt%spinRate)==0 ){
2360 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2361 fflush(stdout);
2362 }
drh3350ce92014-02-06 00:49:12 +00002363 } /* End while */
2364 if( rc==SQLITE_DONE ) break;
2365 sqlite3_finalize(pQuery);
2366 sqlite3_free(zQuery);
2367 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2368 zTable);
2369 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2370 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002371 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2372 break;
drh3350ce92014-02-06 00:49:12 +00002373 }
2374 } /* End for(k=0...) */
2375
2376end_data_xfer:
2377 sqlite3_finalize(pQuery);
2378 sqlite3_finalize(pInsert);
2379 sqlite3_free(zQuery);
2380 sqlite3_free(zInsert);
2381}
2382
2383
2384/*
2385** Try to transfer all rows of the schema that match zWhere. For
2386** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002387** If an error is encountered while moving forward through the
2388** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002389*/
mistachkine31ae902014-02-06 01:15:29 +00002390static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002391 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002392 sqlite3 *newDb,
2393 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002394 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002395){
2396 sqlite3_stmt *pQuery = 0;
2397 char *zQuery = 0;
2398 int rc;
2399 const unsigned char *zName;
2400 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002401 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002402
2403 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2404 " WHERE %s", zWhere);
2405 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2406 if( rc ){
2407 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2408 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2409 zQuery);
2410 goto end_schema_xfer;
2411 }
2412 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2413 zName = sqlite3_column_text(pQuery, 0);
2414 zSql = sqlite3_column_text(pQuery, 1);
2415 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002416 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2417 if( zErrMsg ){
2418 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2419 sqlite3_free(zErrMsg);
2420 zErrMsg = 0;
2421 }
drh3350ce92014-02-06 00:49:12 +00002422 if( xForEach ){
2423 xForEach(p, newDb, (const char*)zName);
2424 }
2425 printf("done\n");
2426 }
2427 if( rc!=SQLITE_DONE ){
2428 sqlite3_finalize(pQuery);
2429 sqlite3_free(zQuery);
2430 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2431 " WHERE %s ORDER BY rowid DESC", zWhere);
2432 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2433 if( rc ){
2434 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2435 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2436 zQuery);
2437 goto end_schema_xfer;
2438 }
2439 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2440 zName = sqlite3_column_text(pQuery, 0);
2441 zSql = sqlite3_column_text(pQuery, 1);
2442 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002443 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2444 if( zErrMsg ){
2445 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2446 sqlite3_free(zErrMsg);
2447 zErrMsg = 0;
2448 }
drh3350ce92014-02-06 00:49:12 +00002449 if( xForEach ){
2450 xForEach(p, newDb, (const char*)zName);
2451 }
2452 printf("done\n");
2453 }
2454 }
2455end_schema_xfer:
2456 sqlite3_finalize(pQuery);
2457 sqlite3_free(zQuery);
2458}
2459
2460/*
2461** Open a new database file named "zNewDb". Try to recover as much information
2462** as possible out of the main database (which might be corrupt) and write it
2463** into zNewDb.
2464*/
drhdcd87a92014-08-18 13:45:42 +00002465static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002466 int rc;
2467 sqlite3 *newDb = 0;
2468 if( access(zNewDb,0)==0 ){
2469 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2470 return;
2471 }
2472 rc = sqlite3_open(zNewDb, &newDb);
2473 if( rc ){
2474 fprintf(stderr, "Cannot create output database: %s\n",
2475 sqlite3_errmsg(newDb));
2476 }else{
drh54d0d2d2014-04-03 00:32:13 +00002477 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002478 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002479 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2480 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002481 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002482 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002483 }
2484 sqlite3_close(newDb);
2485}
2486
2487/*
drhc2ce0be2014-05-29 12:36:14 +00002488** Change the output file back to stdout
2489*/
drhdcd87a92014-08-18 13:45:42 +00002490static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002491 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002492#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002493 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002494#endif
drhc2ce0be2014-05-29 12:36:14 +00002495 }else{
2496 output_file_close(p->out);
2497 }
2498 p->outfile[0] = 0;
2499 p->out = stdout;
2500}
2501
2502/*
drhf7502f02015-02-06 14:19:44 +00002503** Run an SQL command and return the single integer result.
2504*/
2505static int db_int(ShellState *p, const char *zSql){
2506 sqlite3_stmt *pStmt;
2507 int res = 0;
2508 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2509 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2510 res = sqlite3_column_int(pStmt,0);
2511 }
2512 sqlite3_finalize(pStmt);
2513 return res;
2514}
2515
2516/*
2517** Convert a 2-byte or 4-byte big-endian integer into a native integer
2518*/
2519unsigned int get2byteInt(unsigned char *a){
2520 return (a[0]<<8) + a[1];
2521}
2522unsigned int get4byteInt(unsigned char *a){
2523 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2524}
2525
2526/*
2527** Implementation of the ".info" command.
2528**
2529** Return 1 on error, 2 to exit, and 0 otherwise.
2530*/
drh0e55db12015-02-06 14:51:13 +00002531static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002532 static const struct { const char *zName; int ofst; } aField[] = {
2533 { "file change counter:", 24 },
2534 { "database page count:", 28 },
2535 { "freelist page count:", 36 },
2536 { "schema cookie:", 40 },
2537 { "schema format:", 44 },
2538 { "default cache size:", 48 },
2539 { "autovacuum top root:", 52 },
2540 { "incremental vacuum:", 64 },
2541 { "text encoding:", 56 },
2542 { "user version:", 60 },
2543 { "application id:", 68 },
2544 { "software version:", 96 },
2545 };
drh0e55db12015-02-06 14:51:13 +00002546 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2547 { "number of tables:",
2548 "SELECT count(*) FROM %s WHERE type='table'" },
2549 { "number of indexes:",
2550 "SELECT count(*) FROM %s WHERE type='index'" },
2551 { "number of triggers:",
2552 "SELECT count(*) FROM %s WHERE type='trigger'" },
2553 { "number of views:",
2554 "SELECT count(*) FROM %s WHERE type='view'" },
2555 { "schema size:",
2556 "SELECT total(length(sql)) FROM %s" },
2557 };
2558 sqlite3_file *pFile;
2559 int i;
2560 char *zSchemaTab;
2561 char *zDb = nArg>=2 ? azArg[1] : "main";
2562 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002563 open_db(p, 0);
2564 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002565 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002566 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2567 return 1;
2568 }
2569 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2570 if( i!=SQLITE_OK ){
2571 fprintf(stderr, "unable to read database header\n");
2572 return 1;
2573 }
2574 i = get2byteInt(aHdr+16);
2575 if( i==1 ) i = 65536;
2576 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2577 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2578 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2579 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2580 for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
2581 int ofst = aField[i].ofst;
2582 unsigned int val = get4byteInt(aHdr + ofst);
2583 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2584 switch( ofst ){
2585 case 56: {
2586 if( val==1 ) fprintf(p->out, " (utf8)");
2587 if( val==2 ) fprintf(p->out, " (utf16le)");
2588 if( val==3 ) fprintf(p->out, " (utf16be)");
2589 }
2590 }
2591 fprintf(p->out, "\n");
2592 }
drh0e55db12015-02-06 14:51:13 +00002593 if( zDb==0 ){
2594 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2595 }else if( strcmp(zDb,"temp")==0 ){
2596 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2597 }else{
2598 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2599 }
2600 for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
2601 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2602 int val = db_int(p, zSql);
2603 sqlite3_free(zSql);
2604 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2605 }
2606 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002607 return 0;
2608}
2609
2610
2611/*
drh75897232000-05-29 14:26:00 +00002612** If an input line begins with "." then invoke this routine to
2613** process that line.
drh67505e72002-04-19 12:34:06 +00002614**
drh47ad6842006-11-08 12:25:42 +00002615** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002616*/
drhdcd87a92014-08-18 13:45:42 +00002617static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002618 int h = 1;
drh75897232000-05-29 14:26:00 +00002619 int nArg = 0;
2620 int n, c;
drh67505e72002-04-19 12:34:06 +00002621 int rc = 0;
drh75897232000-05-29 14:26:00 +00002622 char *azArg[50];
2623
2624 /* Parse the input line into tokens.
2625 */
mistachkin8e189222015-04-19 21:43:16 +00002626 while( zLine[h] && nArg<ArraySize(azArg) ){
2627 while( IsSpace(zLine[h]) ){ h++; }
2628 if( zLine[h]==0 ) break;
2629 if( zLine[h]=='\'' || zLine[h]=='"' ){
2630 int delim = zLine[h++];
2631 azArg[nArg++] = &zLine[h];
2632 while( zLine[h] && zLine[h]!=delim ){
2633 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2634 h++;
drh4c56b992013-06-27 13:26:55 +00002635 }
mistachkin8e189222015-04-19 21:43:16 +00002636 if( zLine[h]==delim ){
2637 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002638 }
drhfeac5f82004-08-01 00:10:45 +00002639 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002640 }else{
mistachkin8e189222015-04-19 21:43:16 +00002641 azArg[nArg++] = &zLine[h];
2642 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2643 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002644 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002645 }
2646 }
2647
2648 /* Process the input line.
2649 */
shane9bd1b442009-10-23 01:27:39 +00002650 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002651 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002652 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002653 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2654 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2655 ){
drhbc46f022013-01-23 18:53:23 +00002656 const char *zDestFile = 0;
2657 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002658 sqlite3 *pDest;
2659 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002660 int j;
2661 for(j=1; j<nArg; j++){
2662 const char *z = azArg[j];
2663 if( z[0]=='-' ){
2664 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002665 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002666 {
2667 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2668 return 1;
2669 }
2670 }else if( zDestFile==0 ){
2671 zDestFile = azArg[j];
2672 }else if( zDb==0 ){
2673 zDb = zDestFile;
2674 zDestFile = azArg[j];
2675 }else{
2676 fprintf(stderr, "too many arguments to .backup\n");
2677 return 1;
2678 }
drh9ff849f2009-02-04 20:55:57 +00002679 }
drhbc46f022013-01-23 18:53:23 +00002680 if( zDestFile==0 ){
2681 fprintf(stderr, "missing FILENAME argument on .backup\n");
2682 return 1;
2683 }
2684 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002685 rc = sqlite3_open(zDestFile, &pDest);
2686 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002687 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002688 sqlite3_close(pDest);
2689 return 1;
2690 }
drh05782482013-10-24 15:20:20 +00002691 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002692 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2693 if( pBackup==0 ){
2694 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2695 sqlite3_close(pDest);
2696 return 1;
2697 }
2698 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2699 sqlite3_backup_finish(pBackup);
2700 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002701 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002702 }else{
2703 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002704 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002705 }
2706 sqlite3_close(pDest);
2707 }else
2708
drhc2ce0be2014-05-29 12:36:14 +00002709 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2710 if( nArg==2 ){
2711 bail_on_error = booleanValue(azArg[1]);
2712 }else{
2713 fprintf(stderr, "Usage: .bail on|off\n");
2714 rc = 1;
2715 }
drhc49f44e2006-10-26 18:15:42 +00002716 }else
2717
mistachkinf21979d2015-01-18 05:35:01 +00002718 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2719 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002720 if( booleanValue(azArg[1]) ){
2721 setBinaryMode(p->out);
2722 }else{
2723 setTextMode(p->out);
2724 }
mistachkinf21979d2015-01-18 05:35:01 +00002725 }else{
2726 fprintf(stderr, "Usage: .binary on|off\n");
2727 rc = 1;
2728 }
2729 }else
2730
drhd8621b92012-04-17 09:09:33 +00002731 /* The undocumented ".breakpoint" command causes a call to the no-op
2732 ** routine named test_breakpoint().
2733 */
2734 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2735 test_breakpoint();
2736 }else
2737
drhc2ce0be2014-05-29 12:36:14 +00002738 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2739 if( nArg==2 ){
2740 tryToClone(p, azArg[1]);
2741 }else{
2742 fprintf(stderr, "Usage: .clone FILENAME\n");
2743 rc = 1;
2744 }
mistachkine31ae902014-02-06 01:15:29 +00002745 }else
2746
drhc2ce0be2014-05-29 12:36:14 +00002747 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002748 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002749 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002750 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002751 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002752 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002753 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002754 data.colWidth[0] = 3;
2755 data.colWidth[1] = 15;
2756 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002757 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002758 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002759 if( zErrMsg ){
2760 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002761 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002762 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002763 }
2764 }else
2765
drh0e55db12015-02-06 14:51:13 +00002766 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2767 rc = shell_dbinfo_command(p, nArg, azArg);
2768 }else
2769
drhc2ce0be2014-05-29 12:36:14 +00002770 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002771 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002772 /* When playing back a "dump", the content might appear in an order
2773 ** which causes immediate foreign key constraints to be violated.
2774 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002775 if( nArg!=1 && nArg!=2 ){
2776 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2777 rc = 1;
2778 goto meta_command_exit;
2779 }
drhf1dfc4f2009-09-23 15:51:35 +00002780 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002781 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002782 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002783 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002784 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002785 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002786 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002787 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002788 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002789 );
2790 run_schema_dump_query(p,
2791 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002792 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002793 );
drh2f464a02011-10-13 00:41:49 +00002794 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002795 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002796 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002797 );
drh4c653a02000-06-07 01:27:47 +00002798 }else{
2799 int i;
drhdd3d4592004-08-30 01:54:05 +00002800 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002801 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002802 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002803 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002804 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002805 " AND sql NOT NULL");
2806 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002807 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002808 "WHERE sql NOT NULL"
2809 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002810 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002811 );
danielk1977bc6ada42004-06-30 08:20:16 +00002812 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002813 }
2814 }
drh45e29d82006-11-20 16:21:10 +00002815 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002816 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002817 p->writableSchema = 0;
2818 }
drh56197952011-10-13 16:30:13 +00002819 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2820 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002821 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002822 }else
drh75897232000-05-29 14:26:00 +00002823
drhc2ce0be2014-05-29 12:36:14 +00002824 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2825 if( nArg==2 ){
2826 p->echoOn = booleanValue(azArg[1]);
2827 }else{
2828 fprintf(stderr, "Usage: .echo on|off\n");
2829 rc = 1;
2830 }
drhdaffd0e2001-04-11 14:28:42 +00002831 }else
2832
drhc2ce0be2014-05-29 12:36:14 +00002833 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2834 if( nArg==2 ){
2835 p->autoEQP = booleanValue(azArg[1]);
2836 }else{
2837 fprintf(stderr, "Usage: .eqp on|off\n");
2838 rc = 1;
2839 }
drhefbf3b12014-02-28 20:47:24 +00002840 }else
2841
drhd3ac7d92013-01-25 18:33:43 +00002842 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002843 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002844 rc = 2;
drh75897232000-05-29 14:26:00 +00002845 }else
2846
drhc2ce0be2014-05-29 12:36:14 +00002847 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002848 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002849 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002850 if(!p->normalMode.valid) {
2851 p->normalMode.valid = 1;
2852 p->normalMode.mode = p->mode;
2853 p->normalMode.showHeader = p->showHeader;
2854 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002855 }
2856 /* We could put this code under the !p->explainValid
2857 ** condition so that it does not execute if we are already in
2858 ** explain mode. However, always executing it allows us an easy
2859 ** was to reset to explain mode in case the user previously
2860 ** did an .explain followed by a .width, .mode or .header
2861 ** command.
2862 */
danielk19770d78bae2008-01-03 07:09:48 +00002863 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002864 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002865 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002866 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002867 p->colWidth[1] = 13; /* opcode */
2868 p->colWidth[2] = 4; /* P1 */
2869 p->colWidth[3] = 4; /* P2 */
2870 p->colWidth[4] = 4; /* P3 */
2871 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002872 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002873 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002874 }else if (p->normalMode.valid) {
2875 p->normalMode.valid = 0;
2876 p->mode = p->normalMode.mode;
2877 p->showHeader = p->normalMode.showHeader;
2878 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002879 }
drh75897232000-05-29 14:26:00 +00002880 }else
2881
drhc1971542014-06-23 23:28:13 +00002882 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002883 ShellState data;
drhc1971542014-06-23 23:28:13 +00002884 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002885 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002886 if( nArg!=1 ){
2887 fprintf(stderr, "Usage: .fullschema\n");
2888 rc = 1;
2889 goto meta_command_exit;
2890 }
2891 open_db(p, 0);
2892 memcpy(&data, p, sizeof(data));
2893 data.showHeader = 0;
2894 data.mode = MODE_Semi;
2895 rc = sqlite3_exec(p->db,
2896 "SELECT sql FROM"
2897 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2898 " FROM sqlite_master UNION ALL"
2899 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002900 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002901 "ORDER BY rowid",
2902 callback, &data, &zErrMsg
2903 );
drh56f674c2014-07-18 14:43:29 +00002904 if( rc==SQLITE_OK ){
2905 sqlite3_stmt *pStmt;
2906 rc = sqlite3_prepare_v2(p->db,
2907 "SELECT rowid FROM sqlite_master"
2908 " WHERE name GLOB 'sqlite_stat[134]'",
2909 -1, &pStmt, 0);
2910 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2911 sqlite3_finalize(pStmt);
2912 }
2913 if( doStats==0 ){
2914 fprintf(p->out, "/* No STAT tables available */\n");
2915 }else{
2916 fprintf(p->out, "ANALYZE sqlite_master;\n");
2917 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2918 callback, &data, &zErrMsg);
2919 data.mode = MODE_Insert;
2920 data.zDestTable = "sqlite_stat1";
2921 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2922 shell_callback, &data,&zErrMsg);
2923 data.zDestTable = "sqlite_stat3";
2924 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2925 shell_callback, &data,&zErrMsg);
2926 data.zDestTable = "sqlite_stat4";
2927 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2928 shell_callback, &data, &zErrMsg);
2929 fprintf(p->out, "ANALYZE sqlite_master;\n");
2930 }
drhc1971542014-06-23 23:28:13 +00002931 }else
2932
drhc2ce0be2014-05-29 12:36:14 +00002933 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2934 if( nArg==2 ){
2935 p->showHeader = booleanValue(azArg[1]);
2936 }else{
2937 fprintf(stderr, "Usage: .headers on|off\n");
2938 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002939 }
drh75897232000-05-29 14:26:00 +00002940 }else
2941
drhc2ce0be2014-05-29 12:36:14 +00002942 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2943 fprintf(p->out, "%s", zHelp);
2944 }else
2945
2946 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002947 char *zTable; /* Insert data into this table */
2948 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002949 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002950 int nCol; /* Number of columns in the table */
2951 int nByte; /* Number of bytes in an SQL string */
2952 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002953 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002954 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002955 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002956 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00002957 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
2958 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00002959
drhc2ce0be2014-05-29 12:36:14 +00002960 if( nArg!=3 ){
2961 fprintf(stderr, "Usage: .import FILE TABLE\n");
2962 goto meta_command_exit;
2963 }
drh01f37542014-05-31 15:43:33 +00002964 zFile = azArg[1];
2965 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002966 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002967 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002968 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002969 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002970 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002971 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002972 return 1;
drhfeac5f82004-08-01 00:10:45 +00002973 }
drhdb95f682013-06-26 22:46:00 +00002974 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002975 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002976 " for import\n");
2977 return 1;
2978 }
mistachkin636bf9f2014-07-19 20:15:16 +00002979 nSep = strlen30(p->rowSeparator);
2980 if( nSep==0 ){
2981 fprintf(stderr, "Error: non-null row separator required for import\n");
2982 return 1;
2983 }
mistachkine0d68852014-12-11 03:12:33 +00002984 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2985 /* When importing CSV (only), if the row separator is set to the
2986 ** default output row separator, change it to the default input
2987 ** row separator. This avoids having to maintain different input
2988 ** and output row separators. */
2989 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2990 nSep = strlen30(p->rowSeparator);
2991 }
mistachkin636bf9f2014-07-19 20:15:16 +00002992 if( nSep>1 ){
2993 fprintf(stderr, "Error: multi-character row separators not allowed"
2994 " for import\n");
2995 return 1;
2996 }
2997 sCtx.zFile = zFile;
2998 sCtx.nLine = 1;
2999 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003000#ifdef SQLITE_OMIT_POPEN
mistachkinba132c72015-03-19 14:48:38 +00003001 fprintf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003002 return 1;
3003#else
mistachkin636bf9f2014-07-19 20:15:16 +00003004 sCtx.in = popen(sCtx.zFile+1, "r");
3005 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003006 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003007#endif
drh5bde8162013-06-27 14:07:53 +00003008 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003009 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003010 xCloser = fclose;
3011 }
mistachkin636bf9f2014-07-19 20:15:16 +00003012 if( p->mode==MODE_Ascii ){
3013 xRead = ascii_read_one_field;
3014 }else{
3015 xRead = csv_read_one_field;
3016 }
3017 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00003018 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003019 return 1;
3020 }
mistachkin636bf9f2014-07-19 20:15:16 +00003021 sCtx.cColSep = p->colSeparator[0];
3022 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003023 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003024 if( zSql==0 ){
3025 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003026 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003027 return 1;
3028 }
drh4f21c4a2008-12-10 22:15:00 +00003029 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003030 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003031 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003032 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003033 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3034 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003035 while( xRead(&sCtx) ){
3036 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003037 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003038 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003039 }
drh5bde8162013-06-27 14:07:53 +00003040 if( cSep=='(' ){
3041 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003042 sqlite3_free(sCtx.z);
3043 xCloser(sCtx.in);
3044 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003045 return 1;
3046 }
drhdb95f682013-06-26 22:46:00 +00003047 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3048 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3049 sqlite3_free(zCreate);
3050 if( rc ){
3051 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003052 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003053 sqlite3_free(sCtx.z);
3054 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003055 return 1;
3056 }
drhc7181902014-02-27 15:04:13 +00003057 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003058 }
drhfeac5f82004-08-01 00:10:45 +00003059 sqlite3_free(zSql);
3060 if( rc ){
shane916f9612009-10-23 00:37:15 +00003061 if (pStmt) sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003062 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003063 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003064 return 1;
drhfeac5f82004-08-01 00:10:45 +00003065 }
shane916f9612009-10-23 00:37:15 +00003066 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003067 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003068 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003069 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003070 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003071 if( zSql==0 ){
3072 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003073 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003074 return 1;
3075 }
drhdb95f682013-06-26 22:46:00 +00003076 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003077 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003078 for(i=1; i<nCol; i++){
3079 zSql[j++] = ',';
3080 zSql[j++] = '?';
3081 }
3082 zSql[j++] = ')';
3083 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003084 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003085 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003086 if( rc ){
mistachkin8e189222015-04-19 21:43:16 +00003087 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003088 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003089 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003090 return 1;
drhfeac5f82004-08-01 00:10:45 +00003091 }
mistachkin8e189222015-04-19 21:43:16 +00003092 needCommit = sqlite3_get_autocommit(p->db);
3093 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003094 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003095 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003096 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003097 char *z = xRead(&sCtx);
3098 /*
3099 ** Did we reach end-of-file before finding any columns?
3100 ** If so, stop instead of NULL filling the remaining columns.
3101 */
drhdb95f682013-06-26 22:46:00 +00003102 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003103 /*
3104 ** Did we reach end-of-file OR end-of-line before finding any
3105 ** columns in ASCII mode? If so, stop instead of NULL filling
3106 ** the remaining columns.
3107 */
3108 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003109 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003110 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003111 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3112 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003113 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003114 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003115 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003116 }
drhfeac5f82004-08-01 00:10:45 +00003117 }
mistachkin636bf9f2014-07-19 20:15:16 +00003118 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003119 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003120 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003121 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003122 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003123 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3124 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003125 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003126 }
drhdb95f682013-06-26 22:46:00 +00003127 if( i>=nCol ){
3128 sqlite3_step(pStmt);
3129 rc = sqlite3_reset(pStmt);
3130 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003131 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
mistachkin8e189222015-04-19 21:43:16 +00003132 sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003133 }
3134 }
mistachkin636bf9f2014-07-19 20:15:16 +00003135 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003136
mistachkin636bf9f2014-07-19 20:15:16 +00003137 xCloser(sCtx.in);
3138 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003139 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003140 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003141 }else
3142
drh0e55db12015-02-06 14:51:13 +00003143 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3144 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003145 ShellState data;
drh75897232000-05-29 14:26:00 +00003146 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003147 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003148 memcpy(&data, p, sizeof(data));
3149 data.showHeader = 0;
3150 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003151 if( nArg==1 ){
3152 rc = sqlite3_exec(p->db,
3153 "SELECT name FROM sqlite_master "
3154 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3155 "UNION ALL "
3156 "SELECT name FROM sqlite_temp_master "
3157 "WHERE type='index' "
3158 "ORDER BY 1",
3159 callback, &data, &zErrMsg
3160 );
drhc2ce0be2014-05-29 12:36:14 +00003161 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003162 zShellStatic = azArg[1];
3163 rc = sqlite3_exec(p->db,
3164 "SELECT name FROM sqlite_master "
3165 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3166 "UNION ALL "
3167 "SELECT name FROM sqlite_temp_master "
3168 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3169 "ORDER BY 1",
3170 callback, &data, &zErrMsg
3171 );
3172 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003173 }else{
drh0e55db12015-02-06 14:51:13 +00003174 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003175 rc = 1;
3176 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003177 }
drh75897232000-05-29 14:26:00 +00003178 if( zErrMsg ){
3179 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003180 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003181 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003182 }else if( rc != SQLITE_OK ){
3183 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3184 rc = 1;
drh75897232000-05-29 14:26:00 +00003185 }
3186 }else
3187
drhae5e4452007-05-03 17:18:36 +00003188#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003189 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003190 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003191 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3192 iotrace = 0;
3193 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003194 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003195 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003196 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003197 iotrace = stdout;
3198 }else{
3199 iotrace = fopen(azArg[1], "w");
3200 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003201 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003202 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003203 rc = 1;
drhb0603412007-02-28 04:47:26 +00003204 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003205 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003206 }
3207 }
3208 }else
drhae5e4452007-05-03 17:18:36 +00003209#endif
drh1a513372015-05-02 17:40:23 +00003210 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3211 static const struct {
3212 const char *zLimitName; /* Name of a limit */
3213 int limitCode; /* Integer code for that limit */
3214 } aLimit[] = {
3215 { "length", SQLITE_LIMIT_LENGTH },
3216 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3217 { "column", SQLITE_LIMIT_COLUMN },
3218 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3219 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3220 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3221 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3222 { "attached", SQLITE_LIMIT_ATTACHED },
3223 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3224 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3225 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3226 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3227 };
3228 int i, n2;
3229 open_db(p, 0);
3230 if( nArg==1 ){
3231 for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
3232 printf("%20s %d\n", aLimit[i].zLimitName,
3233 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3234 }
3235 }else if( nArg>3 ){
3236 fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
3237 rc = 1;
3238 goto meta_command_exit;
3239 }else{
3240 int iLimit = -1;
3241 n2 = strlen30(azArg[1]);
3242 for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
3243 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3244 if( iLimit<0 ){
3245 iLimit = i;
3246 }else{
3247 fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
3248 rc = 1;
3249 goto meta_command_exit;
3250 }
3251 }
3252 }
3253 if( iLimit<0 ){
3254 fprintf(stderr, "unknown limit: \"%s\"\n"
3255 "enter \".limits\" with no arguments for a list.\n",
3256 azArg[1]);
3257 rc = 1;
3258 goto meta_command_exit;
3259 }
3260 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003261 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3262 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003263 }
3264 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3265 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3266 }
3267 }else
drhb0603412007-02-28 04:47:26 +00003268
drh70df4fe2006-06-13 15:12:21 +00003269#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003270 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003271 const char *zFile, *zProc;
3272 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003273 if( nArg<2 ){
3274 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3275 rc = 1;
3276 goto meta_command_exit;
3277 }
drh1e397f82006-06-08 15:28:43 +00003278 zFile = azArg[1];
3279 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003280 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003281 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3282 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003283 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003284 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003285 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003286 }
3287 }else
drh70df4fe2006-06-13 15:12:21 +00003288#endif
drh1e397f82006-06-08 15:28:43 +00003289
drhc2ce0be2014-05-29 12:36:14 +00003290 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3291 if( nArg!=2 ){
3292 fprintf(stderr, "Usage: .log FILENAME\n");
3293 rc = 1;
3294 }else{
3295 const char *zFile = azArg[1];
3296 output_file_close(p->pLog);
3297 p->pLog = output_file_open(zFile);
3298 }
drh127f9d72010-02-23 01:47:00 +00003299 }else
3300
drhc2ce0be2014-05-29 12:36:14 +00003301 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3302 const char *zMode = nArg>=2 ? azArg[1] : "";
3303 int n2 = (int)strlen(zMode);
3304 int c2 = zMode[0];
3305 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003306 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003307 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003308 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003309 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003310 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003311 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003312 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003313 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003314 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003315 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003316 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003317 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003318 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003319 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003320 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003321 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003322 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003323 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003324 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003325 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003326 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3327 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003328 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3329 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003330 }else {
shane9bd1b442009-10-23 01:27:39 +00003331 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003332 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003333 rc = 1;
drh75897232000-05-29 14:26:00 +00003334 }
3335 }else
3336
drhc2ce0be2014-05-29 12:36:14 +00003337 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3338 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003339 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3340 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003341 }else{
3342 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003343 rc = 1;
3344 }
3345 }else
3346
drh05782482013-10-24 15:20:20 +00003347 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3348 sqlite3 *savedDb = p->db;
3349 const char *zSavedFilename = p->zDbFilename;
3350 char *zNewFilename = 0;
3351 p->db = 0;
3352 if( nArg>=2 ){
3353 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3354 }
3355 open_db(p, 1);
3356 if( p->db!=0 ){
3357 sqlite3_close(savedDb);
3358 sqlite3_free(p->zFreeOnClose);
3359 p->zFreeOnClose = zNewFilename;
3360 }else{
3361 sqlite3_free(zNewFilename);
3362 p->db = savedDb;
3363 p->zDbFilename = zSavedFilename;
3364 }
3365 }else
3366
drhc2ce0be2014-05-29 12:36:14 +00003367 if( c=='o'
3368 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3369 ){
3370 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3371 if( nArg>2 ){
3372 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3373 rc = 1;
3374 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003375 }
drhc2ce0be2014-05-29 12:36:14 +00003376 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3377 if( nArg<2 ){
3378 fprintf(stderr, "Usage: .once FILE\n");
3379 rc = 1;
3380 goto meta_command_exit;
3381 }
3382 p->outCount = 2;
3383 }else{
3384 p->outCount = 0;
3385 }
3386 output_reset(p);
3387 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003388#ifdef SQLITE_OMIT_POPEN
3389 fprintf(stderr,"Error: pipes are not supported in this OS\n");
3390 rc = 1;
3391 p->out = stdout;
3392#else
drhc2ce0be2014-05-29 12:36:14 +00003393 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003394 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003395 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003396 p->out = stdout;
3397 rc = 1;
3398 }else{
drhc2ce0be2014-05-29 12:36:14 +00003399 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003400 }
drh8cd5b252015-03-02 22:06:43 +00003401#endif
drh75897232000-05-29 14:26:00 +00003402 }else{
drhc2ce0be2014-05-29 12:36:14 +00003403 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003404 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003405 if( strcmp(zFile,"off")!=0 ){
3406 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003407 }
drh75897232000-05-29 14:26:00 +00003408 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003409 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003410 } else {
drhc2ce0be2014-05-29 12:36:14 +00003411 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003412 }
3413 }
3414 }else
3415
drh078b1fd2012-09-21 13:40:02 +00003416 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3417 int i;
3418 for(i=1; i<nArg; i++){
3419 if( i>1 ) fprintf(p->out, " ");
3420 fprintf(p->out, "%s", azArg[i]);
3421 }
3422 fprintf(p->out, "\n");
3423 }else
3424
drhc2ce0be2014-05-29 12:36:14 +00003425 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003426 if( nArg >= 2) {
3427 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3428 }
3429 if( nArg >= 3) {
3430 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3431 }
3432 }else
3433
drhc2ce0be2014-05-29 12:36:14 +00003434 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003435 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003436 }else
3437
drhc2ce0be2014-05-29 12:36:14 +00003438 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3439 FILE *alt;
3440 if( nArg!=2 ){
3441 fprintf(stderr, "Usage: .read FILE\n");
3442 rc = 1;
3443 goto meta_command_exit;
3444 }
3445 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003446 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003447 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3448 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003449 }else{
shane9bd1b442009-10-23 01:27:39 +00003450 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003451 fclose(alt);
3452 }
3453 }else
3454
drhc2ce0be2014-05-29 12:36:14 +00003455 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003456 const char *zSrcFile;
3457 const char *zDb;
3458 sqlite3 *pSrc;
3459 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003460 int nTimeout = 0;
3461
drh9ff849f2009-02-04 20:55:57 +00003462 if( nArg==2 ){
3463 zSrcFile = azArg[1];
3464 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003465 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003466 zSrcFile = azArg[2];
3467 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003468 }else{
3469 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3470 rc = 1;
3471 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003472 }
3473 rc = sqlite3_open(zSrcFile, &pSrc);
3474 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003475 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003476 sqlite3_close(pSrc);
3477 return 1;
3478 }
drh05782482013-10-24 15:20:20 +00003479 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003480 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3481 if( pBackup==0 ){
3482 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3483 sqlite3_close(pSrc);
3484 return 1;
3485 }
drhdc2c4912009-02-04 22:46:47 +00003486 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3487 || rc==SQLITE_BUSY ){
3488 if( rc==SQLITE_BUSY ){
3489 if( nTimeout++ >= 3 ) break;
3490 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003491 }
3492 }
3493 sqlite3_backup_finish(pBackup);
3494 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003495 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003496 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003497 fprintf(stderr, "Error: source database is busy\n");
3498 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003499 }else{
3500 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003501 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003502 }
3503 sqlite3_close(pSrc);
3504 }else
3505
dan8d1edb92014-11-05 09:07:28 +00003506
3507 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3508 if( nArg==2 ){
3509 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003510#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3511 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3512#endif
dan8d1edb92014-11-05 09:07:28 +00003513 }else{
3514 fprintf(stderr, "Usage: .scanstats on|off\n");
3515 rc = 1;
3516 }
3517 }else
3518
drhc2ce0be2014-05-29 12:36:14 +00003519 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003520 ShellState data;
drh75897232000-05-29 14:26:00 +00003521 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003522 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003523 memcpy(&data, p, sizeof(data));
3524 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003525 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003526 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003527 int i;
drhf0693c82011-10-11 20:41:54 +00003528 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003529 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003530 char *new_argv[2], *new_colv[2];
3531 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3532 " type text,\n"
3533 " name text,\n"
3534 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003535 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003536 " sql text\n"
3537 ")";
3538 new_argv[1] = 0;
3539 new_colv[0] = "sql";
3540 new_colv[1] = 0;
3541 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003542 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003543 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003544 char *new_argv[2], *new_colv[2];
3545 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3546 " type text,\n"
3547 " name text,\n"
3548 " tbl_name text,\n"
3549 " rootpage integer,\n"
3550 " sql text\n"
3551 ")";
3552 new_argv[1] = 0;
3553 new_colv[0] = "sql";
3554 new_colv[1] = 0;
3555 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003556 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003557 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003558 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003559 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003560 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003561 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003562 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003563 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003564 "WHERE lower(tbl_name) LIKE shellstatic()"
3565 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003566 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003567 callback, &data, &zErrMsg);
3568 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003569 }
drhc2ce0be2014-05-29 12:36:14 +00003570 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003571 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003572 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003573 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003574 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003575 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003576 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003577 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003578 callback, &data, &zErrMsg
3579 );
drhc2ce0be2014-05-29 12:36:14 +00003580 }else{
3581 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3582 rc = 1;
3583 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003584 }
drh75897232000-05-29 14:26:00 +00003585 if( zErrMsg ){
3586 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003587 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003588 rc = 1;
3589 }else if( rc != SQLITE_OK ){
3590 fprintf(stderr,"Error: querying schema information\n");
3591 rc = 1;
3592 }else{
3593 rc = 0;
drh75897232000-05-29 14:26:00 +00003594 }
3595 }else
3596
drhabd4c722014-09-20 18:18:33 +00003597
3598#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3599 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3600 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003601 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003602 }else
3603#endif
3604
3605
drh340f5822013-06-27 13:01:21 +00003606#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003607 /* Undocumented commands for internal testing. Subject to change
3608 ** without notice. */
3609 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3610 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3611 int i, v;
3612 for(i=1; i<nArg; i++){
3613 v = booleanValue(azArg[i]);
3614 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3615 }
3616 }
3617 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3618 int i; sqlite3_int64 v;
3619 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003620 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003621 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003622 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003623 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003624 }
3625 }
3626 }else
drh340f5822013-06-27 13:01:21 +00003627#endif
drh348d19c2013-06-03 12:47:43 +00003628
drhc2ce0be2014-05-29 12:36:14 +00003629 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003630 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003631 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003632 rc = 1;
3633 }
drh6976c212014-07-24 12:09:47 +00003634 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003635 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003636 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003637 }
3638 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003639 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3640 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003641 }
drh75897232000-05-29 14:26:00 +00003642 }else
3643
drh62cdde52014-05-28 20:22:28 +00003644 if( c=='s'
3645 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003646 ){
3647 char *zCmd;
drh54027102014-08-06 14:36:53 +00003648 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003649 if( nArg<2 ){
3650 fprintf(stderr, "Usage: .system COMMAND\n");
3651 rc = 1;
3652 goto meta_command_exit;
3653 }
drhdcb3e3d2014-05-29 03:17:29 +00003654 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003655 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003656 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3657 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003658 }
drh54027102014-08-06 14:36:53 +00003659 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003660 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003661 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003662 }else
3663
drhc2ce0be2014-05-29 12:36:14 +00003664 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003665 int i;
drhc2ce0be2014-05-29 12:36:14 +00003666 if( nArg!=1 ){
3667 fprintf(stderr, "Usage: .show\n");
3668 rc = 1;
3669 goto meta_command_exit;
3670 }
mistachkin636bf9f2014-07-19 20:15:16 +00003671 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3672 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003673 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003674 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3675 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3676 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003677 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003678 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003679 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003680 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003681 fprintf(p->out,"%12.12s: ", "colseparator");
3682 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003683 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003684 fprintf(p->out,"%12.12s: ", "rowseparator");
3685 output_c_string(p->out, p->rowSeparator);
3686 fprintf(p->out, "\n");
3687 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3688 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003689 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003690 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003691 }
drhfeac5f82004-08-01 00:10:45 +00003692 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003693 }else
3694
drhc2ce0be2014-05-29 12:36:14 +00003695 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3696 if( nArg==2 ){
3697 p->statsOn = booleanValue(azArg[1]);
3698 }else{
3699 fprintf(stderr, "Usage: .stats on|off\n");
3700 rc = 1;
3701 }
shaneh642d8b82010-07-28 16:05:34 +00003702 }else
3703
drhc2ce0be2014-05-29 12:36:14 +00003704 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003705 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003706 char **azResult;
drh98781232012-04-23 12:38:05 +00003707 int nRow, nAlloc;
3708 char *zSql = 0;
3709 int ii;
drh05782482013-10-24 15:20:20 +00003710 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003711 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3712 if( rc ) return rc;
3713 zSql = sqlite3_mprintf(
3714 "SELECT name FROM sqlite_master"
3715 " WHERE type IN ('table','view')"
3716 " AND name NOT LIKE 'sqlite_%%'"
3717 " AND name LIKE ?1");
3718 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3719 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3720 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3721 if( strcmp(zDbName,"temp")==0 ){
3722 zSql = sqlite3_mprintf(
3723 "%z UNION ALL "
3724 "SELECT 'temp.' || name FROM sqlite_temp_master"
3725 " WHERE type IN ('table','view')"
3726 " AND name NOT LIKE 'sqlite_%%'"
3727 " AND name LIKE ?1", zSql);
3728 }else{
3729 zSql = sqlite3_mprintf(
3730 "%z UNION ALL "
3731 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3732 " WHERE type IN ('table','view')"
3733 " AND name NOT LIKE 'sqlite_%%'"
3734 " AND name LIKE ?1", zSql, zDbName, zDbName);
3735 }
drha50da102000-08-08 20:19:09 +00003736 }
drh98781232012-04-23 12:38:05 +00003737 sqlite3_finalize(pStmt);
3738 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3739 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3740 sqlite3_free(zSql);
3741 if( rc ) return rc;
3742 nRow = nAlloc = 0;
3743 azResult = 0;
3744 if( nArg>1 ){
3745 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003746 }else{
drh98781232012-04-23 12:38:05 +00003747 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3748 }
3749 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3750 if( nRow>=nAlloc ){
3751 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00003752 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00003753 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00003754 if( azNew==0 ){
3755 fprintf(stderr, "Error: out of memory\n");
3756 break;
3757 }
mistachkin8e189222015-04-19 21:43:16 +00003758 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00003759 azResult = azNew;
3760 }
3761 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3762 if( azResult[nRow] ) nRow++;
3763 }
3764 sqlite3_finalize(pStmt);
3765 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003766 int len, maxlen = 0;
3767 int i, j;
3768 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003769 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003770 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003771 if( len>maxlen ) maxlen = len;
3772 }
3773 nPrintCol = 80/(maxlen+2);
3774 if( nPrintCol<1 ) nPrintCol = 1;
3775 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3776 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003777 for(j=i; j<nRow; j+=nPrintRow){
3778 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003779 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003780 }
drh151b7d52013-05-06 20:28:54 +00003781 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003782 }
3783 }
drh98781232012-04-23 12:38:05 +00003784 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3785 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003786 }else
3787
shaneh96887e12011-02-10 21:08:58 +00003788 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003789 static const struct {
3790 const char *zCtrlName; /* Name of a test-control option */
3791 int ctrlCode; /* Integer code for that option */
3792 } aCtrl[] = {
3793 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3794 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3795 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3796 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3797 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3798 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3799 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3800 { "assert", SQLITE_TESTCTRL_ASSERT },
3801 { "always", SQLITE_TESTCTRL_ALWAYS },
3802 { "reserve", SQLITE_TESTCTRL_RESERVE },
3803 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3804 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003805 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003806 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003807 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003808 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003809 };
shaneh96887e12011-02-10 21:08:58 +00003810 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00003811 int rc2 = 0;
3812 int i, n2;
drh05782482013-10-24 15:20:20 +00003813 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003814
drhd416fe72011-03-17 16:45:50 +00003815 /* convert testctrl text option to value. allow any unique prefix
3816 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00003817 n2 = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003818 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
mistachkin8e189222015-04-19 21:43:16 +00003819 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00003820 if( testctrl<0 ){
3821 testctrl = aCtrl[i].ctrlCode;
3822 }else{
drhb07028f2011-10-14 21:49:18 +00003823 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003824 testctrl = -1;
3825 break;
3826 }
3827 }
3828 }
drh348d19c2013-06-03 12:47:43 +00003829 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003830 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3831 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3832 }else{
3833 switch(testctrl){
3834
3835 /* sqlite3_test_control(int, db, int) */
3836 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3837 case SQLITE_TESTCTRL_RESERVE:
3838 if( nArg==3 ){
3839 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00003840 rc2 = sqlite3_test_control(testctrl, p->db, opt);
3841 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003842 } else {
drhd416fe72011-03-17 16:45:50 +00003843 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3844 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003845 }
3846 break;
3847
3848 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003849 case SQLITE_TESTCTRL_PRNG_SAVE:
3850 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003851 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003852 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003853 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00003854 rc2 = sqlite3_test_control(testctrl);
3855 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003856 } else {
3857 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3858 }
3859 break;
3860
3861 /* sqlite3_test_control(int, uint) */
3862 case SQLITE_TESTCTRL_PENDING_BYTE:
3863 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003864 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003865 rc2 = sqlite3_test_control(testctrl, opt);
3866 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003867 } else {
drhd416fe72011-03-17 16:45:50 +00003868 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3869 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003870 }
3871 break;
3872
3873 /* sqlite3_test_control(int, int) */
3874 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003875 case SQLITE_TESTCTRL_ALWAYS:
3876 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003877 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003878 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003879 rc2 = sqlite3_test_control(testctrl, opt);
3880 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003881 } else {
drhd416fe72011-03-17 16:45:50 +00003882 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3883 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003884 }
3885 break;
3886
3887 /* sqlite3_test_control(int, char *) */
3888#ifdef SQLITE_N_KEYWORD
3889 case SQLITE_TESTCTRL_ISKEYWORD:
3890 if( nArg==3 ){
3891 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00003892 rc2 = sqlite3_test_control(testctrl, opt);
3893 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003894 } else {
drhd416fe72011-03-17 16:45:50 +00003895 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3896 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003897 }
3898 break;
3899#endif
3900
drh1ffede82015-01-30 20:59:27 +00003901 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003902 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00003903 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003904 azArg[2],
drh8964b342015-01-29 17:54:52 +00003905 integerValue(azArg[3]),
3906 integerValue(azArg[4]));
mistachkin8e189222015-04-19 21:43:16 +00003907 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00003908 }else{
drh6f5a37a2015-03-27 02:27:20 +00003909 fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003910 }
3911 break;
3912
shaneh96887e12011-02-10 21:08:58 +00003913 case SQLITE_TESTCTRL_BITVEC_TEST:
3914 case SQLITE_TESTCTRL_FAULT_INSTALL:
3915 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3916 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3917 default:
drhd416fe72011-03-17 16:45:50 +00003918 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3919 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003920 break;
3921 }
3922 }
3923 }else
3924
drhc2ce0be2014-05-29 12:36:14 +00003925 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003926 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003927 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003928 }else
3929
drhc2ce0be2014-05-29 12:36:14 +00003930 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3931 if( nArg==2 ){
3932 enableTimer = booleanValue(azArg[1]);
3933 if( enableTimer && !HAS_TIMER ){
3934 fprintf(stderr, "Error: timer not available on this system.\n");
3935 enableTimer = 0;
3936 }
3937 }else{
3938 fprintf(stderr, "Usage: .timer on|off\n");
3939 rc = 1;
3940 }
shanehe2aa9d72009-11-06 17:20:17 +00003941 }else
3942
drhc2ce0be2014-05-29 12:36:14 +00003943 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003944 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003945 if( nArg!=2 ){
3946 fprintf(stderr, "Usage: .trace FILE|off\n");
3947 rc = 1;
3948 goto meta_command_exit;
3949 }
drh657b4a82015-03-19 13:30:41 +00003950 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00003951 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003952#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003953 if( p->traceOut==0 ){
3954 sqlite3_trace(p->db, 0, 0);
3955 }else{
3956 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3957 }
3958#endif
3959 }else
3960
drhf442e332014-09-10 19:01:14 +00003961#if SQLITE_USER_AUTHENTICATION
3962 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3963 if( nArg<2 ){
3964 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3965 rc = 1;
3966 goto meta_command_exit;
3967 }
drh7883ecf2014-09-11 16:19:31 +00003968 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003969 if( strcmp(azArg[1],"login")==0 ){
3970 if( nArg!=4 ){
3971 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3972 rc = 1;
3973 goto meta_command_exit;
3974 }
drhd39c40f2014-09-11 00:27:53 +00003975 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3976 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003977 if( rc ){
3978 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3979 rc = 1;
3980 }
3981 }else if( strcmp(azArg[1],"add")==0 ){
3982 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003983 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003984 rc = 1;
3985 goto meta_command_exit;
3986 }
drhd39c40f2014-09-11 00:27:53 +00003987 rc = sqlite3_user_add(p->db, azArg[2],
3988 azArg[3], (int)strlen(azArg[3]),
3989 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003990 if( rc ){
3991 fprintf(stderr, "User-Add failed: %d\n", rc);
3992 rc = 1;
3993 }
3994 }else if( strcmp(azArg[1],"edit")==0 ){
3995 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003996 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003997 rc = 1;
3998 goto meta_command_exit;
3999 }
drhd39c40f2014-09-11 00:27:53 +00004000 rc = sqlite3_user_change(p->db, azArg[2],
4001 azArg[3], (int)strlen(azArg[3]),
4002 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004003 if( rc ){
4004 fprintf(stderr, "User-Edit failed: %d\n", rc);
4005 rc = 1;
4006 }
4007 }else if( strcmp(azArg[1],"delete")==0 ){
4008 if( nArg!=3 ){
4009 fprintf(stderr, "Usage: .user delete USER\n");
4010 rc = 1;
4011 goto meta_command_exit;
4012 }
4013 rc = sqlite3_user_delete(p->db, azArg[2]);
4014 if( rc ){
4015 fprintf(stderr, "User-Delete failed: %d\n", rc);
4016 rc = 1;
4017 }
4018 }else{
4019 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
4020 rc = 1;
4021 goto meta_command_exit;
4022 }
4023 }else
4024#endif /* SQLITE_USER_AUTHENTICATION */
4025
drh9fd301b2011-06-03 13:28:22 +00004026 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00004027 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004028 sqlite3_libversion(), sqlite3_sourceid());
4029 }else
4030
drhde60fc22011-12-14 17:53:36 +00004031 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4032 const char *zDbName = nArg==2 ? azArg[1] : "main";
4033 char *zVfsName = 0;
4034 if( p->db ){
4035 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4036 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00004037 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004038 sqlite3_free(zVfsName);
4039 }
4040 }
4041 }else
4042
drhcef4fc82012-09-21 22:50:45 +00004043#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4044 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4045 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004046 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004047 }else
4048#endif
4049
drhc2ce0be2014-05-29 12:36:14 +00004050 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004051 int j;
drh43617e92006-03-06 20:55:46 +00004052 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004053 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004054 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004055 }
4056 }else
4057
4058 {
shane9bd1b442009-10-23 01:27:39 +00004059 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004060 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004061 rc = 1;
drh75897232000-05-29 14:26:00 +00004062 }
drh67505e72002-04-19 12:34:06 +00004063
drhc2ce0be2014-05-29 12:36:14 +00004064meta_command_exit:
4065 if( p->outCount ){
4066 p->outCount--;
4067 if( p->outCount==0 ) output_reset(p);
4068 }
drh67505e72002-04-19 12:34:06 +00004069 return rc;
drh75897232000-05-29 14:26:00 +00004070}
4071
drh67505e72002-04-19 12:34:06 +00004072/*
drh91a66392007-09-07 01:12:32 +00004073** Return TRUE if a semicolon occurs anywhere in the first N characters
4074** of string z[].
drh324ccef2003-02-05 14:06:20 +00004075*/
drh9f099fd2013-08-06 14:01:46 +00004076static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004077 int i;
4078 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4079 return 0;
drh324ccef2003-02-05 14:06:20 +00004080}
4081
4082/*
drh70c7a4b2003-04-26 03:03:06 +00004083** Test to see if a line consists entirely of whitespace.
4084*/
4085static int _all_whitespace(const char *z){
4086 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004087 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004088 if( *z=='/' && z[1]=='*' ){
4089 z += 2;
4090 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4091 if( *z==0 ) return 0;
4092 z++;
4093 continue;
4094 }
4095 if( *z=='-' && z[1]=='-' ){
4096 z += 2;
4097 while( *z && *z!='\n' ){ z++; }
4098 if( *z==0 ) return 1;
4099 continue;
4100 }
4101 return 0;
4102 }
4103 return 1;
4104}
4105
4106/*
drha9b17162003-04-29 18:01:28 +00004107** Return TRUE if the line typed in is an SQL command terminator other
4108** than a semi-colon. The SQL Server style "go" command is understood
4109** as is the Oracle "/".
4110*/
drh9f099fd2013-08-06 14:01:46 +00004111static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004112 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004113 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4114 return 1; /* Oracle */
4115 }
drhf0693c82011-10-11 20:41:54 +00004116 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004117 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004118 return 1; /* SQL Server */
4119 }
4120 return 0;
4121}
4122
4123/*
drh233a5312008-12-18 22:25:13 +00004124** Return true if zSql is a complete SQL statement. Return false if it
4125** ends in the middle of a string literal or C-style comment.
4126*/
drh9f099fd2013-08-06 14:01:46 +00004127static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004128 int rc;
4129 if( zSql==0 ) return 1;
4130 zSql[nSql] = ';';
4131 zSql[nSql+1] = 0;
4132 rc = sqlite3_complete(zSql);
4133 zSql[nSql] = 0;
4134 return rc;
4135}
4136
4137/*
drh67505e72002-04-19 12:34:06 +00004138** Read input from *in and process it. If *in==0 then input
4139** is interactive - the user is typing it it. Otherwise, input
4140** is coming from a file or device. A prompt is issued and history
4141** is saved only if input is interactive. An interrupt signal will
4142** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004143**
4144** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004145*/
drhdcd87a92014-08-18 13:45:42 +00004146static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004147 char *zLine = 0; /* A single input line */
4148 char *zSql = 0; /* Accumulated SQL text */
4149 int nLine; /* Length of current line */
4150 int nSql = 0; /* Bytes of zSql[] used */
4151 int nAlloc = 0; /* Allocated zSql[] space */
4152 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4153 char *zErrMsg; /* Error message returned */
4154 int rc; /* Error code */
4155 int errCnt = 0; /* Number of errors seen */
4156 int lineno = 0; /* Current line number */
4157 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004158
4159 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4160 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004161 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004162 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004163 /* End of input */
4164 if( stdin_is_interactive ) printf("\n");
4165 break;
drhc49f44e2006-10-26 18:15:42 +00004166 }
drh67505e72002-04-19 12:34:06 +00004167 if( seenInterrupt ){
4168 if( in!=0 ) break;
4169 seenInterrupt = 0;
4170 }
drhc28490c2006-10-26 14:25:58 +00004171 lineno++;
drh849a9d92013-12-21 15:46:06 +00004172 if( nSql==0 && _all_whitespace(zLine) ){
4173 if( p->echoOn ) printf("%s\n", zLine);
4174 continue;
4175 }
drh2af0b2d2002-02-21 02:25:02 +00004176 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004177 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004178 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004179 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004180 break;
4181 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004182 errCnt++;
4183 }
drhdaffd0e2001-04-11 14:28:42 +00004184 continue;
4185 }
drh9f099fd2013-08-06 14:01:46 +00004186 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004187 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004188 }
drh9f099fd2013-08-06 14:01:46 +00004189 nLine = strlen30(zLine);
4190 if( nSql+nLine+2>=nAlloc ){
4191 nAlloc = nSql+nLine+100;
4192 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004193 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004194 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004195 exit(1);
4196 }
drhdaffd0e2001-04-11 14:28:42 +00004197 }
drh9f099fd2013-08-06 14:01:46 +00004198 nSqlPrior = nSql;
4199 if( nSql==0 ){
4200 int i;
4201 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004202 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004203 memcpy(zSql, zLine+i, nLine+1-i);
4204 startline = lineno;
4205 nSql = nLine-i;
4206 }else{
4207 zSql[nSql++] = '\n';
4208 memcpy(zSql+nSql, zLine, nLine+1);
4209 nSql += nLine;
4210 }
4211 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004212 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004213 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004214 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004215 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004216 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004217 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004218 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004219 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004220 char zPrefix[100];
4221 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004222 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004223 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004224 }else{
shane9bd1b442009-10-23 01:27:39 +00004225 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004226 }
drh7f953e22002-07-13 17:33:45 +00004227 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004228 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004229 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004230 zErrMsg = 0;
4231 }else{
shaned2bed1c2009-10-21 03:56:54 +00004232 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004233 }
drhc49f44e2006-10-26 18:15:42 +00004234 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004235 }
drhdaffd0e2001-04-11 14:28:42 +00004236 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004237 if( p->outCount ){
4238 output_reset(p);
4239 p->outCount = 0;
4240 }
drh9f099fd2013-08-06 14:01:46 +00004241 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004242 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004243 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004244 }
4245 }
drh9f099fd2013-08-06 14:01:46 +00004246 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004247 if( !_all_whitespace(zSql) ){
4248 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004249 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004250 }
drhdaffd0e2001-04-11 14:28:42 +00004251 free(zSql);
4252 }
danielk19772ac27622007-07-03 05:31:16 +00004253 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004254 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004255}
4256
drh67505e72002-04-19 12:34:06 +00004257/*
4258** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004259** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004260*/
4261static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004262 static char *home_dir = NULL;
4263 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004264
drh4ace5362014-11-10 14:42:28 +00004265#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4266 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004267 {
4268 struct passwd *pwent;
4269 uid_t uid = getuid();
4270 if( (pwent=getpwuid(uid)) != NULL) {
4271 home_dir = pwent->pw_dir;
4272 }
drh67505e72002-04-19 12:34:06 +00004273 }
4274#endif
4275
chw65d3c132007-11-12 21:09:10 +00004276#if defined(_WIN32_WCE)
4277 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4278 */
drh85e72432012-04-11 11:38:53 +00004279 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004280#else
4281
drh83905c92012-06-21 13:00:37 +00004282#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004283 if (!home_dir) {
4284 home_dir = getenv("USERPROFILE");
4285 }
4286#endif
4287
drh67505e72002-04-19 12:34:06 +00004288 if (!home_dir) {
4289 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004290 }
4291
drh83905c92012-06-21 13:00:37 +00004292#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004293 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004294 char *zDrive, *zPath;
4295 int n;
4296 zDrive = getenv("HOMEDRIVE");
4297 zPath = getenv("HOMEPATH");
4298 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004299 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004300 home_dir = malloc( n );
4301 if( home_dir==0 ) return 0;
4302 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4303 return home_dir;
4304 }
4305 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004306 }
4307#endif
4308
chw65d3c132007-11-12 21:09:10 +00004309#endif /* !_WIN32_WCE */
4310
drh67505e72002-04-19 12:34:06 +00004311 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004312 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004313 char *z = malloc( n );
4314 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004315 home_dir = z;
4316 }
drhe98d4fa2002-04-21 19:06:22 +00004317
drh67505e72002-04-19 12:34:06 +00004318 return home_dir;
4319}
4320
4321/*
4322** Read input from the file given by sqliterc_override. Or if that
4323** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004324**
4325** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004326*/
drh534f4df2015-02-28 14:03:35 +00004327static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004328 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004329 const char *sqliterc_override /* Name of config file. NULL to use default */
4330){
persicom7e2dfdd2002-04-18 02:46:52 +00004331 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004332 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004333 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004334 FILE *in = NULL;
4335
4336 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004337 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004338 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004339 fprintf(stderr, "-- warning: cannot find home directory;"
4340 " cannot read ~/.sqliterc\n");
4341 return;
drhe98d4fa2002-04-21 19:06:22 +00004342 }
drh2f3de322012-06-27 16:41:31 +00004343 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004344 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4345 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004346 }
drha1f9b5e2004-02-14 16:31:02 +00004347 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004348 if( in ){
drhc28490c2006-10-26 14:25:58 +00004349 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004350 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004351 }
drh534f4df2015-02-28 14:03:35 +00004352 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004353 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004354 }
drh85e72432012-04-11 11:38:53 +00004355 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004356}
4357
drh67505e72002-04-19 12:34:06 +00004358/*
drhe1e38c42003-05-04 18:30:59 +00004359** Show available command line options
4360*/
4361static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004362 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004363 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004364 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004365 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004366 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004367 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004368 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004369 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004370 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004371#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4372 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4373#endif
drhcc3b4f82012-02-07 14:13:50 +00004374 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004375 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004376 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004377 " -line set output mode to 'line'\n"
4378 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004379 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004380 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004381#ifdef SQLITE_ENABLE_MULTIPLEX
4382 " -multiplex enable the multiplexor VFS\n"
4383#endif
mistachkine0d68852014-12-11 03:12:33 +00004384 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004385 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004386 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4387 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004388 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004389 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004390 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004391 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004392#ifdef SQLITE_ENABLE_VFSTRACE
4393 " -vfstrace enable tracing of all VFS calls\n"
4394#endif
drhe1e38c42003-05-04 18:30:59 +00004395;
4396static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004397 fprintf(stderr,
4398 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4399 "FILENAME is the name of an SQLite database. A new database is created\n"
4400 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004401 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004402 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004403 }else{
4404 fprintf(stderr, "Use the -help option for additional information\n");
4405 }
4406 exit(1);
4407}
4408
4409/*
drh67505e72002-04-19 12:34:06 +00004410** Initialize the state information in data
4411*/
drhdcd87a92014-08-18 13:45:42 +00004412static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004413 memset(data, 0, sizeof(*data));
4414 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004415 memcpy(data->colSeparator,SEP_Column, 2);
4416 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004417 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004418 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004419 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004420 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004421 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004422 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4423 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004424}
4425
drh98d312f2012-10-25 15:23:14 +00004426/*
drh5c7976f2014-02-10 19:59:27 +00004427** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004428*/
4429#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004430static void printBold(const char *zText){
4431 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4432 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4433 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4434 SetConsoleTextAttribute(out,
4435 FOREGROUND_RED|FOREGROUND_INTENSITY
4436 );
4437 printf("%s", zText);
4438 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004439}
4440#else
drh5c7976f2014-02-10 19:59:27 +00004441static void printBold(const char *zText){
4442 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004443}
4444#endif
4445
4446/*
drh98d312f2012-10-25 15:23:14 +00004447** Get the argument to an --option. Throw an error and die if no argument
4448** is available.
4449*/
4450static char *cmdline_option_value(int argc, char **argv, int i){
4451 if( i==argc ){
4452 fprintf(stderr, "%s: Error: missing argument to %s\n",
4453 argv[0], argv[argc-1]);
4454 exit(1);
4455 }
4456 return argv[i];
4457}
4458
mistachkin44723ce2015-03-21 02:22:37 +00004459int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004460 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004461 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004462 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004463 int i;
drhc28490c2006-10-26 14:25:58 +00004464 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004465 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004466 int readStdin = 1;
4467 int nCmd = 0;
4468 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004469
drh69b30ab2014-02-27 15:11:52 +00004470#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004471 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4472 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4473 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4474 exit(1);
4475 }
drhc7181902014-02-27 15:04:13 +00004476#endif
drh047d4532015-01-18 20:30:23 +00004477 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004478 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004479 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004480 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004481 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004482
drh44c2eb12003-04-30 11:38:26 +00004483 /* Make sure we have a valid signal handler early, before anything
4484 ** else is done.
4485 */
drh4c504392000-10-16 22:06:40 +00004486#ifdef SIGINT
4487 signal(SIGINT, interrupt_handler);
4488#endif
drh44c2eb12003-04-30 11:38:26 +00004489
drhac5649a2014-11-28 13:35:03 +00004490#ifdef SQLITE_SHELL_DBNAME_PROC
4491 {
4492 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4493 ** of a C-function that will provide the name of the database file. Use
4494 ** this compile-time option to embed this shell program in larger
4495 ** applications. */
4496 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4497 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4498 warnInmemoryDb = 0;
4499 }
4500#endif
4501
drh22fbcb82004-02-01 01:22:50 +00004502 /* Do an initial pass through the command-line argument to locate
4503 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004504 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004505 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004506 */
drh98d312f2012-10-25 15:23:14 +00004507 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004508 char *z;
drhc28490c2006-10-26 14:25:58 +00004509 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004510 if( z[0]!='-' ){
4511 if( data.zDbFilename==0 ){
4512 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004513 }else{
4514 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4515 ** mean that nothing is read from stdin */
4516 readStdin = 0;
4517 nCmd++;
4518 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4519 if( azCmd==0 ){
4520 fprintf(stderr, "out of memory\n");
4521 exit(1);
4522 }
4523 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004524 }
drh98d312f2012-10-25 15:23:14 +00004525 }
drhcc3b4f82012-02-07 14:13:50 +00004526 if( z[1]=='-' ) z++;
4527 if( strcmp(z,"-separator")==0
4528 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004529 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004530 || strcmp(z,"-cmd")==0
4531 ){
drh98d312f2012-10-25 15:23:14 +00004532 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004533 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004534 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004535 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004536 /* Need to check for batch mode here to so we can avoid printing
4537 ** informational messages (like from process_sqliterc) before
4538 ** we do the actual processing of arguments later in a second pass.
4539 */
shanef69573d2009-10-24 02:06:14 +00004540 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004541 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004542#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004543 const char *zSize;
4544 sqlite3_int64 szHeap;
4545
drh98d312f2012-10-25 15:23:14 +00004546 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004547 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004548 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004549 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4550#endif
drh44dec872014-08-30 15:49:25 +00004551 }else if( strcmp(z,"-scratch")==0 ){
4552 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004553 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004554 if( sz>400000 ) sz = 400000;
4555 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004556 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004557 if( n>10 ) n = 10;
4558 if( n<1 ) n = 1;
4559 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4560 data.shellFlgs |= SHFLG_Scratch;
4561 }else if( strcmp(z,"-pagecache")==0 ){
4562 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004563 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004564 if( sz>70000 ) sz = 70000;
4565 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004566 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004567 if( n<10 ) n = 10;
4568 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4569 data.shellFlgs |= SHFLG_Pagecache;
4570 }else if( strcmp(z,"-lookaside")==0 ){
4571 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004572 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004573 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004574 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004575 if( n<0 ) n = 0;
4576 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4577 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004578#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004579 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004580 extern int vfstrace_register(
4581 const char *zTraceName,
4582 const char *zOldVfsName,
4583 int (*xOut)(const char*,void*),
4584 void *pOutArg,
4585 int makeDefault
4586 );
drh2b625e22011-03-16 17:05:28 +00004587 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004588#endif
drh6f25e892011-07-08 17:02:57 +00004589#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004590 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004591 extern int sqlite3_multiple_initialize(const char*,int);
4592 sqlite3_multiplex_initialize(0, 1);
4593#endif
drh7d9f3942013-04-03 01:26:54 +00004594 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004595 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4596 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004597 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004598 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004599 if( pVfs ){
4600 sqlite3_vfs_register(pVfs, 1);
4601 }else{
4602 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4603 exit(1);
4604 }
drh44c2eb12003-04-30 11:38:26 +00004605 }
4606 }
drh98d312f2012-10-25 15:23:14 +00004607 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004608#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004609 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004610 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004611#else
shane86f5bdb2009-10-24 02:00:07 +00004612 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4613 return 1;
drh01b41712005-08-29 23:06:23 +00004614#endif
drh98d312f2012-10-25 15:23:14 +00004615 }
4616 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004617
drh44c2eb12003-04-30 11:38:26 +00004618 /* Go ahead and open the database file if it already exists. If the
4619 ** file does not exist, delay opening it. This prevents empty database
4620 ** files from being created if a user mistypes the database name argument
4621 ** to the sqlite command-line tool.
4622 */
drhc8d74412004-08-31 23:41:26 +00004623 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004624 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004625 }
4626
drh22fbcb82004-02-01 01:22:50 +00004627 /* Process the initialization file if there is one. If no -init option
4628 ** is given on the command line, look for a file named ~/.sqliterc and
4629 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004630 */
drh534f4df2015-02-28 14:03:35 +00004631 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004632
drh22fbcb82004-02-01 01:22:50 +00004633 /* Make a second pass through the command-line argument and set
4634 ** options. This second pass is delayed until after the initialization
4635 ** file is processed so that the command-line arguments will override
4636 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004637 */
drh98d312f2012-10-25 15:23:14 +00004638 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004639 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004640 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004641 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004642 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004643 i++;
4644 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004645 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004646 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004647 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004648 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004649 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004650 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004651 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004652 }else if( strcmp(z,"-csv")==0 ){
4653 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004654 memcpy(data.colSeparator,",",2);
4655 }else if( strcmp(z,"-ascii")==0 ){
4656 data.mode = MODE_Ascii;
4657 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004658 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004659 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004660 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004661 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004662 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4663 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004664 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004665 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004666 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004667 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004668 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004669 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004670 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004671 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004672 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004673 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004674 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004675 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004676 }else if( strcmp(z,"-eqp")==0 ){
4677 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004678 }else if( strcmp(z,"-stats")==0 ){
4679 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004680 }else if( strcmp(z,"-scanstats")==0 ){
4681 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004682 }else if( strcmp(z,"-backslash")==0 ){
4683 /* Undocumented command-line option: -backslash
4684 ** Causes C-style backslash escapes to be evaluated in SQL statements
4685 ** prior to sending the SQL into SQLite. Useful for injecting
4686 ** crazy bytes in the middle of SQL statements for testing and debugging.
4687 */
4688 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004689 }else if( strcmp(z,"-bail")==0 ){
4690 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004691 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004692 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004693 return 0;
drhc28490c2006-10-26 14:25:58 +00004694 }else if( strcmp(z,"-interactive")==0 ){
4695 stdin_is_interactive = 1;
4696 }else if( strcmp(z,"-batch")==0 ){
4697 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004698 }else if( strcmp(z,"-heap")==0 ){
4699 i++;
drh44dec872014-08-30 15:49:25 +00004700 }else if( strcmp(z,"-scratch")==0 ){
4701 i+=2;
4702 }else if( strcmp(z,"-pagecache")==0 ){
4703 i+=2;
4704 }else if( strcmp(z,"-lookaside")==0 ){
4705 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004706 }else if( strcmp(z,"-mmap")==0 ){
4707 i++;
drha7e61d82011-03-12 17:02:57 +00004708 }else if( strcmp(z,"-vfs")==0 ){
4709 i++;
drh6f25e892011-07-08 17:02:57 +00004710#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004711 }else if( strcmp(z,"-vfstrace")==0 ){
4712 i++;
drh6f25e892011-07-08 17:02:57 +00004713#endif
4714#ifdef SQLITE_ENABLE_MULTIPLEX
4715 }else if( strcmp(z,"-multiplex")==0 ){
4716 i++;
4717#endif
drhcc3b4f82012-02-07 14:13:50 +00004718 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004719 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004720 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004721 /* Run commands that follow -cmd first and separately from commands
4722 ** that simply appear on the command-line. This seems goofy. It would
4723 ** be better if all commands ran in the order that they appear. But
4724 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004725 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004726 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004727 if( z[0]=='.' ){
4728 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004729 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004730 }else{
drh05782482013-10-24 15:20:20 +00004731 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004732 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4733 if( zErrMsg!=0 ){
4734 fprintf(stderr,"Error: %s\n", zErrMsg);
4735 if( bail_on_error ) return rc!=0 ? rc : 1;
4736 }else if( rc!=0 ){
4737 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4738 if( bail_on_error ) return rc;
4739 }
4740 }
drh1e5d0e92000-05-31 23:33:17 +00004741 }else{
shane86f5bdb2009-10-24 02:00:07 +00004742 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004743 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004744 return 1;
4745 }
4746 }
drh44c2eb12003-04-30 11:38:26 +00004747
drhac5649a2014-11-28 13:35:03 +00004748 if( !readStdin ){
4749 /* Run all arguments that do not begin with '-' as if they were separate
4750 ** command-line inputs, except for the argToSkip argument which contains
4751 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004752 */
drhac5649a2014-11-28 13:35:03 +00004753 for(i=0; i<nCmd; i++){
4754 if( azCmd[i][0]=='.' ){
4755 rc = do_meta_command(azCmd[i], &data);
4756 if( rc ) return rc==2 ? 0 : rc;
4757 }else{
4758 open_db(&data, 0);
4759 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4760 if( zErrMsg!=0 ){
4761 fprintf(stderr,"Error: %s\n", zErrMsg);
4762 return rc!=0 ? rc : 1;
4763 }else if( rc!=0 ){
4764 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4765 return rc;
4766 }
drh6ff13852001-11-25 13:18:23 +00004767 }
drh75897232000-05-29 14:26:00 +00004768 }
drhac5649a2014-11-28 13:35:03 +00004769 free(azCmd);
drh75897232000-05-29 14:26:00 +00004770 }else{
drh44c2eb12003-04-30 11:38:26 +00004771 /* Run commands received from standard input
4772 */
drhc28490c2006-10-26 14:25:58 +00004773 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004774 char *zHome;
4775 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004776 int nHistory;
drh75897232000-05-29 14:26:00 +00004777 printf(
drh743e0032011-12-12 16:51:50 +00004778 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004779 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004780 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004781 );
drhb3735912014-02-10 16:13:42 +00004782 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004783 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004784 printBold("transient in-memory database");
4785 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004786 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004787 }
drh67505e72002-04-19 12:34:06 +00004788 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004789 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004790 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004791 if( (zHistory = malloc(nHistory))!=0 ){
4792 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4793 }
drh67505e72002-04-19 12:34:06 +00004794 }
danfd34d6d2015-02-25 10:54:53 +00004795 if( zHistory ) shell_read_history(zHistory);
drhc28490c2006-10-26 14:25:58 +00004796 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004797 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004798 shell_stifle_history(100);
4799 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004800 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004801 }
drhdaffd0e2001-04-11 14:28:42 +00004802 }else{
drhc28490c2006-10-26 14:25:58 +00004803 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004804 }
4805 }
drh33048c02001-10-01 14:29:22 +00004806 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004807 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004808 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004809 }
drh05782482013-10-24 15:20:20 +00004810 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004811 return rc;
drh75897232000-05-29 14:26:00 +00004812}