blob: 7f8a9ef3a69c9e17f8db6d5f480c6432da1642aa [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 */
drha0c66f52000-07-29 13:20:21 +0000476 int colWidth[100]; /* Requested width of each column when in column mode*/
477 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000478 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000479 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000480 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000481 char outfile[FILENAME_MAX]; /* Filename for *out */
482 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000483 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000484 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000485 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000486 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000487 int *aiIndent; /* Array of indents used in MODE_Explain */
488 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000489 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000490};
491
492/*
drh44dec872014-08-30 15:49:25 +0000493** These are the allowed shellFlgs values
494*/
495#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
496#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
497#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
498
499/*
drh75897232000-05-29 14:26:00 +0000500** These are the allowed modes.
501*/
drh967e8b72000-06-21 13:59:10 +0000502#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000503#define MODE_Column 1 /* One record per line in neat columns */
504#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000505#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
506#define MODE_Html 4 /* Generate an XHTML table */
507#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000508#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000509#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000510#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000511#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000512
drh66ce4d02008-02-15 17:38:06 +0000513static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000514 "line",
515 "column",
516 "list",
517 "semi",
518 "html",
drhfeac5f82004-08-01 00:10:45 +0000519 "insert",
520 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000521 "csv",
drh66ce4d02008-02-15 17:38:06 +0000522 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000523 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000524};
drh75897232000-05-29 14:26:00 +0000525
526/*
mistachkinfad42082014-07-24 22:13:12 +0000527** These are the column/row/line separators used by the various
528** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000529*/
mistachkinfad42082014-07-24 22:13:12 +0000530#define SEP_Column "|"
531#define SEP_Row "\n"
532#define SEP_Tab "\t"
533#define SEP_Space " "
534#define SEP_Comma ","
535#define SEP_CrLf "\r\n"
536#define SEP_Unit "\x1F"
537#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000538
539/*
drh75897232000-05-29 14:26:00 +0000540** Number of elements in an array
541*/
drh902b9ee2008-12-05 17:17:07 +0000542#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000543
544/*
drhea678832008-12-10 19:26:22 +0000545** Compute a string length that is limited to what can be stored in
546** lower 30 bits of a 32-bit signed integer.
547*/
drh4f21c4a2008-12-10 22:15:00 +0000548static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000549 const char *z2 = z;
550 while( *z2 ){ z2++; }
551 return 0x3fffffff & (int)(z2 - z);
552}
553
554/*
drh127f9d72010-02-23 01:47:00 +0000555** A callback for the sqlite3_log() interface.
556*/
557static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000558 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000559 if( p->pLog==0 ) return;
560 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
561 fflush(p->pLog);
562}
563
564/*
shane626a6e42009-10-22 17:30:15 +0000565** Output the given string as a hex-encoded blob (eg. X'1234' )
566*/
567static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
568 int i;
569 char *zBlob = (char *)pBlob;
570 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000571 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000572 fprintf(out,"'");
573}
574
575/*
drh28bd4bc2000-06-15 15:57:22 +0000576** Output the given string as a quoted string using SQL quoting conventions.
577*/
578static void output_quoted_string(FILE *out, const char *z){
579 int i;
580 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000581 for(i=0; z[i]; i++){
582 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000583 }
584 if( nSingle==0 ){
585 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000586 }else{
587 fprintf(out,"'");
588 while( *z ){
589 for(i=0; z[i] && z[i]!='\''; i++){}
590 if( i==0 ){
591 fprintf(out,"''");
592 z++;
593 }else if( z[i]=='\'' ){
594 fprintf(out,"%.*s''",i,z);
595 z += i+1;
596 }else{
drhcd7d2732002-02-26 23:24:26 +0000597 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000598 break;
599 }
600 }
drhcd7d2732002-02-26 23:24:26 +0000601 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000602 }
603}
604
605/*
drhfeac5f82004-08-01 00:10:45 +0000606** Output the given string as a quoted according to C or TCL quoting rules.
607*/
608static void output_c_string(FILE *out, const char *z){
609 unsigned int c;
610 fputc('"', out);
611 while( (c = *(z++))!=0 ){
612 if( c=='\\' ){
613 fputc(c, out);
614 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000615 }else if( c=='"' ){
616 fputc('\\', out);
617 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000618 }else if( c=='\t' ){
619 fputc('\\', out);
620 fputc('t', out);
621 }else if( c=='\n' ){
622 fputc('\\', out);
623 fputc('n', out);
624 }else if( c=='\r' ){
625 fputc('\\', out);
626 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000627 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000628 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000629 }else{
630 fputc(c, out);
631 }
632 }
633 fputc('"', out);
634}
635
636/*
drhc08a4f12000-06-15 16:49:48 +0000637** Output the given string with characters that are special to
638** HTML escaped.
639*/
640static void output_html_string(FILE *out, const char *z){
641 int i;
drhc3d6ba42014-01-13 20:38:35 +0000642 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000643 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000644 for(i=0; z[i]
645 && z[i]!='<'
646 && z[i]!='&'
647 && z[i]!='>'
648 && z[i]!='\"'
649 && z[i]!='\'';
650 i++){}
drhc08a4f12000-06-15 16:49:48 +0000651 if( i>0 ){
652 fprintf(out,"%.*s",i,z);
653 }
654 if( z[i]=='<' ){
655 fprintf(out,"&lt;");
656 }else if( z[i]=='&' ){
657 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000658 }else if( z[i]=='>' ){
659 fprintf(out,"&gt;");
660 }else if( z[i]=='\"' ){
661 fprintf(out,"&quot;");
662 }else if( z[i]=='\'' ){
663 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000664 }else{
665 break;
666 }
667 z += i + 1;
668 }
669}
670
671/*
drhc49f44e2006-10-26 18:15:42 +0000672** If a field contains any character identified by a 1 in the following
673** array, then the string must be quoted for CSV.
674*/
675static const char needCsvQuote[] = {
676 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
677 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
678 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
679 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,
684 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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};
693
694/*
mistachkindd11f2d2014-12-11 04:49:46 +0000695** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000696** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000697** the null value. Strings are quoted if necessary. The separator
698** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000699*/
drhdcd87a92014-08-18 13:45:42 +0000700static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000701 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000702 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000703 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000704 }else{
drhc49f44e2006-10-26 18:15:42 +0000705 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000706 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000707 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000708 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000709 || (z[i]==p->colSeparator[0] &&
710 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000711 i = 0;
712 break;
713 }
714 }
715 if( i==0 ){
716 putc('"', out);
717 for(i=0; z[i]; i++){
718 if( z[i]=='"' ) putc('"', out);
719 putc(z[i], out);
720 }
721 putc('"', out);
722 }else{
723 fprintf(out, "%s", z);
724 }
drh8e64d1c2004-10-07 00:32:39 +0000725 }
726 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000727 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000728 }
729}
730
danielk19774af00c62005-01-23 23:43:21 +0000731#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000732/*
drh4c504392000-10-16 22:06:40 +0000733** This routine runs when the user presses Ctrl-C
734*/
735static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000736 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000737 seenInterrupt++;
738 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000739 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000740}
danielk19774af00c62005-01-23 23:43:21 +0000741#endif
drh4c504392000-10-16 22:06:40 +0000742
743/*
shane626a6e42009-10-22 17:30:15 +0000744** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000745** invokes for each row of a query result.
746*/
drh4ace5362014-11-10 14:42:28 +0000747static int shell_callback(
748 void *pArg,
749 int nArg, /* Number of result columns */
750 char **azArg, /* Text of each result column */
751 char **azCol, /* Column names */
752 int *aiType /* Column types */
753){
drh75897232000-05-29 14:26:00 +0000754 int i;
drhdcd87a92014-08-18 13:45:42 +0000755 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000756
drh75897232000-05-29 14:26:00 +0000757 switch( p->mode ){
758 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000759 int w = 5;
drh6a535342001-10-19 16:44:56 +0000760 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000761 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000762 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000763 if( len>w ) w = len;
764 }
mistachkin636bf9f2014-07-19 20:15:16 +0000765 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000766 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000767 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000768 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000769 }
770 break;
771 }
danielk19770d78bae2008-01-03 07:09:48 +0000772 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000773 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000774 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000775 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000776 int w, n;
777 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000778 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000779 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000780 w = 0;
drh75897232000-05-29 14:26:00 +0000781 }
drh078b1fd2012-09-21 13:40:02 +0000782 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000783 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000784 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000785 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000786 if( w<n ) w = n;
787 }
788 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000789 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000790 }
791 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000792 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000793 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
794 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000795 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000796 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
797 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000798 }
drha0c66f52000-07-29 13:20:21 +0000799 }
800 }
801 if( p->showHeader ){
802 for(i=0; i<nArg; i++){
803 int w;
804 if( i<ArraySize(p->actualWidth) ){
805 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000806 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000807 }else{
808 w = 10;
809 }
810 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
811 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000812 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000813 }
drh75897232000-05-29 14:26:00 +0000814 }
815 }
drh6a535342001-10-19 16:44:56 +0000816 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000817 for(i=0; i<nArg; i++){
818 int w;
drha0c66f52000-07-29 13:20:21 +0000819 if( i<ArraySize(p->actualWidth) ){
820 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000821 }else{
822 w = 10;
823 }
dana98bf362013-11-13 18:35:01 +0000824 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000825 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000826 }
dana98bf362013-11-13 18:35:01 +0000827 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000828 if( p->iIndent<p->nIndent ){
829 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000830 }
danc4650bb2013-11-18 08:41:06 +0000831 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000832 }
drh078b1fd2012-09-21 13:40:02 +0000833 if( w<0 ){
834 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000835 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000836 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000837 }else{
838 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000839 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000840 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000841 }
drh75897232000-05-29 14:26:00 +0000842 }
843 break;
844 }
drhe3710332000-09-29 13:30:53 +0000845 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000846 case MODE_List: {
847 if( p->cnt++==0 && p->showHeader ){
848 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000849 fprintf(p->out,"%s%s",azCol[i],
850 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000851 }
852 }
drh6a535342001-10-19 16:44:56 +0000853 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000854 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000855 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000856 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000857 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000858 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000859 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000860 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000861 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000862 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000863 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000864 }
drh75897232000-05-29 14:26:00 +0000865 }
866 break;
867 }
drh1e5d0e92000-05-31 23:33:17 +0000868 case MODE_Html: {
869 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000870 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000871 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000872 fprintf(p->out,"<TH>");
873 output_html_string(p->out, azCol[i]);
874 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000875 }
mihailim57c591a2008-06-23 21:26:05 +0000876 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000877 }
drh6a535342001-10-19 16:44:56 +0000878 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000879 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000880 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000881 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000882 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000883 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000884 }
mihailim57c591a2008-06-23 21:26:05 +0000885 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000886 break;
887 }
drhfeac5f82004-08-01 00:10:45 +0000888 case MODE_Tcl: {
889 if( p->cnt++==0 && p->showHeader ){
890 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000891 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000892 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000893 }
mistachkin636bf9f2014-07-19 20:15:16 +0000894 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000895 }
896 if( azArg==0 ) break;
897 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000898 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000899 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000900 }
mistachkin636bf9f2014-07-19 20:15:16 +0000901 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000902 break;
903 }
drh8e64d1c2004-10-07 00:32:39 +0000904 case MODE_Csv: {
drh6976c212014-07-24 12:09:47 +0000905#if defined(WIN32) || defined(_WIN32)
906 fflush(p->out);
907 _setmode(_fileno(p->out), _O_BINARY);
908#endif
drh8e64d1c2004-10-07 00:32:39 +0000909 if( p->cnt++==0 && p->showHeader ){
910 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000911 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000912 }
mistachkine0d68852014-12-11 03:12:33 +0000913 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000914 }
drh40253262014-10-17 21:35:05 +0000915 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000916 for(i=0; i<nArg; i++){
917 output_csv(p, azArg[i], i<nArg-1);
918 }
mistachkine0d68852014-12-11 03:12:33 +0000919 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000920 }
drh6976c212014-07-24 12:09:47 +0000921#if defined(WIN32) || defined(_WIN32)
922 fflush(p->out);
923 _setmode(_fileno(p->out), _O_TEXT);
924#endif
drh8e64d1c2004-10-07 00:32:39 +0000925 break;
926 }
drh28bd4bc2000-06-15 15:57:22 +0000927 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000928 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000929 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000930 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000931 for(i=0; i<nArg; i++){
932 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000933 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000934 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000935 }else if( aiType && aiType[i]==SQLITE_TEXT ){
936 if( zSep[0] ) fprintf(p->out,"%s",zSep);
937 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +0000938 }else if( aiType && (aiType[i]==SQLITE_INTEGER
939 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +0000940 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000941 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
942 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
943 int nBlob = sqlite3_column_bytes(p->pStmt, i);
944 if( zSep[0] ) fprintf(p->out,"%s",zSep);
945 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000946 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000947 fprintf(p->out,"%s%s",zSep, azArg[i]);
948 }else{
949 if( zSep[0] ) fprintf(p->out,"%s",zSep);
950 output_quoted_string(p->out, azArg[i]);
951 }
952 }
953 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000954 break;
drh28bd4bc2000-06-15 15:57:22 +0000955 }
mistachkin636bf9f2014-07-19 20:15:16 +0000956 case MODE_Ascii: {
957 if( p->cnt++==0 && p->showHeader ){
958 for(i=0; i<nArg; i++){
959 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
960 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
961 }
962 fprintf(p->out, "%s", p->rowSeparator);
963 }
964 if( azArg==0 ) break;
965 for(i=0; i<nArg; i++){
966 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +0000967 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000968 }
969 fprintf(p->out, "%s", p->rowSeparator);
970 break;
971 }
persicom1d0b8722002-04-18 02:53:04 +0000972 }
drh75897232000-05-29 14:26:00 +0000973 return 0;
974}
975
976/*
shane626a6e42009-10-22 17:30:15 +0000977** This is the callback routine that the SQLite library
978** invokes for each row of a query result.
979*/
980static int callback(void *pArg, int nArg, char **azArg, char **azCol){
981 /* since we don't have type info, call the shell_callback with a NULL value */
982 return shell_callback(pArg, nArg, azArg, azCol, NULL);
983}
984
985/*
drhdcd87a92014-08-18 13:45:42 +0000986** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +0000987** the name of the table given. Escape any quote characters in the
988** table name.
989*/
drhdcd87a92014-08-18 13:45:42 +0000990static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +0000991 int i, n;
992 int needQuote;
993 char *z;
994
995 if( p->zDestTable ){
996 free(p->zDestTable);
997 p->zDestTable = 0;
998 }
999 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001000 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001001 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001002 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001003 needQuote = 1;
1004 if( zName[i]=='\'' ) n++;
1005 }
1006 }
1007 if( needQuote ) n += 2;
1008 z = p->zDestTable = malloc( n+1 );
1009 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001010 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001011 exit(1);
1012 }
1013 n = 0;
1014 if( needQuote ) z[n++] = '\'';
1015 for(i=0; zName[i]; i++){
1016 z[n++] = zName[i];
1017 if( zName[i]=='\'' ) z[n++] = '\'';
1018 }
1019 if( needQuote ) z[n++] = '\'';
1020 z[n] = 0;
1021}
1022
danielk19772a02e332004-06-05 08:04:36 +00001023/* zIn is either a pointer to a NULL-terminated string in memory obtained
1024** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1025** added to zIn, and the result returned in memory obtained from malloc().
1026** zIn, if it was not NULL, is freed.
1027**
1028** If the third argument, quote, is not '\0', then it is used as a
1029** quote character for zAppend.
1030*/
drhc28490c2006-10-26 14:25:58 +00001031static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001032 int len;
1033 int i;
drh4f21c4a2008-12-10 22:15:00 +00001034 int nAppend = strlen30(zAppend);
1035 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001036
1037 len = nAppend+nIn+1;
1038 if( quote ){
1039 len += 2;
1040 for(i=0; i<nAppend; i++){
1041 if( zAppend[i]==quote ) len++;
1042 }
1043 }
1044
1045 zIn = (char *)realloc(zIn, len);
1046 if( !zIn ){
1047 return 0;
1048 }
1049
1050 if( quote ){
1051 char *zCsr = &zIn[nIn];
1052 *zCsr++ = quote;
1053 for(i=0; i<nAppend; i++){
1054 *zCsr++ = zAppend[i];
1055 if( zAppend[i]==quote ) *zCsr++ = quote;
1056 }
1057 *zCsr++ = quote;
1058 *zCsr++ = '\0';
1059 assert( (zCsr-zIn)==len );
1060 }else{
1061 memcpy(&zIn[nIn], zAppend, nAppend);
1062 zIn[len-1] = '\0';
1063 }
1064
1065 return zIn;
1066}
1067
drhdd3d4592004-08-30 01:54:05 +00001068
1069/*
drhb21a8e42012-01-28 21:08:51 +00001070** Execute a query statement that will generate SQL output. Print
1071** the result columns, comma-separated, on a line and then add a
1072** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001073**
drhb21a8e42012-01-28 21:08:51 +00001074** If the number of columns is 1 and that column contains text "--"
1075** then write the semicolon on a separate line. That way, if a
1076** "--" comment occurs at the end of the statement, the comment
1077** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001078*/
drh157e29a2009-05-21 15:15:00 +00001079static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001080 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001081 const char *zSelect, /* SELECT statement to extract content */
1082 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001083){
drhdd3d4592004-08-30 01:54:05 +00001084 sqlite3_stmt *pSelect;
1085 int rc;
drhb21a8e42012-01-28 21:08:51 +00001086 int nResult;
1087 int i;
1088 const char *z;
drhc7181902014-02-27 15:04:13 +00001089 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001090 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001091 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001092 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001093 return rc;
1094 }
1095 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001096 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001097 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001098 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001099 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001100 zFirstRow = 0;
1101 }
drhb21a8e42012-01-28 21:08:51 +00001102 z = (const char*)sqlite3_column_text(pSelect, 0);
1103 fprintf(p->out, "%s", z);
1104 for(i=1; i<nResult; i++){
1105 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1106 }
1107 if( z==0 ) z = "";
1108 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1109 if( z[0] ){
1110 fprintf(p->out, "\n;\n");
1111 }else{
1112 fprintf(p->out, ";\n");
1113 }
drhdd3d4592004-08-30 01:54:05 +00001114 rc = sqlite3_step(pSelect);
1115 }
drh2f464a02011-10-13 00:41:49 +00001116 rc = sqlite3_finalize(pSelect);
1117 if( rc!=SQLITE_OK ){
1118 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001119 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001120 }
1121 return rc;
drhdd3d4592004-08-30 01:54:05 +00001122}
1123
shane626a6e42009-10-22 17:30:15 +00001124/*
1125** Allocate space and save off current error string.
1126*/
1127static char *save_err_msg(
1128 sqlite3 *db /* Database to query */
1129){
1130 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1131 char *zErrMsg = sqlite3_malloc(nErrMsg);
1132 if( zErrMsg ){
1133 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1134 }
1135 return zErrMsg;
1136}
1137
1138/*
shaneh642d8b82010-07-28 16:05:34 +00001139** Display memory stats.
1140*/
1141static int display_stats(
1142 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001143 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001144 int bReset /* True to reset the stats */
1145){
1146 int iCur;
1147 int iHiwtr;
1148
1149 if( pArg && pArg->out ){
1150
1151 iHiwtr = iCur = -1;
1152 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001153 fprintf(pArg->out,
1154 "Memory Used: %d (max %d) bytes\n",
1155 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001156 iHiwtr = iCur = -1;
1157 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001158 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1159 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001160 if( pArg->shellFlgs & SHFLG_Pagecache ){
1161 iHiwtr = iCur = -1;
1162 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001163 fprintf(pArg->out,
1164 "Number of Pcache Pages Used: %d (max %d) pages\n",
1165 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001166 }
shaneh642d8b82010-07-28 16:05:34 +00001167 iHiwtr = iCur = -1;
1168 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001169 fprintf(pArg->out,
1170 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1171 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001172 if( pArg->shellFlgs & SHFLG_Scratch ){
1173 iHiwtr = iCur = -1;
1174 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001175 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1176 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001177 }
shaneh642d8b82010-07-28 16:05:34 +00001178 iHiwtr = iCur = -1;
1179 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001180 fprintf(pArg->out,
1181 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1182 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001183 iHiwtr = iCur = -1;
1184 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001185 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1186 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001187 iHiwtr = iCur = -1;
1188 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001189 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1190 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001191 iHiwtr = iCur = -1;
1192 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001193 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1194 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001195#ifdef YYTRACKMAXSTACKDEPTH
1196 iHiwtr = iCur = -1;
1197 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001198 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1199 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001200#endif
1201 }
1202
1203 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001204 if( pArg->shellFlgs & SHFLG_Lookaside ){
1205 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001206 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1207 &iCur, &iHiwtr, bReset);
1208 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1209 iCur, iHiwtr);
1210 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1211 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001212 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001213 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1214 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001215 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001216 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1217 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001218 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1219 }
shaneh642d8b82010-07-28 16:05:34 +00001220 iHiwtr = iCur = -1;
1221 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001222 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1223 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001224 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1225 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1226 iHiwtr = iCur = -1;
1227 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1228 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001229 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001230 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1231 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1232 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001233 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001234 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001235 iHiwtr = iCur = -1;
1236 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001237 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001238 }
1239
1240 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001241 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1242 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001243 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1244 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1245 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001246 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001247 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001248 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1249 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001250 }
1251
1252 return 0;
1253}
1254
1255/*
dan8d1edb92014-11-05 09:07:28 +00001256** Display scan stats.
1257*/
1258static void display_scanstats(
1259 sqlite3 *db, /* Database to query */
1260 ShellState *pArg /* Pointer to ShellState */
1261){
1262#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001263 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001264 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001265 mx = 0;
1266 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001267 double rEstLoop = 1.0;
1268 for(i=n=0; 1; i++){
1269 sqlite3_stmt *p = pArg->pStmt;
1270 sqlite3_int64 nLoop, nVisit;
1271 double rEst;
1272 int iSid;
1273 const char *zExplain;
1274 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1275 break;
1276 }
1277 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001278 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001279 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001280 if( n==0 ){
1281 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001282 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001283 }
drh42f30bc2014-11-06 12:08:21 +00001284 n++;
1285 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1286 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1287 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1288 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1289 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001290 fprintf(pArg->out,
1291 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001292 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001293 );
dan8d1edb92014-11-05 09:07:28 +00001294 }
dan8d1edb92014-11-05 09:07:28 +00001295 }
dan8d1edb92014-11-05 09:07:28 +00001296 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001297#endif
dan8d1edb92014-11-05 09:07:28 +00001298}
1299
1300/*
dana98bf362013-11-13 18:35:01 +00001301** Parameter azArray points to a zero-terminated array of strings. zStr
1302** points to a single nul-terminated string. Return non-zero if zStr
1303** is equal, according to strcmp(), to any of the strings in the array.
1304** Otherwise, return zero.
1305*/
1306static int str_in_array(const char *zStr, const char **azArray){
1307 int i;
1308 for(i=0; azArray[i]; i++){
1309 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1310 }
1311 return 0;
1312}
1313
1314/*
1315** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001316** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001317** spaces each opcode should be indented before it is output.
1318**
1319** The indenting rules are:
1320**
1321** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1322** all opcodes that occur between the p2 jump destination and the opcode
1323** itself by 2 spaces.
1324**
drh01752bc2013-11-14 23:59:33 +00001325** * For each "Goto", if the jump destination is earlier in the program
1326** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001327** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001328** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001329** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001330** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001331*/
drhdcd87a92014-08-18 13:45:42 +00001332static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001333 const char *zSql; /* The text of the SQL statement */
1334 const char *z; /* Used to check if this is an EXPLAIN */
1335 int *abYield = 0; /* True if op is an OP_Yield */
1336 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001337 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001338
drh8ad0de32014-03-20 18:45:27 +00001339 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1340 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001341 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1342 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001343 const char *azGoto[] = { "Goto", 0 };
1344
1345 /* Try to figure out if this is really an EXPLAIN statement. If this
1346 ** cannot be verified, return early. */
1347 zSql = sqlite3_sql(pSql);
1348 if( zSql==0 ) return;
1349 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1350 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1351
1352 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1353 int i;
danc4650bb2013-11-18 08:41:06 +00001354 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001355 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001356
1357 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1358 ** p2 is an instruction address, set variable p2op to the index of that
1359 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1360 ** the current instruction is part of a sub-program generated by an
1361 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001362 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001363 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001364
1365 /* Grow the p->aiIndent array as required */
1366 if( iOp>=nAlloc ){
1367 nAlloc += 100;
1368 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1369 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1370 }
1371 abYield[iOp] = str_in_array(zOp, azYield);
1372 p->aiIndent[iOp] = 0;
1373 p->nIndent = iOp+1;
1374
1375 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001376 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001377 }
drhfe705102014-03-06 13:38:37 +00001378 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1379 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1380 ){
drhe73f0592014-01-21 22:25:45 +00001381 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001382 }
1383 }
1384
danc4650bb2013-11-18 08:41:06 +00001385 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001386 sqlite3_free(abYield);
1387 sqlite3_reset(pSql);
1388}
1389
1390/*
1391** Free the array allocated by explain_data_prepare().
1392*/
drhdcd87a92014-08-18 13:45:42 +00001393static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001394 sqlite3_free(p->aiIndent);
1395 p->aiIndent = 0;
1396 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001397 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001398}
1399
1400/*
shane626a6e42009-10-22 17:30:15 +00001401** Execute a statement or set of statements. Print
1402** any result rows/columns depending on the current mode
1403** set via the supplied callback.
1404**
1405** This is very similar to SQLite's built-in sqlite3_exec()
1406** function except it takes a slightly different callback
1407** and callback data argument.
1408*/
1409static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001410 sqlite3 *db, /* An open database */
1411 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001412 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001413 /* (not the same as sqlite3_exec) */
1414 ShellState *pArg, /* Pointer to ShellState */
1415 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001416){
dan4564ced2010-01-05 04:59:56 +00001417 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1418 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001419 int rc2;
dan4564ced2010-01-05 04:59:56 +00001420 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001421
1422 if( pzErrMsg ){
1423 *pzErrMsg = NULL;
1424 }
1425
shaneb9fc17d2009-10-22 21:23:35 +00001426 while( zSql[0] && (SQLITE_OK == rc) ){
1427 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1428 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001429 if( pzErrMsg ){
1430 *pzErrMsg = save_err_msg(db);
1431 }
1432 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001433 if( !pStmt ){
1434 /* this happens for a comment or white-space */
1435 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001436 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001437 continue;
1438 }
shane626a6e42009-10-22 17:30:15 +00001439
shaneh642d8b82010-07-28 16:05:34 +00001440 /* save off the prepared statment handle and reset row count */
1441 if( pArg ){
1442 pArg->pStmt = pStmt;
1443 pArg->cnt = 0;
1444 }
1445
shanehb7977c52010-01-18 18:17:10 +00001446 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001447 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001448 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001449 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001450 }
shanehb7977c52010-01-18 18:17:10 +00001451
drhefbf3b12014-02-28 20:47:24 +00001452 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1453 if( pArg && pArg->autoEQP ){
1454 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001455 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1456 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001457 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1458 if( rc==SQLITE_OK ){
1459 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1460 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1461 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1462 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1463 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1464 }
1465 }
1466 sqlite3_finalize(pExplain);
1467 sqlite3_free(zEQP);
1468 }
1469
dana98bf362013-11-13 18:35:01 +00001470 /* If the shell is currently in ".explain" mode, gather the extra
1471 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001472 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001473 explain_data_prepare(pArg, pStmt);
1474 }
1475
shaneb9fc17d2009-10-22 21:23:35 +00001476 /* perform the first step. this will tell us if we
1477 ** have a result set or not and how wide it is.
1478 */
1479 rc = sqlite3_step(pStmt);
1480 /* if we have a result set... */
1481 if( SQLITE_ROW == rc ){
1482 /* if we have a callback... */
1483 if( xCallback ){
1484 /* allocate space for col name ptr, value ptr, and type */
1485 int nCol = sqlite3_column_count(pStmt);
1486 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1487 if( !pData ){
1488 rc = SQLITE_NOMEM;
1489 }else{
1490 char **azCols = (char **)pData; /* Names of result columns */
1491 char **azVals = &azCols[nCol]; /* Results */
1492 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001493 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001494 assert(sizeof(int) <= sizeof(char *));
1495 /* save off ptrs to column names */
1496 for(i=0; i<nCol; i++){
1497 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1498 }
shaneb9fc17d2009-10-22 21:23:35 +00001499 do{
1500 /* extract the data and data types */
1501 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001502 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001503 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001504 azVals[i] = "";
1505 }else{
1506 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1507 }
shaneb9fc17d2009-10-22 21:23:35 +00001508 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1509 rc = SQLITE_NOMEM;
1510 break; /* from for */
1511 }
1512 } /* end for */
1513
1514 /* if data and types extracted successfully... */
1515 if( SQLITE_ROW == rc ){
1516 /* call the supplied callback with the result row data */
1517 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1518 rc = SQLITE_ABORT;
1519 }else{
1520 rc = sqlite3_step(pStmt);
1521 }
1522 }
1523 } while( SQLITE_ROW == rc );
1524 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001525 }
1526 }else{
1527 do{
1528 rc = sqlite3_step(pStmt);
1529 } while( rc == SQLITE_ROW );
1530 }
1531 }
1532
dana98bf362013-11-13 18:35:01 +00001533 explain_data_delete(pArg);
1534
shaneh642d8b82010-07-28 16:05:34 +00001535 /* print usage stats if stats on */
1536 if( pArg && pArg->statsOn ){
1537 display_stats(db, pArg, 0);
1538 }
1539
dan8d1edb92014-11-05 09:07:28 +00001540 /* print loop-counters if required */
1541 if( pArg && pArg->scanstatsOn ){
1542 display_scanstats(db, pArg);
1543 }
1544
dan4564ced2010-01-05 04:59:56 +00001545 /* Finalize the statement just executed. If this fails, save a
1546 ** copy of the error message. Otherwise, set zSql to point to the
1547 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001548 rc2 = sqlite3_finalize(pStmt);
1549 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001550 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001551 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001552 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001553 }else if( pzErrMsg ){
1554 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001555 }
shaneh642d8b82010-07-28 16:05:34 +00001556
1557 /* clear saved stmt handle */
1558 if( pArg ){
1559 pArg->pStmt = NULL;
1560 }
shane626a6e42009-10-22 17:30:15 +00001561 }
shaneb9fc17d2009-10-22 21:23:35 +00001562 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001563
1564 return rc;
1565}
1566
drhdd3d4592004-08-30 01:54:05 +00001567
drh33048c02001-10-01 14:29:22 +00001568/*
drh4c653a02000-06-07 01:27:47 +00001569** This is a different callback routine used for dumping the database.
1570** Each row received by this callback consists of a table name,
1571** the table type ("index" or "table") and SQL to create the table.
1572** This routine should print text sufficient to recreate the table.
1573*/
1574static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001575 int rc;
1576 const char *zTable;
1577 const char *zType;
1578 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001579 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001580 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001581
drh902b9ee2008-12-05 17:17:07 +00001582 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001583 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001584 zTable = azArg[0];
1585 zType = azArg[1];
1586 zSql = azArg[2];
1587
drh00b950d2005-09-11 02:03:03 +00001588 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001589 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001590 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001591 fprintf(p->out, "ANALYZE sqlite_master;\n");
1592 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1593 return 0;
drh45e29d82006-11-20 16:21:10 +00001594 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1595 char *zIns;
1596 if( !p->writableSchema ){
1597 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1598 p->writableSchema = 1;
1599 }
1600 zIns = sqlite3_mprintf(
1601 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1602 "VALUES('table','%q','%q',0,'%q');",
1603 zTable, zTable, zSql);
1604 fprintf(p->out, "%s\n", zIns);
1605 sqlite3_free(zIns);
1606 return 0;
drh00b950d2005-09-11 02:03:03 +00001607 }else{
1608 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001609 }
danielk19772a02e332004-06-05 08:04:36 +00001610
1611 if( strcmp(zType, "table")==0 ){
1612 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001613 char *zSelect = 0;
1614 char *zTableInfo = 0;
1615 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001616 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001617
1618 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1619 zTableInfo = appendText(zTableInfo, zTable, '"');
1620 zTableInfo = appendText(zTableInfo, ");", 0);
1621
drhc7181902014-02-27 15:04:13 +00001622 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001623 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001624 if( rc!=SQLITE_OK || !pTableInfo ){
1625 return 1;
1626 }
1627
1628 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001629 /* Always quote the table name, even if it appears to be pure ascii,
1630 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1631 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001632 if( zTmp ){
1633 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001634 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001635 }
1636 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1637 rc = sqlite3_step(pTableInfo);
1638 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001639 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001640 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001641 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001642 rc = sqlite3_step(pTableInfo);
1643 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001644 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001645 }else{
1646 zSelect = appendText(zSelect, ") ", 0);
1647 }
drh157e29a2009-05-21 15:15:00 +00001648 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001649 }
1650 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001651 if( rc!=SQLITE_OK || nRow==0 ){
1652 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001653 return 1;
1654 }
1655 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1656 zSelect = appendText(zSelect, zTable, '"');
1657
drh2f464a02011-10-13 00:41:49 +00001658 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001659 if( rc==SQLITE_CORRUPT ){
1660 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001661 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001662 }
drh85e72432012-04-11 11:38:53 +00001663 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001664 }
drh4c653a02000-06-07 01:27:47 +00001665 return 0;
1666}
1667
1668/*
drh45e29d82006-11-20 16:21:10 +00001669** Run zQuery. Use dump_callback() as the callback routine so that
1670** the contents of the query are output as SQL statements.
1671**
drhdd3d4592004-08-30 01:54:05 +00001672** If we get a SQLITE_CORRUPT error, rerun the query after appending
1673** "ORDER BY rowid DESC" to the end.
1674*/
1675static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001676 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001677 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001678){
1679 int rc;
drh2f464a02011-10-13 00:41:49 +00001680 char *zErr = 0;
1681 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001682 if( rc==SQLITE_CORRUPT ){
1683 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001684 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001685 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1686 if( zErr ){
1687 fprintf(p->out, "/****** %s ******/\n", zErr);
1688 sqlite3_free(zErr);
1689 zErr = 0;
1690 }
drhdd3d4592004-08-30 01:54:05 +00001691 zQ2 = malloc( len+100 );
1692 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001693 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001694 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1695 if( rc ){
1696 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1697 }else{
1698 rc = SQLITE_CORRUPT;
1699 }
1700 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001701 free(zQ2);
1702 }
1703 return rc;
1704}
1705
1706/*
drh75897232000-05-29 14:26:00 +00001707** Text of a help message
1708*/
persicom1d0b8722002-04-18 02:53:04 +00001709static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001710 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001711 ".bail on|off Stop after hitting an error. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001712 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001713 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001714 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001715 " If TABLE specified, only dump tables matching\n"
1716 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001717 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001718 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001719 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001720 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001721 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001722 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001723 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001724 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001725 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001726 ".indices ?TABLE? Show names of all indices\n"
1727 " If TABLE specified, only show indices for tables\n"
1728 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001729#ifdef SQLITE_ENABLE_IOTRACE
1730 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1731#endif
drh70df4fe2006-06-13 15:12:21 +00001732#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001733 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001734#endif
drh127f9d72010-02-23 01:47:00 +00001735 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001736 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001737 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001738 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001739 " column Left-aligned columns. (See .width)\n"
1740 " html HTML <table> code\n"
1741 " insert SQL insert statements for TABLE\n"
1742 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001743 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001744 " tabs Tab-separated values\n"
1745 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001746 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001747 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001748 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001749 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001750 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001751 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001752 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001753 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001754 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001755 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001756 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001757 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001758 " If TABLE specified, only show tables matching\n"
1759 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001760 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1761 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001762 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001763 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001764 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001765 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001766 ".tables ?TABLE? List names of tables\n"
1767 " If TABLE specified, only list tables matching\n"
1768 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001769 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001770 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001771 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001772 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001773 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001774 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001775;
1776
drhdaffd0e2001-04-11 14:28:42 +00001777/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001778static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001779/*
1780** Implementation of the "readfile(X)" SQL function. The entire content
1781** of the file named X is read and returned as a BLOB. NULL is returned
1782** if the file does not exist or is unreadable.
1783*/
1784static void readfileFunc(
1785 sqlite3_context *context,
1786 int argc,
1787 sqlite3_value **argv
1788){
1789 const char *zName;
1790 FILE *in;
1791 long nIn;
1792 void *pBuf;
1793
1794 zName = (const char*)sqlite3_value_text(argv[0]);
1795 if( zName==0 ) return;
1796 in = fopen(zName, "rb");
1797 if( in==0 ) return;
1798 fseek(in, 0, SEEK_END);
1799 nIn = ftell(in);
1800 rewind(in);
1801 pBuf = sqlite3_malloc( nIn );
1802 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1803 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1804 }else{
1805 sqlite3_free(pBuf);
1806 }
1807 fclose(in);
1808}
1809
1810/*
1811** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1812** is written into file X. The number of bytes written is returned. Or
1813** NULL is returned if something goes wrong, such as being unable to open
1814** file X for writing.
1815*/
1816static void writefileFunc(
1817 sqlite3_context *context,
1818 int argc,
1819 sqlite3_value **argv
1820){
1821 FILE *out;
1822 const char *z;
drhba5b0932014-07-24 12:39:59 +00001823 sqlite3_int64 rc;
1824 const char *zFile;
1825
1826 zFile = (const char*)sqlite3_value_text(argv[0]);
1827 if( zFile==0 ) return;
1828 out = fopen(zFile, "wb");
1829 if( out==0 ) return;
1830 z = (const char*)sqlite3_value_blob(argv[1]);
1831 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001832 rc = 0;
1833 }else{
drh490fe862014-08-11 14:21:32 +00001834 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001835 }
1836 fclose(out);
1837 sqlite3_result_int64(context, rc);
1838}
drhdaffd0e2001-04-11 14:28:42 +00001839
drh75897232000-05-29 14:26:00 +00001840/*
drh44c2eb12003-04-30 11:38:26 +00001841** Make sure the database is open. If it is not, then open it. If
1842** the database fails to open, print an error message and exit.
1843*/
drhdcd87a92014-08-18 13:45:42 +00001844static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001845 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001846 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001847 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001848 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001849 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1850 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1851 shellstaticFunc, 0, 0);
1852 }
1853 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001854 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001855 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001856 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001857 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001858 }
drhc2e87a32006-06-27 15:16:14 +00001859#ifndef SQLITE_OMIT_LOAD_EXTENSION
1860 sqlite3_enable_load_extension(p->db, 1);
1861#endif
drhba5b0932014-07-24 12:39:59 +00001862 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1863 readfileFunc, 0, 0);
1864 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1865 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001866 }
1867}
1868
1869/*
drhfeac5f82004-08-01 00:10:45 +00001870** Do C-language style dequoting.
1871**
1872** \t -> tab
1873** \n -> newline
1874** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001875** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001876** \NNN -> ascii character NNN in octal
1877** \\ -> backslash
1878*/
1879static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001880 int i, j;
1881 char c;
drhc2ce0be2014-05-29 12:36:14 +00001882 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001883 for(i=j=0; (c = z[i])!=0; i++, j++){
1884 if( c=='\\' ){
1885 c = z[++i];
1886 if( c=='n' ){
1887 c = '\n';
1888 }else if( c=='t' ){
1889 c = '\t';
1890 }else if( c=='r' ){
1891 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001892 }else if( c=='\\' ){
1893 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001894 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001895 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001896 if( z[i+1]>='0' && z[i+1]<='7' ){
1897 i++;
1898 c = (c<<3) + z[i] - '0';
1899 if( z[i+1]>='0' && z[i+1]<='7' ){
1900 i++;
1901 c = (c<<3) + z[i] - '0';
1902 }
1903 }
1904 }
1905 }
1906 z[j] = c;
1907 }
drhc2ce0be2014-05-29 12:36:14 +00001908 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001909}
1910
1911/*
drh348d19c2013-06-03 12:47:43 +00001912** Return the value of a hexadecimal digit. Return -1 if the input
1913** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001914*/
drh348d19c2013-06-03 12:47:43 +00001915static int hexDigitValue(char c){
1916 if( c>='0' && c<='9' ) return c - '0';
1917 if( c>='a' && c<='f' ) return c - 'a' + 10;
1918 if( c>='A' && c<='F' ) return c - 'A' + 10;
1919 return -1;
drhc28490c2006-10-26 14:25:58 +00001920}
1921
1922/*
drh7d9f3942013-04-03 01:26:54 +00001923** Interpret zArg as an integer value, possibly with suffixes.
1924*/
1925static sqlite3_int64 integerValue(const char *zArg){
1926 sqlite3_int64 v = 0;
1927 static const struct { char *zSuffix; int iMult; } aMult[] = {
1928 { "KiB", 1024 },
1929 { "MiB", 1024*1024 },
1930 { "GiB", 1024*1024*1024 },
1931 { "KB", 1000 },
1932 { "MB", 1000000 },
1933 { "GB", 1000000000 },
1934 { "K", 1000 },
1935 { "M", 1000000 },
1936 { "G", 1000000000 },
1937 };
1938 int i;
1939 int isNeg = 0;
1940 if( zArg[0]=='-' ){
1941 isNeg = 1;
1942 zArg++;
1943 }else if( zArg[0]=='+' ){
1944 zArg++;
1945 }
drh348d19c2013-06-03 12:47:43 +00001946 if( zArg[0]=='0' && zArg[1]=='x' ){
1947 int x;
1948 zArg += 2;
1949 while( (x = hexDigitValue(zArg[0]))>=0 ){
1950 v = (v<<4) + x;
1951 zArg++;
1952 }
1953 }else{
1954 while( IsDigit(zArg[0]) ){
1955 v = v*10 + zArg[0] - '0';
1956 zArg++;
1957 }
drh7d9f3942013-04-03 01:26:54 +00001958 }
drhc2bed0a2013-05-24 11:57:50 +00001959 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001960 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1961 v *= aMult[i].iMult;
1962 break;
1963 }
1964 }
1965 return isNeg? -v : v;
1966}
1967
1968/*
drh348d19c2013-06-03 12:47:43 +00001969** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1970** for TRUE and FALSE. Return the integer value if appropriate.
1971*/
1972static int booleanValue(char *zArg){
1973 int i;
1974 if( zArg[0]=='0' && zArg[1]=='x' ){
1975 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1976 }else{
1977 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1978 }
1979 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1980 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1981 return 1;
1982 }
1983 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1984 return 0;
1985 }
1986 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1987 zArg);
1988 return 0;
1989}
1990
1991/*
drh42f64e52012-04-04 16:56:23 +00001992** Close an output file, assuming it is not stderr or stdout
1993*/
1994static void output_file_close(FILE *f){
1995 if( f && f!=stdout && f!=stderr ) fclose(f);
1996}
1997
1998/*
1999** Try to open an output file. The names "stdout" and "stderr" are
2000** recognized and do the right thing. NULL is returned if the output
2001** filename is "off".
2002*/
2003static FILE *output_file_open(const char *zFile){
2004 FILE *f;
2005 if( strcmp(zFile,"stdout")==0 ){
2006 f = stdout;
2007 }else if( strcmp(zFile, "stderr")==0 ){
2008 f = stderr;
2009 }else if( strcmp(zFile, "off")==0 ){
2010 f = 0;
2011 }else{
2012 f = fopen(zFile, "wb");
2013 if( f==0 ){
2014 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2015 }
2016 }
2017 return f;
2018}
2019
2020/*
2021** A routine for handling output from sqlite3_trace().
2022*/
2023static void sql_trace_callback(void *pArg, const char *z){
2024 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002025 if( f ){
2026 int i = (int)strlen(z);
2027 while( i>0 && z[i-1]==';' ){ i--; }
2028 fprintf(f, "%.*s;\n", i, z);
2029 }
drh42f64e52012-04-04 16:56:23 +00002030}
2031
2032/*
drhd8621b92012-04-17 09:09:33 +00002033** A no-op routine that runs with the ".breakpoint" doc-command. This is
2034** a useful spot to set a debugger breakpoint.
2035*/
2036static void test_breakpoint(void){
2037 static int nCall = 0;
2038 nCall++;
2039}
2040
2041/*
mistachkin636bf9f2014-07-19 20:15:16 +00002042** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002043*/
mistachkin636bf9f2014-07-19 20:15:16 +00002044typedef struct ImportCtx ImportCtx;
2045struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002046 const char *zFile; /* Name of the input file */
2047 FILE *in; /* Read the CSV text from this input stream */
2048 char *z; /* Accumulated text for a field */
2049 int n; /* Number of bytes in z */
2050 int nAlloc; /* Space allocated for z[] */
2051 int nLine; /* Current line number */
2052 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002053 int cColSep; /* The column separator character. (Usually ",") */
2054 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002055};
2056
2057/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002058static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002059 if( p->n+1>=p->nAlloc ){
2060 p->nAlloc += p->nAlloc + 100;
2061 p->z = sqlite3_realloc(p->z, p->nAlloc);
2062 if( p->z==0 ){
2063 fprintf(stderr, "out of memory\n");
2064 exit(1);
2065 }
2066 }
2067 p->z[p->n++] = (char)c;
2068}
2069
2070/* Read a single field of CSV text. Compatible with rfc4180 and extended
2071** with the option of having a separator other than ",".
2072**
2073** + Input comes from p->in.
2074** + Store results in p->z of length p->n. Space to hold p->z comes
2075** from sqlite3_malloc().
mistachkin636bf9f2014-07-19 20:15:16 +00002076** + Use p->cSep as the column separator. The default is ",".
2077** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002078** + Keep track of the line number in p->nLine.
2079** + Store the character that terminates the field in p->cTerm. Store
2080** EOF on end-of-file.
2081** + Report syntax errors on stderr
2082*/
mistachkin636bf9f2014-07-19 20:15:16 +00002083static char *csv_read_one_field(ImportCtx *p){
2084 int c;
2085 int cSep = p->cColSep;
2086 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002087 p->n = 0;
2088 c = fgetc(p->in);
2089 if( c==EOF || seenInterrupt ){
2090 p->cTerm = EOF;
2091 return 0;
2092 }
2093 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002094 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002095 int startLine = p->nLine;
2096 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002097 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002098 while( 1 ){
2099 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002100 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002101 if( c==cQuote ){
2102 if( pc==cQuote ){
2103 pc = 0;
2104 continue;
2105 }
2106 }
2107 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002108 || (c==rSep && pc==cQuote)
2109 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002110 || (c==EOF && pc==cQuote)
2111 ){
2112 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002113 p->cTerm = c;
2114 break;
2115 }
2116 if( pc==cQuote && c!='\r' ){
2117 fprintf(stderr, "%s:%d: unescaped %c character\n",
2118 p->zFile, p->nLine, cQuote);
2119 }
2120 if( c==EOF ){
2121 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2122 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002123 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002124 break;
2125 }
mistachkin636bf9f2014-07-19 20:15:16 +00002126 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002127 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002128 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002129 }
drhdb95f682013-06-26 22:46:00 +00002130 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002131 while( c!=EOF && c!=cSep && c!=rSep ){
2132 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002133 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002134 }
mistachkin636bf9f2014-07-19 20:15:16 +00002135 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002136 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002137 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002138 }
drhdb95f682013-06-26 22:46:00 +00002139 p->cTerm = c;
2140 }
drh8dd675e2013-07-12 21:09:24 +00002141 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002142 return p->z;
2143}
2144
mistachkin636bf9f2014-07-19 20:15:16 +00002145/* Read a single field of ASCII delimited text.
2146**
2147** + Input comes from p->in.
2148** + Store results in p->z of length p->n. Space to hold p->z comes
2149** from sqlite3_malloc().
2150** + Use p->cSep as the column separator. The default is "\x1F".
2151** + Use p->rSep as the row separator. The default is "\x1E".
2152** + Keep track of the row number in p->nLine.
2153** + Store the character that terminates the field in p->cTerm. Store
2154** EOF on end-of-file.
2155** + Report syntax errors on stderr
2156*/
2157static char *ascii_read_one_field(ImportCtx *p){
2158 int c;
2159 int cSep = p->cColSep;
2160 int rSep = p->cRowSep;
2161 p->n = 0;
2162 c = fgetc(p->in);
2163 if( c==EOF || seenInterrupt ){
2164 p->cTerm = EOF;
2165 return 0;
2166 }
2167 while( c!=EOF && c!=cSep && c!=rSep ){
2168 import_append_char(p, c);
2169 c = fgetc(p->in);
2170 }
2171 if( c==rSep ){
2172 p->nLine++;
2173 }
2174 p->cTerm = c;
2175 if( p->z ) p->z[p->n] = 0;
2176 return p->z;
2177}
2178
drhdb95f682013-06-26 22:46:00 +00002179/*
drh4bbcf102014-02-06 02:46:08 +00002180** Try to transfer data for table zTable. If an error is seen while
2181** moving forward, try to go backwards. The backwards movement won't
2182** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002183*/
mistachkine31ae902014-02-06 01:15:29 +00002184static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002185 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002186 sqlite3 *newDb,
2187 const char *zTable
2188){
2189 sqlite3_stmt *pQuery = 0;
2190 sqlite3_stmt *pInsert = 0;
2191 char *zQuery = 0;
2192 char *zInsert = 0;
2193 int rc;
2194 int i, j, n;
2195 int nTable = (int)strlen(zTable);
2196 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002197 int cnt = 0;
2198 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002199
2200 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2201 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2202 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002203 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002204 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2205 zQuery);
2206 goto end_data_xfer;
2207 }
2208 n = sqlite3_column_count(pQuery);
2209 zInsert = sqlite3_malloc(200 + nTable + n*3);
2210 if( zInsert==0 ){
2211 fprintf(stderr, "out of memory\n");
2212 goto end_data_xfer;
2213 }
2214 sqlite3_snprintf(200+nTable,zInsert,
2215 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2216 i = (int)strlen(zInsert);
2217 for(j=1; j<n; j++){
2218 memcpy(zInsert+i, ",?", 2);
2219 i += 2;
2220 }
2221 memcpy(zInsert+i, ");", 3);
2222 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2223 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002224 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002225 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2226 zQuery);
2227 goto end_data_xfer;
2228 }
2229 for(k=0; k<2; k++){
2230 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2231 for(i=0; i<n; i++){
2232 switch( sqlite3_column_type(pQuery, i) ){
2233 case SQLITE_NULL: {
2234 sqlite3_bind_null(pInsert, i+1);
2235 break;
2236 }
2237 case SQLITE_INTEGER: {
2238 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2239 break;
2240 }
2241 case SQLITE_FLOAT: {
2242 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2243 break;
2244 }
2245 case SQLITE_TEXT: {
2246 sqlite3_bind_text(pInsert, i+1,
2247 (const char*)sqlite3_column_text(pQuery,i),
2248 -1, SQLITE_STATIC);
2249 break;
2250 }
2251 case SQLITE_BLOB: {
2252 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2253 sqlite3_column_bytes(pQuery,i),
2254 SQLITE_STATIC);
2255 break;
2256 }
2257 }
2258 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002259 rc = sqlite3_step(pInsert);
2260 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2261 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2262 sqlite3_errmsg(newDb));
2263 }
drh3350ce92014-02-06 00:49:12 +00002264 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002265 cnt++;
2266 if( (cnt%spinRate)==0 ){
2267 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2268 fflush(stdout);
2269 }
drh3350ce92014-02-06 00:49:12 +00002270 } /* End while */
2271 if( rc==SQLITE_DONE ) break;
2272 sqlite3_finalize(pQuery);
2273 sqlite3_free(zQuery);
2274 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2275 zTable);
2276 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2277 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002278 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2279 break;
drh3350ce92014-02-06 00:49:12 +00002280 }
2281 } /* End for(k=0...) */
2282
2283end_data_xfer:
2284 sqlite3_finalize(pQuery);
2285 sqlite3_finalize(pInsert);
2286 sqlite3_free(zQuery);
2287 sqlite3_free(zInsert);
2288}
2289
2290
2291/*
2292** Try to transfer all rows of the schema that match zWhere. For
2293** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002294** If an error is encountered while moving forward through the
2295** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002296*/
mistachkine31ae902014-02-06 01:15:29 +00002297static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002298 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002299 sqlite3 *newDb,
2300 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002301 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002302){
2303 sqlite3_stmt *pQuery = 0;
2304 char *zQuery = 0;
2305 int rc;
2306 const unsigned char *zName;
2307 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002308 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002309
2310 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2311 " WHERE %s", zWhere);
2312 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2313 if( rc ){
2314 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2315 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2316 zQuery);
2317 goto end_schema_xfer;
2318 }
2319 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2320 zName = sqlite3_column_text(pQuery, 0);
2321 zSql = sqlite3_column_text(pQuery, 1);
2322 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002323 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2324 if( zErrMsg ){
2325 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2326 sqlite3_free(zErrMsg);
2327 zErrMsg = 0;
2328 }
drh3350ce92014-02-06 00:49:12 +00002329 if( xForEach ){
2330 xForEach(p, newDb, (const char*)zName);
2331 }
2332 printf("done\n");
2333 }
2334 if( rc!=SQLITE_DONE ){
2335 sqlite3_finalize(pQuery);
2336 sqlite3_free(zQuery);
2337 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2338 " WHERE %s ORDER BY rowid DESC", zWhere);
2339 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2340 if( rc ){
2341 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2342 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2343 zQuery);
2344 goto end_schema_xfer;
2345 }
2346 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2347 zName = sqlite3_column_text(pQuery, 0);
2348 zSql = sqlite3_column_text(pQuery, 1);
2349 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002350 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2351 if( zErrMsg ){
2352 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2353 sqlite3_free(zErrMsg);
2354 zErrMsg = 0;
2355 }
drh3350ce92014-02-06 00:49:12 +00002356 if( xForEach ){
2357 xForEach(p, newDb, (const char*)zName);
2358 }
2359 printf("done\n");
2360 }
2361 }
2362end_schema_xfer:
2363 sqlite3_finalize(pQuery);
2364 sqlite3_free(zQuery);
2365}
2366
2367/*
2368** Open a new database file named "zNewDb". Try to recover as much information
2369** as possible out of the main database (which might be corrupt) and write it
2370** into zNewDb.
2371*/
drhdcd87a92014-08-18 13:45:42 +00002372static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002373 int rc;
2374 sqlite3 *newDb = 0;
2375 if( access(zNewDb,0)==0 ){
2376 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2377 return;
2378 }
2379 rc = sqlite3_open(zNewDb, &newDb);
2380 if( rc ){
2381 fprintf(stderr, "Cannot create output database: %s\n",
2382 sqlite3_errmsg(newDb));
2383 }else{
drh54d0d2d2014-04-03 00:32:13 +00002384 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002385 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002386 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2387 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002388 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002389 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002390 }
2391 sqlite3_close(newDb);
2392}
2393
2394/*
drhc2ce0be2014-05-29 12:36:14 +00002395** Change the output file back to stdout
2396*/
drhdcd87a92014-08-18 13:45:42 +00002397static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002398 if( p->outfile[0]=='|' ){
2399 pclose(p->out);
2400 }else{
2401 output_file_close(p->out);
2402 }
2403 p->outfile[0] = 0;
2404 p->out = stdout;
2405}
2406
2407/*
drh75897232000-05-29 14:26:00 +00002408** If an input line begins with "." then invoke this routine to
2409** process that line.
drh67505e72002-04-19 12:34:06 +00002410**
drh47ad6842006-11-08 12:25:42 +00002411** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002412*/
drhdcd87a92014-08-18 13:45:42 +00002413static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002414 int i = 1;
2415 int nArg = 0;
2416 int n, c;
drh67505e72002-04-19 12:34:06 +00002417 int rc = 0;
drh75897232000-05-29 14:26:00 +00002418 char *azArg[50];
2419
2420 /* Parse the input line into tokens.
2421 */
2422 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002423 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002424 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002425 if( zLine[i]=='\'' || zLine[i]=='"' ){
2426 int delim = zLine[i++];
2427 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002428 while( zLine[i] && zLine[i]!=delim ){
2429 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2430 i++;
2431 }
drh75897232000-05-29 14:26:00 +00002432 if( zLine[i]==delim ){
2433 zLine[i++] = 0;
2434 }
drhfeac5f82004-08-01 00:10:45 +00002435 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002436 }else{
2437 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002438 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002439 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002440 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002441 }
2442 }
2443
2444 /* Process the input line.
2445 */
shane9bd1b442009-10-23 01:27:39 +00002446 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002447 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002448 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002449 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2450 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2451 ){
drhbc46f022013-01-23 18:53:23 +00002452 const char *zDestFile = 0;
2453 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002454 sqlite3 *pDest;
2455 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002456 int j;
2457 for(j=1; j<nArg; j++){
2458 const char *z = azArg[j];
2459 if( z[0]=='-' ){
2460 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002461 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002462 {
2463 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2464 return 1;
2465 }
2466 }else if( zDestFile==0 ){
2467 zDestFile = azArg[j];
2468 }else if( zDb==0 ){
2469 zDb = zDestFile;
2470 zDestFile = azArg[j];
2471 }else{
2472 fprintf(stderr, "too many arguments to .backup\n");
2473 return 1;
2474 }
drh9ff849f2009-02-04 20:55:57 +00002475 }
drhbc46f022013-01-23 18:53:23 +00002476 if( zDestFile==0 ){
2477 fprintf(stderr, "missing FILENAME argument on .backup\n");
2478 return 1;
2479 }
2480 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002481 rc = sqlite3_open(zDestFile, &pDest);
2482 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002483 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002484 sqlite3_close(pDest);
2485 return 1;
2486 }
drh05782482013-10-24 15:20:20 +00002487 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002488 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2489 if( pBackup==0 ){
2490 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2491 sqlite3_close(pDest);
2492 return 1;
2493 }
2494 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2495 sqlite3_backup_finish(pBackup);
2496 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002497 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002498 }else{
2499 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002500 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002501 }
2502 sqlite3_close(pDest);
2503 }else
2504
drhc2ce0be2014-05-29 12:36:14 +00002505 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2506 if( nArg==2 ){
2507 bail_on_error = booleanValue(azArg[1]);
2508 }else{
2509 fprintf(stderr, "Usage: .bail on|off\n");
2510 rc = 1;
2511 }
drhc49f44e2006-10-26 18:15:42 +00002512 }else
2513
drhd8621b92012-04-17 09:09:33 +00002514 /* The undocumented ".breakpoint" command causes a call to the no-op
2515 ** routine named test_breakpoint().
2516 */
2517 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2518 test_breakpoint();
2519 }else
2520
drhc2ce0be2014-05-29 12:36:14 +00002521 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2522 if( nArg==2 ){
2523 tryToClone(p, azArg[1]);
2524 }else{
2525 fprintf(stderr, "Usage: .clone FILENAME\n");
2526 rc = 1;
2527 }
mistachkine31ae902014-02-06 01:15:29 +00002528 }else
2529
drhc2ce0be2014-05-29 12:36:14 +00002530 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002531 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002532 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002533 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002534 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002535 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002536 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002537 data.colWidth[0] = 3;
2538 data.colWidth[1] = 15;
2539 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002540 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002541 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002542 if( zErrMsg ){
2543 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002544 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002545 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002546 }
2547 }else
2548
drhc2ce0be2014-05-29 12:36:14 +00002549 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002550 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002551 /* When playing back a "dump", the content might appear in an order
2552 ** which causes immediate foreign key constraints to be violated.
2553 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002554 if( nArg!=1 && nArg!=2 ){
2555 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2556 rc = 1;
2557 goto meta_command_exit;
2558 }
drhf1dfc4f2009-09-23 15:51:35 +00002559 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002560 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002561 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002562 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002563 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002564 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002565 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002566 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002567 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002568 );
2569 run_schema_dump_query(p,
2570 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002571 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002572 );
drh2f464a02011-10-13 00:41:49 +00002573 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002574 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002575 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002576 );
drh4c653a02000-06-07 01:27:47 +00002577 }else{
2578 int i;
drhdd3d4592004-08-30 01:54:05 +00002579 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002580 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002581 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002582 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002583 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002584 " AND sql NOT NULL");
2585 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002586 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002587 "WHERE sql NOT NULL"
2588 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002589 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002590 );
danielk1977bc6ada42004-06-30 08:20:16 +00002591 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002592 }
2593 }
drh45e29d82006-11-20 16:21:10 +00002594 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002595 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002596 p->writableSchema = 0;
2597 }
drh56197952011-10-13 16:30:13 +00002598 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2599 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002600 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002601 }else
drh75897232000-05-29 14:26:00 +00002602
drhc2ce0be2014-05-29 12:36:14 +00002603 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2604 if( nArg==2 ){
2605 p->echoOn = booleanValue(azArg[1]);
2606 }else{
2607 fprintf(stderr, "Usage: .echo on|off\n");
2608 rc = 1;
2609 }
drhdaffd0e2001-04-11 14:28:42 +00002610 }else
2611
drhc2ce0be2014-05-29 12:36:14 +00002612 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2613 if( nArg==2 ){
2614 p->autoEQP = booleanValue(azArg[1]);
2615 }else{
2616 fprintf(stderr, "Usage: .eqp on|off\n");
2617 rc = 1;
2618 }
drhefbf3b12014-02-28 20:47:24 +00002619 }else
2620
drhd3ac7d92013-01-25 18:33:43 +00002621 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002622 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002623 rc = 2;
drh75897232000-05-29 14:26:00 +00002624 }else
2625
drhc2ce0be2014-05-29 12:36:14 +00002626 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002627 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002628 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002629 if(!p->normalMode.valid) {
2630 p->normalMode.valid = 1;
2631 p->normalMode.mode = p->mode;
2632 p->normalMode.showHeader = p->showHeader;
2633 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002634 }
2635 /* We could put this code under the !p->explainValid
2636 ** condition so that it does not execute if we are already in
2637 ** explain mode. However, always executing it allows us an easy
2638 ** was to reset to explain mode in case the user previously
2639 ** did an .explain followed by a .width, .mode or .header
2640 ** command.
2641 */
danielk19770d78bae2008-01-03 07:09:48 +00002642 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002643 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002644 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002645 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002646 p->colWidth[1] = 13; /* opcode */
2647 p->colWidth[2] = 4; /* P1 */
2648 p->colWidth[3] = 4; /* P2 */
2649 p->colWidth[4] = 4; /* P3 */
2650 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002651 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002652 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002653 }else if (p->normalMode.valid) {
2654 p->normalMode.valid = 0;
2655 p->mode = p->normalMode.mode;
2656 p->showHeader = p->normalMode.showHeader;
2657 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002658 }
drh75897232000-05-29 14:26:00 +00002659 }else
2660
drhc1971542014-06-23 23:28:13 +00002661 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002662 ShellState data;
drhc1971542014-06-23 23:28:13 +00002663 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002664 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002665 if( nArg!=1 ){
2666 fprintf(stderr, "Usage: .fullschema\n");
2667 rc = 1;
2668 goto meta_command_exit;
2669 }
2670 open_db(p, 0);
2671 memcpy(&data, p, sizeof(data));
2672 data.showHeader = 0;
2673 data.mode = MODE_Semi;
2674 rc = sqlite3_exec(p->db,
2675 "SELECT sql FROM"
2676 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2677 " FROM sqlite_master UNION ALL"
2678 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002679 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002680 "ORDER BY rowid",
2681 callback, &data, &zErrMsg
2682 );
drh56f674c2014-07-18 14:43:29 +00002683 if( rc==SQLITE_OK ){
2684 sqlite3_stmt *pStmt;
2685 rc = sqlite3_prepare_v2(p->db,
2686 "SELECT rowid FROM sqlite_master"
2687 " WHERE name GLOB 'sqlite_stat[134]'",
2688 -1, &pStmt, 0);
2689 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2690 sqlite3_finalize(pStmt);
2691 }
2692 if( doStats==0 ){
2693 fprintf(p->out, "/* No STAT tables available */\n");
2694 }else{
2695 fprintf(p->out, "ANALYZE sqlite_master;\n");
2696 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2697 callback, &data, &zErrMsg);
2698 data.mode = MODE_Insert;
2699 data.zDestTable = "sqlite_stat1";
2700 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2701 shell_callback, &data,&zErrMsg);
2702 data.zDestTable = "sqlite_stat3";
2703 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2704 shell_callback, &data,&zErrMsg);
2705 data.zDestTable = "sqlite_stat4";
2706 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2707 shell_callback, &data, &zErrMsg);
2708 fprintf(p->out, "ANALYZE sqlite_master;\n");
2709 }
drhc1971542014-06-23 23:28:13 +00002710 }else
2711
drhc2ce0be2014-05-29 12:36:14 +00002712 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2713 if( nArg==2 ){
2714 p->showHeader = booleanValue(azArg[1]);
2715 }else{
2716 fprintf(stderr, "Usage: .headers on|off\n");
2717 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002718 }
drh75897232000-05-29 14:26:00 +00002719 }else
2720
drhc2ce0be2014-05-29 12:36:14 +00002721 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2722 fprintf(p->out, "%s", zHelp);
2723 }else
2724
2725 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002726 char *zTable; /* Insert data into this table */
2727 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002728 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002729 int nCol; /* Number of columns in the table */
2730 int nByte; /* Number of bytes in an SQL string */
2731 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002732 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002733 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002734 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002735 ImportCtx sCtx; /* Reader context */
mistachkin486fd432014-07-24 22:20:23 +00002736 char *(*xRead)(ImportCtx*); /* Procedure to read one value */
drh5bde8162013-06-27 14:07:53 +00002737 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002738
drhc2ce0be2014-05-29 12:36:14 +00002739 if( nArg!=3 ){
2740 fprintf(stderr, "Usage: .import FILE TABLE\n");
2741 goto meta_command_exit;
2742 }
drh01f37542014-05-31 15:43:33 +00002743 zFile = azArg[1];
2744 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002745 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002746 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002747 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002748 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002749 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002750 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002751 return 1;
drhfeac5f82004-08-01 00:10:45 +00002752 }
drhdb95f682013-06-26 22:46:00 +00002753 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002754 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002755 " for import\n");
2756 return 1;
2757 }
mistachkin636bf9f2014-07-19 20:15:16 +00002758 nSep = strlen30(p->rowSeparator);
2759 if( nSep==0 ){
2760 fprintf(stderr, "Error: non-null row separator required for import\n");
2761 return 1;
2762 }
mistachkine0d68852014-12-11 03:12:33 +00002763 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2764 /* When importing CSV (only), if the row separator is set to the
2765 ** default output row separator, change it to the default input
2766 ** row separator. This avoids having to maintain different input
2767 ** and output row separators. */
2768 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2769 nSep = strlen30(p->rowSeparator);
2770 }
mistachkin636bf9f2014-07-19 20:15:16 +00002771 if( nSep>1 ){
2772 fprintf(stderr, "Error: multi-character row separators not allowed"
2773 " for import\n");
2774 return 1;
2775 }
2776 sCtx.zFile = zFile;
2777 sCtx.nLine = 1;
2778 if( sCtx.zFile[0]=='|' ){
2779 sCtx.in = popen(sCtx.zFile+1, "r");
2780 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00002781 xCloser = pclose;
2782 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002783 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00002784 xCloser = fclose;
2785 }
mistachkin636bf9f2014-07-19 20:15:16 +00002786 if( p->mode==MODE_Ascii ){
2787 xRead = ascii_read_one_field;
2788 }else{
2789 xRead = csv_read_one_field;
2790 }
2791 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002792 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002793 return 1;
2794 }
mistachkin636bf9f2014-07-19 20:15:16 +00002795 sCtx.cColSep = p->colSeparator[0];
2796 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00002797 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002798 if( zSql==0 ){
2799 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002800 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002801 return 1;
2802 }
drh4f21c4a2008-12-10 22:15:00 +00002803 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002804 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002805 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
drhdb95f682013-06-26 22:46:00 +00002806 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2807 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2808 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00002809 while( xRead(&sCtx) ){
2810 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00002811 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00002812 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00002813 }
drh5bde8162013-06-27 14:07:53 +00002814 if( cSep=='(' ){
2815 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00002816 sqlite3_free(sCtx.z);
2817 xCloser(sCtx.in);
2818 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00002819 return 1;
2820 }
drhdb95f682013-06-26 22:46:00 +00002821 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2822 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2823 sqlite3_free(zCreate);
2824 if( rc ){
2825 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2826 sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002827 sqlite3_free(sCtx.z);
2828 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00002829 return 1;
2830 }
drhc7181902014-02-27 15:04:13 +00002831 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002832 }
drhfeac5f82004-08-01 00:10:45 +00002833 sqlite3_free(zSql);
2834 if( rc ){
shane916f9612009-10-23 00:37:15 +00002835 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002836 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002837 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002838 return 1;
drhfeac5f82004-08-01 00:10:45 +00002839 }
shane916f9612009-10-23 00:37:15 +00002840 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002841 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002842 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002843 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002844 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002845 if( zSql==0 ){
2846 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002847 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002848 return 1;
2849 }
drhdb95f682013-06-26 22:46:00 +00002850 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002851 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002852 for(i=1; i<nCol; i++){
2853 zSql[j++] = ',';
2854 zSql[j++] = '?';
2855 }
2856 zSql[j++] = ')';
2857 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00002858 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002859 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002860 if( rc ){
2861 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002862 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00002863 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00002864 return 1;
drhfeac5f82004-08-01 00:10:45 +00002865 }
drh2d463112013-08-06 14:36:36 +00002866 needCommit = sqlite3_get_autocommit(db);
2867 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00002868 do{
mistachkin636bf9f2014-07-19 20:15:16 +00002869 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00002870 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00002871 char *z = xRead(&sCtx);
2872 /*
2873 ** Did we reach end-of-file before finding any columns?
2874 ** If so, stop instead of NULL filling the remaining columns.
2875 */
drhdb95f682013-06-26 22:46:00 +00002876 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00002877 /*
2878 ** Did we reach end-of-file OR end-of-line before finding any
2879 ** columns in ASCII mode? If so, stop instead of NULL filling
2880 ** the remaining columns.
2881 */
2882 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00002883 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00002884 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00002885 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2886 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00002887 sCtx.zFile, startLine, nCol, i+1);
drhdb95f682013-06-26 22:46:00 +00002888 i++;
mistachkin6fe03382014-06-16 22:45:28 +00002889 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002890 }
drhfeac5f82004-08-01 00:10:45 +00002891 }
mistachkin636bf9f2014-07-19 20:15:16 +00002892 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00002893 do{
mistachkin636bf9f2014-07-19 20:15:16 +00002894 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00002895 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00002896 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00002897 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2898 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00002899 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002900 }
drhdb95f682013-06-26 22:46:00 +00002901 if( i>=nCol ){
2902 sqlite3_step(pStmt);
2903 rc = sqlite3_reset(pStmt);
2904 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00002905 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
drhdb95f682013-06-26 22:46:00 +00002906 sqlite3_errmsg(db));
2907 }
2908 }
mistachkin636bf9f2014-07-19 20:15:16 +00002909 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00002910
mistachkin636bf9f2014-07-19 20:15:16 +00002911 xCloser(sCtx.in);
2912 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00002913 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00002914 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002915 }else
2916
drhc2ce0be2014-05-29 12:36:14 +00002917 if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002918 ShellState data;
drh75897232000-05-29 14:26:00 +00002919 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002920 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00002921 memcpy(&data, p, sizeof(data));
2922 data.showHeader = 0;
2923 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002924 if( nArg==1 ){
2925 rc = sqlite3_exec(p->db,
2926 "SELECT name FROM sqlite_master "
2927 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2928 "UNION ALL "
2929 "SELECT name FROM sqlite_temp_master "
2930 "WHERE type='index' "
2931 "ORDER BY 1",
2932 callback, &data, &zErrMsg
2933 );
drhc2ce0be2014-05-29 12:36:14 +00002934 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00002935 zShellStatic = azArg[1];
2936 rc = sqlite3_exec(p->db,
2937 "SELECT name FROM sqlite_master "
2938 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2939 "UNION ALL "
2940 "SELECT name FROM sqlite_temp_master "
2941 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2942 "ORDER BY 1",
2943 callback, &data, &zErrMsg
2944 );
2945 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00002946 }else{
2947 fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
2948 rc = 1;
2949 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00002950 }
drh75897232000-05-29 14:26:00 +00002951 if( zErrMsg ){
2952 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002953 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002954 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002955 }else if( rc != SQLITE_OK ){
2956 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2957 rc = 1;
drh75897232000-05-29 14:26:00 +00002958 }
2959 }else
2960
drhae5e4452007-05-03 17:18:36 +00002961#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002962 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002963 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002964 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2965 iotrace = 0;
2966 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002967 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002968 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002969 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002970 iotrace = stdout;
2971 }else{
2972 iotrace = fopen(azArg[1], "w");
2973 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002974 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002975 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002976 rc = 1;
drhb0603412007-02-28 04:47:26 +00002977 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002978 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002979 }
2980 }
2981 }else
drhae5e4452007-05-03 17:18:36 +00002982#endif
drhb0603412007-02-28 04:47:26 +00002983
drh70df4fe2006-06-13 15:12:21 +00002984#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00002985 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00002986 const char *zFile, *zProc;
2987 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00002988 if( nArg<2 ){
2989 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
2990 rc = 1;
2991 goto meta_command_exit;
2992 }
drh1e397f82006-06-08 15:28:43 +00002993 zFile = azArg[1];
2994 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00002995 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00002996 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2997 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002998 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002999 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003000 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003001 }
3002 }else
drh70df4fe2006-06-13 15:12:21 +00003003#endif
drh1e397f82006-06-08 15:28:43 +00003004
drhc2ce0be2014-05-29 12:36:14 +00003005 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3006 if( nArg!=2 ){
3007 fprintf(stderr, "Usage: .log FILENAME\n");
3008 rc = 1;
3009 }else{
3010 const char *zFile = azArg[1];
3011 output_file_close(p->pLog);
3012 p->pLog = output_file_open(zFile);
3013 }
drh127f9d72010-02-23 01:47:00 +00003014 }else
3015
drhc2ce0be2014-05-29 12:36:14 +00003016 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3017 const char *zMode = nArg>=2 ? azArg[1] : "";
3018 int n2 = (int)strlen(zMode);
3019 int c2 = zMode[0];
3020 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003021 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003022 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003023 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003024 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003025 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003026 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003027 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003028 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003029 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003030 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003031 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003032 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003033 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003034 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003035 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003036 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003037 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003038 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003039 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003040 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003041 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3042 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003043 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3044 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003045 }else {
shane9bd1b442009-10-23 01:27:39 +00003046 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003047 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003048 rc = 1;
drh75897232000-05-29 14:26:00 +00003049 }
3050 }else
3051
drhc2ce0be2014-05-29 12:36:14 +00003052 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3053 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003054 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3055 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003056 }else{
3057 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003058 rc = 1;
3059 }
3060 }else
3061
drh05782482013-10-24 15:20:20 +00003062 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3063 sqlite3 *savedDb = p->db;
3064 const char *zSavedFilename = p->zDbFilename;
3065 char *zNewFilename = 0;
3066 p->db = 0;
3067 if( nArg>=2 ){
3068 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3069 }
3070 open_db(p, 1);
3071 if( p->db!=0 ){
3072 sqlite3_close(savedDb);
3073 sqlite3_free(p->zFreeOnClose);
3074 p->zFreeOnClose = zNewFilename;
3075 }else{
3076 sqlite3_free(zNewFilename);
3077 p->db = savedDb;
3078 p->zDbFilename = zSavedFilename;
3079 }
3080 }else
3081
drhc2ce0be2014-05-29 12:36:14 +00003082 if( c=='o'
3083 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3084 ){
3085 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3086 if( nArg>2 ){
3087 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3088 rc = 1;
3089 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003090 }
drhc2ce0be2014-05-29 12:36:14 +00003091 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3092 if( nArg<2 ){
3093 fprintf(stderr, "Usage: .once FILE\n");
3094 rc = 1;
3095 goto meta_command_exit;
3096 }
3097 p->outCount = 2;
3098 }else{
3099 p->outCount = 0;
3100 }
3101 output_reset(p);
3102 if( zFile[0]=='|' ){
3103 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003104 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003105 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003106 p->out = stdout;
3107 rc = 1;
3108 }else{
drhc2ce0be2014-05-29 12:36:14 +00003109 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003110 }
drh75897232000-05-29 14:26:00 +00003111 }else{
drhc2ce0be2014-05-29 12:36:14 +00003112 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003113 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003114 if( strcmp(zFile,"off")!=0 ){
3115 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003116 }
drh75897232000-05-29 14:26:00 +00003117 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003118 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003119 } else {
drhc2ce0be2014-05-29 12:36:14 +00003120 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003121 }
3122 }
3123 }else
3124
drh078b1fd2012-09-21 13:40:02 +00003125 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3126 int i;
3127 for(i=1; i<nArg; i++){
3128 if( i>1 ) fprintf(p->out, " ");
3129 fprintf(p->out, "%s", azArg[i]);
3130 }
3131 fprintf(p->out, "\n");
3132 }else
3133
drhc2ce0be2014-05-29 12:36:14 +00003134 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003135 if( nArg >= 2) {
3136 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3137 }
3138 if( nArg >= 3) {
3139 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3140 }
3141 }else
3142
drhc2ce0be2014-05-29 12:36:14 +00003143 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003144 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003145 }else
3146
drhc2ce0be2014-05-29 12:36:14 +00003147 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3148 FILE *alt;
3149 if( nArg!=2 ){
3150 fprintf(stderr, "Usage: .read FILE\n");
3151 rc = 1;
3152 goto meta_command_exit;
3153 }
3154 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003155 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003156 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3157 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003158 }else{
shane9bd1b442009-10-23 01:27:39 +00003159 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003160 fclose(alt);
3161 }
3162 }else
3163
drhc2ce0be2014-05-29 12:36:14 +00003164 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003165 const char *zSrcFile;
3166 const char *zDb;
3167 sqlite3 *pSrc;
3168 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003169 int nTimeout = 0;
3170
drh9ff849f2009-02-04 20:55:57 +00003171 if( nArg==2 ){
3172 zSrcFile = azArg[1];
3173 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003174 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003175 zSrcFile = azArg[2];
3176 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003177 }else{
3178 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3179 rc = 1;
3180 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003181 }
3182 rc = sqlite3_open(zSrcFile, &pSrc);
3183 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003184 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003185 sqlite3_close(pSrc);
3186 return 1;
3187 }
drh05782482013-10-24 15:20:20 +00003188 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003189 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3190 if( pBackup==0 ){
3191 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3192 sqlite3_close(pSrc);
3193 return 1;
3194 }
drhdc2c4912009-02-04 22:46:47 +00003195 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3196 || rc==SQLITE_BUSY ){
3197 if( rc==SQLITE_BUSY ){
3198 if( nTimeout++ >= 3 ) break;
3199 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003200 }
3201 }
3202 sqlite3_backup_finish(pBackup);
3203 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003204 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003205 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003206 fprintf(stderr, "Error: source database is busy\n");
3207 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003208 }else{
3209 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003210 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003211 }
3212 sqlite3_close(pSrc);
3213 }else
3214
dan8d1edb92014-11-05 09:07:28 +00003215
3216 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3217 if( nArg==2 ){
3218 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003219#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3220 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3221#endif
dan8d1edb92014-11-05 09:07:28 +00003222 }else{
3223 fprintf(stderr, "Usage: .scanstats on|off\n");
3224 rc = 1;
3225 }
3226 }else
3227
drhc2ce0be2014-05-29 12:36:14 +00003228 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003229 ShellState data;
drh75897232000-05-29 14:26:00 +00003230 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003231 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003232 memcpy(&data, p, sizeof(data));
3233 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003234 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003235 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003236 int i;
drhf0693c82011-10-11 20:41:54 +00003237 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003238 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003239 char *new_argv[2], *new_colv[2];
3240 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3241 " type text,\n"
3242 " name text,\n"
3243 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003244 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003245 " sql text\n"
3246 ")";
3247 new_argv[1] = 0;
3248 new_colv[0] = "sql";
3249 new_colv[1] = 0;
3250 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003251 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003252 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003253 char *new_argv[2], *new_colv[2];
3254 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3255 " type text,\n"
3256 " name text,\n"
3257 " tbl_name text,\n"
3258 " rootpage integer,\n"
3259 " sql text\n"
3260 ")";
3261 new_argv[1] = 0;
3262 new_colv[0] = "sql";
3263 new_colv[1] = 0;
3264 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003265 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003266 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003267 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003268 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003269 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003270 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003271 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003272 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003273 "WHERE lower(tbl_name) LIKE shellstatic()"
3274 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003275 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003276 callback, &data, &zErrMsg);
3277 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003278 }
drhc2ce0be2014-05-29 12:36:14 +00003279 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003280 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003281 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003282 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003283 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003284 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003285 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003286 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003287 callback, &data, &zErrMsg
3288 );
drhc2ce0be2014-05-29 12:36:14 +00003289 }else{
3290 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3291 rc = 1;
3292 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003293 }
drh75897232000-05-29 14:26:00 +00003294 if( zErrMsg ){
3295 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003296 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003297 rc = 1;
3298 }else if( rc != SQLITE_OK ){
3299 fprintf(stderr,"Error: querying schema information\n");
3300 rc = 1;
3301 }else{
3302 rc = 0;
drh75897232000-05-29 14:26:00 +00003303 }
3304 }else
3305
drhabd4c722014-09-20 18:18:33 +00003306
3307#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3308 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3309 extern int sqlite3SelectTrace;
3310 sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
3311 }else
3312#endif
3313
3314
drh340f5822013-06-27 13:01:21 +00003315#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003316 /* Undocumented commands for internal testing. Subject to change
3317 ** without notice. */
3318 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3319 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3320 int i, v;
3321 for(i=1; i<nArg; i++){
3322 v = booleanValue(azArg[i]);
3323 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3324 }
3325 }
3326 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3327 int i; sqlite3_int64 v;
3328 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003329 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003330 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003331 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003332 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003333 }
3334 }
3335 }else
drh340f5822013-06-27 13:01:21 +00003336#endif
drh348d19c2013-06-03 12:47:43 +00003337
drhc2ce0be2014-05-29 12:36:14 +00003338 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003339 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003340 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003341 rc = 1;
3342 }
drh6976c212014-07-24 12:09:47 +00003343 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003344 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003345 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003346 }
3347 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003348 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3349 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003350 }
drh75897232000-05-29 14:26:00 +00003351 }else
3352
drh62cdde52014-05-28 20:22:28 +00003353 if( c=='s'
3354 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003355 ){
3356 char *zCmd;
drh54027102014-08-06 14:36:53 +00003357 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003358 if( nArg<2 ){
3359 fprintf(stderr, "Usage: .system COMMAND\n");
3360 rc = 1;
3361 goto meta_command_exit;
3362 }
drhdcb3e3d2014-05-29 03:17:29 +00003363 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003364 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003365 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3366 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003367 }
drh54027102014-08-06 14:36:53 +00003368 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003369 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003370 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003371 }else
3372
drhc2ce0be2014-05-29 12:36:14 +00003373 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003374 int i;
drhc2ce0be2014-05-29 12:36:14 +00003375 if( nArg!=1 ){
3376 fprintf(stderr, "Usage: .show\n");
3377 rc = 1;
3378 goto meta_command_exit;
3379 }
mistachkin636bf9f2014-07-19 20:15:16 +00003380 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3381 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003382 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003383 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3384 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3385 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003386 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003387 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003388 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003389 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003390 fprintf(p->out,"%12.12s: ", "colseparator");
3391 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003392 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003393 fprintf(p->out,"%12.12s: ", "rowseparator");
3394 output_c_string(p->out, p->rowSeparator);
3395 fprintf(p->out, "\n");
3396 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3397 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003398 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003399 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003400 }
drhfeac5f82004-08-01 00:10:45 +00003401 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003402 }else
3403
drhc2ce0be2014-05-29 12:36:14 +00003404 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3405 if( nArg==2 ){
3406 p->statsOn = booleanValue(azArg[1]);
3407 }else{
3408 fprintf(stderr, "Usage: .stats on|off\n");
3409 rc = 1;
3410 }
shaneh642d8b82010-07-28 16:05:34 +00003411 }else
3412
drhc2ce0be2014-05-29 12:36:14 +00003413 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003414 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003415 char **azResult;
drh98781232012-04-23 12:38:05 +00003416 int nRow, nAlloc;
3417 char *zSql = 0;
3418 int ii;
drh05782482013-10-24 15:20:20 +00003419 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003420 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3421 if( rc ) return rc;
3422 zSql = sqlite3_mprintf(
3423 "SELECT name FROM sqlite_master"
3424 " WHERE type IN ('table','view')"
3425 " AND name NOT LIKE 'sqlite_%%'"
3426 " AND name LIKE ?1");
3427 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3428 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3429 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3430 if( strcmp(zDbName,"temp")==0 ){
3431 zSql = sqlite3_mprintf(
3432 "%z UNION ALL "
3433 "SELECT 'temp.' || name FROM sqlite_temp_master"
3434 " WHERE type IN ('table','view')"
3435 " AND name NOT LIKE 'sqlite_%%'"
3436 " AND name LIKE ?1", zSql);
3437 }else{
3438 zSql = sqlite3_mprintf(
3439 "%z UNION ALL "
3440 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3441 " WHERE type IN ('table','view')"
3442 " AND name NOT LIKE 'sqlite_%%'"
3443 " AND name LIKE ?1", zSql, zDbName, zDbName);
3444 }
drha50da102000-08-08 20:19:09 +00003445 }
drh98781232012-04-23 12:38:05 +00003446 sqlite3_finalize(pStmt);
3447 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3448 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3449 sqlite3_free(zSql);
3450 if( rc ) return rc;
3451 nRow = nAlloc = 0;
3452 azResult = 0;
3453 if( nArg>1 ){
3454 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003455 }else{
drh98781232012-04-23 12:38:05 +00003456 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3457 }
3458 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3459 if( nRow>=nAlloc ){
3460 char **azNew;
3461 int n = nAlloc*2 + 10;
3462 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3463 if( azNew==0 ){
3464 fprintf(stderr, "Error: out of memory\n");
3465 break;
3466 }
3467 nAlloc = n;
3468 azResult = azNew;
3469 }
3470 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3471 if( azResult[nRow] ) nRow++;
3472 }
3473 sqlite3_finalize(pStmt);
3474 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003475 int len, maxlen = 0;
3476 int i, j;
3477 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003478 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003479 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003480 if( len>maxlen ) maxlen = len;
3481 }
3482 nPrintCol = 80/(maxlen+2);
3483 if( nPrintCol<1 ) nPrintCol = 1;
3484 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3485 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003486 for(j=i; j<nRow; j+=nPrintRow){
3487 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003488 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003489 }
drh151b7d52013-05-06 20:28:54 +00003490 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003491 }
3492 }
drh98781232012-04-23 12:38:05 +00003493 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3494 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003495 }else
3496
shaneh96887e12011-02-10 21:08:58 +00003497 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003498 static const struct {
3499 const char *zCtrlName; /* Name of a test-control option */
3500 int ctrlCode; /* Integer code for that option */
3501 } aCtrl[] = {
3502 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3503 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3504 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3505 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3506 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3507 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3508 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3509 { "assert", SQLITE_TESTCTRL_ASSERT },
3510 { "always", SQLITE_TESTCTRL_ALWAYS },
3511 { "reserve", SQLITE_TESTCTRL_RESERVE },
3512 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3513 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003514 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003515 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhd416fe72011-03-17 16:45:50 +00003516 };
shaneh96887e12011-02-10 21:08:58 +00003517 int testctrl = -1;
3518 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003519 int i, n;
drh05782482013-10-24 15:20:20 +00003520 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003521
drhd416fe72011-03-17 16:45:50 +00003522 /* convert testctrl text option to value. allow any unique prefix
3523 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003524 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003525 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003526 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3527 if( testctrl<0 ){
3528 testctrl = aCtrl[i].ctrlCode;
3529 }else{
drhb07028f2011-10-14 21:49:18 +00003530 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003531 testctrl = -1;
3532 break;
3533 }
3534 }
3535 }
drh348d19c2013-06-03 12:47:43 +00003536 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003537 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3538 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3539 }else{
3540 switch(testctrl){
3541
3542 /* sqlite3_test_control(int, db, int) */
3543 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3544 case SQLITE_TESTCTRL_RESERVE:
3545 if( nArg==3 ){
3546 int opt = (int)strtol(azArg[2], 0, 0);
3547 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003548 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003549 } else {
drhd416fe72011-03-17 16:45:50 +00003550 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3551 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003552 }
3553 break;
3554
3555 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003556 case SQLITE_TESTCTRL_PRNG_SAVE:
3557 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003558 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003559 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003560 if( nArg==2 ){
3561 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003562 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003563 } else {
3564 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3565 }
3566 break;
3567
3568 /* sqlite3_test_control(int, uint) */
3569 case SQLITE_TESTCTRL_PENDING_BYTE:
3570 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003571 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003572 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003573 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003574 } else {
drhd416fe72011-03-17 16:45:50 +00003575 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3576 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003577 }
3578 break;
3579
3580 /* sqlite3_test_control(int, int) */
3581 case SQLITE_TESTCTRL_ASSERT:
3582 case SQLITE_TESTCTRL_ALWAYS:
3583 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003584 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003585 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003586 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003587 } else {
drhd416fe72011-03-17 16:45:50 +00003588 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3589 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003590 }
3591 break;
3592
3593 /* sqlite3_test_control(int, char *) */
3594#ifdef SQLITE_N_KEYWORD
3595 case SQLITE_TESTCTRL_ISKEYWORD:
3596 if( nArg==3 ){
3597 const char *opt = azArg[2];
3598 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003599 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003600 } else {
drhd416fe72011-03-17 16:45:50 +00003601 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3602 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003603 }
3604 break;
3605#endif
3606
3607 case SQLITE_TESTCTRL_BITVEC_TEST:
3608 case SQLITE_TESTCTRL_FAULT_INSTALL:
3609 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3610 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3611 default:
drhd416fe72011-03-17 16:45:50 +00003612 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3613 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003614 break;
3615 }
3616 }
3617 }else
3618
drhc2ce0be2014-05-29 12:36:14 +00003619 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003620 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003621 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003622 }else
3623
drhc2ce0be2014-05-29 12:36:14 +00003624 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3625 if( nArg==2 ){
3626 enableTimer = booleanValue(azArg[1]);
3627 if( enableTimer && !HAS_TIMER ){
3628 fprintf(stderr, "Error: timer not available on this system.\n");
3629 enableTimer = 0;
3630 }
3631 }else{
3632 fprintf(stderr, "Usage: .timer on|off\n");
3633 rc = 1;
3634 }
shanehe2aa9d72009-11-06 17:20:17 +00003635 }else
3636
drhc2ce0be2014-05-29 12:36:14 +00003637 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003638 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00003639 output_file_close(p->traceOut);
drhc2ce0be2014-05-29 12:36:14 +00003640 if( nArg!=2 ){
3641 fprintf(stderr, "Usage: .trace FILE|off\n");
3642 rc = 1;
3643 goto meta_command_exit;
3644 }
drh42f64e52012-04-04 16:56:23 +00003645 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003646#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003647 if( p->traceOut==0 ){
3648 sqlite3_trace(p->db, 0, 0);
3649 }else{
3650 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3651 }
3652#endif
3653 }else
3654
drhf442e332014-09-10 19:01:14 +00003655#if SQLITE_USER_AUTHENTICATION
3656 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3657 if( nArg<2 ){
3658 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3659 rc = 1;
3660 goto meta_command_exit;
3661 }
drh7883ecf2014-09-11 16:19:31 +00003662 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003663 if( strcmp(azArg[1],"login")==0 ){
3664 if( nArg!=4 ){
3665 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3666 rc = 1;
3667 goto meta_command_exit;
3668 }
drhd39c40f2014-09-11 00:27:53 +00003669 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3670 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003671 if( rc ){
3672 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3673 rc = 1;
3674 }
3675 }else if( strcmp(azArg[1],"add")==0 ){
3676 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003677 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003678 rc = 1;
3679 goto meta_command_exit;
3680 }
drhd39c40f2014-09-11 00:27:53 +00003681 rc = sqlite3_user_add(p->db, azArg[2],
3682 azArg[3], (int)strlen(azArg[3]),
3683 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003684 if( rc ){
3685 fprintf(stderr, "User-Add failed: %d\n", rc);
3686 rc = 1;
3687 }
3688 }else if( strcmp(azArg[1],"edit")==0 ){
3689 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003690 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003691 rc = 1;
3692 goto meta_command_exit;
3693 }
drhd39c40f2014-09-11 00:27:53 +00003694 rc = sqlite3_user_change(p->db, azArg[2],
3695 azArg[3], (int)strlen(azArg[3]),
3696 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003697 if( rc ){
3698 fprintf(stderr, "User-Edit failed: %d\n", rc);
3699 rc = 1;
3700 }
3701 }else if( strcmp(azArg[1],"delete")==0 ){
3702 if( nArg!=3 ){
3703 fprintf(stderr, "Usage: .user delete USER\n");
3704 rc = 1;
3705 goto meta_command_exit;
3706 }
3707 rc = sqlite3_user_delete(p->db, azArg[2]);
3708 if( rc ){
3709 fprintf(stderr, "User-Delete failed: %d\n", rc);
3710 rc = 1;
3711 }
3712 }else{
3713 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
3714 rc = 1;
3715 goto meta_command_exit;
3716 }
3717 }else
3718#endif /* SQLITE_USER_AUTHENTICATION */
3719
drh9fd301b2011-06-03 13:28:22 +00003720 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003721 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003722 sqlite3_libversion(), sqlite3_sourceid());
3723 }else
3724
drhde60fc22011-12-14 17:53:36 +00003725 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3726 const char *zDbName = nArg==2 ? azArg[1] : "main";
3727 char *zVfsName = 0;
3728 if( p->db ){
3729 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3730 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003731 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003732 sqlite3_free(zVfsName);
3733 }
3734 }
3735 }else
3736
drhcef4fc82012-09-21 22:50:45 +00003737#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3738 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3739 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003740 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003741 }else
3742#endif
3743
drhc2ce0be2014-05-29 12:36:14 +00003744 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003745 int j;
drh43617e92006-03-06 20:55:46 +00003746 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003747 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003748 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003749 }
3750 }else
3751
3752 {
shane9bd1b442009-10-23 01:27:39 +00003753 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003754 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003755 rc = 1;
drh75897232000-05-29 14:26:00 +00003756 }
drh67505e72002-04-19 12:34:06 +00003757
drhc2ce0be2014-05-29 12:36:14 +00003758meta_command_exit:
3759 if( p->outCount ){
3760 p->outCount--;
3761 if( p->outCount==0 ) output_reset(p);
3762 }
drh67505e72002-04-19 12:34:06 +00003763 return rc;
drh75897232000-05-29 14:26:00 +00003764}
3765
drh67505e72002-04-19 12:34:06 +00003766/*
drh91a66392007-09-07 01:12:32 +00003767** Return TRUE if a semicolon occurs anywhere in the first N characters
3768** of string z[].
drh324ccef2003-02-05 14:06:20 +00003769*/
drh9f099fd2013-08-06 14:01:46 +00003770static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00003771 int i;
3772 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3773 return 0;
drh324ccef2003-02-05 14:06:20 +00003774}
3775
3776/*
drh70c7a4b2003-04-26 03:03:06 +00003777** Test to see if a line consists entirely of whitespace.
3778*/
3779static int _all_whitespace(const char *z){
3780 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00003781 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003782 if( *z=='/' && z[1]=='*' ){
3783 z += 2;
3784 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3785 if( *z==0 ) return 0;
3786 z++;
3787 continue;
3788 }
3789 if( *z=='-' && z[1]=='-' ){
3790 z += 2;
3791 while( *z && *z!='\n' ){ z++; }
3792 if( *z==0 ) return 1;
3793 continue;
3794 }
3795 return 0;
3796 }
3797 return 1;
3798}
3799
3800/*
drha9b17162003-04-29 18:01:28 +00003801** Return TRUE if the line typed in is an SQL command terminator other
3802** than a semi-colon. The SQL Server style "go" command is understood
3803** as is the Oracle "/".
3804*/
drh9f099fd2013-08-06 14:01:46 +00003805static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00003806 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00003807 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3808 return 1; /* Oracle */
3809 }
drhf0693c82011-10-11 20:41:54 +00003810 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00003811 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00003812 return 1; /* SQL Server */
3813 }
3814 return 0;
3815}
3816
3817/*
drh233a5312008-12-18 22:25:13 +00003818** Return true if zSql is a complete SQL statement. Return false if it
3819** ends in the middle of a string literal or C-style comment.
3820*/
drh9f099fd2013-08-06 14:01:46 +00003821static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00003822 int rc;
3823 if( zSql==0 ) return 1;
3824 zSql[nSql] = ';';
3825 zSql[nSql+1] = 0;
3826 rc = sqlite3_complete(zSql);
3827 zSql[nSql] = 0;
3828 return rc;
3829}
3830
3831/*
drh67505e72002-04-19 12:34:06 +00003832** Read input from *in and process it. If *in==0 then input
3833** is interactive - the user is typing it it. Otherwise, input
3834** is coming from a file or device. A prompt is issued and history
3835** is saved only if input is interactive. An interrupt signal will
3836** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00003837**
3838** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00003839*/
drhdcd87a92014-08-18 13:45:42 +00003840static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00003841 char *zLine = 0; /* A single input line */
3842 char *zSql = 0; /* Accumulated SQL text */
3843 int nLine; /* Length of current line */
3844 int nSql = 0; /* Bytes of zSql[] used */
3845 int nAlloc = 0; /* Allocated zSql[] space */
3846 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
3847 char *zErrMsg; /* Error message returned */
3848 int rc; /* Error code */
3849 int errCnt = 0; /* Number of errors seen */
3850 int lineno = 0; /* Current line number */
3851 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00003852
3853 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
3854 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00003855 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00003856 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00003857 /* End of input */
3858 if( stdin_is_interactive ) printf("\n");
3859 break;
drhc49f44e2006-10-26 18:15:42 +00003860 }
drh67505e72002-04-19 12:34:06 +00003861 if( seenInterrupt ){
3862 if( in!=0 ) break;
3863 seenInterrupt = 0;
3864 }
drhc28490c2006-10-26 14:25:58 +00003865 lineno++;
drh849a9d92013-12-21 15:46:06 +00003866 if( nSql==0 && _all_whitespace(zLine) ){
3867 if( p->echoOn ) printf("%s\n", zLine);
3868 continue;
3869 }
drh2af0b2d2002-02-21 02:25:02 +00003870 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00003871 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00003872 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00003873 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00003874 break;
3875 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00003876 errCnt++;
3877 }
drhdaffd0e2001-04-11 14:28:42 +00003878 continue;
3879 }
drh9f099fd2013-08-06 14:01:46 +00003880 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00003881 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00003882 }
drh9f099fd2013-08-06 14:01:46 +00003883 nLine = strlen30(zLine);
3884 if( nSql+nLine+2>=nAlloc ){
3885 nAlloc = nSql+nLine+100;
3886 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00003887 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00003888 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00003889 exit(1);
3890 }
drhdaffd0e2001-04-11 14:28:42 +00003891 }
drh9f099fd2013-08-06 14:01:46 +00003892 nSqlPrior = nSql;
3893 if( nSql==0 ){
3894 int i;
3895 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00003896 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00003897 memcpy(zSql, zLine+i, nLine+1-i);
3898 startline = lineno;
3899 nSql = nLine-i;
3900 }else{
3901 zSql[nSql++] = '\n';
3902 memcpy(zSql+nSql, zLine, nLine+1);
3903 nSql += nLine;
3904 }
3905 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00003906 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00003907 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00003908 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00003909 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00003910 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00003911 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00003912 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00003913 char zPrefix[100];
3914 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00003915 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00003916 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00003917 }else{
shane9bd1b442009-10-23 01:27:39 +00003918 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00003919 }
drh7f953e22002-07-13 17:33:45 +00003920 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00003921 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003922 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00003923 zErrMsg = 0;
3924 }else{
shaned2bed1c2009-10-21 03:56:54 +00003925 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00003926 }
drhc49f44e2006-10-26 18:15:42 +00003927 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00003928 }
drhdaffd0e2001-04-11 14:28:42 +00003929 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00003930 if( p->outCount ){
3931 output_reset(p);
3932 p->outCount = 0;
3933 }
drh9f099fd2013-08-06 14:01:46 +00003934 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00003935 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00003936 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00003937 }
3938 }
drh9f099fd2013-08-06 14:01:46 +00003939 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00003940 if( !_all_whitespace(zSql) ){
3941 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00003942 errCnt++;
drhd416fe72011-03-17 16:45:50 +00003943 }
drhdaffd0e2001-04-11 14:28:42 +00003944 free(zSql);
3945 }
danielk19772ac27622007-07-03 05:31:16 +00003946 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00003947 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00003948}
3949
drh67505e72002-04-19 12:34:06 +00003950/*
3951** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00003952** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00003953*/
3954static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00003955 static char *home_dir = NULL;
3956 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00003957
drh4ace5362014-11-10 14:42:28 +00003958#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
3959 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00003960 {
3961 struct passwd *pwent;
3962 uid_t uid = getuid();
3963 if( (pwent=getpwuid(uid)) != NULL) {
3964 home_dir = pwent->pw_dir;
3965 }
drh67505e72002-04-19 12:34:06 +00003966 }
3967#endif
3968
chw65d3c132007-11-12 21:09:10 +00003969#if defined(_WIN32_WCE)
3970 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
3971 */
drh85e72432012-04-11 11:38:53 +00003972 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00003973#else
3974
drh83905c92012-06-21 13:00:37 +00003975#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00003976 if (!home_dir) {
3977 home_dir = getenv("USERPROFILE");
3978 }
3979#endif
3980
drh67505e72002-04-19 12:34:06 +00003981 if (!home_dir) {
3982 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00003983 }
3984
drh83905c92012-06-21 13:00:37 +00003985#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00003986 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00003987 char *zDrive, *zPath;
3988 int n;
3989 zDrive = getenv("HOMEDRIVE");
3990 zPath = getenv("HOMEPATH");
3991 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00003992 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00003993 home_dir = malloc( n );
3994 if( home_dir==0 ) return 0;
3995 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3996 return home_dir;
3997 }
3998 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00003999 }
4000#endif
4001
chw65d3c132007-11-12 21:09:10 +00004002#endif /* !_WIN32_WCE */
4003
drh67505e72002-04-19 12:34:06 +00004004 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004005 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004006 char *z = malloc( n );
4007 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004008 home_dir = z;
4009 }
drhe98d4fa2002-04-21 19:06:22 +00004010
drh67505e72002-04-19 12:34:06 +00004011 return home_dir;
4012}
4013
4014/*
4015** Read input from the file given by sqliterc_override. Or if that
4016** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004017**
4018** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004019*/
shane9bd1b442009-10-23 01:27:39 +00004020static int process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004021 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004022 const char *sqliterc_override /* Name of config file. NULL to use default */
4023){
persicom7e2dfdd2002-04-18 02:46:52 +00004024 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004025 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004026 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004027 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00004028 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004029
4030 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004031 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004032 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00004033#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00004034 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00004035#endif
shane9bd1b442009-10-23 01:27:39 +00004036 return 1;
drhe98d4fa2002-04-21 19:06:22 +00004037 }
drh2f3de322012-06-27 16:41:31 +00004038 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004039 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4040 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004041 }
drha1f9b5e2004-02-14 16:31:02 +00004042 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004043 if( in ){
drhc28490c2006-10-26 14:25:58 +00004044 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004045 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004046 }
shane9bd1b442009-10-23 01:27:39 +00004047 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004048 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004049 }
drh85e72432012-04-11 11:38:53 +00004050 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00004051 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00004052}
4053
drh67505e72002-04-19 12:34:06 +00004054/*
drhe1e38c42003-05-04 18:30:59 +00004055** Show available command line options
4056*/
4057static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004058 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004059 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004060 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004061 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004062 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004063 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004064 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004065 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004066 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004067#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4068 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4069#endif
drhcc3b4f82012-02-07 14:13:50 +00004070 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004071 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004072 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004073 " -line set output mode to 'line'\n"
4074 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004075 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004076 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004077#ifdef SQLITE_ENABLE_MULTIPLEX
4078 " -multiplex enable the multiplexor VFS\n"
4079#endif
mistachkine0d68852014-12-11 03:12:33 +00004080 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004081 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004082 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4083 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004084 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004085 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004086 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004087 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004088#ifdef SQLITE_ENABLE_VFSTRACE
4089 " -vfstrace enable tracing of all VFS calls\n"
4090#endif
drhe1e38c42003-05-04 18:30:59 +00004091;
4092static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004093 fprintf(stderr,
4094 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4095 "FILENAME is the name of an SQLite database. A new database is created\n"
4096 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004097 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004098 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004099 }else{
4100 fprintf(stderr, "Use the -help option for additional information\n");
4101 }
4102 exit(1);
4103}
4104
4105/*
drh67505e72002-04-19 12:34:06 +00004106** Initialize the state information in data
4107*/
drhdcd87a92014-08-18 13:45:42 +00004108static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004109 memset(data, 0, sizeof(*data));
4110 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004111 memcpy(data->colSeparator,SEP_Column, 2);
4112 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004113 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004114 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004115 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004116 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004117 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004118 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4119 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004120}
4121
drh98d312f2012-10-25 15:23:14 +00004122/*
drh5c7976f2014-02-10 19:59:27 +00004123** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004124*/
4125#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004126static void printBold(const char *zText){
4127 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4128 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4129 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4130 SetConsoleTextAttribute(out,
4131 FOREGROUND_RED|FOREGROUND_INTENSITY
4132 );
4133 printf("%s", zText);
4134 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004135}
4136#else
drh5c7976f2014-02-10 19:59:27 +00004137static void printBold(const char *zText){
4138 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004139}
4140#endif
4141
4142/*
drh98d312f2012-10-25 15:23:14 +00004143** Get the argument to an --option. Throw an error and die if no argument
4144** is available.
4145*/
4146static char *cmdline_option_value(int argc, char **argv, int i){
4147 if( i==argc ){
4148 fprintf(stderr, "%s: Error: missing argument to %s\n",
4149 argv[0], argv[argc-1]);
4150 exit(1);
4151 }
4152 return argv[i];
4153}
4154
drh75897232000-05-29 14:26:00 +00004155int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004156 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004157 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004158 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004159 int i;
drhc28490c2006-10-26 14:25:58 +00004160 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004161 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004162 int readStdin = 1;
4163 int nCmd = 0;
4164 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004165
drh69b30ab2014-02-27 15:11:52 +00004166#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004167 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4168 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4169 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4170 exit(1);
4171 }
drhc7181902014-02-27 15:04:13 +00004172#endif
drhdaffd0e2001-04-11 14:28:42 +00004173 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004174 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004175 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004176
drh44c2eb12003-04-30 11:38:26 +00004177 /* Make sure we have a valid signal handler early, before anything
4178 ** else is done.
4179 */
drh4c504392000-10-16 22:06:40 +00004180#ifdef SIGINT
4181 signal(SIGINT, interrupt_handler);
4182#endif
drh44c2eb12003-04-30 11:38:26 +00004183
drhac5649a2014-11-28 13:35:03 +00004184#ifdef SQLITE_SHELL_DBNAME_PROC
4185 {
4186 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4187 ** of a C-function that will provide the name of the database file. Use
4188 ** this compile-time option to embed this shell program in larger
4189 ** applications. */
4190 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4191 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4192 warnInmemoryDb = 0;
4193 }
4194#endif
4195
drh22fbcb82004-02-01 01:22:50 +00004196 /* Do an initial pass through the command-line argument to locate
4197 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004198 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004199 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004200 */
drh98d312f2012-10-25 15:23:14 +00004201 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004202 char *z;
drhc28490c2006-10-26 14:25:58 +00004203 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004204 if( z[0]!='-' ){
4205 if( data.zDbFilename==0 ){
4206 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004207 }else{
4208 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4209 ** mean that nothing is read from stdin */
4210 readStdin = 0;
4211 nCmd++;
4212 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4213 if( azCmd==0 ){
4214 fprintf(stderr, "out of memory\n");
4215 exit(1);
4216 }
4217 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004218 }
drh98d312f2012-10-25 15:23:14 +00004219 }
drhcc3b4f82012-02-07 14:13:50 +00004220 if( z[1]=='-' ) z++;
4221 if( strcmp(z,"-separator")==0
4222 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004223 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004224 || strcmp(z,"-cmd")==0
4225 ){
drh98d312f2012-10-25 15:23:14 +00004226 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004227 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004228 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004229 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004230 /* Need to check for batch mode here to so we can avoid printing
4231 ** informational messages (like from process_sqliterc) before
4232 ** we do the actual processing of arguments later in a second pass.
4233 */
shanef69573d2009-10-24 02:06:14 +00004234 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004235 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004236#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004237 const char *zSize;
4238 sqlite3_int64 szHeap;
4239
drh98d312f2012-10-25 15:23:14 +00004240 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004241 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004242 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004243 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4244#endif
drh44dec872014-08-30 15:49:25 +00004245 }else if( strcmp(z,"-scratch")==0 ){
4246 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004247 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004248 if( sz>400000 ) sz = 400000;
4249 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004250 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004251 if( n>10 ) n = 10;
4252 if( n<1 ) n = 1;
4253 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4254 data.shellFlgs |= SHFLG_Scratch;
4255 }else if( strcmp(z,"-pagecache")==0 ){
4256 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004257 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004258 if( sz>70000 ) sz = 70000;
4259 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004260 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004261 if( n<10 ) n = 10;
4262 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4263 data.shellFlgs |= SHFLG_Pagecache;
4264 }else if( strcmp(z,"-lookaside")==0 ){
4265 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004266 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004267 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004268 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004269 if( n<0 ) n = 0;
4270 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4271 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004272#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004273 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004274 extern int vfstrace_register(
4275 const char *zTraceName,
4276 const char *zOldVfsName,
4277 int (*xOut)(const char*,void*),
4278 void *pOutArg,
4279 int makeDefault
4280 );
drh2b625e22011-03-16 17:05:28 +00004281 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004282#endif
drh6f25e892011-07-08 17:02:57 +00004283#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004284 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004285 extern int sqlite3_multiple_initialize(const char*,int);
4286 sqlite3_multiplex_initialize(0, 1);
4287#endif
drh7d9f3942013-04-03 01:26:54 +00004288 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004289 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4290 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004291 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004292 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004293 if( pVfs ){
4294 sqlite3_vfs_register(pVfs, 1);
4295 }else{
4296 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4297 exit(1);
4298 }
drh44c2eb12003-04-30 11:38:26 +00004299 }
4300 }
drh98d312f2012-10-25 15:23:14 +00004301 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004302#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004303 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004304 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004305#else
shane86f5bdb2009-10-24 02:00:07 +00004306 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4307 return 1;
drh01b41712005-08-29 23:06:23 +00004308#endif
drh98d312f2012-10-25 15:23:14 +00004309 }
4310 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004311
drh44c2eb12003-04-30 11:38:26 +00004312 /* Go ahead and open the database file if it already exists. If the
4313 ** file does not exist, delay opening it. This prevents empty database
4314 ** files from being created if a user mistypes the database name argument
4315 ** to the sqlite command-line tool.
4316 */
drhc8d74412004-08-31 23:41:26 +00004317 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004318 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004319 }
4320
drh22fbcb82004-02-01 01:22:50 +00004321 /* Process the initialization file if there is one. If no -init option
4322 ** is given on the command line, look for a file named ~/.sqliterc and
4323 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004324 */
shane86f5bdb2009-10-24 02:00:07 +00004325 rc = process_sqliterc(&data,zInitFile);
4326 if( rc>0 ){
4327 return rc;
4328 }
drh44c2eb12003-04-30 11:38:26 +00004329
drh22fbcb82004-02-01 01:22:50 +00004330 /* Make a second pass through the command-line argument and set
4331 ** options. This second pass is delayed until after the initialization
4332 ** file is processed so that the command-line arguments will override
4333 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004334 */
drh98d312f2012-10-25 15:23:14 +00004335 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004336 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004337 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004338 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004339 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004340 i++;
4341 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004342 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004343 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004344 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004345 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004346 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004347 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004348 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004349 }else if( strcmp(z,"-csv")==0 ){
4350 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004351 memcpy(data.colSeparator,",",2);
4352 }else if( strcmp(z,"-ascii")==0 ){
4353 data.mode = MODE_Ascii;
4354 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004355 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004356 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004357 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004358 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004359 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4360 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004361 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004362 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004363 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004364 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004365 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004366 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004367 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004368 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004369 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004370 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004371 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004372 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004373 }else if( strcmp(z,"-eqp")==0 ){
4374 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004375 }else if( strcmp(z,"-stats")==0 ){
4376 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004377 }else if( strcmp(z,"-scanstats")==0 ){
4378 data.scanstatsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004379 }else if( strcmp(z,"-bail")==0 ){
4380 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004381 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004382 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004383 return 0;
drhc28490c2006-10-26 14:25:58 +00004384 }else if( strcmp(z,"-interactive")==0 ){
4385 stdin_is_interactive = 1;
4386 }else if( strcmp(z,"-batch")==0 ){
4387 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004388 }else if( strcmp(z,"-heap")==0 ){
4389 i++;
drh44dec872014-08-30 15:49:25 +00004390 }else if( strcmp(z,"-scratch")==0 ){
4391 i+=2;
4392 }else if( strcmp(z,"-pagecache")==0 ){
4393 i+=2;
4394 }else if( strcmp(z,"-lookaside")==0 ){
4395 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004396 }else if( strcmp(z,"-mmap")==0 ){
4397 i++;
drha7e61d82011-03-12 17:02:57 +00004398 }else if( strcmp(z,"-vfs")==0 ){
4399 i++;
drh6f25e892011-07-08 17:02:57 +00004400#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004401 }else if( strcmp(z,"-vfstrace")==0 ){
4402 i++;
drh6f25e892011-07-08 17:02:57 +00004403#endif
4404#ifdef SQLITE_ENABLE_MULTIPLEX
4405 }else if( strcmp(z,"-multiplex")==0 ){
4406 i++;
4407#endif
drhcc3b4f82012-02-07 14:13:50 +00004408 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004409 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004410 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004411 /* Run commands that follow -cmd first and separately from commands
4412 ** that simply appear on the command-line. This seems goofy. It would
4413 ** be better if all commands ran in the order that they appear. But
4414 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004415 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004416 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004417 if( z[0]=='.' ){
4418 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004419 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004420 }else{
drh05782482013-10-24 15:20:20 +00004421 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004422 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4423 if( zErrMsg!=0 ){
4424 fprintf(stderr,"Error: %s\n", zErrMsg);
4425 if( bail_on_error ) return rc!=0 ? rc : 1;
4426 }else if( rc!=0 ){
4427 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4428 if( bail_on_error ) return rc;
4429 }
4430 }
drh1e5d0e92000-05-31 23:33:17 +00004431 }else{
shane86f5bdb2009-10-24 02:00:07 +00004432 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004433 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004434 return 1;
4435 }
4436 }
drh44c2eb12003-04-30 11:38:26 +00004437
drhac5649a2014-11-28 13:35:03 +00004438 if( !readStdin ){
4439 /* Run all arguments that do not begin with '-' as if they were separate
4440 ** command-line inputs, except for the argToSkip argument which contains
4441 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004442 */
drhac5649a2014-11-28 13:35:03 +00004443 for(i=0; i<nCmd; i++){
4444 if( azCmd[i][0]=='.' ){
4445 rc = do_meta_command(azCmd[i], &data);
4446 if( rc ) return rc==2 ? 0 : rc;
4447 }else{
4448 open_db(&data, 0);
4449 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4450 if( zErrMsg!=0 ){
4451 fprintf(stderr,"Error: %s\n", zErrMsg);
4452 return rc!=0 ? rc : 1;
4453 }else if( rc!=0 ){
4454 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4455 return rc;
4456 }
drh6ff13852001-11-25 13:18:23 +00004457 }
drh75897232000-05-29 14:26:00 +00004458 }
drhac5649a2014-11-28 13:35:03 +00004459 free(azCmd);
drh75897232000-05-29 14:26:00 +00004460 }else{
drh44c2eb12003-04-30 11:38:26 +00004461 /* Run commands received from standard input
4462 */
drhc28490c2006-10-26 14:25:58 +00004463 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004464 char *zHome;
4465 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004466 int nHistory;
drh75897232000-05-29 14:26:00 +00004467 printf(
drh743e0032011-12-12 16:51:50 +00004468 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004469 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004470 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004471 );
drhb3735912014-02-10 16:13:42 +00004472 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004473 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004474 printBold("transient in-memory database");
4475 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004476 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004477 }
drh67505e72002-04-19 12:34:06 +00004478 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004479 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004480 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004481 if( (zHistory = malloc(nHistory))!=0 ){
4482 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4483 }
drh67505e72002-04-19 12:34:06 +00004484 }
drhaaa21b42014-02-11 14:37:51 +00004485#if defined(HAVE_READLINE)
drh67505e72002-04-19 12:34:06 +00004486 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00004487#endif
drhc28490c2006-10-26 14:25:58 +00004488 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004489 if( zHistory ){
4490 stifle_history(100);
4491 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004492 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004493 }
drhdaffd0e2001-04-11 14:28:42 +00004494 }else{
drhc28490c2006-10-26 14:25:58 +00004495 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004496 }
4497 }
drh33048c02001-10-01 14:29:22 +00004498 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004499 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004500 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004501 }
drh05782482013-10-24 15:20:20 +00004502 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004503 return rc;
drh75897232000-05-29 14:26:00 +00004504}