blob: f9a360c7b50d6b2e7b249d9dab61fdb7964ede29 [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"
drhb860bc92004-08-04 15:16:55 +00001736 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001737 " If TABLE specified, only dump tables matching\n"
1738 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001739 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001740 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001741 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001742 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001743 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001744 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001745 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001746 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001747 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001748 ".indices ?TABLE? Show names of all indices\n"
1749 " If TABLE specified, only show indices for tables\n"
1750 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001751#ifdef SQLITE_ENABLE_IOTRACE
1752 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1753#endif
drh70df4fe2006-06-13 15:12:21 +00001754#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001755 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001756#endif
drh127f9d72010-02-23 01:47:00 +00001757 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001758 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001759 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001760 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001761 " column Left-aligned columns. (See .width)\n"
1762 " html HTML <table> code\n"
1763 " insert SQL insert statements for TABLE\n"
1764 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001765 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001766 " tabs Tab-separated values\n"
1767 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001768 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001769 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001770 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001771 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001772 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001773 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001774 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001775 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001776 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001777 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001778 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001779 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001780 " If TABLE specified, only show tables matching\n"
1781 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001782 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1783 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001784 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001785 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001786 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001787 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001788 ".tables ?TABLE? List names of tables\n"
1789 " If TABLE specified, only list tables matching\n"
1790 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001791 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001792 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001793 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001794 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001795 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001796 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001797;
1798
drhdaffd0e2001-04-11 14:28:42 +00001799/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001800static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001801/*
1802** Implementation of the "readfile(X)" SQL function. The entire content
1803** of the file named X is read and returned as a BLOB. NULL is returned
1804** if the file does not exist or is unreadable.
1805*/
1806static void readfileFunc(
1807 sqlite3_context *context,
1808 int argc,
1809 sqlite3_value **argv
1810){
1811 const char *zName;
1812 FILE *in;
1813 long nIn;
1814 void *pBuf;
1815
1816 zName = (const char*)sqlite3_value_text(argv[0]);
1817 if( zName==0 ) return;
1818 in = fopen(zName, "rb");
1819 if( in==0 ) return;
1820 fseek(in, 0, SEEK_END);
1821 nIn = ftell(in);
1822 rewind(in);
1823 pBuf = sqlite3_malloc( nIn );
1824 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1825 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1826 }else{
1827 sqlite3_free(pBuf);
1828 }
1829 fclose(in);
1830}
1831
1832/*
1833** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1834** is written into file X. The number of bytes written is returned. Or
1835** NULL is returned if something goes wrong, such as being unable to open
1836** file X for writing.
1837*/
1838static void writefileFunc(
1839 sqlite3_context *context,
1840 int argc,
1841 sqlite3_value **argv
1842){
1843 FILE *out;
1844 const char *z;
drhba5b0932014-07-24 12:39:59 +00001845 sqlite3_int64 rc;
1846 const char *zFile;
1847
1848 zFile = (const char*)sqlite3_value_text(argv[0]);
1849 if( zFile==0 ) return;
1850 out = fopen(zFile, "wb");
1851 if( out==0 ) return;
1852 z = (const char*)sqlite3_value_blob(argv[1]);
1853 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001854 rc = 0;
1855 }else{
drh490fe862014-08-11 14:21:32 +00001856 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001857 }
1858 fclose(out);
1859 sqlite3_result_int64(context, rc);
1860}
drhdaffd0e2001-04-11 14:28:42 +00001861
drh75897232000-05-29 14:26:00 +00001862/*
drh44c2eb12003-04-30 11:38:26 +00001863** Make sure the database is open. If it is not, then open it. If
1864** the database fails to open, print an error message and exit.
1865*/
drhdcd87a92014-08-18 13:45:42 +00001866static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001867 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001868 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001869 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001870 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001871 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1872 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1873 shellstaticFunc, 0, 0);
1874 }
1875 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001876 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001877 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001878 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001879 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001880 }
drhc2e87a32006-06-27 15:16:14 +00001881#ifndef SQLITE_OMIT_LOAD_EXTENSION
1882 sqlite3_enable_load_extension(p->db, 1);
1883#endif
drhba5b0932014-07-24 12:39:59 +00001884 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1885 readfileFunc, 0, 0);
1886 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1887 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001888 }
1889}
1890
1891/*
drhfeac5f82004-08-01 00:10:45 +00001892** Do C-language style dequoting.
1893**
1894** \t -> tab
1895** \n -> newline
1896** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001897** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001898** \NNN -> ascii character NNN in octal
1899** \\ -> backslash
1900*/
1901static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001902 int i, j;
1903 char c;
drhc2ce0be2014-05-29 12:36:14 +00001904 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001905 for(i=j=0; (c = z[i])!=0; i++, j++){
1906 if( c=='\\' ){
1907 c = z[++i];
1908 if( c=='n' ){
1909 c = '\n';
1910 }else if( c=='t' ){
1911 c = '\t';
1912 }else if( c=='r' ){
1913 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001914 }else if( c=='\\' ){
1915 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001916 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001917 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001918 if( z[i+1]>='0' && z[i+1]<='7' ){
1919 i++;
1920 c = (c<<3) + z[i] - '0';
1921 if( z[i+1]>='0' && z[i+1]<='7' ){
1922 i++;
1923 c = (c<<3) + z[i] - '0';
1924 }
1925 }
1926 }
1927 }
1928 z[j] = c;
1929 }
drhc2ce0be2014-05-29 12:36:14 +00001930 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001931}
1932
1933/*
drh348d19c2013-06-03 12:47:43 +00001934** Return the value of a hexadecimal digit. Return -1 if the input
1935** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001936*/
drh348d19c2013-06-03 12:47:43 +00001937static int hexDigitValue(char c){
1938 if( c>='0' && c<='9' ) return c - '0';
1939 if( c>='a' && c<='f' ) return c - 'a' + 10;
1940 if( c>='A' && c<='F' ) return c - 'A' + 10;
1941 return -1;
drhc28490c2006-10-26 14:25:58 +00001942}
1943
1944/*
drh7d9f3942013-04-03 01:26:54 +00001945** Interpret zArg as an integer value, possibly with suffixes.
1946*/
1947static sqlite3_int64 integerValue(const char *zArg){
1948 sqlite3_int64 v = 0;
1949 static const struct { char *zSuffix; int iMult; } aMult[] = {
1950 { "KiB", 1024 },
1951 { "MiB", 1024*1024 },
1952 { "GiB", 1024*1024*1024 },
1953 { "KB", 1000 },
1954 { "MB", 1000000 },
1955 { "GB", 1000000000 },
1956 { "K", 1000 },
1957 { "M", 1000000 },
1958 { "G", 1000000000 },
1959 };
1960 int i;
1961 int isNeg = 0;
1962 if( zArg[0]=='-' ){
1963 isNeg = 1;
1964 zArg++;
1965 }else if( zArg[0]=='+' ){
1966 zArg++;
1967 }
drh348d19c2013-06-03 12:47:43 +00001968 if( zArg[0]=='0' && zArg[1]=='x' ){
1969 int x;
1970 zArg += 2;
1971 while( (x = hexDigitValue(zArg[0]))>=0 ){
1972 v = (v<<4) + x;
1973 zArg++;
1974 }
1975 }else{
1976 while( IsDigit(zArg[0]) ){
1977 v = v*10 + zArg[0] - '0';
1978 zArg++;
1979 }
drh7d9f3942013-04-03 01:26:54 +00001980 }
drhc2bed0a2013-05-24 11:57:50 +00001981 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001982 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1983 v *= aMult[i].iMult;
1984 break;
1985 }
1986 }
1987 return isNeg? -v : v;
1988}
1989
1990/*
drh348d19c2013-06-03 12:47:43 +00001991** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1992** for TRUE and FALSE. Return the integer value if appropriate.
1993*/
1994static int booleanValue(char *zArg){
1995 int i;
1996 if( zArg[0]=='0' && zArg[1]=='x' ){
1997 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1998 }else{
1999 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2000 }
2001 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2002 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2003 return 1;
2004 }
2005 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2006 return 0;
2007 }
2008 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2009 zArg);
2010 return 0;
2011}
2012
2013/*
drh42f64e52012-04-04 16:56:23 +00002014** Close an output file, assuming it is not stderr or stdout
2015*/
2016static void output_file_close(FILE *f){
2017 if( f && f!=stdout && f!=stderr ) fclose(f);
2018}
2019
2020/*
2021** Try to open an output file. The names "stdout" and "stderr" are
2022** recognized and do the right thing. NULL is returned if the output
2023** filename is "off".
2024*/
2025static FILE *output_file_open(const char *zFile){
2026 FILE *f;
2027 if( strcmp(zFile,"stdout")==0 ){
2028 f = stdout;
2029 }else if( strcmp(zFile, "stderr")==0 ){
2030 f = stderr;
2031 }else if( strcmp(zFile, "off")==0 ){
2032 f = 0;
2033 }else{
2034 f = fopen(zFile, "wb");
2035 if( f==0 ){
2036 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2037 }
2038 }
2039 return f;
2040}
2041
2042/*
2043** A routine for handling output from sqlite3_trace().
2044*/
2045static void sql_trace_callback(void *pArg, const char *z){
2046 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002047 if( f ){
2048 int i = (int)strlen(z);
2049 while( i>0 && z[i-1]==';' ){ i--; }
2050 fprintf(f, "%.*s;\n", i, z);
2051 }
drh42f64e52012-04-04 16:56:23 +00002052}
2053
2054/*
drhd8621b92012-04-17 09:09:33 +00002055** A no-op routine that runs with the ".breakpoint" doc-command. This is
2056** a useful spot to set a debugger breakpoint.
2057*/
2058static void test_breakpoint(void){
2059 static int nCall = 0;
2060 nCall++;
2061}
2062
2063/*
mistachkin636bf9f2014-07-19 20:15:16 +00002064** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002065*/
mistachkin636bf9f2014-07-19 20:15:16 +00002066typedef struct ImportCtx ImportCtx;
2067struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002068 const char *zFile; /* Name of the input file */
2069 FILE *in; /* Read the CSV text from this input stream */
2070 char *z; /* Accumulated text for a field */
2071 int n; /* Number of bytes in z */
2072 int nAlloc; /* Space allocated for z[] */
2073 int nLine; /* Current line number */
2074 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002075 int cColSep; /* The column separator character. (Usually ",") */
2076 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002077};
2078
2079/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002080static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002081 if( p->n+1>=p->nAlloc ){
2082 p->nAlloc += p->nAlloc + 100;
2083 p->z = sqlite3_realloc(p->z, p->nAlloc);
2084 if( p->z==0 ){
2085 fprintf(stderr, "out of memory\n");
2086 exit(1);
2087 }
2088 }
2089 p->z[p->n++] = (char)c;
2090}
2091
2092/* Read a single field of CSV text. Compatible with rfc4180 and extended
2093** with the option of having a separator other than ",".
2094**
2095** + Input comes from p->in.
2096** + Store results in p->z of length p->n. Space to hold p->z comes
2097** from sqlite3_malloc().
mistachkin636bf9f2014-07-19 20:15:16 +00002098** + Use p->cSep as the column separator. The default is ",".
2099** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002100** + Keep track of the line number in p->nLine.
2101** + Store the character that terminates the field in p->cTerm. Store
2102** EOF on end-of-file.
2103** + Report syntax errors on stderr
2104*/
mistachkin636bf9f2014-07-19 20:15:16 +00002105static char *csv_read_one_field(ImportCtx *p){
2106 int c;
2107 int cSep = p->cColSep;
2108 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002109 p->n = 0;
2110 c = fgetc(p->in);
2111 if( c==EOF || seenInterrupt ){
2112 p->cTerm = EOF;
2113 return 0;
2114 }
2115 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002116 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002117 int startLine = p->nLine;
2118 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002119 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002120 while( 1 ){
2121 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002122 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002123 if( c==cQuote ){
2124 if( pc==cQuote ){
2125 pc = 0;
2126 continue;
2127 }
2128 }
2129 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002130 || (c==rSep && pc==cQuote)
2131 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002132 || (c==EOF && pc==cQuote)
2133 ){
2134 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002135 p->cTerm = c;
2136 break;
2137 }
2138 if( pc==cQuote && c!='\r' ){
2139 fprintf(stderr, "%s:%d: unescaped %c character\n",
2140 p->zFile, p->nLine, cQuote);
2141 }
2142 if( c==EOF ){
2143 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2144 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002145 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002146 break;
2147 }
mistachkin636bf9f2014-07-19 20:15:16 +00002148 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002149 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002150 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002151 }
drhdb95f682013-06-26 22:46:00 +00002152 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002153 while( c!=EOF && c!=cSep && c!=rSep ){
2154 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002155 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002156 }
mistachkin636bf9f2014-07-19 20:15:16 +00002157 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002158 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002159 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002160 }
drhdb95f682013-06-26 22:46:00 +00002161 p->cTerm = c;
2162 }
drh8dd675e2013-07-12 21:09:24 +00002163 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002164 return p->z;
2165}
2166
mistachkin636bf9f2014-07-19 20:15:16 +00002167/* Read a single field of ASCII delimited text.
2168**
2169** + Input comes from p->in.
2170** + Store results in p->z of length p->n. Space to hold p->z comes
2171** from sqlite3_malloc().
2172** + Use p->cSep as the column separator. The default is "\x1F".
2173** + Use p->rSep as the row separator. The default is "\x1E".
2174** + Keep track of the row number in p->nLine.
2175** + Store the character that terminates the field in p->cTerm. Store
2176** EOF on end-of-file.
2177** + Report syntax errors on stderr
2178*/
2179static char *ascii_read_one_field(ImportCtx *p){
2180 int c;
2181 int cSep = p->cColSep;
2182 int rSep = p->cRowSep;
2183 p->n = 0;
2184 c = fgetc(p->in);
2185 if( c==EOF || seenInterrupt ){
2186 p->cTerm = EOF;
2187 return 0;
2188 }
2189 while( c!=EOF && c!=cSep && c!=rSep ){
2190 import_append_char(p, c);
2191 c = fgetc(p->in);
2192 }
2193 if( c==rSep ){
2194 p->nLine++;
2195 }
2196 p->cTerm = c;
2197 if( p->z ) p->z[p->n] = 0;
2198 return p->z;
2199}
2200
drhdb95f682013-06-26 22:46:00 +00002201/*
drh4bbcf102014-02-06 02:46:08 +00002202** Try to transfer data for table zTable. If an error is seen while
2203** moving forward, try to go backwards. The backwards movement won't
2204** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002205*/
mistachkine31ae902014-02-06 01:15:29 +00002206static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002207 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002208 sqlite3 *newDb,
2209 const char *zTable
2210){
2211 sqlite3_stmt *pQuery = 0;
2212 sqlite3_stmt *pInsert = 0;
2213 char *zQuery = 0;
2214 char *zInsert = 0;
2215 int rc;
2216 int i, j, n;
2217 int nTable = (int)strlen(zTable);
2218 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002219 int cnt = 0;
2220 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002221
2222 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2223 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2224 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002225 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002226 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2227 zQuery);
2228 goto end_data_xfer;
2229 }
2230 n = sqlite3_column_count(pQuery);
2231 zInsert = sqlite3_malloc(200 + nTable + n*3);
2232 if( zInsert==0 ){
2233 fprintf(stderr, "out of memory\n");
2234 goto end_data_xfer;
2235 }
2236 sqlite3_snprintf(200+nTable,zInsert,
2237 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2238 i = (int)strlen(zInsert);
2239 for(j=1; j<n; j++){
2240 memcpy(zInsert+i, ",?", 2);
2241 i += 2;
2242 }
2243 memcpy(zInsert+i, ");", 3);
2244 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2245 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002246 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002247 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2248 zQuery);
2249 goto end_data_xfer;
2250 }
2251 for(k=0; k<2; k++){
2252 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2253 for(i=0; i<n; i++){
2254 switch( sqlite3_column_type(pQuery, i) ){
2255 case SQLITE_NULL: {
2256 sqlite3_bind_null(pInsert, i+1);
2257 break;
2258 }
2259 case SQLITE_INTEGER: {
2260 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2261 break;
2262 }
2263 case SQLITE_FLOAT: {
2264 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2265 break;
2266 }
2267 case SQLITE_TEXT: {
2268 sqlite3_bind_text(pInsert, i+1,
2269 (const char*)sqlite3_column_text(pQuery,i),
2270 -1, SQLITE_STATIC);
2271 break;
2272 }
2273 case SQLITE_BLOB: {
2274 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2275 sqlite3_column_bytes(pQuery,i),
2276 SQLITE_STATIC);
2277 break;
2278 }
2279 }
2280 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002281 rc = sqlite3_step(pInsert);
2282 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2283 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2284 sqlite3_errmsg(newDb));
2285 }
drh3350ce92014-02-06 00:49:12 +00002286 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002287 cnt++;
2288 if( (cnt%spinRate)==0 ){
2289 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2290 fflush(stdout);
2291 }
drh3350ce92014-02-06 00:49:12 +00002292 } /* End while */
2293 if( rc==SQLITE_DONE ) break;
2294 sqlite3_finalize(pQuery);
2295 sqlite3_free(zQuery);
2296 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2297 zTable);
2298 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2299 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002300 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2301 break;
drh3350ce92014-02-06 00:49:12 +00002302 }
2303 } /* End for(k=0...) */
2304
2305end_data_xfer:
2306 sqlite3_finalize(pQuery);
2307 sqlite3_finalize(pInsert);
2308 sqlite3_free(zQuery);
2309 sqlite3_free(zInsert);
2310}
2311
2312
2313/*
2314** Try to transfer all rows of the schema that match zWhere. For
2315** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002316** If an error is encountered while moving forward through the
2317** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002318*/
mistachkine31ae902014-02-06 01:15:29 +00002319static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002320 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002321 sqlite3 *newDb,
2322 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002323 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002324){
2325 sqlite3_stmt *pQuery = 0;
2326 char *zQuery = 0;
2327 int rc;
2328 const unsigned char *zName;
2329 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002330 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002331
2332 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2333 " WHERE %s", zWhere);
2334 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2335 if( rc ){
2336 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2337 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2338 zQuery);
2339 goto end_schema_xfer;
2340 }
2341 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2342 zName = sqlite3_column_text(pQuery, 0);
2343 zSql = sqlite3_column_text(pQuery, 1);
2344 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002345 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2346 if( zErrMsg ){
2347 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2348 sqlite3_free(zErrMsg);
2349 zErrMsg = 0;
2350 }
drh3350ce92014-02-06 00:49:12 +00002351 if( xForEach ){
2352 xForEach(p, newDb, (const char*)zName);
2353 }
2354 printf("done\n");
2355 }
2356 if( rc!=SQLITE_DONE ){
2357 sqlite3_finalize(pQuery);
2358 sqlite3_free(zQuery);
2359 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2360 " WHERE %s ORDER BY rowid DESC", zWhere);
2361 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2362 if( rc ){
2363 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2364 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2365 zQuery);
2366 goto end_schema_xfer;
2367 }
2368 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2369 zName = sqlite3_column_text(pQuery, 0);
2370 zSql = sqlite3_column_text(pQuery, 1);
2371 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002372 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2373 if( zErrMsg ){
2374 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2375 sqlite3_free(zErrMsg);
2376 zErrMsg = 0;
2377 }
drh3350ce92014-02-06 00:49:12 +00002378 if( xForEach ){
2379 xForEach(p, newDb, (const char*)zName);
2380 }
2381 printf("done\n");
2382 }
2383 }
2384end_schema_xfer:
2385 sqlite3_finalize(pQuery);
2386 sqlite3_free(zQuery);
2387}
2388
2389/*
2390** Open a new database file named "zNewDb". Try to recover as much information
2391** as possible out of the main database (which might be corrupt) and write it
2392** into zNewDb.
2393*/
drhdcd87a92014-08-18 13:45:42 +00002394static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002395 int rc;
2396 sqlite3 *newDb = 0;
2397 if( access(zNewDb,0)==0 ){
2398 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2399 return;
2400 }
2401 rc = sqlite3_open(zNewDb, &newDb);
2402 if( rc ){
2403 fprintf(stderr, "Cannot create output database: %s\n",
2404 sqlite3_errmsg(newDb));
2405 }else{
drh54d0d2d2014-04-03 00:32:13 +00002406 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002407 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002408 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2409 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002410 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002411 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002412 }
2413 sqlite3_close(newDb);
2414}
2415
2416/*
drhc2ce0be2014-05-29 12:36:14 +00002417** Change the output file back to stdout
2418*/
drhdcd87a92014-08-18 13:45:42 +00002419static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002420 if( p->outfile[0]=='|' ){
2421 pclose(p->out);
2422 }else{
2423 output_file_close(p->out);
2424 }
2425 p->outfile[0] = 0;
2426 p->out = stdout;
2427}
2428
2429/*
drh75897232000-05-29 14:26:00 +00002430** If an input line begins with "." then invoke this routine to
2431** process that line.
drh67505e72002-04-19 12:34:06 +00002432**
drh47ad6842006-11-08 12:25:42 +00002433** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002434*/
drhdcd87a92014-08-18 13:45:42 +00002435static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002436 int i = 1;
2437 int nArg = 0;
2438 int n, c;
drh67505e72002-04-19 12:34:06 +00002439 int rc = 0;
drh75897232000-05-29 14:26:00 +00002440 char *azArg[50];
2441
2442 /* Parse the input line into tokens.
2443 */
2444 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002445 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002446 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002447 if( zLine[i]=='\'' || zLine[i]=='"' ){
2448 int delim = zLine[i++];
2449 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002450 while( zLine[i] && zLine[i]!=delim ){
2451 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2452 i++;
2453 }
drh75897232000-05-29 14:26:00 +00002454 if( zLine[i]==delim ){
2455 zLine[i++] = 0;
2456 }
drhfeac5f82004-08-01 00:10:45 +00002457 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002458 }else{
2459 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002460 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002461 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002462 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002463 }
2464 }
2465
2466 /* Process the input line.
2467 */
shane9bd1b442009-10-23 01:27:39 +00002468 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002469 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002470 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002471 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2472 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2473 ){
drhbc46f022013-01-23 18:53:23 +00002474 const char *zDestFile = 0;
2475 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002476 sqlite3 *pDest;
2477 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002478 int j;
2479 for(j=1; j<nArg; j++){
2480 const char *z = azArg[j];
2481 if( z[0]=='-' ){
2482 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002483 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002484 {
2485 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2486 return 1;
2487 }
2488 }else if( zDestFile==0 ){
2489 zDestFile = azArg[j];
2490 }else if( zDb==0 ){
2491 zDb = zDestFile;
2492 zDestFile = azArg[j];
2493 }else{
2494 fprintf(stderr, "too many arguments to .backup\n");
2495 return 1;
2496 }
drh9ff849f2009-02-04 20:55:57 +00002497 }
drhbc46f022013-01-23 18:53:23 +00002498 if( zDestFile==0 ){
2499 fprintf(stderr, "missing FILENAME argument on .backup\n");
2500 return 1;
2501 }
2502 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002503 rc = sqlite3_open(zDestFile, &pDest);
2504 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002505 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002506 sqlite3_close(pDest);
2507 return 1;
2508 }
drh05782482013-10-24 15:20:20 +00002509 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002510 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2511 if( pBackup==0 ){
2512 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2513 sqlite3_close(pDest);
2514 return 1;
2515 }
2516 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2517 sqlite3_backup_finish(pBackup);
2518 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002519 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002520 }else{
2521 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002522 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002523 }
2524 sqlite3_close(pDest);
2525 }else
2526
drhc2ce0be2014-05-29 12:36:14 +00002527 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2528 if( nArg==2 ){
2529 bail_on_error = booleanValue(azArg[1]);
2530 }else{
2531 fprintf(stderr, "Usage: .bail on|off\n");
2532 rc = 1;
2533 }
drhc49f44e2006-10-26 18:15:42 +00002534 }else
2535
drhd8621b92012-04-17 09:09:33 +00002536 /* The undocumented ".breakpoint" command causes a call to the no-op
2537 ** routine named test_breakpoint().
2538 */
2539 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2540 test_breakpoint();
2541 }else
2542
drhc2ce0be2014-05-29 12:36:14 +00002543 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2544 if( nArg==2 ){
2545 tryToClone(p, azArg[1]);
2546 }else{
2547 fprintf(stderr, "Usage: .clone FILENAME\n");
2548 rc = 1;
2549 }
mistachkine31ae902014-02-06 01:15:29 +00002550 }else
2551
drhc2ce0be2014-05-29 12:36:14 +00002552 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002553 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002554 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002555 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002556 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002557 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002558 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002559 data.colWidth[0] = 3;
2560 data.colWidth[1] = 15;
2561 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002562 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002563 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002564 if( zErrMsg ){
2565 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002566 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002567 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002568 }
2569 }else
2570
drhc2ce0be2014-05-29 12:36:14 +00002571 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002572 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002573 /* When playing back a "dump", the content might appear in an order
2574 ** which causes immediate foreign key constraints to be violated.
2575 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002576 if( nArg!=1 && nArg!=2 ){
2577 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2578 rc = 1;
2579 goto meta_command_exit;
2580 }
drhf1dfc4f2009-09-23 15:51:35 +00002581 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002582 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002583 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002584 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002585 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002586 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002587 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002588 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002589 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002590 );
2591 run_schema_dump_query(p,
2592 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002593 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002594 );
drh2f464a02011-10-13 00:41:49 +00002595 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002596 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002597 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002598 );
drh4c653a02000-06-07 01:27:47 +00002599 }else{
2600 int i;
drhdd3d4592004-08-30 01:54:05 +00002601 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002602 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002603 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002604 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002605 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002606 " AND sql NOT NULL");
2607 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002608 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002609 "WHERE sql NOT NULL"
2610 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002611 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002612 );
danielk1977bc6ada42004-06-30 08:20:16 +00002613 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002614 }
2615 }
drh45e29d82006-11-20 16:21:10 +00002616 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002617 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002618 p->writableSchema = 0;
2619 }
drh56197952011-10-13 16:30:13 +00002620 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2621 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002622 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002623 }else
drh75897232000-05-29 14:26:00 +00002624
drhc2ce0be2014-05-29 12:36:14 +00002625 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2626 if( nArg==2 ){
2627 p->echoOn = booleanValue(azArg[1]);
2628 }else{
2629 fprintf(stderr, "Usage: .echo on|off\n");
2630 rc = 1;
2631 }
drhdaffd0e2001-04-11 14:28:42 +00002632 }else
2633
drhc2ce0be2014-05-29 12:36:14 +00002634 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2635 if( nArg==2 ){
2636 p->autoEQP = booleanValue(azArg[1]);
2637 }else{
2638 fprintf(stderr, "Usage: .eqp on|off\n");
2639 rc = 1;
2640 }
drhefbf3b12014-02-28 20:47:24 +00002641 }else
2642
drhd3ac7d92013-01-25 18:33:43 +00002643 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002644 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002645 rc = 2;
drh75897232000-05-29 14:26:00 +00002646 }else
2647
drhc2ce0be2014-05-29 12:36:14 +00002648 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002649 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002650 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002651 if(!p->normalMode.valid) {
2652 p->normalMode.valid = 1;
2653 p->normalMode.mode = p->mode;
2654 p->normalMode.showHeader = p->showHeader;
2655 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002656 }
2657 /* We could put this code under the !p->explainValid
2658 ** condition so that it does not execute if we are already in
2659 ** explain mode. However, always executing it allows us an easy
2660 ** was to reset to explain mode in case the user previously
2661 ** did an .explain followed by a .width, .mode or .header
2662 ** command.
2663 */
danielk19770d78bae2008-01-03 07:09:48 +00002664 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002665 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002666 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002667 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002668 p->colWidth[1] = 13; /* opcode */
2669 p->colWidth[2] = 4; /* P1 */
2670 p->colWidth[3] = 4; /* P2 */
2671 p->colWidth[4] = 4; /* P3 */
2672 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002673 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002674 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002675 }else if (p->normalMode.valid) {
2676 p->normalMode.valid = 0;
2677 p->mode = p->normalMode.mode;
2678 p->showHeader = p->normalMode.showHeader;
2679 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002680 }
drh75897232000-05-29 14:26:00 +00002681 }else
2682
drhc1971542014-06-23 23:28:13 +00002683 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002684 ShellState data;
drhc1971542014-06-23 23:28:13 +00002685 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002686 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002687 if( nArg!=1 ){
2688 fprintf(stderr, "Usage: .fullschema\n");
2689 rc = 1;
2690 goto meta_command_exit;
2691 }
2692 open_db(p, 0);
2693 memcpy(&data, p, sizeof(data));
2694 data.showHeader = 0;
2695 data.mode = MODE_Semi;
2696 rc = sqlite3_exec(p->db,
2697 "SELECT sql FROM"
2698 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2699 " FROM sqlite_master UNION ALL"
2700 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002701 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002702 "ORDER BY rowid",
2703 callback, &data, &zErrMsg
2704 );
drh56f674c2014-07-18 14:43:29 +00002705 if( rc==SQLITE_OK ){
2706 sqlite3_stmt *pStmt;
2707 rc = sqlite3_prepare_v2(p->db,
2708 "SELECT rowid FROM sqlite_master"
2709 " WHERE name GLOB 'sqlite_stat[134]'",
2710 -1, &pStmt, 0);
2711 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2712 sqlite3_finalize(pStmt);
2713 }
2714 if( doStats==0 ){
2715 fprintf(p->out, "/* No STAT tables available */\n");
2716 }else{
2717 fprintf(p->out, "ANALYZE sqlite_master;\n");
2718 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2719 callback, &data, &zErrMsg);
2720 data.mode = MODE_Insert;
2721 data.zDestTable = "sqlite_stat1";
2722 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2723 shell_callback, &data,&zErrMsg);
2724 data.zDestTable = "sqlite_stat3";
2725 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2726 shell_callback, &data,&zErrMsg);
2727 data.zDestTable = "sqlite_stat4";
2728 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2729 shell_callback, &data, &zErrMsg);
2730 fprintf(p->out, "ANALYZE sqlite_master;\n");
2731 }
drhc1971542014-06-23 23:28:13 +00002732 }else
2733
drhc2ce0be2014-05-29 12:36:14 +00002734 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2735 if( nArg==2 ){
2736 p->showHeader = booleanValue(azArg[1]);
2737 }else{
2738 fprintf(stderr, "Usage: .headers on|off\n");
2739 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002740 }
drh75897232000-05-29 14:26:00 +00002741 }else
2742
drhc2ce0be2014-05-29 12:36:14 +00002743 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2744 fprintf(p->out, "%s", zHelp);
2745 }else
2746
2747 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002748 char *zTable; /* Insert data into this table */
2749 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002750 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002751 int nCol; /* Number of columns in the table */
2752 int nByte; /* Number of bytes in an SQL string */
2753 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002754 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002755 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002756 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002757 ImportCtx sCtx; /* Reader context */
mistachkin486fd432014-07-24 22:20:23 +00002758 char *(*xRead)(ImportCtx*); /* Procedure to read one value */
drh5bde8162013-06-27 14:07:53 +00002759 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002760
drhc2ce0be2014-05-29 12:36:14 +00002761 if( nArg!=3 ){
2762 fprintf(stderr, "Usage: .import FILE TABLE\n");
2763 goto meta_command_exit;
2764 }
drh01f37542014-05-31 15:43:33 +00002765 zFile = azArg[1];
2766 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002767 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002768 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002769 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002770 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002771 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002772 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002773 return 1;
drhfeac5f82004-08-01 00:10:45 +00002774 }
drhdb95f682013-06-26 22:46:00 +00002775 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002776 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002777 " for import\n");
2778 return 1;
2779 }
mistachkin636bf9f2014-07-19 20:15:16 +00002780 nSep = strlen30(p->rowSeparator);
2781 if( nSep==0 ){
2782 fprintf(stderr, "Error: non-null row separator required for import\n");
2783 return 1;
2784 }
mistachkine0d68852014-12-11 03:12:33 +00002785 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2786 /* When importing CSV (only), if the row separator is set to the
2787 ** default output row separator, change it to the default input
2788 ** row separator. This avoids having to maintain different input
2789 ** and output row separators. */
2790 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2791 nSep = strlen30(p->rowSeparator);
2792 }
mistachkin636bf9f2014-07-19 20:15:16 +00002793 if( nSep>1 ){
2794 fprintf(stderr, "Error: multi-character row separators not allowed"
2795 " for import\n");
2796 return 1;
2797 }
2798 sCtx.zFile = zFile;
2799 sCtx.nLine = 1;
2800 if( sCtx.zFile[0]=='|' ){
2801 sCtx.in = popen(sCtx.zFile+1, "r");
2802 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00002803 xCloser = pclose;
2804 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002805 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00002806 xCloser = fclose;
2807 }
mistachkin636bf9f2014-07-19 20:15:16 +00002808 if( p->mode==MODE_Ascii ){
2809 xRead = ascii_read_one_field;
2810 }else{
2811 xRead = csv_read_one_field;
2812 }
2813 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002814 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002815 return 1;
2816 }
mistachkin636bf9f2014-07-19 20:15:16 +00002817 sCtx.cColSep = p->colSeparator[0];
2818 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00002819 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002820 if( zSql==0 ){
2821 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002822 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002823 return 1;
2824 }
drh4f21c4a2008-12-10 22:15:00 +00002825 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002826 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002827 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
drhdb95f682013-06-26 22:46:00 +00002828 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2829 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2830 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00002831 while( xRead(&sCtx) ){
2832 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00002833 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00002834 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00002835 }
drh5bde8162013-06-27 14:07:53 +00002836 if( cSep=='(' ){
2837 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00002838 sqlite3_free(sCtx.z);
2839 xCloser(sCtx.in);
2840 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00002841 return 1;
2842 }
drhdb95f682013-06-26 22:46:00 +00002843 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2844 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2845 sqlite3_free(zCreate);
2846 if( rc ){
2847 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2848 sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002849 sqlite3_free(sCtx.z);
2850 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00002851 return 1;
2852 }
drhc7181902014-02-27 15:04:13 +00002853 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002854 }
drhfeac5f82004-08-01 00:10:45 +00002855 sqlite3_free(zSql);
2856 if( rc ){
shane916f9612009-10-23 00:37:15 +00002857 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002858 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002859 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002860 return 1;
drhfeac5f82004-08-01 00:10:45 +00002861 }
shane916f9612009-10-23 00:37:15 +00002862 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002863 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002864 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002865 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002866 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002867 if( zSql==0 ){
2868 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002869 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002870 return 1;
2871 }
drhdb95f682013-06-26 22:46:00 +00002872 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002873 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002874 for(i=1; i<nCol; i++){
2875 zSql[j++] = ',';
2876 zSql[j++] = '?';
2877 }
2878 zSql[j++] = ')';
2879 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00002880 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002881 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002882 if( rc ){
2883 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002884 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00002885 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00002886 return 1;
drhfeac5f82004-08-01 00:10:45 +00002887 }
drh2d463112013-08-06 14:36:36 +00002888 needCommit = sqlite3_get_autocommit(db);
2889 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00002890 do{
mistachkin636bf9f2014-07-19 20:15:16 +00002891 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00002892 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00002893 char *z = xRead(&sCtx);
2894 /*
2895 ** Did we reach end-of-file before finding any columns?
2896 ** If so, stop instead of NULL filling the remaining columns.
2897 */
drhdb95f682013-06-26 22:46:00 +00002898 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00002899 /*
2900 ** Did we reach end-of-file OR end-of-line before finding any
2901 ** columns in ASCII mode? If so, stop instead of NULL filling
2902 ** the remaining columns.
2903 */
2904 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00002905 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00002906 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00002907 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2908 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00002909 sCtx.zFile, startLine, nCol, i+1);
drhdb95f682013-06-26 22:46:00 +00002910 i++;
mistachkin6fe03382014-06-16 22:45:28 +00002911 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002912 }
drhfeac5f82004-08-01 00:10:45 +00002913 }
mistachkin636bf9f2014-07-19 20:15:16 +00002914 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00002915 do{
mistachkin636bf9f2014-07-19 20:15:16 +00002916 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00002917 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00002918 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00002919 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2920 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00002921 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002922 }
drhdb95f682013-06-26 22:46:00 +00002923 if( i>=nCol ){
2924 sqlite3_step(pStmt);
2925 rc = sqlite3_reset(pStmt);
2926 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00002927 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
drhdb95f682013-06-26 22:46:00 +00002928 sqlite3_errmsg(db));
2929 }
2930 }
mistachkin636bf9f2014-07-19 20:15:16 +00002931 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00002932
mistachkin636bf9f2014-07-19 20:15:16 +00002933 xCloser(sCtx.in);
2934 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00002935 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00002936 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002937 }else
2938
drhc2ce0be2014-05-29 12:36:14 +00002939 if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002940 ShellState data;
drh75897232000-05-29 14:26:00 +00002941 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002942 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00002943 memcpy(&data, p, sizeof(data));
2944 data.showHeader = 0;
2945 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002946 if( nArg==1 ){
2947 rc = sqlite3_exec(p->db,
2948 "SELECT name FROM sqlite_master "
2949 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2950 "UNION ALL "
2951 "SELECT name FROM sqlite_temp_master "
2952 "WHERE type='index' "
2953 "ORDER BY 1",
2954 callback, &data, &zErrMsg
2955 );
drhc2ce0be2014-05-29 12:36:14 +00002956 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00002957 zShellStatic = azArg[1];
2958 rc = sqlite3_exec(p->db,
2959 "SELECT name FROM sqlite_master "
2960 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2961 "UNION ALL "
2962 "SELECT name FROM sqlite_temp_master "
2963 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2964 "ORDER BY 1",
2965 callback, &data, &zErrMsg
2966 );
2967 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00002968 }else{
2969 fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
2970 rc = 1;
2971 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00002972 }
drh75897232000-05-29 14:26:00 +00002973 if( zErrMsg ){
2974 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002975 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002976 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002977 }else if( rc != SQLITE_OK ){
2978 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2979 rc = 1;
drh75897232000-05-29 14:26:00 +00002980 }
2981 }else
2982
drhae5e4452007-05-03 17:18:36 +00002983#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002984 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002985 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002986 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2987 iotrace = 0;
2988 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002989 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002990 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002991 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002992 iotrace = stdout;
2993 }else{
2994 iotrace = fopen(azArg[1], "w");
2995 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002996 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002997 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002998 rc = 1;
drhb0603412007-02-28 04:47:26 +00002999 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003000 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003001 }
3002 }
3003 }else
drhae5e4452007-05-03 17:18:36 +00003004#endif
drhb0603412007-02-28 04:47:26 +00003005
drh70df4fe2006-06-13 15:12:21 +00003006#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003007 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003008 const char *zFile, *zProc;
3009 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003010 if( nArg<2 ){
3011 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3012 rc = 1;
3013 goto meta_command_exit;
3014 }
drh1e397f82006-06-08 15:28:43 +00003015 zFile = azArg[1];
3016 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003017 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003018 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3019 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003020 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003021 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003022 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003023 }
3024 }else
drh70df4fe2006-06-13 15:12:21 +00003025#endif
drh1e397f82006-06-08 15:28:43 +00003026
drhc2ce0be2014-05-29 12:36:14 +00003027 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3028 if( nArg!=2 ){
3029 fprintf(stderr, "Usage: .log FILENAME\n");
3030 rc = 1;
3031 }else{
3032 const char *zFile = azArg[1];
3033 output_file_close(p->pLog);
3034 p->pLog = output_file_open(zFile);
3035 }
drh127f9d72010-02-23 01:47:00 +00003036 }else
3037
drhc2ce0be2014-05-29 12:36:14 +00003038 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3039 const char *zMode = nArg>=2 ? azArg[1] : "";
3040 int n2 = (int)strlen(zMode);
3041 int c2 = zMode[0];
3042 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003043 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003044 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003045 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003046 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003047 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003048 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003049 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003050 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003051 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003052 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003053 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003054 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003055 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003056 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003057 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003058 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003059 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003060 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003061 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003062 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003063 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3064 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003065 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3066 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003067 }else {
shane9bd1b442009-10-23 01:27:39 +00003068 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003069 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003070 rc = 1;
drh75897232000-05-29 14:26:00 +00003071 }
3072 }else
3073
drhc2ce0be2014-05-29 12:36:14 +00003074 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3075 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003076 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3077 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003078 }else{
3079 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003080 rc = 1;
3081 }
3082 }else
3083
drh05782482013-10-24 15:20:20 +00003084 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3085 sqlite3 *savedDb = p->db;
3086 const char *zSavedFilename = p->zDbFilename;
3087 char *zNewFilename = 0;
3088 p->db = 0;
3089 if( nArg>=2 ){
3090 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3091 }
3092 open_db(p, 1);
3093 if( p->db!=0 ){
3094 sqlite3_close(savedDb);
3095 sqlite3_free(p->zFreeOnClose);
3096 p->zFreeOnClose = zNewFilename;
3097 }else{
3098 sqlite3_free(zNewFilename);
3099 p->db = savedDb;
3100 p->zDbFilename = zSavedFilename;
3101 }
3102 }else
3103
drhc2ce0be2014-05-29 12:36:14 +00003104 if( c=='o'
3105 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3106 ){
3107 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3108 if( nArg>2 ){
3109 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3110 rc = 1;
3111 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003112 }
drhc2ce0be2014-05-29 12:36:14 +00003113 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3114 if( nArg<2 ){
3115 fprintf(stderr, "Usage: .once FILE\n");
3116 rc = 1;
3117 goto meta_command_exit;
3118 }
3119 p->outCount = 2;
3120 }else{
3121 p->outCount = 0;
3122 }
3123 output_reset(p);
3124 if( zFile[0]=='|' ){
3125 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003126 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003127 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003128 p->out = stdout;
3129 rc = 1;
3130 }else{
drhc2ce0be2014-05-29 12:36:14 +00003131 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003132 }
drh75897232000-05-29 14:26:00 +00003133 }else{
drhc2ce0be2014-05-29 12:36:14 +00003134 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003135 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003136 if( strcmp(zFile,"off")!=0 ){
3137 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003138 }
drh75897232000-05-29 14:26:00 +00003139 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003140 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003141 } else {
drhc2ce0be2014-05-29 12:36:14 +00003142 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003143 }
3144 }
3145 }else
3146
drh078b1fd2012-09-21 13:40:02 +00003147 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3148 int i;
3149 for(i=1; i<nArg; i++){
3150 if( i>1 ) fprintf(p->out, " ");
3151 fprintf(p->out, "%s", azArg[i]);
3152 }
3153 fprintf(p->out, "\n");
3154 }else
3155
drhc2ce0be2014-05-29 12:36:14 +00003156 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003157 if( nArg >= 2) {
3158 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3159 }
3160 if( nArg >= 3) {
3161 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3162 }
3163 }else
3164
drhc2ce0be2014-05-29 12:36:14 +00003165 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003166 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003167 }else
3168
drhc2ce0be2014-05-29 12:36:14 +00003169 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3170 FILE *alt;
3171 if( nArg!=2 ){
3172 fprintf(stderr, "Usage: .read FILE\n");
3173 rc = 1;
3174 goto meta_command_exit;
3175 }
3176 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003177 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003178 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3179 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003180 }else{
shane9bd1b442009-10-23 01:27:39 +00003181 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003182 fclose(alt);
3183 }
3184 }else
3185
drhc2ce0be2014-05-29 12:36:14 +00003186 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003187 const char *zSrcFile;
3188 const char *zDb;
3189 sqlite3 *pSrc;
3190 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003191 int nTimeout = 0;
3192
drh9ff849f2009-02-04 20:55:57 +00003193 if( nArg==2 ){
3194 zSrcFile = azArg[1];
3195 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003196 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003197 zSrcFile = azArg[2];
3198 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003199 }else{
3200 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3201 rc = 1;
3202 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003203 }
3204 rc = sqlite3_open(zSrcFile, &pSrc);
3205 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003206 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003207 sqlite3_close(pSrc);
3208 return 1;
3209 }
drh05782482013-10-24 15:20:20 +00003210 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003211 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3212 if( pBackup==0 ){
3213 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3214 sqlite3_close(pSrc);
3215 return 1;
3216 }
drhdc2c4912009-02-04 22:46:47 +00003217 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3218 || rc==SQLITE_BUSY ){
3219 if( rc==SQLITE_BUSY ){
3220 if( nTimeout++ >= 3 ) break;
3221 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003222 }
3223 }
3224 sqlite3_backup_finish(pBackup);
3225 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003226 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003227 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003228 fprintf(stderr, "Error: source database is busy\n");
3229 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003230 }else{
3231 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003232 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003233 }
3234 sqlite3_close(pSrc);
3235 }else
3236
dan8d1edb92014-11-05 09:07:28 +00003237
3238 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3239 if( nArg==2 ){
3240 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003241#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3242 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3243#endif
dan8d1edb92014-11-05 09:07:28 +00003244 }else{
3245 fprintf(stderr, "Usage: .scanstats on|off\n");
3246 rc = 1;
3247 }
3248 }else
3249
drhc2ce0be2014-05-29 12:36:14 +00003250 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003251 ShellState data;
drh75897232000-05-29 14:26:00 +00003252 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003253 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003254 memcpy(&data, p, sizeof(data));
3255 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003256 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003257 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003258 int i;
drhf0693c82011-10-11 20:41:54 +00003259 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003260 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003261 char *new_argv[2], *new_colv[2];
3262 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3263 " type text,\n"
3264 " name text,\n"
3265 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003266 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003267 " sql text\n"
3268 ")";
3269 new_argv[1] = 0;
3270 new_colv[0] = "sql";
3271 new_colv[1] = 0;
3272 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003273 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003274 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003275 char *new_argv[2], *new_colv[2];
3276 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3277 " type text,\n"
3278 " name text,\n"
3279 " tbl_name text,\n"
3280 " rootpage integer,\n"
3281 " sql text\n"
3282 ")";
3283 new_argv[1] = 0;
3284 new_colv[0] = "sql";
3285 new_colv[1] = 0;
3286 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003287 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003288 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003289 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003290 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003291 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003292 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003293 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003294 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003295 "WHERE lower(tbl_name) LIKE shellstatic()"
3296 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003297 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003298 callback, &data, &zErrMsg);
3299 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003300 }
drhc2ce0be2014-05-29 12:36:14 +00003301 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003302 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003303 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003304 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003305 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003306 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003307 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003308 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003309 callback, &data, &zErrMsg
3310 );
drhc2ce0be2014-05-29 12:36:14 +00003311 }else{
3312 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3313 rc = 1;
3314 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003315 }
drh75897232000-05-29 14:26:00 +00003316 if( zErrMsg ){
3317 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003318 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003319 rc = 1;
3320 }else if( rc != SQLITE_OK ){
3321 fprintf(stderr,"Error: querying schema information\n");
3322 rc = 1;
3323 }else{
3324 rc = 0;
drh75897232000-05-29 14:26:00 +00003325 }
3326 }else
3327
drhabd4c722014-09-20 18:18:33 +00003328
3329#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3330 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3331 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003332 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003333 }else
3334#endif
3335
3336
drh340f5822013-06-27 13:01:21 +00003337#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003338 /* Undocumented commands for internal testing. Subject to change
3339 ** without notice. */
3340 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3341 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3342 int i, v;
3343 for(i=1; i<nArg; i++){
3344 v = booleanValue(azArg[i]);
3345 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3346 }
3347 }
3348 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3349 int i; sqlite3_int64 v;
3350 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003351 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003352 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003353 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003354 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003355 }
3356 }
3357 }else
drh340f5822013-06-27 13:01:21 +00003358#endif
drh348d19c2013-06-03 12:47:43 +00003359
drhc2ce0be2014-05-29 12:36:14 +00003360 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003361 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003362 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003363 rc = 1;
3364 }
drh6976c212014-07-24 12:09:47 +00003365 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003366 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003367 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003368 }
3369 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003370 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3371 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003372 }
drh75897232000-05-29 14:26:00 +00003373 }else
3374
drh62cdde52014-05-28 20:22:28 +00003375 if( c=='s'
3376 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003377 ){
3378 char *zCmd;
drh54027102014-08-06 14:36:53 +00003379 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003380 if( nArg<2 ){
3381 fprintf(stderr, "Usage: .system COMMAND\n");
3382 rc = 1;
3383 goto meta_command_exit;
3384 }
drhdcb3e3d2014-05-29 03:17:29 +00003385 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003386 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003387 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3388 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003389 }
drh54027102014-08-06 14:36:53 +00003390 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003391 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003392 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003393 }else
3394
drhc2ce0be2014-05-29 12:36:14 +00003395 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003396 int i;
drhc2ce0be2014-05-29 12:36:14 +00003397 if( nArg!=1 ){
3398 fprintf(stderr, "Usage: .show\n");
3399 rc = 1;
3400 goto meta_command_exit;
3401 }
mistachkin636bf9f2014-07-19 20:15:16 +00003402 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3403 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003404 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003405 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3406 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3407 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003408 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003409 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003410 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003411 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003412 fprintf(p->out,"%12.12s: ", "colseparator");
3413 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003414 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003415 fprintf(p->out,"%12.12s: ", "rowseparator");
3416 output_c_string(p->out, p->rowSeparator);
3417 fprintf(p->out, "\n");
3418 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3419 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003420 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003421 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003422 }
drhfeac5f82004-08-01 00:10:45 +00003423 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003424 }else
3425
drhc2ce0be2014-05-29 12:36:14 +00003426 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3427 if( nArg==2 ){
3428 p->statsOn = booleanValue(azArg[1]);
3429 }else{
3430 fprintf(stderr, "Usage: .stats on|off\n");
3431 rc = 1;
3432 }
shaneh642d8b82010-07-28 16:05:34 +00003433 }else
3434
drhc2ce0be2014-05-29 12:36:14 +00003435 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003436 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003437 char **azResult;
drh98781232012-04-23 12:38:05 +00003438 int nRow, nAlloc;
3439 char *zSql = 0;
3440 int ii;
drh05782482013-10-24 15:20:20 +00003441 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003442 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3443 if( rc ) return rc;
3444 zSql = sqlite3_mprintf(
3445 "SELECT name FROM sqlite_master"
3446 " WHERE type IN ('table','view')"
3447 " AND name NOT LIKE 'sqlite_%%'"
3448 " AND name LIKE ?1");
3449 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3450 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3451 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3452 if( strcmp(zDbName,"temp")==0 ){
3453 zSql = sqlite3_mprintf(
3454 "%z UNION ALL "
3455 "SELECT 'temp.' || name FROM sqlite_temp_master"
3456 " WHERE type IN ('table','view')"
3457 " AND name NOT LIKE 'sqlite_%%'"
3458 " AND name LIKE ?1", zSql);
3459 }else{
3460 zSql = sqlite3_mprintf(
3461 "%z UNION ALL "
3462 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3463 " WHERE type IN ('table','view')"
3464 " AND name NOT LIKE 'sqlite_%%'"
3465 " AND name LIKE ?1", zSql, zDbName, zDbName);
3466 }
drha50da102000-08-08 20:19:09 +00003467 }
drh98781232012-04-23 12:38:05 +00003468 sqlite3_finalize(pStmt);
3469 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3470 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3471 sqlite3_free(zSql);
3472 if( rc ) return rc;
3473 nRow = nAlloc = 0;
3474 azResult = 0;
3475 if( nArg>1 ){
3476 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003477 }else{
drh98781232012-04-23 12:38:05 +00003478 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3479 }
3480 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3481 if( nRow>=nAlloc ){
3482 char **azNew;
3483 int n = nAlloc*2 + 10;
3484 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3485 if( azNew==0 ){
3486 fprintf(stderr, "Error: out of memory\n");
3487 break;
3488 }
3489 nAlloc = n;
3490 azResult = azNew;
3491 }
3492 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3493 if( azResult[nRow] ) nRow++;
3494 }
3495 sqlite3_finalize(pStmt);
3496 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003497 int len, maxlen = 0;
3498 int i, j;
3499 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003500 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003501 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003502 if( len>maxlen ) maxlen = len;
3503 }
3504 nPrintCol = 80/(maxlen+2);
3505 if( nPrintCol<1 ) nPrintCol = 1;
3506 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3507 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003508 for(j=i; j<nRow; j+=nPrintRow){
3509 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003510 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003511 }
drh151b7d52013-05-06 20:28:54 +00003512 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003513 }
3514 }
drh98781232012-04-23 12:38:05 +00003515 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3516 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003517 }else
3518
shaneh96887e12011-02-10 21:08:58 +00003519 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003520 static const struct {
3521 const char *zCtrlName; /* Name of a test-control option */
3522 int ctrlCode; /* Integer code for that option */
3523 } aCtrl[] = {
3524 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3525 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3526 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3527 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3528 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3529 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3530 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3531 { "assert", SQLITE_TESTCTRL_ASSERT },
3532 { "always", SQLITE_TESTCTRL_ALWAYS },
3533 { "reserve", SQLITE_TESTCTRL_RESERVE },
3534 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3535 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003536 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003537 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003538 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drhd416fe72011-03-17 16:45:50 +00003539 };
shaneh96887e12011-02-10 21:08:58 +00003540 int testctrl = -1;
3541 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003542 int i, n;
drh05782482013-10-24 15:20:20 +00003543 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003544
drhd416fe72011-03-17 16:45:50 +00003545 /* convert testctrl text option to value. allow any unique prefix
3546 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003547 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003548 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003549 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3550 if( testctrl<0 ){
3551 testctrl = aCtrl[i].ctrlCode;
3552 }else{
drhb07028f2011-10-14 21:49:18 +00003553 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003554 testctrl = -1;
3555 break;
3556 }
3557 }
3558 }
drh348d19c2013-06-03 12:47:43 +00003559 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003560 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3561 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3562 }else{
3563 switch(testctrl){
3564
3565 /* sqlite3_test_control(int, db, int) */
3566 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3567 case SQLITE_TESTCTRL_RESERVE:
3568 if( nArg==3 ){
3569 int opt = (int)strtol(azArg[2], 0, 0);
3570 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003571 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003572 } else {
drhd416fe72011-03-17 16:45:50 +00003573 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3574 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003575 }
3576 break;
3577
3578 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003579 case SQLITE_TESTCTRL_PRNG_SAVE:
3580 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003581 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003582 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003583 if( nArg==2 ){
3584 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003585 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003586 } else {
3587 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3588 }
3589 break;
3590
3591 /* sqlite3_test_control(int, uint) */
3592 case SQLITE_TESTCTRL_PENDING_BYTE:
3593 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003594 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003595 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003596 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003597 } else {
drhd416fe72011-03-17 16:45:50 +00003598 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3599 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003600 }
3601 break;
3602
3603 /* sqlite3_test_control(int, int) */
3604 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003605 case SQLITE_TESTCTRL_ALWAYS:
3606 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003607 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003608 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003609 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003610 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003611 } else {
drhd416fe72011-03-17 16:45:50 +00003612 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3613 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003614 }
3615 break;
3616
3617 /* sqlite3_test_control(int, char *) */
3618#ifdef SQLITE_N_KEYWORD
3619 case SQLITE_TESTCTRL_ISKEYWORD:
3620 if( nArg==3 ){
3621 const char *opt = azArg[2];
3622 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003623 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003624 } else {
drhd416fe72011-03-17 16:45:50 +00003625 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3626 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003627 }
3628 break;
3629#endif
3630
3631 case SQLITE_TESTCTRL_BITVEC_TEST:
3632 case SQLITE_TESTCTRL_FAULT_INSTALL:
3633 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3634 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3635 default:
drhd416fe72011-03-17 16:45:50 +00003636 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3637 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003638 break;
3639 }
3640 }
3641 }else
3642
drhc2ce0be2014-05-29 12:36:14 +00003643 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003644 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003645 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003646 }else
3647
drhc2ce0be2014-05-29 12:36:14 +00003648 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3649 if( nArg==2 ){
3650 enableTimer = booleanValue(azArg[1]);
3651 if( enableTimer && !HAS_TIMER ){
3652 fprintf(stderr, "Error: timer not available on this system.\n");
3653 enableTimer = 0;
3654 }
3655 }else{
3656 fprintf(stderr, "Usage: .timer on|off\n");
3657 rc = 1;
3658 }
shanehe2aa9d72009-11-06 17:20:17 +00003659 }else
3660
drhc2ce0be2014-05-29 12:36:14 +00003661 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003662 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00003663 output_file_close(p->traceOut);
drhc2ce0be2014-05-29 12:36:14 +00003664 if( nArg!=2 ){
3665 fprintf(stderr, "Usage: .trace FILE|off\n");
3666 rc = 1;
3667 goto meta_command_exit;
3668 }
drh42f64e52012-04-04 16:56:23 +00003669 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003670#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003671 if( p->traceOut==0 ){
3672 sqlite3_trace(p->db, 0, 0);
3673 }else{
3674 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3675 }
3676#endif
3677 }else
3678
drhf442e332014-09-10 19:01:14 +00003679#if SQLITE_USER_AUTHENTICATION
3680 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3681 if( nArg<2 ){
3682 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3683 rc = 1;
3684 goto meta_command_exit;
3685 }
drh7883ecf2014-09-11 16:19:31 +00003686 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003687 if( strcmp(azArg[1],"login")==0 ){
3688 if( nArg!=4 ){
3689 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3690 rc = 1;
3691 goto meta_command_exit;
3692 }
drhd39c40f2014-09-11 00:27:53 +00003693 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3694 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003695 if( rc ){
3696 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3697 rc = 1;
3698 }
3699 }else if( strcmp(azArg[1],"add")==0 ){
3700 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003701 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003702 rc = 1;
3703 goto meta_command_exit;
3704 }
drhd39c40f2014-09-11 00:27:53 +00003705 rc = sqlite3_user_add(p->db, azArg[2],
3706 azArg[3], (int)strlen(azArg[3]),
3707 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003708 if( rc ){
3709 fprintf(stderr, "User-Add failed: %d\n", rc);
3710 rc = 1;
3711 }
3712 }else if( strcmp(azArg[1],"edit")==0 ){
3713 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003714 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003715 rc = 1;
3716 goto meta_command_exit;
3717 }
drhd39c40f2014-09-11 00:27:53 +00003718 rc = sqlite3_user_change(p->db, azArg[2],
3719 azArg[3], (int)strlen(azArg[3]),
3720 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003721 if( rc ){
3722 fprintf(stderr, "User-Edit failed: %d\n", rc);
3723 rc = 1;
3724 }
3725 }else if( strcmp(azArg[1],"delete")==0 ){
3726 if( nArg!=3 ){
3727 fprintf(stderr, "Usage: .user delete USER\n");
3728 rc = 1;
3729 goto meta_command_exit;
3730 }
3731 rc = sqlite3_user_delete(p->db, azArg[2]);
3732 if( rc ){
3733 fprintf(stderr, "User-Delete failed: %d\n", rc);
3734 rc = 1;
3735 }
3736 }else{
3737 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
3738 rc = 1;
3739 goto meta_command_exit;
3740 }
3741 }else
3742#endif /* SQLITE_USER_AUTHENTICATION */
3743
drh9fd301b2011-06-03 13:28:22 +00003744 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003745 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003746 sqlite3_libversion(), sqlite3_sourceid());
3747 }else
3748
drhde60fc22011-12-14 17:53:36 +00003749 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3750 const char *zDbName = nArg==2 ? azArg[1] : "main";
3751 char *zVfsName = 0;
3752 if( p->db ){
3753 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3754 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003755 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003756 sqlite3_free(zVfsName);
3757 }
3758 }
3759 }else
3760
drhcef4fc82012-09-21 22:50:45 +00003761#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3762 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3763 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003764 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003765 }else
3766#endif
3767
drhc2ce0be2014-05-29 12:36:14 +00003768 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003769 int j;
drh43617e92006-03-06 20:55:46 +00003770 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003771 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003772 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003773 }
3774 }else
3775
3776 {
shane9bd1b442009-10-23 01:27:39 +00003777 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003778 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003779 rc = 1;
drh75897232000-05-29 14:26:00 +00003780 }
drh67505e72002-04-19 12:34:06 +00003781
drhc2ce0be2014-05-29 12:36:14 +00003782meta_command_exit:
3783 if( p->outCount ){
3784 p->outCount--;
3785 if( p->outCount==0 ) output_reset(p);
3786 }
drh67505e72002-04-19 12:34:06 +00003787 return rc;
drh75897232000-05-29 14:26:00 +00003788}
3789
drh67505e72002-04-19 12:34:06 +00003790/*
drh91a66392007-09-07 01:12:32 +00003791** Return TRUE if a semicolon occurs anywhere in the first N characters
3792** of string z[].
drh324ccef2003-02-05 14:06:20 +00003793*/
drh9f099fd2013-08-06 14:01:46 +00003794static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00003795 int i;
3796 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3797 return 0;
drh324ccef2003-02-05 14:06:20 +00003798}
3799
3800/*
drh70c7a4b2003-04-26 03:03:06 +00003801** Test to see if a line consists entirely of whitespace.
3802*/
3803static int _all_whitespace(const char *z){
3804 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00003805 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003806 if( *z=='/' && z[1]=='*' ){
3807 z += 2;
3808 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3809 if( *z==0 ) return 0;
3810 z++;
3811 continue;
3812 }
3813 if( *z=='-' && z[1]=='-' ){
3814 z += 2;
3815 while( *z && *z!='\n' ){ z++; }
3816 if( *z==0 ) return 1;
3817 continue;
3818 }
3819 return 0;
3820 }
3821 return 1;
3822}
3823
3824/*
drha9b17162003-04-29 18:01:28 +00003825** Return TRUE if the line typed in is an SQL command terminator other
3826** than a semi-colon. The SQL Server style "go" command is understood
3827** as is the Oracle "/".
3828*/
drh9f099fd2013-08-06 14:01:46 +00003829static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00003830 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00003831 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3832 return 1; /* Oracle */
3833 }
drhf0693c82011-10-11 20:41:54 +00003834 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00003835 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00003836 return 1; /* SQL Server */
3837 }
3838 return 0;
3839}
3840
3841/*
drh233a5312008-12-18 22:25:13 +00003842** Return true if zSql is a complete SQL statement. Return false if it
3843** ends in the middle of a string literal or C-style comment.
3844*/
drh9f099fd2013-08-06 14:01:46 +00003845static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00003846 int rc;
3847 if( zSql==0 ) return 1;
3848 zSql[nSql] = ';';
3849 zSql[nSql+1] = 0;
3850 rc = sqlite3_complete(zSql);
3851 zSql[nSql] = 0;
3852 return rc;
3853}
3854
3855/*
drh67505e72002-04-19 12:34:06 +00003856** Read input from *in and process it. If *in==0 then input
3857** is interactive - the user is typing it it. Otherwise, input
3858** is coming from a file or device. A prompt is issued and history
3859** is saved only if input is interactive. An interrupt signal will
3860** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00003861**
3862** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00003863*/
drhdcd87a92014-08-18 13:45:42 +00003864static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00003865 char *zLine = 0; /* A single input line */
3866 char *zSql = 0; /* Accumulated SQL text */
3867 int nLine; /* Length of current line */
3868 int nSql = 0; /* Bytes of zSql[] used */
3869 int nAlloc = 0; /* Allocated zSql[] space */
3870 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
3871 char *zErrMsg; /* Error message returned */
3872 int rc; /* Error code */
3873 int errCnt = 0; /* Number of errors seen */
3874 int lineno = 0; /* Current line number */
3875 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00003876
3877 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
3878 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00003879 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00003880 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00003881 /* End of input */
3882 if( stdin_is_interactive ) printf("\n");
3883 break;
drhc49f44e2006-10-26 18:15:42 +00003884 }
drh67505e72002-04-19 12:34:06 +00003885 if( seenInterrupt ){
3886 if( in!=0 ) break;
3887 seenInterrupt = 0;
3888 }
drhc28490c2006-10-26 14:25:58 +00003889 lineno++;
drh849a9d92013-12-21 15:46:06 +00003890 if( nSql==0 && _all_whitespace(zLine) ){
3891 if( p->echoOn ) printf("%s\n", zLine);
3892 continue;
3893 }
drh2af0b2d2002-02-21 02:25:02 +00003894 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00003895 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00003896 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00003897 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00003898 break;
3899 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00003900 errCnt++;
3901 }
drhdaffd0e2001-04-11 14:28:42 +00003902 continue;
3903 }
drh9f099fd2013-08-06 14:01:46 +00003904 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00003905 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00003906 }
drh9f099fd2013-08-06 14:01:46 +00003907 nLine = strlen30(zLine);
3908 if( nSql+nLine+2>=nAlloc ){
3909 nAlloc = nSql+nLine+100;
3910 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00003911 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00003912 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00003913 exit(1);
3914 }
drhdaffd0e2001-04-11 14:28:42 +00003915 }
drh9f099fd2013-08-06 14:01:46 +00003916 nSqlPrior = nSql;
3917 if( nSql==0 ){
3918 int i;
3919 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00003920 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00003921 memcpy(zSql, zLine+i, nLine+1-i);
3922 startline = lineno;
3923 nSql = nLine-i;
3924 }else{
3925 zSql[nSql++] = '\n';
3926 memcpy(zSql+nSql, zLine, nLine+1);
3927 nSql += nLine;
3928 }
3929 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00003930 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00003931 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00003932 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00003933 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00003934 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00003935 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00003936 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00003937 char zPrefix[100];
3938 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00003939 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00003940 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00003941 }else{
shane9bd1b442009-10-23 01:27:39 +00003942 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00003943 }
drh7f953e22002-07-13 17:33:45 +00003944 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00003945 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003946 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00003947 zErrMsg = 0;
3948 }else{
shaned2bed1c2009-10-21 03:56:54 +00003949 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00003950 }
drhc49f44e2006-10-26 18:15:42 +00003951 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00003952 }
drhdaffd0e2001-04-11 14:28:42 +00003953 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00003954 if( p->outCount ){
3955 output_reset(p);
3956 p->outCount = 0;
3957 }
drh9f099fd2013-08-06 14:01:46 +00003958 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00003959 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00003960 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00003961 }
3962 }
drh9f099fd2013-08-06 14:01:46 +00003963 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00003964 if( !_all_whitespace(zSql) ){
3965 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00003966 errCnt++;
drhd416fe72011-03-17 16:45:50 +00003967 }
drhdaffd0e2001-04-11 14:28:42 +00003968 free(zSql);
3969 }
danielk19772ac27622007-07-03 05:31:16 +00003970 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00003971 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00003972}
3973
drh67505e72002-04-19 12:34:06 +00003974/*
3975** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00003976** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00003977*/
3978static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00003979 static char *home_dir = NULL;
3980 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00003981
drh4ace5362014-11-10 14:42:28 +00003982#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
3983 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00003984 {
3985 struct passwd *pwent;
3986 uid_t uid = getuid();
3987 if( (pwent=getpwuid(uid)) != NULL) {
3988 home_dir = pwent->pw_dir;
3989 }
drh67505e72002-04-19 12:34:06 +00003990 }
3991#endif
3992
chw65d3c132007-11-12 21:09:10 +00003993#if defined(_WIN32_WCE)
3994 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
3995 */
drh85e72432012-04-11 11:38:53 +00003996 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00003997#else
3998
drh83905c92012-06-21 13:00:37 +00003999#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004000 if (!home_dir) {
4001 home_dir = getenv("USERPROFILE");
4002 }
4003#endif
4004
drh67505e72002-04-19 12:34:06 +00004005 if (!home_dir) {
4006 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004007 }
4008
drh83905c92012-06-21 13:00:37 +00004009#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004010 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004011 char *zDrive, *zPath;
4012 int n;
4013 zDrive = getenv("HOMEDRIVE");
4014 zPath = getenv("HOMEPATH");
4015 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004016 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004017 home_dir = malloc( n );
4018 if( home_dir==0 ) return 0;
4019 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4020 return home_dir;
4021 }
4022 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004023 }
4024#endif
4025
chw65d3c132007-11-12 21:09:10 +00004026#endif /* !_WIN32_WCE */
4027
drh67505e72002-04-19 12:34:06 +00004028 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004029 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004030 char *z = malloc( n );
4031 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004032 home_dir = z;
4033 }
drhe98d4fa2002-04-21 19:06:22 +00004034
drh67505e72002-04-19 12:34:06 +00004035 return home_dir;
4036}
4037
4038/*
4039** Read input from the file given by sqliterc_override. Or if that
4040** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004041**
4042** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004043*/
shane9bd1b442009-10-23 01:27:39 +00004044static int process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004045 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004046 const char *sqliterc_override /* Name of config file. NULL to use default */
4047){
persicom7e2dfdd2002-04-18 02:46:52 +00004048 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004049 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004050 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004051 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00004052 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004053
4054 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004055 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004056 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00004057#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00004058 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00004059#endif
shane9bd1b442009-10-23 01:27:39 +00004060 return 1;
drhe98d4fa2002-04-21 19:06:22 +00004061 }
drh2f3de322012-06-27 16:41:31 +00004062 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004063 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4064 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004065 }
drha1f9b5e2004-02-14 16:31:02 +00004066 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004067 if( in ){
drhc28490c2006-10-26 14:25:58 +00004068 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004069 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004070 }
shane9bd1b442009-10-23 01:27:39 +00004071 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004072 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004073 }
drh85e72432012-04-11 11:38:53 +00004074 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00004075 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00004076}
4077
drh67505e72002-04-19 12:34:06 +00004078/*
drhe1e38c42003-05-04 18:30:59 +00004079** Show available command line options
4080*/
4081static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004082 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004083 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004084 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004085 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004086 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004087 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004088 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004089 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004090 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004091#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4092 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4093#endif
drhcc3b4f82012-02-07 14:13:50 +00004094 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004095 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004096 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004097 " -line set output mode to 'line'\n"
4098 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004099 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004100 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004101#ifdef SQLITE_ENABLE_MULTIPLEX
4102 " -multiplex enable the multiplexor VFS\n"
4103#endif
mistachkine0d68852014-12-11 03:12:33 +00004104 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004105 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004106 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4107 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004108 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004109 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004110 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004111 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004112#ifdef SQLITE_ENABLE_VFSTRACE
4113 " -vfstrace enable tracing of all VFS calls\n"
4114#endif
drhe1e38c42003-05-04 18:30:59 +00004115;
4116static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004117 fprintf(stderr,
4118 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4119 "FILENAME is the name of an SQLite database. A new database is created\n"
4120 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004121 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004122 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004123 }else{
4124 fprintf(stderr, "Use the -help option for additional information\n");
4125 }
4126 exit(1);
4127}
4128
4129/*
drh67505e72002-04-19 12:34:06 +00004130** Initialize the state information in data
4131*/
drhdcd87a92014-08-18 13:45:42 +00004132static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004133 memset(data, 0, sizeof(*data));
4134 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004135 memcpy(data->colSeparator,SEP_Column, 2);
4136 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004137 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004138 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004139 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004140 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004141 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004142 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4143 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004144}
4145
drh98d312f2012-10-25 15:23:14 +00004146/*
drh5c7976f2014-02-10 19:59:27 +00004147** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004148*/
4149#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004150static void printBold(const char *zText){
4151 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4152 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4153 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4154 SetConsoleTextAttribute(out,
4155 FOREGROUND_RED|FOREGROUND_INTENSITY
4156 );
4157 printf("%s", zText);
4158 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004159}
4160#else
drh5c7976f2014-02-10 19:59:27 +00004161static void printBold(const char *zText){
4162 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004163}
4164#endif
4165
4166/*
drh98d312f2012-10-25 15:23:14 +00004167** Get the argument to an --option. Throw an error and die if no argument
4168** is available.
4169*/
4170static char *cmdline_option_value(int argc, char **argv, int i){
4171 if( i==argc ){
4172 fprintf(stderr, "%s: Error: missing argument to %s\n",
4173 argv[0], argv[argc-1]);
4174 exit(1);
4175 }
4176 return argv[i];
4177}
4178
drh75897232000-05-29 14:26:00 +00004179int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004180 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004181 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004182 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004183 int i;
drhc28490c2006-10-26 14:25:58 +00004184 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004185 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004186 int readStdin = 1;
4187 int nCmd = 0;
4188 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004189
drh69b30ab2014-02-27 15:11:52 +00004190#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004191 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4192 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4193 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4194 exit(1);
4195 }
drhc7181902014-02-27 15:04:13 +00004196#endif
drh047d4532015-01-18 20:30:23 +00004197 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004198 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004199 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004200 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004201 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004202
drh44c2eb12003-04-30 11:38:26 +00004203 /* Make sure we have a valid signal handler early, before anything
4204 ** else is done.
4205 */
drh4c504392000-10-16 22:06:40 +00004206#ifdef SIGINT
4207 signal(SIGINT, interrupt_handler);
4208#endif
drh44c2eb12003-04-30 11:38:26 +00004209
drhac5649a2014-11-28 13:35:03 +00004210#ifdef SQLITE_SHELL_DBNAME_PROC
4211 {
4212 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4213 ** of a C-function that will provide the name of the database file. Use
4214 ** this compile-time option to embed this shell program in larger
4215 ** applications. */
4216 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4217 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4218 warnInmemoryDb = 0;
4219 }
4220#endif
4221
drh22fbcb82004-02-01 01:22:50 +00004222 /* Do an initial pass through the command-line argument to locate
4223 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004224 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004225 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004226 */
drh98d312f2012-10-25 15:23:14 +00004227 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004228 char *z;
drhc28490c2006-10-26 14:25:58 +00004229 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004230 if( z[0]!='-' ){
4231 if( data.zDbFilename==0 ){
4232 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004233 }else{
4234 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4235 ** mean that nothing is read from stdin */
4236 readStdin = 0;
4237 nCmd++;
4238 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4239 if( azCmd==0 ){
4240 fprintf(stderr, "out of memory\n");
4241 exit(1);
4242 }
4243 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004244 }
drh98d312f2012-10-25 15:23:14 +00004245 }
drhcc3b4f82012-02-07 14:13:50 +00004246 if( z[1]=='-' ) z++;
4247 if( strcmp(z,"-separator")==0
4248 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004249 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004250 || strcmp(z,"-cmd")==0
4251 ){
drh98d312f2012-10-25 15:23:14 +00004252 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004253 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004254 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004255 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004256 /* Need to check for batch mode here to so we can avoid printing
4257 ** informational messages (like from process_sqliterc) before
4258 ** we do the actual processing of arguments later in a second pass.
4259 */
shanef69573d2009-10-24 02:06:14 +00004260 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004261 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004262#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004263 const char *zSize;
4264 sqlite3_int64 szHeap;
4265
drh98d312f2012-10-25 15:23:14 +00004266 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004267 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004268 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004269 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4270#endif
drh44dec872014-08-30 15:49:25 +00004271 }else if( strcmp(z,"-scratch")==0 ){
4272 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004273 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004274 if( sz>400000 ) sz = 400000;
4275 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004276 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004277 if( n>10 ) n = 10;
4278 if( n<1 ) n = 1;
4279 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4280 data.shellFlgs |= SHFLG_Scratch;
4281 }else if( strcmp(z,"-pagecache")==0 ){
4282 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004283 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004284 if( sz>70000 ) sz = 70000;
4285 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004286 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004287 if( n<10 ) n = 10;
4288 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4289 data.shellFlgs |= SHFLG_Pagecache;
4290 }else if( strcmp(z,"-lookaside")==0 ){
4291 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004292 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004293 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004294 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004295 if( n<0 ) n = 0;
4296 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4297 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004298#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004299 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004300 extern int vfstrace_register(
4301 const char *zTraceName,
4302 const char *zOldVfsName,
4303 int (*xOut)(const char*,void*),
4304 void *pOutArg,
4305 int makeDefault
4306 );
drh2b625e22011-03-16 17:05:28 +00004307 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004308#endif
drh6f25e892011-07-08 17:02:57 +00004309#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004310 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004311 extern int sqlite3_multiple_initialize(const char*,int);
4312 sqlite3_multiplex_initialize(0, 1);
4313#endif
drh7d9f3942013-04-03 01:26:54 +00004314 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004315 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4316 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004317 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004318 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004319 if( pVfs ){
4320 sqlite3_vfs_register(pVfs, 1);
4321 }else{
4322 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4323 exit(1);
4324 }
drh44c2eb12003-04-30 11:38:26 +00004325 }
4326 }
drh98d312f2012-10-25 15:23:14 +00004327 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004328#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004329 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004330 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004331#else
shane86f5bdb2009-10-24 02:00:07 +00004332 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4333 return 1;
drh01b41712005-08-29 23:06:23 +00004334#endif
drh98d312f2012-10-25 15:23:14 +00004335 }
4336 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004337
drh44c2eb12003-04-30 11:38:26 +00004338 /* Go ahead and open the database file if it already exists. If the
4339 ** file does not exist, delay opening it. This prevents empty database
4340 ** files from being created if a user mistypes the database name argument
4341 ** to the sqlite command-line tool.
4342 */
drhc8d74412004-08-31 23:41:26 +00004343 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004344 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004345 }
4346
drh22fbcb82004-02-01 01:22:50 +00004347 /* Process the initialization file if there is one. If no -init option
4348 ** is given on the command line, look for a file named ~/.sqliterc and
4349 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004350 */
shane86f5bdb2009-10-24 02:00:07 +00004351 rc = process_sqliterc(&data,zInitFile);
4352 if( rc>0 ){
4353 return rc;
4354 }
drh44c2eb12003-04-30 11:38:26 +00004355
drh22fbcb82004-02-01 01:22:50 +00004356 /* Make a second pass through the command-line argument and set
4357 ** options. This second pass is delayed until after the initialization
4358 ** file is processed so that the command-line arguments will override
4359 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004360 */
drh98d312f2012-10-25 15:23:14 +00004361 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004362 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004363 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004364 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004365 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004366 i++;
4367 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004368 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004369 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004370 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004371 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004372 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004373 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004374 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004375 }else if( strcmp(z,"-csv")==0 ){
4376 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004377 memcpy(data.colSeparator,",",2);
4378 }else if( strcmp(z,"-ascii")==0 ){
4379 data.mode = MODE_Ascii;
4380 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004381 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004382 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004383 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004384 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004385 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4386 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004387 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004388 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004389 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004390 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004391 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004392 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004393 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004394 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004395 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004396 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004397 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004398 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004399 }else if( strcmp(z,"-eqp")==0 ){
4400 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004401 }else if( strcmp(z,"-stats")==0 ){
4402 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004403 }else if( strcmp(z,"-scanstats")==0 ){
4404 data.scanstatsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004405 }else if( strcmp(z,"-bail")==0 ){
4406 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004407 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004408 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004409 return 0;
drhc28490c2006-10-26 14:25:58 +00004410 }else if( strcmp(z,"-interactive")==0 ){
4411 stdin_is_interactive = 1;
4412 }else if( strcmp(z,"-batch")==0 ){
4413 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004414 }else if( strcmp(z,"-heap")==0 ){
4415 i++;
drh44dec872014-08-30 15:49:25 +00004416 }else if( strcmp(z,"-scratch")==0 ){
4417 i+=2;
4418 }else if( strcmp(z,"-pagecache")==0 ){
4419 i+=2;
4420 }else if( strcmp(z,"-lookaside")==0 ){
4421 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004422 }else if( strcmp(z,"-mmap")==0 ){
4423 i++;
drha7e61d82011-03-12 17:02:57 +00004424 }else if( strcmp(z,"-vfs")==0 ){
4425 i++;
drh6f25e892011-07-08 17:02:57 +00004426#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004427 }else if( strcmp(z,"-vfstrace")==0 ){
4428 i++;
drh6f25e892011-07-08 17:02:57 +00004429#endif
4430#ifdef SQLITE_ENABLE_MULTIPLEX
4431 }else if( strcmp(z,"-multiplex")==0 ){
4432 i++;
4433#endif
drhcc3b4f82012-02-07 14:13:50 +00004434 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004435 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004436 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004437 /* Run commands that follow -cmd first and separately from commands
4438 ** that simply appear on the command-line. This seems goofy. It would
4439 ** be better if all commands ran in the order that they appear. But
4440 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004441 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004442 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004443 if( z[0]=='.' ){
4444 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004445 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004446 }else{
drh05782482013-10-24 15:20:20 +00004447 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004448 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4449 if( zErrMsg!=0 ){
4450 fprintf(stderr,"Error: %s\n", zErrMsg);
4451 if( bail_on_error ) return rc!=0 ? rc : 1;
4452 }else if( rc!=0 ){
4453 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4454 if( bail_on_error ) return rc;
4455 }
4456 }
drh1e5d0e92000-05-31 23:33:17 +00004457 }else{
shane86f5bdb2009-10-24 02:00:07 +00004458 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004459 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004460 return 1;
4461 }
4462 }
drh44c2eb12003-04-30 11:38:26 +00004463
drhac5649a2014-11-28 13:35:03 +00004464 if( !readStdin ){
4465 /* Run all arguments that do not begin with '-' as if they were separate
4466 ** command-line inputs, except for the argToSkip argument which contains
4467 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004468 */
drhac5649a2014-11-28 13:35:03 +00004469 for(i=0; i<nCmd; i++){
4470 if( azCmd[i][0]=='.' ){
4471 rc = do_meta_command(azCmd[i], &data);
4472 if( rc ) return rc==2 ? 0 : rc;
4473 }else{
4474 open_db(&data, 0);
4475 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4476 if( zErrMsg!=0 ){
4477 fprintf(stderr,"Error: %s\n", zErrMsg);
4478 return rc!=0 ? rc : 1;
4479 }else if( rc!=0 ){
4480 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4481 return rc;
4482 }
drh6ff13852001-11-25 13:18:23 +00004483 }
drh75897232000-05-29 14:26:00 +00004484 }
drhac5649a2014-11-28 13:35:03 +00004485 free(azCmd);
drh75897232000-05-29 14:26:00 +00004486 }else{
drh44c2eb12003-04-30 11:38:26 +00004487 /* Run commands received from standard input
4488 */
drhc28490c2006-10-26 14:25:58 +00004489 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004490 char *zHome;
4491 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004492 int nHistory;
drh75897232000-05-29 14:26:00 +00004493 printf(
drh743e0032011-12-12 16:51:50 +00004494 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004495 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004496 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004497 );
drhb3735912014-02-10 16:13:42 +00004498 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004499 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004500 printBold("transient in-memory database");
4501 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004502 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004503 }
drh67505e72002-04-19 12:34:06 +00004504 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004505 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004506 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004507 if( (zHistory = malloc(nHistory))!=0 ){
4508 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4509 }
drh67505e72002-04-19 12:34:06 +00004510 }
drh0ede9eb2015-01-10 16:49:23 +00004511#if HAVE_READLINE
drh67505e72002-04-19 12:34:06 +00004512 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00004513#endif
drhc28490c2006-10-26 14:25:58 +00004514 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004515 if( zHistory ){
4516 stifle_history(100);
4517 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004518 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004519 }
drhdaffd0e2001-04-11 14:28:42 +00004520 }else{
drhc28490c2006-10-26 14:25:58 +00004521 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004522 }
4523 }
drh33048c02001-10-01 14:29:22 +00004524 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004525 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004526 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004527 }
drh05782482013-10-24 15:20:20 +00004528 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004529 return rc;
drh75897232000-05-29 14:26:00 +00004530}