blob: c1d8f183333e8d5b3cf9a5335e595b6e664af5d1 [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/*
21** Enable large-file support for fopen() and friends on unix.
22*/
23#ifndef SQLITE_DISABLE_LFS
24# define _LARGE_FILE 1
25# ifndef _FILE_OFFSET_BITS
26# define _FILE_OFFSET_BITS 64
27# endif
28# define _LARGEFILE_SOURCE 1
29#endif
30
drh75897232000-05-29 14:26:00 +000031#include <stdlib.h>
32#include <string.h>
33#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000034#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000035#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000036#if SQLITE_USER_AUTHENTICATION
37# include "sqlite3userauth.h"
38#endif
drh75897232000-05-29 14:26:00 +000039#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000040#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000041
drh83905c92012-06-21 13:00:37 +000042#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000043# include <signal.h>
chw97185482008-11-17 08:05:31 +000044# if !defined(__RTP__) && !defined(_WRS_KERNEL)
45# include <pwd.h>
46# endif
drhdd45df82002-04-18 12:39:03 +000047# include <unistd.h>
48# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000049#endif
drh75897232000-05-29 14:26:00 +000050
drhaaa21b42014-02-11 14:37:51 +000051#if defined(HAVE_READLINE) && HAVE_READLINE!=0
drh8e7e7a22000-05-30 18:45:23 +000052# include <readline/readline.h>
53# include <readline/history.h>
drhaaa21b42014-02-11 14:37:51 +000054#else
55# undef HAVE_READLINE
drh81d7fd12010-12-08 00:02:26 +000056#endif
drhaaa21b42014-02-11 14:37:51 +000057#if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE)
58# define HAVE_READLINE 1
59# include <editline/readline.h>
60#endif
61#if !defined(HAVE_READLINE)
persicom1d0b8722002-04-18 02:53:04 +000062# define add_history(X)
drh67505e72002-04-19 12:34:06 +000063# define read_history(X)
64# define write_history(X)
65# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000066#endif
67
adamd2e8464a2006-09-06 21:39:40 +000068#if defined(_WIN32) || defined(WIN32)
69# include <io.h>
drh6976c212014-07-24 12:09:47 +000070# include <fcntl.h>
shane18e526c2008-12-10 22:30:24 +000071#define isatty(h) _isatty(h)
drh07901eb2014-02-28 19:37:45 +000072#ifndef access
73# define access(f,m) _access((f),(m))
74#endif
drh67ceaa62012-08-27 21:19:03 +000075#undef popen
drh53371f92013-07-25 17:07:03 +000076#define popen _popen
drh67ceaa62012-08-27 21:19:03 +000077#undef pclose
drh12cd6cf2013-06-29 15:40:22 +000078#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +000079#else
drh4328c8b2003-04-26 02:50:11 +000080/* Make sure isatty() has a prototype.
81*/
drhb2acc3b2011-10-13 16:36:29 +000082extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +000083
drh53371f92013-07-25 17:07:03 +000084/* popen and pclose are not C89 functions and so are sometimes omitted from
85** the <stdio.h> header */
mistachkinf6418892013-08-28 01:54:12 +000086extern FILE *popen(const char*,const char*);
87extern int pclose(FILE*);
88#endif
drh53371f92013-07-25 17:07:03 +000089
chw65d3c132007-11-12 21:09:10 +000090#if defined(_WIN32_WCE)
91/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
92 * thus we always assume that we have a console. That can be
93 * overridden with the -batch command line option.
94 */
95#define isatty(x) 1
96#endif
97
drhf0693c82011-10-11 20:41:54 +000098/* ctype macros that work with signed characters */
99#define IsSpace(X) isspace((unsigned char)X)
100#define IsDigit(X) isdigit((unsigned char)X)
101#define ToLower(X) (char)tolower((unsigned char)X)
102
drh43408312013-10-30 12:43:36 +0000103
104/* True if the timer is enabled */
105static int enableTimer = 0;
106
107/* Return the current wall-clock time */
108static sqlite3_int64 timeOfDay(void){
109 static sqlite3_vfs *clockVfs = 0;
110 sqlite3_int64 t;
111 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
112 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
113 clockVfs->xCurrentTimeInt64(clockVfs, &t);
114 }else{
115 double r;
116 clockVfs->xCurrentTime(clockVfs, &r);
117 t = (sqlite3_int64)(r*86400000.0);
118 }
119 return t;
120}
121
drhd5d0f642013-02-20 00:54:21 +0000122#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
123 && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000124#include <sys/time.h>
125#include <sys/resource.h>
126
drhda108222009-02-25 19:07:24 +0000127/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000128static struct rusage sBegin; /* CPU time at start */
129static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000130
drhda108222009-02-25 19:07:24 +0000131/*
132** Begin timing an operation
133*/
134static void beginTimer(void){
135 if( enableTimer ){
136 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000137 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000138 }
139}
140
141/* Return the difference of two time_structs in seconds */
142static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
143 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
144 (double)(pEnd->tv_sec - pStart->tv_sec);
145}
146
147/*
148** Print the timing results.
149*/
150static void endTimer(void){
151 if( enableTimer ){
152 struct rusage sEnd;
drh43408312013-10-30 12:43:36 +0000153 sqlite3_int64 iEnd = timeOfDay();
drhda108222009-02-25 19:07:24 +0000154 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000155 printf("Run Time: real %.3f user %f sys %f\n",
156 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000157 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
158 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
159 }
160}
shaneb320ccd2009-10-21 03:42:58 +0000161
drhda108222009-02-25 19:07:24 +0000162#define BEGIN_TIMER beginTimer()
163#define END_TIMER endTimer()
164#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000165
166#elif (defined(_WIN32) || defined(WIN32))
167
168#include <windows.h>
169
170/* Saved resource information for the beginning of an operation */
171static HANDLE hProcess;
172static FILETIME ftKernelBegin;
173static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000174static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000175typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
176 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000177static GETPROCTIMES getProcessTimesAddr = NULL;
178
shaneb320ccd2009-10-21 03:42:58 +0000179/*
180** Check to see if we have timer support. Return 1 if necessary
181** support found (or found previously).
182*/
183static int hasTimer(void){
184 if( getProcessTimesAddr ){
185 return 1;
186 } else {
drh4ace5362014-11-10 14:42:28 +0000187 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
188 ** versions. See if the version we are running on has it, and if it
189 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000190 */
191 hProcess = GetCurrentProcess();
192 if( hProcess ){
193 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
194 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000195 getProcessTimesAddr =
196 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000197 if( NULL != getProcessTimesAddr ){
198 return 1;
199 }
200 FreeLibrary(hinstLib);
201 }
202 }
203 }
204 return 0;
205}
206
207/*
208** Begin timing an operation
209*/
210static void beginTimer(void){
211 if( enableTimer && getProcessTimesAddr ){
212 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000213 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
214 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000215 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000216 }
217}
218
219/* Return the difference of two FILETIME structs in seconds */
220static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
221 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
222 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
223 return (double) ((i64End - i64Start) / 10000000.0);
224}
225
226/*
227** Print the timing results.
228*/
229static void endTimer(void){
230 if( enableTimer && getProcessTimesAddr){
231 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000232 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000233 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000234 printf("Run Time: real %.3f user %f sys %f\n",
235 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000236 timeDiff(&ftUserBegin, &ftUserEnd),
237 timeDiff(&ftKernelBegin, &ftKernelEnd));
238 }
239}
240
241#define BEGIN_TIMER beginTimer()
242#define END_TIMER endTimer()
243#define HAS_TIMER hasTimer()
244
drhda108222009-02-25 19:07:24 +0000245#else
246#define BEGIN_TIMER
247#define END_TIMER
248#define HAS_TIMER 0
249#endif
250
shanec0688ea2009-03-05 03:48:06 +0000251/*
252** Used to prevent warnings about unused parameters
253*/
254#define UNUSED_PARAMETER(x) (void)(x)
255
drhe91d16b2008-12-08 18:27:31 +0000256/*
drhc49f44e2006-10-26 18:15:42 +0000257** If the following flag is set, then command execution stops
258** at an error if we are not interactive.
259*/
260static int bail_on_error = 0;
261
262/*
drhc28490c2006-10-26 14:25:58 +0000263** Threat stdin as an interactive input if the following variable
264** is true. Otherwise, assume stdin is connected to a file or pipe.
265*/
266static int stdin_is_interactive = 1;
267
268/*
drh4c504392000-10-16 22:06:40 +0000269** The following is the open SQLite database. We make a pointer
270** to this database a static variable so that it can be accessed
271** by the SIGINT handler to interrupt database processing.
272*/
danielk197792f9a1b2004-06-19 09:08:16 +0000273static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000274
275/*
drh67505e72002-04-19 12:34:06 +0000276** True if an interrupt (Control-C) has been received.
277*/
drh43617e92006-03-06 20:55:46 +0000278static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000279
280/*
persicom7e2dfdd2002-04-18 02:46:52 +0000281** This is the name of our program. It is set in main(), used
282** in a number of other places, mostly for error messages.
283*/
284static char *Argv0;
285
286/*
287** Prompt strings. Initialized in main. Settable with
288** .prompt main continue
289*/
290static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
291static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
292
drhb0603412007-02-28 04:47:26 +0000293/*
294** Write I/O traces to the following stream.
295*/
rsebe0a9092007-07-30 18:24:38 +0000296#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000297static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000298#endif
drhb0603412007-02-28 04:47:26 +0000299
300/*
301** This routine works like printf in that its first argument is a
302** format string and subsequent arguments are values to be substituted
303** in place of % fields. The result of formatting this string
304** is written to iotrace.
305*/
rsebe0a9092007-07-30 18:24:38 +0000306#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000307static void iotracePrintf(const char *zFormat, ...){
308 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000309 char *z;
drhb0603412007-02-28 04:47:26 +0000310 if( iotrace==0 ) return;
311 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000312 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000313 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000314 fprintf(iotrace, "%s", z);
315 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000316}
rsebe0a9092007-07-30 18:24:38 +0000317#endif
drhb0603412007-02-28 04:47:26 +0000318
drh44c2eb12003-04-30 11:38:26 +0000319
persicom7e2dfdd2002-04-18 02:46:52 +0000320/*
drh83965662003-04-17 02:54:13 +0000321** Determines if a string is a number of not.
322*/
danielk19772e588c72005-12-09 14:25:08 +0000323static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000324 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000325 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000326 return 0;
327 }
328 z++;
329 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000330 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000331 if( *z=='.' ){
332 z++;
drhf0693c82011-10-11 20:41:54 +0000333 if( !IsDigit(*z) ) return 0;
334 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000335 if( realnum ) *realnum = 1;
336 }
337 if( *z=='e' || *z=='E' ){
338 z++;
339 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000340 if( !IsDigit(*z) ) return 0;
341 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000342 if( realnum ) *realnum = 1;
343 }
344 return *z==0;
345}
drh83965662003-04-17 02:54:13 +0000346
347/*
danielk1977bc6ada42004-06-30 08:20:16 +0000348** A global char* and an SQL function to access its current value
349** from within an SQL statement. This program used to use the
350** sqlite_exec_printf() API to substitue a string into an SQL statement.
351** The correct way to do this with sqlite3 is to use the bind API, but
352** since the shell is built around the callback paradigm it would be a lot
353** of work. Instead just use this hack, which is quite harmless.
354*/
355static const char *zShellStatic = 0;
356static void shellstaticFunc(
357 sqlite3_context *context,
358 int argc,
359 sqlite3_value **argv
360){
361 assert( 0==argc );
362 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000363 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000364 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000365 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
366}
367
368
369/*
drhfeac5f82004-08-01 00:10:45 +0000370** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000371** the text in memory obtained from malloc() and returns a pointer
372** to the text. NULL is returned at end of file, or if malloc()
373** fails.
374**
drh9f099fd2013-08-06 14:01:46 +0000375** If zLine is not NULL then it is a malloced buffer returned from
376** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000377*/
drh9f099fd2013-08-06 14:01:46 +0000378static char *local_getline(char *zLine, FILE *in){
379 int nLine = zLine==0 ? 0 : 100;
380 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000381
drhb07028f2011-10-14 21:49:18 +0000382 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000383 if( n+100>nLine ){
384 nLine = nLine*2 + 100;
385 zLine = realloc(zLine, nLine);
386 if( zLine==0 ) return 0;
387 }
drhdaffd0e2001-04-11 14:28:42 +0000388 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000389 if( n==0 ){
390 free(zLine);
391 return 0;
392 }
393 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000394 break;
395 }
drh9f099fd2013-08-06 14:01:46 +0000396 while( zLine[n] ) n++;
397 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000398 n--;
shaneh13b36022009-12-17 21:07:15 +0000399 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000400 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000401 break;
drh8e7e7a22000-05-30 18:45:23 +0000402 }
403 }
drh8e7e7a22000-05-30 18:45:23 +0000404 return zLine;
405}
406
407/*
drhc28490c2006-10-26 14:25:58 +0000408** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000409**
drh9f099fd2013-08-06 14:01:46 +0000410** If in==0 then read from standard input and prompt before each line.
411** If isContinuation is true, then a continuation prompt is appropriate.
412** If isContinuation is zero, then the main prompt should be used.
413**
414** If zPrior is not NULL then it is a buffer from a prior call to this
415** routine that can be reused.
416**
417** The result is stored in space obtained from malloc() and must either
418** be freed by the caller or else passed back into this routine via the
419** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000420*/
drh9f099fd2013-08-06 14:01:46 +0000421static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000422 char *zPrompt;
423 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000424 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000425 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000426 }else{
drh9f099fd2013-08-06 14:01:46 +0000427 zPrompt = isContinuation ? continuePrompt : mainPrompt;
drhaaa21b42014-02-11 14:37:51 +0000428#if defined(HAVE_READLINE)
drh9f099fd2013-08-06 14:01:46 +0000429 free(zPrior);
430 zResult = readline(zPrompt);
431 if( zResult && *zResult ) add_history(zResult);
432#else
433 printf("%s", zPrompt);
434 fflush(stdout);
435 zResult = local_getline(zPrior, stdin);
danielk19774af00c62005-01-23 23:43:21 +0000436#endif
drh9f099fd2013-08-06 14:01:46 +0000437 }
drh8e7e7a22000-05-30 18:45:23 +0000438 return zResult;
439}
440
drhdcd87a92014-08-18 13:45:42 +0000441/*
442** Shell output mode information from before ".explain on",
443** saved so that it can be restored by ".explain off"
444*/
445typedef struct SavedModeInfo SavedModeInfo;
446struct SavedModeInfo {
447 int valid; /* Is there legit data in here? */
448 int mode; /* Mode prior to ".explain on" */
449 int showHeader; /* The ".header" setting prior to ".explain on" */
450 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000451};
drh45e29d82006-11-20 16:21:10 +0000452
drh8e7e7a22000-05-30 18:45:23 +0000453/*
drhdcd87a92014-08-18 13:45:42 +0000454** State information about the database connection is contained in an
455** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000456*/
drhdcd87a92014-08-18 13:45:42 +0000457typedef struct ShellState ShellState;
458struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000459 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000460 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000461 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000462 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000463 int scanstatsOn; /* True to display scan stats before each finalize */
drhc2ce0be2014-05-29 12:36:14 +0000464 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000465 int cnt; /* Number of records displayed so far */
466 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000467 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000468 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000469 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000470 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000471 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000472 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000473 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000474 char colSeparator[20]; /* Column separator character for several modes */
475 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drh6976c212014-07-24 12:09:47 +0000476 char newline[20]; /* Record separator in MODE_Csv */
drha0c66f52000-07-29 13:20:21 +0000477 int colWidth[100]; /* Requested width of each column when in column mode*/
478 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000479 char nullvalue[20]; /* The text to print when a NULL comes back from
480 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000481 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000482 char outfile[FILENAME_MAX]; /* Filename for *out */
483 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000484 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000485 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000486 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000487 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000488 int *aiIndent; /* Array of indents used in MODE_Explain */
489 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000490 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000491};
492
493/*
drh44dec872014-08-30 15:49:25 +0000494** These are the allowed shellFlgs values
495*/
496#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
497#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
498#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
499
500/*
drh75897232000-05-29 14:26:00 +0000501** These are the allowed modes.
502*/
drh967e8b72000-06-21 13:59:10 +0000503#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000504#define MODE_Column 1 /* One record per line in neat columns */
505#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000506#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
507#define MODE_Html 4 /* Generate an XHTML table */
508#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000509#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000510#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000511#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000512#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000513
drh66ce4d02008-02-15 17:38:06 +0000514static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000515 "line",
516 "column",
517 "list",
518 "semi",
519 "html",
drhfeac5f82004-08-01 00:10:45 +0000520 "insert",
521 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000522 "csv",
drh66ce4d02008-02-15 17:38:06 +0000523 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000524 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000525};
drh75897232000-05-29 14:26:00 +0000526
527/*
mistachkinfad42082014-07-24 22:13:12 +0000528** These are the column/row/line separators used by the various
529** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000530*/
mistachkinfad42082014-07-24 22:13:12 +0000531#define SEP_Column "|"
532#define SEP_Row "\n"
533#define SEP_Tab "\t"
534#define SEP_Space " "
535#define SEP_Comma ","
536#define SEP_CrLf "\r\n"
537#define SEP_Unit "\x1F"
538#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000539
540/*
drh75897232000-05-29 14:26:00 +0000541** Number of elements in an array
542*/
drh902b9ee2008-12-05 17:17:07 +0000543#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000544
545/*
drhea678832008-12-10 19:26:22 +0000546** Compute a string length that is limited to what can be stored in
547** lower 30 bits of a 32-bit signed integer.
548*/
drh4f21c4a2008-12-10 22:15:00 +0000549static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000550 const char *z2 = z;
551 while( *z2 ){ z2++; }
552 return 0x3fffffff & (int)(z2 - z);
553}
554
555/*
drh127f9d72010-02-23 01:47:00 +0000556** A callback for the sqlite3_log() interface.
557*/
558static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000559 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000560 if( p->pLog==0 ) return;
561 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
562 fflush(p->pLog);
563}
564
565/*
shane626a6e42009-10-22 17:30:15 +0000566** Output the given string as a hex-encoded blob (eg. X'1234' )
567*/
568static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
569 int i;
570 char *zBlob = (char *)pBlob;
571 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000572 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000573 fprintf(out,"'");
574}
575
576/*
drh28bd4bc2000-06-15 15:57:22 +0000577** Output the given string as a quoted string using SQL quoting conventions.
578*/
579static void output_quoted_string(FILE *out, const char *z){
580 int i;
581 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000582 for(i=0; z[i]; i++){
583 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000584 }
585 if( nSingle==0 ){
586 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000587 }else{
588 fprintf(out,"'");
589 while( *z ){
590 for(i=0; z[i] && z[i]!='\''; i++){}
591 if( i==0 ){
592 fprintf(out,"''");
593 z++;
594 }else if( z[i]=='\'' ){
595 fprintf(out,"%.*s''",i,z);
596 z += i+1;
597 }else{
drhcd7d2732002-02-26 23:24:26 +0000598 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000599 break;
600 }
601 }
drhcd7d2732002-02-26 23:24:26 +0000602 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000603 }
604}
605
606/*
drhfeac5f82004-08-01 00:10:45 +0000607** Output the given string as a quoted according to C or TCL quoting rules.
608*/
609static void output_c_string(FILE *out, const char *z){
610 unsigned int c;
611 fputc('"', out);
612 while( (c = *(z++))!=0 ){
613 if( c=='\\' ){
614 fputc(c, out);
615 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000616 }else if( c=='"' ){
617 fputc('\\', out);
618 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000619 }else if( c=='\t' ){
620 fputc('\\', out);
621 fputc('t', out);
622 }else if( c=='\n' ){
623 fputc('\\', out);
624 fputc('n', out);
625 }else if( c=='\r' ){
626 fputc('\\', out);
627 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000628 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000629 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000630 }else{
631 fputc(c, out);
632 }
633 }
634 fputc('"', out);
635}
636
637/*
drhc08a4f12000-06-15 16:49:48 +0000638** Output the given string with characters that are special to
639** HTML escaped.
640*/
641static void output_html_string(FILE *out, const char *z){
642 int i;
drhc3d6ba42014-01-13 20:38:35 +0000643 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000644 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000645 for(i=0; z[i]
646 && z[i]!='<'
647 && z[i]!='&'
648 && z[i]!='>'
649 && z[i]!='\"'
650 && z[i]!='\'';
651 i++){}
drhc08a4f12000-06-15 16:49:48 +0000652 if( i>0 ){
653 fprintf(out,"%.*s",i,z);
654 }
655 if( z[i]=='<' ){
656 fprintf(out,"&lt;");
657 }else if( z[i]=='&' ){
658 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000659 }else if( z[i]=='>' ){
660 fprintf(out,"&gt;");
661 }else if( z[i]=='\"' ){
662 fprintf(out,"&quot;");
663 }else if( z[i]=='\'' ){
664 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000665 }else{
666 break;
667 }
668 z += i + 1;
669 }
670}
671
672/*
drhc49f44e2006-10-26 18:15:42 +0000673** If a field contains any character identified by a 1 in the following
674** array, then the string must be quoted for CSV.
675*/
676static const char needCsvQuote[] = {
677 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
678 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
679 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
680 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
681 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
682 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
683 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
684 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
685 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
686 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
687 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
688 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
689 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
690 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
691 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
692 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
693};
694
695/*
drh8e64d1c2004-10-07 00:32:39 +0000696** Output a single term of CSV. Actually, p->separator is used for
697** the separator, which may or may not be a comma. p->nullvalue is
drh6976c212014-07-24 12:09:47 +0000698** the null value. Strings are quoted if necessary. The separator
699** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000700*/
drhdcd87a92014-08-18 13:45:42 +0000701static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000702 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000703 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000704 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000705 }else{
drhc49f44e2006-10-26 18:15:42 +0000706 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000707 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000708 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000709 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000710 || (z[i]==p->colSeparator[0] &&
711 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000712 i = 0;
713 break;
714 }
715 }
716 if( i==0 ){
717 putc('"', out);
718 for(i=0; z[i]; i++){
719 if( z[i]=='"' ) putc('"', out);
720 putc(z[i], out);
721 }
722 putc('"', out);
723 }else{
724 fprintf(out, "%s", z);
725 }
drh8e64d1c2004-10-07 00:32:39 +0000726 }
727 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000728 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000729 }
730}
731
danielk19774af00c62005-01-23 23:43:21 +0000732#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000733/*
drh4c504392000-10-16 22:06:40 +0000734** This routine runs when the user presses Ctrl-C
735*/
736static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000737 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000738 seenInterrupt++;
739 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000740 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000741}
danielk19774af00c62005-01-23 23:43:21 +0000742#endif
drh4c504392000-10-16 22:06:40 +0000743
744/*
shane626a6e42009-10-22 17:30:15 +0000745** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000746** invokes for each row of a query result.
747*/
drh4ace5362014-11-10 14:42:28 +0000748static int shell_callback(
749 void *pArg,
750 int nArg, /* Number of result columns */
751 char **azArg, /* Text of each result column */
752 char **azCol, /* Column names */
753 int *aiType /* Column types */
754){
drh75897232000-05-29 14:26:00 +0000755 int i;
drhdcd87a92014-08-18 13:45:42 +0000756 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000757
drh75897232000-05-29 14:26:00 +0000758 switch( p->mode ){
759 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000760 int w = 5;
drh6a535342001-10-19 16:44:56 +0000761 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000762 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000763 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000764 if( len>w ) w = len;
765 }
mistachkin636bf9f2014-07-19 20:15:16 +0000766 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000767 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000768 fprintf(p->out,"%*s = %s%s", w, azCol[i],
769 azArg[i] ? azArg[i] : p->nullvalue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000770 }
771 break;
772 }
danielk19770d78bae2008-01-03 07:09:48 +0000773 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000774 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000775 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000776 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000777 int w, n;
778 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000779 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000780 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000781 w = 0;
drh75897232000-05-29 14:26:00 +0000782 }
drh078b1fd2012-09-21 13:40:02 +0000783 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000784 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000785 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000786 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000787 if( w<n ) w = n;
788 }
789 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000790 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000791 }
792 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000793 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000794 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
795 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000796 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000797 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
798 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000799 }
drha0c66f52000-07-29 13:20:21 +0000800 }
801 }
802 if( p->showHeader ){
803 for(i=0; i<nArg; i++){
804 int w;
805 if( i<ArraySize(p->actualWidth) ){
806 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000807 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000808 }else{
809 w = 10;
810 }
811 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
812 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000813 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000814 }
drh75897232000-05-29 14:26:00 +0000815 }
816 }
drh6a535342001-10-19 16:44:56 +0000817 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000818 for(i=0; i<nArg; i++){
819 int w;
drha0c66f52000-07-29 13:20:21 +0000820 if( i<ArraySize(p->actualWidth) ){
821 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000822 }else{
823 w = 10;
824 }
dana98bf362013-11-13 18:35:01 +0000825 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000826 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000827 }
dana98bf362013-11-13 18:35:01 +0000828 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000829 if( p->iIndent<p->nIndent ){
830 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000831 }
danc4650bb2013-11-18 08:41:06 +0000832 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000833 }
drh078b1fd2012-09-21 13:40:02 +0000834 if( w<0 ){
835 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin636bf9f2014-07-19 20:15:16 +0000836 azArg[i] ? azArg[i] : p->nullvalue,
837 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000838 }else{
839 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin636bf9f2014-07-19 20:15:16 +0000840 azArg[i] ? azArg[i] : p->nullvalue,
841 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000842 }
drh75897232000-05-29 14:26:00 +0000843 }
844 break;
845 }
drhe3710332000-09-29 13:30:53 +0000846 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000847 case MODE_List: {
848 if( p->cnt++==0 && p->showHeader ){
849 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000850 fprintf(p->out,"%s%s",azCol[i],
851 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000852 }
853 }
drh6a535342001-10-19 16:44:56 +0000854 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000855 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000856 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000857 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000858 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000859 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000860 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000861 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000862 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000863 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000864 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000865 }
drh75897232000-05-29 14:26:00 +0000866 }
867 break;
868 }
drh1e5d0e92000-05-31 23:33:17 +0000869 case MODE_Html: {
870 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000871 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000872 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000873 fprintf(p->out,"<TH>");
874 output_html_string(p->out, azCol[i]);
875 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000876 }
mihailim57c591a2008-06-23 21:26:05 +0000877 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000878 }
drh6a535342001-10-19 16:44:56 +0000879 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000880 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000881 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000882 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000883 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000884 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000885 }
mihailim57c591a2008-06-23 21:26:05 +0000886 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000887 break;
888 }
drhfeac5f82004-08-01 00:10:45 +0000889 case MODE_Tcl: {
890 if( p->cnt++==0 && p->showHeader ){
891 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000892 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000893 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000894 }
mistachkin636bf9f2014-07-19 20:15:16 +0000895 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000896 }
897 if( azArg==0 ) break;
898 for(i=0; i<nArg; i++){
899 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mistachkin636bf9f2014-07-19 20:15:16 +0000900 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000901 }
mistachkin636bf9f2014-07-19 20:15:16 +0000902 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000903 break;
904 }
drh8e64d1c2004-10-07 00:32:39 +0000905 case MODE_Csv: {
drh6976c212014-07-24 12:09:47 +0000906#if defined(WIN32) || defined(_WIN32)
907 fflush(p->out);
908 _setmode(_fileno(p->out), _O_BINARY);
909#endif
drh8e64d1c2004-10-07 00:32:39 +0000910 if( p->cnt++==0 && p->showHeader ){
911 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000912 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000913 }
mistachkine0d68852014-12-11 03:12:33 +0000914 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000915 }
drh40253262014-10-17 21:35:05 +0000916 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000917 for(i=0; i<nArg; i++){
918 output_csv(p, azArg[i], i<nArg-1);
919 }
mistachkine0d68852014-12-11 03:12:33 +0000920 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000921 }
drh6976c212014-07-24 12:09:47 +0000922#if defined(WIN32) || defined(_WIN32)
923 fflush(p->out);
924 _setmode(_fileno(p->out), _O_TEXT);
925#endif
drh8e64d1c2004-10-07 00:32:39 +0000926 break;
927 }
drh28bd4bc2000-06-15 15:57:22 +0000928 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000929 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000930 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000931 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000932 for(i=0; i<nArg; i++){
933 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000934 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000935 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000936 }else if( aiType && aiType[i]==SQLITE_TEXT ){
937 if( zSep[0] ) fprintf(p->out,"%s",zSep);
938 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +0000939 }else if( aiType && (aiType[i]==SQLITE_INTEGER
940 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +0000941 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000942 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
943 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
944 int nBlob = sqlite3_column_bytes(p->pStmt, i);
945 if( zSep[0] ) fprintf(p->out,"%s",zSep);
946 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000947 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000948 fprintf(p->out,"%s%s",zSep, azArg[i]);
949 }else{
950 if( zSep[0] ) fprintf(p->out,"%s",zSep);
951 output_quoted_string(p->out, azArg[i]);
952 }
953 }
954 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000955 break;
drh28bd4bc2000-06-15 15:57:22 +0000956 }
mistachkin636bf9f2014-07-19 20:15:16 +0000957 case MODE_Ascii: {
958 if( p->cnt++==0 && p->showHeader ){
959 for(i=0; i<nArg; i++){
960 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
961 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
962 }
963 fprintf(p->out, "%s", p->rowSeparator);
964 }
965 if( azArg==0 ) break;
966 for(i=0; i<nArg; i++){
967 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
968 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullvalue);
969 }
970 fprintf(p->out, "%s", p->rowSeparator);
971 break;
972 }
persicom1d0b8722002-04-18 02:53:04 +0000973 }
drh75897232000-05-29 14:26:00 +0000974 return 0;
975}
976
977/*
shane626a6e42009-10-22 17:30:15 +0000978** This is the callback routine that the SQLite library
979** invokes for each row of a query result.
980*/
981static int callback(void *pArg, int nArg, char **azArg, char **azCol){
982 /* since we don't have type info, call the shell_callback with a NULL value */
983 return shell_callback(pArg, nArg, azArg, azCol, NULL);
984}
985
986/*
drhdcd87a92014-08-18 13:45:42 +0000987** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +0000988** the name of the table given. Escape any quote characters in the
989** table name.
990*/
drhdcd87a92014-08-18 13:45:42 +0000991static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +0000992 int i, n;
993 int needQuote;
994 char *z;
995
996 if( p->zDestTable ){
997 free(p->zDestTable);
998 p->zDestTable = 0;
999 }
1000 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001001 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001002 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001003 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001004 needQuote = 1;
1005 if( zName[i]=='\'' ) n++;
1006 }
1007 }
1008 if( needQuote ) n += 2;
1009 z = p->zDestTable = malloc( n+1 );
1010 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001011 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001012 exit(1);
1013 }
1014 n = 0;
1015 if( needQuote ) z[n++] = '\'';
1016 for(i=0; zName[i]; i++){
1017 z[n++] = zName[i];
1018 if( zName[i]=='\'' ) z[n++] = '\'';
1019 }
1020 if( needQuote ) z[n++] = '\'';
1021 z[n] = 0;
1022}
1023
danielk19772a02e332004-06-05 08:04:36 +00001024/* zIn is either a pointer to a NULL-terminated string in memory obtained
1025** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1026** added to zIn, and the result returned in memory obtained from malloc().
1027** zIn, if it was not NULL, is freed.
1028**
1029** If the third argument, quote, is not '\0', then it is used as a
1030** quote character for zAppend.
1031*/
drhc28490c2006-10-26 14:25:58 +00001032static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001033 int len;
1034 int i;
drh4f21c4a2008-12-10 22:15:00 +00001035 int nAppend = strlen30(zAppend);
1036 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001037
1038 len = nAppend+nIn+1;
1039 if( quote ){
1040 len += 2;
1041 for(i=0; i<nAppend; i++){
1042 if( zAppend[i]==quote ) len++;
1043 }
1044 }
1045
1046 zIn = (char *)realloc(zIn, len);
1047 if( !zIn ){
1048 return 0;
1049 }
1050
1051 if( quote ){
1052 char *zCsr = &zIn[nIn];
1053 *zCsr++ = quote;
1054 for(i=0; i<nAppend; i++){
1055 *zCsr++ = zAppend[i];
1056 if( zAppend[i]==quote ) *zCsr++ = quote;
1057 }
1058 *zCsr++ = quote;
1059 *zCsr++ = '\0';
1060 assert( (zCsr-zIn)==len );
1061 }else{
1062 memcpy(&zIn[nIn], zAppend, nAppend);
1063 zIn[len-1] = '\0';
1064 }
1065
1066 return zIn;
1067}
1068
drhdd3d4592004-08-30 01:54:05 +00001069
1070/*
drhb21a8e42012-01-28 21:08:51 +00001071** Execute a query statement that will generate SQL output. Print
1072** the result columns, comma-separated, on a line and then add a
1073** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001074**
drhb21a8e42012-01-28 21:08:51 +00001075** If the number of columns is 1 and that column contains text "--"
1076** then write the semicolon on a separate line. That way, if a
1077** "--" comment occurs at the end of the statement, the comment
1078** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001079*/
drh157e29a2009-05-21 15:15:00 +00001080static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001081 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001082 const char *zSelect, /* SELECT statement to extract content */
1083 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001084){
drhdd3d4592004-08-30 01:54:05 +00001085 sqlite3_stmt *pSelect;
1086 int rc;
drhb21a8e42012-01-28 21:08:51 +00001087 int nResult;
1088 int i;
1089 const char *z;
drhc7181902014-02-27 15:04:13 +00001090 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001091 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001092 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001093 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001094 return rc;
1095 }
1096 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001097 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001098 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001099 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001100 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001101 zFirstRow = 0;
1102 }
drhb21a8e42012-01-28 21:08:51 +00001103 z = (const char*)sqlite3_column_text(pSelect, 0);
1104 fprintf(p->out, "%s", z);
1105 for(i=1; i<nResult; i++){
1106 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1107 }
1108 if( z==0 ) z = "";
1109 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1110 if( z[0] ){
1111 fprintf(p->out, "\n;\n");
1112 }else{
1113 fprintf(p->out, ";\n");
1114 }
drhdd3d4592004-08-30 01:54:05 +00001115 rc = sqlite3_step(pSelect);
1116 }
drh2f464a02011-10-13 00:41:49 +00001117 rc = sqlite3_finalize(pSelect);
1118 if( rc!=SQLITE_OK ){
1119 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001120 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001121 }
1122 return rc;
drhdd3d4592004-08-30 01:54:05 +00001123}
1124
shane626a6e42009-10-22 17:30:15 +00001125/*
1126** Allocate space and save off current error string.
1127*/
1128static char *save_err_msg(
1129 sqlite3 *db /* Database to query */
1130){
1131 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1132 char *zErrMsg = sqlite3_malloc(nErrMsg);
1133 if( zErrMsg ){
1134 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1135 }
1136 return zErrMsg;
1137}
1138
1139/*
shaneh642d8b82010-07-28 16:05:34 +00001140** Display memory stats.
1141*/
1142static int display_stats(
1143 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001144 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001145 int bReset /* True to reset the stats */
1146){
1147 int iCur;
1148 int iHiwtr;
1149
1150 if( pArg && pArg->out ){
1151
1152 iHiwtr = iCur = -1;
1153 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001154 fprintf(pArg->out,
1155 "Memory Used: %d (max %d) bytes\n",
1156 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001157 iHiwtr = iCur = -1;
1158 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001159 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1160 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001161 if( pArg->shellFlgs & SHFLG_Pagecache ){
1162 iHiwtr = iCur = -1;
1163 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001164 fprintf(pArg->out,
1165 "Number of Pcache Pages Used: %d (max %d) pages\n",
1166 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001167 }
shaneh642d8b82010-07-28 16:05:34 +00001168 iHiwtr = iCur = -1;
1169 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001170 fprintf(pArg->out,
1171 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1172 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001173 if( pArg->shellFlgs & SHFLG_Scratch ){
1174 iHiwtr = iCur = -1;
1175 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001176 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1177 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001178 }
shaneh642d8b82010-07-28 16:05:34 +00001179 iHiwtr = iCur = -1;
1180 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001181 fprintf(pArg->out,
1182 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1183 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001184 iHiwtr = iCur = -1;
1185 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001186 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1187 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001188 iHiwtr = iCur = -1;
1189 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001190 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1191 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001192 iHiwtr = iCur = -1;
1193 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001194 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1195 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001196#ifdef YYTRACKMAXSTACKDEPTH
1197 iHiwtr = iCur = -1;
1198 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001199 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1200 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001201#endif
1202 }
1203
1204 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001205 if( pArg->shellFlgs & SHFLG_Lookaside ){
1206 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001207 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1208 &iCur, &iHiwtr, bReset);
1209 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1210 iCur, iHiwtr);
1211 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1212 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001213 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001214 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1215 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001216 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001217 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1218 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001219 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1220 }
shaneh642d8b82010-07-28 16:05:34 +00001221 iHiwtr = iCur = -1;
1222 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001223 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1224 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001225 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1226 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1227 iHiwtr = iCur = -1;
1228 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1229 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001230 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001231 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1232 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1233 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001234 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001235 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001236 iHiwtr = iCur = -1;
1237 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001238 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001239 }
1240
1241 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001242 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1243 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001244 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1245 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1246 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001247 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001248 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001249 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1250 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001251 }
1252
1253 return 0;
1254}
1255
1256/*
dan8d1edb92014-11-05 09:07:28 +00001257** Display scan stats.
1258*/
1259static void display_scanstats(
1260 sqlite3 *db, /* Database to query */
1261 ShellState *pArg /* Pointer to ShellState */
1262){
1263#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001264 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001265 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001266 mx = 0;
1267 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001268 double rEstLoop = 1.0;
1269 for(i=n=0; 1; i++){
1270 sqlite3_stmt *p = pArg->pStmt;
1271 sqlite3_int64 nLoop, nVisit;
1272 double rEst;
1273 int iSid;
1274 const char *zExplain;
1275 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1276 break;
1277 }
1278 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001279 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001280 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001281 if( n==0 ){
1282 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001283 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001284 }
drh42f30bc2014-11-06 12:08:21 +00001285 n++;
1286 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1287 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1288 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1289 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1290 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001291 fprintf(pArg->out,
1292 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001293 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001294 );
dan8d1edb92014-11-05 09:07:28 +00001295 }
dan8d1edb92014-11-05 09:07:28 +00001296 }
dan8d1edb92014-11-05 09:07:28 +00001297 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001298#endif
dan8d1edb92014-11-05 09:07:28 +00001299}
1300
1301/*
dana98bf362013-11-13 18:35:01 +00001302** Parameter azArray points to a zero-terminated array of strings. zStr
1303** points to a single nul-terminated string. Return non-zero if zStr
1304** is equal, according to strcmp(), to any of the strings in the array.
1305** Otherwise, return zero.
1306*/
1307static int str_in_array(const char *zStr, const char **azArray){
1308 int i;
1309 for(i=0; azArray[i]; i++){
1310 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1311 }
1312 return 0;
1313}
1314
1315/*
1316** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001317** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001318** spaces each opcode should be indented before it is output.
1319**
1320** The indenting rules are:
1321**
1322** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1323** all opcodes that occur between the p2 jump destination and the opcode
1324** itself by 2 spaces.
1325**
drh01752bc2013-11-14 23:59:33 +00001326** * For each "Goto", if the jump destination is earlier in the program
1327** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001328** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001329** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001330** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001331** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001332*/
drhdcd87a92014-08-18 13:45:42 +00001333static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001334 const char *zSql; /* The text of the SQL statement */
1335 const char *z; /* Used to check if this is an EXPLAIN */
1336 int *abYield = 0; /* True if op is an OP_Yield */
1337 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001338 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001339
drh8ad0de32014-03-20 18:45:27 +00001340 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1341 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001342 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1343 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001344 const char *azGoto[] = { "Goto", 0 };
1345
1346 /* Try to figure out if this is really an EXPLAIN statement. If this
1347 ** cannot be verified, return early. */
1348 zSql = sqlite3_sql(pSql);
1349 if( zSql==0 ) return;
1350 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1351 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1352
1353 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1354 int i;
danc4650bb2013-11-18 08:41:06 +00001355 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001356 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001357
1358 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1359 ** p2 is an instruction address, set variable p2op to the index of that
1360 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1361 ** the current instruction is part of a sub-program generated by an
1362 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001363 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001364 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001365
1366 /* Grow the p->aiIndent array as required */
1367 if( iOp>=nAlloc ){
1368 nAlloc += 100;
1369 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1370 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1371 }
1372 abYield[iOp] = str_in_array(zOp, azYield);
1373 p->aiIndent[iOp] = 0;
1374 p->nIndent = iOp+1;
1375
1376 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001377 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001378 }
drhfe705102014-03-06 13:38:37 +00001379 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1380 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1381 ){
drhe73f0592014-01-21 22:25:45 +00001382 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001383 }
1384 }
1385
danc4650bb2013-11-18 08:41:06 +00001386 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001387 sqlite3_free(abYield);
1388 sqlite3_reset(pSql);
1389}
1390
1391/*
1392** Free the array allocated by explain_data_prepare().
1393*/
drhdcd87a92014-08-18 13:45:42 +00001394static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001395 sqlite3_free(p->aiIndent);
1396 p->aiIndent = 0;
1397 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001398 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001399}
1400
1401/*
shane626a6e42009-10-22 17:30:15 +00001402** Execute a statement or set of statements. Print
1403** any result rows/columns depending on the current mode
1404** set via the supplied callback.
1405**
1406** This is very similar to SQLite's built-in sqlite3_exec()
1407** function except it takes a slightly different callback
1408** and callback data argument.
1409*/
1410static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001411 sqlite3 *db, /* An open database */
1412 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001413 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001414 /* (not the same as sqlite3_exec) */
1415 ShellState *pArg, /* Pointer to ShellState */
1416 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001417){
dan4564ced2010-01-05 04:59:56 +00001418 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1419 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001420 int rc2;
dan4564ced2010-01-05 04:59:56 +00001421 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001422
1423 if( pzErrMsg ){
1424 *pzErrMsg = NULL;
1425 }
1426
shaneb9fc17d2009-10-22 21:23:35 +00001427 while( zSql[0] && (SQLITE_OK == rc) ){
1428 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1429 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001430 if( pzErrMsg ){
1431 *pzErrMsg = save_err_msg(db);
1432 }
1433 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001434 if( !pStmt ){
1435 /* this happens for a comment or white-space */
1436 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001437 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001438 continue;
1439 }
shane626a6e42009-10-22 17:30:15 +00001440
shaneh642d8b82010-07-28 16:05:34 +00001441 /* save off the prepared statment handle and reset row count */
1442 if( pArg ){
1443 pArg->pStmt = pStmt;
1444 pArg->cnt = 0;
1445 }
1446
shanehb7977c52010-01-18 18:17:10 +00001447 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001448 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001449 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001450 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001451 }
shanehb7977c52010-01-18 18:17:10 +00001452
drhefbf3b12014-02-28 20:47:24 +00001453 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1454 if( pArg && pArg->autoEQP ){
1455 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001456 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1457 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001458 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1459 if( rc==SQLITE_OK ){
1460 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1461 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1462 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1463 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1464 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1465 }
1466 }
1467 sqlite3_finalize(pExplain);
1468 sqlite3_free(zEQP);
1469 }
1470
dana98bf362013-11-13 18:35:01 +00001471 /* If the shell is currently in ".explain" mode, gather the extra
1472 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001473 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001474 explain_data_prepare(pArg, pStmt);
1475 }
1476
shaneb9fc17d2009-10-22 21:23:35 +00001477 /* perform the first step. this will tell us if we
1478 ** have a result set or not and how wide it is.
1479 */
1480 rc = sqlite3_step(pStmt);
1481 /* if we have a result set... */
1482 if( SQLITE_ROW == rc ){
1483 /* if we have a callback... */
1484 if( xCallback ){
1485 /* allocate space for col name ptr, value ptr, and type */
1486 int nCol = sqlite3_column_count(pStmt);
1487 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1488 if( !pData ){
1489 rc = SQLITE_NOMEM;
1490 }else{
1491 char **azCols = (char **)pData; /* Names of result columns */
1492 char **azVals = &azCols[nCol]; /* Results */
1493 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001494 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001495 assert(sizeof(int) <= sizeof(char *));
1496 /* save off ptrs to column names */
1497 for(i=0; i<nCol; i++){
1498 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1499 }
shaneb9fc17d2009-10-22 21:23:35 +00001500 do{
1501 /* extract the data and data types */
1502 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001503 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001504 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001505 azVals[i] = "";
1506 }else{
1507 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1508 }
shaneb9fc17d2009-10-22 21:23:35 +00001509 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1510 rc = SQLITE_NOMEM;
1511 break; /* from for */
1512 }
1513 } /* end for */
1514
1515 /* if data and types extracted successfully... */
1516 if( SQLITE_ROW == rc ){
1517 /* call the supplied callback with the result row data */
1518 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1519 rc = SQLITE_ABORT;
1520 }else{
1521 rc = sqlite3_step(pStmt);
1522 }
1523 }
1524 } while( SQLITE_ROW == rc );
1525 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001526 }
1527 }else{
1528 do{
1529 rc = sqlite3_step(pStmt);
1530 } while( rc == SQLITE_ROW );
1531 }
1532 }
1533
dana98bf362013-11-13 18:35:01 +00001534 explain_data_delete(pArg);
1535
shaneh642d8b82010-07-28 16:05:34 +00001536 /* print usage stats if stats on */
1537 if( pArg && pArg->statsOn ){
1538 display_stats(db, pArg, 0);
1539 }
1540
dan8d1edb92014-11-05 09:07:28 +00001541 /* print loop-counters if required */
1542 if( pArg && pArg->scanstatsOn ){
1543 display_scanstats(db, pArg);
1544 }
1545
dan4564ced2010-01-05 04:59:56 +00001546 /* Finalize the statement just executed. If this fails, save a
1547 ** copy of the error message. Otherwise, set zSql to point to the
1548 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001549 rc2 = sqlite3_finalize(pStmt);
1550 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001551 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001552 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001553 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001554 }else if( pzErrMsg ){
1555 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001556 }
shaneh642d8b82010-07-28 16:05:34 +00001557
1558 /* clear saved stmt handle */
1559 if( pArg ){
1560 pArg->pStmt = NULL;
1561 }
shane626a6e42009-10-22 17:30:15 +00001562 }
shaneb9fc17d2009-10-22 21:23:35 +00001563 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001564
1565 return rc;
1566}
1567
drhdd3d4592004-08-30 01:54:05 +00001568
drh33048c02001-10-01 14:29:22 +00001569/*
drh4c653a02000-06-07 01:27:47 +00001570** This is a different callback routine used for dumping the database.
1571** Each row received by this callback consists of a table name,
1572** the table type ("index" or "table") and SQL to create the table.
1573** This routine should print text sufficient to recreate the table.
1574*/
1575static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001576 int rc;
1577 const char *zTable;
1578 const char *zType;
1579 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001580 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001581 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001582
drh902b9ee2008-12-05 17:17:07 +00001583 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001584 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001585 zTable = azArg[0];
1586 zType = azArg[1];
1587 zSql = azArg[2];
1588
drh00b950d2005-09-11 02:03:03 +00001589 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001590 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001591 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001592 fprintf(p->out, "ANALYZE sqlite_master;\n");
1593 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1594 return 0;
drh45e29d82006-11-20 16:21:10 +00001595 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1596 char *zIns;
1597 if( !p->writableSchema ){
1598 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1599 p->writableSchema = 1;
1600 }
1601 zIns = sqlite3_mprintf(
1602 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1603 "VALUES('table','%q','%q',0,'%q');",
1604 zTable, zTable, zSql);
1605 fprintf(p->out, "%s\n", zIns);
1606 sqlite3_free(zIns);
1607 return 0;
drh00b950d2005-09-11 02:03:03 +00001608 }else{
1609 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001610 }
danielk19772a02e332004-06-05 08:04:36 +00001611
1612 if( strcmp(zType, "table")==0 ){
1613 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001614 char *zSelect = 0;
1615 char *zTableInfo = 0;
1616 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001617 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001618
1619 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1620 zTableInfo = appendText(zTableInfo, zTable, '"');
1621 zTableInfo = appendText(zTableInfo, ");", 0);
1622
drhc7181902014-02-27 15:04:13 +00001623 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001624 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001625 if( rc!=SQLITE_OK || !pTableInfo ){
1626 return 1;
1627 }
1628
1629 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001630 /* Always quote the table name, even if it appears to be pure ascii,
1631 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1632 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001633 if( zTmp ){
1634 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001635 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001636 }
1637 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1638 rc = sqlite3_step(pTableInfo);
1639 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001640 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001641 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001642 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001643 rc = sqlite3_step(pTableInfo);
1644 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001645 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001646 }else{
1647 zSelect = appendText(zSelect, ") ", 0);
1648 }
drh157e29a2009-05-21 15:15:00 +00001649 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001650 }
1651 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001652 if( rc!=SQLITE_OK || nRow==0 ){
1653 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001654 return 1;
1655 }
1656 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1657 zSelect = appendText(zSelect, zTable, '"');
1658
drh2f464a02011-10-13 00:41:49 +00001659 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001660 if( rc==SQLITE_CORRUPT ){
1661 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001662 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001663 }
drh85e72432012-04-11 11:38:53 +00001664 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001665 }
drh4c653a02000-06-07 01:27:47 +00001666 return 0;
1667}
1668
1669/*
drh45e29d82006-11-20 16:21:10 +00001670** Run zQuery. Use dump_callback() as the callback routine so that
1671** the contents of the query are output as SQL statements.
1672**
drhdd3d4592004-08-30 01:54:05 +00001673** If we get a SQLITE_CORRUPT error, rerun the query after appending
1674** "ORDER BY rowid DESC" to the end.
1675*/
1676static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001677 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001678 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001679){
1680 int rc;
drh2f464a02011-10-13 00:41:49 +00001681 char *zErr = 0;
1682 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001683 if( rc==SQLITE_CORRUPT ){
1684 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001685 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001686 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1687 if( zErr ){
1688 fprintf(p->out, "/****** %s ******/\n", zErr);
1689 sqlite3_free(zErr);
1690 zErr = 0;
1691 }
drhdd3d4592004-08-30 01:54:05 +00001692 zQ2 = malloc( len+100 );
1693 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001694 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001695 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1696 if( rc ){
1697 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1698 }else{
1699 rc = SQLITE_CORRUPT;
1700 }
1701 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001702 free(zQ2);
1703 }
1704 return rc;
1705}
1706
1707/*
drh75897232000-05-29 14:26:00 +00001708** Text of a help message
1709*/
persicom1d0b8722002-04-18 02:53:04 +00001710static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001711 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001712 ".bail on|off Stop after hitting an error. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001713 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001714 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001715 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001716 " If TABLE specified, only dump tables matching\n"
1717 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001718 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001719 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001720 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001721 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001722 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001723 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001724 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001725 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001726 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001727 ".indices ?TABLE? Show names of all indices\n"
1728 " If TABLE specified, only show indices for tables\n"
1729 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001730#ifdef SQLITE_ENABLE_IOTRACE
1731 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1732#endif
drh70df4fe2006-06-13 15:12:21 +00001733#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001734 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001735#endif
drh127f9d72010-02-23 01:47:00 +00001736 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001737 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001738 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001739 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001740 " column Left-aligned columns. (See .width)\n"
1741 " html HTML <table> code\n"
1742 " insert SQL insert statements for TABLE\n"
1743 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001744 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001745 " tabs Tab-separated values\n"
1746 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001747 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001748 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001749 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001750 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001751 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001752 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001753 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001754 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001755 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001756 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001757 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001758 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001759 " If TABLE specified, only show tables matching\n"
1760 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001761 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1762 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001763 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001764 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001765 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001766 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001767 ".tables ?TABLE? List names of tables\n"
1768 " If TABLE specified, only list tables matching\n"
1769 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001770 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001771 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001772 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001773 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001774 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001775 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001776;
1777
drhdaffd0e2001-04-11 14:28:42 +00001778/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001779static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001780/*
1781** Implementation of the "readfile(X)" SQL function. The entire content
1782** of the file named X is read and returned as a BLOB. NULL is returned
1783** if the file does not exist or is unreadable.
1784*/
1785static void readfileFunc(
1786 sqlite3_context *context,
1787 int argc,
1788 sqlite3_value **argv
1789){
1790 const char *zName;
1791 FILE *in;
1792 long nIn;
1793 void *pBuf;
1794
1795 zName = (const char*)sqlite3_value_text(argv[0]);
1796 if( zName==0 ) return;
1797 in = fopen(zName, "rb");
1798 if( in==0 ) return;
1799 fseek(in, 0, SEEK_END);
1800 nIn = ftell(in);
1801 rewind(in);
1802 pBuf = sqlite3_malloc( nIn );
1803 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1804 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1805 }else{
1806 sqlite3_free(pBuf);
1807 }
1808 fclose(in);
1809}
1810
1811/*
1812** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1813** is written into file X. The number of bytes written is returned. Or
1814** NULL is returned if something goes wrong, such as being unable to open
1815** file X for writing.
1816*/
1817static void writefileFunc(
1818 sqlite3_context *context,
1819 int argc,
1820 sqlite3_value **argv
1821){
1822 FILE *out;
1823 const char *z;
drhba5b0932014-07-24 12:39:59 +00001824 sqlite3_int64 rc;
1825 const char *zFile;
1826
1827 zFile = (const char*)sqlite3_value_text(argv[0]);
1828 if( zFile==0 ) return;
1829 out = fopen(zFile, "wb");
1830 if( out==0 ) return;
1831 z = (const char*)sqlite3_value_blob(argv[1]);
1832 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001833 rc = 0;
1834 }else{
drh490fe862014-08-11 14:21:32 +00001835 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001836 }
1837 fclose(out);
1838 sqlite3_result_int64(context, rc);
1839}
drhdaffd0e2001-04-11 14:28:42 +00001840
drh75897232000-05-29 14:26:00 +00001841/*
drh44c2eb12003-04-30 11:38:26 +00001842** Make sure the database is open. If it is not, then open it. If
1843** the database fails to open, print an error message and exit.
1844*/
drhdcd87a92014-08-18 13:45:42 +00001845static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001846 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001847 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001848 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001849 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001850 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1851 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1852 shellstaticFunc, 0, 0);
1853 }
1854 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001855 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001856 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001857 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001858 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001859 }
drhc2e87a32006-06-27 15:16:14 +00001860#ifndef SQLITE_OMIT_LOAD_EXTENSION
1861 sqlite3_enable_load_extension(p->db, 1);
1862#endif
drhba5b0932014-07-24 12:39:59 +00001863 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1864 readfileFunc, 0, 0);
1865 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1866 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001867 }
1868}
1869
1870/*
drhfeac5f82004-08-01 00:10:45 +00001871** Do C-language style dequoting.
1872**
1873** \t -> tab
1874** \n -> newline
1875** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001876** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001877** \NNN -> ascii character NNN in octal
1878** \\ -> backslash
1879*/
1880static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001881 int i, j;
1882 char c;
drhc2ce0be2014-05-29 12:36:14 +00001883 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001884 for(i=j=0; (c = z[i])!=0; i++, j++){
1885 if( c=='\\' ){
1886 c = z[++i];
1887 if( c=='n' ){
1888 c = '\n';
1889 }else if( c=='t' ){
1890 c = '\t';
1891 }else if( c=='r' ){
1892 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001893 }else if( c=='\\' ){
1894 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001895 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001896 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001897 if( z[i+1]>='0' && z[i+1]<='7' ){
1898 i++;
1899 c = (c<<3) + z[i] - '0';
1900 if( z[i+1]>='0' && z[i+1]<='7' ){
1901 i++;
1902 c = (c<<3) + z[i] - '0';
1903 }
1904 }
1905 }
1906 }
1907 z[j] = c;
1908 }
drhc2ce0be2014-05-29 12:36:14 +00001909 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001910}
1911
1912/*
drh348d19c2013-06-03 12:47:43 +00001913** Return the value of a hexadecimal digit. Return -1 if the input
1914** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001915*/
drh348d19c2013-06-03 12:47:43 +00001916static int hexDigitValue(char c){
1917 if( c>='0' && c<='9' ) return c - '0';
1918 if( c>='a' && c<='f' ) return c - 'a' + 10;
1919 if( c>='A' && c<='F' ) return c - 'A' + 10;
1920 return -1;
drhc28490c2006-10-26 14:25:58 +00001921}
1922
1923/*
drh7d9f3942013-04-03 01:26:54 +00001924** Interpret zArg as an integer value, possibly with suffixes.
1925*/
1926static sqlite3_int64 integerValue(const char *zArg){
1927 sqlite3_int64 v = 0;
1928 static const struct { char *zSuffix; int iMult; } aMult[] = {
1929 { "KiB", 1024 },
1930 { "MiB", 1024*1024 },
1931 { "GiB", 1024*1024*1024 },
1932 { "KB", 1000 },
1933 { "MB", 1000000 },
1934 { "GB", 1000000000 },
1935 { "K", 1000 },
1936 { "M", 1000000 },
1937 { "G", 1000000000 },
1938 };
1939 int i;
1940 int isNeg = 0;
1941 if( zArg[0]=='-' ){
1942 isNeg = 1;
1943 zArg++;
1944 }else if( zArg[0]=='+' ){
1945 zArg++;
1946 }
drh348d19c2013-06-03 12:47:43 +00001947 if( zArg[0]=='0' && zArg[1]=='x' ){
1948 int x;
1949 zArg += 2;
1950 while( (x = hexDigitValue(zArg[0]))>=0 ){
1951 v = (v<<4) + x;
1952 zArg++;
1953 }
1954 }else{
1955 while( IsDigit(zArg[0]) ){
1956 v = v*10 + zArg[0] - '0';
1957 zArg++;
1958 }
drh7d9f3942013-04-03 01:26:54 +00001959 }
drhc2bed0a2013-05-24 11:57:50 +00001960 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001961 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1962 v *= aMult[i].iMult;
1963 break;
1964 }
1965 }
1966 return isNeg? -v : v;
1967}
1968
1969/*
drh348d19c2013-06-03 12:47:43 +00001970** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1971** for TRUE and FALSE. Return the integer value if appropriate.
1972*/
1973static int booleanValue(char *zArg){
1974 int i;
1975 if( zArg[0]=='0' && zArg[1]=='x' ){
1976 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1977 }else{
1978 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1979 }
1980 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1981 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1982 return 1;
1983 }
1984 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1985 return 0;
1986 }
1987 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1988 zArg);
1989 return 0;
1990}
1991
1992/*
drh42f64e52012-04-04 16:56:23 +00001993** Close an output file, assuming it is not stderr or stdout
1994*/
1995static void output_file_close(FILE *f){
1996 if( f && f!=stdout && f!=stderr ) fclose(f);
1997}
1998
1999/*
2000** Try to open an output file. The names "stdout" and "stderr" are
2001** recognized and do the right thing. NULL is returned if the output
2002** filename is "off".
2003*/
2004static FILE *output_file_open(const char *zFile){
2005 FILE *f;
2006 if( strcmp(zFile,"stdout")==0 ){
2007 f = stdout;
2008 }else if( strcmp(zFile, "stderr")==0 ){
2009 f = stderr;
2010 }else if( strcmp(zFile, "off")==0 ){
2011 f = 0;
2012 }else{
2013 f = fopen(zFile, "wb");
2014 if( f==0 ){
2015 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2016 }
2017 }
2018 return f;
2019}
2020
2021/*
2022** A routine for handling output from sqlite3_trace().
2023*/
2024static void sql_trace_callback(void *pArg, const char *z){
2025 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002026 if( f ){
2027 int i = (int)strlen(z);
2028 while( i>0 && z[i-1]==';' ){ i--; }
2029 fprintf(f, "%.*s;\n", i, z);
2030 }
drh42f64e52012-04-04 16:56:23 +00002031}
2032
2033/*
drhd8621b92012-04-17 09:09:33 +00002034** A no-op routine that runs with the ".breakpoint" doc-command. This is
2035** a useful spot to set a debugger breakpoint.
2036*/
2037static void test_breakpoint(void){
2038 static int nCall = 0;
2039 nCall++;
2040}
2041
2042/*
mistachkin636bf9f2014-07-19 20:15:16 +00002043** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002044*/
mistachkin636bf9f2014-07-19 20:15:16 +00002045typedef struct ImportCtx ImportCtx;
2046struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002047 const char *zFile; /* Name of the input file */
2048 FILE *in; /* Read the CSV text from this input stream */
2049 char *z; /* Accumulated text for a field */
2050 int n; /* Number of bytes in z */
2051 int nAlloc; /* Space allocated for z[] */
2052 int nLine; /* Current line number */
2053 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002054 int cColSep; /* The column separator character. (Usually ",") */
2055 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002056};
2057
2058/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002059static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002060 if( p->n+1>=p->nAlloc ){
2061 p->nAlloc += p->nAlloc + 100;
2062 p->z = sqlite3_realloc(p->z, p->nAlloc);
2063 if( p->z==0 ){
2064 fprintf(stderr, "out of memory\n");
2065 exit(1);
2066 }
2067 }
2068 p->z[p->n++] = (char)c;
2069}
2070
2071/* Read a single field of CSV text. Compatible with rfc4180 and extended
2072** with the option of having a separator other than ",".
2073**
2074** + Input comes from p->in.
2075** + Store results in p->z of length p->n. Space to hold p->z comes
2076** from sqlite3_malloc().
mistachkin636bf9f2014-07-19 20:15:16 +00002077** + Use p->cSep as the column separator. The default is ",".
2078** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002079** + Keep track of the line number in p->nLine.
2080** + Store the character that terminates the field in p->cTerm. Store
2081** EOF on end-of-file.
2082** + Report syntax errors on stderr
2083*/
mistachkin636bf9f2014-07-19 20:15:16 +00002084static char *csv_read_one_field(ImportCtx *p){
2085 int c;
2086 int cSep = p->cColSep;
2087 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002088 p->n = 0;
2089 c = fgetc(p->in);
2090 if( c==EOF || seenInterrupt ){
2091 p->cTerm = EOF;
2092 return 0;
2093 }
2094 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002095 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002096 int startLine = p->nLine;
2097 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002098 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002099 while( 1 ){
2100 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002101 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002102 if( c==cQuote ){
2103 if( pc==cQuote ){
2104 pc = 0;
2105 continue;
2106 }
2107 }
2108 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002109 || (c==rSep && pc==cQuote)
2110 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002111 || (c==EOF && pc==cQuote)
2112 ){
2113 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002114 p->cTerm = c;
2115 break;
2116 }
2117 if( pc==cQuote && c!='\r' ){
2118 fprintf(stderr, "%s:%d: unescaped %c character\n",
2119 p->zFile, p->nLine, cQuote);
2120 }
2121 if( c==EOF ){
2122 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2123 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002124 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002125 break;
2126 }
mistachkin636bf9f2014-07-19 20:15:16 +00002127 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002128 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002129 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002130 }
drhdb95f682013-06-26 22:46:00 +00002131 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002132 while( c!=EOF && c!=cSep && c!=rSep ){
2133 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002134 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002135 }
mistachkin636bf9f2014-07-19 20:15:16 +00002136 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002137 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002138 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002139 }
drhdb95f682013-06-26 22:46:00 +00002140 p->cTerm = c;
2141 }
drh8dd675e2013-07-12 21:09:24 +00002142 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002143 return p->z;
2144}
2145
mistachkin636bf9f2014-07-19 20:15:16 +00002146/* Read a single field of ASCII delimited text.
2147**
2148** + Input comes from p->in.
2149** + Store results in p->z of length p->n. Space to hold p->z comes
2150** from sqlite3_malloc().
2151** + Use p->cSep as the column separator. The default is "\x1F".
2152** + Use p->rSep as the row separator. The default is "\x1E".
2153** + Keep track of the row number in p->nLine.
2154** + Store the character that terminates the field in p->cTerm. Store
2155** EOF on end-of-file.
2156** + Report syntax errors on stderr
2157*/
2158static char *ascii_read_one_field(ImportCtx *p){
2159 int c;
2160 int cSep = p->cColSep;
2161 int rSep = p->cRowSep;
2162 p->n = 0;
2163 c = fgetc(p->in);
2164 if( c==EOF || seenInterrupt ){
2165 p->cTerm = EOF;
2166 return 0;
2167 }
2168 while( c!=EOF && c!=cSep && c!=rSep ){
2169 import_append_char(p, c);
2170 c = fgetc(p->in);
2171 }
2172 if( c==rSep ){
2173 p->nLine++;
2174 }
2175 p->cTerm = c;
2176 if( p->z ) p->z[p->n] = 0;
2177 return p->z;
2178}
2179
drhdb95f682013-06-26 22:46:00 +00002180/*
drh4bbcf102014-02-06 02:46:08 +00002181** Try to transfer data for table zTable. If an error is seen while
2182** moving forward, try to go backwards. The backwards movement won't
2183** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002184*/
mistachkine31ae902014-02-06 01:15:29 +00002185static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002186 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002187 sqlite3 *newDb,
2188 const char *zTable
2189){
2190 sqlite3_stmt *pQuery = 0;
2191 sqlite3_stmt *pInsert = 0;
2192 char *zQuery = 0;
2193 char *zInsert = 0;
2194 int rc;
2195 int i, j, n;
2196 int nTable = (int)strlen(zTable);
2197 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002198 int cnt = 0;
2199 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002200
2201 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2202 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2203 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002204 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002205 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2206 zQuery);
2207 goto end_data_xfer;
2208 }
2209 n = sqlite3_column_count(pQuery);
2210 zInsert = sqlite3_malloc(200 + nTable + n*3);
2211 if( zInsert==0 ){
2212 fprintf(stderr, "out of memory\n");
2213 goto end_data_xfer;
2214 }
2215 sqlite3_snprintf(200+nTable,zInsert,
2216 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2217 i = (int)strlen(zInsert);
2218 for(j=1; j<n; j++){
2219 memcpy(zInsert+i, ",?", 2);
2220 i += 2;
2221 }
2222 memcpy(zInsert+i, ");", 3);
2223 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2224 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002225 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002226 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2227 zQuery);
2228 goto end_data_xfer;
2229 }
2230 for(k=0; k<2; k++){
2231 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2232 for(i=0; i<n; i++){
2233 switch( sqlite3_column_type(pQuery, i) ){
2234 case SQLITE_NULL: {
2235 sqlite3_bind_null(pInsert, i+1);
2236 break;
2237 }
2238 case SQLITE_INTEGER: {
2239 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2240 break;
2241 }
2242 case SQLITE_FLOAT: {
2243 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2244 break;
2245 }
2246 case SQLITE_TEXT: {
2247 sqlite3_bind_text(pInsert, i+1,
2248 (const char*)sqlite3_column_text(pQuery,i),
2249 -1, SQLITE_STATIC);
2250 break;
2251 }
2252 case SQLITE_BLOB: {
2253 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2254 sqlite3_column_bytes(pQuery,i),
2255 SQLITE_STATIC);
2256 break;
2257 }
2258 }
2259 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002260 rc = sqlite3_step(pInsert);
2261 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2262 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2263 sqlite3_errmsg(newDb));
2264 }
drh3350ce92014-02-06 00:49:12 +00002265 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002266 cnt++;
2267 if( (cnt%spinRate)==0 ){
2268 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2269 fflush(stdout);
2270 }
drh3350ce92014-02-06 00:49:12 +00002271 } /* End while */
2272 if( rc==SQLITE_DONE ) break;
2273 sqlite3_finalize(pQuery);
2274 sqlite3_free(zQuery);
2275 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2276 zTable);
2277 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2278 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002279 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2280 break;
drh3350ce92014-02-06 00:49:12 +00002281 }
2282 } /* End for(k=0...) */
2283
2284end_data_xfer:
2285 sqlite3_finalize(pQuery);
2286 sqlite3_finalize(pInsert);
2287 sqlite3_free(zQuery);
2288 sqlite3_free(zInsert);
2289}
2290
2291
2292/*
2293** Try to transfer all rows of the schema that match zWhere. For
2294** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002295** If an error is encountered while moving forward through the
2296** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002297*/
mistachkine31ae902014-02-06 01:15:29 +00002298static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002299 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002300 sqlite3 *newDb,
2301 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002302 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002303){
2304 sqlite3_stmt *pQuery = 0;
2305 char *zQuery = 0;
2306 int rc;
2307 const unsigned char *zName;
2308 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002309 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002310
2311 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2312 " WHERE %s", zWhere);
2313 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2314 if( rc ){
2315 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2316 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2317 zQuery);
2318 goto end_schema_xfer;
2319 }
2320 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2321 zName = sqlite3_column_text(pQuery, 0);
2322 zSql = sqlite3_column_text(pQuery, 1);
2323 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002324 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2325 if( zErrMsg ){
2326 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2327 sqlite3_free(zErrMsg);
2328 zErrMsg = 0;
2329 }
drh3350ce92014-02-06 00:49:12 +00002330 if( xForEach ){
2331 xForEach(p, newDb, (const char*)zName);
2332 }
2333 printf("done\n");
2334 }
2335 if( rc!=SQLITE_DONE ){
2336 sqlite3_finalize(pQuery);
2337 sqlite3_free(zQuery);
2338 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2339 " WHERE %s ORDER BY rowid DESC", zWhere);
2340 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2341 if( rc ){
2342 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2343 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2344 zQuery);
2345 goto end_schema_xfer;
2346 }
2347 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2348 zName = sqlite3_column_text(pQuery, 0);
2349 zSql = sqlite3_column_text(pQuery, 1);
2350 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002351 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2352 if( zErrMsg ){
2353 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2354 sqlite3_free(zErrMsg);
2355 zErrMsg = 0;
2356 }
drh3350ce92014-02-06 00:49:12 +00002357 if( xForEach ){
2358 xForEach(p, newDb, (const char*)zName);
2359 }
2360 printf("done\n");
2361 }
2362 }
2363end_schema_xfer:
2364 sqlite3_finalize(pQuery);
2365 sqlite3_free(zQuery);
2366}
2367
2368/*
2369** Open a new database file named "zNewDb". Try to recover as much information
2370** as possible out of the main database (which might be corrupt) and write it
2371** into zNewDb.
2372*/
drhdcd87a92014-08-18 13:45:42 +00002373static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002374 int rc;
2375 sqlite3 *newDb = 0;
2376 if( access(zNewDb,0)==0 ){
2377 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2378 return;
2379 }
2380 rc = sqlite3_open(zNewDb, &newDb);
2381 if( rc ){
2382 fprintf(stderr, "Cannot create output database: %s\n",
2383 sqlite3_errmsg(newDb));
2384 }else{
drh54d0d2d2014-04-03 00:32:13 +00002385 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002386 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002387 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2388 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002389 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002390 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002391 }
2392 sqlite3_close(newDb);
2393}
2394
2395/*
drhc2ce0be2014-05-29 12:36:14 +00002396** Change the output file back to stdout
2397*/
drhdcd87a92014-08-18 13:45:42 +00002398static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002399 if( p->outfile[0]=='|' ){
2400 pclose(p->out);
2401 }else{
2402 output_file_close(p->out);
2403 }
2404 p->outfile[0] = 0;
2405 p->out = stdout;
2406}
2407
2408/*
drh75897232000-05-29 14:26:00 +00002409** If an input line begins with "." then invoke this routine to
2410** process that line.
drh67505e72002-04-19 12:34:06 +00002411**
drh47ad6842006-11-08 12:25:42 +00002412** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002413*/
drhdcd87a92014-08-18 13:45:42 +00002414static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002415 int i = 1;
2416 int nArg = 0;
2417 int n, c;
drh67505e72002-04-19 12:34:06 +00002418 int rc = 0;
drh75897232000-05-29 14:26:00 +00002419 char *azArg[50];
2420
2421 /* Parse the input line into tokens.
2422 */
2423 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002424 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002425 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002426 if( zLine[i]=='\'' || zLine[i]=='"' ){
2427 int delim = zLine[i++];
2428 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002429 while( zLine[i] && zLine[i]!=delim ){
2430 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2431 i++;
2432 }
drh75897232000-05-29 14:26:00 +00002433 if( zLine[i]==delim ){
2434 zLine[i++] = 0;
2435 }
drhfeac5f82004-08-01 00:10:45 +00002436 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002437 }else{
2438 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002439 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002440 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002441 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002442 }
2443 }
2444
2445 /* Process the input line.
2446 */
shane9bd1b442009-10-23 01:27:39 +00002447 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002448 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002449 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002450 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2451 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2452 ){
drhbc46f022013-01-23 18:53:23 +00002453 const char *zDestFile = 0;
2454 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002455 sqlite3 *pDest;
2456 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002457 int j;
2458 for(j=1; j<nArg; j++){
2459 const char *z = azArg[j];
2460 if( z[0]=='-' ){
2461 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002462 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002463 {
2464 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2465 return 1;
2466 }
2467 }else if( zDestFile==0 ){
2468 zDestFile = azArg[j];
2469 }else if( zDb==0 ){
2470 zDb = zDestFile;
2471 zDestFile = azArg[j];
2472 }else{
2473 fprintf(stderr, "too many arguments to .backup\n");
2474 return 1;
2475 }
drh9ff849f2009-02-04 20:55:57 +00002476 }
drhbc46f022013-01-23 18:53:23 +00002477 if( zDestFile==0 ){
2478 fprintf(stderr, "missing FILENAME argument on .backup\n");
2479 return 1;
2480 }
2481 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002482 rc = sqlite3_open(zDestFile, &pDest);
2483 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002484 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002485 sqlite3_close(pDest);
2486 return 1;
2487 }
drh05782482013-10-24 15:20:20 +00002488 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002489 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2490 if( pBackup==0 ){
2491 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2492 sqlite3_close(pDest);
2493 return 1;
2494 }
2495 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2496 sqlite3_backup_finish(pBackup);
2497 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002498 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002499 }else{
2500 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002501 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002502 }
2503 sqlite3_close(pDest);
2504 }else
2505
drhc2ce0be2014-05-29 12:36:14 +00002506 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2507 if( nArg==2 ){
2508 bail_on_error = booleanValue(azArg[1]);
2509 }else{
2510 fprintf(stderr, "Usage: .bail on|off\n");
2511 rc = 1;
2512 }
drhc49f44e2006-10-26 18:15:42 +00002513 }else
2514
drhd8621b92012-04-17 09:09:33 +00002515 /* The undocumented ".breakpoint" command causes a call to the no-op
2516 ** routine named test_breakpoint().
2517 */
2518 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2519 test_breakpoint();
2520 }else
2521
drhc2ce0be2014-05-29 12:36:14 +00002522 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2523 if( nArg==2 ){
2524 tryToClone(p, azArg[1]);
2525 }else{
2526 fprintf(stderr, "Usage: .clone FILENAME\n");
2527 rc = 1;
2528 }
mistachkine31ae902014-02-06 01:15:29 +00002529 }else
2530
drhc2ce0be2014-05-29 12:36:14 +00002531 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002532 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002533 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002534 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002535 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002536 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002537 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002538 data.colWidth[0] = 3;
2539 data.colWidth[1] = 15;
2540 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002541 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002542 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002543 if( zErrMsg ){
2544 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002545 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002546 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002547 }
2548 }else
2549
drhc2ce0be2014-05-29 12:36:14 +00002550 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002551 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002552 /* When playing back a "dump", the content might appear in an order
2553 ** which causes immediate foreign key constraints to be violated.
2554 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002555 if( nArg!=1 && nArg!=2 ){
2556 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2557 rc = 1;
2558 goto meta_command_exit;
2559 }
drhf1dfc4f2009-09-23 15:51:35 +00002560 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002561 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002562 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002563 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002564 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002565 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002566 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002567 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002568 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002569 );
2570 run_schema_dump_query(p,
2571 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002572 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002573 );
drh2f464a02011-10-13 00:41:49 +00002574 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002575 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002576 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002577 );
drh4c653a02000-06-07 01:27:47 +00002578 }else{
2579 int i;
drhdd3d4592004-08-30 01:54:05 +00002580 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002581 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002582 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002583 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002584 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002585 " AND sql NOT NULL");
2586 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002587 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002588 "WHERE sql NOT NULL"
2589 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002590 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002591 );
danielk1977bc6ada42004-06-30 08:20:16 +00002592 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002593 }
2594 }
drh45e29d82006-11-20 16:21:10 +00002595 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002596 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002597 p->writableSchema = 0;
2598 }
drh56197952011-10-13 16:30:13 +00002599 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2600 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002601 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002602 }else
drh75897232000-05-29 14:26:00 +00002603
drhc2ce0be2014-05-29 12:36:14 +00002604 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2605 if( nArg==2 ){
2606 p->echoOn = booleanValue(azArg[1]);
2607 }else{
2608 fprintf(stderr, "Usage: .echo on|off\n");
2609 rc = 1;
2610 }
drhdaffd0e2001-04-11 14:28:42 +00002611 }else
2612
drhc2ce0be2014-05-29 12:36:14 +00002613 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2614 if( nArg==2 ){
2615 p->autoEQP = booleanValue(azArg[1]);
2616 }else{
2617 fprintf(stderr, "Usage: .eqp on|off\n");
2618 rc = 1;
2619 }
drhefbf3b12014-02-28 20:47:24 +00002620 }else
2621
drhd3ac7d92013-01-25 18:33:43 +00002622 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002623 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002624 rc = 2;
drh75897232000-05-29 14:26:00 +00002625 }else
2626
drhc2ce0be2014-05-29 12:36:14 +00002627 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002628 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002629 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002630 if(!p->normalMode.valid) {
2631 p->normalMode.valid = 1;
2632 p->normalMode.mode = p->mode;
2633 p->normalMode.showHeader = p->showHeader;
2634 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002635 }
2636 /* We could put this code under the !p->explainValid
2637 ** condition so that it does not execute if we are already in
2638 ** explain mode. However, always executing it allows us an easy
2639 ** was to reset to explain mode in case the user previously
2640 ** did an .explain followed by a .width, .mode or .header
2641 ** command.
2642 */
danielk19770d78bae2008-01-03 07:09:48 +00002643 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002644 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002645 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002646 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002647 p->colWidth[1] = 13; /* opcode */
2648 p->colWidth[2] = 4; /* P1 */
2649 p->colWidth[3] = 4; /* P2 */
2650 p->colWidth[4] = 4; /* P3 */
2651 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002652 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002653 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002654 }else if (p->normalMode.valid) {
2655 p->normalMode.valid = 0;
2656 p->mode = p->normalMode.mode;
2657 p->showHeader = p->normalMode.showHeader;
2658 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002659 }
drh75897232000-05-29 14:26:00 +00002660 }else
2661
drhc1971542014-06-23 23:28:13 +00002662 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002663 ShellState data;
drhc1971542014-06-23 23:28:13 +00002664 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002665 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002666 if( nArg!=1 ){
2667 fprintf(stderr, "Usage: .fullschema\n");
2668 rc = 1;
2669 goto meta_command_exit;
2670 }
2671 open_db(p, 0);
2672 memcpy(&data, p, sizeof(data));
2673 data.showHeader = 0;
2674 data.mode = MODE_Semi;
2675 rc = sqlite3_exec(p->db,
2676 "SELECT sql FROM"
2677 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2678 " FROM sqlite_master UNION ALL"
2679 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002680 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002681 "ORDER BY rowid",
2682 callback, &data, &zErrMsg
2683 );
drh56f674c2014-07-18 14:43:29 +00002684 if( rc==SQLITE_OK ){
2685 sqlite3_stmt *pStmt;
2686 rc = sqlite3_prepare_v2(p->db,
2687 "SELECT rowid FROM sqlite_master"
2688 " WHERE name GLOB 'sqlite_stat[134]'",
2689 -1, &pStmt, 0);
2690 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2691 sqlite3_finalize(pStmt);
2692 }
2693 if( doStats==0 ){
2694 fprintf(p->out, "/* No STAT tables available */\n");
2695 }else{
2696 fprintf(p->out, "ANALYZE sqlite_master;\n");
2697 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2698 callback, &data, &zErrMsg);
2699 data.mode = MODE_Insert;
2700 data.zDestTable = "sqlite_stat1";
2701 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2702 shell_callback, &data,&zErrMsg);
2703 data.zDestTable = "sqlite_stat3";
2704 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2705 shell_callback, &data,&zErrMsg);
2706 data.zDestTable = "sqlite_stat4";
2707 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2708 shell_callback, &data, &zErrMsg);
2709 fprintf(p->out, "ANALYZE sqlite_master;\n");
2710 }
drhc1971542014-06-23 23:28:13 +00002711 }else
2712
drhc2ce0be2014-05-29 12:36:14 +00002713 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2714 if( nArg==2 ){
2715 p->showHeader = booleanValue(azArg[1]);
2716 }else{
2717 fprintf(stderr, "Usage: .headers on|off\n");
2718 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002719 }
drh75897232000-05-29 14:26:00 +00002720 }else
2721
drhc2ce0be2014-05-29 12:36:14 +00002722 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2723 fprintf(p->out, "%s", zHelp);
2724 }else
2725
2726 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002727 char *zTable; /* Insert data into this table */
2728 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002729 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002730 int nCol; /* Number of columns in the table */
2731 int nByte; /* Number of bytes in an SQL string */
2732 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002733 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002734 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002735 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002736 ImportCtx sCtx; /* Reader context */
mistachkin486fd432014-07-24 22:20:23 +00002737 char *(*xRead)(ImportCtx*); /* Procedure to read one value */
drh5bde8162013-06-27 14:07:53 +00002738 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002739
drhc2ce0be2014-05-29 12:36:14 +00002740 if( nArg!=3 ){
2741 fprintf(stderr, "Usage: .import FILE TABLE\n");
2742 goto meta_command_exit;
2743 }
drh01f37542014-05-31 15:43:33 +00002744 zFile = azArg[1];
2745 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002746 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002747 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002748 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002749 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002750 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002751 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002752 return 1;
drhfeac5f82004-08-01 00:10:45 +00002753 }
drhdb95f682013-06-26 22:46:00 +00002754 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002755 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002756 " for import\n");
2757 return 1;
2758 }
mistachkin636bf9f2014-07-19 20:15:16 +00002759 nSep = strlen30(p->rowSeparator);
2760 if( nSep==0 ){
2761 fprintf(stderr, "Error: non-null row separator required for import\n");
2762 return 1;
2763 }
mistachkine0d68852014-12-11 03:12:33 +00002764 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2765 /* When importing CSV (only), if the row separator is set to the
2766 ** default output row separator, change it to the default input
2767 ** row separator. This avoids having to maintain different input
2768 ** and output row separators. */
2769 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2770 nSep = strlen30(p->rowSeparator);
2771 }
mistachkin636bf9f2014-07-19 20:15:16 +00002772 if( nSep>1 ){
2773 fprintf(stderr, "Error: multi-character row separators not allowed"
2774 " for import\n");
2775 return 1;
2776 }
2777 sCtx.zFile = zFile;
2778 sCtx.nLine = 1;
2779 if( sCtx.zFile[0]=='|' ){
2780 sCtx.in = popen(sCtx.zFile+1, "r");
2781 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00002782 xCloser = pclose;
2783 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002784 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00002785 xCloser = fclose;
2786 }
mistachkin636bf9f2014-07-19 20:15:16 +00002787 if( p->mode==MODE_Ascii ){
2788 xRead = ascii_read_one_field;
2789 }else{
2790 xRead = csv_read_one_field;
2791 }
2792 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002793 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002794 return 1;
2795 }
mistachkin636bf9f2014-07-19 20:15:16 +00002796 sCtx.cColSep = p->colSeparator[0];
2797 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00002798 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002799 if( zSql==0 ){
2800 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002801 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002802 return 1;
2803 }
drh4f21c4a2008-12-10 22:15:00 +00002804 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002805 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002806 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
drhdb95f682013-06-26 22:46:00 +00002807 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2808 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2809 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00002810 while( xRead(&sCtx) ){
2811 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00002812 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00002813 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00002814 }
drh5bde8162013-06-27 14:07:53 +00002815 if( cSep=='(' ){
2816 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00002817 sqlite3_free(sCtx.z);
2818 xCloser(sCtx.in);
2819 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00002820 return 1;
2821 }
drhdb95f682013-06-26 22:46:00 +00002822 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2823 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2824 sqlite3_free(zCreate);
2825 if( rc ){
2826 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2827 sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002828 sqlite3_free(sCtx.z);
2829 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00002830 return 1;
2831 }
drhc7181902014-02-27 15:04:13 +00002832 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002833 }
drhfeac5f82004-08-01 00:10:45 +00002834 sqlite3_free(zSql);
2835 if( rc ){
shane916f9612009-10-23 00:37:15 +00002836 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002837 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002838 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002839 return 1;
drhfeac5f82004-08-01 00:10:45 +00002840 }
shane916f9612009-10-23 00:37:15 +00002841 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002842 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002843 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002844 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002845 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002846 if( zSql==0 ){
2847 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002848 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002849 return 1;
2850 }
drhdb95f682013-06-26 22:46:00 +00002851 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002852 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002853 for(i=1; i<nCol; i++){
2854 zSql[j++] = ',';
2855 zSql[j++] = '?';
2856 }
2857 zSql[j++] = ')';
2858 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00002859 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002860 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002861 if( rc ){
2862 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002863 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00002864 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00002865 return 1;
drhfeac5f82004-08-01 00:10:45 +00002866 }
drh2d463112013-08-06 14:36:36 +00002867 needCommit = sqlite3_get_autocommit(db);
2868 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00002869 do{
mistachkin636bf9f2014-07-19 20:15:16 +00002870 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00002871 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00002872 char *z = xRead(&sCtx);
2873 /*
2874 ** Did we reach end-of-file before finding any columns?
2875 ** If so, stop instead of NULL filling the remaining columns.
2876 */
drhdb95f682013-06-26 22:46:00 +00002877 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00002878 /*
2879 ** Did we reach end-of-file OR end-of-line before finding any
2880 ** columns in ASCII mode? If so, stop instead of NULL filling
2881 ** the remaining columns.
2882 */
2883 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00002884 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00002885 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00002886 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2887 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00002888 sCtx.zFile, startLine, nCol, i+1);
drhdb95f682013-06-26 22:46:00 +00002889 i++;
mistachkin6fe03382014-06-16 22:45:28 +00002890 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002891 }
drhfeac5f82004-08-01 00:10:45 +00002892 }
mistachkin636bf9f2014-07-19 20:15:16 +00002893 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00002894 do{
mistachkin636bf9f2014-07-19 20:15:16 +00002895 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00002896 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00002897 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00002898 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2899 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00002900 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002901 }
drhdb95f682013-06-26 22:46:00 +00002902 if( i>=nCol ){
2903 sqlite3_step(pStmt);
2904 rc = sqlite3_reset(pStmt);
2905 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00002906 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
drhdb95f682013-06-26 22:46:00 +00002907 sqlite3_errmsg(db));
2908 }
2909 }
mistachkin636bf9f2014-07-19 20:15:16 +00002910 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00002911
mistachkin636bf9f2014-07-19 20:15:16 +00002912 xCloser(sCtx.in);
2913 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00002914 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00002915 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002916 }else
2917
drhc2ce0be2014-05-29 12:36:14 +00002918 if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002919 ShellState data;
drh75897232000-05-29 14:26:00 +00002920 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002921 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00002922 memcpy(&data, p, sizeof(data));
2923 data.showHeader = 0;
2924 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002925 if( nArg==1 ){
2926 rc = sqlite3_exec(p->db,
2927 "SELECT name FROM sqlite_master "
2928 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2929 "UNION ALL "
2930 "SELECT name FROM sqlite_temp_master "
2931 "WHERE type='index' "
2932 "ORDER BY 1",
2933 callback, &data, &zErrMsg
2934 );
drhc2ce0be2014-05-29 12:36:14 +00002935 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00002936 zShellStatic = azArg[1];
2937 rc = sqlite3_exec(p->db,
2938 "SELECT name FROM sqlite_master "
2939 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2940 "UNION ALL "
2941 "SELECT name FROM sqlite_temp_master "
2942 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2943 "ORDER BY 1",
2944 callback, &data, &zErrMsg
2945 );
2946 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00002947 }else{
2948 fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
2949 rc = 1;
2950 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00002951 }
drh75897232000-05-29 14:26:00 +00002952 if( zErrMsg ){
2953 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002954 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002955 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002956 }else if( rc != SQLITE_OK ){
2957 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2958 rc = 1;
drh75897232000-05-29 14:26:00 +00002959 }
2960 }else
2961
drhae5e4452007-05-03 17:18:36 +00002962#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002963 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002964 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002965 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2966 iotrace = 0;
2967 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002968 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002969 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002970 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002971 iotrace = stdout;
2972 }else{
2973 iotrace = fopen(azArg[1], "w");
2974 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002975 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002976 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002977 rc = 1;
drhb0603412007-02-28 04:47:26 +00002978 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002979 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002980 }
2981 }
2982 }else
drhae5e4452007-05-03 17:18:36 +00002983#endif
drhb0603412007-02-28 04:47:26 +00002984
drh70df4fe2006-06-13 15:12:21 +00002985#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00002986 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00002987 const char *zFile, *zProc;
2988 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00002989 if( nArg<2 ){
2990 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
2991 rc = 1;
2992 goto meta_command_exit;
2993 }
drh1e397f82006-06-08 15:28:43 +00002994 zFile = azArg[1];
2995 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00002996 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00002997 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2998 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002999 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003000 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003001 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003002 }
3003 }else
drh70df4fe2006-06-13 15:12:21 +00003004#endif
drh1e397f82006-06-08 15:28:43 +00003005
drhc2ce0be2014-05-29 12:36:14 +00003006 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3007 if( nArg!=2 ){
3008 fprintf(stderr, "Usage: .log FILENAME\n");
3009 rc = 1;
3010 }else{
3011 const char *zFile = azArg[1];
3012 output_file_close(p->pLog);
3013 p->pLog = output_file_open(zFile);
3014 }
drh127f9d72010-02-23 01:47:00 +00003015 }else
3016
drhc2ce0be2014-05-29 12:36:14 +00003017 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3018 const char *zMode = nArg>=2 ? azArg[1] : "";
3019 int n2 = (int)strlen(zMode);
3020 int c2 = zMode[0];
3021 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003022 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003023 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003024 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003025 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003026 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003027 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003028 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003029 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003030 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003031 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
3032 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
drhc2ce0be2014-05-29 12:36:14 +00003033 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003034 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003035 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003036 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003037 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003038 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003039 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
3040 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
drhc2ce0be2014-05-29 12:36:14 +00003041 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003042 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003043 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003044 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3045 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003046 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3047 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003048 }else {
shane9bd1b442009-10-23 01:27:39 +00003049 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003050 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003051 rc = 1;
drh75897232000-05-29 14:26:00 +00003052 }
3053 }else
3054
drhc2ce0be2014-05-29 12:36:14 +00003055 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3056 if( nArg==2 ){
3057 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
3058 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
3059 }else{
3060 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003061 rc = 1;
3062 }
3063 }else
3064
drh05782482013-10-24 15:20:20 +00003065 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3066 sqlite3 *savedDb = p->db;
3067 const char *zSavedFilename = p->zDbFilename;
3068 char *zNewFilename = 0;
3069 p->db = 0;
3070 if( nArg>=2 ){
3071 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3072 }
3073 open_db(p, 1);
3074 if( p->db!=0 ){
3075 sqlite3_close(savedDb);
3076 sqlite3_free(p->zFreeOnClose);
3077 p->zFreeOnClose = zNewFilename;
3078 }else{
3079 sqlite3_free(zNewFilename);
3080 p->db = savedDb;
3081 p->zDbFilename = zSavedFilename;
3082 }
3083 }else
3084
drhc2ce0be2014-05-29 12:36:14 +00003085 if( c=='o'
3086 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3087 ){
3088 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3089 if( nArg>2 ){
3090 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3091 rc = 1;
3092 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003093 }
drhc2ce0be2014-05-29 12:36:14 +00003094 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3095 if( nArg<2 ){
3096 fprintf(stderr, "Usage: .once FILE\n");
3097 rc = 1;
3098 goto meta_command_exit;
3099 }
3100 p->outCount = 2;
3101 }else{
3102 p->outCount = 0;
3103 }
3104 output_reset(p);
3105 if( zFile[0]=='|' ){
3106 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003107 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003108 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003109 p->out = stdout;
3110 rc = 1;
3111 }else{
drhc2ce0be2014-05-29 12:36:14 +00003112 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003113 }
drh75897232000-05-29 14:26:00 +00003114 }else{
drhc2ce0be2014-05-29 12:36:14 +00003115 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003116 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003117 if( strcmp(zFile,"off")!=0 ){
3118 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003119 }
drh75897232000-05-29 14:26:00 +00003120 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003121 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003122 } else {
drhc2ce0be2014-05-29 12:36:14 +00003123 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003124 }
3125 }
3126 }else
3127
drh078b1fd2012-09-21 13:40:02 +00003128 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3129 int i;
3130 for(i=1; i<nArg; i++){
3131 if( i>1 ) fprintf(p->out, " ");
3132 fprintf(p->out, "%s", azArg[i]);
3133 }
3134 fprintf(p->out, "\n");
3135 }else
3136
drhc2ce0be2014-05-29 12:36:14 +00003137 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003138 if( nArg >= 2) {
3139 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3140 }
3141 if( nArg >= 3) {
3142 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3143 }
3144 }else
3145
drhc2ce0be2014-05-29 12:36:14 +00003146 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003147 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003148 }else
3149
drhc2ce0be2014-05-29 12:36:14 +00003150 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3151 FILE *alt;
3152 if( nArg!=2 ){
3153 fprintf(stderr, "Usage: .read FILE\n");
3154 rc = 1;
3155 goto meta_command_exit;
3156 }
3157 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003158 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003159 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3160 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003161 }else{
shane9bd1b442009-10-23 01:27:39 +00003162 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003163 fclose(alt);
3164 }
3165 }else
3166
drhc2ce0be2014-05-29 12:36:14 +00003167 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003168 const char *zSrcFile;
3169 const char *zDb;
3170 sqlite3 *pSrc;
3171 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003172 int nTimeout = 0;
3173
drh9ff849f2009-02-04 20:55:57 +00003174 if( nArg==2 ){
3175 zSrcFile = azArg[1];
3176 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003177 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003178 zSrcFile = azArg[2];
3179 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003180 }else{
3181 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3182 rc = 1;
3183 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003184 }
3185 rc = sqlite3_open(zSrcFile, &pSrc);
3186 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003187 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003188 sqlite3_close(pSrc);
3189 return 1;
3190 }
drh05782482013-10-24 15:20:20 +00003191 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003192 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3193 if( pBackup==0 ){
3194 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3195 sqlite3_close(pSrc);
3196 return 1;
3197 }
drhdc2c4912009-02-04 22:46:47 +00003198 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3199 || rc==SQLITE_BUSY ){
3200 if( rc==SQLITE_BUSY ){
3201 if( nTimeout++ >= 3 ) break;
3202 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003203 }
3204 }
3205 sqlite3_backup_finish(pBackup);
3206 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003207 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003208 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003209 fprintf(stderr, "Error: source database is busy\n");
3210 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003211 }else{
3212 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003213 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003214 }
3215 sqlite3_close(pSrc);
3216 }else
3217
dan8d1edb92014-11-05 09:07:28 +00003218
3219 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3220 if( nArg==2 ){
3221 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003222#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3223 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3224#endif
dan8d1edb92014-11-05 09:07:28 +00003225 }else{
3226 fprintf(stderr, "Usage: .scanstats on|off\n");
3227 rc = 1;
3228 }
3229 }else
3230
drhc2ce0be2014-05-29 12:36:14 +00003231 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003232 ShellState data;
drh75897232000-05-29 14:26:00 +00003233 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003234 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003235 memcpy(&data, p, sizeof(data));
3236 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003237 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003238 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003239 int i;
drhf0693c82011-10-11 20:41:54 +00003240 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003241 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003242 char *new_argv[2], *new_colv[2];
3243 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3244 " type text,\n"
3245 " name text,\n"
3246 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003247 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003248 " sql text\n"
3249 ")";
3250 new_argv[1] = 0;
3251 new_colv[0] = "sql";
3252 new_colv[1] = 0;
3253 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003254 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003255 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003256 char *new_argv[2], *new_colv[2];
3257 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3258 " type text,\n"
3259 " name text,\n"
3260 " tbl_name text,\n"
3261 " rootpage integer,\n"
3262 " sql text\n"
3263 ")";
3264 new_argv[1] = 0;
3265 new_colv[0] = "sql";
3266 new_colv[1] = 0;
3267 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003268 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003269 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003270 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003271 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003272 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003273 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003274 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003275 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003276 "WHERE lower(tbl_name) LIKE shellstatic()"
3277 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003278 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003279 callback, &data, &zErrMsg);
3280 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003281 }
drhc2ce0be2014-05-29 12:36:14 +00003282 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003283 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003284 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003285 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003286 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003287 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003288 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003289 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003290 callback, &data, &zErrMsg
3291 );
drhc2ce0be2014-05-29 12:36:14 +00003292 }else{
3293 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3294 rc = 1;
3295 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003296 }
drh75897232000-05-29 14:26:00 +00003297 if( zErrMsg ){
3298 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003299 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003300 rc = 1;
3301 }else if( rc != SQLITE_OK ){
3302 fprintf(stderr,"Error: querying schema information\n");
3303 rc = 1;
3304 }else{
3305 rc = 0;
drh75897232000-05-29 14:26:00 +00003306 }
3307 }else
3308
drhabd4c722014-09-20 18:18:33 +00003309
3310#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3311 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3312 extern int sqlite3SelectTrace;
3313 sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
3314 }else
3315#endif
3316
3317
drh340f5822013-06-27 13:01:21 +00003318#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003319 /* Undocumented commands for internal testing. Subject to change
3320 ** without notice. */
3321 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3322 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3323 int i, v;
3324 for(i=1; i<nArg; i++){
3325 v = booleanValue(azArg[i]);
3326 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3327 }
3328 }
3329 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3330 int i; sqlite3_int64 v;
3331 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003332 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003333 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003334 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003335 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003336 }
3337 }
3338 }else
drh340f5822013-06-27 13:01:21 +00003339#endif
drh348d19c2013-06-03 12:47:43 +00003340
drhc2ce0be2014-05-29 12:36:14 +00003341 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003342 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003343 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003344 rc = 1;
3345 }
drh6976c212014-07-24 12:09:47 +00003346 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003347 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003348 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003349 }
3350 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003351 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3352 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003353 }
drh75897232000-05-29 14:26:00 +00003354 }else
3355
drh62cdde52014-05-28 20:22:28 +00003356 if( c=='s'
3357 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003358 ){
3359 char *zCmd;
drh54027102014-08-06 14:36:53 +00003360 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003361 if( nArg<2 ){
3362 fprintf(stderr, "Usage: .system COMMAND\n");
3363 rc = 1;
3364 goto meta_command_exit;
3365 }
drhdcb3e3d2014-05-29 03:17:29 +00003366 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003367 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003368 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3369 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003370 }
drh54027102014-08-06 14:36:53 +00003371 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003372 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003373 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003374 }else
3375
drhc2ce0be2014-05-29 12:36:14 +00003376 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003377 int i;
drhc2ce0be2014-05-29 12:36:14 +00003378 if( nArg!=1 ){
3379 fprintf(stderr, "Usage: .show\n");
3380 rc = 1;
3381 goto meta_command_exit;
3382 }
mistachkin636bf9f2014-07-19 20:15:16 +00003383 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3384 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003385 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003386 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3387 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3388 fprintf(p->out,"%12.12s: ", "nullvalue");
drhfeac5f82004-08-01 00:10:45 +00003389 output_c_string(p->out, p->nullvalue);
3390 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003391 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003392 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003393 fprintf(p->out,"%12.12s: ", "colseparator");
3394 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003395 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003396 fprintf(p->out,"%12.12s: ", "rowseparator");
3397 output_c_string(p->out, p->rowSeparator);
3398 fprintf(p->out, "\n");
3399 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3400 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003401 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003402 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003403 }
drhfeac5f82004-08-01 00:10:45 +00003404 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003405 }else
3406
drhc2ce0be2014-05-29 12:36:14 +00003407 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3408 if( nArg==2 ){
3409 p->statsOn = booleanValue(azArg[1]);
3410 }else{
3411 fprintf(stderr, "Usage: .stats on|off\n");
3412 rc = 1;
3413 }
shaneh642d8b82010-07-28 16:05:34 +00003414 }else
3415
drhc2ce0be2014-05-29 12:36:14 +00003416 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003417 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003418 char **azResult;
drh98781232012-04-23 12:38:05 +00003419 int nRow, nAlloc;
3420 char *zSql = 0;
3421 int ii;
drh05782482013-10-24 15:20:20 +00003422 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003423 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3424 if( rc ) return rc;
3425 zSql = sqlite3_mprintf(
3426 "SELECT name FROM sqlite_master"
3427 " WHERE type IN ('table','view')"
3428 " AND name NOT LIKE 'sqlite_%%'"
3429 " AND name LIKE ?1");
3430 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3431 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3432 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3433 if( strcmp(zDbName,"temp")==0 ){
3434 zSql = sqlite3_mprintf(
3435 "%z UNION ALL "
3436 "SELECT 'temp.' || name FROM sqlite_temp_master"
3437 " WHERE type IN ('table','view')"
3438 " AND name NOT LIKE 'sqlite_%%'"
3439 " AND name LIKE ?1", zSql);
3440 }else{
3441 zSql = sqlite3_mprintf(
3442 "%z UNION ALL "
3443 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3444 " WHERE type IN ('table','view')"
3445 " AND name NOT LIKE 'sqlite_%%'"
3446 " AND name LIKE ?1", zSql, zDbName, zDbName);
3447 }
drha50da102000-08-08 20:19:09 +00003448 }
drh98781232012-04-23 12:38:05 +00003449 sqlite3_finalize(pStmt);
3450 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3451 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3452 sqlite3_free(zSql);
3453 if( rc ) return rc;
3454 nRow = nAlloc = 0;
3455 azResult = 0;
3456 if( nArg>1 ){
3457 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003458 }else{
drh98781232012-04-23 12:38:05 +00003459 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3460 }
3461 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3462 if( nRow>=nAlloc ){
3463 char **azNew;
3464 int n = nAlloc*2 + 10;
3465 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3466 if( azNew==0 ){
3467 fprintf(stderr, "Error: out of memory\n");
3468 break;
3469 }
3470 nAlloc = n;
3471 azResult = azNew;
3472 }
3473 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3474 if( azResult[nRow] ) nRow++;
3475 }
3476 sqlite3_finalize(pStmt);
3477 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003478 int len, maxlen = 0;
3479 int i, j;
3480 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003481 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003482 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003483 if( len>maxlen ) maxlen = len;
3484 }
3485 nPrintCol = 80/(maxlen+2);
3486 if( nPrintCol<1 ) nPrintCol = 1;
3487 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3488 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003489 for(j=i; j<nRow; j+=nPrintRow){
3490 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003491 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003492 }
drh151b7d52013-05-06 20:28:54 +00003493 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003494 }
3495 }
drh98781232012-04-23 12:38:05 +00003496 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3497 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003498 }else
3499
shaneh96887e12011-02-10 21:08:58 +00003500 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003501 static const struct {
3502 const char *zCtrlName; /* Name of a test-control option */
3503 int ctrlCode; /* Integer code for that option */
3504 } aCtrl[] = {
3505 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3506 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3507 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3508 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3509 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3510 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3511 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3512 { "assert", SQLITE_TESTCTRL_ASSERT },
3513 { "always", SQLITE_TESTCTRL_ALWAYS },
3514 { "reserve", SQLITE_TESTCTRL_RESERVE },
3515 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3516 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003517 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003518 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhd416fe72011-03-17 16:45:50 +00003519 };
shaneh96887e12011-02-10 21:08:58 +00003520 int testctrl = -1;
3521 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003522 int i, n;
drh05782482013-10-24 15:20:20 +00003523 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003524
drhd416fe72011-03-17 16:45:50 +00003525 /* convert testctrl text option to value. allow any unique prefix
3526 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003527 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003528 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003529 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3530 if( testctrl<0 ){
3531 testctrl = aCtrl[i].ctrlCode;
3532 }else{
drhb07028f2011-10-14 21:49:18 +00003533 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003534 testctrl = -1;
3535 break;
3536 }
3537 }
3538 }
drh348d19c2013-06-03 12:47:43 +00003539 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003540 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3541 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3542 }else{
3543 switch(testctrl){
3544
3545 /* sqlite3_test_control(int, db, int) */
3546 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3547 case SQLITE_TESTCTRL_RESERVE:
3548 if( nArg==3 ){
3549 int opt = (int)strtol(azArg[2], 0, 0);
3550 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003551 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003552 } else {
drhd416fe72011-03-17 16:45:50 +00003553 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3554 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003555 }
3556 break;
3557
3558 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003559 case SQLITE_TESTCTRL_PRNG_SAVE:
3560 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003561 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003562 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003563 if( nArg==2 ){
3564 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003565 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003566 } else {
3567 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3568 }
3569 break;
3570
3571 /* sqlite3_test_control(int, uint) */
3572 case SQLITE_TESTCTRL_PENDING_BYTE:
3573 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003574 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003575 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003576 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003577 } else {
drhd416fe72011-03-17 16:45:50 +00003578 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3579 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003580 }
3581 break;
3582
3583 /* sqlite3_test_control(int, int) */
3584 case SQLITE_TESTCTRL_ASSERT:
3585 case SQLITE_TESTCTRL_ALWAYS:
3586 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003587 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003588 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003589 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003590 } else {
drhd416fe72011-03-17 16:45:50 +00003591 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3592 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003593 }
3594 break;
3595
3596 /* sqlite3_test_control(int, char *) */
3597#ifdef SQLITE_N_KEYWORD
3598 case SQLITE_TESTCTRL_ISKEYWORD:
3599 if( nArg==3 ){
3600 const char *opt = azArg[2];
3601 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003602 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003603 } else {
drhd416fe72011-03-17 16:45:50 +00003604 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3605 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003606 }
3607 break;
3608#endif
3609
3610 case SQLITE_TESTCTRL_BITVEC_TEST:
3611 case SQLITE_TESTCTRL_FAULT_INSTALL:
3612 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3613 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3614 default:
drhd416fe72011-03-17 16:45:50 +00003615 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3616 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003617 break;
3618 }
3619 }
3620 }else
3621
drhc2ce0be2014-05-29 12:36:14 +00003622 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003623 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003624 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003625 }else
3626
drhc2ce0be2014-05-29 12:36:14 +00003627 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3628 if( nArg==2 ){
3629 enableTimer = booleanValue(azArg[1]);
3630 if( enableTimer && !HAS_TIMER ){
3631 fprintf(stderr, "Error: timer not available on this system.\n");
3632 enableTimer = 0;
3633 }
3634 }else{
3635 fprintf(stderr, "Usage: .timer on|off\n");
3636 rc = 1;
3637 }
shanehe2aa9d72009-11-06 17:20:17 +00003638 }else
3639
drhc2ce0be2014-05-29 12:36:14 +00003640 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003641 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00003642 output_file_close(p->traceOut);
drhc2ce0be2014-05-29 12:36:14 +00003643 if( nArg!=2 ){
3644 fprintf(stderr, "Usage: .trace FILE|off\n");
3645 rc = 1;
3646 goto meta_command_exit;
3647 }
drh42f64e52012-04-04 16:56:23 +00003648 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003649#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003650 if( p->traceOut==0 ){
3651 sqlite3_trace(p->db, 0, 0);
3652 }else{
3653 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3654 }
3655#endif
3656 }else
3657
drhf442e332014-09-10 19:01:14 +00003658#if SQLITE_USER_AUTHENTICATION
3659 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3660 if( nArg<2 ){
3661 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3662 rc = 1;
3663 goto meta_command_exit;
3664 }
drh7883ecf2014-09-11 16:19:31 +00003665 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003666 if( strcmp(azArg[1],"login")==0 ){
3667 if( nArg!=4 ){
3668 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3669 rc = 1;
3670 goto meta_command_exit;
3671 }
drhd39c40f2014-09-11 00:27:53 +00003672 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3673 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003674 if( rc ){
3675 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3676 rc = 1;
3677 }
3678 }else if( strcmp(azArg[1],"add")==0 ){
3679 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003680 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003681 rc = 1;
3682 goto meta_command_exit;
3683 }
drhd39c40f2014-09-11 00:27:53 +00003684 rc = sqlite3_user_add(p->db, azArg[2],
3685 azArg[3], (int)strlen(azArg[3]),
3686 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003687 if( rc ){
3688 fprintf(stderr, "User-Add failed: %d\n", rc);
3689 rc = 1;
3690 }
3691 }else if( strcmp(azArg[1],"edit")==0 ){
3692 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003693 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003694 rc = 1;
3695 goto meta_command_exit;
3696 }
drhd39c40f2014-09-11 00:27:53 +00003697 rc = sqlite3_user_change(p->db, azArg[2],
3698 azArg[3], (int)strlen(azArg[3]),
3699 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003700 if( rc ){
3701 fprintf(stderr, "User-Edit failed: %d\n", rc);
3702 rc = 1;
3703 }
3704 }else if( strcmp(azArg[1],"delete")==0 ){
3705 if( nArg!=3 ){
3706 fprintf(stderr, "Usage: .user delete USER\n");
3707 rc = 1;
3708 goto meta_command_exit;
3709 }
3710 rc = sqlite3_user_delete(p->db, azArg[2]);
3711 if( rc ){
3712 fprintf(stderr, "User-Delete failed: %d\n", rc);
3713 rc = 1;
3714 }
3715 }else{
3716 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
3717 rc = 1;
3718 goto meta_command_exit;
3719 }
3720 }else
3721#endif /* SQLITE_USER_AUTHENTICATION */
3722
drh9fd301b2011-06-03 13:28:22 +00003723 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003724 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003725 sqlite3_libversion(), sqlite3_sourceid());
3726 }else
3727
drhde60fc22011-12-14 17:53:36 +00003728 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3729 const char *zDbName = nArg==2 ? azArg[1] : "main";
3730 char *zVfsName = 0;
3731 if( p->db ){
3732 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3733 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003734 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003735 sqlite3_free(zVfsName);
3736 }
3737 }
3738 }else
3739
drhcef4fc82012-09-21 22:50:45 +00003740#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3741 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3742 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003743 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003744 }else
3745#endif
3746
drhc2ce0be2014-05-29 12:36:14 +00003747 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003748 int j;
drh43617e92006-03-06 20:55:46 +00003749 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003750 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003751 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003752 }
3753 }else
3754
3755 {
shane9bd1b442009-10-23 01:27:39 +00003756 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003757 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003758 rc = 1;
drh75897232000-05-29 14:26:00 +00003759 }
drh67505e72002-04-19 12:34:06 +00003760
drhc2ce0be2014-05-29 12:36:14 +00003761meta_command_exit:
3762 if( p->outCount ){
3763 p->outCount--;
3764 if( p->outCount==0 ) output_reset(p);
3765 }
drh67505e72002-04-19 12:34:06 +00003766 return rc;
drh75897232000-05-29 14:26:00 +00003767}
3768
drh67505e72002-04-19 12:34:06 +00003769/*
drh91a66392007-09-07 01:12:32 +00003770** Return TRUE if a semicolon occurs anywhere in the first N characters
3771** of string z[].
drh324ccef2003-02-05 14:06:20 +00003772*/
drh9f099fd2013-08-06 14:01:46 +00003773static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00003774 int i;
3775 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3776 return 0;
drh324ccef2003-02-05 14:06:20 +00003777}
3778
3779/*
drh70c7a4b2003-04-26 03:03:06 +00003780** Test to see if a line consists entirely of whitespace.
3781*/
3782static int _all_whitespace(const char *z){
3783 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00003784 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003785 if( *z=='/' && z[1]=='*' ){
3786 z += 2;
3787 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3788 if( *z==0 ) return 0;
3789 z++;
3790 continue;
3791 }
3792 if( *z=='-' && z[1]=='-' ){
3793 z += 2;
3794 while( *z && *z!='\n' ){ z++; }
3795 if( *z==0 ) return 1;
3796 continue;
3797 }
3798 return 0;
3799 }
3800 return 1;
3801}
3802
3803/*
drha9b17162003-04-29 18:01:28 +00003804** Return TRUE if the line typed in is an SQL command terminator other
3805** than a semi-colon. The SQL Server style "go" command is understood
3806** as is the Oracle "/".
3807*/
drh9f099fd2013-08-06 14:01:46 +00003808static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00003809 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00003810 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3811 return 1; /* Oracle */
3812 }
drhf0693c82011-10-11 20:41:54 +00003813 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00003814 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00003815 return 1; /* SQL Server */
3816 }
3817 return 0;
3818}
3819
3820/*
drh233a5312008-12-18 22:25:13 +00003821** Return true if zSql is a complete SQL statement. Return false if it
3822** ends in the middle of a string literal or C-style comment.
3823*/
drh9f099fd2013-08-06 14:01:46 +00003824static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00003825 int rc;
3826 if( zSql==0 ) return 1;
3827 zSql[nSql] = ';';
3828 zSql[nSql+1] = 0;
3829 rc = sqlite3_complete(zSql);
3830 zSql[nSql] = 0;
3831 return rc;
3832}
3833
3834/*
drh67505e72002-04-19 12:34:06 +00003835** Read input from *in and process it. If *in==0 then input
3836** is interactive - the user is typing it it. Otherwise, input
3837** is coming from a file or device. A prompt is issued and history
3838** is saved only if input is interactive. An interrupt signal will
3839** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00003840**
3841** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00003842*/
drhdcd87a92014-08-18 13:45:42 +00003843static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00003844 char *zLine = 0; /* A single input line */
3845 char *zSql = 0; /* Accumulated SQL text */
3846 int nLine; /* Length of current line */
3847 int nSql = 0; /* Bytes of zSql[] used */
3848 int nAlloc = 0; /* Allocated zSql[] space */
3849 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
3850 char *zErrMsg; /* Error message returned */
3851 int rc; /* Error code */
3852 int errCnt = 0; /* Number of errors seen */
3853 int lineno = 0; /* Current line number */
3854 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00003855
3856 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
3857 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00003858 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00003859 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00003860 /* End of input */
3861 if( stdin_is_interactive ) printf("\n");
3862 break;
drhc49f44e2006-10-26 18:15:42 +00003863 }
drh67505e72002-04-19 12:34:06 +00003864 if( seenInterrupt ){
3865 if( in!=0 ) break;
3866 seenInterrupt = 0;
3867 }
drhc28490c2006-10-26 14:25:58 +00003868 lineno++;
drh849a9d92013-12-21 15:46:06 +00003869 if( nSql==0 && _all_whitespace(zLine) ){
3870 if( p->echoOn ) printf("%s\n", zLine);
3871 continue;
3872 }
drh2af0b2d2002-02-21 02:25:02 +00003873 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00003874 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00003875 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00003876 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00003877 break;
3878 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00003879 errCnt++;
3880 }
drhdaffd0e2001-04-11 14:28:42 +00003881 continue;
3882 }
drh9f099fd2013-08-06 14:01:46 +00003883 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00003884 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00003885 }
drh9f099fd2013-08-06 14:01:46 +00003886 nLine = strlen30(zLine);
3887 if( nSql+nLine+2>=nAlloc ){
3888 nAlloc = nSql+nLine+100;
3889 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00003890 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00003891 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00003892 exit(1);
3893 }
drhdaffd0e2001-04-11 14:28:42 +00003894 }
drh9f099fd2013-08-06 14:01:46 +00003895 nSqlPrior = nSql;
3896 if( nSql==0 ){
3897 int i;
3898 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00003899 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00003900 memcpy(zSql, zLine+i, nLine+1-i);
3901 startline = lineno;
3902 nSql = nLine-i;
3903 }else{
3904 zSql[nSql++] = '\n';
3905 memcpy(zSql+nSql, zLine, nLine+1);
3906 nSql += nLine;
3907 }
3908 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00003909 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00003910 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00003911 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00003912 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00003913 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00003914 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00003915 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00003916 char zPrefix[100];
3917 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00003918 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00003919 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00003920 }else{
shane9bd1b442009-10-23 01:27:39 +00003921 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00003922 }
drh7f953e22002-07-13 17:33:45 +00003923 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00003924 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003925 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00003926 zErrMsg = 0;
3927 }else{
shaned2bed1c2009-10-21 03:56:54 +00003928 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00003929 }
drhc49f44e2006-10-26 18:15:42 +00003930 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00003931 }
drhdaffd0e2001-04-11 14:28:42 +00003932 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00003933 if( p->outCount ){
3934 output_reset(p);
3935 p->outCount = 0;
3936 }
drh9f099fd2013-08-06 14:01:46 +00003937 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00003938 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00003939 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00003940 }
3941 }
drh9f099fd2013-08-06 14:01:46 +00003942 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00003943 if( !_all_whitespace(zSql) ){
3944 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00003945 errCnt++;
drhd416fe72011-03-17 16:45:50 +00003946 }
drhdaffd0e2001-04-11 14:28:42 +00003947 free(zSql);
3948 }
danielk19772ac27622007-07-03 05:31:16 +00003949 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00003950 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00003951}
3952
drh67505e72002-04-19 12:34:06 +00003953/*
3954** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00003955** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00003956*/
3957static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00003958 static char *home_dir = NULL;
3959 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00003960
drh4ace5362014-11-10 14:42:28 +00003961#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
3962 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00003963 {
3964 struct passwd *pwent;
3965 uid_t uid = getuid();
3966 if( (pwent=getpwuid(uid)) != NULL) {
3967 home_dir = pwent->pw_dir;
3968 }
drh67505e72002-04-19 12:34:06 +00003969 }
3970#endif
3971
chw65d3c132007-11-12 21:09:10 +00003972#if defined(_WIN32_WCE)
3973 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
3974 */
drh85e72432012-04-11 11:38:53 +00003975 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00003976#else
3977
drh83905c92012-06-21 13:00:37 +00003978#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00003979 if (!home_dir) {
3980 home_dir = getenv("USERPROFILE");
3981 }
3982#endif
3983
drh67505e72002-04-19 12:34:06 +00003984 if (!home_dir) {
3985 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00003986 }
3987
drh83905c92012-06-21 13:00:37 +00003988#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00003989 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00003990 char *zDrive, *zPath;
3991 int n;
3992 zDrive = getenv("HOMEDRIVE");
3993 zPath = getenv("HOMEPATH");
3994 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00003995 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00003996 home_dir = malloc( n );
3997 if( home_dir==0 ) return 0;
3998 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3999 return home_dir;
4000 }
4001 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004002 }
4003#endif
4004
chw65d3c132007-11-12 21:09:10 +00004005#endif /* !_WIN32_WCE */
4006
drh67505e72002-04-19 12:34:06 +00004007 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004008 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004009 char *z = malloc( n );
4010 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004011 home_dir = z;
4012 }
drhe98d4fa2002-04-21 19:06:22 +00004013
drh67505e72002-04-19 12:34:06 +00004014 return home_dir;
4015}
4016
4017/*
4018** Read input from the file given by sqliterc_override. Or if that
4019** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004020**
4021** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004022*/
shane9bd1b442009-10-23 01:27:39 +00004023static int process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004024 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004025 const char *sqliterc_override /* Name of config file. NULL to use default */
4026){
persicom7e2dfdd2002-04-18 02:46:52 +00004027 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004028 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004029 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004030 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00004031 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004032
4033 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004034 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004035 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00004036#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00004037 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00004038#endif
shane9bd1b442009-10-23 01:27:39 +00004039 return 1;
drhe98d4fa2002-04-21 19:06:22 +00004040 }
drh2f3de322012-06-27 16:41:31 +00004041 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004042 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4043 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004044 }
drha1f9b5e2004-02-14 16:31:02 +00004045 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004046 if( in ){
drhc28490c2006-10-26 14:25:58 +00004047 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004048 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004049 }
shane9bd1b442009-10-23 01:27:39 +00004050 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004051 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004052 }
drh85e72432012-04-11 11:38:53 +00004053 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00004054 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00004055}
4056
drh67505e72002-04-19 12:34:06 +00004057/*
drhe1e38c42003-05-04 18:30:59 +00004058** Show available command line options
4059*/
4060static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004061 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004062 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004063 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004064 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004065 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004066 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004067 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004068 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004069 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004070#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4071 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4072#endif
drhcc3b4f82012-02-07 14:13:50 +00004073 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004074 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004075 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004076 " -line set output mode to 'line'\n"
4077 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004078 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004079 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004080#ifdef SQLITE_ENABLE_MULTIPLEX
4081 " -multiplex enable the multiplexor VFS\n"
4082#endif
mistachkine0d68852014-12-11 03:12:33 +00004083 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004084 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004085 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4086 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004087 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004088 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004089 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004090 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004091#ifdef SQLITE_ENABLE_VFSTRACE
4092 " -vfstrace enable tracing of all VFS calls\n"
4093#endif
drhe1e38c42003-05-04 18:30:59 +00004094;
4095static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004096 fprintf(stderr,
4097 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4098 "FILENAME is the name of an SQLite database. A new database is created\n"
4099 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004100 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004101 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004102 }else{
4103 fprintf(stderr, "Use the -help option for additional information\n");
4104 }
4105 exit(1);
4106}
4107
4108/*
drh67505e72002-04-19 12:34:06 +00004109** Initialize the state information in data
4110*/
drhdcd87a92014-08-18 13:45:42 +00004111static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004112 memset(data, 0, sizeof(*data));
4113 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004114 memcpy(data->colSeparator,SEP_Column, 2);
4115 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004116 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004117 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004118 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004119 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004120 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004121 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4122 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004123}
4124
drh98d312f2012-10-25 15:23:14 +00004125/*
drh5c7976f2014-02-10 19:59:27 +00004126** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004127*/
4128#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004129static void printBold(const char *zText){
4130 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4131 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4132 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4133 SetConsoleTextAttribute(out,
4134 FOREGROUND_RED|FOREGROUND_INTENSITY
4135 );
4136 printf("%s", zText);
4137 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004138}
4139#else
drh5c7976f2014-02-10 19:59:27 +00004140static void printBold(const char *zText){
4141 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004142}
4143#endif
4144
4145/*
drh98d312f2012-10-25 15:23:14 +00004146** Get the argument to an --option. Throw an error and die if no argument
4147** is available.
4148*/
4149static char *cmdline_option_value(int argc, char **argv, int i){
4150 if( i==argc ){
4151 fprintf(stderr, "%s: Error: missing argument to %s\n",
4152 argv[0], argv[argc-1]);
4153 exit(1);
4154 }
4155 return argv[i];
4156}
4157
drh75897232000-05-29 14:26:00 +00004158int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004159 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004160 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004161 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004162 int i;
drhc28490c2006-10-26 14:25:58 +00004163 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004164 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004165 int readStdin = 1;
4166 int nCmd = 0;
4167 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004168
drh69b30ab2014-02-27 15:11:52 +00004169#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004170 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4171 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4172 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4173 exit(1);
4174 }
drhc7181902014-02-27 15:04:13 +00004175#endif
drhdaffd0e2001-04-11 14:28:42 +00004176 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004177 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004178 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004179
drh44c2eb12003-04-30 11:38:26 +00004180 /* Make sure we have a valid signal handler early, before anything
4181 ** else is done.
4182 */
drh4c504392000-10-16 22:06:40 +00004183#ifdef SIGINT
4184 signal(SIGINT, interrupt_handler);
4185#endif
drh44c2eb12003-04-30 11:38:26 +00004186
drhac5649a2014-11-28 13:35:03 +00004187#ifdef SQLITE_SHELL_DBNAME_PROC
4188 {
4189 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4190 ** of a C-function that will provide the name of the database file. Use
4191 ** this compile-time option to embed this shell program in larger
4192 ** applications. */
4193 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4194 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4195 warnInmemoryDb = 0;
4196 }
4197#endif
4198
drh22fbcb82004-02-01 01:22:50 +00004199 /* Do an initial pass through the command-line argument to locate
4200 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004201 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004202 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004203 */
drh98d312f2012-10-25 15:23:14 +00004204 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004205 char *z;
drhc28490c2006-10-26 14:25:58 +00004206 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004207 if( z[0]!='-' ){
4208 if( data.zDbFilename==0 ){
4209 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004210 }else{
4211 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4212 ** mean that nothing is read from stdin */
4213 readStdin = 0;
4214 nCmd++;
4215 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4216 if( azCmd==0 ){
4217 fprintf(stderr, "out of memory\n");
4218 exit(1);
4219 }
4220 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004221 }
drh98d312f2012-10-25 15:23:14 +00004222 }
drhcc3b4f82012-02-07 14:13:50 +00004223 if( z[1]=='-' ) z++;
4224 if( strcmp(z,"-separator")==0
4225 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004226 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004227 || strcmp(z,"-cmd")==0
4228 ){
drh98d312f2012-10-25 15:23:14 +00004229 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004230 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004231 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004232 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004233 /* Need to check for batch mode here to so we can avoid printing
4234 ** informational messages (like from process_sqliterc) before
4235 ** we do the actual processing of arguments later in a second pass.
4236 */
shanef69573d2009-10-24 02:06:14 +00004237 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004238 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004239#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004240 const char *zSize;
4241 sqlite3_int64 szHeap;
4242
drh98d312f2012-10-25 15:23:14 +00004243 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004244 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004245 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004246 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4247#endif
drh44dec872014-08-30 15:49:25 +00004248 }else if( strcmp(z,"-scratch")==0 ){
4249 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004250 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004251 if( sz>400000 ) sz = 400000;
4252 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004253 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004254 if( n>10 ) n = 10;
4255 if( n<1 ) n = 1;
4256 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4257 data.shellFlgs |= SHFLG_Scratch;
4258 }else if( strcmp(z,"-pagecache")==0 ){
4259 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004260 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004261 if( sz>70000 ) sz = 70000;
4262 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004263 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004264 if( n<10 ) n = 10;
4265 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4266 data.shellFlgs |= SHFLG_Pagecache;
4267 }else if( strcmp(z,"-lookaside")==0 ){
4268 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004269 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004270 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004271 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004272 if( n<0 ) n = 0;
4273 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4274 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004275#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004276 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004277 extern int vfstrace_register(
4278 const char *zTraceName,
4279 const char *zOldVfsName,
4280 int (*xOut)(const char*,void*),
4281 void *pOutArg,
4282 int makeDefault
4283 );
drh2b625e22011-03-16 17:05:28 +00004284 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004285#endif
drh6f25e892011-07-08 17:02:57 +00004286#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004287 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004288 extern int sqlite3_multiple_initialize(const char*,int);
4289 sqlite3_multiplex_initialize(0, 1);
4290#endif
drh7d9f3942013-04-03 01:26:54 +00004291 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004292 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4293 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004294 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004295 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004296 if( pVfs ){
4297 sqlite3_vfs_register(pVfs, 1);
4298 }else{
4299 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4300 exit(1);
4301 }
drh44c2eb12003-04-30 11:38:26 +00004302 }
4303 }
drh98d312f2012-10-25 15:23:14 +00004304 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004305#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004306 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004307 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004308#else
shane86f5bdb2009-10-24 02:00:07 +00004309 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4310 return 1;
drh01b41712005-08-29 23:06:23 +00004311#endif
drh98d312f2012-10-25 15:23:14 +00004312 }
4313 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004314
drh44c2eb12003-04-30 11:38:26 +00004315 /* Go ahead and open the database file if it already exists. If the
4316 ** file does not exist, delay opening it. This prevents empty database
4317 ** files from being created if a user mistypes the database name argument
4318 ** to the sqlite command-line tool.
4319 */
drhc8d74412004-08-31 23:41:26 +00004320 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004321 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004322 }
4323
drh22fbcb82004-02-01 01:22:50 +00004324 /* Process the initialization file if there is one. If no -init option
4325 ** is given on the command line, look for a file named ~/.sqliterc and
4326 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004327 */
shane86f5bdb2009-10-24 02:00:07 +00004328 rc = process_sqliterc(&data,zInitFile);
4329 if( rc>0 ){
4330 return rc;
4331 }
drh44c2eb12003-04-30 11:38:26 +00004332
drh22fbcb82004-02-01 01:22:50 +00004333 /* Make a second pass through the command-line argument and set
4334 ** options. This second pass is delayed until after the initialization
4335 ** file is processed so that the command-line arguments will override
4336 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004337 */
drh98d312f2012-10-25 15:23:14 +00004338 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004339 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004340 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004341 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004342 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004343 i++;
4344 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004345 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004346 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004347 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004348 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004349 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004350 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004351 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004352 }else if( strcmp(z,"-csv")==0 ){
4353 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004354 memcpy(data.colSeparator,",",2);
4355 }else if( strcmp(z,"-ascii")==0 ){
4356 data.mode = MODE_Ascii;
4357 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004358 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004359 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004360 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004361 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004362 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4363 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004364 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004365 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004366 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004367 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00004368 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00004369 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004370 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004371 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004372 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004373 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004374 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004375 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004376 }else if( strcmp(z,"-eqp")==0 ){
4377 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004378 }else if( strcmp(z,"-stats")==0 ){
4379 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004380 }else if( strcmp(z,"-scanstats")==0 ){
4381 data.scanstatsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004382 }else if( strcmp(z,"-bail")==0 ){
4383 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004384 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004385 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004386 return 0;
drhc28490c2006-10-26 14:25:58 +00004387 }else if( strcmp(z,"-interactive")==0 ){
4388 stdin_is_interactive = 1;
4389 }else if( strcmp(z,"-batch")==0 ){
4390 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004391 }else if( strcmp(z,"-heap")==0 ){
4392 i++;
drh44dec872014-08-30 15:49:25 +00004393 }else if( strcmp(z,"-scratch")==0 ){
4394 i+=2;
4395 }else if( strcmp(z,"-pagecache")==0 ){
4396 i+=2;
4397 }else if( strcmp(z,"-lookaside")==0 ){
4398 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004399 }else if( strcmp(z,"-mmap")==0 ){
4400 i++;
drha7e61d82011-03-12 17:02:57 +00004401 }else if( strcmp(z,"-vfs")==0 ){
4402 i++;
drh6f25e892011-07-08 17:02:57 +00004403#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004404 }else if( strcmp(z,"-vfstrace")==0 ){
4405 i++;
drh6f25e892011-07-08 17:02:57 +00004406#endif
4407#ifdef SQLITE_ENABLE_MULTIPLEX
4408 }else if( strcmp(z,"-multiplex")==0 ){
4409 i++;
4410#endif
drhcc3b4f82012-02-07 14:13:50 +00004411 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004412 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004413 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004414 /* Run commands that follow -cmd first and separately from commands
4415 ** that simply appear on the command-line. This seems goofy. It would
4416 ** be better if all commands ran in the order that they appear. But
4417 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004418 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004419 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004420 if( z[0]=='.' ){
4421 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004422 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004423 }else{
drh05782482013-10-24 15:20:20 +00004424 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004425 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4426 if( zErrMsg!=0 ){
4427 fprintf(stderr,"Error: %s\n", zErrMsg);
4428 if( bail_on_error ) return rc!=0 ? rc : 1;
4429 }else if( rc!=0 ){
4430 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4431 if( bail_on_error ) return rc;
4432 }
4433 }
drh1e5d0e92000-05-31 23:33:17 +00004434 }else{
shane86f5bdb2009-10-24 02:00:07 +00004435 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004436 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004437 return 1;
4438 }
4439 }
drh44c2eb12003-04-30 11:38:26 +00004440
drhac5649a2014-11-28 13:35:03 +00004441 if( !readStdin ){
4442 /* Run all arguments that do not begin with '-' as if they were separate
4443 ** command-line inputs, except for the argToSkip argument which contains
4444 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004445 */
drhac5649a2014-11-28 13:35:03 +00004446 for(i=0; i<nCmd; i++){
4447 if( azCmd[i][0]=='.' ){
4448 rc = do_meta_command(azCmd[i], &data);
4449 if( rc ) return rc==2 ? 0 : rc;
4450 }else{
4451 open_db(&data, 0);
4452 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4453 if( zErrMsg!=0 ){
4454 fprintf(stderr,"Error: %s\n", zErrMsg);
4455 return rc!=0 ? rc : 1;
4456 }else if( rc!=0 ){
4457 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4458 return rc;
4459 }
drh6ff13852001-11-25 13:18:23 +00004460 }
drh75897232000-05-29 14:26:00 +00004461 }
drhac5649a2014-11-28 13:35:03 +00004462 free(azCmd);
drh75897232000-05-29 14:26:00 +00004463 }else{
drh44c2eb12003-04-30 11:38:26 +00004464 /* Run commands received from standard input
4465 */
drhc28490c2006-10-26 14:25:58 +00004466 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004467 char *zHome;
4468 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004469 int nHistory;
drh75897232000-05-29 14:26:00 +00004470 printf(
drh743e0032011-12-12 16:51:50 +00004471 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004472 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004473 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004474 );
drhb3735912014-02-10 16:13:42 +00004475 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004476 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004477 printBold("transient in-memory database");
4478 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004479 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004480 }
drh67505e72002-04-19 12:34:06 +00004481 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004482 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004483 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004484 if( (zHistory = malloc(nHistory))!=0 ){
4485 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4486 }
drh67505e72002-04-19 12:34:06 +00004487 }
drhaaa21b42014-02-11 14:37:51 +00004488#if defined(HAVE_READLINE)
drh67505e72002-04-19 12:34:06 +00004489 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00004490#endif
drhc28490c2006-10-26 14:25:58 +00004491 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004492 if( zHistory ){
4493 stifle_history(100);
4494 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004495 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004496 }
drhdaffd0e2001-04-11 14:28:42 +00004497 }else{
drhc28490c2006-10-26 14:25:58 +00004498 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004499 }
4500 }
drh33048c02001-10-01 14:29:22 +00004501 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004502 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004503 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004504 }
drh05782482013-10-24 15:20:20 +00004505 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004506 return rc;
drh75897232000-05-29 14:26:00 +00004507}