blob: c45c95e8f187dca5b40bf15601e25b5b87fb6346 [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/*
drh36f7dd32011-10-13 16:02:17 +000028** Enable large-file support for fopen() and friends on unix.
29*/
30#ifndef SQLITE_DISABLE_LFS
31# define _LARGE_FILE 1
32# ifndef _FILE_OFFSET_BITS
33# define _FILE_OFFSET_BITS 64
34# endif
35# define _LARGEFILE_SOURCE 1
36#endif
37
drh75897232000-05-29 14:26:00 +000038#include <stdlib.h>
39#include <string.h>
40#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000041#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000042#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000043#if SQLITE_USER_AUTHENTICATION
44# include "sqlite3userauth.h"
45#endif
drh75897232000-05-29 14:26:00 +000046#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000047#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000048
drh83905c92012-06-21 13:00:37 +000049#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000050# include <signal.h>
chw97185482008-11-17 08:05:31 +000051# if !defined(__RTP__) && !defined(_WRS_KERNEL)
52# include <pwd.h>
53# endif
drhdd45df82002-04-18 12:39:03 +000054# include <unistd.h>
55# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000056#endif
drh75897232000-05-29 14:26:00 +000057
drh0ede9eb2015-01-10 16:49:23 +000058#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000059# include <readline/readline.h>
60# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000061#endif
danfd34d6d2015-02-25 10:54:53 +000062
drh0ede9eb2015-01-10 16:49:23 +000063#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000064# include <editline/readline.h>
65#endif
danfd34d6d2015-02-25 10:54:53 +000066
67#if HAVE_EDITLINE || HAVE_READLINE
68
69# define shell_add_history(X) add_history(X)
70# define shell_read_history(X) read_history(X)
71# define shell_write_history(X) write_history(X)
72# define shell_stifle_history(X) stifle_history(X)
73# define shell_readline(X) readline(X)
74
75#elif HAVE_LINENOISE
76
77# include "linenoise.h"
78# define shell_add_history(X) linenoiseHistoryAdd(X)
79# define shell_read_history(X) linenoiseHistoryLoad(X)
80# define shell_write_history(X) linenoiseHistorySave(X)
81# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
82# define shell_readline(X) linenoise(X)
83
84#else
85
86# define shell_read_history(X)
87# define shell_write_history(X)
88# define shell_stifle_history(X)
89
90# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000091#endif
92
danfd34d6d2015-02-25 10:54:53 +000093
adamd2e8464a2006-09-06 21:39:40 +000094#if defined(_WIN32) || defined(WIN32)
95# include <io.h>
drh6976c212014-07-24 12:09:47 +000096# include <fcntl.h>
shane18e526c2008-12-10 22:30:24 +000097#define isatty(h) _isatty(h)
drh07901eb2014-02-28 19:37:45 +000098#ifndef access
99# define access(f,m) _access((f),(m))
100#endif
drh67ceaa62012-08-27 21:19:03 +0000101#undef popen
drh53371f92013-07-25 17:07:03 +0000102#define popen _popen
drh67ceaa62012-08-27 21:19:03 +0000103#undef pclose
drh12cd6cf2013-06-29 15:40:22 +0000104#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000105#else
drh4328c8b2003-04-26 02:50:11 +0000106/* Make sure isatty() has a prototype.
107*/
drhb2acc3b2011-10-13 16:36:29 +0000108extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000109
drh53371f92013-07-25 17:07:03 +0000110/* popen and pclose are not C89 functions and so are sometimes omitted from
111** the <stdio.h> header */
mistachkinf6418892013-08-28 01:54:12 +0000112extern FILE *popen(const char*,const char*);
113extern int pclose(FILE*);
114#endif
drh53371f92013-07-25 17:07:03 +0000115
chw65d3c132007-11-12 21:09:10 +0000116#if defined(_WIN32_WCE)
117/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
118 * thus we always assume that we have a console. That can be
119 * overridden with the -batch command line option.
120 */
121#define isatty(x) 1
122#endif
123
drhf0693c82011-10-11 20:41:54 +0000124/* ctype macros that work with signed characters */
125#define IsSpace(X) isspace((unsigned char)X)
126#define IsDigit(X) isdigit((unsigned char)X)
127#define ToLower(X) (char)tolower((unsigned char)X)
128
drh047d4532015-01-18 20:30:23 +0000129/* On Windows, we normally run with output mode of TEXT so that \n characters
130** are automatically translated into \r\n. However, this behavior needs
131** to be disabled in some cases (ex: when generating CSV output and when
132** rendering quoted strings that contain \n characters). The following
133** routines take care of that.
134*/
135#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000136static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000137 fflush(out);
138 _setmode(_fileno(out), _O_BINARY);
139}
mistachkine4a0d792015-01-27 21:24:33 +0000140static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000141 fflush(out);
142 _setmode(_fileno(out), _O_TEXT);
143}
144#else
145# define setBinaryMode(X)
146# define setTextMode(X)
147#endif
148
drh43408312013-10-30 12:43:36 +0000149
150/* True if the timer is enabled */
151static int enableTimer = 0;
152
153/* Return the current wall-clock time */
154static sqlite3_int64 timeOfDay(void){
155 static sqlite3_vfs *clockVfs = 0;
156 sqlite3_int64 t;
157 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
158 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
159 clockVfs->xCurrentTimeInt64(clockVfs, &t);
160 }else{
161 double r;
162 clockVfs->xCurrentTime(clockVfs, &r);
163 t = (sqlite3_int64)(r*86400000.0);
164 }
165 return t;
166}
167
drhd5d0f642013-02-20 00:54:21 +0000168#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
169 && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000170#include <sys/time.h>
171#include <sys/resource.h>
172
drhda108222009-02-25 19:07:24 +0000173/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000174static struct rusage sBegin; /* CPU time at start */
175static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000176
drhda108222009-02-25 19:07:24 +0000177/*
178** Begin timing an operation
179*/
180static void beginTimer(void){
181 if( enableTimer ){
182 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000183 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000184 }
185}
186
187/* Return the difference of two time_structs in seconds */
188static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
189 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
190 (double)(pEnd->tv_sec - pStart->tv_sec);
191}
192
193/*
194** Print the timing results.
195*/
196static void endTimer(void){
197 if( enableTimer ){
198 struct rusage sEnd;
drh43408312013-10-30 12:43:36 +0000199 sqlite3_int64 iEnd = timeOfDay();
drhda108222009-02-25 19:07:24 +0000200 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000201 printf("Run Time: real %.3f user %f sys %f\n",
202 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000203 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
204 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
205 }
206}
shaneb320ccd2009-10-21 03:42:58 +0000207
drhda108222009-02-25 19:07:24 +0000208#define BEGIN_TIMER beginTimer()
209#define END_TIMER endTimer()
210#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000211
212#elif (defined(_WIN32) || defined(WIN32))
213
214#include <windows.h>
215
216/* Saved resource information for the beginning of an operation */
217static HANDLE hProcess;
218static FILETIME ftKernelBegin;
219static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000220static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000221typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
222 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000223static GETPROCTIMES getProcessTimesAddr = NULL;
224
shaneb320ccd2009-10-21 03:42:58 +0000225/*
226** Check to see if we have timer support. Return 1 if necessary
227** support found (or found previously).
228*/
229static int hasTimer(void){
230 if( getProcessTimesAddr ){
231 return 1;
232 } else {
drh4ace5362014-11-10 14:42:28 +0000233 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
234 ** versions. See if the version we are running on has it, and if it
235 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000236 */
237 hProcess = GetCurrentProcess();
238 if( hProcess ){
239 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
240 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000241 getProcessTimesAddr =
242 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000243 if( NULL != getProcessTimesAddr ){
244 return 1;
245 }
246 FreeLibrary(hinstLib);
247 }
248 }
249 }
250 return 0;
251}
252
253/*
254** Begin timing an operation
255*/
256static void beginTimer(void){
257 if( enableTimer && getProcessTimesAddr ){
258 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000259 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
260 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000261 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000262 }
263}
264
265/* Return the difference of two FILETIME structs in seconds */
266static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
267 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
268 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
269 return (double) ((i64End - i64Start) / 10000000.0);
270}
271
272/*
273** Print the timing results.
274*/
275static void endTimer(void){
276 if( enableTimer && getProcessTimesAddr){
277 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000278 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000279 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000280 printf("Run Time: real %.3f user %f sys %f\n",
281 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000282 timeDiff(&ftUserBegin, &ftUserEnd),
283 timeDiff(&ftKernelBegin, &ftKernelEnd));
284 }
285}
286
287#define BEGIN_TIMER beginTimer()
288#define END_TIMER endTimer()
289#define HAS_TIMER hasTimer()
290
drhda108222009-02-25 19:07:24 +0000291#else
292#define BEGIN_TIMER
293#define END_TIMER
294#define HAS_TIMER 0
295#endif
296
shanec0688ea2009-03-05 03:48:06 +0000297/*
298** Used to prevent warnings about unused parameters
299*/
300#define UNUSED_PARAMETER(x) (void)(x)
301
drhe91d16b2008-12-08 18:27:31 +0000302/*
drhc49f44e2006-10-26 18:15:42 +0000303** If the following flag is set, then command execution stops
304** at an error if we are not interactive.
305*/
306static int bail_on_error = 0;
307
308/*
drhc28490c2006-10-26 14:25:58 +0000309** Threat stdin as an interactive input if the following variable
310** is true. Otherwise, assume stdin is connected to a file or pipe.
311*/
312static int stdin_is_interactive = 1;
313
314/*
drh4c504392000-10-16 22:06:40 +0000315** The following is the open SQLite database. We make a pointer
316** to this database a static variable so that it can be accessed
317** by the SIGINT handler to interrupt database processing.
318*/
danielk197792f9a1b2004-06-19 09:08:16 +0000319static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000320
321/*
drh67505e72002-04-19 12:34:06 +0000322** True if an interrupt (Control-C) has been received.
323*/
drh43617e92006-03-06 20:55:46 +0000324static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000325
326/*
persicom7e2dfdd2002-04-18 02:46:52 +0000327** This is the name of our program. It is set in main(), used
328** in a number of other places, mostly for error messages.
329*/
330static char *Argv0;
331
332/*
333** Prompt strings. Initialized in main. Settable with
334** .prompt main continue
335*/
336static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
337static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
338
drhb0603412007-02-28 04:47:26 +0000339/*
340** Write I/O traces to the following stream.
341*/
rsebe0a9092007-07-30 18:24:38 +0000342#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000343static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000344#endif
drhb0603412007-02-28 04:47:26 +0000345
346/*
347** This routine works like printf in that its first argument is a
348** format string and subsequent arguments are values to be substituted
349** in place of % fields. The result of formatting this string
350** is written to iotrace.
351*/
rsebe0a9092007-07-30 18:24:38 +0000352#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000353static void iotracePrintf(const char *zFormat, ...){
354 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000355 char *z;
drhb0603412007-02-28 04:47:26 +0000356 if( iotrace==0 ) return;
357 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000358 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000359 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000360 fprintf(iotrace, "%s", z);
361 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000362}
rsebe0a9092007-07-30 18:24:38 +0000363#endif
drhb0603412007-02-28 04:47:26 +0000364
drh44c2eb12003-04-30 11:38:26 +0000365
persicom7e2dfdd2002-04-18 02:46:52 +0000366/*
drh83965662003-04-17 02:54:13 +0000367** Determines if a string is a number of not.
368*/
danielk19772e588c72005-12-09 14:25:08 +0000369static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000370 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000371 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000372 return 0;
373 }
374 z++;
375 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000376 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000377 if( *z=='.' ){
378 z++;
drhf0693c82011-10-11 20:41:54 +0000379 if( !IsDigit(*z) ) return 0;
380 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000381 if( realnum ) *realnum = 1;
382 }
383 if( *z=='e' || *z=='E' ){
384 z++;
385 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000386 if( !IsDigit(*z) ) return 0;
387 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000388 if( realnum ) *realnum = 1;
389 }
390 return *z==0;
391}
drh83965662003-04-17 02:54:13 +0000392
393/*
danielk1977bc6ada42004-06-30 08:20:16 +0000394** A global char* and an SQL function to access its current value
395** from within an SQL statement. This program used to use the
396** sqlite_exec_printf() API to substitue a string into an SQL statement.
397** The correct way to do this with sqlite3 is to use the bind API, but
398** since the shell is built around the callback paradigm it would be a lot
399** of work. Instead just use this hack, which is quite harmless.
400*/
401static const char *zShellStatic = 0;
402static void shellstaticFunc(
403 sqlite3_context *context,
404 int argc,
405 sqlite3_value **argv
406){
407 assert( 0==argc );
408 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000409 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000410 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000411 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
412}
413
414
415/*
drhfeac5f82004-08-01 00:10:45 +0000416** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000417** the text in memory obtained from malloc() and returns a pointer
418** to the text. NULL is returned at end of file, or if malloc()
419** fails.
420**
drh9f099fd2013-08-06 14:01:46 +0000421** If zLine is not NULL then it is a malloced buffer returned from
422** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000423*/
drh9f099fd2013-08-06 14:01:46 +0000424static char *local_getline(char *zLine, FILE *in){
425 int nLine = zLine==0 ? 0 : 100;
426 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000427
drhb07028f2011-10-14 21:49:18 +0000428 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000429 if( n+100>nLine ){
430 nLine = nLine*2 + 100;
431 zLine = realloc(zLine, nLine);
432 if( zLine==0 ) return 0;
433 }
drhdaffd0e2001-04-11 14:28:42 +0000434 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000435 if( n==0 ){
436 free(zLine);
437 return 0;
438 }
439 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000440 break;
441 }
drh9f099fd2013-08-06 14:01:46 +0000442 while( zLine[n] ) n++;
443 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000444 n--;
shaneh13b36022009-12-17 21:07:15 +0000445 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000446 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000447 break;
drh8e7e7a22000-05-30 18:45:23 +0000448 }
449 }
drh8e7e7a22000-05-30 18:45:23 +0000450 return zLine;
451}
452
453/*
drhc28490c2006-10-26 14:25:58 +0000454** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000455**
drh9f099fd2013-08-06 14:01:46 +0000456** If in==0 then read from standard input and prompt before each line.
457** If isContinuation is true, then a continuation prompt is appropriate.
458** If isContinuation is zero, then the main prompt should be used.
459**
460** If zPrior is not NULL then it is a buffer from a prior call to this
461** routine that can be reused.
462**
463** The result is stored in space obtained from malloc() and must either
464** be freed by the caller or else passed back into this routine via the
465** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000466*/
drh9f099fd2013-08-06 14:01:46 +0000467static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000468 char *zPrompt;
469 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000470 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000471 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000472 }else{
drh9f099fd2013-08-06 14:01:46 +0000473 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000474#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000475 printf("%s", zPrompt);
476 fflush(stdout);
477 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000478#else
479 free(zPrior);
480 zResult = shell_readline(zPrompt);
481 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000482#endif
drh9f099fd2013-08-06 14:01:46 +0000483 }
drh8e7e7a22000-05-30 18:45:23 +0000484 return zResult;
485}
486
drhdcd87a92014-08-18 13:45:42 +0000487/*
488** Shell output mode information from before ".explain on",
489** saved so that it can be restored by ".explain off"
490*/
491typedef struct SavedModeInfo SavedModeInfo;
492struct SavedModeInfo {
493 int valid; /* Is there legit data in here? */
494 int mode; /* Mode prior to ".explain on" */
495 int showHeader; /* The ".header" setting prior to ".explain on" */
496 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000497};
drh45e29d82006-11-20 16:21:10 +0000498
drh8e7e7a22000-05-30 18:45:23 +0000499/*
drhdcd87a92014-08-18 13:45:42 +0000500** State information about the database connection is contained in an
501** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000502*/
drhdcd87a92014-08-18 13:45:42 +0000503typedef struct ShellState ShellState;
504struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000505 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000506 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000507 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000508 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000509 int scanstatsOn; /* True to display scan stats before each finalize */
drhc2ce0be2014-05-29 12:36:14 +0000510 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000511 int cnt; /* Number of records displayed so far */
512 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000513 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000514 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000515 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000516 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000517 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000518 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000519 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000520 char colSeparator[20]; /* Column separator character for several modes */
521 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000522 int colWidth[100]; /* Requested width of each column when in column mode*/
523 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000524 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000525 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000526 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000527 char outfile[FILENAME_MAX]; /* Filename for *out */
528 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000529 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000530 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000531 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000532 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000533 int *aiIndent; /* Array of indents used in MODE_Explain */
534 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000535 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000536};
537
538/*
drh44dec872014-08-30 15:49:25 +0000539** These are the allowed shellFlgs values
540*/
541#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
542#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
543#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
544
545/*
drh75897232000-05-29 14:26:00 +0000546** These are the allowed modes.
547*/
drh967e8b72000-06-21 13:59:10 +0000548#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000549#define MODE_Column 1 /* One record per line in neat columns */
550#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000551#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
552#define MODE_Html 4 /* Generate an XHTML table */
553#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000554#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000555#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000556#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000557#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000558
drh66ce4d02008-02-15 17:38:06 +0000559static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000560 "line",
561 "column",
562 "list",
563 "semi",
564 "html",
drhfeac5f82004-08-01 00:10:45 +0000565 "insert",
566 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000567 "csv",
drh66ce4d02008-02-15 17:38:06 +0000568 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000569 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000570};
drh75897232000-05-29 14:26:00 +0000571
572/*
mistachkinfad42082014-07-24 22:13:12 +0000573** These are the column/row/line separators used by the various
574** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000575*/
mistachkinfad42082014-07-24 22:13:12 +0000576#define SEP_Column "|"
577#define SEP_Row "\n"
578#define SEP_Tab "\t"
579#define SEP_Space " "
580#define SEP_Comma ","
581#define SEP_CrLf "\r\n"
582#define SEP_Unit "\x1F"
583#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000584
585/*
drh75897232000-05-29 14:26:00 +0000586** Number of elements in an array
587*/
drh902b9ee2008-12-05 17:17:07 +0000588#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000589
590/*
drhea678832008-12-10 19:26:22 +0000591** Compute a string length that is limited to what can be stored in
592** lower 30 bits of a 32-bit signed integer.
593*/
drh4f21c4a2008-12-10 22:15:00 +0000594static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000595 const char *z2 = z;
596 while( *z2 ){ z2++; }
597 return 0x3fffffff & (int)(z2 - z);
598}
599
600/*
drh127f9d72010-02-23 01:47:00 +0000601** A callback for the sqlite3_log() interface.
602*/
603static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000604 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000605 if( p->pLog==0 ) return;
606 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
607 fflush(p->pLog);
608}
609
610/*
shane626a6e42009-10-22 17:30:15 +0000611** Output the given string as a hex-encoded blob (eg. X'1234' )
612*/
613static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
614 int i;
615 char *zBlob = (char *)pBlob;
616 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000617 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000618 fprintf(out,"'");
619}
620
621/*
drh28bd4bc2000-06-15 15:57:22 +0000622** Output the given string as a quoted string using SQL quoting conventions.
623*/
624static void output_quoted_string(FILE *out, const char *z){
625 int i;
626 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000627 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000628 for(i=0; z[i]; i++){
629 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000630 }
631 if( nSingle==0 ){
632 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000633 }else{
634 fprintf(out,"'");
635 while( *z ){
636 for(i=0; z[i] && z[i]!='\''; i++){}
637 if( i==0 ){
638 fprintf(out,"''");
639 z++;
640 }else if( z[i]=='\'' ){
641 fprintf(out,"%.*s''",i,z);
642 z += i+1;
643 }else{
drhcd7d2732002-02-26 23:24:26 +0000644 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000645 break;
646 }
647 }
drhcd7d2732002-02-26 23:24:26 +0000648 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000649 }
drh047d4532015-01-18 20:30:23 +0000650 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000651}
652
653/*
drhfeac5f82004-08-01 00:10:45 +0000654** Output the given string as a quoted according to C or TCL quoting rules.
655*/
656static void output_c_string(FILE *out, const char *z){
657 unsigned int c;
658 fputc('"', out);
659 while( (c = *(z++))!=0 ){
660 if( c=='\\' ){
661 fputc(c, out);
662 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000663 }else if( c=='"' ){
664 fputc('\\', out);
665 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000666 }else if( c=='\t' ){
667 fputc('\\', out);
668 fputc('t', out);
669 }else if( c=='\n' ){
670 fputc('\\', out);
671 fputc('n', out);
672 }else if( c=='\r' ){
673 fputc('\\', out);
674 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000675 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000676 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000677 }else{
678 fputc(c, out);
679 }
680 }
681 fputc('"', out);
682}
683
684/*
drhc08a4f12000-06-15 16:49:48 +0000685** Output the given string with characters that are special to
686** HTML escaped.
687*/
688static void output_html_string(FILE *out, const char *z){
689 int i;
drhc3d6ba42014-01-13 20:38:35 +0000690 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000691 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000692 for(i=0; z[i]
693 && z[i]!='<'
694 && z[i]!='&'
695 && z[i]!='>'
696 && z[i]!='\"'
697 && z[i]!='\'';
698 i++){}
drhc08a4f12000-06-15 16:49:48 +0000699 if( i>0 ){
700 fprintf(out,"%.*s",i,z);
701 }
702 if( z[i]=='<' ){
703 fprintf(out,"&lt;");
704 }else if( z[i]=='&' ){
705 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000706 }else if( z[i]=='>' ){
707 fprintf(out,"&gt;");
708 }else if( z[i]=='\"' ){
709 fprintf(out,"&quot;");
710 }else if( z[i]=='\'' ){
711 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000712 }else{
713 break;
714 }
715 z += i + 1;
716 }
717}
718
719/*
drhc49f44e2006-10-26 18:15:42 +0000720** If a field contains any character identified by a 1 in the following
721** array, then the string must be quoted for CSV.
722*/
723static const char needCsvQuote[] = {
724 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
725 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
726 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
727 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
728 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
729 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
730 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
731 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
732 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
733 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
734 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
735 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
736 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
737 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
738 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
739 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
740};
741
742/*
mistachkindd11f2d2014-12-11 04:49:46 +0000743** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000744** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000745** the null value. Strings are quoted if necessary. The separator
746** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000747*/
drhdcd87a92014-08-18 13:45:42 +0000748static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000749 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000750 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000751 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000752 }else{
drhc49f44e2006-10-26 18:15:42 +0000753 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000754 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000755 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000756 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000757 || (z[i]==p->colSeparator[0] &&
758 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000759 i = 0;
760 break;
761 }
762 }
763 if( i==0 ){
764 putc('"', out);
765 for(i=0; z[i]; i++){
766 if( z[i]=='"' ) putc('"', out);
767 putc(z[i], out);
768 }
769 putc('"', out);
770 }else{
771 fprintf(out, "%s", z);
772 }
drh8e64d1c2004-10-07 00:32:39 +0000773 }
774 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000775 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000776 }
777}
778
danielk19774af00c62005-01-23 23:43:21 +0000779#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000780/*
drh4c504392000-10-16 22:06:40 +0000781** This routine runs when the user presses Ctrl-C
782*/
783static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000784 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000785 seenInterrupt++;
786 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000787 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000788}
danielk19774af00c62005-01-23 23:43:21 +0000789#endif
drh4c504392000-10-16 22:06:40 +0000790
791/*
drh536a4092015-02-26 14:27:16 +0000792** Return the length of a string in characters. Multibyte UTF8 characters
793** count as a single character.
794*/
795static int strlenChar(const char *z){
796 int n = 0;
797 while( *z ){
798 if( (0xc0&*(z++))!=0x80 ) n++;
799 }
800 return n;
801}
802
803/*
804** Print abs(w) characters of string "z" on FILE "out".
805**
806** w is in units of characters, not bytes!
807**
808** The output is always exactly abs(w) characters wide. If z contains
809** more than abs(w) characters, it is truncated. If z contains fewer
810** than abs(w) characters it is padded with spaces. Spaces are added
811** on the right if w>0 (left justification) or on the left if w<0
812** (right justification).
813*/
814static void outputFixedWidth(FILE *out, int w, const char *z){
815 int n = strlenChar(z);
816 int absw = w<0 ? -w : w;
817 int i;
818
819 if( n<=absw ){
820 if( w<0 ) for(i=absw-n; i>0; i--) putc(' ', out);
821 fputs(z, out);
822 if( w>0 ) for(i=absw-n; i>0; i--) putc(' ', out);
823 }else{
824 for(i=n=0; z[i]; i++){
825 if( (z[i]&0xc0)==0x80 ) continue;
826 if( n==absw ) break;
827 n++;
828 }
829 fwrite(z, 1, i, out);
830 }
831}
832
833/*
shane626a6e42009-10-22 17:30:15 +0000834** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000835** invokes for each row of a query result.
836*/
drh4ace5362014-11-10 14:42:28 +0000837static int shell_callback(
838 void *pArg,
839 int nArg, /* Number of result columns */
840 char **azArg, /* Text of each result column */
841 char **azCol, /* Column names */
842 int *aiType /* Column types */
843){
drh75897232000-05-29 14:26:00 +0000844 int i;
drhdcd87a92014-08-18 13:45:42 +0000845 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000846
drh75897232000-05-29 14:26:00 +0000847 switch( p->mode ){
848 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000849 int w = 5;
drh6a535342001-10-19 16:44:56 +0000850 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000851 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000852 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000853 if( len>w ) w = len;
854 }
mistachkin636bf9f2014-07-19 20:15:16 +0000855 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000856 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000857 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000858 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000859 }
860 break;
861 }
danielk19770d78bae2008-01-03 07:09:48 +0000862 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000863 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000864 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000865 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000866 int w, n;
867 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000868 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000869 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000870 w = 0;
drh75897232000-05-29 14:26:00 +0000871 }
drh078b1fd2012-09-21 13:40:02 +0000872 if( w==0 ){
drh536a4092015-02-26 14:27:16 +0000873 w = strlenChar(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000874 if( w<10 ) w = 10;
drh536a4092015-02-26 14:27:16 +0000875 n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000876 if( w<n ) w = n;
877 }
878 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000879 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000880 }
881 if( p->showHeader ){
drh536a4092015-02-26 14:27:16 +0000882 outputFixedWidth(p->out, w, azCol[i]);
883 fprintf(p->out, "%s", i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000884 }
885 }
886 if( p->showHeader ){
887 for(i=0; i<nArg; i++){
888 int w;
889 if( i<ArraySize(p->actualWidth) ){
890 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000891 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000892 }else{
893 w = 10;
894 }
895 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
896 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000897 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000898 }
drh75897232000-05-29 14:26:00 +0000899 }
900 }
drh6a535342001-10-19 16:44:56 +0000901 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000902 for(i=0; i<nArg; i++){
903 int w;
drha0c66f52000-07-29 13:20:21 +0000904 if( i<ArraySize(p->actualWidth) ){
905 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000906 }else{
907 w = 10;
908 }
dana98bf362013-11-13 18:35:01 +0000909 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh536a4092015-02-26 14:27:16 +0000910 w = strlenChar(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000911 }
dana98bf362013-11-13 18:35:01 +0000912 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000913 if( p->iIndent<p->nIndent ){
914 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000915 }
danc4650bb2013-11-18 08:41:06 +0000916 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000917 }
drh536a4092015-02-26 14:27:16 +0000918 outputFixedWidth(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
919 fprintf(p->out, "%s", i==nArg-1 ? p->rowSeparator : " ");
drh75897232000-05-29 14:26:00 +0000920 }
921 break;
922 }
drhe3710332000-09-29 13:30:53 +0000923 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000924 case MODE_List: {
925 if( p->cnt++==0 && p->showHeader ){
926 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000927 fprintf(p->out,"%s%s",azCol[i],
928 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000929 }
930 }
drh6a535342001-10-19 16:44:56 +0000931 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000932 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000933 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000934 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000935 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000936 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000937 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000938 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000939 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000940 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000941 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000942 }
drh75897232000-05-29 14:26:00 +0000943 }
944 break;
945 }
drh1e5d0e92000-05-31 23:33:17 +0000946 case MODE_Html: {
947 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000948 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000949 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000950 fprintf(p->out,"<TH>");
951 output_html_string(p->out, azCol[i]);
952 fprintf(p->out,"</TH>\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 }
drh6a535342001-10-19 16:44:56 +0000956 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000957 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000958 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000959 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000960 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000961 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000962 }
mihailim57c591a2008-06-23 21:26:05 +0000963 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000964 break;
965 }
drhfeac5f82004-08-01 00:10:45 +0000966 case MODE_Tcl: {
967 if( p->cnt++==0 && p->showHeader ){
968 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000969 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000970 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000971 }
mistachkin636bf9f2014-07-19 20:15:16 +0000972 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000973 }
974 if( azArg==0 ) break;
975 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000976 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000977 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000978 }
mistachkin636bf9f2014-07-19 20:15:16 +0000979 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000980 break;
981 }
drh8e64d1c2004-10-07 00:32:39 +0000982 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000983 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000984 if( p->cnt++==0 && p->showHeader ){
985 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000986 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000987 }
mistachkine0d68852014-12-11 03:12:33 +0000988 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000989 }
drh40253262014-10-17 21:35:05 +0000990 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000991 for(i=0; i<nArg; i++){
992 output_csv(p, azArg[i], i<nArg-1);
993 }
mistachkine0d68852014-12-11 03:12:33 +0000994 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000995 }
drh047d4532015-01-18 20:30:23 +0000996 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000997 break;
998 }
drh28bd4bc2000-06-15 15:57:22 +0000999 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001000 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001001 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +00001002 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
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));
1203 char *zErrMsg = sqlite3_malloc(nErrMsg);
1204 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;
1440 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1441 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1442 }
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);
1558 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1559 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"
drh4bbcf102014-02-06 02:46:08 +00001784 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001785 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001786 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001787 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001788 " If TABLE specified, only dump tables matching\n"
1789 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001790 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001791 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001792 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001793 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001794 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001795 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001796 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001797 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001798 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001799 ".indexes ?TABLE? Show names of all indexes\n"
1800 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001801 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001802#ifdef SQLITE_ENABLE_IOTRACE
1803 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1804#endif
drh70df4fe2006-06-13 15:12:21 +00001805#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001806 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001807#endif
drh127f9d72010-02-23 01:47:00 +00001808 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001809 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001810 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001811 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001812 " column Left-aligned columns. (See .width)\n"
1813 " html HTML <table> code\n"
1814 " insert SQL insert statements for TABLE\n"
1815 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001816 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001817 " tabs Tab-separated values\n"
1818 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001819 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001820 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001821 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001822 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001823 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001824 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001825 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001826 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001827 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001828 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001829 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001830 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001831 " If TABLE specified, only show tables matching\n"
1832 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001833 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1834 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001835 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001836 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001837 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001838 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001839 ".tables ?TABLE? List names of tables\n"
1840 " If TABLE specified, only list tables matching\n"
1841 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001842 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001843 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001844 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001845 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001846 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001847 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001848;
1849
drhdaffd0e2001-04-11 14:28:42 +00001850/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001851static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001852/*
1853** Implementation of the "readfile(X)" SQL function. The entire content
1854** of the file named X is read and returned as a BLOB. NULL is returned
1855** if the file does not exist or is unreadable.
1856*/
1857static void readfileFunc(
1858 sqlite3_context *context,
1859 int argc,
1860 sqlite3_value **argv
1861){
1862 const char *zName;
1863 FILE *in;
1864 long nIn;
1865 void *pBuf;
1866
1867 zName = (const char*)sqlite3_value_text(argv[0]);
1868 if( zName==0 ) return;
1869 in = fopen(zName, "rb");
1870 if( in==0 ) return;
1871 fseek(in, 0, SEEK_END);
1872 nIn = ftell(in);
1873 rewind(in);
1874 pBuf = sqlite3_malloc( nIn );
1875 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1876 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1877 }else{
1878 sqlite3_free(pBuf);
1879 }
1880 fclose(in);
1881}
1882
1883/*
1884** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1885** is written into file X. The number of bytes written is returned. Or
1886** NULL is returned if something goes wrong, such as being unable to open
1887** file X for writing.
1888*/
1889static void writefileFunc(
1890 sqlite3_context *context,
1891 int argc,
1892 sqlite3_value **argv
1893){
1894 FILE *out;
1895 const char *z;
drhba5b0932014-07-24 12:39:59 +00001896 sqlite3_int64 rc;
1897 const char *zFile;
1898
1899 zFile = (const char*)sqlite3_value_text(argv[0]);
1900 if( zFile==0 ) return;
1901 out = fopen(zFile, "wb");
1902 if( out==0 ) return;
1903 z = (const char*)sqlite3_value_blob(argv[1]);
1904 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001905 rc = 0;
1906 }else{
drh490fe862014-08-11 14:21:32 +00001907 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001908 }
1909 fclose(out);
1910 sqlite3_result_int64(context, rc);
1911}
drhdaffd0e2001-04-11 14:28:42 +00001912
drh75897232000-05-29 14:26:00 +00001913/*
drh44c2eb12003-04-30 11:38:26 +00001914** Make sure the database is open. If it is not, then open it. If
1915** the database fails to open, print an error message and exit.
1916*/
drhdcd87a92014-08-18 13:45:42 +00001917static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001918 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001919 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001920 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001921 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001922 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1923 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1924 shellstaticFunc, 0, 0);
1925 }
1926 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001927 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001928 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001929 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001930 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001931 }
drhc2e87a32006-06-27 15:16:14 +00001932#ifndef SQLITE_OMIT_LOAD_EXTENSION
1933 sqlite3_enable_load_extension(p->db, 1);
1934#endif
drhba5b0932014-07-24 12:39:59 +00001935 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1936 readfileFunc, 0, 0);
1937 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1938 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001939 }
1940}
1941
1942/*
drhfeac5f82004-08-01 00:10:45 +00001943** Do C-language style dequoting.
1944**
1945** \t -> tab
1946** \n -> newline
1947** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001948** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001949** \NNN -> ascii character NNN in octal
1950** \\ -> backslash
1951*/
1952static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001953 int i, j;
1954 char c;
drhc2ce0be2014-05-29 12:36:14 +00001955 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001956 for(i=j=0; (c = z[i])!=0; i++, j++){
1957 if( c=='\\' ){
1958 c = z[++i];
1959 if( c=='n' ){
1960 c = '\n';
1961 }else if( c=='t' ){
1962 c = '\t';
1963 }else if( c=='r' ){
1964 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001965 }else if( c=='\\' ){
1966 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001967 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001968 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001969 if( z[i+1]>='0' && z[i+1]<='7' ){
1970 i++;
1971 c = (c<<3) + z[i] - '0';
1972 if( z[i+1]>='0' && z[i+1]<='7' ){
1973 i++;
1974 c = (c<<3) + z[i] - '0';
1975 }
1976 }
1977 }
1978 }
1979 z[j] = c;
1980 }
drhc2ce0be2014-05-29 12:36:14 +00001981 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001982}
1983
1984/*
drh348d19c2013-06-03 12:47:43 +00001985** Return the value of a hexadecimal digit. Return -1 if the input
1986** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001987*/
drh348d19c2013-06-03 12:47:43 +00001988static int hexDigitValue(char c){
1989 if( c>='0' && c<='9' ) return c - '0';
1990 if( c>='a' && c<='f' ) return c - 'a' + 10;
1991 if( c>='A' && c<='F' ) return c - 'A' + 10;
1992 return -1;
drhc28490c2006-10-26 14:25:58 +00001993}
1994
1995/*
drh7d9f3942013-04-03 01:26:54 +00001996** Interpret zArg as an integer value, possibly with suffixes.
1997*/
1998static sqlite3_int64 integerValue(const char *zArg){
1999 sqlite3_int64 v = 0;
2000 static const struct { char *zSuffix; int iMult; } aMult[] = {
2001 { "KiB", 1024 },
2002 { "MiB", 1024*1024 },
2003 { "GiB", 1024*1024*1024 },
2004 { "KB", 1000 },
2005 { "MB", 1000000 },
2006 { "GB", 1000000000 },
2007 { "K", 1000 },
2008 { "M", 1000000 },
2009 { "G", 1000000000 },
2010 };
2011 int i;
2012 int isNeg = 0;
2013 if( zArg[0]=='-' ){
2014 isNeg = 1;
2015 zArg++;
2016 }else if( zArg[0]=='+' ){
2017 zArg++;
2018 }
drh348d19c2013-06-03 12:47:43 +00002019 if( zArg[0]=='0' && zArg[1]=='x' ){
2020 int x;
2021 zArg += 2;
2022 while( (x = hexDigitValue(zArg[0]))>=0 ){
2023 v = (v<<4) + x;
2024 zArg++;
2025 }
2026 }else{
2027 while( IsDigit(zArg[0]) ){
2028 v = v*10 + zArg[0] - '0';
2029 zArg++;
2030 }
drh7d9f3942013-04-03 01:26:54 +00002031 }
drhc2bed0a2013-05-24 11:57:50 +00002032 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002033 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2034 v *= aMult[i].iMult;
2035 break;
2036 }
2037 }
2038 return isNeg? -v : v;
2039}
2040
2041/*
drh348d19c2013-06-03 12:47:43 +00002042** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2043** for TRUE and FALSE. Return the integer value if appropriate.
2044*/
2045static int booleanValue(char *zArg){
2046 int i;
2047 if( zArg[0]=='0' && zArg[1]=='x' ){
2048 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2049 }else{
2050 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2051 }
2052 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2053 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2054 return 1;
2055 }
2056 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2057 return 0;
2058 }
2059 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2060 zArg);
2061 return 0;
2062}
2063
2064/*
drh42f64e52012-04-04 16:56:23 +00002065** Close an output file, assuming it is not stderr or stdout
2066*/
2067static void output_file_close(FILE *f){
2068 if( f && f!=stdout && f!=stderr ) fclose(f);
2069}
2070
2071/*
2072** Try to open an output file. The names "stdout" and "stderr" are
2073** recognized and do the right thing. NULL is returned if the output
2074** filename is "off".
2075*/
2076static FILE *output_file_open(const char *zFile){
2077 FILE *f;
2078 if( strcmp(zFile,"stdout")==0 ){
2079 f = stdout;
2080 }else if( strcmp(zFile, "stderr")==0 ){
2081 f = stderr;
2082 }else if( strcmp(zFile, "off")==0 ){
2083 f = 0;
2084 }else{
2085 f = fopen(zFile, "wb");
2086 if( f==0 ){
2087 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2088 }
2089 }
2090 return f;
2091}
2092
2093/*
2094** A routine for handling output from sqlite3_trace().
2095*/
2096static void sql_trace_callback(void *pArg, const char *z){
2097 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002098 if( f ){
2099 int i = (int)strlen(z);
2100 while( i>0 && z[i-1]==';' ){ i--; }
2101 fprintf(f, "%.*s;\n", i, z);
2102 }
drh42f64e52012-04-04 16:56:23 +00002103}
2104
2105/*
drhd8621b92012-04-17 09:09:33 +00002106** A no-op routine that runs with the ".breakpoint" doc-command. This is
2107** a useful spot to set a debugger breakpoint.
2108*/
2109static void test_breakpoint(void){
2110 static int nCall = 0;
2111 nCall++;
2112}
2113
2114/*
mistachkin636bf9f2014-07-19 20:15:16 +00002115** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002116*/
mistachkin636bf9f2014-07-19 20:15:16 +00002117typedef struct ImportCtx ImportCtx;
2118struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002119 const char *zFile; /* Name of the input file */
2120 FILE *in; /* Read the CSV text from this input stream */
2121 char *z; /* Accumulated text for a field */
2122 int n; /* Number of bytes in z */
2123 int nAlloc; /* Space allocated for z[] */
2124 int nLine; /* Current line number */
2125 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002126 int cColSep; /* The column separator character. (Usually ",") */
2127 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002128};
2129
2130/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002131static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002132 if( p->n+1>=p->nAlloc ){
2133 p->nAlloc += p->nAlloc + 100;
2134 p->z = sqlite3_realloc(p->z, p->nAlloc);
2135 if( p->z==0 ){
2136 fprintf(stderr, "out of memory\n");
2137 exit(1);
2138 }
2139 }
2140 p->z[p->n++] = (char)c;
2141}
2142
2143/* Read a single field of CSV text. Compatible with rfc4180 and extended
2144** with the option of having a separator other than ",".
2145**
2146** + Input comes from p->in.
2147** + Store results in p->z of length p->n. Space to hold p->z comes
2148** from sqlite3_malloc().
mistachkin636bf9f2014-07-19 20:15:16 +00002149** + Use p->cSep as the column separator. The default is ",".
2150** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002151** + Keep track of the line number in p->nLine.
2152** + Store the character that terminates the field in p->cTerm. Store
2153** EOF on end-of-file.
2154** + Report syntax errors on stderr
2155*/
mistachkin636bf9f2014-07-19 20:15:16 +00002156static char *csv_read_one_field(ImportCtx *p){
2157 int c;
2158 int cSep = p->cColSep;
2159 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002160 p->n = 0;
2161 c = fgetc(p->in);
2162 if( c==EOF || seenInterrupt ){
2163 p->cTerm = EOF;
2164 return 0;
2165 }
2166 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002167 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002168 int startLine = p->nLine;
2169 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002170 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002171 while( 1 ){
2172 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002173 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002174 if( c==cQuote ){
2175 if( pc==cQuote ){
2176 pc = 0;
2177 continue;
2178 }
2179 }
2180 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002181 || (c==rSep && pc==cQuote)
2182 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002183 || (c==EOF && pc==cQuote)
2184 ){
2185 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002186 p->cTerm = c;
2187 break;
2188 }
2189 if( pc==cQuote && c!='\r' ){
2190 fprintf(stderr, "%s:%d: unescaped %c character\n",
2191 p->zFile, p->nLine, cQuote);
2192 }
2193 if( c==EOF ){
2194 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2195 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002196 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002197 break;
2198 }
mistachkin636bf9f2014-07-19 20:15:16 +00002199 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002200 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002201 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002202 }
drhdb95f682013-06-26 22:46:00 +00002203 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002204 while( c!=EOF && c!=cSep && c!=rSep ){
2205 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002206 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002207 }
mistachkin636bf9f2014-07-19 20:15:16 +00002208 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002209 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002210 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002211 }
drhdb95f682013-06-26 22:46:00 +00002212 p->cTerm = c;
2213 }
drh8dd675e2013-07-12 21:09:24 +00002214 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002215 return p->z;
2216}
2217
mistachkin636bf9f2014-07-19 20:15:16 +00002218/* Read a single field of ASCII delimited text.
2219**
2220** + Input comes from p->in.
2221** + Store results in p->z of length p->n. Space to hold p->z comes
2222** from sqlite3_malloc().
2223** + Use p->cSep as the column separator. The default is "\x1F".
2224** + Use p->rSep as the row separator. The default is "\x1E".
2225** + Keep track of the row number in p->nLine.
2226** + Store the character that terminates the field in p->cTerm. Store
2227** EOF on end-of-file.
2228** + Report syntax errors on stderr
2229*/
2230static char *ascii_read_one_field(ImportCtx *p){
2231 int c;
2232 int cSep = p->cColSep;
2233 int rSep = p->cRowSep;
2234 p->n = 0;
2235 c = fgetc(p->in);
2236 if( c==EOF || seenInterrupt ){
2237 p->cTerm = EOF;
2238 return 0;
2239 }
2240 while( c!=EOF && c!=cSep && c!=rSep ){
2241 import_append_char(p, c);
2242 c = fgetc(p->in);
2243 }
2244 if( c==rSep ){
2245 p->nLine++;
2246 }
2247 p->cTerm = c;
2248 if( p->z ) p->z[p->n] = 0;
2249 return p->z;
2250}
2251
drhdb95f682013-06-26 22:46:00 +00002252/*
drh4bbcf102014-02-06 02:46:08 +00002253** Try to transfer data for table zTable. If an error is seen while
2254** moving forward, try to go backwards. The backwards movement won't
2255** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002256*/
mistachkine31ae902014-02-06 01:15:29 +00002257static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002258 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002259 sqlite3 *newDb,
2260 const char *zTable
2261){
2262 sqlite3_stmt *pQuery = 0;
2263 sqlite3_stmt *pInsert = 0;
2264 char *zQuery = 0;
2265 char *zInsert = 0;
2266 int rc;
2267 int i, j, n;
2268 int nTable = (int)strlen(zTable);
2269 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002270 int cnt = 0;
2271 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002272
2273 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2274 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2275 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002276 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002277 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2278 zQuery);
2279 goto end_data_xfer;
2280 }
2281 n = sqlite3_column_count(pQuery);
2282 zInsert = sqlite3_malloc(200 + nTable + n*3);
2283 if( zInsert==0 ){
2284 fprintf(stderr, "out of memory\n");
2285 goto end_data_xfer;
2286 }
2287 sqlite3_snprintf(200+nTable,zInsert,
2288 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2289 i = (int)strlen(zInsert);
2290 for(j=1; j<n; j++){
2291 memcpy(zInsert+i, ",?", 2);
2292 i += 2;
2293 }
2294 memcpy(zInsert+i, ");", 3);
2295 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2296 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002297 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002298 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2299 zQuery);
2300 goto end_data_xfer;
2301 }
2302 for(k=0; k<2; k++){
2303 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2304 for(i=0; i<n; i++){
2305 switch( sqlite3_column_type(pQuery, i) ){
2306 case SQLITE_NULL: {
2307 sqlite3_bind_null(pInsert, i+1);
2308 break;
2309 }
2310 case SQLITE_INTEGER: {
2311 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2312 break;
2313 }
2314 case SQLITE_FLOAT: {
2315 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2316 break;
2317 }
2318 case SQLITE_TEXT: {
2319 sqlite3_bind_text(pInsert, i+1,
2320 (const char*)sqlite3_column_text(pQuery,i),
2321 -1, SQLITE_STATIC);
2322 break;
2323 }
2324 case SQLITE_BLOB: {
2325 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2326 sqlite3_column_bytes(pQuery,i),
2327 SQLITE_STATIC);
2328 break;
2329 }
2330 }
2331 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002332 rc = sqlite3_step(pInsert);
2333 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2334 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2335 sqlite3_errmsg(newDb));
2336 }
drh3350ce92014-02-06 00:49:12 +00002337 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002338 cnt++;
2339 if( (cnt%spinRate)==0 ){
2340 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2341 fflush(stdout);
2342 }
drh3350ce92014-02-06 00:49:12 +00002343 } /* End while */
2344 if( rc==SQLITE_DONE ) break;
2345 sqlite3_finalize(pQuery);
2346 sqlite3_free(zQuery);
2347 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2348 zTable);
2349 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2350 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002351 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2352 break;
drh3350ce92014-02-06 00:49:12 +00002353 }
2354 } /* End for(k=0...) */
2355
2356end_data_xfer:
2357 sqlite3_finalize(pQuery);
2358 sqlite3_finalize(pInsert);
2359 sqlite3_free(zQuery);
2360 sqlite3_free(zInsert);
2361}
2362
2363
2364/*
2365** Try to transfer all rows of the schema that match zWhere. For
2366** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002367** If an error is encountered while moving forward through the
2368** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002369*/
mistachkine31ae902014-02-06 01:15:29 +00002370static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002371 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002372 sqlite3 *newDb,
2373 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002374 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002375){
2376 sqlite3_stmt *pQuery = 0;
2377 char *zQuery = 0;
2378 int rc;
2379 const unsigned char *zName;
2380 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002381 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002382
2383 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2384 " WHERE %s", zWhere);
2385 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2386 if( rc ){
2387 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2388 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2389 zQuery);
2390 goto end_schema_xfer;
2391 }
2392 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2393 zName = sqlite3_column_text(pQuery, 0);
2394 zSql = sqlite3_column_text(pQuery, 1);
2395 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002396 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2397 if( zErrMsg ){
2398 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2399 sqlite3_free(zErrMsg);
2400 zErrMsg = 0;
2401 }
drh3350ce92014-02-06 00:49:12 +00002402 if( xForEach ){
2403 xForEach(p, newDb, (const char*)zName);
2404 }
2405 printf("done\n");
2406 }
2407 if( rc!=SQLITE_DONE ){
2408 sqlite3_finalize(pQuery);
2409 sqlite3_free(zQuery);
2410 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2411 " WHERE %s ORDER BY rowid DESC", zWhere);
2412 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2413 if( rc ){
2414 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2415 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2416 zQuery);
2417 goto end_schema_xfer;
2418 }
2419 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2420 zName = sqlite3_column_text(pQuery, 0);
2421 zSql = sqlite3_column_text(pQuery, 1);
2422 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002423 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2424 if( zErrMsg ){
2425 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2426 sqlite3_free(zErrMsg);
2427 zErrMsg = 0;
2428 }
drh3350ce92014-02-06 00:49:12 +00002429 if( xForEach ){
2430 xForEach(p, newDb, (const char*)zName);
2431 }
2432 printf("done\n");
2433 }
2434 }
2435end_schema_xfer:
2436 sqlite3_finalize(pQuery);
2437 sqlite3_free(zQuery);
2438}
2439
2440/*
2441** Open a new database file named "zNewDb". Try to recover as much information
2442** as possible out of the main database (which might be corrupt) and write it
2443** into zNewDb.
2444*/
drhdcd87a92014-08-18 13:45:42 +00002445static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002446 int rc;
2447 sqlite3 *newDb = 0;
2448 if( access(zNewDb,0)==0 ){
2449 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2450 return;
2451 }
2452 rc = sqlite3_open(zNewDb, &newDb);
2453 if( rc ){
2454 fprintf(stderr, "Cannot create output database: %s\n",
2455 sqlite3_errmsg(newDb));
2456 }else{
drh54d0d2d2014-04-03 00:32:13 +00002457 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002458 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002459 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2460 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002461 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002462 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002463 }
2464 sqlite3_close(newDb);
2465}
2466
2467/*
drhc2ce0be2014-05-29 12:36:14 +00002468** Change the output file back to stdout
2469*/
drhdcd87a92014-08-18 13:45:42 +00002470static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002471 if( p->outfile[0]=='|' ){
2472 pclose(p->out);
2473 }else{
2474 output_file_close(p->out);
2475 }
2476 p->outfile[0] = 0;
2477 p->out = stdout;
2478}
2479
2480/*
drhf7502f02015-02-06 14:19:44 +00002481** Run an SQL command and return the single integer result.
2482*/
2483static int db_int(ShellState *p, const char *zSql){
2484 sqlite3_stmt *pStmt;
2485 int res = 0;
2486 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2487 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2488 res = sqlite3_column_int(pStmt,0);
2489 }
2490 sqlite3_finalize(pStmt);
2491 return res;
2492}
2493
2494/*
2495** Convert a 2-byte or 4-byte big-endian integer into a native integer
2496*/
2497unsigned int get2byteInt(unsigned char *a){
2498 return (a[0]<<8) + a[1];
2499}
2500unsigned int get4byteInt(unsigned char *a){
2501 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2502}
2503
2504/*
2505** Implementation of the ".info" command.
2506**
2507** Return 1 on error, 2 to exit, and 0 otherwise.
2508*/
drh0e55db12015-02-06 14:51:13 +00002509static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002510 static const struct { const char *zName; int ofst; } aField[] = {
2511 { "file change counter:", 24 },
2512 { "database page count:", 28 },
2513 { "freelist page count:", 36 },
2514 { "schema cookie:", 40 },
2515 { "schema format:", 44 },
2516 { "default cache size:", 48 },
2517 { "autovacuum top root:", 52 },
2518 { "incremental vacuum:", 64 },
2519 { "text encoding:", 56 },
2520 { "user version:", 60 },
2521 { "application id:", 68 },
2522 { "software version:", 96 },
2523 };
drh0e55db12015-02-06 14:51:13 +00002524 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2525 { "number of tables:",
2526 "SELECT count(*) FROM %s WHERE type='table'" },
2527 { "number of indexes:",
2528 "SELECT count(*) FROM %s WHERE type='index'" },
2529 { "number of triggers:",
2530 "SELECT count(*) FROM %s WHERE type='trigger'" },
2531 { "number of views:",
2532 "SELECT count(*) FROM %s WHERE type='view'" },
2533 { "schema size:",
2534 "SELECT total(length(sql)) FROM %s" },
2535 };
2536 sqlite3_file *pFile;
2537 int i;
2538 char *zSchemaTab;
2539 char *zDb = nArg>=2 ? azArg[1] : "main";
2540 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002541 open_db(p, 0);
2542 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002543 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002544 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2545 return 1;
2546 }
2547 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2548 if( i!=SQLITE_OK ){
2549 fprintf(stderr, "unable to read database header\n");
2550 return 1;
2551 }
2552 i = get2byteInt(aHdr+16);
2553 if( i==1 ) i = 65536;
2554 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2555 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2556 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2557 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2558 for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
2559 int ofst = aField[i].ofst;
2560 unsigned int val = get4byteInt(aHdr + ofst);
2561 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2562 switch( ofst ){
2563 case 56: {
2564 if( val==1 ) fprintf(p->out, " (utf8)");
2565 if( val==2 ) fprintf(p->out, " (utf16le)");
2566 if( val==3 ) fprintf(p->out, " (utf16be)");
2567 }
2568 }
2569 fprintf(p->out, "\n");
2570 }
drh0e55db12015-02-06 14:51:13 +00002571 if( zDb==0 ){
2572 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2573 }else if( strcmp(zDb,"temp")==0 ){
2574 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2575 }else{
2576 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2577 }
2578 for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
2579 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2580 int val = db_int(p, zSql);
2581 sqlite3_free(zSql);
2582 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2583 }
2584 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002585 return 0;
2586}
2587
2588
2589/*
drh75897232000-05-29 14:26:00 +00002590** If an input line begins with "." then invoke this routine to
2591** process that line.
drh67505e72002-04-19 12:34:06 +00002592**
drh47ad6842006-11-08 12:25:42 +00002593** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002594*/
drhdcd87a92014-08-18 13:45:42 +00002595static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002596 int i = 1;
2597 int nArg = 0;
2598 int n, c;
drh67505e72002-04-19 12:34:06 +00002599 int rc = 0;
drh75897232000-05-29 14:26:00 +00002600 char *azArg[50];
2601
2602 /* Parse the input line into tokens.
2603 */
2604 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002605 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002606 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002607 if( zLine[i]=='\'' || zLine[i]=='"' ){
2608 int delim = zLine[i++];
2609 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002610 while( zLine[i] && zLine[i]!=delim ){
2611 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2612 i++;
2613 }
drh75897232000-05-29 14:26:00 +00002614 if( zLine[i]==delim ){
2615 zLine[i++] = 0;
2616 }
drhfeac5f82004-08-01 00:10:45 +00002617 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002618 }else{
2619 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002620 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002621 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002622 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002623 }
2624 }
2625
2626 /* Process the input line.
2627 */
shane9bd1b442009-10-23 01:27:39 +00002628 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002629 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002630 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002631 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2632 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2633 ){
drhbc46f022013-01-23 18:53:23 +00002634 const char *zDestFile = 0;
2635 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002636 sqlite3 *pDest;
2637 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002638 int j;
2639 for(j=1; j<nArg; j++){
2640 const char *z = azArg[j];
2641 if( z[0]=='-' ){
2642 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002643 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002644 {
2645 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2646 return 1;
2647 }
2648 }else if( zDestFile==0 ){
2649 zDestFile = azArg[j];
2650 }else if( zDb==0 ){
2651 zDb = zDestFile;
2652 zDestFile = azArg[j];
2653 }else{
2654 fprintf(stderr, "too many arguments to .backup\n");
2655 return 1;
2656 }
drh9ff849f2009-02-04 20:55:57 +00002657 }
drhbc46f022013-01-23 18:53:23 +00002658 if( zDestFile==0 ){
2659 fprintf(stderr, "missing FILENAME argument on .backup\n");
2660 return 1;
2661 }
2662 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002663 rc = sqlite3_open(zDestFile, &pDest);
2664 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002665 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002666 sqlite3_close(pDest);
2667 return 1;
2668 }
drh05782482013-10-24 15:20:20 +00002669 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002670 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2671 if( pBackup==0 ){
2672 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2673 sqlite3_close(pDest);
2674 return 1;
2675 }
2676 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2677 sqlite3_backup_finish(pBackup);
2678 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002679 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002680 }else{
2681 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002682 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002683 }
2684 sqlite3_close(pDest);
2685 }else
2686
drhc2ce0be2014-05-29 12:36:14 +00002687 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2688 if( nArg==2 ){
2689 bail_on_error = booleanValue(azArg[1]);
2690 }else{
2691 fprintf(stderr, "Usage: .bail on|off\n");
2692 rc = 1;
2693 }
drhc49f44e2006-10-26 18:15:42 +00002694 }else
2695
drhd8621b92012-04-17 09:09:33 +00002696 /* The undocumented ".breakpoint" command causes a call to the no-op
2697 ** routine named test_breakpoint().
2698 */
2699 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2700 test_breakpoint();
2701 }else
2702
drhc2ce0be2014-05-29 12:36:14 +00002703 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2704 if( nArg==2 ){
2705 tryToClone(p, azArg[1]);
2706 }else{
2707 fprintf(stderr, "Usage: .clone FILENAME\n");
2708 rc = 1;
2709 }
mistachkine31ae902014-02-06 01:15:29 +00002710 }else
2711
drhc2ce0be2014-05-29 12:36:14 +00002712 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002713 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002714 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002715 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002716 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002717 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002718 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002719 data.colWidth[0] = 3;
2720 data.colWidth[1] = 15;
2721 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002722 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002723 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002724 if( zErrMsg ){
2725 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002726 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002727 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002728 }
2729 }else
2730
drh0e55db12015-02-06 14:51:13 +00002731 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2732 rc = shell_dbinfo_command(p, nArg, azArg);
2733 }else
2734
drhc2ce0be2014-05-29 12:36:14 +00002735 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002736 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002737 /* When playing back a "dump", the content might appear in an order
2738 ** which causes immediate foreign key constraints to be violated.
2739 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002740 if( nArg!=1 && nArg!=2 ){
2741 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2742 rc = 1;
2743 goto meta_command_exit;
2744 }
drhf1dfc4f2009-09-23 15:51:35 +00002745 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002746 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002747 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002748 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002749 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002750 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002751 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002752 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002753 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002754 );
2755 run_schema_dump_query(p,
2756 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002757 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002758 );
drh2f464a02011-10-13 00:41:49 +00002759 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002760 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002761 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002762 );
drh4c653a02000-06-07 01:27:47 +00002763 }else{
2764 int i;
drhdd3d4592004-08-30 01:54:05 +00002765 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002766 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002767 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002768 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002769 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002770 " AND sql NOT NULL");
2771 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002772 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002773 "WHERE sql NOT NULL"
2774 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002775 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002776 );
danielk1977bc6ada42004-06-30 08:20:16 +00002777 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002778 }
2779 }
drh45e29d82006-11-20 16:21:10 +00002780 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002781 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002782 p->writableSchema = 0;
2783 }
drh56197952011-10-13 16:30:13 +00002784 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2785 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002786 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002787 }else
drh75897232000-05-29 14:26:00 +00002788
drhc2ce0be2014-05-29 12:36:14 +00002789 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2790 if( nArg==2 ){
2791 p->echoOn = booleanValue(azArg[1]);
2792 }else{
2793 fprintf(stderr, "Usage: .echo on|off\n");
2794 rc = 1;
2795 }
drhdaffd0e2001-04-11 14:28:42 +00002796 }else
2797
drhc2ce0be2014-05-29 12:36:14 +00002798 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2799 if( nArg==2 ){
2800 p->autoEQP = booleanValue(azArg[1]);
2801 }else{
2802 fprintf(stderr, "Usage: .eqp on|off\n");
2803 rc = 1;
2804 }
drhefbf3b12014-02-28 20:47:24 +00002805 }else
2806
drhd3ac7d92013-01-25 18:33:43 +00002807 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002808 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002809 rc = 2;
drh75897232000-05-29 14:26:00 +00002810 }else
2811
drhc2ce0be2014-05-29 12:36:14 +00002812 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002813 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002814 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002815 if(!p->normalMode.valid) {
2816 p->normalMode.valid = 1;
2817 p->normalMode.mode = p->mode;
2818 p->normalMode.showHeader = p->showHeader;
2819 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002820 }
2821 /* We could put this code under the !p->explainValid
2822 ** condition so that it does not execute if we are already in
2823 ** explain mode. However, always executing it allows us an easy
2824 ** was to reset to explain mode in case the user previously
2825 ** did an .explain followed by a .width, .mode or .header
2826 ** command.
2827 */
danielk19770d78bae2008-01-03 07:09:48 +00002828 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002829 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002830 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002831 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002832 p->colWidth[1] = 13; /* opcode */
2833 p->colWidth[2] = 4; /* P1 */
2834 p->colWidth[3] = 4; /* P2 */
2835 p->colWidth[4] = 4; /* P3 */
2836 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002837 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002838 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002839 }else if (p->normalMode.valid) {
2840 p->normalMode.valid = 0;
2841 p->mode = p->normalMode.mode;
2842 p->showHeader = p->normalMode.showHeader;
2843 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002844 }
drh75897232000-05-29 14:26:00 +00002845 }else
2846
drhc1971542014-06-23 23:28:13 +00002847 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002848 ShellState data;
drhc1971542014-06-23 23:28:13 +00002849 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002850 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002851 if( nArg!=1 ){
2852 fprintf(stderr, "Usage: .fullschema\n");
2853 rc = 1;
2854 goto meta_command_exit;
2855 }
2856 open_db(p, 0);
2857 memcpy(&data, p, sizeof(data));
2858 data.showHeader = 0;
2859 data.mode = MODE_Semi;
2860 rc = sqlite3_exec(p->db,
2861 "SELECT sql FROM"
2862 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2863 " FROM sqlite_master UNION ALL"
2864 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002865 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002866 "ORDER BY rowid",
2867 callback, &data, &zErrMsg
2868 );
drh56f674c2014-07-18 14:43:29 +00002869 if( rc==SQLITE_OK ){
2870 sqlite3_stmt *pStmt;
2871 rc = sqlite3_prepare_v2(p->db,
2872 "SELECT rowid FROM sqlite_master"
2873 " WHERE name GLOB 'sqlite_stat[134]'",
2874 -1, &pStmt, 0);
2875 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2876 sqlite3_finalize(pStmt);
2877 }
2878 if( doStats==0 ){
2879 fprintf(p->out, "/* No STAT tables available */\n");
2880 }else{
2881 fprintf(p->out, "ANALYZE sqlite_master;\n");
2882 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2883 callback, &data, &zErrMsg);
2884 data.mode = MODE_Insert;
2885 data.zDestTable = "sqlite_stat1";
2886 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2887 shell_callback, &data,&zErrMsg);
2888 data.zDestTable = "sqlite_stat3";
2889 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2890 shell_callback, &data,&zErrMsg);
2891 data.zDestTable = "sqlite_stat4";
2892 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2893 shell_callback, &data, &zErrMsg);
2894 fprintf(p->out, "ANALYZE sqlite_master;\n");
2895 }
drhc1971542014-06-23 23:28:13 +00002896 }else
2897
drhc2ce0be2014-05-29 12:36:14 +00002898 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2899 if( nArg==2 ){
2900 p->showHeader = booleanValue(azArg[1]);
2901 }else{
2902 fprintf(stderr, "Usage: .headers on|off\n");
2903 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002904 }
drh75897232000-05-29 14:26:00 +00002905 }else
2906
drhc2ce0be2014-05-29 12:36:14 +00002907 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2908 fprintf(p->out, "%s", zHelp);
2909 }else
2910
2911 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002912 char *zTable; /* Insert data into this table */
2913 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002914 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002915 int nCol; /* Number of columns in the table */
2916 int nByte; /* Number of bytes in an SQL string */
2917 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002918 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002919 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002920 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002921 ImportCtx sCtx; /* Reader context */
mistachkin486fd432014-07-24 22:20:23 +00002922 char *(*xRead)(ImportCtx*); /* Procedure to read one value */
drh5bde8162013-06-27 14:07:53 +00002923 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002924
drhc2ce0be2014-05-29 12:36:14 +00002925 if( nArg!=3 ){
2926 fprintf(stderr, "Usage: .import FILE TABLE\n");
2927 goto meta_command_exit;
2928 }
drh01f37542014-05-31 15:43:33 +00002929 zFile = azArg[1];
2930 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002931 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002932 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002933 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002934 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002935 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002936 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002937 return 1;
drhfeac5f82004-08-01 00:10:45 +00002938 }
drhdb95f682013-06-26 22:46:00 +00002939 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002940 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002941 " for import\n");
2942 return 1;
2943 }
mistachkin636bf9f2014-07-19 20:15:16 +00002944 nSep = strlen30(p->rowSeparator);
2945 if( nSep==0 ){
2946 fprintf(stderr, "Error: non-null row separator required for import\n");
2947 return 1;
2948 }
mistachkine0d68852014-12-11 03:12:33 +00002949 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2950 /* When importing CSV (only), if the row separator is set to the
2951 ** default output row separator, change it to the default input
2952 ** row separator. This avoids having to maintain different input
2953 ** and output row separators. */
2954 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2955 nSep = strlen30(p->rowSeparator);
2956 }
mistachkin636bf9f2014-07-19 20:15:16 +00002957 if( nSep>1 ){
2958 fprintf(stderr, "Error: multi-character row separators not allowed"
2959 " for import\n");
2960 return 1;
2961 }
2962 sCtx.zFile = zFile;
2963 sCtx.nLine = 1;
2964 if( sCtx.zFile[0]=='|' ){
2965 sCtx.in = popen(sCtx.zFile+1, "r");
2966 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00002967 xCloser = pclose;
2968 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002969 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00002970 xCloser = fclose;
2971 }
mistachkin636bf9f2014-07-19 20:15:16 +00002972 if( p->mode==MODE_Ascii ){
2973 xRead = ascii_read_one_field;
2974 }else{
2975 xRead = csv_read_one_field;
2976 }
2977 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002978 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002979 return 1;
2980 }
mistachkin636bf9f2014-07-19 20:15:16 +00002981 sCtx.cColSep = p->colSeparator[0];
2982 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00002983 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002984 if( zSql==0 ){
2985 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002986 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002987 return 1;
2988 }
drh4f21c4a2008-12-10 22:15:00 +00002989 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002990 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002991 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
drhdb95f682013-06-26 22:46:00 +00002992 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2993 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2994 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00002995 while( xRead(&sCtx) ){
2996 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00002997 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00002998 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00002999 }
drh5bde8162013-06-27 14:07:53 +00003000 if( cSep=='(' ){
3001 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003002 sqlite3_free(sCtx.z);
3003 xCloser(sCtx.in);
3004 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003005 return 1;
3006 }
drhdb95f682013-06-26 22:46:00 +00003007 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3008 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3009 sqlite3_free(zCreate);
3010 if( rc ){
3011 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
3012 sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00003013 sqlite3_free(sCtx.z);
3014 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003015 return 1;
3016 }
drhc7181902014-02-27 15:04:13 +00003017 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003018 }
drhfeac5f82004-08-01 00:10:45 +00003019 sqlite3_free(zSql);
3020 if( rc ){
shane916f9612009-10-23 00:37:15 +00003021 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003022 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00003023 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003024 return 1;
drhfeac5f82004-08-01 00:10:45 +00003025 }
shane916f9612009-10-23 00:37:15 +00003026 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003027 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003028 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003029 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00003030 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003031 if( zSql==0 ){
3032 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003033 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003034 return 1;
3035 }
drhdb95f682013-06-26 22:46:00 +00003036 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003037 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003038 for(i=1; i<nCol; i++){
3039 zSql[j++] = ',';
3040 zSql[j++] = '?';
3041 }
3042 zSql[j++] = ')';
3043 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003044 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003045 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003046 if( rc ){
3047 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00003048 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003049 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003050 return 1;
drhfeac5f82004-08-01 00:10:45 +00003051 }
drh2d463112013-08-06 14:36:36 +00003052 needCommit = sqlite3_get_autocommit(db);
3053 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003054 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003055 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003056 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003057 char *z = xRead(&sCtx);
3058 /*
3059 ** Did we reach end-of-file before finding any columns?
3060 ** If so, stop instead of NULL filling the remaining columns.
3061 */
drhdb95f682013-06-26 22:46:00 +00003062 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003063 /*
3064 ** Did we reach end-of-file OR end-of-line before finding any
3065 ** columns in ASCII mode? If so, stop instead of NULL filling
3066 ** the remaining columns.
3067 */
3068 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003069 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003070 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003071 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3072 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003073 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003074 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003075 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003076 }
drhfeac5f82004-08-01 00:10:45 +00003077 }
mistachkin636bf9f2014-07-19 20:15:16 +00003078 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003079 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003080 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003081 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003082 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003083 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3084 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003085 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003086 }
drhdb95f682013-06-26 22:46:00 +00003087 if( i>=nCol ){
3088 sqlite3_step(pStmt);
3089 rc = sqlite3_reset(pStmt);
3090 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003091 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
drhdb95f682013-06-26 22:46:00 +00003092 sqlite3_errmsg(db));
3093 }
3094 }
mistachkin636bf9f2014-07-19 20:15:16 +00003095 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003096
mistachkin636bf9f2014-07-19 20:15:16 +00003097 xCloser(sCtx.in);
3098 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003099 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00003100 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003101 }else
3102
drh0e55db12015-02-06 14:51:13 +00003103 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3104 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003105 ShellState data;
drh75897232000-05-29 14:26:00 +00003106 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003107 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003108 memcpy(&data, p, sizeof(data));
3109 data.showHeader = 0;
3110 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003111 if( nArg==1 ){
3112 rc = sqlite3_exec(p->db,
3113 "SELECT name FROM sqlite_master "
3114 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3115 "UNION ALL "
3116 "SELECT name FROM sqlite_temp_master "
3117 "WHERE type='index' "
3118 "ORDER BY 1",
3119 callback, &data, &zErrMsg
3120 );
drhc2ce0be2014-05-29 12:36:14 +00003121 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003122 zShellStatic = azArg[1];
3123 rc = sqlite3_exec(p->db,
3124 "SELECT name FROM sqlite_master "
3125 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3126 "UNION ALL "
3127 "SELECT name FROM sqlite_temp_master "
3128 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3129 "ORDER BY 1",
3130 callback, &data, &zErrMsg
3131 );
3132 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003133 }else{
drh0e55db12015-02-06 14:51:13 +00003134 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003135 rc = 1;
3136 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003137 }
drh75897232000-05-29 14:26:00 +00003138 if( zErrMsg ){
3139 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003140 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003141 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003142 }else if( rc != SQLITE_OK ){
3143 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3144 rc = 1;
drh75897232000-05-29 14:26:00 +00003145 }
3146 }else
3147
drhae5e4452007-05-03 17:18:36 +00003148#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003149 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003150 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003151 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3152 iotrace = 0;
3153 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003154 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003155 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003156 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003157 iotrace = stdout;
3158 }else{
3159 iotrace = fopen(azArg[1], "w");
3160 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003161 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003162 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003163 rc = 1;
drhb0603412007-02-28 04:47:26 +00003164 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003165 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003166 }
3167 }
3168 }else
drhae5e4452007-05-03 17:18:36 +00003169#endif
drhb0603412007-02-28 04:47:26 +00003170
drh70df4fe2006-06-13 15:12:21 +00003171#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003172 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003173 const char *zFile, *zProc;
3174 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003175 if( nArg<2 ){
3176 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3177 rc = 1;
3178 goto meta_command_exit;
3179 }
drh1e397f82006-06-08 15:28:43 +00003180 zFile = azArg[1];
3181 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003182 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003183 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3184 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003185 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003186 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003187 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003188 }
3189 }else
drh70df4fe2006-06-13 15:12:21 +00003190#endif
drh1e397f82006-06-08 15:28:43 +00003191
drhc2ce0be2014-05-29 12:36:14 +00003192 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3193 if( nArg!=2 ){
3194 fprintf(stderr, "Usage: .log FILENAME\n");
3195 rc = 1;
3196 }else{
3197 const char *zFile = azArg[1];
3198 output_file_close(p->pLog);
3199 p->pLog = output_file_open(zFile);
3200 }
drh127f9d72010-02-23 01:47:00 +00003201 }else
3202
drhc2ce0be2014-05-29 12:36:14 +00003203 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3204 const char *zMode = nArg>=2 ? azArg[1] : "";
3205 int n2 = (int)strlen(zMode);
3206 int c2 = zMode[0];
3207 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003208 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003209 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003210 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003211 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003212 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003213 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003214 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003215 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003216 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003217 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003218 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003219 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003220 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003221 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003222 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003223 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003224 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003225 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003226 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003227 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003228 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3229 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003230 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3231 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003232 }else {
shane9bd1b442009-10-23 01:27:39 +00003233 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003234 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003235 rc = 1;
drh75897232000-05-29 14:26:00 +00003236 }
3237 }else
3238
drhc2ce0be2014-05-29 12:36:14 +00003239 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3240 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003241 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3242 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003243 }else{
3244 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003245 rc = 1;
3246 }
3247 }else
3248
drh05782482013-10-24 15:20:20 +00003249 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3250 sqlite3 *savedDb = p->db;
3251 const char *zSavedFilename = p->zDbFilename;
3252 char *zNewFilename = 0;
3253 p->db = 0;
3254 if( nArg>=2 ){
3255 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3256 }
3257 open_db(p, 1);
3258 if( p->db!=0 ){
3259 sqlite3_close(savedDb);
3260 sqlite3_free(p->zFreeOnClose);
3261 p->zFreeOnClose = zNewFilename;
3262 }else{
3263 sqlite3_free(zNewFilename);
3264 p->db = savedDb;
3265 p->zDbFilename = zSavedFilename;
3266 }
3267 }else
3268
drhc2ce0be2014-05-29 12:36:14 +00003269 if( c=='o'
3270 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3271 ){
3272 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3273 if( nArg>2 ){
3274 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3275 rc = 1;
3276 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003277 }
drhc2ce0be2014-05-29 12:36:14 +00003278 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3279 if( nArg<2 ){
3280 fprintf(stderr, "Usage: .once FILE\n");
3281 rc = 1;
3282 goto meta_command_exit;
3283 }
3284 p->outCount = 2;
3285 }else{
3286 p->outCount = 0;
3287 }
3288 output_reset(p);
3289 if( zFile[0]=='|' ){
3290 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003291 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003292 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003293 p->out = stdout;
3294 rc = 1;
3295 }else{
drhc2ce0be2014-05-29 12:36:14 +00003296 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003297 }
drh75897232000-05-29 14:26:00 +00003298 }else{
drhc2ce0be2014-05-29 12:36:14 +00003299 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003300 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003301 if( strcmp(zFile,"off")!=0 ){
3302 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003303 }
drh75897232000-05-29 14:26:00 +00003304 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003305 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003306 } else {
drhc2ce0be2014-05-29 12:36:14 +00003307 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003308 }
3309 }
3310 }else
3311
drh078b1fd2012-09-21 13:40:02 +00003312 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3313 int i;
3314 for(i=1; i<nArg; i++){
3315 if( i>1 ) fprintf(p->out, " ");
3316 fprintf(p->out, "%s", azArg[i]);
3317 }
3318 fprintf(p->out, "\n");
3319 }else
3320
drhc2ce0be2014-05-29 12:36:14 +00003321 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003322 if( nArg >= 2) {
3323 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3324 }
3325 if( nArg >= 3) {
3326 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3327 }
3328 }else
3329
drhc2ce0be2014-05-29 12:36:14 +00003330 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003331 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003332 }else
3333
drhc2ce0be2014-05-29 12:36:14 +00003334 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3335 FILE *alt;
3336 if( nArg!=2 ){
3337 fprintf(stderr, "Usage: .read FILE\n");
3338 rc = 1;
3339 goto meta_command_exit;
3340 }
3341 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003342 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003343 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3344 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003345 }else{
shane9bd1b442009-10-23 01:27:39 +00003346 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003347 fclose(alt);
3348 }
3349 }else
3350
drhc2ce0be2014-05-29 12:36:14 +00003351 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003352 const char *zSrcFile;
3353 const char *zDb;
3354 sqlite3 *pSrc;
3355 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003356 int nTimeout = 0;
3357
drh9ff849f2009-02-04 20:55:57 +00003358 if( nArg==2 ){
3359 zSrcFile = azArg[1];
3360 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003361 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003362 zSrcFile = azArg[2];
3363 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003364 }else{
3365 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3366 rc = 1;
3367 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003368 }
3369 rc = sqlite3_open(zSrcFile, &pSrc);
3370 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003371 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003372 sqlite3_close(pSrc);
3373 return 1;
3374 }
drh05782482013-10-24 15:20:20 +00003375 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003376 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3377 if( pBackup==0 ){
3378 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3379 sqlite3_close(pSrc);
3380 return 1;
3381 }
drhdc2c4912009-02-04 22:46:47 +00003382 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3383 || rc==SQLITE_BUSY ){
3384 if( rc==SQLITE_BUSY ){
3385 if( nTimeout++ >= 3 ) break;
3386 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003387 }
3388 }
3389 sqlite3_backup_finish(pBackup);
3390 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003391 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003392 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003393 fprintf(stderr, "Error: source database is busy\n");
3394 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003395 }else{
3396 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003397 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003398 }
3399 sqlite3_close(pSrc);
3400 }else
3401
dan8d1edb92014-11-05 09:07:28 +00003402
3403 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3404 if( nArg==2 ){
3405 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003406#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3407 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3408#endif
dan8d1edb92014-11-05 09:07:28 +00003409 }else{
3410 fprintf(stderr, "Usage: .scanstats on|off\n");
3411 rc = 1;
3412 }
3413 }else
3414
drhc2ce0be2014-05-29 12:36:14 +00003415 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003416 ShellState data;
drh75897232000-05-29 14:26:00 +00003417 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003418 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003419 memcpy(&data, p, sizeof(data));
3420 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003421 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003422 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003423 int i;
drhf0693c82011-10-11 20:41:54 +00003424 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003425 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003426 char *new_argv[2], *new_colv[2];
3427 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3428 " type text,\n"
3429 " name text,\n"
3430 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003431 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003432 " sql text\n"
3433 ")";
3434 new_argv[1] = 0;
3435 new_colv[0] = "sql";
3436 new_colv[1] = 0;
3437 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003438 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003439 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003440 char *new_argv[2], *new_colv[2];
3441 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3442 " type text,\n"
3443 " name text,\n"
3444 " tbl_name text,\n"
3445 " rootpage integer,\n"
3446 " sql text\n"
3447 ")";
3448 new_argv[1] = 0;
3449 new_colv[0] = "sql";
3450 new_colv[1] = 0;
3451 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003452 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003453 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003454 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003455 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003456 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003457 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003458 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003459 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003460 "WHERE lower(tbl_name) LIKE shellstatic()"
3461 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003462 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003463 callback, &data, &zErrMsg);
3464 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003465 }
drhc2ce0be2014-05-29 12:36:14 +00003466 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003467 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003468 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003469 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003470 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003471 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003472 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003473 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003474 callback, &data, &zErrMsg
3475 );
drhc2ce0be2014-05-29 12:36:14 +00003476 }else{
3477 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3478 rc = 1;
3479 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003480 }
drh75897232000-05-29 14:26:00 +00003481 if( zErrMsg ){
3482 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003483 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003484 rc = 1;
3485 }else if( rc != SQLITE_OK ){
3486 fprintf(stderr,"Error: querying schema information\n");
3487 rc = 1;
3488 }else{
3489 rc = 0;
drh75897232000-05-29 14:26:00 +00003490 }
3491 }else
3492
drhabd4c722014-09-20 18:18:33 +00003493
3494#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3495 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3496 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003497 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003498 }else
3499#endif
3500
3501
drh340f5822013-06-27 13:01:21 +00003502#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003503 /* Undocumented commands for internal testing. Subject to change
3504 ** without notice. */
3505 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3506 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3507 int i, v;
3508 for(i=1; i<nArg; i++){
3509 v = booleanValue(azArg[i]);
3510 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3511 }
3512 }
3513 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3514 int i; sqlite3_int64 v;
3515 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003516 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003517 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003518 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003519 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003520 }
3521 }
3522 }else
drh340f5822013-06-27 13:01:21 +00003523#endif
drh348d19c2013-06-03 12:47:43 +00003524
drhc2ce0be2014-05-29 12:36:14 +00003525 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003526 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003527 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003528 rc = 1;
3529 }
drh6976c212014-07-24 12:09:47 +00003530 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003531 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003532 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003533 }
3534 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003535 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3536 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003537 }
drh75897232000-05-29 14:26:00 +00003538 }else
3539
drh62cdde52014-05-28 20:22:28 +00003540 if( c=='s'
3541 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003542 ){
3543 char *zCmd;
drh54027102014-08-06 14:36:53 +00003544 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003545 if( nArg<2 ){
3546 fprintf(stderr, "Usage: .system COMMAND\n");
3547 rc = 1;
3548 goto meta_command_exit;
3549 }
drhdcb3e3d2014-05-29 03:17:29 +00003550 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003551 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003552 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3553 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003554 }
drh54027102014-08-06 14:36:53 +00003555 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003556 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003557 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003558 }else
3559
drhc2ce0be2014-05-29 12:36:14 +00003560 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003561 int i;
drhc2ce0be2014-05-29 12:36:14 +00003562 if( nArg!=1 ){
3563 fprintf(stderr, "Usage: .show\n");
3564 rc = 1;
3565 goto meta_command_exit;
3566 }
mistachkin636bf9f2014-07-19 20:15:16 +00003567 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3568 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003569 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003570 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3571 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3572 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003573 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003574 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003575 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003576 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003577 fprintf(p->out,"%12.12s: ", "colseparator");
3578 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003579 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003580 fprintf(p->out,"%12.12s: ", "rowseparator");
3581 output_c_string(p->out, p->rowSeparator);
3582 fprintf(p->out, "\n");
3583 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3584 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003585 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003586 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003587 }
drhfeac5f82004-08-01 00:10:45 +00003588 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003589 }else
3590
drhc2ce0be2014-05-29 12:36:14 +00003591 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3592 if( nArg==2 ){
3593 p->statsOn = booleanValue(azArg[1]);
3594 }else{
3595 fprintf(stderr, "Usage: .stats on|off\n");
3596 rc = 1;
3597 }
shaneh642d8b82010-07-28 16:05:34 +00003598 }else
3599
drhc2ce0be2014-05-29 12:36:14 +00003600 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003601 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003602 char **azResult;
drh98781232012-04-23 12:38:05 +00003603 int nRow, nAlloc;
3604 char *zSql = 0;
3605 int ii;
drh05782482013-10-24 15:20:20 +00003606 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003607 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3608 if( rc ) return rc;
3609 zSql = sqlite3_mprintf(
3610 "SELECT name FROM sqlite_master"
3611 " WHERE type IN ('table','view')"
3612 " AND name NOT LIKE 'sqlite_%%'"
3613 " AND name LIKE ?1");
3614 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3615 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3616 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3617 if( strcmp(zDbName,"temp")==0 ){
3618 zSql = sqlite3_mprintf(
3619 "%z UNION ALL "
3620 "SELECT 'temp.' || name FROM sqlite_temp_master"
3621 " WHERE type IN ('table','view')"
3622 " AND name NOT LIKE 'sqlite_%%'"
3623 " AND name LIKE ?1", zSql);
3624 }else{
3625 zSql = sqlite3_mprintf(
3626 "%z UNION ALL "
3627 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3628 " WHERE type IN ('table','view')"
3629 " AND name NOT LIKE 'sqlite_%%'"
3630 " AND name LIKE ?1", zSql, zDbName, zDbName);
3631 }
drha50da102000-08-08 20:19:09 +00003632 }
drh98781232012-04-23 12:38:05 +00003633 sqlite3_finalize(pStmt);
3634 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3635 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3636 sqlite3_free(zSql);
3637 if( rc ) return rc;
3638 nRow = nAlloc = 0;
3639 azResult = 0;
3640 if( nArg>1 ){
3641 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003642 }else{
drh98781232012-04-23 12:38:05 +00003643 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3644 }
3645 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3646 if( nRow>=nAlloc ){
3647 char **azNew;
3648 int n = nAlloc*2 + 10;
3649 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3650 if( azNew==0 ){
3651 fprintf(stderr, "Error: out of memory\n");
3652 break;
3653 }
3654 nAlloc = n;
3655 azResult = azNew;
3656 }
3657 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3658 if( azResult[nRow] ) nRow++;
3659 }
3660 sqlite3_finalize(pStmt);
3661 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003662 int len, maxlen = 0;
3663 int i, j;
3664 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003665 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003666 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003667 if( len>maxlen ) maxlen = len;
3668 }
3669 nPrintCol = 80/(maxlen+2);
3670 if( nPrintCol<1 ) nPrintCol = 1;
3671 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3672 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003673 for(j=i; j<nRow; j+=nPrintRow){
3674 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003675 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003676 }
drh151b7d52013-05-06 20:28:54 +00003677 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003678 }
3679 }
drh98781232012-04-23 12:38:05 +00003680 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3681 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003682 }else
3683
shaneh96887e12011-02-10 21:08:58 +00003684 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003685 static const struct {
3686 const char *zCtrlName; /* Name of a test-control option */
3687 int ctrlCode; /* Integer code for that option */
3688 } aCtrl[] = {
3689 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3690 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3691 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3692 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3693 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3694 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3695 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3696 { "assert", SQLITE_TESTCTRL_ASSERT },
3697 { "always", SQLITE_TESTCTRL_ALWAYS },
3698 { "reserve", SQLITE_TESTCTRL_RESERVE },
3699 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3700 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003701 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003702 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003703 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003704 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003705 };
shaneh96887e12011-02-10 21:08:58 +00003706 int testctrl = -1;
3707 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003708 int i, n;
drh05782482013-10-24 15:20:20 +00003709 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003710
drhd416fe72011-03-17 16:45:50 +00003711 /* convert testctrl text option to value. allow any unique prefix
3712 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003713 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003714 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003715 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3716 if( testctrl<0 ){
3717 testctrl = aCtrl[i].ctrlCode;
3718 }else{
drhb07028f2011-10-14 21:49:18 +00003719 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003720 testctrl = -1;
3721 break;
3722 }
3723 }
3724 }
drh348d19c2013-06-03 12:47:43 +00003725 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003726 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3727 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3728 }else{
3729 switch(testctrl){
3730
3731 /* sqlite3_test_control(int, db, int) */
3732 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3733 case SQLITE_TESTCTRL_RESERVE:
3734 if( nArg==3 ){
3735 int opt = (int)strtol(azArg[2], 0, 0);
3736 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003737 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003738 } else {
drhd416fe72011-03-17 16:45:50 +00003739 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3740 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003741 }
3742 break;
3743
3744 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003745 case SQLITE_TESTCTRL_PRNG_SAVE:
3746 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003747 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003748 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003749 if( nArg==2 ){
3750 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003751 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003752 } else {
3753 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3754 }
3755 break;
3756
3757 /* sqlite3_test_control(int, uint) */
3758 case SQLITE_TESTCTRL_PENDING_BYTE:
3759 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003760 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003761 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003762 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003763 } else {
drhd416fe72011-03-17 16:45:50 +00003764 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3765 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003766 }
3767 break;
3768
3769 /* sqlite3_test_control(int, int) */
3770 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003771 case SQLITE_TESTCTRL_ALWAYS:
3772 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003773 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003774 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003775 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003776 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003777 } else {
drhd416fe72011-03-17 16:45:50 +00003778 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3779 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003780 }
3781 break;
3782
3783 /* sqlite3_test_control(int, char *) */
3784#ifdef SQLITE_N_KEYWORD
3785 case SQLITE_TESTCTRL_ISKEYWORD:
3786 if( nArg==3 ){
3787 const char *opt = azArg[2];
3788 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003789 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003790 } else {
drhd416fe72011-03-17 16:45:50 +00003791 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3792 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003793 }
3794 break;
3795#endif
3796
drh1ffede82015-01-30 20:59:27 +00003797 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003798 if( nArg==5 ){
3799 rc = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003800 azArg[2],
drh8964b342015-01-29 17:54:52 +00003801 integerValue(azArg[3]),
3802 integerValue(azArg[4]));
3803 }else{
drh1ffede82015-01-30 20:59:27 +00003804 fprintf(stderr,"Usage: .testctrl initmode dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003805 rc = 1;
3806 }
3807 break;
3808
shaneh96887e12011-02-10 21:08:58 +00003809 case SQLITE_TESTCTRL_BITVEC_TEST:
3810 case SQLITE_TESTCTRL_FAULT_INSTALL:
3811 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3812 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3813 default:
drhd416fe72011-03-17 16:45:50 +00003814 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3815 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003816 break;
3817 }
3818 }
3819 }else
3820
drhc2ce0be2014-05-29 12:36:14 +00003821 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003822 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003823 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003824 }else
3825
drhc2ce0be2014-05-29 12:36:14 +00003826 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3827 if( nArg==2 ){
3828 enableTimer = booleanValue(azArg[1]);
3829 if( enableTimer && !HAS_TIMER ){
3830 fprintf(stderr, "Error: timer not available on this system.\n");
3831 enableTimer = 0;
3832 }
3833 }else{
3834 fprintf(stderr, "Usage: .timer on|off\n");
3835 rc = 1;
3836 }
shanehe2aa9d72009-11-06 17:20:17 +00003837 }else
3838
drhc2ce0be2014-05-29 12:36:14 +00003839 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003840 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00003841 output_file_close(p->traceOut);
drhc2ce0be2014-05-29 12:36:14 +00003842 if( nArg!=2 ){
3843 fprintf(stderr, "Usage: .trace FILE|off\n");
3844 rc = 1;
3845 goto meta_command_exit;
3846 }
drh42f64e52012-04-04 16:56:23 +00003847 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003848#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003849 if( p->traceOut==0 ){
3850 sqlite3_trace(p->db, 0, 0);
3851 }else{
3852 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3853 }
3854#endif
3855 }else
3856
drhf442e332014-09-10 19:01:14 +00003857#if SQLITE_USER_AUTHENTICATION
3858 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3859 if( nArg<2 ){
3860 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3861 rc = 1;
3862 goto meta_command_exit;
3863 }
drh7883ecf2014-09-11 16:19:31 +00003864 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003865 if( strcmp(azArg[1],"login")==0 ){
3866 if( nArg!=4 ){
3867 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3868 rc = 1;
3869 goto meta_command_exit;
3870 }
drhd39c40f2014-09-11 00:27:53 +00003871 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3872 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003873 if( rc ){
3874 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3875 rc = 1;
3876 }
3877 }else if( strcmp(azArg[1],"add")==0 ){
3878 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003879 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003880 rc = 1;
3881 goto meta_command_exit;
3882 }
drhd39c40f2014-09-11 00:27:53 +00003883 rc = sqlite3_user_add(p->db, azArg[2],
3884 azArg[3], (int)strlen(azArg[3]),
3885 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003886 if( rc ){
3887 fprintf(stderr, "User-Add failed: %d\n", rc);
3888 rc = 1;
3889 }
3890 }else if( strcmp(azArg[1],"edit")==0 ){
3891 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003892 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003893 rc = 1;
3894 goto meta_command_exit;
3895 }
drhd39c40f2014-09-11 00:27:53 +00003896 rc = sqlite3_user_change(p->db, azArg[2],
3897 azArg[3], (int)strlen(azArg[3]),
3898 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003899 if( rc ){
3900 fprintf(stderr, "User-Edit failed: %d\n", rc);
3901 rc = 1;
3902 }
3903 }else if( strcmp(azArg[1],"delete")==0 ){
3904 if( nArg!=3 ){
3905 fprintf(stderr, "Usage: .user delete USER\n");
3906 rc = 1;
3907 goto meta_command_exit;
3908 }
3909 rc = sqlite3_user_delete(p->db, azArg[2]);
3910 if( rc ){
3911 fprintf(stderr, "User-Delete failed: %d\n", rc);
3912 rc = 1;
3913 }
3914 }else{
3915 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
3916 rc = 1;
3917 goto meta_command_exit;
3918 }
3919 }else
3920#endif /* SQLITE_USER_AUTHENTICATION */
3921
drh9fd301b2011-06-03 13:28:22 +00003922 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003923 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003924 sqlite3_libversion(), sqlite3_sourceid());
3925 }else
3926
drhde60fc22011-12-14 17:53:36 +00003927 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3928 const char *zDbName = nArg==2 ? azArg[1] : "main";
3929 char *zVfsName = 0;
3930 if( p->db ){
3931 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3932 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003933 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003934 sqlite3_free(zVfsName);
3935 }
3936 }
3937 }else
3938
drhcef4fc82012-09-21 22:50:45 +00003939#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3940 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3941 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003942 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003943 }else
3944#endif
3945
drhc2ce0be2014-05-29 12:36:14 +00003946 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003947 int j;
drh43617e92006-03-06 20:55:46 +00003948 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003949 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003950 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003951 }
3952 }else
3953
3954 {
shane9bd1b442009-10-23 01:27:39 +00003955 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003956 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003957 rc = 1;
drh75897232000-05-29 14:26:00 +00003958 }
drh67505e72002-04-19 12:34:06 +00003959
drhc2ce0be2014-05-29 12:36:14 +00003960meta_command_exit:
3961 if( p->outCount ){
3962 p->outCount--;
3963 if( p->outCount==0 ) output_reset(p);
3964 }
drh67505e72002-04-19 12:34:06 +00003965 return rc;
drh75897232000-05-29 14:26:00 +00003966}
3967
drh67505e72002-04-19 12:34:06 +00003968/*
drh91a66392007-09-07 01:12:32 +00003969** Return TRUE if a semicolon occurs anywhere in the first N characters
3970** of string z[].
drh324ccef2003-02-05 14:06:20 +00003971*/
drh9f099fd2013-08-06 14:01:46 +00003972static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00003973 int i;
3974 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3975 return 0;
drh324ccef2003-02-05 14:06:20 +00003976}
3977
3978/*
drh70c7a4b2003-04-26 03:03:06 +00003979** Test to see if a line consists entirely of whitespace.
3980*/
3981static int _all_whitespace(const char *z){
3982 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00003983 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003984 if( *z=='/' && z[1]=='*' ){
3985 z += 2;
3986 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3987 if( *z==0 ) return 0;
3988 z++;
3989 continue;
3990 }
3991 if( *z=='-' && z[1]=='-' ){
3992 z += 2;
3993 while( *z && *z!='\n' ){ z++; }
3994 if( *z==0 ) return 1;
3995 continue;
3996 }
3997 return 0;
3998 }
3999 return 1;
4000}
4001
4002/*
drha9b17162003-04-29 18:01:28 +00004003** Return TRUE if the line typed in is an SQL command terminator other
4004** than a semi-colon. The SQL Server style "go" command is understood
4005** as is the Oracle "/".
4006*/
drh9f099fd2013-08-06 14:01:46 +00004007static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004008 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004009 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4010 return 1; /* Oracle */
4011 }
drhf0693c82011-10-11 20:41:54 +00004012 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004013 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004014 return 1; /* SQL Server */
4015 }
4016 return 0;
4017}
4018
4019/*
drh233a5312008-12-18 22:25:13 +00004020** Return true if zSql is a complete SQL statement. Return false if it
4021** ends in the middle of a string literal or C-style comment.
4022*/
drh9f099fd2013-08-06 14:01:46 +00004023static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004024 int rc;
4025 if( zSql==0 ) return 1;
4026 zSql[nSql] = ';';
4027 zSql[nSql+1] = 0;
4028 rc = sqlite3_complete(zSql);
4029 zSql[nSql] = 0;
4030 return rc;
4031}
4032
4033/*
drh67505e72002-04-19 12:34:06 +00004034** Read input from *in and process it. If *in==0 then input
4035** is interactive - the user is typing it it. Otherwise, input
4036** is coming from a file or device. A prompt is issued and history
4037** is saved only if input is interactive. An interrupt signal will
4038** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004039**
4040** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004041*/
drhdcd87a92014-08-18 13:45:42 +00004042static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004043 char *zLine = 0; /* A single input line */
4044 char *zSql = 0; /* Accumulated SQL text */
4045 int nLine; /* Length of current line */
4046 int nSql = 0; /* Bytes of zSql[] used */
4047 int nAlloc = 0; /* Allocated zSql[] space */
4048 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4049 char *zErrMsg; /* Error message returned */
4050 int rc; /* Error code */
4051 int errCnt = 0; /* Number of errors seen */
4052 int lineno = 0; /* Current line number */
4053 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004054
4055 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4056 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004057 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004058 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004059 /* End of input */
4060 if( stdin_is_interactive ) printf("\n");
4061 break;
drhc49f44e2006-10-26 18:15:42 +00004062 }
drh67505e72002-04-19 12:34:06 +00004063 if( seenInterrupt ){
4064 if( in!=0 ) break;
4065 seenInterrupt = 0;
4066 }
drhc28490c2006-10-26 14:25:58 +00004067 lineno++;
drh849a9d92013-12-21 15:46:06 +00004068 if( nSql==0 && _all_whitespace(zLine) ){
4069 if( p->echoOn ) printf("%s\n", zLine);
4070 continue;
4071 }
drh2af0b2d2002-02-21 02:25:02 +00004072 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004073 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004074 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004075 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004076 break;
4077 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004078 errCnt++;
4079 }
drhdaffd0e2001-04-11 14:28:42 +00004080 continue;
4081 }
drh9f099fd2013-08-06 14:01:46 +00004082 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004083 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004084 }
drh9f099fd2013-08-06 14:01:46 +00004085 nLine = strlen30(zLine);
4086 if( nSql+nLine+2>=nAlloc ){
4087 nAlloc = nSql+nLine+100;
4088 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004089 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004090 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004091 exit(1);
4092 }
drhdaffd0e2001-04-11 14:28:42 +00004093 }
drh9f099fd2013-08-06 14:01:46 +00004094 nSqlPrior = nSql;
4095 if( nSql==0 ){
4096 int i;
4097 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004098 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004099 memcpy(zSql, zLine+i, nLine+1-i);
4100 startline = lineno;
4101 nSql = nLine-i;
4102 }else{
4103 zSql[nSql++] = '\n';
4104 memcpy(zSql+nSql, zLine, nLine+1);
4105 nSql += nLine;
4106 }
4107 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004108 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004109 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004110 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00004111 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004112 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004113 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004114 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004115 char zPrefix[100];
4116 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004117 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004118 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004119 }else{
shane9bd1b442009-10-23 01:27:39 +00004120 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004121 }
drh7f953e22002-07-13 17:33:45 +00004122 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004123 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004124 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004125 zErrMsg = 0;
4126 }else{
shaned2bed1c2009-10-21 03:56:54 +00004127 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004128 }
drhc49f44e2006-10-26 18:15:42 +00004129 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004130 }
drhdaffd0e2001-04-11 14:28:42 +00004131 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004132 if( p->outCount ){
4133 output_reset(p);
4134 p->outCount = 0;
4135 }
drh9f099fd2013-08-06 14:01:46 +00004136 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004137 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004138 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004139 }
4140 }
drh9f099fd2013-08-06 14:01:46 +00004141 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004142 if( !_all_whitespace(zSql) ){
4143 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004144 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004145 }
drhdaffd0e2001-04-11 14:28:42 +00004146 free(zSql);
4147 }
danielk19772ac27622007-07-03 05:31:16 +00004148 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004149 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004150}
4151
drh67505e72002-04-19 12:34:06 +00004152/*
4153** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004154** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004155*/
4156static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004157 static char *home_dir = NULL;
4158 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004159
drh4ace5362014-11-10 14:42:28 +00004160#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4161 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004162 {
4163 struct passwd *pwent;
4164 uid_t uid = getuid();
4165 if( (pwent=getpwuid(uid)) != NULL) {
4166 home_dir = pwent->pw_dir;
4167 }
drh67505e72002-04-19 12:34:06 +00004168 }
4169#endif
4170
chw65d3c132007-11-12 21:09:10 +00004171#if defined(_WIN32_WCE)
4172 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4173 */
drh85e72432012-04-11 11:38:53 +00004174 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004175#else
4176
drh83905c92012-06-21 13:00:37 +00004177#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004178 if (!home_dir) {
4179 home_dir = getenv("USERPROFILE");
4180 }
4181#endif
4182
drh67505e72002-04-19 12:34:06 +00004183 if (!home_dir) {
4184 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004185 }
4186
drh83905c92012-06-21 13:00:37 +00004187#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004188 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004189 char *zDrive, *zPath;
4190 int n;
4191 zDrive = getenv("HOMEDRIVE");
4192 zPath = getenv("HOMEPATH");
4193 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004194 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004195 home_dir = malloc( n );
4196 if( home_dir==0 ) return 0;
4197 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4198 return home_dir;
4199 }
4200 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004201 }
4202#endif
4203
chw65d3c132007-11-12 21:09:10 +00004204#endif /* !_WIN32_WCE */
4205
drh67505e72002-04-19 12:34:06 +00004206 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004207 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004208 char *z = malloc( n );
4209 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004210 home_dir = z;
4211 }
drhe98d4fa2002-04-21 19:06:22 +00004212
drh67505e72002-04-19 12:34:06 +00004213 return home_dir;
4214}
4215
4216/*
4217** Read input from the file given by sqliterc_override. Or if that
4218** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004219**
4220** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004221*/
shane9bd1b442009-10-23 01:27:39 +00004222static int process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004223 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004224 const char *sqliterc_override /* Name of config file. NULL to use default */
4225){
persicom7e2dfdd2002-04-18 02:46:52 +00004226 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004227 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004228 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004229 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00004230 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004231
4232 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004233 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004234 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00004235#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00004236 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00004237#endif
shane9bd1b442009-10-23 01:27:39 +00004238 return 1;
drhe98d4fa2002-04-21 19:06:22 +00004239 }
drh2f3de322012-06-27 16:41:31 +00004240 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004241 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4242 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004243 }
drha1f9b5e2004-02-14 16:31:02 +00004244 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004245 if( in ){
drhc28490c2006-10-26 14:25:58 +00004246 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004247 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004248 }
shane9bd1b442009-10-23 01:27:39 +00004249 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004250 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004251 }
drh85e72432012-04-11 11:38:53 +00004252 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00004253 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00004254}
4255
drh67505e72002-04-19 12:34:06 +00004256/*
drhe1e38c42003-05-04 18:30:59 +00004257** Show available command line options
4258*/
4259static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004260 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004261 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004262 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004263 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004264 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004265 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004266 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004267 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004268 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004269#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4270 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4271#endif
drhcc3b4f82012-02-07 14:13:50 +00004272 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004273 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004274 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004275 " -line set output mode to 'line'\n"
4276 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004277 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004278 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004279#ifdef SQLITE_ENABLE_MULTIPLEX
4280 " -multiplex enable the multiplexor VFS\n"
4281#endif
mistachkine0d68852014-12-11 03:12:33 +00004282 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004283 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004284 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4285 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004286 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004287 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004288 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004289 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004290#ifdef SQLITE_ENABLE_VFSTRACE
4291 " -vfstrace enable tracing of all VFS calls\n"
4292#endif
drhe1e38c42003-05-04 18:30:59 +00004293;
4294static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004295 fprintf(stderr,
4296 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4297 "FILENAME is the name of an SQLite database. A new database is created\n"
4298 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004299 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004300 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004301 }else{
4302 fprintf(stderr, "Use the -help option for additional information\n");
4303 }
4304 exit(1);
4305}
4306
4307/*
drh67505e72002-04-19 12:34:06 +00004308** Initialize the state information in data
4309*/
drhdcd87a92014-08-18 13:45:42 +00004310static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004311 memset(data, 0, sizeof(*data));
4312 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004313 memcpy(data->colSeparator,SEP_Column, 2);
4314 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004315 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004316 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004317 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004318 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004319 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004320 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4321 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004322}
4323
drh98d312f2012-10-25 15:23:14 +00004324/*
drh5c7976f2014-02-10 19:59:27 +00004325** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004326*/
4327#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004328static void printBold(const char *zText){
4329 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4330 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4331 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4332 SetConsoleTextAttribute(out,
4333 FOREGROUND_RED|FOREGROUND_INTENSITY
4334 );
4335 printf("%s", zText);
4336 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004337}
4338#else
drh5c7976f2014-02-10 19:59:27 +00004339static void printBold(const char *zText){
4340 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004341}
4342#endif
4343
4344/*
drh98d312f2012-10-25 15:23:14 +00004345** Get the argument to an --option. Throw an error and die if no argument
4346** is available.
4347*/
4348static char *cmdline_option_value(int argc, char **argv, int i){
4349 if( i==argc ){
4350 fprintf(stderr, "%s: Error: missing argument to %s\n",
4351 argv[0], argv[argc-1]);
4352 exit(1);
4353 }
4354 return argv[i];
4355}
4356
drh75897232000-05-29 14:26:00 +00004357int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004358 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004359 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004360 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004361 int i;
drhc28490c2006-10-26 14:25:58 +00004362 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004363 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004364 int readStdin = 1;
4365 int nCmd = 0;
4366 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004367
drh69b30ab2014-02-27 15:11:52 +00004368#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004369 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4370 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4371 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4372 exit(1);
4373 }
drhc7181902014-02-27 15:04:13 +00004374#endif
drh047d4532015-01-18 20:30:23 +00004375 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004376 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004377 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004378 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004379 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004380
drh44c2eb12003-04-30 11:38:26 +00004381 /* Make sure we have a valid signal handler early, before anything
4382 ** else is done.
4383 */
drh4c504392000-10-16 22:06:40 +00004384#ifdef SIGINT
4385 signal(SIGINT, interrupt_handler);
4386#endif
drh44c2eb12003-04-30 11:38:26 +00004387
drhac5649a2014-11-28 13:35:03 +00004388#ifdef SQLITE_SHELL_DBNAME_PROC
4389 {
4390 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4391 ** of a C-function that will provide the name of the database file. Use
4392 ** this compile-time option to embed this shell program in larger
4393 ** applications. */
4394 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4395 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4396 warnInmemoryDb = 0;
4397 }
4398#endif
4399
drh22fbcb82004-02-01 01:22:50 +00004400 /* Do an initial pass through the command-line argument to locate
4401 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004402 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004403 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004404 */
drh98d312f2012-10-25 15:23:14 +00004405 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004406 char *z;
drhc28490c2006-10-26 14:25:58 +00004407 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004408 if( z[0]!='-' ){
4409 if( data.zDbFilename==0 ){
4410 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004411 }else{
4412 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4413 ** mean that nothing is read from stdin */
4414 readStdin = 0;
4415 nCmd++;
4416 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4417 if( azCmd==0 ){
4418 fprintf(stderr, "out of memory\n");
4419 exit(1);
4420 }
4421 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004422 }
drh98d312f2012-10-25 15:23:14 +00004423 }
drhcc3b4f82012-02-07 14:13:50 +00004424 if( z[1]=='-' ) z++;
4425 if( strcmp(z,"-separator")==0
4426 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004427 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004428 || strcmp(z,"-cmd")==0
4429 ){
drh98d312f2012-10-25 15:23:14 +00004430 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004431 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004432 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004433 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004434 /* Need to check for batch mode here to so we can avoid printing
4435 ** informational messages (like from process_sqliterc) before
4436 ** we do the actual processing of arguments later in a second pass.
4437 */
shanef69573d2009-10-24 02:06:14 +00004438 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004439 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004440#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004441 const char *zSize;
4442 sqlite3_int64 szHeap;
4443
drh98d312f2012-10-25 15:23:14 +00004444 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004445 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004446 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004447 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4448#endif
drh44dec872014-08-30 15:49:25 +00004449 }else if( strcmp(z,"-scratch")==0 ){
4450 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004451 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004452 if( sz>400000 ) sz = 400000;
4453 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004454 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004455 if( n>10 ) n = 10;
4456 if( n<1 ) n = 1;
4457 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4458 data.shellFlgs |= SHFLG_Scratch;
4459 }else if( strcmp(z,"-pagecache")==0 ){
4460 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004461 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004462 if( sz>70000 ) sz = 70000;
4463 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004464 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004465 if( n<10 ) n = 10;
4466 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4467 data.shellFlgs |= SHFLG_Pagecache;
4468 }else if( strcmp(z,"-lookaside")==0 ){
4469 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004470 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004471 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004472 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004473 if( n<0 ) n = 0;
4474 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4475 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004476#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004477 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004478 extern int vfstrace_register(
4479 const char *zTraceName,
4480 const char *zOldVfsName,
4481 int (*xOut)(const char*,void*),
4482 void *pOutArg,
4483 int makeDefault
4484 );
drh2b625e22011-03-16 17:05:28 +00004485 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004486#endif
drh6f25e892011-07-08 17:02:57 +00004487#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004488 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004489 extern int sqlite3_multiple_initialize(const char*,int);
4490 sqlite3_multiplex_initialize(0, 1);
4491#endif
drh7d9f3942013-04-03 01:26:54 +00004492 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004493 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4494 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004495 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004496 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004497 if( pVfs ){
4498 sqlite3_vfs_register(pVfs, 1);
4499 }else{
4500 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4501 exit(1);
4502 }
drh44c2eb12003-04-30 11:38:26 +00004503 }
4504 }
drh98d312f2012-10-25 15:23:14 +00004505 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004506#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004507 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004508 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004509#else
shane86f5bdb2009-10-24 02:00:07 +00004510 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4511 return 1;
drh01b41712005-08-29 23:06:23 +00004512#endif
drh98d312f2012-10-25 15:23:14 +00004513 }
4514 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004515
drh44c2eb12003-04-30 11:38:26 +00004516 /* Go ahead and open the database file if it already exists. If the
4517 ** file does not exist, delay opening it. This prevents empty database
4518 ** files from being created if a user mistypes the database name argument
4519 ** to the sqlite command-line tool.
4520 */
drhc8d74412004-08-31 23:41:26 +00004521 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004522 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004523 }
4524
drh22fbcb82004-02-01 01:22:50 +00004525 /* Process the initialization file if there is one. If no -init option
4526 ** is given on the command line, look for a file named ~/.sqliterc and
4527 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004528 */
shane86f5bdb2009-10-24 02:00:07 +00004529 rc = process_sqliterc(&data,zInitFile);
4530 if( rc>0 ){
4531 return rc;
4532 }
drh44c2eb12003-04-30 11:38:26 +00004533
drh22fbcb82004-02-01 01:22:50 +00004534 /* Make a second pass through the command-line argument and set
4535 ** options. This second pass is delayed until after the initialization
4536 ** file is processed so that the command-line arguments will override
4537 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004538 */
drh98d312f2012-10-25 15:23:14 +00004539 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004540 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004541 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004542 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004543 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004544 i++;
4545 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004546 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004547 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004548 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004549 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004550 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004551 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004552 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004553 }else if( strcmp(z,"-csv")==0 ){
4554 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004555 memcpy(data.colSeparator,",",2);
4556 }else if( strcmp(z,"-ascii")==0 ){
4557 data.mode = MODE_Ascii;
4558 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004559 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004560 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004561 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004562 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004563 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4564 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004565 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004566 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004567 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004568 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004569 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004570 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004571 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004572 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004573 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004574 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004575 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004576 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004577 }else if( strcmp(z,"-eqp")==0 ){
4578 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004579 }else if( strcmp(z,"-stats")==0 ){
4580 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004581 }else if( strcmp(z,"-scanstats")==0 ){
4582 data.scanstatsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004583 }else if( strcmp(z,"-bail")==0 ){
4584 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004585 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004586 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004587 return 0;
drhc28490c2006-10-26 14:25:58 +00004588 }else if( strcmp(z,"-interactive")==0 ){
4589 stdin_is_interactive = 1;
4590 }else if( strcmp(z,"-batch")==0 ){
4591 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004592 }else if( strcmp(z,"-heap")==0 ){
4593 i++;
drh44dec872014-08-30 15:49:25 +00004594 }else if( strcmp(z,"-scratch")==0 ){
4595 i+=2;
4596 }else if( strcmp(z,"-pagecache")==0 ){
4597 i+=2;
4598 }else if( strcmp(z,"-lookaside")==0 ){
4599 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004600 }else if( strcmp(z,"-mmap")==0 ){
4601 i++;
drha7e61d82011-03-12 17:02:57 +00004602 }else if( strcmp(z,"-vfs")==0 ){
4603 i++;
drh6f25e892011-07-08 17:02:57 +00004604#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004605 }else if( strcmp(z,"-vfstrace")==0 ){
4606 i++;
drh6f25e892011-07-08 17:02:57 +00004607#endif
4608#ifdef SQLITE_ENABLE_MULTIPLEX
4609 }else if( strcmp(z,"-multiplex")==0 ){
4610 i++;
4611#endif
drhcc3b4f82012-02-07 14:13:50 +00004612 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004613 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004614 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004615 /* Run commands that follow -cmd first and separately from commands
4616 ** that simply appear on the command-line. This seems goofy. It would
4617 ** be better if all commands ran in the order that they appear. But
4618 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004619 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004620 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004621 if( z[0]=='.' ){
4622 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004623 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004624 }else{
drh05782482013-10-24 15:20:20 +00004625 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004626 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4627 if( zErrMsg!=0 ){
4628 fprintf(stderr,"Error: %s\n", zErrMsg);
4629 if( bail_on_error ) return rc!=0 ? rc : 1;
4630 }else if( rc!=0 ){
4631 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4632 if( bail_on_error ) return rc;
4633 }
4634 }
drh1e5d0e92000-05-31 23:33:17 +00004635 }else{
shane86f5bdb2009-10-24 02:00:07 +00004636 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004637 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004638 return 1;
4639 }
4640 }
drh44c2eb12003-04-30 11:38:26 +00004641
drhac5649a2014-11-28 13:35:03 +00004642 if( !readStdin ){
4643 /* Run all arguments that do not begin with '-' as if they were separate
4644 ** command-line inputs, except for the argToSkip argument which contains
4645 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004646 */
drhac5649a2014-11-28 13:35:03 +00004647 for(i=0; i<nCmd; i++){
4648 if( azCmd[i][0]=='.' ){
4649 rc = do_meta_command(azCmd[i], &data);
4650 if( rc ) return rc==2 ? 0 : rc;
4651 }else{
4652 open_db(&data, 0);
4653 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4654 if( zErrMsg!=0 ){
4655 fprintf(stderr,"Error: %s\n", zErrMsg);
4656 return rc!=0 ? rc : 1;
4657 }else if( rc!=0 ){
4658 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4659 return rc;
4660 }
drh6ff13852001-11-25 13:18:23 +00004661 }
drh75897232000-05-29 14:26:00 +00004662 }
drhac5649a2014-11-28 13:35:03 +00004663 free(azCmd);
drh75897232000-05-29 14:26:00 +00004664 }else{
drh44c2eb12003-04-30 11:38:26 +00004665 /* Run commands received from standard input
4666 */
drhc28490c2006-10-26 14:25:58 +00004667 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004668 char *zHome;
4669 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004670 int nHistory;
drh75897232000-05-29 14:26:00 +00004671 printf(
drh743e0032011-12-12 16:51:50 +00004672 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004673 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004674 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004675 );
drhb3735912014-02-10 16:13:42 +00004676 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004677 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004678 printBold("transient in-memory database");
4679 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004680 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004681 }
drh67505e72002-04-19 12:34:06 +00004682 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004683 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004684 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004685 if( (zHistory = malloc(nHistory))!=0 ){
4686 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4687 }
drh67505e72002-04-19 12:34:06 +00004688 }
danfd34d6d2015-02-25 10:54:53 +00004689 if( zHistory ) shell_read_history(zHistory);
drhc28490c2006-10-26 14:25:58 +00004690 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004691 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004692 shell_stifle_history(100);
4693 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004694 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004695 }
drhdaffd0e2001-04-11 14:28:42 +00004696 }else{
drhc28490c2006-10-26 14:25:58 +00004697 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004698 }
4699 }
drh33048c02001-10-01 14:29:22 +00004700 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004701 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004702 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004703 }
drh05782482013-10-24 15:20:20 +00004704 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004705 return rc;
drh75897232000-05-29 14:26:00 +00004706}