blob: e0d0b78b7d3ae1c3abff7c4679d999523a947d41 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh36f7dd32011-10-13 16:02:17 +000028** Enable large-file support for fopen() and friends on unix.
29*/
30#ifndef SQLITE_DISABLE_LFS
31# define _LARGE_FILE 1
32# ifndef _FILE_OFFSET_BITS
33# define _FILE_OFFSET_BITS 64
34# endif
35# define _LARGEFILE_SOURCE 1
36#endif
37
drh75897232000-05-29 14:26:00 +000038#include <stdlib.h>
39#include <string.h>
40#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000041#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000042#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000043#if SQLITE_USER_AUTHENTICATION
44# include "sqlite3userauth.h"
45#endif
drh75897232000-05-29 14:26:00 +000046#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000047#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000048
drh83905c92012-06-21 13:00:37 +000049#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000050# include <signal.h>
chw97185482008-11-17 08:05:31 +000051# if !defined(__RTP__) && !defined(_WRS_KERNEL)
52# include <pwd.h>
53# endif
drhdd45df82002-04-18 12:39:03 +000054# include <unistd.h>
55# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000056#endif
drh75897232000-05-29 14:26:00 +000057
drh0ede9eb2015-01-10 16:49:23 +000058#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000059# include <readline/readline.h>
60# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000061#endif
drh0ede9eb2015-01-10 16:49:23 +000062#if HAVE_EDITLINE
63# undef HAVE_READLINE
drhaaa21b42014-02-11 14:37:51 +000064# define HAVE_READLINE 1
65# include <editline/readline.h>
66#endif
drh0ede9eb2015-01-10 16:49:23 +000067#if !HAVE_READLINE
persicom1d0b8722002-04-18 02:53:04 +000068# define add_history(X)
drh67505e72002-04-19 12:34:06 +000069# define read_history(X)
70# define write_history(X)
71# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000072#endif
73
adamd2e8464a2006-09-06 21:39:40 +000074#if defined(_WIN32) || defined(WIN32)
75# include <io.h>
drh6976c212014-07-24 12:09:47 +000076# include <fcntl.h>
shane18e526c2008-12-10 22:30:24 +000077#define isatty(h) _isatty(h)
drh07901eb2014-02-28 19:37:45 +000078#ifndef access
79# define access(f,m) _access((f),(m))
80#endif
drh67ceaa62012-08-27 21:19:03 +000081#undef popen
drh53371f92013-07-25 17:07:03 +000082#define popen _popen
drh67ceaa62012-08-27 21:19:03 +000083#undef pclose
drh12cd6cf2013-06-29 15:40:22 +000084#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +000085#else
drh4328c8b2003-04-26 02:50:11 +000086/* Make sure isatty() has a prototype.
87*/
drhb2acc3b2011-10-13 16:36:29 +000088extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +000089
drh53371f92013-07-25 17:07:03 +000090/* popen and pclose are not C89 functions and so are sometimes omitted from
91** the <stdio.h> header */
mistachkinf6418892013-08-28 01:54:12 +000092extern FILE *popen(const char*,const char*);
93extern int pclose(FILE*);
94#endif
drh53371f92013-07-25 17:07:03 +000095
chw65d3c132007-11-12 21:09:10 +000096#if defined(_WIN32_WCE)
97/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
98 * thus we always assume that we have a console. That can be
99 * overridden with the -batch command line option.
100 */
101#define isatty(x) 1
102#endif
103
drhf0693c82011-10-11 20:41:54 +0000104/* ctype macros that work with signed characters */
105#define IsSpace(X) isspace((unsigned char)X)
106#define IsDigit(X) isdigit((unsigned char)X)
107#define ToLower(X) (char)tolower((unsigned char)X)
108
drh047d4532015-01-18 20:30:23 +0000109/* On Windows, we normally run with output mode of TEXT so that \n characters
110** are automatically translated into \r\n. However, this behavior needs
111** to be disabled in some cases (ex: when generating CSV output and when
112** rendering quoted strings that contain \n characters). The following
113** routines take care of that.
114*/
115#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000116static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000117 fflush(out);
118 _setmode(_fileno(out), _O_BINARY);
119}
mistachkine4a0d792015-01-27 21:24:33 +0000120static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000121 fflush(out);
122 _setmode(_fileno(out), _O_TEXT);
123}
124#else
125# define setBinaryMode(X)
126# define setTextMode(X)
127#endif
128
drh43408312013-10-30 12:43:36 +0000129
130/* True if the timer is enabled */
131static int enableTimer = 0;
132
133/* Return the current wall-clock time */
134static sqlite3_int64 timeOfDay(void){
135 static sqlite3_vfs *clockVfs = 0;
136 sqlite3_int64 t;
137 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
138 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
139 clockVfs->xCurrentTimeInt64(clockVfs, &t);
140 }else{
141 double r;
142 clockVfs->xCurrentTime(clockVfs, &r);
143 t = (sqlite3_int64)(r*86400000.0);
144 }
145 return t;
146}
147
drhd5d0f642013-02-20 00:54:21 +0000148#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
149 && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000150#include <sys/time.h>
151#include <sys/resource.h>
152
drhda108222009-02-25 19:07:24 +0000153/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000154static struct rusage sBegin; /* CPU time at start */
155static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000156
drhda108222009-02-25 19:07:24 +0000157/*
158** Begin timing an operation
159*/
160static void beginTimer(void){
161 if( enableTimer ){
162 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000163 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000164 }
165}
166
167/* Return the difference of two time_structs in seconds */
168static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
169 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
170 (double)(pEnd->tv_sec - pStart->tv_sec);
171}
172
173/*
174** Print the timing results.
175*/
176static void endTimer(void){
177 if( enableTimer ){
178 struct rusage sEnd;
drh43408312013-10-30 12:43:36 +0000179 sqlite3_int64 iEnd = timeOfDay();
drhda108222009-02-25 19:07:24 +0000180 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000181 printf("Run Time: real %.3f user %f sys %f\n",
182 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000183 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
184 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
185 }
186}
shaneb320ccd2009-10-21 03:42:58 +0000187
drhda108222009-02-25 19:07:24 +0000188#define BEGIN_TIMER beginTimer()
189#define END_TIMER endTimer()
190#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000191
192#elif (defined(_WIN32) || defined(WIN32))
193
194#include <windows.h>
195
196/* Saved resource information for the beginning of an operation */
197static HANDLE hProcess;
198static FILETIME ftKernelBegin;
199static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000200static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000201typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
202 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000203static GETPROCTIMES getProcessTimesAddr = NULL;
204
shaneb320ccd2009-10-21 03:42:58 +0000205/*
206** Check to see if we have timer support. Return 1 if necessary
207** support found (or found previously).
208*/
209static int hasTimer(void){
210 if( getProcessTimesAddr ){
211 return 1;
212 } else {
drh4ace5362014-11-10 14:42:28 +0000213 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
214 ** versions. See if the version we are running on has it, and if it
215 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000216 */
217 hProcess = GetCurrentProcess();
218 if( hProcess ){
219 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
220 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000221 getProcessTimesAddr =
222 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000223 if( NULL != getProcessTimesAddr ){
224 return 1;
225 }
226 FreeLibrary(hinstLib);
227 }
228 }
229 }
230 return 0;
231}
232
233/*
234** Begin timing an operation
235*/
236static void beginTimer(void){
237 if( enableTimer && getProcessTimesAddr ){
238 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000239 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
240 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000241 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000242 }
243}
244
245/* Return the difference of two FILETIME structs in seconds */
246static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
247 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
248 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
249 return (double) ((i64End - i64Start) / 10000000.0);
250}
251
252/*
253** Print the timing results.
254*/
255static void endTimer(void){
256 if( enableTimer && getProcessTimesAddr){
257 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000258 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000259 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000260 printf("Run Time: real %.3f user %f sys %f\n",
261 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000262 timeDiff(&ftUserBegin, &ftUserEnd),
263 timeDiff(&ftKernelBegin, &ftKernelEnd));
264 }
265}
266
267#define BEGIN_TIMER beginTimer()
268#define END_TIMER endTimer()
269#define HAS_TIMER hasTimer()
270
drhda108222009-02-25 19:07:24 +0000271#else
272#define BEGIN_TIMER
273#define END_TIMER
274#define HAS_TIMER 0
275#endif
276
shanec0688ea2009-03-05 03:48:06 +0000277/*
278** Used to prevent warnings about unused parameters
279*/
280#define UNUSED_PARAMETER(x) (void)(x)
281
drhe91d16b2008-12-08 18:27:31 +0000282/*
drhc49f44e2006-10-26 18:15:42 +0000283** If the following flag is set, then command execution stops
284** at an error if we are not interactive.
285*/
286static int bail_on_error = 0;
287
288/*
drhc28490c2006-10-26 14:25:58 +0000289** Threat stdin as an interactive input if the following variable
290** is true. Otherwise, assume stdin is connected to a file or pipe.
291*/
292static int stdin_is_interactive = 1;
293
294/*
drh4c504392000-10-16 22:06:40 +0000295** The following is the open SQLite database. We make a pointer
296** to this database a static variable so that it can be accessed
297** by the SIGINT handler to interrupt database processing.
298*/
danielk197792f9a1b2004-06-19 09:08:16 +0000299static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000300
301/*
drh67505e72002-04-19 12:34:06 +0000302** True if an interrupt (Control-C) has been received.
303*/
drh43617e92006-03-06 20:55:46 +0000304static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000305
306/*
persicom7e2dfdd2002-04-18 02:46:52 +0000307** This is the name of our program. It is set in main(), used
308** in a number of other places, mostly for error messages.
309*/
310static char *Argv0;
311
312/*
313** Prompt strings. Initialized in main. Settable with
314** .prompt main continue
315*/
316static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
317static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
318
drhb0603412007-02-28 04:47:26 +0000319/*
320** Write I/O traces to the following stream.
321*/
rsebe0a9092007-07-30 18:24:38 +0000322#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000323static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000324#endif
drhb0603412007-02-28 04:47:26 +0000325
326/*
327** This routine works like printf in that its first argument is a
328** format string and subsequent arguments are values to be substituted
329** in place of % fields. The result of formatting this string
330** is written to iotrace.
331*/
rsebe0a9092007-07-30 18:24:38 +0000332#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000333static void iotracePrintf(const char *zFormat, ...){
334 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000335 char *z;
drhb0603412007-02-28 04:47:26 +0000336 if( iotrace==0 ) return;
337 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000338 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000339 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000340 fprintf(iotrace, "%s", z);
341 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000342}
rsebe0a9092007-07-30 18:24:38 +0000343#endif
drhb0603412007-02-28 04:47:26 +0000344
drh44c2eb12003-04-30 11:38:26 +0000345
persicom7e2dfdd2002-04-18 02:46:52 +0000346/*
drh83965662003-04-17 02:54:13 +0000347** Determines if a string is a number of not.
348*/
danielk19772e588c72005-12-09 14:25:08 +0000349static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000350 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000351 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000352 return 0;
353 }
354 z++;
355 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000356 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000357 if( *z=='.' ){
358 z++;
drhf0693c82011-10-11 20:41:54 +0000359 if( !IsDigit(*z) ) return 0;
360 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000361 if( realnum ) *realnum = 1;
362 }
363 if( *z=='e' || *z=='E' ){
364 z++;
365 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000366 if( !IsDigit(*z) ) return 0;
367 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000368 if( realnum ) *realnum = 1;
369 }
370 return *z==0;
371}
drh83965662003-04-17 02:54:13 +0000372
373/*
danielk1977bc6ada42004-06-30 08:20:16 +0000374** A global char* and an SQL function to access its current value
375** from within an SQL statement. This program used to use the
376** sqlite_exec_printf() API to substitue a string into an SQL statement.
377** The correct way to do this with sqlite3 is to use the bind API, but
378** since the shell is built around the callback paradigm it would be a lot
379** of work. Instead just use this hack, which is quite harmless.
380*/
381static const char *zShellStatic = 0;
382static void shellstaticFunc(
383 sqlite3_context *context,
384 int argc,
385 sqlite3_value **argv
386){
387 assert( 0==argc );
388 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000389 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000390 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000391 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
392}
393
394
395/*
drhfeac5f82004-08-01 00:10:45 +0000396** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000397** the text in memory obtained from malloc() and returns a pointer
398** to the text. NULL is returned at end of file, or if malloc()
399** fails.
400**
drh9f099fd2013-08-06 14:01:46 +0000401** If zLine is not NULL then it is a malloced buffer returned from
402** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000403*/
drh9f099fd2013-08-06 14:01:46 +0000404static char *local_getline(char *zLine, FILE *in){
405 int nLine = zLine==0 ? 0 : 100;
406 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000407
drhb07028f2011-10-14 21:49:18 +0000408 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000409 if( n+100>nLine ){
410 nLine = nLine*2 + 100;
411 zLine = realloc(zLine, nLine);
412 if( zLine==0 ) return 0;
413 }
drhdaffd0e2001-04-11 14:28:42 +0000414 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000415 if( n==0 ){
416 free(zLine);
417 return 0;
418 }
419 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000420 break;
421 }
drh9f099fd2013-08-06 14:01:46 +0000422 while( zLine[n] ) n++;
423 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000424 n--;
shaneh13b36022009-12-17 21:07:15 +0000425 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000426 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000427 break;
drh8e7e7a22000-05-30 18:45:23 +0000428 }
429 }
drh8e7e7a22000-05-30 18:45:23 +0000430 return zLine;
431}
432
433/*
drhc28490c2006-10-26 14:25:58 +0000434** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000435**
drh9f099fd2013-08-06 14:01:46 +0000436** If in==0 then read from standard input and prompt before each line.
437** If isContinuation is true, then a continuation prompt is appropriate.
438** If isContinuation is zero, then the main prompt should be used.
439**
440** If zPrior is not NULL then it is a buffer from a prior call to this
441** routine that can be reused.
442**
443** The result is stored in space obtained from malloc() and must either
444** be freed by the caller or else passed back into this routine via the
445** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000446*/
drh9f099fd2013-08-06 14:01:46 +0000447static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000448 char *zPrompt;
449 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000450 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000451 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000452 }else{
drh9f099fd2013-08-06 14:01:46 +0000453 zPrompt = isContinuation ? continuePrompt : mainPrompt;
drh0ede9eb2015-01-10 16:49:23 +0000454#if HAVE_READLINE
drh9f099fd2013-08-06 14:01:46 +0000455 free(zPrior);
456 zResult = readline(zPrompt);
457 if( zResult && *zResult ) add_history(zResult);
458#else
459 printf("%s", zPrompt);
460 fflush(stdout);
461 zResult = local_getline(zPrior, stdin);
danielk19774af00c62005-01-23 23:43:21 +0000462#endif
drh9f099fd2013-08-06 14:01:46 +0000463 }
drh8e7e7a22000-05-30 18:45:23 +0000464 return zResult;
465}
466
drhdcd87a92014-08-18 13:45:42 +0000467/*
468** Shell output mode information from before ".explain on",
469** saved so that it can be restored by ".explain off"
470*/
471typedef struct SavedModeInfo SavedModeInfo;
472struct SavedModeInfo {
473 int valid; /* Is there legit data in here? */
474 int mode; /* Mode prior to ".explain on" */
475 int showHeader; /* The ".header" setting prior to ".explain on" */
476 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000477};
drh45e29d82006-11-20 16:21:10 +0000478
drh8e7e7a22000-05-30 18:45:23 +0000479/*
drhdcd87a92014-08-18 13:45:42 +0000480** State information about the database connection is contained in an
481** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000482*/
drhdcd87a92014-08-18 13:45:42 +0000483typedef struct ShellState ShellState;
484struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000485 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000486 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000487 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000488 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000489 int scanstatsOn; /* True to display scan stats before each finalize */
drhc2ce0be2014-05-29 12:36:14 +0000490 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000491 int cnt; /* Number of records displayed so far */
492 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000493 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000494 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000495 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000496 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000497 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000498 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000499 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000500 char colSeparator[20]; /* Column separator character for several modes */
501 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000502 int colWidth[100]; /* Requested width of each column when in column mode*/
503 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000504 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000505 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000506 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000507 char outfile[FILENAME_MAX]; /* Filename for *out */
508 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000509 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000510 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000511 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000512 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000513 int *aiIndent; /* Array of indents used in MODE_Explain */
514 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000515 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000516};
517
518/*
drh44dec872014-08-30 15:49:25 +0000519** These are the allowed shellFlgs values
520*/
521#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
522#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
523#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
524
525/*
drh75897232000-05-29 14:26:00 +0000526** These are the allowed modes.
527*/
drh967e8b72000-06-21 13:59:10 +0000528#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000529#define MODE_Column 1 /* One record per line in neat columns */
530#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000531#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
532#define MODE_Html 4 /* Generate an XHTML table */
533#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000534#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000535#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000536#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000537#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000538
drh66ce4d02008-02-15 17:38:06 +0000539static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000540 "line",
541 "column",
542 "list",
543 "semi",
544 "html",
drhfeac5f82004-08-01 00:10:45 +0000545 "insert",
546 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000547 "csv",
drh66ce4d02008-02-15 17:38:06 +0000548 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000549 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000550};
drh75897232000-05-29 14:26:00 +0000551
552/*
mistachkinfad42082014-07-24 22:13:12 +0000553** These are the column/row/line separators used by the various
554** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000555*/
mistachkinfad42082014-07-24 22:13:12 +0000556#define SEP_Column "|"
557#define SEP_Row "\n"
558#define SEP_Tab "\t"
559#define SEP_Space " "
560#define SEP_Comma ","
561#define SEP_CrLf "\r\n"
562#define SEP_Unit "\x1F"
563#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000564
565/*
drh75897232000-05-29 14:26:00 +0000566** Number of elements in an array
567*/
drh902b9ee2008-12-05 17:17:07 +0000568#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000569
570/*
drhea678832008-12-10 19:26:22 +0000571** Compute a string length that is limited to what can be stored in
572** lower 30 bits of a 32-bit signed integer.
573*/
drh4f21c4a2008-12-10 22:15:00 +0000574static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000575 const char *z2 = z;
576 while( *z2 ){ z2++; }
577 return 0x3fffffff & (int)(z2 - z);
578}
579
580/*
drh127f9d72010-02-23 01:47:00 +0000581** A callback for the sqlite3_log() interface.
582*/
583static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000584 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000585 if( p->pLog==0 ) return;
586 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
587 fflush(p->pLog);
588}
589
590/*
shane626a6e42009-10-22 17:30:15 +0000591** Output the given string as a hex-encoded blob (eg. X'1234' )
592*/
593static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
594 int i;
595 char *zBlob = (char *)pBlob;
596 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000597 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000598 fprintf(out,"'");
599}
600
601/*
drh28bd4bc2000-06-15 15:57:22 +0000602** Output the given string as a quoted string using SQL quoting conventions.
603*/
604static void output_quoted_string(FILE *out, const char *z){
605 int i;
606 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000607 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000608 for(i=0; z[i]; i++){
609 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000610 }
611 if( nSingle==0 ){
612 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000613 }else{
614 fprintf(out,"'");
615 while( *z ){
616 for(i=0; z[i] && z[i]!='\''; i++){}
617 if( i==0 ){
618 fprintf(out,"''");
619 z++;
620 }else if( z[i]=='\'' ){
621 fprintf(out,"%.*s''",i,z);
622 z += i+1;
623 }else{
drhcd7d2732002-02-26 23:24:26 +0000624 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000625 break;
626 }
627 }
drhcd7d2732002-02-26 23:24:26 +0000628 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000629 }
drh047d4532015-01-18 20:30:23 +0000630 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000631}
632
633/*
drhfeac5f82004-08-01 00:10:45 +0000634** Output the given string as a quoted according to C or TCL quoting rules.
635*/
636static void output_c_string(FILE *out, const char *z){
637 unsigned int c;
638 fputc('"', out);
639 while( (c = *(z++))!=0 ){
640 if( c=='\\' ){
641 fputc(c, out);
642 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000643 }else if( c=='"' ){
644 fputc('\\', out);
645 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000646 }else if( c=='\t' ){
647 fputc('\\', out);
648 fputc('t', out);
649 }else if( c=='\n' ){
650 fputc('\\', out);
651 fputc('n', out);
652 }else if( c=='\r' ){
653 fputc('\\', out);
654 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000655 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000656 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000657 }else{
658 fputc(c, out);
659 }
660 }
661 fputc('"', out);
662}
663
664/*
drhc08a4f12000-06-15 16:49:48 +0000665** Output the given string with characters that are special to
666** HTML escaped.
667*/
668static void output_html_string(FILE *out, const char *z){
669 int i;
drhc3d6ba42014-01-13 20:38:35 +0000670 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000671 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000672 for(i=0; z[i]
673 && z[i]!='<'
674 && z[i]!='&'
675 && z[i]!='>'
676 && z[i]!='\"'
677 && z[i]!='\'';
678 i++){}
drhc08a4f12000-06-15 16:49:48 +0000679 if( i>0 ){
680 fprintf(out,"%.*s",i,z);
681 }
682 if( z[i]=='<' ){
683 fprintf(out,"&lt;");
684 }else if( z[i]=='&' ){
685 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000686 }else if( z[i]=='>' ){
687 fprintf(out,"&gt;");
688 }else if( z[i]=='\"' ){
689 fprintf(out,"&quot;");
690 }else if( z[i]=='\'' ){
691 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000692 }else{
693 break;
694 }
695 z += i + 1;
696 }
697}
698
699/*
drhc49f44e2006-10-26 18:15:42 +0000700** If a field contains any character identified by a 1 in the following
701** array, then the string must be quoted for CSV.
702*/
703static const char needCsvQuote[] = {
704 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
705 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
706 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
707 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
708 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
709 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
710 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
711 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
712 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
713 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
714 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
715 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
716 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
717 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
718 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
719 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
720};
721
722/*
mistachkindd11f2d2014-12-11 04:49:46 +0000723** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000724** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000725** the null value. Strings are quoted if necessary. The separator
726** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000727*/
drhdcd87a92014-08-18 13:45:42 +0000728static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000729 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000730 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000731 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000732 }else{
drhc49f44e2006-10-26 18:15:42 +0000733 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000734 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000735 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000736 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000737 || (z[i]==p->colSeparator[0] &&
738 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000739 i = 0;
740 break;
741 }
742 }
743 if( i==0 ){
744 putc('"', out);
745 for(i=0; z[i]; i++){
746 if( z[i]=='"' ) putc('"', out);
747 putc(z[i], out);
748 }
749 putc('"', out);
750 }else{
751 fprintf(out, "%s", z);
752 }
drh8e64d1c2004-10-07 00:32:39 +0000753 }
754 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000755 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000756 }
757}
758
danielk19774af00c62005-01-23 23:43:21 +0000759#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000760/*
drh4c504392000-10-16 22:06:40 +0000761** This routine runs when the user presses Ctrl-C
762*/
763static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000764 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000765 seenInterrupt++;
766 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000767 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000768}
danielk19774af00c62005-01-23 23:43:21 +0000769#endif
drh4c504392000-10-16 22:06:40 +0000770
771/*
shane626a6e42009-10-22 17:30:15 +0000772** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000773** invokes for each row of a query result.
774*/
drh4ace5362014-11-10 14:42:28 +0000775static int shell_callback(
776 void *pArg,
777 int nArg, /* Number of result columns */
778 char **azArg, /* Text of each result column */
779 char **azCol, /* Column names */
780 int *aiType /* Column types */
781){
drh75897232000-05-29 14:26:00 +0000782 int i;
drhdcd87a92014-08-18 13:45:42 +0000783 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000784
drh75897232000-05-29 14:26:00 +0000785 switch( p->mode ){
786 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000787 int w = 5;
drh6a535342001-10-19 16:44:56 +0000788 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000789 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000790 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000791 if( len>w ) w = len;
792 }
mistachkin636bf9f2014-07-19 20:15:16 +0000793 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000794 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000795 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000796 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000797 }
798 break;
799 }
danielk19770d78bae2008-01-03 07:09:48 +0000800 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000801 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000802 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000803 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000804 int w, n;
805 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000806 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000807 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000808 w = 0;
drh75897232000-05-29 14:26:00 +0000809 }
drh078b1fd2012-09-21 13:40:02 +0000810 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000811 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000812 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000813 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000814 if( w<n ) w = n;
815 }
816 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000817 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000818 }
819 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000820 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000821 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
822 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000823 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000824 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
825 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000826 }
drha0c66f52000-07-29 13:20:21 +0000827 }
828 }
829 if( p->showHeader ){
830 for(i=0; i<nArg; i++){
831 int w;
832 if( i<ArraySize(p->actualWidth) ){
833 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000834 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000835 }else{
836 w = 10;
837 }
838 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
839 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000840 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000841 }
drh75897232000-05-29 14:26:00 +0000842 }
843 }
drh6a535342001-10-19 16:44:56 +0000844 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000845 for(i=0; i<nArg; i++){
846 int w;
drha0c66f52000-07-29 13:20:21 +0000847 if( i<ArraySize(p->actualWidth) ){
848 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000849 }else{
850 w = 10;
851 }
dana98bf362013-11-13 18:35:01 +0000852 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000853 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000854 }
dana98bf362013-11-13 18:35:01 +0000855 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000856 if( p->iIndent<p->nIndent ){
857 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000858 }
danc4650bb2013-11-18 08:41:06 +0000859 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000860 }
drh078b1fd2012-09-21 13:40:02 +0000861 if( w<0 ){
862 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000863 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000864 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000865 }else{
866 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000867 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000868 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000869 }
drh75897232000-05-29 14:26:00 +0000870 }
871 break;
872 }
drhe3710332000-09-29 13:30:53 +0000873 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000874 case MODE_List: {
875 if( p->cnt++==0 && p->showHeader ){
876 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000877 fprintf(p->out,"%s%s",azCol[i],
878 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000879 }
880 }
drh6a535342001-10-19 16:44:56 +0000881 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000882 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000883 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000884 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000885 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000886 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000887 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000888 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000889 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000890 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000891 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000892 }
drh75897232000-05-29 14:26:00 +0000893 }
894 break;
895 }
drh1e5d0e92000-05-31 23:33:17 +0000896 case MODE_Html: {
897 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000898 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000899 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000900 fprintf(p->out,"<TH>");
901 output_html_string(p->out, azCol[i]);
902 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000903 }
mihailim57c591a2008-06-23 21:26:05 +0000904 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000905 }
drh6a535342001-10-19 16:44:56 +0000906 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000907 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000908 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000909 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000910 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000911 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000912 }
mihailim57c591a2008-06-23 21:26:05 +0000913 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000914 break;
915 }
drhfeac5f82004-08-01 00:10:45 +0000916 case MODE_Tcl: {
917 if( p->cnt++==0 && p->showHeader ){
918 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000919 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000920 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000921 }
mistachkin636bf9f2014-07-19 20:15:16 +0000922 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000923 }
924 if( azArg==0 ) break;
925 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000926 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000927 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000928 }
mistachkin636bf9f2014-07-19 20:15:16 +0000929 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000930 break;
931 }
drh8e64d1c2004-10-07 00:32:39 +0000932 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000933 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000934 if( p->cnt++==0 && p->showHeader ){
935 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000936 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000937 }
mistachkine0d68852014-12-11 03:12:33 +0000938 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000939 }
drh40253262014-10-17 21:35:05 +0000940 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000941 for(i=0; i<nArg; i++){
942 output_csv(p, azArg[i], i<nArg-1);
943 }
mistachkine0d68852014-12-11 03:12:33 +0000944 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000945 }
drh047d4532015-01-18 20:30:23 +0000946 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000947 break;
948 }
drh28bd4bc2000-06-15 15:57:22 +0000949 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000950 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000951 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000952 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000953 for(i=0; i<nArg; i++){
954 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000955 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000956 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000957 }else if( aiType && aiType[i]==SQLITE_TEXT ){
958 if( zSep[0] ) fprintf(p->out,"%s",zSep);
959 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +0000960 }else if( aiType && (aiType[i]==SQLITE_INTEGER
961 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +0000962 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000963 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
964 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
965 int nBlob = sqlite3_column_bytes(p->pStmt, i);
966 if( zSep[0] ) fprintf(p->out,"%s",zSep);
967 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000968 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000969 fprintf(p->out,"%s%s",zSep, azArg[i]);
970 }else{
971 if( zSep[0] ) fprintf(p->out,"%s",zSep);
972 output_quoted_string(p->out, azArg[i]);
973 }
974 }
975 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000976 break;
drh28bd4bc2000-06-15 15:57:22 +0000977 }
mistachkin636bf9f2014-07-19 20:15:16 +0000978 case MODE_Ascii: {
979 if( p->cnt++==0 && p->showHeader ){
980 for(i=0; i<nArg; i++){
981 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
982 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
983 }
984 fprintf(p->out, "%s", p->rowSeparator);
985 }
986 if( azArg==0 ) break;
987 for(i=0; i<nArg; i++){
988 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +0000989 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000990 }
991 fprintf(p->out, "%s", p->rowSeparator);
992 break;
993 }
persicom1d0b8722002-04-18 02:53:04 +0000994 }
drh75897232000-05-29 14:26:00 +0000995 return 0;
996}
997
998/*
shane626a6e42009-10-22 17:30:15 +0000999** This is the callback routine that the SQLite library
1000** invokes for each row of a query result.
1001*/
1002static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1003 /* since we don't have type info, call the shell_callback with a NULL value */
1004 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1005}
1006
1007/*
drhdcd87a92014-08-18 13:45:42 +00001008** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001009** the name of the table given. Escape any quote characters in the
1010** table name.
1011*/
drhdcd87a92014-08-18 13:45:42 +00001012static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001013 int i, n;
1014 int needQuote;
1015 char *z;
1016
1017 if( p->zDestTable ){
1018 free(p->zDestTable);
1019 p->zDestTable = 0;
1020 }
1021 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001022 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001023 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001024 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001025 needQuote = 1;
1026 if( zName[i]=='\'' ) n++;
1027 }
1028 }
1029 if( needQuote ) n += 2;
1030 z = p->zDestTable = malloc( n+1 );
1031 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001032 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001033 exit(1);
1034 }
1035 n = 0;
1036 if( needQuote ) z[n++] = '\'';
1037 for(i=0; zName[i]; i++){
1038 z[n++] = zName[i];
1039 if( zName[i]=='\'' ) z[n++] = '\'';
1040 }
1041 if( needQuote ) z[n++] = '\'';
1042 z[n] = 0;
1043}
1044
danielk19772a02e332004-06-05 08:04:36 +00001045/* zIn is either a pointer to a NULL-terminated string in memory obtained
1046** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1047** added to zIn, and the result returned in memory obtained from malloc().
1048** zIn, if it was not NULL, is freed.
1049**
1050** If the third argument, quote, is not '\0', then it is used as a
1051** quote character for zAppend.
1052*/
drhc28490c2006-10-26 14:25:58 +00001053static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001054 int len;
1055 int i;
drh4f21c4a2008-12-10 22:15:00 +00001056 int nAppend = strlen30(zAppend);
1057 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001058
1059 len = nAppend+nIn+1;
1060 if( quote ){
1061 len += 2;
1062 for(i=0; i<nAppend; i++){
1063 if( zAppend[i]==quote ) len++;
1064 }
1065 }
1066
1067 zIn = (char *)realloc(zIn, len);
1068 if( !zIn ){
1069 return 0;
1070 }
1071
1072 if( quote ){
1073 char *zCsr = &zIn[nIn];
1074 *zCsr++ = quote;
1075 for(i=0; i<nAppend; i++){
1076 *zCsr++ = zAppend[i];
1077 if( zAppend[i]==quote ) *zCsr++ = quote;
1078 }
1079 *zCsr++ = quote;
1080 *zCsr++ = '\0';
1081 assert( (zCsr-zIn)==len );
1082 }else{
1083 memcpy(&zIn[nIn], zAppend, nAppend);
1084 zIn[len-1] = '\0';
1085 }
1086
1087 return zIn;
1088}
1089
drhdd3d4592004-08-30 01:54:05 +00001090
1091/*
drhb21a8e42012-01-28 21:08:51 +00001092** Execute a query statement that will generate SQL output. Print
1093** the result columns, comma-separated, on a line and then add a
1094** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001095**
drhb21a8e42012-01-28 21:08:51 +00001096** If the number of columns is 1 and that column contains text "--"
1097** then write the semicolon on a separate line. That way, if a
1098** "--" comment occurs at the end of the statement, the comment
1099** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001100*/
drh157e29a2009-05-21 15:15:00 +00001101static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001102 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001103 const char *zSelect, /* SELECT statement to extract content */
1104 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001105){
drhdd3d4592004-08-30 01:54:05 +00001106 sqlite3_stmt *pSelect;
1107 int rc;
drhb21a8e42012-01-28 21:08:51 +00001108 int nResult;
1109 int i;
1110 const char *z;
drhc7181902014-02-27 15:04:13 +00001111 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001112 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001113 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001114 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001115 return rc;
1116 }
1117 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001118 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001119 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001120 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001121 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001122 zFirstRow = 0;
1123 }
drhb21a8e42012-01-28 21:08:51 +00001124 z = (const char*)sqlite3_column_text(pSelect, 0);
1125 fprintf(p->out, "%s", z);
1126 for(i=1; i<nResult; i++){
1127 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1128 }
1129 if( z==0 ) z = "";
1130 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1131 if( z[0] ){
1132 fprintf(p->out, "\n;\n");
1133 }else{
1134 fprintf(p->out, ";\n");
1135 }
drhdd3d4592004-08-30 01:54:05 +00001136 rc = sqlite3_step(pSelect);
1137 }
drh2f464a02011-10-13 00:41:49 +00001138 rc = sqlite3_finalize(pSelect);
1139 if( rc!=SQLITE_OK ){
1140 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001141 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001142 }
1143 return rc;
drhdd3d4592004-08-30 01:54:05 +00001144}
1145
shane626a6e42009-10-22 17:30:15 +00001146/*
1147** Allocate space and save off current error string.
1148*/
1149static char *save_err_msg(
1150 sqlite3 *db /* Database to query */
1151){
1152 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1153 char *zErrMsg = sqlite3_malloc(nErrMsg);
1154 if( zErrMsg ){
1155 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1156 }
1157 return zErrMsg;
1158}
1159
1160/*
shaneh642d8b82010-07-28 16:05:34 +00001161** Display memory stats.
1162*/
1163static int display_stats(
1164 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001165 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001166 int bReset /* True to reset the stats */
1167){
1168 int iCur;
1169 int iHiwtr;
1170
1171 if( pArg && pArg->out ){
1172
1173 iHiwtr = iCur = -1;
1174 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001175 fprintf(pArg->out,
1176 "Memory Used: %d (max %d) bytes\n",
1177 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001178 iHiwtr = iCur = -1;
1179 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001180 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1181 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001182 if( pArg->shellFlgs & SHFLG_Pagecache ){
1183 iHiwtr = iCur = -1;
1184 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001185 fprintf(pArg->out,
1186 "Number of Pcache Pages Used: %d (max %d) pages\n",
1187 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001188 }
shaneh642d8b82010-07-28 16:05:34 +00001189 iHiwtr = iCur = -1;
1190 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001191 fprintf(pArg->out,
1192 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1193 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001194 if( pArg->shellFlgs & SHFLG_Scratch ){
1195 iHiwtr = iCur = -1;
1196 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001197 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1198 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001199 }
shaneh642d8b82010-07-28 16:05:34 +00001200 iHiwtr = iCur = -1;
1201 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001202 fprintf(pArg->out,
1203 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1204 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001205 iHiwtr = iCur = -1;
1206 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001207 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1208 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001209 iHiwtr = iCur = -1;
1210 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001211 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1212 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001213 iHiwtr = iCur = -1;
1214 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001215 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1216 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001217#ifdef YYTRACKMAXSTACKDEPTH
1218 iHiwtr = iCur = -1;
1219 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001220 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1221 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001222#endif
1223 }
1224
1225 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001226 if( pArg->shellFlgs & SHFLG_Lookaside ){
1227 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001228 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1229 &iCur, &iHiwtr, bReset);
1230 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1231 iCur, iHiwtr);
1232 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1233 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001234 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001235 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1236 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001237 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001238 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1239 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001240 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1241 }
shaneh642d8b82010-07-28 16:05:34 +00001242 iHiwtr = iCur = -1;
1243 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001244 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1245 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001246 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1247 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1248 iHiwtr = iCur = -1;
1249 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1250 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001251 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001252 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1253 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1254 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001255 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001256 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001257 iHiwtr = iCur = -1;
1258 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001259 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001260 }
1261
1262 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001263 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1264 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001265 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1266 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1267 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001268 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001269 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001270 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1271 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001272 }
1273
1274 return 0;
1275}
1276
1277/*
dan8d1edb92014-11-05 09:07:28 +00001278** Display scan stats.
1279*/
1280static void display_scanstats(
1281 sqlite3 *db, /* Database to query */
1282 ShellState *pArg /* Pointer to ShellState */
1283){
1284#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001285 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001286 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001287 mx = 0;
1288 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001289 double rEstLoop = 1.0;
1290 for(i=n=0; 1; i++){
1291 sqlite3_stmt *p = pArg->pStmt;
1292 sqlite3_int64 nLoop, nVisit;
1293 double rEst;
1294 int iSid;
1295 const char *zExplain;
1296 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1297 break;
1298 }
1299 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001300 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001301 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001302 if( n==0 ){
1303 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001304 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001305 }
drh42f30bc2014-11-06 12:08:21 +00001306 n++;
1307 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1308 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1309 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1310 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1311 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001312 fprintf(pArg->out,
1313 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001314 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001315 );
dan8d1edb92014-11-05 09:07:28 +00001316 }
dan8d1edb92014-11-05 09:07:28 +00001317 }
dan8d1edb92014-11-05 09:07:28 +00001318 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001319#endif
dan8d1edb92014-11-05 09:07:28 +00001320}
1321
1322/*
dana98bf362013-11-13 18:35:01 +00001323** Parameter azArray points to a zero-terminated array of strings. zStr
1324** points to a single nul-terminated string. Return non-zero if zStr
1325** is equal, according to strcmp(), to any of the strings in the array.
1326** Otherwise, return zero.
1327*/
1328static int str_in_array(const char *zStr, const char **azArray){
1329 int i;
1330 for(i=0; azArray[i]; i++){
1331 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1332 }
1333 return 0;
1334}
1335
1336/*
1337** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001338** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001339** spaces each opcode should be indented before it is output.
1340**
1341** The indenting rules are:
1342**
1343** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1344** all opcodes that occur between the p2 jump destination and the opcode
1345** itself by 2 spaces.
1346**
drh01752bc2013-11-14 23:59:33 +00001347** * For each "Goto", if the jump destination is earlier in the program
1348** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001349** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001350** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001351** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001352** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001353*/
drhdcd87a92014-08-18 13:45:42 +00001354static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001355 const char *zSql; /* The text of the SQL statement */
1356 const char *z; /* Used to check if this is an EXPLAIN */
1357 int *abYield = 0; /* True if op is an OP_Yield */
1358 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001359 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001360
drh8ad0de32014-03-20 18:45:27 +00001361 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1362 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001363 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1364 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001365 const char *azGoto[] = { "Goto", 0 };
1366
1367 /* Try to figure out if this is really an EXPLAIN statement. If this
1368 ** cannot be verified, return early. */
1369 zSql = sqlite3_sql(pSql);
1370 if( zSql==0 ) return;
1371 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1372 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1373
1374 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1375 int i;
danc4650bb2013-11-18 08:41:06 +00001376 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001377 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001378
1379 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1380 ** p2 is an instruction address, set variable p2op to the index of that
1381 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1382 ** the current instruction is part of a sub-program generated by an
1383 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001384 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001385 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001386
1387 /* Grow the p->aiIndent array as required */
1388 if( iOp>=nAlloc ){
1389 nAlloc += 100;
1390 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1391 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1392 }
1393 abYield[iOp] = str_in_array(zOp, azYield);
1394 p->aiIndent[iOp] = 0;
1395 p->nIndent = iOp+1;
1396
1397 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001398 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001399 }
drhfe705102014-03-06 13:38:37 +00001400 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1401 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1402 ){
drhe73f0592014-01-21 22:25:45 +00001403 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001404 }
1405 }
1406
danc4650bb2013-11-18 08:41:06 +00001407 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001408 sqlite3_free(abYield);
1409 sqlite3_reset(pSql);
1410}
1411
1412/*
1413** Free the array allocated by explain_data_prepare().
1414*/
drhdcd87a92014-08-18 13:45:42 +00001415static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001416 sqlite3_free(p->aiIndent);
1417 p->aiIndent = 0;
1418 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001419 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001420}
1421
1422/*
shane626a6e42009-10-22 17:30:15 +00001423** Execute a statement or set of statements. Print
1424** any result rows/columns depending on the current mode
1425** set via the supplied callback.
1426**
1427** This is very similar to SQLite's built-in sqlite3_exec()
1428** function except it takes a slightly different callback
1429** and callback data argument.
1430*/
1431static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001432 sqlite3 *db, /* An open database */
1433 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001434 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001435 /* (not the same as sqlite3_exec) */
1436 ShellState *pArg, /* Pointer to ShellState */
1437 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001438){
dan4564ced2010-01-05 04:59:56 +00001439 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1440 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001441 int rc2;
dan4564ced2010-01-05 04:59:56 +00001442 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001443
1444 if( pzErrMsg ){
1445 *pzErrMsg = NULL;
1446 }
1447
shaneb9fc17d2009-10-22 21:23:35 +00001448 while( zSql[0] && (SQLITE_OK == rc) ){
1449 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1450 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001451 if( pzErrMsg ){
1452 *pzErrMsg = save_err_msg(db);
1453 }
1454 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001455 if( !pStmt ){
1456 /* this happens for a comment or white-space */
1457 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001458 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001459 continue;
1460 }
shane626a6e42009-10-22 17:30:15 +00001461
shaneh642d8b82010-07-28 16:05:34 +00001462 /* save off the prepared statment handle and reset row count */
1463 if( pArg ){
1464 pArg->pStmt = pStmt;
1465 pArg->cnt = 0;
1466 }
1467
shanehb7977c52010-01-18 18:17:10 +00001468 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001469 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001470 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001471 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001472 }
shanehb7977c52010-01-18 18:17:10 +00001473
drhefbf3b12014-02-28 20:47:24 +00001474 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1475 if( pArg && pArg->autoEQP ){
1476 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001477 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1478 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001479 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1480 if( rc==SQLITE_OK ){
1481 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1482 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1483 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1484 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1485 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1486 }
1487 }
1488 sqlite3_finalize(pExplain);
1489 sqlite3_free(zEQP);
1490 }
1491
dana98bf362013-11-13 18:35:01 +00001492 /* If the shell is currently in ".explain" mode, gather the extra
1493 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001494 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001495 explain_data_prepare(pArg, pStmt);
1496 }
1497
shaneb9fc17d2009-10-22 21:23:35 +00001498 /* perform the first step. this will tell us if we
1499 ** have a result set or not and how wide it is.
1500 */
1501 rc = sqlite3_step(pStmt);
1502 /* if we have a result set... */
1503 if( SQLITE_ROW == rc ){
1504 /* if we have a callback... */
1505 if( xCallback ){
1506 /* allocate space for col name ptr, value ptr, and type */
1507 int nCol = sqlite3_column_count(pStmt);
1508 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1509 if( !pData ){
1510 rc = SQLITE_NOMEM;
1511 }else{
1512 char **azCols = (char **)pData; /* Names of result columns */
1513 char **azVals = &azCols[nCol]; /* Results */
1514 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001515 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001516 assert(sizeof(int) <= sizeof(char *));
1517 /* save off ptrs to column names */
1518 for(i=0; i<nCol; i++){
1519 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1520 }
shaneb9fc17d2009-10-22 21:23:35 +00001521 do{
1522 /* extract the data and data types */
1523 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001524 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001525 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001526 azVals[i] = "";
1527 }else{
1528 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1529 }
shaneb9fc17d2009-10-22 21:23:35 +00001530 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1531 rc = SQLITE_NOMEM;
1532 break; /* from for */
1533 }
1534 } /* end for */
1535
1536 /* if data and types extracted successfully... */
1537 if( SQLITE_ROW == rc ){
1538 /* call the supplied callback with the result row data */
1539 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1540 rc = SQLITE_ABORT;
1541 }else{
1542 rc = sqlite3_step(pStmt);
1543 }
1544 }
1545 } while( SQLITE_ROW == rc );
1546 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001547 }
1548 }else{
1549 do{
1550 rc = sqlite3_step(pStmt);
1551 } while( rc == SQLITE_ROW );
1552 }
1553 }
1554
dana98bf362013-11-13 18:35:01 +00001555 explain_data_delete(pArg);
1556
shaneh642d8b82010-07-28 16:05:34 +00001557 /* print usage stats if stats on */
1558 if( pArg && pArg->statsOn ){
1559 display_stats(db, pArg, 0);
1560 }
1561
dan8d1edb92014-11-05 09:07:28 +00001562 /* print loop-counters if required */
1563 if( pArg && pArg->scanstatsOn ){
1564 display_scanstats(db, pArg);
1565 }
1566
dan4564ced2010-01-05 04:59:56 +00001567 /* Finalize the statement just executed. If this fails, save a
1568 ** copy of the error message. Otherwise, set zSql to point to the
1569 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001570 rc2 = sqlite3_finalize(pStmt);
1571 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001572 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001573 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001574 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001575 }else if( pzErrMsg ){
1576 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001577 }
shaneh642d8b82010-07-28 16:05:34 +00001578
1579 /* clear saved stmt handle */
1580 if( pArg ){
1581 pArg->pStmt = NULL;
1582 }
shane626a6e42009-10-22 17:30:15 +00001583 }
shaneb9fc17d2009-10-22 21:23:35 +00001584 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001585
1586 return rc;
1587}
1588
drhdd3d4592004-08-30 01:54:05 +00001589
drh33048c02001-10-01 14:29:22 +00001590/*
drh4c653a02000-06-07 01:27:47 +00001591** This is a different callback routine used for dumping the database.
1592** Each row received by this callback consists of a table name,
1593** the table type ("index" or "table") and SQL to create the table.
1594** This routine should print text sufficient to recreate the table.
1595*/
1596static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001597 int rc;
1598 const char *zTable;
1599 const char *zType;
1600 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001601 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001602 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001603
drh902b9ee2008-12-05 17:17:07 +00001604 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001605 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001606 zTable = azArg[0];
1607 zType = azArg[1];
1608 zSql = azArg[2];
1609
drh00b950d2005-09-11 02:03:03 +00001610 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001611 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001612 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001613 fprintf(p->out, "ANALYZE sqlite_master;\n");
1614 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1615 return 0;
drh45e29d82006-11-20 16:21:10 +00001616 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1617 char *zIns;
1618 if( !p->writableSchema ){
1619 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1620 p->writableSchema = 1;
1621 }
1622 zIns = sqlite3_mprintf(
1623 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1624 "VALUES('table','%q','%q',0,'%q');",
1625 zTable, zTable, zSql);
1626 fprintf(p->out, "%s\n", zIns);
1627 sqlite3_free(zIns);
1628 return 0;
drh00b950d2005-09-11 02:03:03 +00001629 }else{
1630 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001631 }
danielk19772a02e332004-06-05 08:04:36 +00001632
1633 if( strcmp(zType, "table")==0 ){
1634 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001635 char *zSelect = 0;
1636 char *zTableInfo = 0;
1637 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001638 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001639
1640 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1641 zTableInfo = appendText(zTableInfo, zTable, '"');
1642 zTableInfo = appendText(zTableInfo, ");", 0);
1643
drhc7181902014-02-27 15:04:13 +00001644 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001645 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001646 if( rc!=SQLITE_OK || !pTableInfo ){
1647 return 1;
1648 }
1649
1650 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001651 /* Always quote the table name, even if it appears to be pure ascii,
1652 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1653 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001654 if( zTmp ){
1655 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001656 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001657 }
1658 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1659 rc = sqlite3_step(pTableInfo);
1660 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001661 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001662 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001663 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001664 rc = sqlite3_step(pTableInfo);
1665 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001666 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001667 }else{
1668 zSelect = appendText(zSelect, ") ", 0);
1669 }
drh157e29a2009-05-21 15:15:00 +00001670 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001671 }
1672 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001673 if( rc!=SQLITE_OK || nRow==0 ){
1674 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001675 return 1;
1676 }
1677 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1678 zSelect = appendText(zSelect, zTable, '"');
1679
drh2f464a02011-10-13 00:41:49 +00001680 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001681 if( rc==SQLITE_CORRUPT ){
1682 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001683 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001684 }
drh85e72432012-04-11 11:38:53 +00001685 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001686 }
drh4c653a02000-06-07 01:27:47 +00001687 return 0;
1688}
1689
1690/*
drh45e29d82006-11-20 16:21:10 +00001691** Run zQuery. Use dump_callback() as the callback routine so that
1692** the contents of the query are output as SQL statements.
1693**
drhdd3d4592004-08-30 01:54:05 +00001694** If we get a SQLITE_CORRUPT error, rerun the query after appending
1695** "ORDER BY rowid DESC" to the end.
1696*/
1697static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001698 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001699 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001700){
1701 int rc;
drh2f464a02011-10-13 00:41:49 +00001702 char *zErr = 0;
1703 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001704 if( rc==SQLITE_CORRUPT ){
1705 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001706 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001707 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1708 if( zErr ){
1709 fprintf(p->out, "/****** %s ******/\n", zErr);
1710 sqlite3_free(zErr);
1711 zErr = 0;
1712 }
drhdd3d4592004-08-30 01:54:05 +00001713 zQ2 = malloc( len+100 );
1714 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001715 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001716 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1717 if( rc ){
1718 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1719 }else{
1720 rc = SQLITE_CORRUPT;
1721 }
1722 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001723 free(zQ2);
1724 }
1725 return rc;
1726}
1727
1728/*
drh75897232000-05-29 14:26:00 +00001729** Text of a help message
1730*/
persicom1d0b8722002-04-18 02:53:04 +00001731static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001732 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001733 ".bail on|off Stop after hitting an error. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001734 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001735 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001736 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001737 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001738 " If TABLE specified, only dump tables matching\n"
1739 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001740 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001741 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001742 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001743 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001744 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001745 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001746 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001747 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001748 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001749 ".indexes ?TABLE? Show names of all indexes\n"
1750 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001751 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001752#ifdef SQLITE_ENABLE_IOTRACE
1753 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1754#endif
drh70df4fe2006-06-13 15:12:21 +00001755#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001756 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001757#endif
drh127f9d72010-02-23 01:47:00 +00001758 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001759 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001760 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001761 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001762 " column Left-aligned columns. (See .width)\n"
1763 " html HTML <table> code\n"
1764 " insert SQL insert statements for TABLE\n"
1765 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001766 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001767 " tabs Tab-separated values\n"
1768 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001769 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001770 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001771 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001772 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001773 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001774 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001775 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001776 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001777 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001778 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001779 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001780 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001781 " If TABLE specified, only show tables matching\n"
1782 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001783 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1784 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001785 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001786 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001787 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001788 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001789 ".tables ?TABLE? List names of tables\n"
1790 " If TABLE specified, only list tables matching\n"
1791 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001792 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001793 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001794 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001795 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001796 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001797 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001798;
1799
drhdaffd0e2001-04-11 14:28:42 +00001800/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001801static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001802/*
1803** Implementation of the "readfile(X)" SQL function. The entire content
1804** of the file named X is read and returned as a BLOB. NULL is returned
1805** if the file does not exist or is unreadable.
1806*/
1807static void readfileFunc(
1808 sqlite3_context *context,
1809 int argc,
1810 sqlite3_value **argv
1811){
1812 const char *zName;
1813 FILE *in;
1814 long nIn;
1815 void *pBuf;
1816
1817 zName = (const char*)sqlite3_value_text(argv[0]);
1818 if( zName==0 ) return;
1819 in = fopen(zName, "rb");
1820 if( in==0 ) return;
1821 fseek(in, 0, SEEK_END);
1822 nIn = ftell(in);
1823 rewind(in);
1824 pBuf = sqlite3_malloc( nIn );
1825 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1826 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1827 }else{
1828 sqlite3_free(pBuf);
1829 }
1830 fclose(in);
1831}
1832
1833/*
1834** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1835** is written into file X. The number of bytes written is returned. Or
1836** NULL is returned if something goes wrong, such as being unable to open
1837** file X for writing.
1838*/
1839static void writefileFunc(
1840 sqlite3_context *context,
1841 int argc,
1842 sqlite3_value **argv
1843){
1844 FILE *out;
1845 const char *z;
drhba5b0932014-07-24 12:39:59 +00001846 sqlite3_int64 rc;
1847 const char *zFile;
1848
1849 zFile = (const char*)sqlite3_value_text(argv[0]);
1850 if( zFile==0 ) return;
1851 out = fopen(zFile, "wb");
1852 if( out==0 ) return;
1853 z = (const char*)sqlite3_value_blob(argv[1]);
1854 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001855 rc = 0;
1856 }else{
drh490fe862014-08-11 14:21:32 +00001857 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001858 }
1859 fclose(out);
1860 sqlite3_result_int64(context, rc);
1861}
drhdaffd0e2001-04-11 14:28:42 +00001862
drh75897232000-05-29 14:26:00 +00001863/*
drh44c2eb12003-04-30 11:38:26 +00001864** Make sure the database is open. If it is not, then open it. If
1865** the database fails to open, print an error message and exit.
1866*/
drhdcd87a92014-08-18 13:45:42 +00001867static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001868 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001869 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001870 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001871 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001872 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1873 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1874 shellstaticFunc, 0, 0);
1875 }
1876 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001877 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001878 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001879 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001880 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001881 }
drhc2e87a32006-06-27 15:16:14 +00001882#ifndef SQLITE_OMIT_LOAD_EXTENSION
1883 sqlite3_enable_load_extension(p->db, 1);
1884#endif
drhba5b0932014-07-24 12:39:59 +00001885 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1886 readfileFunc, 0, 0);
1887 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1888 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001889 }
1890}
1891
1892/*
drhfeac5f82004-08-01 00:10:45 +00001893** Do C-language style dequoting.
1894**
1895** \t -> tab
1896** \n -> newline
1897** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001898** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001899** \NNN -> ascii character NNN in octal
1900** \\ -> backslash
1901*/
1902static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001903 int i, j;
1904 char c;
drhc2ce0be2014-05-29 12:36:14 +00001905 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001906 for(i=j=0; (c = z[i])!=0; i++, j++){
1907 if( c=='\\' ){
1908 c = z[++i];
1909 if( c=='n' ){
1910 c = '\n';
1911 }else if( c=='t' ){
1912 c = '\t';
1913 }else if( c=='r' ){
1914 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001915 }else if( c=='\\' ){
1916 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001917 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001918 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001919 if( z[i+1]>='0' && z[i+1]<='7' ){
1920 i++;
1921 c = (c<<3) + z[i] - '0';
1922 if( z[i+1]>='0' && z[i+1]<='7' ){
1923 i++;
1924 c = (c<<3) + z[i] - '0';
1925 }
1926 }
1927 }
1928 }
1929 z[j] = c;
1930 }
drhc2ce0be2014-05-29 12:36:14 +00001931 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001932}
1933
1934/*
drh348d19c2013-06-03 12:47:43 +00001935** Return the value of a hexadecimal digit. Return -1 if the input
1936** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001937*/
drh348d19c2013-06-03 12:47:43 +00001938static int hexDigitValue(char c){
1939 if( c>='0' && c<='9' ) return c - '0';
1940 if( c>='a' && c<='f' ) return c - 'a' + 10;
1941 if( c>='A' && c<='F' ) return c - 'A' + 10;
1942 return -1;
drhc28490c2006-10-26 14:25:58 +00001943}
1944
1945/*
drh7d9f3942013-04-03 01:26:54 +00001946** Interpret zArg as an integer value, possibly with suffixes.
1947*/
1948static sqlite3_int64 integerValue(const char *zArg){
1949 sqlite3_int64 v = 0;
1950 static const struct { char *zSuffix; int iMult; } aMult[] = {
1951 { "KiB", 1024 },
1952 { "MiB", 1024*1024 },
1953 { "GiB", 1024*1024*1024 },
1954 { "KB", 1000 },
1955 { "MB", 1000000 },
1956 { "GB", 1000000000 },
1957 { "K", 1000 },
1958 { "M", 1000000 },
1959 { "G", 1000000000 },
1960 };
1961 int i;
1962 int isNeg = 0;
1963 if( zArg[0]=='-' ){
1964 isNeg = 1;
1965 zArg++;
1966 }else if( zArg[0]=='+' ){
1967 zArg++;
1968 }
drh348d19c2013-06-03 12:47:43 +00001969 if( zArg[0]=='0' && zArg[1]=='x' ){
1970 int x;
1971 zArg += 2;
1972 while( (x = hexDigitValue(zArg[0]))>=0 ){
1973 v = (v<<4) + x;
1974 zArg++;
1975 }
1976 }else{
1977 while( IsDigit(zArg[0]) ){
1978 v = v*10 + zArg[0] - '0';
1979 zArg++;
1980 }
drh7d9f3942013-04-03 01:26:54 +00001981 }
drhc2bed0a2013-05-24 11:57:50 +00001982 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001983 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1984 v *= aMult[i].iMult;
1985 break;
1986 }
1987 }
1988 return isNeg? -v : v;
1989}
1990
1991/*
drh348d19c2013-06-03 12:47:43 +00001992** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1993** for TRUE and FALSE. Return the integer value if appropriate.
1994*/
1995static int booleanValue(char *zArg){
1996 int i;
1997 if( zArg[0]=='0' && zArg[1]=='x' ){
1998 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1999 }else{
2000 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2001 }
2002 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2003 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2004 return 1;
2005 }
2006 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2007 return 0;
2008 }
2009 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2010 zArg);
2011 return 0;
2012}
2013
2014/*
drh42f64e52012-04-04 16:56:23 +00002015** Close an output file, assuming it is not stderr or stdout
2016*/
2017static void output_file_close(FILE *f){
2018 if( f && f!=stdout && f!=stderr ) fclose(f);
2019}
2020
2021/*
2022** Try to open an output file. The names "stdout" and "stderr" are
2023** recognized and do the right thing. NULL is returned if the output
2024** filename is "off".
2025*/
2026static FILE *output_file_open(const char *zFile){
2027 FILE *f;
2028 if( strcmp(zFile,"stdout")==0 ){
2029 f = stdout;
2030 }else if( strcmp(zFile, "stderr")==0 ){
2031 f = stderr;
2032 }else if( strcmp(zFile, "off")==0 ){
2033 f = 0;
2034 }else{
2035 f = fopen(zFile, "wb");
2036 if( f==0 ){
2037 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2038 }
2039 }
2040 return f;
2041}
2042
2043/*
2044** A routine for handling output from sqlite3_trace().
2045*/
2046static void sql_trace_callback(void *pArg, const char *z){
2047 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002048 if( f ){
2049 int i = (int)strlen(z);
2050 while( i>0 && z[i-1]==';' ){ i--; }
2051 fprintf(f, "%.*s;\n", i, z);
2052 }
drh42f64e52012-04-04 16:56:23 +00002053}
2054
2055/*
drhd8621b92012-04-17 09:09:33 +00002056** A no-op routine that runs with the ".breakpoint" doc-command. This is
2057** a useful spot to set a debugger breakpoint.
2058*/
2059static void test_breakpoint(void){
2060 static int nCall = 0;
2061 nCall++;
2062}
2063
2064/*
mistachkin636bf9f2014-07-19 20:15:16 +00002065** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002066*/
mistachkin636bf9f2014-07-19 20:15:16 +00002067typedef struct ImportCtx ImportCtx;
2068struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002069 const char *zFile; /* Name of the input file */
2070 FILE *in; /* Read the CSV text from this input stream */
2071 char *z; /* Accumulated text for a field */
2072 int n; /* Number of bytes in z */
2073 int nAlloc; /* Space allocated for z[] */
2074 int nLine; /* Current line number */
2075 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002076 int cColSep; /* The column separator character. (Usually ",") */
2077 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002078};
2079
2080/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002081static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002082 if( p->n+1>=p->nAlloc ){
2083 p->nAlloc += p->nAlloc + 100;
2084 p->z = sqlite3_realloc(p->z, p->nAlloc);
2085 if( p->z==0 ){
2086 fprintf(stderr, "out of memory\n");
2087 exit(1);
2088 }
2089 }
2090 p->z[p->n++] = (char)c;
2091}
2092
2093/* Read a single field of CSV text. Compatible with rfc4180 and extended
2094** with the option of having a separator other than ",".
2095**
2096** + Input comes from p->in.
2097** + Store results in p->z of length p->n. Space to hold p->z comes
2098** from sqlite3_malloc().
mistachkin636bf9f2014-07-19 20:15:16 +00002099** + Use p->cSep as the column separator. The default is ",".
2100** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002101** + Keep track of the line number in p->nLine.
2102** + Store the character that terminates the field in p->cTerm. Store
2103** EOF on end-of-file.
2104** + Report syntax errors on stderr
2105*/
mistachkin636bf9f2014-07-19 20:15:16 +00002106static char *csv_read_one_field(ImportCtx *p){
2107 int c;
2108 int cSep = p->cColSep;
2109 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002110 p->n = 0;
2111 c = fgetc(p->in);
2112 if( c==EOF || seenInterrupt ){
2113 p->cTerm = EOF;
2114 return 0;
2115 }
2116 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002117 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002118 int startLine = p->nLine;
2119 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002120 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002121 while( 1 ){
2122 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002123 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002124 if( c==cQuote ){
2125 if( pc==cQuote ){
2126 pc = 0;
2127 continue;
2128 }
2129 }
2130 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002131 || (c==rSep && pc==cQuote)
2132 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002133 || (c==EOF && pc==cQuote)
2134 ){
2135 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002136 p->cTerm = c;
2137 break;
2138 }
2139 if( pc==cQuote && c!='\r' ){
2140 fprintf(stderr, "%s:%d: unescaped %c character\n",
2141 p->zFile, p->nLine, cQuote);
2142 }
2143 if( c==EOF ){
2144 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2145 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002146 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002147 break;
2148 }
mistachkin636bf9f2014-07-19 20:15:16 +00002149 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002150 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002151 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002152 }
drhdb95f682013-06-26 22:46:00 +00002153 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002154 while( c!=EOF && c!=cSep && c!=rSep ){
2155 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002156 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002157 }
mistachkin636bf9f2014-07-19 20:15:16 +00002158 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002159 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002160 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002161 }
drhdb95f682013-06-26 22:46:00 +00002162 p->cTerm = c;
2163 }
drh8dd675e2013-07-12 21:09:24 +00002164 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002165 return p->z;
2166}
2167
mistachkin636bf9f2014-07-19 20:15:16 +00002168/* Read a single field of ASCII delimited text.
2169**
2170** + Input comes from p->in.
2171** + Store results in p->z of length p->n. Space to hold p->z comes
2172** from sqlite3_malloc().
2173** + Use p->cSep as the column separator. The default is "\x1F".
2174** + Use p->rSep as the row separator. The default is "\x1E".
2175** + Keep track of the row number in p->nLine.
2176** + Store the character that terminates the field in p->cTerm. Store
2177** EOF on end-of-file.
2178** + Report syntax errors on stderr
2179*/
2180static char *ascii_read_one_field(ImportCtx *p){
2181 int c;
2182 int cSep = p->cColSep;
2183 int rSep = p->cRowSep;
2184 p->n = 0;
2185 c = fgetc(p->in);
2186 if( c==EOF || seenInterrupt ){
2187 p->cTerm = EOF;
2188 return 0;
2189 }
2190 while( c!=EOF && c!=cSep && c!=rSep ){
2191 import_append_char(p, c);
2192 c = fgetc(p->in);
2193 }
2194 if( c==rSep ){
2195 p->nLine++;
2196 }
2197 p->cTerm = c;
2198 if( p->z ) p->z[p->n] = 0;
2199 return p->z;
2200}
2201
drhdb95f682013-06-26 22:46:00 +00002202/*
drh4bbcf102014-02-06 02:46:08 +00002203** Try to transfer data for table zTable. If an error is seen while
2204** moving forward, try to go backwards. The backwards movement won't
2205** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002206*/
mistachkine31ae902014-02-06 01:15:29 +00002207static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002208 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002209 sqlite3 *newDb,
2210 const char *zTable
2211){
2212 sqlite3_stmt *pQuery = 0;
2213 sqlite3_stmt *pInsert = 0;
2214 char *zQuery = 0;
2215 char *zInsert = 0;
2216 int rc;
2217 int i, j, n;
2218 int nTable = (int)strlen(zTable);
2219 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002220 int cnt = 0;
2221 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002222
2223 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2224 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2225 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002226 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002227 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2228 zQuery);
2229 goto end_data_xfer;
2230 }
2231 n = sqlite3_column_count(pQuery);
2232 zInsert = sqlite3_malloc(200 + nTable + n*3);
2233 if( zInsert==0 ){
2234 fprintf(stderr, "out of memory\n");
2235 goto end_data_xfer;
2236 }
2237 sqlite3_snprintf(200+nTable,zInsert,
2238 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2239 i = (int)strlen(zInsert);
2240 for(j=1; j<n; j++){
2241 memcpy(zInsert+i, ",?", 2);
2242 i += 2;
2243 }
2244 memcpy(zInsert+i, ");", 3);
2245 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2246 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002247 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002248 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2249 zQuery);
2250 goto end_data_xfer;
2251 }
2252 for(k=0; k<2; k++){
2253 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2254 for(i=0; i<n; i++){
2255 switch( sqlite3_column_type(pQuery, i) ){
2256 case SQLITE_NULL: {
2257 sqlite3_bind_null(pInsert, i+1);
2258 break;
2259 }
2260 case SQLITE_INTEGER: {
2261 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2262 break;
2263 }
2264 case SQLITE_FLOAT: {
2265 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2266 break;
2267 }
2268 case SQLITE_TEXT: {
2269 sqlite3_bind_text(pInsert, i+1,
2270 (const char*)sqlite3_column_text(pQuery,i),
2271 -1, SQLITE_STATIC);
2272 break;
2273 }
2274 case SQLITE_BLOB: {
2275 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2276 sqlite3_column_bytes(pQuery,i),
2277 SQLITE_STATIC);
2278 break;
2279 }
2280 }
2281 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002282 rc = sqlite3_step(pInsert);
2283 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2284 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2285 sqlite3_errmsg(newDb));
2286 }
drh3350ce92014-02-06 00:49:12 +00002287 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002288 cnt++;
2289 if( (cnt%spinRate)==0 ){
2290 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2291 fflush(stdout);
2292 }
drh3350ce92014-02-06 00:49:12 +00002293 } /* End while */
2294 if( rc==SQLITE_DONE ) break;
2295 sqlite3_finalize(pQuery);
2296 sqlite3_free(zQuery);
2297 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2298 zTable);
2299 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2300 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002301 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2302 break;
drh3350ce92014-02-06 00:49:12 +00002303 }
2304 } /* End for(k=0...) */
2305
2306end_data_xfer:
2307 sqlite3_finalize(pQuery);
2308 sqlite3_finalize(pInsert);
2309 sqlite3_free(zQuery);
2310 sqlite3_free(zInsert);
2311}
2312
2313
2314/*
2315** Try to transfer all rows of the schema that match zWhere. For
2316** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002317** If an error is encountered while moving forward through the
2318** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002319*/
mistachkine31ae902014-02-06 01:15:29 +00002320static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002321 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002322 sqlite3 *newDb,
2323 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002324 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002325){
2326 sqlite3_stmt *pQuery = 0;
2327 char *zQuery = 0;
2328 int rc;
2329 const unsigned char *zName;
2330 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002331 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002332
2333 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2334 " WHERE %s", zWhere);
2335 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2336 if( rc ){
2337 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2338 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2339 zQuery);
2340 goto end_schema_xfer;
2341 }
2342 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2343 zName = sqlite3_column_text(pQuery, 0);
2344 zSql = sqlite3_column_text(pQuery, 1);
2345 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002346 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2347 if( zErrMsg ){
2348 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2349 sqlite3_free(zErrMsg);
2350 zErrMsg = 0;
2351 }
drh3350ce92014-02-06 00:49:12 +00002352 if( xForEach ){
2353 xForEach(p, newDb, (const char*)zName);
2354 }
2355 printf("done\n");
2356 }
2357 if( rc!=SQLITE_DONE ){
2358 sqlite3_finalize(pQuery);
2359 sqlite3_free(zQuery);
2360 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2361 " WHERE %s ORDER BY rowid DESC", zWhere);
2362 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2363 if( rc ){
2364 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2365 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2366 zQuery);
2367 goto end_schema_xfer;
2368 }
2369 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2370 zName = sqlite3_column_text(pQuery, 0);
2371 zSql = sqlite3_column_text(pQuery, 1);
2372 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002373 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2374 if( zErrMsg ){
2375 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2376 sqlite3_free(zErrMsg);
2377 zErrMsg = 0;
2378 }
drh3350ce92014-02-06 00:49:12 +00002379 if( xForEach ){
2380 xForEach(p, newDb, (const char*)zName);
2381 }
2382 printf("done\n");
2383 }
2384 }
2385end_schema_xfer:
2386 sqlite3_finalize(pQuery);
2387 sqlite3_free(zQuery);
2388}
2389
2390/*
2391** Open a new database file named "zNewDb". Try to recover as much information
2392** as possible out of the main database (which might be corrupt) and write it
2393** into zNewDb.
2394*/
drhdcd87a92014-08-18 13:45:42 +00002395static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002396 int rc;
2397 sqlite3 *newDb = 0;
2398 if( access(zNewDb,0)==0 ){
2399 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2400 return;
2401 }
2402 rc = sqlite3_open(zNewDb, &newDb);
2403 if( rc ){
2404 fprintf(stderr, "Cannot create output database: %s\n",
2405 sqlite3_errmsg(newDb));
2406 }else{
drh54d0d2d2014-04-03 00:32:13 +00002407 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002408 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002409 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2410 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002411 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002412 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002413 }
2414 sqlite3_close(newDb);
2415}
2416
2417/*
drhc2ce0be2014-05-29 12:36:14 +00002418** Change the output file back to stdout
2419*/
drhdcd87a92014-08-18 13:45:42 +00002420static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002421 if( p->outfile[0]=='|' ){
2422 pclose(p->out);
2423 }else{
2424 output_file_close(p->out);
2425 }
2426 p->outfile[0] = 0;
2427 p->out = stdout;
2428}
2429
2430/*
drhf7502f02015-02-06 14:19:44 +00002431** Run an SQL command and return the single integer result.
2432*/
2433static int db_int(ShellState *p, const char *zSql){
2434 sqlite3_stmt *pStmt;
2435 int res = 0;
2436 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2437 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2438 res = sqlite3_column_int(pStmt,0);
2439 }
2440 sqlite3_finalize(pStmt);
2441 return res;
2442}
2443
2444/*
2445** Convert a 2-byte or 4-byte big-endian integer into a native integer
2446*/
2447unsigned int get2byteInt(unsigned char *a){
2448 return (a[0]<<8) + a[1];
2449}
2450unsigned int get4byteInt(unsigned char *a){
2451 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2452}
2453
2454/*
2455** Implementation of the ".info" command.
2456**
2457** Return 1 on error, 2 to exit, and 0 otherwise.
2458*/
drh0e55db12015-02-06 14:51:13 +00002459static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002460 static const struct { const char *zName; int ofst; } aField[] = {
2461 { "file change counter:", 24 },
2462 { "database page count:", 28 },
2463 { "freelist page count:", 36 },
2464 { "schema cookie:", 40 },
2465 { "schema format:", 44 },
2466 { "default cache size:", 48 },
2467 { "autovacuum top root:", 52 },
2468 { "incremental vacuum:", 64 },
2469 { "text encoding:", 56 },
2470 { "user version:", 60 },
2471 { "application id:", 68 },
2472 { "software version:", 96 },
2473 };
drh0e55db12015-02-06 14:51:13 +00002474 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2475 { "number of tables:",
2476 "SELECT count(*) FROM %s WHERE type='table'" },
2477 { "number of indexes:",
2478 "SELECT count(*) FROM %s WHERE type='index'" },
2479 { "number of triggers:",
2480 "SELECT count(*) FROM %s WHERE type='trigger'" },
2481 { "number of views:",
2482 "SELECT count(*) FROM %s WHERE type='view'" },
2483 { "schema size:",
2484 "SELECT total(length(sql)) FROM %s" },
2485 };
2486 sqlite3_file *pFile;
2487 int i;
2488 char *zSchemaTab;
2489 char *zDb = nArg>=2 ? azArg[1] : "main";
2490 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002491 open_db(p, 0);
2492 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002493 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002494 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2495 return 1;
2496 }
2497 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2498 if( i!=SQLITE_OK ){
2499 fprintf(stderr, "unable to read database header\n");
2500 return 1;
2501 }
2502 i = get2byteInt(aHdr+16);
2503 if( i==1 ) i = 65536;
2504 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2505 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2506 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2507 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2508 for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
2509 int ofst = aField[i].ofst;
2510 unsigned int val = get4byteInt(aHdr + ofst);
2511 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2512 switch( ofst ){
2513 case 56: {
2514 if( val==1 ) fprintf(p->out, " (utf8)");
2515 if( val==2 ) fprintf(p->out, " (utf16le)");
2516 if( val==3 ) fprintf(p->out, " (utf16be)");
2517 }
2518 }
2519 fprintf(p->out, "\n");
2520 }
drh0e55db12015-02-06 14:51:13 +00002521 if( zDb==0 ){
2522 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2523 }else if( strcmp(zDb,"temp")==0 ){
2524 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2525 }else{
2526 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2527 }
2528 for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
2529 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2530 int val = db_int(p, zSql);
2531 sqlite3_free(zSql);
2532 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2533 }
2534 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002535 return 0;
2536}
2537
2538
2539/*
drh75897232000-05-29 14:26:00 +00002540** If an input line begins with "." then invoke this routine to
2541** process that line.
drh67505e72002-04-19 12:34:06 +00002542**
drh47ad6842006-11-08 12:25:42 +00002543** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002544*/
drhdcd87a92014-08-18 13:45:42 +00002545static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002546 int i = 1;
2547 int nArg = 0;
2548 int n, c;
drh67505e72002-04-19 12:34:06 +00002549 int rc = 0;
drh75897232000-05-29 14:26:00 +00002550 char *azArg[50];
2551
2552 /* Parse the input line into tokens.
2553 */
2554 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002555 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002556 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002557 if( zLine[i]=='\'' || zLine[i]=='"' ){
2558 int delim = zLine[i++];
2559 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002560 while( zLine[i] && zLine[i]!=delim ){
2561 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2562 i++;
2563 }
drh75897232000-05-29 14:26:00 +00002564 if( zLine[i]==delim ){
2565 zLine[i++] = 0;
2566 }
drhfeac5f82004-08-01 00:10:45 +00002567 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002568 }else{
2569 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002570 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002571 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002572 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002573 }
2574 }
2575
2576 /* Process the input line.
2577 */
shane9bd1b442009-10-23 01:27:39 +00002578 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002579 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002580 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002581 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2582 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2583 ){
drhbc46f022013-01-23 18:53:23 +00002584 const char *zDestFile = 0;
2585 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002586 sqlite3 *pDest;
2587 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002588 int j;
2589 for(j=1; j<nArg; j++){
2590 const char *z = azArg[j];
2591 if( z[0]=='-' ){
2592 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002593 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002594 {
2595 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2596 return 1;
2597 }
2598 }else if( zDestFile==0 ){
2599 zDestFile = azArg[j];
2600 }else if( zDb==0 ){
2601 zDb = zDestFile;
2602 zDestFile = azArg[j];
2603 }else{
2604 fprintf(stderr, "too many arguments to .backup\n");
2605 return 1;
2606 }
drh9ff849f2009-02-04 20:55:57 +00002607 }
drhbc46f022013-01-23 18:53:23 +00002608 if( zDestFile==0 ){
2609 fprintf(stderr, "missing FILENAME argument on .backup\n");
2610 return 1;
2611 }
2612 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002613 rc = sqlite3_open(zDestFile, &pDest);
2614 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002615 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002616 sqlite3_close(pDest);
2617 return 1;
2618 }
drh05782482013-10-24 15:20:20 +00002619 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002620 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2621 if( pBackup==0 ){
2622 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2623 sqlite3_close(pDest);
2624 return 1;
2625 }
2626 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2627 sqlite3_backup_finish(pBackup);
2628 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002629 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002630 }else{
2631 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002632 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002633 }
2634 sqlite3_close(pDest);
2635 }else
2636
drhc2ce0be2014-05-29 12:36:14 +00002637 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2638 if( nArg==2 ){
2639 bail_on_error = booleanValue(azArg[1]);
2640 }else{
2641 fprintf(stderr, "Usage: .bail on|off\n");
2642 rc = 1;
2643 }
drhc49f44e2006-10-26 18:15:42 +00002644 }else
2645
drhd8621b92012-04-17 09:09:33 +00002646 /* The undocumented ".breakpoint" command causes a call to the no-op
2647 ** routine named test_breakpoint().
2648 */
2649 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2650 test_breakpoint();
2651 }else
2652
drhc2ce0be2014-05-29 12:36:14 +00002653 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2654 if( nArg==2 ){
2655 tryToClone(p, azArg[1]);
2656 }else{
2657 fprintf(stderr, "Usage: .clone FILENAME\n");
2658 rc = 1;
2659 }
mistachkine31ae902014-02-06 01:15:29 +00002660 }else
2661
drhc2ce0be2014-05-29 12:36:14 +00002662 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002663 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002664 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002665 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002666 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002667 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002668 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002669 data.colWidth[0] = 3;
2670 data.colWidth[1] = 15;
2671 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002672 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002673 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002674 if( zErrMsg ){
2675 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002676 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002677 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002678 }
2679 }else
2680
drh0e55db12015-02-06 14:51:13 +00002681 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2682 rc = shell_dbinfo_command(p, nArg, azArg);
2683 }else
2684
drhc2ce0be2014-05-29 12:36:14 +00002685 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002686 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002687 /* When playing back a "dump", the content might appear in an order
2688 ** which causes immediate foreign key constraints to be violated.
2689 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002690 if( nArg!=1 && nArg!=2 ){
2691 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2692 rc = 1;
2693 goto meta_command_exit;
2694 }
drhf1dfc4f2009-09-23 15:51:35 +00002695 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002696 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002697 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002698 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002699 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002700 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002701 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002702 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002703 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002704 );
2705 run_schema_dump_query(p,
2706 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002707 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002708 );
drh2f464a02011-10-13 00:41:49 +00002709 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002710 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002711 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002712 );
drh4c653a02000-06-07 01:27:47 +00002713 }else{
2714 int i;
drhdd3d4592004-08-30 01:54:05 +00002715 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002716 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002717 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002718 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002719 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002720 " AND sql NOT NULL");
2721 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002722 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002723 "WHERE sql NOT NULL"
2724 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002725 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002726 );
danielk1977bc6ada42004-06-30 08:20:16 +00002727 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002728 }
2729 }
drh45e29d82006-11-20 16:21:10 +00002730 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002731 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002732 p->writableSchema = 0;
2733 }
drh56197952011-10-13 16:30:13 +00002734 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2735 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002736 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002737 }else
drh75897232000-05-29 14:26:00 +00002738
drhc2ce0be2014-05-29 12:36:14 +00002739 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2740 if( nArg==2 ){
2741 p->echoOn = booleanValue(azArg[1]);
2742 }else{
2743 fprintf(stderr, "Usage: .echo on|off\n");
2744 rc = 1;
2745 }
drhdaffd0e2001-04-11 14:28:42 +00002746 }else
2747
drhc2ce0be2014-05-29 12:36:14 +00002748 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2749 if( nArg==2 ){
2750 p->autoEQP = booleanValue(azArg[1]);
2751 }else{
2752 fprintf(stderr, "Usage: .eqp on|off\n");
2753 rc = 1;
2754 }
drhefbf3b12014-02-28 20:47:24 +00002755 }else
2756
drhd3ac7d92013-01-25 18:33:43 +00002757 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002758 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002759 rc = 2;
drh75897232000-05-29 14:26:00 +00002760 }else
2761
drhc2ce0be2014-05-29 12:36:14 +00002762 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002763 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002764 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002765 if(!p->normalMode.valid) {
2766 p->normalMode.valid = 1;
2767 p->normalMode.mode = p->mode;
2768 p->normalMode.showHeader = p->showHeader;
2769 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002770 }
2771 /* We could put this code under the !p->explainValid
2772 ** condition so that it does not execute if we are already in
2773 ** explain mode. However, always executing it allows us an easy
2774 ** was to reset to explain mode in case the user previously
2775 ** did an .explain followed by a .width, .mode or .header
2776 ** command.
2777 */
danielk19770d78bae2008-01-03 07:09:48 +00002778 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002779 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002780 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002781 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002782 p->colWidth[1] = 13; /* opcode */
2783 p->colWidth[2] = 4; /* P1 */
2784 p->colWidth[3] = 4; /* P2 */
2785 p->colWidth[4] = 4; /* P3 */
2786 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002787 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002788 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002789 }else if (p->normalMode.valid) {
2790 p->normalMode.valid = 0;
2791 p->mode = p->normalMode.mode;
2792 p->showHeader = p->normalMode.showHeader;
2793 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002794 }
drh75897232000-05-29 14:26:00 +00002795 }else
2796
drhc1971542014-06-23 23:28:13 +00002797 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002798 ShellState data;
drhc1971542014-06-23 23:28:13 +00002799 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002800 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002801 if( nArg!=1 ){
2802 fprintf(stderr, "Usage: .fullschema\n");
2803 rc = 1;
2804 goto meta_command_exit;
2805 }
2806 open_db(p, 0);
2807 memcpy(&data, p, sizeof(data));
2808 data.showHeader = 0;
2809 data.mode = MODE_Semi;
2810 rc = sqlite3_exec(p->db,
2811 "SELECT sql FROM"
2812 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2813 " FROM sqlite_master UNION ALL"
2814 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002815 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002816 "ORDER BY rowid",
2817 callback, &data, &zErrMsg
2818 );
drh56f674c2014-07-18 14:43:29 +00002819 if( rc==SQLITE_OK ){
2820 sqlite3_stmt *pStmt;
2821 rc = sqlite3_prepare_v2(p->db,
2822 "SELECT rowid FROM sqlite_master"
2823 " WHERE name GLOB 'sqlite_stat[134]'",
2824 -1, &pStmt, 0);
2825 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2826 sqlite3_finalize(pStmt);
2827 }
2828 if( doStats==0 ){
2829 fprintf(p->out, "/* No STAT tables available */\n");
2830 }else{
2831 fprintf(p->out, "ANALYZE sqlite_master;\n");
2832 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2833 callback, &data, &zErrMsg);
2834 data.mode = MODE_Insert;
2835 data.zDestTable = "sqlite_stat1";
2836 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2837 shell_callback, &data,&zErrMsg);
2838 data.zDestTable = "sqlite_stat3";
2839 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2840 shell_callback, &data,&zErrMsg);
2841 data.zDestTable = "sqlite_stat4";
2842 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2843 shell_callback, &data, &zErrMsg);
2844 fprintf(p->out, "ANALYZE sqlite_master;\n");
2845 }
drhc1971542014-06-23 23:28:13 +00002846 }else
2847
drhc2ce0be2014-05-29 12:36:14 +00002848 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2849 if( nArg==2 ){
2850 p->showHeader = booleanValue(azArg[1]);
2851 }else{
2852 fprintf(stderr, "Usage: .headers on|off\n");
2853 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002854 }
drh75897232000-05-29 14:26:00 +00002855 }else
2856
drhc2ce0be2014-05-29 12:36:14 +00002857 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2858 fprintf(p->out, "%s", zHelp);
2859 }else
2860
2861 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002862 char *zTable; /* Insert data into this table */
2863 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002864 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002865 int nCol; /* Number of columns in the table */
2866 int nByte; /* Number of bytes in an SQL string */
2867 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002868 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002869 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002870 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002871 ImportCtx sCtx; /* Reader context */
mistachkin486fd432014-07-24 22:20:23 +00002872 char *(*xRead)(ImportCtx*); /* Procedure to read one value */
drh5bde8162013-06-27 14:07:53 +00002873 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002874
drhc2ce0be2014-05-29 12:36:14 +00002875 if( nArg!=3 ){
2876 fprintf(stderr, "Usage: .import FILE TABLE\n");
2877 goto meta_command_exit;
2878 }
drh01f37542014-05-31 15:43:33 +00002879 zFile = azArg[1];
2880 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002881 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002882 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002883 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002884 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002885 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002886 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002887 return 1;
drhfeac5f82004-08-01 00:10:45 +00002888 }
drhdb95f682013-06-26 22:46:00 +00002889 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002890 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002891 " for import\n");
2892 return 1;
2893 }
mistachkin636bf9f2014-07-19 20:15:16 +00002894 nSep = strlen30(p->rowSeparator);
2895 if( nSep==0 ){
2896 fprintf(stderr, "Error: non-null row separator required for import\n");
2897 return 1;
2898 }
mistachkine0d68852014-12-11 03:12:33 +00002899 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2900 /* When importing CSV (only), if the row separator is set to the
2901 ** default output row separator, change it to the default input
2902 ** row separator. This avoids having to maintain different input
2903 ** and output row separators. */
2904 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2905 nSep = strlen30(p->rowSeparator);
2906 }
mistachkin636bf9f2014-07-19 20:15:16 +00002907 if( nSep>1 ){
2908 fprintf(stderr, "Error: multi-character row separators not allowed"
2909 " for import\n");
2910 return 1;
2911 }
2912 sCtx.zFile = zFile;
2913 sCtx.nLine = 1;
2914 if( sCtx.zFile[0]=='|' ){
2915 sCtx.in = popen(sCtx.zFile+1, "r");
2916 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00002917 xCloser = pclose;
2918 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002919 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00002920 xCloser = fclose;
2921 }
mistachkin636bf9f2014-07-19 20:15:16 +00002922 if( p->mode==MODE_Ascii ){
2923 xRead = ascii_read_one_field;
2924 }else{
2925 xRead = csv_read_one_field;
2926 }
2927 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002928 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002929 return 1;
2930 }
mistachkin636bf9f2014-07-19 20:15:16 +00002931 sCtx.cColSep = p->colSeparator[0];
2932 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00002933 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002934 if( zSql==0 ){
2935 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002936 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002937 return 1;
2938 }
drh4f21c4a2008-12-10 22:15:00 +00002939 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002940 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002941 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
drhdb95f682013-06-26 22:46:00 +00002942 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2943 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2944 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00002945 while( xRead(&sCtx) ){
2946 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00002947 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00002948 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00002949 }
drh5bde8162013-06-27 14:07:53 +00002950 if( cSep=='(' ){
2951 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00002952 sqlite3_free(sCtx.z);
2953 xCloser(sCtx.in);
2954 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00002955 return 1;
2956 }
drhdb95f682013-06-26 22:46:00 +00002957 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2958 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2959 sqlite3_free(zCreate);
2960 if( rc ){
2961 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2962 sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002963 sqlite3_free(sCtx.z);
2964 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00002965 return 1;
2966 }
drhc7181902014-02-27 15:04:13 +00002967 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002968 }
drhfeac5f82004-08-01 00:10:45 +00002969 sqlite3_free(zSql);
2970 if( rc ){
shane916f9612009-10-23 00:37:15 +00002971 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002972 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002973 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002974 return 1;
drhfeac5f82004-08-01 00:10:45 +00002975 }
shane916f9612009-10-23 00:37:15 +00002976 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002977 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002978 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002979 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002980 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002981 if( zSql==0 ){
2982 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002983 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002984 return 1;
2985 }
drhdb95f682013-06-26 22:46:00 +00002986 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002987 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002988 for(i=1; i<nCol; i++){
2989 zSql[j++] = ',';
2990 zSql[j++] = '?';
2991 }
2992 zSql[j++] = ')';
2993 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00002994 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002995 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002996 if( rc ){
2997 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002998 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00002999 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003000 return 1;
drhfeac5f82004-08-01 00:10:45 +00003001 }
drh2d463112013-08-06 14:36:36 +00003002 needCommit = sqlite3_get_autocommit(db);
3003 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003004 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003005 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003006 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003007 char *z = xRead(&sCtx);
3008 /*
3009 ** Did we reach end-of-file before finding any columns?
3010 ** If so, stop instead of NULL filling the remaining columns.
3011 */
drhdb95f682013-06-26 22:46:00 +00003012 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003013 /*
3014 ** Did we reach end-of-file OR end-of-line before finding any
3015 ** columns in ASCII mode? If so, stop instead of NULL filling
3016 ** the remaining columns.
3017 */
3018 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003019 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003020 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003021 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3022 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003023 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003024 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003025 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003026 }
drhfeac5f82004-08-01 00:10:45 +00003027 }
mistachkin636bf9f2014-07-19 20:15:16 +00003028 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003029 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003030 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003031 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003032 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003033 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3034 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003035 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003036 }
drhdb95f682013-06-26 22:46:00 +00003037 if( i>=nCol ){
3038 sqlite3_step(pStmt);
3039 rc = sqlite3_reset(pStmt);
3040 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003041 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
drhdb95f682013-06-26 22:46:00 +00003042 sqlite3_errmsg(db));
3043 }
3044 }
mistachkin636bf9f2014-07-19 20:15:16 +00003045 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003046
mistachkin636bf9f2014-07-19 20:15:16 +00003047 xCloser(sCtx.in);
3048 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003049 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00003050 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003051 }else
3052
drh0e55db12015-02-06 14:51:13 +00003053 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3054 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003055 ShellState data;
drh75897232000-05-29 14:26:00 +00003056 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003057 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003058 memcpy(&data, p, sizeof(data));
3059 data.showHeader = 0;
3060 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003061 if( nArg==1 ){
3062 rc = sqlite3_exec(p->db,
3063 "SELECT name FROM sqlite_master "
3064 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3065 "UNION ALL "
3066 "SELECT name FROM sqlite_temp_master "
3067 "WHERE type='index' "
3068 "ORDER BY 1",
3069 callback, &data, &zErrMsg
3070 );
drhc2ce0be2014-05-29 12:36:14 +00003071 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003072 zShellStatic = azArg[1];
3073 rc = sqlite3_exec(p->db,
3074 "SELECT name FROM sqlite_master "
3075 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3076 "UNION ALL "
3077 "SELECT name FROM sqlite_temp_master "
3078 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3079 "ORDER BY 1",
3080 callback, &data, &zErrMsg
3081 );
3082 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003083 }else{
drh0e55db12015-02-06 14:51:13 +00003084 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003085 rc = 1;
3086 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003087 }
drh75897232000-05-29 14:26:00 +00003088 if( zErrMsg ){
3089 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003090 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003091 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003092 }else if( rc != SQLITE_OK ){
3093 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3094 rc = 1;
drh75897232000-05-29 14:26:00 +00003095 }
3096 }else
3097
drhae5e4452007-05-03 17:18:36 +00003098#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003099 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003100 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003101 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3102 iotrace = 0;
3103 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003104 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003105 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003106 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003107 iotrace = stdout;
3108 }else{
3109 iotrace = fopen(azArg[1], "w");
3110 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003111 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003112 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003113 rc = 1;
drhb0603412007-02-28 04:47:26 +00003114 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003115 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003116 }
3117 }
3118 }else
drhae5e4452007-05-03 17:18:36 +00003119#endif
drhb0603412007-02-28 04:47:26 +00003120
drh70df4fe2006-06-13 15:12:21 +00003121#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003122 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003123 const char *zFile, *zProc;
3124 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003125 if( nArg<2 ){
3126 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3127 rc = 1;
3128 goto meta_command_exit;
3129 }
drh1e397f82006-06-08 15:28:43 +00003130 zFile = azArg[1];
3131 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003132 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003133 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3134 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003135 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003136 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003137 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003138 }
3139 }else
drh70df4fe2006-06-13 15:12:21 +00003140#endif
drh1e397f82006-06-08 15:28:43 +00003141
drhc2ce0be2014-05-29 12:36:14 +00003142 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3143 if( nArg!=2 ){
3144 fprintf(stderr, "Usage: .log FILENAME\n");
3145 rc = 1;
3146 }else{
3147 const char *zFile = azArg[1];
3148 output_file_close(p->pLog);
3149 p->pLog = output_file_open(zFile);
3150 }
drh127f9d72010-02-23 01:47:00 +00003151 }else
3152
drhc2ce0be2014-05-29 12:36:14 +00003153 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3154 const char *zMode = nArg>=2 ? azArg[1] : "";
3155 int n2 = (int)strlen(zMode);
3156 int c2 = zMode[0];
3157 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003158 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003159 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003160 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003161 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003162 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003163 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003164 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003165 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003166 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003167 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003168 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003169 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003170 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003171 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003172 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003173 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003174 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003175 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003176 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003177 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003178 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3179 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003180 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3181 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003182 }else {
shane9bd1b442009-10-23 01:27:39 +00003183 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003184 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003185 rc = 1;
drh75897232000-05-29 14:26:00 +00003186 }
3187 }else
3188
drhc2ce0be2014-05-29 12:36:14 +00003189 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3190 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003191 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3192 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003193 }else{
3194 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003195 rc = 1;
3196 }
3197 }else
3198
drh05782482013-10-24 15:20:20 +00003199 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3200 sqlite3 *savedDb = p->db;
3201 const char *zSavedFilename = p->zDbFilename;
3202 char *zNewFilename = 0;
3203 p->db = 0;
3204 if( nArg>=2 ){
3205 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3206 }
3207 open_db(p, 1);
3208 if( p->db!=0 ){
3209 sqlite3_close(savedDb);
3210 sqlite3_free(p->zFreeOnClose);
3211 p->zFreeOnClose = zNewFilename;
3212 }else{
3213 sqlite3_free(zNewFilename);
3214 p->db = savedDb;
3215 p->zDbFilename = zSavedFilename;
3216 }
3217 }else
3218
drhc2ce0be2014-05-29 12:36:14 +00003219 if( c=='o'
3220 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3221 ){
3222 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3223 if( nArg>2 ){
3224 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3225 rc = 1;
3226 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003227 }
drhc2ce0be2014-05-29 12:36:14 +00003228 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3229 if( nArg<2 ){
3230 fprintf(stderr, "Usage: .once FILE\n");
3231 rc = 1;
3232 goto meta_command_exit;
3233 }
3234 p->outCount = 2;
3235 }else{
3236 p->outCount = 0;
3237 }
3238 output_reset(p);
3239 if( zFile[0]=='|' ){
3240 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003241 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003242 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003243 p->out = stdout;
3244 rc = 1;
3245 }else{
drhc2ce0be2014-05-29 12:36:14 +00003246 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003247 }
drh75897232000-05-29 14:26:00 +00003248 }else{
drhc2ce0be2014-05-29 12:36:14 +00003249 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003250 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003251 if( strcmp(zFile,"off")!=0 ){
3252 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003253 }
drh75897232000-05-29 14:26:00 +00003254 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003255 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003256 } else {
drhc2ce0be2014-05-29 12:36:14 +00003257 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003258 }
3259 }
3260 }else
3261
drh078b1fd2012-09-21 13:40:02 +00003262 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3263 int i;
3264 for(i=1; i<nArg; i++){
3265 if( i>1 ) fprintf(p->out, " ");
3266 fprintf(p->out, "%s", azArg[i]);
3267 }
3268 fprintf(p->out, "\n");
3269 }else
3270
drhc2ce0be2014-05-29 12:36:14 +00003271 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003272 if( nArg >= 2) {
3273 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3274 }
3275 if( nArg >= 3) {
3276 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3277 }
3278 }else
3279
drhc2ce0be2014-05-29 12:36:14 +00003280 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003281 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003282 }else
3283
drhc2ce0be2014-05-29 12:36:14 +00003284 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3285 FILE *alt;
3286 if( nArg!=2 ){
3287 fprintf(stderr, "Usage: .read FILE\n");
3288 rc = 1;
3289 goto meta_command_exit;
3290 }
3291 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003292 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003293 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3294 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003295 }else{
shane9bd1b442009-10-23 01:27:39 +00003296 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003297 fclose(alt);
3298 }
3299 }else
3300
drhc2ce0be2014-05-29 12:36:14 +00003301 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003302 const char *zSrcFile;
3303 const char *zDb;
3304 sqlite3 *pSrc;
3305 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003306 int nTimeout = 0;
3307
drh9ff849f2009-02-04 20:55:57 +00003308 if( nArg==2 ){
3309 zSrcFile = azArg[1];
3310 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003311 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003312 zSrcFile = azArg[2];
3313 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003314 }else{
3315 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3316 rc = 1;
3317 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003318 }
3319 rc = sqlite3_open(zSrcFile, &pSrc);
3320 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003321 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003322 sqlite3_close(pSrc);
3323 return 1;
3324 }
drh05782482013-10-24 15:20:20 +00003325 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003326 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3327 if( pBackup==0 ){
3328 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3329 sqlite3_close(pSrc);
3330 return 1;
3331 }
drhdc2c4912009-02-04 22:46:47 +00003332 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3333 || rc==SQLITE_BUSY ){
3334 if( rc==SQLITE_BUSY ){
3335 if( nTimeout++ >= 3 ) break;
3336 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003337 }
3338 }
3339 sqlite3_backup_finish(pBackup);
3340 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003341 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003342 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003343 fprintf(stderr, "Error: source database is busy\n");
3344 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003345 }else{
3346 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003347 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003348 }
3349 sqlite3_close(pSrc);
3350 }else
3351
dan8d1edb92014-11-05 09:07:28 +00003352
3353 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3354 if( nArg==2 ){
3355 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003356#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3357 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3358#endif
dan8d1edb92014-11-05 09:07:28 +00003359 }else{
3360 fprintf(stderr, "Usage: .scanstats on|off\n");
3361 rc = 1;
3362 }
3363 }else
3364
drhc2ce0be2014-05-29 12:36:14 +00003365 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003366 ShellState data;
drh75897232000-05-29 14:26:00 +00003367 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003368 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003369 memcpy(&data, p, sizeof(data));
3370 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003371 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003372 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003373 int i;
drhf0693c82011-10-11 20:41:54 +00003374 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003375 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003376 char *new_argv[2], *new_colv[2];
3377 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3378 " type text,\n"
3379 " name text,\n"
3380 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003381 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003382 " sql text\n"
3383 ")";
3384 new_argv[1] = 0;
3385 new_colv[0] = "sql";
3386 new_colv[1] = 0;
3387 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003388 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003389 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003390 char *new_argv[2], *new_colv[2];
3391 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3392 " type text,\n"
3393 " name text,\n"
3394 " tbl_name text,\n"
3395 " rootpage integer,\n"
3396 " sql text\n"
3397 ")";
3398 new_argv[1] = 0;
3399 new_colv[0] = "sql";
3400 new_colv[1] = 0;
3401 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003402 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003403 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003404 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003405 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003406 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003407 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003408 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003409 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003410 "WHERE lower(tbl_name) LIKE shellstatic()"
3411 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003412 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003413 callback, &data, &zErrMsg);
3414 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003415 }
drhc2ce0be2014-05-29 12:36:14 +00003416 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003417 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003418 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003419 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003420 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003421 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003422 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003423 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003424 callback, &data, &zErrMsg
3425 );
drhc2ce0be2014-05-29 12:36:14 +00003426 }else{
3427 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3428 rc = 1;
3429 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003430 }
drh75897232000-05-29 14:26:00 +00003431 if( zErrMsg ){
3432 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003433 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003434 rc = 1;
3435 }else if( rc != SQLITE_OK ){
3436 fprintf(stderr,"Error: querying schema information\n");
3437 rc = 1;
3438 }else{
3439 rc = 0;
drh75897232000-05-29 14:26:00 +00003440 }
3441 }else
3442
drhabd4c722014-09-20 18:18:33 +00003443
3444#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3445 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3446 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003447 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003448 }else
3449#endif
3450
3451
drh340f5822013-06-27 13:01:21 +00003452#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003453 /* Undocumented commands for internal testing. Subject to change
3454 ** without notice. */
3455 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3456 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3457 int i, v;
3458 for(i=1; i<nArg; i++){
3459 v = booleanValue(azArg[i]);
3460 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3461 }
3462 }
3463 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3464 int i; sqlite3_int64 v;
3465 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003466 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003467 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003468 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003469 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003470 }
3471 }
3472 }else
drh340f5822013-06-27 13:01:21 +00003473#endif
drh348d19c2013-06-03 12:47:43 +00003474
drhc2ce0be2014-05-29 12:36:14 +00003475 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003476 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003477 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003478 rc = 1;
3479 }
drh6976c212014-07-24 12:09:47 +00003480 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003481 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003482 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003483 }
3484 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003485 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3486 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003487 }
drh75897232000-05-29 14:26:00 +00003488 }else
3489
drh62cdde52014-05-28 20:22:28 +00003490 if( c=='s'
3491 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003492 ){
3493 char *zCmd;
drh54027102014-08-06 14:36:53 +00003494 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003495 if( nArg<2 ){
3496 fprintf(stderr, "Usage: .system COMMAND\n");
3497 rc = 1;
3498 goto meta_command_exit;
3499 }
drhdcb3e3d2014-05-29 03:17:29 +00003500 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003501 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003502 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3503 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003504 }
drh54027102014-08-06 14:36:53 +00003505 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003506 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003507 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003508 }else
3509
drhc2ce0be2014-05-29 12:36:14 +00003510 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003511 int i;
drhc2ce0be2014-05-29 12:36:14 +00003512 if( nArg!=1 ){
3513 fprintf(stderr, "Usage: .show\n");
3514 rc = 1;
3515 goto meta_command_exit;
3516 }
mistachkin636bf9f2014-07-19 20:15:16 +00003517 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3518 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003519 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003520 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3521 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3522 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003523 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003524 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003525 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003526 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003527 fprintf(p->out,"%12.12s: ", "colseparator");
3528 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003529 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003530 fprintf(p->out,"%12.12s: ", "rowseparator");
3531 output_c_string(p->out, p->rowSeparator);
3532 fprintf(p->out, "\n");
3533 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3534 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003535 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003536 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003537 }
drhfeac5f82004-08-01 00:10:45 +00003538 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003539 }else
3540
drhc2ce0be2014-05-29 12:36:14 +00003541 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3542 if( nArg==2 ){
3543 p->statsOn = booleanValue(azArg[1]);
3544 }else{
3545 fprintf(stderr, "Usage: .stats on|off\n");
3546 rc = 1;
3547 }
shaneh642d8b82010-07-28 16:05:34 +00003548 }else
3549
drhc2ce0be2014-05-29 12:36:14 +00003550 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003551 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003552 char **azResult;
drh98781232012-04-23 12:38:05 +00003553 int nRow, nAlloc;
3554 char *zSql = 0;
3555 int ii;
drh05782482013-10-24 15:20:20 +00003556 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003557 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3558 if( rc ) return rc;
3559 zSql = sqlite3_mprintf(
3560 "SELECT name FROM sqlite_master"
3561 " WHERE type IN ('table','view')"
3562 " AND name NOT LIKE 'sqlite_%%'"
3563 " AND name LIKE ?1");
3564 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3565 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3566 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3567 if( strcmp(zDbName,"temp")==0 ){
3568 zSql = sqlite3_mprintf(
3569 "%z UNION ALL "
3570 "SELECT 'temp.' || name FROM sqlite_temp_master"
3571 " WHERE type IN ('table','view')"
3572 " AND name NOT LIKE 'sqlite_%%'"
3573 " AND name LIKE ?1", zSql);
3574 }else{
3575 zSql = sqlite3_mprintf(
3576 "%z UNION ALL "
3577 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3578 " WHERE type IN ('table','view')"
3579 " AND name NOT LIKE 'sqlite_%%'"
3580 " AND name LIKE ?1", zSql, zDbName, zDbName);
3581 }
drha50da102000-08-08 20:19:09 +00003582 }
drh98781232012-04-23 12:38:05 +00003583 sqlite3_finalize(pStmt);
3584 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3585 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3586 sqlite3_free(zSql);
3587 if( rc ) return rc;
3588 nRow = nAlloc = 0;
3589 azResult = 0;
3590 if( nArg>1 ){
3591 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003592 }else{
drh98781232012-04-23 12:38:05 +00003593 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3594 }
3595 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3596 if( nRow>=nAlloc ){
3597 char **azNew;
3598 int n = nAlloc*2 + 10;
3599 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3600 if( azNew==0 ){
3601 fprintf(stderr, "Error: out of memory\n");
3602 break;
3603 }
3604 nAlloc = n;
3605 azResult = azNew;
3606 }
3607 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3608 if( azResult[nRow] ) nRow++;
3609 }
3610 sqlite3_finalize(pStmt);
3611 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003612 int len, maxlen = 0;
3613 int i, j;
3614 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003615 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003616 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003617 if( len>maxlen ) maxlen = len;
3618 }
3619 nPrintCol = 80/(maxlen+2);
3620 if( nPrintCol<1 ) nPrintCol = 1;
3621 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3622 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003623 for(j=i; j<nRow; j+=nPrintRow){
3624 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003625 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003626 }
drh151b7d52013-05-06 20:28:54 +00003627 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003628 }
3629 }
drh98781232012-04-23 12:38:05 +00003630 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3631 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003632 }else
3633
shaneh96887e12011-02-10 21:08:58 +00003634 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003635 static const struct {
3636 const char *zCtrlName; /* Name of a test-control option */
3637 int ctrlCode; /* Integer code for that option */
3638 } aCtrl[] = {
3639 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3640 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3641 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3642 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3643 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3644 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3645 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3646 { "assert", SQLITE_TESTCTRL_ASSERT },
3647 { "always", SQLITE_TESTCTRL_ALWAYS },
3648 { "reserve", SQLITE_TESTCTRL_RESERVE },
3649 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3650 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003651 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003652 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003653 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003654 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003655 };
shaneh96887e12011-02-10 21:08:58 +00003656 int testctrl = -1;
3657 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003658 int i, n;
drh05782482013-10-24 15:20:20 +00003659 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003660
drhd416fe72011-03-17 16:45:50 +00003661 /* convert testctrl text option to value. allow any unique prefix
3662 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003663 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003664 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003665 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3666 if( testctrl<0 ){
3667 testctrl = aCtrl[i].ctrlCode;
3668 }else{
drhb07028f2011-10-14 21:49:18 +00003669 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003670 testctrl = -1;
3671 break;
3672 }
3673 }
3674 }
drh348d19c2013-06-03 12:47:43 +00003675 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003676 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3677 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3678 }else{
3679 switch(testctrl){
3680
3681 /* sqlite3_test_control(int, db, int) */
3682 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3683 case SQLITE_TESTCTRL_RESERVE:
3684 if( nArg==3 ){
3685 int opt = (int)strtol(azArg[2], 0, 0);
3686 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003687 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003688 } else {
drhd416fe72011-03-17 16:45:50 +00003689 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3690 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003691 }
3692 break;
3693
3694 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003695 case SQLITE_TESTCTRL_PRNG_SAVE:
3696 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003697 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003698 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003699 if( nArg==2 ){
3700 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003701 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003702 } else {
3703 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3704 }
3705 break;
3706
3707 /* sqlite3_test_control(int, uint) */
3708 case SQLITE_TESTCTRL_PENDING_BYTE:
3709 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003710 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003711 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003712 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003713 } else {
drhd416fe72011-03-17 16:45:50 +00003714 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3715 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003716 }
3717 break;
3718
3719 /* sqlite3_test_control(int, int) */
3720 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003721 case SQLITE_TESTCTRL_ALWAYS:
3722 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003723 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003724 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003725 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003726 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003727 } else {
drhd416fe72011-03-17 16:45:50 +00003728 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3729 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003730 }
3731 break;
3732
3733 /* sqlite3_test_control(int, char *) */
3734#ifdef SQLITE_N_KEYWORD
3735 case SQLITE_TESTCTRL_ISKEYWORD:
3736 if( nArg==3 ){
3737 const char *opt = azArg[2];
3738 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003739 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003740 } else {
drhd416fe72011-03-17 16:45:50 +00003741 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3742 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003743 }
3744 break;
3745#endif
3746
drh1ffede82015-01-30 20:59:27 +00003747 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003748 if( nArg==5 ){
3749 rc = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003750 azArg[2],
drh8964b342015-01-29 17:54:52 +00003751 integerValue(azArg[3]),
3752 integerValue(azArg[4]));
3753 }else{
drh1ffede82015-01-30 20:59:27 +00003754 fprintf(stderr,"Usage: .testctrl initmode dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003755 rc = 1;
3756 }
3757 break;
3758
shaneh96887e12011-02-10 21:08:58 +00003759 case SQLITE_TESTCTRL_BITVEC_TEST:
3760 case SQLITE_TESTCTRL_FAULT_INSTALL:
3761 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3762 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3763 default:
drhd416fe72011-03-17 16:45:50 +00003764 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3765 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003766 break;
3767 }
3768 }
3769 }else
3770
drhc2ce0be2014-05-29 12:36:14 +00003771 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003772 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003773 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003774 }else
3775
drhc2ce0be2014-05-29 12:36:14 +00003776 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3777 if( nArg==2 ){
3778 enableTimer = booleanValue(azArg[1]);
3779 if( enableTimer && !HAS_TIMER ){
3780 fprintf(stderr, "Error: timer not available on this system.\n");
3781 enableTimer = 0;
3782 }
3783 }else{
3784 fprintf(stderr, "Usage: .timer on|off\n");
3785 rc = 1;
3786 }
shanehe2aa9d72009-11-06 17:20:17 +00003787 }else
3788
drhc2ce0be2014-05-29 12:36:14 +00003789 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003790 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00003791 output_file_close(p->traceOut);
drhc2ce0be2014-05-29 12:36:14 +00003792 if( nArg!=2 ){
3793 fprintf(stderr, "Usage: .trace FILE|off\n");
3794 rc = 1;
3795 goto meta_command_exit;
3796 }
drh42f64e52012-04-04 16:56:23 +00003797 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003798#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003799 if( p->traceOut==0 ){
3800 sqlite3_trace(p->db, 0, 0);
3801 }else{
3802 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3803 }
3804#endif
3805 }else
3806
drhf442e332014-09-10 19:01:14 +00003807#if SQLITE_USER_AUTHENTICATION
3808 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3809 if( nArg<2 ){
3810 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3811 rc = 1;
3812 goto meta_command_exit;
3813 }
drh7883ecf2014-09-11 16:19:31 +00003814 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003815 if( strcmp(azArg[1],"login")==0 ){
3816 if( nArg!=4 ){
3817 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3818 rc = 1;
3819 goto meta_command_exit;
3820 }
drhd39c40f2014-09-11 00:27:53 +00003821 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3822 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003823 if( rc ){
3824 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3825 rc = 1;
3826 }
3827 }else if( strcmp(azArg[1],"add")==0 ){
3828 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003829 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003830 rc = 1;
3831 goto meta_command_exit;
3832 }
drhd39c40f2014-09-11 00:27:53 +00003833 rc = sqlite3_user_add(p->db, azArg[2],
3834 azArg[3], (int)strlen(azArg[3]),
3835 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003836 if( rc ){
3837 fprintf(stderr, "User-Add failed: %d\n", rc);
3838 rc = 1;
3839 }
3840 }else if( strcmp(azArg[1],"edit")==0 ){
3841 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003842 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003843 rc = 1;
3844 goto meta_command_exit;
3845 }
drhd39c40f2014-09-11 00:27:53 +00003846 rc = sqlite3_user_change(p->db, azArg[2],
3847 azArg[3], (int)strlen(azArg[3]),
3848 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003849 if( rc ){
3850 fprintf(stderr, "User-Edit failed: %d\n", rc);
3851 rc = 1;
3852 }
3853 }else if( strcmp(azArg[1],"delete")==0 ){
3854 if( nArg!=3 ){
3855 fprintf(stderr, "Usage: .user delete USER\n");
3856 rc = 1;
3857 goto meta_command_exit;
3858 }
3859 rc = sqlite3_user_delete(p->db, azArg[2]);
3860 if( rc ){
3861 fprintf(stderr, "User-Delete failed: %d\n", rc);
3862 rc = 1;
3863 }
3864 }else{
3865 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
3866 rc = 1;
3867 goto meta_command_exit;
3868 }
3869 }else
3870#endif /* SQLITE_USER_AUTHENTICATION */
3871
drh9fd301b2011-06-03 13:28:22 +00003872 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003873 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003874 sqlite3_libversion(), sqlite3_sourceid());
3875 }else
3876
drhde60fc22011-12-14 17:53:36 +00003877 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3878 const char *zDbName = nArg==2 ? azArg[1] : "main";
3879 char *zVfsName = 0;
3880 if( p->db ){
3881 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3882 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003883 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003884 sqlite3_free(zVfsName);
3885 }
3886 }
3887 }else
3888
drhcef4fc82012-09-21 22:50:45 +00003889#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3890 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3891 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003892 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003893 }else
3894#endif
3895
drhc2ce0be2014-05-29 12:36:14 +00003896 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003897 int j;
drh43617e92006-03-06 20:55:46 +00003898 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003899 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003900 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003901 }
3902 }else
3903
3904 {
shane9bd1b442009-10-23 01:27:39 +00003905 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003906 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003907 rc = 1;
drh75897232000-05-29 14:26:00 +00003908 }
drh67505e72002-04-19 12:34:06 +00003909
drhc2ce0be2014-05-29 12:36:14 +00003910meta_command_exit:
3911 if( p->outCount ){
3912 p->outCount--;
3913 if( p->outCount==0 ) output_reset(p);
3914 }
drh67505e72002-04-19 12:34:06 +00003915 return rc;
drh75897232000-05-29 14:26:00 +00003916}
3917
drh67505e72002-04-19 12:34:06 +00003918/*
drh91a66392007-09-07 01:12:32 +00003919** Return TRUE if a semicolon occurs anywhere in the first N characters
3920** of string z[].
drh324ccef2003-02-05 14:06:20 +00003921*/
drh9f099fd2013-08-06 14:01:46 +00003922static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00003923 int i;
3924 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3925 return 0;
drh324ccef2003-02-05 14:06:20 +00003926}
3927
3928/*
drh70c7a4b2003-04-26 03:03:06 +00003929** Test to see if a line consists entirely of whitespace.
3930*/
3931static int _all_whitespace(const char *z){
3932 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00003933 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003934 if( *z=='/' && z[1]=='*' ){
3935 z += 2;
3936 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3937 if( *z==0 ) return 0;
3938 z++;
3939 continue;
3940 }
3941 if( *z=='-' && z[1]=='-' ){
3942 z += 2;
3943 while( *z && *z!='\n' ){ z++; }
3944 if( *z==0 ) return 1;
3945 continue;
3946 }
3947 return 0;
3948 }
3949 return 1;
3950}
3951
3952/*
drha9b17162003-04-29 18:01:28 +00003953** Return TRUE if the line typed in is an SQL command terminator other
3954** than a semi-colon. The SQL Server style "go" command is understood
3955** as is the Oracle "/".
3956*/
drh9f099fd2013-08-06 14:01:46 +00003957static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00003958 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00003959 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3960 return 1; /* Oracle */
3961 }
drhf0693c82011-10-11 20:41:54 +00003962 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00003963 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00003964 return 1; /* SQL Server */
3965 }
3966 return 0;
3967}
3968
3969/*
drh233a5312008-12-18 22:25:13 +00003970** Return true if zSql is a complete SQL statement. Return false if it
3971** ends in the middle of a string literal or C-style comment.
3972*/
drh9f099fd2013-08-06 14:01:46 +00003973static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00003974 int rc;
3975 if( zSql==0 ) return 1;
3976 zSql[nSql] = ';';
3977 zSql[nSql+1] = 0;
3978 rc = sqlite3_complete(zSql);
3979 zSql[nSql] = 0;
3980 return rc;
3981}
3982
3983/*
drh67505e72002-04-19 12:34:06 +00003984** Read input from *in and process it. If *in==0 then input
3985** is interactive - the user is typing it it. Otherwise, input
3986** is coming from a file or device. A prompt is issued and history
3987** is saved only if input is interactive. An interrupt signal will
3988** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00003989**
3990** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00003991*/
drhdcd87a92014-08-18 13:45:42 +00003992static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00003993 char *zLine = 0; /* A single input line */
3994 char *zSql = 0; /* Accumulated SQL text */
3995 int nLine; /* Length of current line */
3996 int nSql = 0; /* Bytes of zSql[] used */
3997 int nAlloc = 0; /* Allocated zSql[] space */
3998 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
3999 char *zErrMsg; /* Error message returned */
4000 int rc; /* Error code */
4001 int errCnt = 0; /* Number of errors seen */
4002 int lineno = 0; /* Current line number */
4003 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004004
4005 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4006 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004007 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004008 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004009 /* End of input */
4010 if( stdin_is_interactive ) printf("\n");
4011 break;
drhc49f44e2006-10-26 18:15:42 +00004012 }
drh67505e72002-04-19 12:34:06 +00004013 if( seenInterrupt ){
4014 if( in!=0 ) break;
4015 seenInterrupt = 0;
4016 }
drhc28490c2006-10-26 14:25:58 +00004017 lineno++;
drh849a9d92013-12-21 15:46:06 +00004018 if( nSql==0 && _all_whitespace(zLine) ){
4019 if( p->echoOn ) printf("%s\n", zLine);
4020 continue;
4021 }
drh2af0b2d2002-02-21 02:25:02 +00004022 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004023 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004024 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004025 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004026 break;
4027 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004028 errCnt++;
4029 }
drhdaffd0e2001-04-11 14:28:42 +00004030 continue;
4031 }
drh9f099fd2013-08-06 14:01:46 +00004032 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004033 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004034 }
drh9f099fd2013-08-06 14:01:46 +00004035 nLine = strlen30(zLine);
4036 if( nSql+nLine+2>=nAlloc ){
4037 nAlloc = nSql+nLine+100;
4038 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004039 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004040 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004041 exit(1);
4042 }
drhdaffd0e2001-04-11 14:28:42 +00004043 }
drh9f099fd2013-08-06 14:01:46 +00004044 nSqlPrior = nSql;
4045 if( nSql==0 ){
4046 int i;
4047 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004048 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004049 memcpy(zSql, zLine+i, nLine+1-i);
4050 startline = lineno;
4051 nSql = nLine-i;
4052 }else{
4053 zSql[nSql++] = '\n';
4054 memcpy(zSql+nSql, zLine, nLine+1);
4055 nSql += nLine;
4056 }
4057 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004058 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004059 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004060 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00004061 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004062 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004063 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004064 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004065 char zPrefix[100];
4066 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004067 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004068 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004069 }else{
shane9bd1b442009-10-23 01:27:39 +00004070 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004071 }
drh7f953e22002-07-13 17:33:45 +00004072 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004073 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004074 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004075 zErrMsg = 0;
4076 }else{
shaned2bed1c2009-10-21 03:56:54 +00004077 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004078 }
drhc49f44e2006-10-26 18:15:42 +00004079 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004080 }
drhdaffd0e2001-04-11 14:28:42 +00004081 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004082 if( p->outCount ){
4083 output_reset(p);
4084 p->outCount = 0;
4085 }
drh9f099fd2013-08-06 14:01:46 +00004086 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004087 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004088 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004089 }
4090 }
drh9f099fd2013-08-06 14:01:46 +00004091 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004092 if( !_all_whitespace(zSql) ){
4093 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004094 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004095 }
drhdaffd0e2001-04-11 14:28:42 +00004096 free(zSql);
4097 }
danielk19772ac27622007-07-03 05:31:16 +00004098 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004099 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004100}
4101
drh67505e72002-04-19 12:34:06 +00004102/*
4103** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004104** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004105*/
4106static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004107 static char *home_dir = NULL;
4108 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004109
drh4ace5362014-11-10 14:42:28 +00004110#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4111 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004112 {
4113 struct passwd *pwent;
4114 uid_t uid = getuid();
4115 if( (pwent=getpwuid(uid)) != NULL) {
4116 home_dir = pwent->pw_dir;
4117 }
drh67505e72002-04-19 12:34:06 +00004118 }
4119#endif
4120
chw65d3c132007-11-12 21:09:10 +00004121#if defined(_WIN32_WCE)
4122 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4123 */
drh85e72432012-04-11 11:38:53 +00004124 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004125#else
4126
drh83905c92012-06-21 13:00:37 +00004127#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004128 if (!home_dir) {
4129 home_dir = getenv("USERPROFILE");
4130 }
4131#endif
4132
drh67505e72002-04-19 12:34:06 +00004133 if (!home_dir) {
4134 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004135 }
4136
drh83905c92012-06-21 13:00:37 +00004137#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004138 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004139 char *zDrive, *zPath;
4140 int n;
4141 zDrive = getenv("HOMEDRIVE");
4142 zPath = getenv("HOMEPATH");
4143 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004144 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004145 home_dir = malloc( n );
4146 if( home_dir==0 ) return 0;
4147 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4148 return home_dir;
4149 }
4150 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004151 }
4152#endif
4153
chw65d3c132007-11-12 21:09:10 +00004154#endif /* !_WIN32_WCE */
4155
drh67505e72002-04-19 12:34:06 +00004156 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004157 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004158 char *z = malloc( n );
4159 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004160 home_dir = z;
4161 }
drhe98d4fa2002-04-21 19:06:22 +00004162
drh67505e72002-04-19 12:34:06 +00004163 return home_dir;
4164}
4165
4166/*
4167** Read input from the file given by sqliterc_override. Or if that
4168** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004169**
4170** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004171*/
shane9bd1b442009-10-23 01:27:39 +00004172static int process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004173 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004174 const char *sqliterc_override /* Name of config file. NULL to use default */
4175){
persicom7e2dfdd2002-04-18 02:46:52 +00004176 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004177 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004178 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004179 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00004180 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004181
4182 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004183 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004184 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00004185#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00004186 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00004187#endif
shane9bd1b442009-10-23 01:27:39 +00004188 return 1;
drhe98d4fa2002-04-21 19:06:22 +00004189 }
drh2f3de322012-06-27 16:41:31 +00004190 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004191 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4192 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004193 }
drha1f9b5e2004-02-14 16:31:02 +00004194 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004195 if( in ){
drhc28490c2006-10-26 14:25:58 +00004196 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004197 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004198 }
shane9bd1b442009-10-23 01:27:39 +00004199 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004200 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004201 }
drh85e72432012-04-11 11:38:53 +00004202 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00004203 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00004204}
4205
drh67505e72002-04-19 12:34:06 +00004206/*
drhe1e38c42003-05-04 18:30:59 +00004207** Show available command line options
4208*/
4209static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004210 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004211 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004212 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004213 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004214 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004215 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004216 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004217 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004218 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004219#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4220 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4221#endif
drhcc3b4f82012-02-07 14:13:50 +00004222 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004223 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004224 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004225 " -line set output mode to 'line'\n"
4226 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004227 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004228 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004229#ifdef SQLITE_ENABLE_MULTIPLEX
4230 " -multiplex enable the multiplexor VFS\n"
4231#endif
mistachkine0d68852014-12-11 03:12:33 +00004232 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004233 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004234 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4235 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004236 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004237 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004238 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004239 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004240#ifdef SQLITE_ENABLE_VFSTRACE
4241 " -vfstrace enable tracing of all VFS calls\n"
4242#endif
drhe1e38c42003-05-04 18:30:59 +00004243;
4244static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004245 fprintf(stderr,
4246 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4247 "FILENAME is the name of an SQLite database. A new database is created\n"
4248 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004249 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004250 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004251 }else{
4252 fprintf(stderr, "Use the -help option for additional information\n");
4253 }
4254 exit(1);
4255}
4256
4257/*
drh67505e72002-04-19 12:34:06 +00004258** Initialize the state information in data
4259*/
drhdcd87a92014-08-18 13:45:42 +00004260static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004261 memset(data, 0, sizeof(*data));
4262 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004263 memcpy(data->colSeparator,SEP_Column, 2);
4264 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004265 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004266 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004267 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004268 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004269 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004270 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4271 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004272}
4273
drh98d312f2012-10-25 15:23:14 +00004274/*
drh5c7976f2014-02-10 19:59:27 +00004275** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004276*/
4277#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004278static void printBold(const char *zText){
4279 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4280 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4281 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4282 SetConsoleTextAttribute(out,
4283 FOREGROUND_RED|FOREGROUND_INTENSITY
4284 );
4285 printf("%s", zText);
4286 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004287}
4288#else
drh5c7976f2014-02-10 19:59:27 +00004289static void printBold(const char *zText){
4290 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004291}
4292#endif
4293
4294/*
drh98d312f2012-10-25 15:23:14 +00004295** Get the argument to an --option. Throw an error and die if no argument
4296** is available.
4297*/
4298static char *cmdline_option_value(int argc, char **argv, int i){
4299 if( i==argc ){
4300 fprintf(stderr, "%s: Error: missing argument to %s\n",
4301 argv[0], argv[argc-1]);
4302 exit(1);
4303 }
4304 return argv[i];
4305}
4306
drh75897232000-05-29 14:26:00 +00004307int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004308 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004309 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004310 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004311 int i;
drhc28490c2006-10-26 14:25:58 +00004312 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004313 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004314 int readStdin = 1;
4315 int nCmd = 0;
4316 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004317
drh69b30ab2014-02-27 15:11:52 +00004318#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004319 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4320 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4321 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4322 exit(1);
4323 }
drhc7181902014-02-27 15:04:13 +00004324#endif
drh047d4532015-01-18 20:30:23 +00004325 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004326 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004327 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004328 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004329 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004330
drh44c2eb12003-04-30 11:38:26 +00004331 /* Make sure we have a valid signal handler early, before anything
4332 ** else is done.
4333 */
drh4c504392000-10-16 22:06:40 +00004334#ifdef SIGINT
4335 signal(SIGINT, interrupt_handler);
4336#endif
drh44c2eb12003-04-30 11:38:26 +00004337
drhac5649a2014-11-28 13:35:03 +00004338#ifdef SQLITE_SHELL_DBNAME_PROC
4339 {
4340 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4341 ** of a C-function that will provide the name of the database file. Use
4342 ** this compile-time option to embed this shell program in larger
4343 ** applications. */
4344 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4345 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4346 warnInmemoryDb = 0;
4347 }
4348#endif
4349
drh22fbcb82004-02-01 01:22:50 +00004350 /* Do an initial pass through the command-line argument to locate
4351 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004352 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004353 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004354 */
drh98d312f2012-10-25 15:23:14 +00004355 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004356 char *z;
drhc28490c2006-10-26 14:25:58 +00004357 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004358 if( z[0]!='-' ){
4359 if( data.zDbFilename==0 ){
4360 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004361 }else{
4362 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4363 ** mean that nothing is read from stdin */
4364 readStdin = 0;
4365 nCmd++;
4366 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4367 if( azCmd==0 ){
4368 fprintf(stderr, "out of memory\n");
4369 exit(1);
4370 }
4371 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004372 }
drh98d312f2012-10-25 15:23:14 +00004373 }
drhcc3b4f82012-02-07 14:13:50 +00004374 if( z[1]=='-' ) z++;
4375 if( strcmp(z,"-separator")==0
4376 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004377 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004378 || strcmp(z,"-cmd")==0
4379 ){
drh98d312f2012-10-25 15:23:14 +00004380 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004381 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004382 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004383 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004384 /* Need to check for batch mode here to so we can avoid printing
4385 ** informational messages (like from process_sqliterc) before
4386 ** we do the actual processing of arguments later in a second pass.
4387 */
shanef69573d2009-10-24 02:06:14 +00004388 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004389 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004390#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004391 const char *zSize;
4392 sqlite3_int64 szHeap;
4393
drh98d312f2012-10-25 15:23:14 +00004394 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004395 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004396 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004397 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4398#endif
drh44dec872014-08-30 15:49:25 +00004399 }else if( strcmp(z,"-scratch")==0 ){
4400 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004401 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004402 if( sz>400000 ) sz = 400000;
4403 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004404 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004405 if( n>10 ) n = 10;
4406 if( n<1 ) n = 1;
4407 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4408 data.shellFlgs |= SHFLG_Scratch;
4409 }else if( strcmp(z,"-pagecache")==0 ){
4410 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004411 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004412 if( sz>70000 ) sz = 70000;
4413 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004414 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004415 if( n<10 ) n = 10;
4416 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4417 data.shellFlgs |= SHFLG_Pagecache;
4418 }else if( strcmp(z,"-lookaside")==0 ){
4419 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004420 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004421 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004422 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004423 if( n<0 ) n = 0;
4424 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4425 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004426#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004427 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004428 extern int vfstrace_register(
4429 const char *zTraceName,
4430 const char *zOldVfsName,
4431 int (*xOut)(const char*,void*),
4432 void *pOutArg,
4433 int makeDefault
4434 );
drh2b625e22011-03-16 17:05:28 +00004435 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004436#endif
drh6f25e892011-07-08 17:02:57 +00004437#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004438 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004439 extern int sqlite3_multiple_initialize(const char*,int);
4440 sqlite3_multiplex_initialize(0, 1);
4441#endif
drh7d9f3942013-04-03 01:26:54 +00004442 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004443 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4444 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004445 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004446 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004447 if( pVfs ){
4448 sqlite3_vfs_register(pVfs, 1);
4449 }else{
4450 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4451 exit(1);
4452 }
drh44c2eb12003-04-30 11:38:26 +00004453 }
4454 }
drh98d312f2012-10-25 15:23:14 +00004455 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004456#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004457 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004458 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004459#else
shane86f5bdb2009-10-24 02:00:07 +00004460 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4461 return 1;
drh01b41712005-08-29 23:06:23 +00004462#endif
drh98d312f2012-10-25 15:23:14 +00004463 }
4464 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004465
drh44c2eb12003-04-30 11:38:26 +00004466 /* Go ahead and open the database file if it already exists. If the
4467 ** file does not exist, delay opening it. This prevents empty database
4468 ** files from being created if a user mistypes the database name argument
4469 ** to the sqlite command-line tool.
4470 */
drhc8d74412004-08-31 23:41:26 +00004471 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004472 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004473 }
4474
drh22fbcb82004-02-01 01:22:50 +00004475 /* Process the initialization file if there is one. If no -init option
4476 ** is given on the command line, look for a file named ~/.sqliterc and
4477 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004478 */
shane86f5bdb2009-10-24 02:00:07 +00004479 rc = process_sqliterc(&data,zInitFile);
4480 if( rc>0 ){
4481 return rc;
4482 }
drh44c2eb12003-04-30 11:38:26 +00004483
drh22fbcb82004-02-01 01:22:50 +00004484 /* Make a second pass through the command-line argument and set
4485 ** options. This second pass is delayed until after the initialization
4486 ** file is processed so that the command-line arguments will override
4487 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004488 */
drh98d312f2012-10-25 15:23:14 +00004489 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004490 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004491 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004492 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004493 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004494 i++;
4495 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004496 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004497 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004498 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004499 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004500 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004501 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004502 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004503 }else if( strcmp(z,"-csv")==0 ){
4504 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004505 memcpy(data.colSeparator,",",2);
4506 }else if( strcmp(z,"-ascii")==0 ){
4507 data.mode = MODE_Ascii;
4508 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004509 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004510 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004511 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004512 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004513 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4514 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004515 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004516 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004517 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004518 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004519 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004520 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004521 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004522 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004523 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004524 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004525 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004526 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004527 }else if( strcmp(z,"-eqp")==0 ){
4528 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004529 }else if( strcmp(z,"-stats")==0 ){
4530 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004531 }else if( strcmp(z,"-scanstats")==0 ){
4532 data.scanstatsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004533 }else if( strcmp(z,"-bail")==0 ){
4534 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004535 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004536 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004537 return 0;
drhc28490c2006-10-26 14:25:58 +00004538 }else if( strcmp(z,"-interactive")==0 ){
4539 stdin_is_interactive = 1;
4540 }else if( strcmp(z,"-batch")==0 ){
4541 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004542 }else if( strcmp(z,"-heap")==0 ){
4543 i++;
drh44dec872014-08-30 15:49:25 +00004544 }else if( strcmp(z,"-scratch")==0 ){
4545 i+=2;
4546 }else if( strcmp(z,"-pagecache")==0 ){
4547 i+=2;
4548 }else if( strcmp(z,"-lookaside")==0 ){
4549 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004550 }else if( strcmp(z,"-mmap")==0 ){
4551 i++;
drha7e61d82011-03-12 17:02:57 +00004552 }else if( strcmp(z,"-vfs")==0 ){
4553 i++;
drh6f25e892011-07-08 17:02:57 +00004554#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004555 }else if( strcmp(z,"-vfstrace")==0 ){
4556 i++;
drh6f25e892011-07-08 17:02:57 +00004557#endif
4558#ifdef SQLITE_ENABLE_MULTIPLEX
4559 }else if( strcmp(z,"-multiplex")==0 ){
4560 i++;
4561#endif
drhcc3b4f82012-02-07 14:13:50 +00004562 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004563 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004564 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004565 /* Run commands that follow -cmd first and separately from commands
4566 ** that simply appear on the command-line. This seems goofy. It would
4567 ** be better if all commands ran in the order that they appear. But
4568 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004569 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004570 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004571 if( z[0]=='.' ){
4572 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004573 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004574 }else{
drh05782482013-10-24 15:20:20 +00004575 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004576 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4577 if( zErrMsg!=0 ){
4578 fprintf(stderr,"Error: %s\n", zErrMsg);
4579 if( bail_on_error ) return rc!=0 ? rc : 1;
4580 }else if( rc!=0 ){
4581 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4582 if( bail_on_error ) return rc;
4583 }
4584 }
drh1e5d0e92000-05-31 23:33:17 +00004585 }else{
shane86f5bdb2009-10-24 02:00:07 +00004586 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004587 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004588 return 1;
4589 }
4590 }
drh44c2eb12003-04-30 11:38:26 +00004591
drhac5649a2014-11-28 13:35:03 +00004592 if( !readStdin ){
4593 /* Run all arguments that do not begin with '-' as if they were separate
4594 ** command-line inputs, except for the argToSkip argument which contains
4595 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004596 */
drhac5649a2014-11-28 13:35:03 +00004597 for(i=0; i<nCmd; i++){
4598 if( azCmd[i][0]=='.' ){
4599 rc = do_meta_command(azCmd[i], &data);
4600 if( rc ) return rc==2 ? 0 : rc;
4601 }else{
4602 open_db(&data, 0);
4603 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4604 if( zErrMsg!=0 ){
4605 fprintf(stderr,"Error: %s\n", zErrMsg);
4606 return rc!=0 ? rc : 1;
4607 }else if( rc!=0 ){
4608 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4609 return rc;
4610 }
drh6ff13852001-11-25 13:18:23 +00004611 }
drh75897232000-05-29 14:26:00 +00004612 }
drhac5649a2014-11-28 13:35:03 +00004613 free(azCmd);
drh75897232000-05-29 14:26:00 +00004614 }else{
drh44c2eb12003-04-30 11:38:26 +00004615 /* Run commands received from standard input
4616 */
drhc28490c2006-10-26 14:25:58 +00004617 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004618 char *zHome;
4619 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004620 int nHistory;
drh75897232000-05-29 14:26:00 +00004621 printf(
drh743e0032011-12-12 16:51:50 +00004622 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004623 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004624 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004625 );
drhb3735912014-02-10 16:13:42 +00004626 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004627 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004628 printBold("transient in-memory database");
4629 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004630 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004631 }
drh67505e72002-04-19 12:34:06 +00004632 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004633 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004634 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004635 if( (zHistory = malloc(nHistory))!=0 ){
4636 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4637 }
drh67505e72002-04-19 12:34:06 +00004638 }
drh0ede9eb2015-01-10 16:49:23 +00004639#if HAVE_READLINE
drh67505e72002-04-19 12:34:06 +00004640 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00004641#endif
drhc28490c2006-10-26 14:25:58 +00004642 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004643 if( zHistory ){
4644 stifle_history(100);
4645 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004646 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004647 }
drhdaffd0e2001-04-11 14:28:42 +00004648 }else{
drhc28490c2006-10-26 14:25:58 +00004649 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004650 }
4651 }
drh33048c02001-10-01 14:29:22 +00004652 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004653 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004654 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004655 }
drh05782482013-10-24 15:20:20 +00004656 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004657 return rc;
drh75897232000-05-29 14:26:00 +00004658}