blob: baedcceb599935f0d436a9b4035f4edc86381dad [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
21** Enable large-file support for fopen() and friends on unix.
22*/
23#ifndef SQLITE_DISABLE_LFS
24# define _LARGE_FILE 1
25# ifndef _FILE_OFFSET_BITS
26# define _FILE_OFFSET_BITS 64
27# endif
28# define _LARGEFILE_SOURCE 1
29#endif
30
drh75897232000-05-29 14:26:00 +000031#include <stdlib.h>
32#include <string.h>
33#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000034#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000035#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000036#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000037#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000038
drh83905c92012-06-21 13:00:37 +000039#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000040# include <signal.h>
chw97185482008-11-17 08:05:31 +000041# if !defined(__RTP__) && !defined(_WRS_KERNEL)
42# include <pwd.h>
43# endif
drhdd45df82002-04-18 12:39:03 +000044# include <unistd.h>
45# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000046#endif
drh75897232000-05-29 14:26:00 +000047
drh81d7fd12010-12-08 00:02:26 +000048#ifdef HAVE_EDITLINE
49# include <editline/editline.h>
50#endif
drh16e59552000-07-31 11:57:37 +000051#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000052# include <readline/readline.h>
53# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000054#endif
55#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
drh18f52e02012-01-16 16:56:31 +000056# define readline(p) local_getline(p,stdin,0)
persicom1d0b8722002-04-18 02:53:04 +000057# define add_history(X)
drh67505e72002-04-19 12:34:06 +000058# define read_history(X)
59# define write_history(X)
60# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000061#endif
62
adamd2e8464a2006-09-06 21:39:40 +000063#if defined(_WIN32) || defined(WIN32)
64# include <io.h>
shane18e526c2008-12-10 22:30:24 +000065#define isatty(h) _isatty(h)
66#define access(f,m) _access((f),(m))
drhe1da8fa2012-03-30 00:05:57 +000067#define popen(a,b) _popen((a),(b))
68#define pclose(x) _pclose(x)
adamd2e8464a2006-09-06 21:39:40 +000069#else
drh4328c8b2003-04-26 02:50:11 +000070/* Make sure isatty() has a prototype.
71*/
drhb2acc3b2011-10-13 16:36:29 +000072extern int isatty(int);
adamd2e8464a2006-09-06 21:39:40 +000073#endif
drh4328c8b2003-04-26 02:50:11 +000074
chw65d3c132007-11-12 21:09:10 +000075#if defined(_WIN32_WCE)
76/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
77 * thus we always assume that we have a console. That can be
78 * overridden with the -batch command line option.
79 */
80#define isatty(x) 1
81#endif
82
drhc6e41722011-04-11 15:36:26 +000083/* True if the timer is enabled */
84static int enableTimer = 0;
85
drhf0693c82011-10-11 20:41:54 +000086/* ctype macros that work with signed characters */
87#define IsSpace(X) isspace((unsigned char)X)
88#define IsDigit(X) isdigit((unsigned char)X)
89#define ToLower(X) (char)tolower((unsigned char)X)
90
drh83905c92012-06-21 13:00:37 +000091#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000092#include <sys/time.h>
93#include <sys/resource.h>
94
drhda108222009-02-25 19:07:24 +000095/* Saved resource information for the beginning of an operation */
96static struct rusage sBegin;
97
drhda108222009-02-25 19:07:24 +000098/*
99** Begin timing an operation
100*/
101static void beginTimer(void){
102 if( enableTimer ){
103 getrusage(RUSAGE_SELF, &sBegin);
104 }
105}
106
107/* Return the difference of two time_structs in seconds */
108static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
109 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
110 (double)(pEnd->tv_sec - pStart->tv_sec);
111}
112
113/*
114** Print the timing results.
115*/
116static void endTimer(void){
117 if( enableTimer ){
118 struct rusage sEnd;
119 getrusage(RUSAGE_SELF, &sEnd);
120 printf("CPU Time: user %f sys %f\n",
121 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
122 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
123 }
124}
shaneb320ccd2009-10-21 03:42:58 +0000125
drhda108222009-02-25 19:07:24 +0000126#define BEGIN_TIMER beginTimer()
127#define END_TIMER endTimer()
128#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000129
130#elif (defined(_WIN32) || defined(WIN32))
131
132#include <windows.h>
133
134/* Saved resource information for the beginning of an operation */
135static HANDLE hProcess;
136static FILETIME ftKernelBegin;
137static FILETIME ftUserBegin;
138typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
139static GETPROCTIMES getProcessTimesAddr = NULL;
140
shaneb320ccd2009-10-21 03:42:58 +0000141/*
142** Check to see if we have timer support. Return 1 if necessary
143** support found (or found previously).
144*/
145static int hasTimer(void){
146 if( getProcessTimesAddr ){
147 return 1;
148 } else {
149 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
150 ** See if the version we are running on has it, and if it does, save off
151 ** a pointer to it and the current process handle.
152 */
153 hProcess = GetCurrentProcess();
154 if( hProcess ){
155 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
156 if( NULL != hinstLib ){
157 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
158 if( NULL != getProcessTimesAddr ){
159 return 1;
160 }
161 FreeLibrary(hinstLib);
162 }
163 }
164 }
165 return 0;
166}
167
168/*
169** Begin timing an operation
170*/
171static void beginTimer(void){
172 if( enableTimer && getProcessTimesAddr ){
173 FILETIME ftCreation, ftExit;
174 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
175 }
176}
177
178/* Return the difference of two FILETIME structs in seconds */
179static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
180 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
181 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
182 return (double) ((i64End - i64Start) / 10000000.0);
183}
184
185/*
186** Print the timing results.
187*/
188static void endTimer(void){
189 if( enableTimer && getProcessTimesAddr){
190 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
191 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
192 printf("CPU Time: user %f sys %f\n",
193 timeDiff(&ftUserBegin, &ftUserEnd),
194 timeDiff(&ftKernelBegin, &ftKernelEnd));
195 }
196}
197
198#define BEGIN_TIMER beginTimer()
199#define END_TIMER endTimer()
200#define HAS_TIMER hasTimer()
201
drhda108222009-02-25 19:07:24 +0000202#else
203#define BEGIN_TIMER
204#define END_TIMER
205#define HAS_TIMER 0
206#endif
207
shanec0688ea2009-03-05 03:48:06 +0000208/*
209** Used to prevent warnings about unused parameters
210*/
211#define UNUSED_PARAMETER(x) (void)(x)
212
drhe91d16b2008-12-08 18:27:31 +0000213/*
drhc49f44e2006-10-26 18:15:42 +0000214** If the following flag is set, then command execution stops
215** at an error if we are not interactive.
216*/
217static int bail_on_error = 0;
218
219/*
drhc28490c2006-10-26 14:25:58 +0000220** Threat stdin as an interactive input if the following variable
221** is true. Otherwise, assume stdin is connected to a file or pipe.
222*/
223static int stdin_is_interactive = 1;
224
225/*
drh4c504392000-10-16 22:06:40 +0000226** The following is the open SQLite database. We make a pointer
227** to this database a static variable so that it can be accessed
228** by the SIGINT handler to interrupt database processing.
229*/
danielk197792f9a1b2004-06-19 09:08:16 +0000230static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000231
232/*
drh67505e72002-04-19 12:34:06 +0000233** True if an interrupt (Control-C) has been received.
234*/
drh43617e92006-03-06 20:55:46 +0000235static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000236
237/*
persicom7e2dfdd2002-04-18 02:46:52 +0000238** This is the name of our program. It is set in main(), used
239** in a number of other places, mostly for error messages.
240*/
241static char *Argv0;
242
243/*
244** Prompt strings. Initialized in main. Settable with
245** .prompt main continue
246*/
247static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
248static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
249
drhb0603412007-02-28 04:47:26 +0000250/*
251** Write I/O traces to the following stream.
252*/
rsebe0a9092007-07-30 18:24:38 +0000253#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000254static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000255#endif
drhb0603412007-02-28 04:47:26 +0000256
257/*
258** This routine works like printf in that its first argument is a
259** format string and subsequent arguments are values to be substituted
260** in place of % fields. The result of formatting this string
261** is written to iotrace.
262*/
rsebe0a9092007-07-30 18:24:38 +0000263#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000264static void iotracePrintf(const char *zFormat, ...){
265 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000266 char *z;
drhb0603412007-02-28 04:47:26 +0000267 if( iotrace==0 ) return;
268 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000269 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000270 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000271 fprintf(iotrace, "%s", z);
272 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000273}
rsebe0a9092007-07-30 18:24:38 +0000274#endif
drhb0603412007-02-28 04:47:26 +0000275
drh44c2eb12003-04-30 11:38:26 +0000276
persicom7e2dfdd2002-04-18 02:46:52 +0000277/*
drh83965662003-04-17 02:54:13 +0000278** Determines if a string is a number of not.
279*/
danielk19772e588c72005-12-09 14:25:08 +0000280static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000281 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000282 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000283 return 0;
284 }
285 z++;
286 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000287 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000288 if( *z=='.' ){
289 z++;
drhf0693c82011-10-11 20:41:54 +0000290 if( !IsDigit(*z) ) return 0;
291 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000292 if( realnum ) *realnum = 1;
293 }
294 if( *z=='e' || *z=='E' ){
295 z++;
296 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000297 if( !IsDigit(*z) ) return 0;
298 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000299 if( realnum ) *realnum = 1;
300 }
301 return *z==0;
302}
drh83965662003-04-17 02:54:13 +0000303
304/*
danielk1977bc6ada42004-06-30 08:20:16 +0000305** A global char* and an SQL function to access its current value
306** from within an SQL statement. This program used to use the
307** sqlite_exec_printf() API to substitue a string into an SQL statement.
308** The correct way to do this with sqlite3 is to use the bind API, but
309** since the shell is built around the callback paradigm it would be a lot
310** of work. Instead just use this hack, which is quite harmless.
311*/
312static const char *zShellStatic = 0;
313static void shellstaticFunc(
314 sqlite3_context *context,
315 int argc,
316 sqlite3_value **argv
317){
318 assert( 0==argc );
319 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000320 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000321 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000322 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
323}
324
325
326/*
drhfeac5f82004-08-01 00:10:45 +0000327** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000328** the text in memory obtained from malloc() and returns a pointer
329** to the text. NULL is returned at end of file, or if malloc()
330** fails.
331**
332** The interface is like "readline" but no command-line editing
333** is done.
334*/
drh18f52e02012-01-16 16:56:31 +0000335static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
drh8e7e7a22000-05-30 18:45:23 +0000336 char *zLine;
337 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000338 int n;
drh18f52e02012-01-16 16:56:31 +0000339 int inQuote = 0;
drh8e7e7a22000-05-30 18:45:23 +0000340
341 if( zPrompt && *zPrompt ){
342 printf("%s",zPrompt);
343 fflush(stdout);
344 }
345 nLine = 100;
346 zLine = malloc( nLine );
347 if( zLine==0 ) return 0;
348 n = 0;
drhb07028f2011-10-14 21:49:18 +0000349 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000350 if( n+100>nLine ){
351 nLine = nLine*2 + 100;
352 zLine = realloc(zLine, nLine);
353 if( zLine==0 ) return 0;
354 }
drhdaffd0e2001-04-11 14:28:42 +0000355 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000356 if( n==0 ){
357 free(zLine);
358 return 0;
359 }
360 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000361 break;
362 }
drh18f52e02012-01-16 16:56:31 +0000363 while( zLine[n] ){
364 if( zLine[n]=='"' ) inQuote = !inQuote;
365 n++;
366 }
367 if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
drh8e7e7a22000-05-30 18:45:23 +0000368 n--;
shaneh13b36022009-12-17 21:07:15 +0000369 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000370 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000371 break;
drh8e7e7a22000-05-30 18:45:23 +0000372 }
373 }
374 zLine = realloc( zLine, n+1 );
375 return zLine;
376}
377
378/*
drhc28490c2006-10-26 14:25:58 +0000379** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000380**
381** zPrior is a string of prior text retrieved. If not the empty
382** string, then issue a continuation prompt.
383*/
drhdaffd0e2001-04-11 14:28:42 +0000384static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000385 char *zPrompt;
386 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000387 if( in!=0 ){
drh18f52e02012-01-16 16:56:31 +0000388 return local_getline(0, in, 0);
drh8e7e7a22000-05-30 18:45:23 +0000389 }
390 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000391 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000392 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000393 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000394 }
395 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000396#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000397 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000398#endif
drh8e7e7a22000-05-30 18:45:23 +0000399 return zResult;
400}
401
persicom7e2dfdd2002-04-18 02:46:52 +0000402struct previous_mode_data {
403 int valid; /* Is there legit data in here? */
404 int mode;
405 int showHeader;
406 int colWidth[100];
407};
drh45e29d82006-11-20 16:21:10 +0000408
drh8e7e7a22000-05-30 18:45:23 +0000409/*
drh75897232000-05-29 14:26:00 +0000410** An pointer to an instance of this structure is passed from
411** the main program to the callback. This is used to communicate
412** state and mode information.
413*/
414struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000415 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000416 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000417 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000418 int cnt; /* Number of records displayed so far */
419 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000420 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000421 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000422 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000423 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000424 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000425 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000426 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000427 int colWidth[100]; /* Requested width of each column when in column mode*/
428 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000429 char nullvalue[20]; /* The text to print when a NULL comes back from
430 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000431 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000432 /* Holds the mode information just before
433 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000434 char outfile[FILENAME_MAX]; /* Filename for *out */
435 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000436 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000437 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000438 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000439};
440
441/*
442** These are the allowed modes.
443*/
drh967e8b72000-06-21 13:59:10 +0000444#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000445#define MODE_Column 1 /* One record per line in neat columns */
446#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000447#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
448#define MODE_Html 4 /* Generate an XHTML table */
449#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000450#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000451#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000452#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000453
drh66ce4d02008-02-15 17:38:06 +0000454static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000455 "line",
456 "column",
457 "list",
458 "semi",
459 "html",
drhfeac5f82004-08-01 00:10:45 +0000460 "insert",
461 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000462 "csv",
drh66ce4d02008-02-15 17:38:06 +0000463 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000464};
drh75897232000-05-29 14:26:00 +0000465
466/*
467** Number of elements in an array
468*/
drh902b9ee2008-12-05 17:17:07 +0000469#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000470
471/*
drhea678832008-12-10 19:26:22 +0000472** Compute a string length that is limited to what can be stored in
473** lower 30 bits of a 32-bit signed integer.
474*/
drh4f21c4a2008-12-10 22:15:00 +0000475static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000476 const char *z2 = z;
477 while( *z2 ){ z2++; }
478 return 0x3fffffff & (int)(z2 - z);
479}
480
481/*
drh127f9d72010-02-23 01:47:00 +0000482** A callback for the sqlite3_log() interface.
483*/
484static void shellLog(void *pArg, int iErrCode, const char *zMsg){
485 struct callback_data *p = (struct callback_data*)pArg;
486 if( p->pLog==0 ) return;
487 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
488 fflush(p->pLog);
489}
490
491/*
shane626a6e42009-10-22 17:30:15 +0000492** Output the given string as a hex-encoded blob (eg. X'1234' )
493*/
494static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
495 int i;
496 char *zBlob = (char *)pBlob;
497 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000498 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000499 fprintf(out,"'");
500}
501
502/*
drh28bd4bc2000-06-15 15:57:22 +0000503** Output the given string as a quoted string using SQL quoting conventions.
504*/
505static void output_quoted_string(FILE *out, const char *z){
506 int i;
507 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000508 for(i=0; z[i]; i++){
509 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000510 }
511 if( nSingle==0 ){
512 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000513 }else{
514 fprintf(out,"'");
515 while( *z ){
516 for(i=0; z[i] && z[i]!='\''; i++){}
517 if( i==0 ){
518 fprintf(out,"''");
519 z++;
520 }else if( z[i]=='\'' ){
521 fprintf(out,"%.*s''",i,z);
522 z += i+1;
523 }else{
drhcd7d2732002-02-26 23:24:26 +0000524 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000525 break;
526 }
527 }
drhcd7d2732002-02-26 23:24:26 +0000528 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000529 }
530}
531
532/*
drhfeac5f82004-08-01 00:10:45 +0000533** Output the given string as a quoted according to C or TCL quoting rules.
534*/
535static void output_c_string(FILE *out, const char *z){
536 unsigned int c;
537 fputc('"', out);
538 while( (c = *(z++))!=0 ){
539 if( c=='\\' ){
540 fputc(c, out);
541 fputc(c, out);
542 }else if( c=='\t' ){
543 fputc('\\', out);
544 fputc('t', out);
545 }else if( c=='\n' ){
546 fputc('\\', out);
547 fputc('n', out);
548 }else if( c=='\r' ){
549 fputc('\\', out);
550 fputc('r', out);
551 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000552 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000553 }else{
554 fputc(c, out);
555 }
556 }
557 fputc('"', out);
558}
559
560/*
drhc08a4f12000-06-15 16:49:48 +0000561** Output the given string with characters that are special to
562** HTML escaped.
563*/
564static void output_html_string(FILE *out, const char *z){
565 int i;
566 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000567 for(i=0; z[i]
568 && z[i]!='<'
569 && z[i]!='&'
570 && z[i]!='>'
571 && z[i]!='\"'
572 && z[i]!='\'';
573 i++){}
drhc08a4f12000-06-15 16:49:48 +0000574 if( i>0 ){
575 fprintf(out,"%.*s",i,z);
576 }
577 if( z[i]=='<' ){
578 fprintf(out,"&lt;");
579 }else if( z[i]=='&' ){
580 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000581 }else if( z[i]=='>' ){
582 fprintf(out,"&gt;");
583 }else if( z[i]=='\"' ){
584 fprintf(out,"&quot;");
585 }else if( z[i]=='\'' ){
586 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000587 }else{
588 break;
589 }
590 z += i + 1;
591 }
592}
593
594/*
drhc49f44e2006-10-26 18:15:42 +0000595** If a field contains any character identified by a 1 in the following
596** array, then the string must be quoted for CSV.
597*/
598static const char needCsvQuote[] = {
599 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
600 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
601 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
602 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
603 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
607 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
608 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
609 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
610 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
611 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
612 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
613 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
614 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
615};
616
617/*
drh8e64d1c2004-10-07 00:32:39 +0000618** Output a single term of CSV. Actually, p->separator is used for
619** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000620** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000621*/
622static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000623 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000624 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000625 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000626 }else{
drhc49f44e2006-10-26 18:15:42 +0000627 int i;
drh4f21c4a2008-12-10 22:15:00 +0000628 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000629 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000630 if( needCsvQuote[((unsigned char*)z)[i]]
631 || (z[i]==p->separator[0] &&
632 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000633 i = 0;
634 break;
635 }
636 }
637 if( i==0 ){
638 putc('"', out);
639 for(i=0; z[i]; i++){
640 if( z[i]=='"' ) putc('"', out);
641 putc(z[i], out);
642 }
643 putc('"', out);
644 }else{
645 fprintf(out, "%s", z);
646 }
drh8e64d1c2004-10-07 00:32:39 +0000647 }
648 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000649 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000650 }
651}
652
danielk19774af00c62005-01-23 23:43:21 +0000653#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000654/*
drh4c504392000-10-16 22:06:40 +0000655** This routine runs when the user presses Ctrl-C
656*/
657static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000658 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000659 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000660 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000661}
danielk19774af00c62005-01-23 23:43:21 +0000662#endif
drh4c504392000-10-16 22:06:40 +0000663
664/*
shane626a6e42009-10-22 17:30:15 +0000665** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000666** invokes for each row of a query result.
667*/
shane626a6e42009-10-22 17:30:15 +0000668static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000669 int i;
670 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000671
drh75897232000-05-29 14:26:00 +0000672 switch( p->mode ){
673 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000674 int w = 5;
drh6a535342001-10-19 16:44:56 +0000675 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000676 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000677 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000678 if( len>w ) w = len;
679 }
drh75897232000-05-29 14:26:00 +0000680 if( p->cnt++>0 ) fprintf(p->out,"\n");
681 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000682 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000683 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000684 }
685 break;
686 }
danielk19770d78bae2008-01-03 07:09:48 +0000687 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000688 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000689 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000690 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000691 int w, n;
692 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000693 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000694 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000695 w = 0;
drh75897232000-05-29 14:26:00 +0000696 }
drha0c66f52000-07-29 13:20:21 +0000697 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000698 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000699 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000700 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000701 if( w<n ) w = n;
702 }
703 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000704 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000705 }
706 if( p->showHeader ){
707 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
708 }
709 }
710 if( p->showHeader ){
711 for(i=0; i<nArg; i++){
712 int w;
713 if( i<ArraySize(p->actualWidth) ){
714 w = p->actualWidth[i];
715 }else{
716 w = 10;
717 }
718 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
719 "----------------------------------------------------------",
720 i==nArg-1 ? "\n": " ");
721 }
drh75897232000-05-29 14:26:00 +0000722 }
723 }
drh6a535342001-10-19 16:44:56 +0000724 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000725 for(i=0; i<nArg; i++){
726 int w;
drha0c66f52000-07-29 13:20:21 +0000727 if( i<ArraySize(p->actualWidth) ){
728 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000729 }else{
730 w = 10;
731 }
drhea678832008-12-10 19:26:22 +0000732 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000733 strlen30(azArg[i])>w ){
734 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000735 }
drhc61053b2000-06-04 12:58:36 +0000736 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000737 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000738 }
739 break;
740 }
drhe3710332000-09-29 13:30:53 +0000741 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000742 case MODE_List: {
743 if( p->cnt++==0 && p->showHeader ){
744 for(i=0; i<nArg; i++){
745 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
746 }
747 }
drh6a535342001-10-19 16:44:56 +0000748 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000749 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000750 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000751 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000752 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000753 if( i<nArg-1 ){
754 fprintf(p->out, "%s", p->separator);
755 }else if( p->mode==MODE_Semi ){
756 fprintf(p->out, ";\n");
757 }else{
758 fprintf(p->out, "\n");
759 }
drh75897232000-05-29 14:26:00 +0000760 }
761 break;
762 }
drh1e5d0e92000-05-31 23:33:17 +0000763 case MODE_Html: {
764 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000765 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000766 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000767 fprintf(p->out,"<TH>");
768 output_html_string(p->out, azCol[i]);
769 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000770 }
mihailim57c591a2008-06-23 21:26:05 +0000771 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000772 }
drh6a535342001-10-19 16:44:56 +0000773 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000774 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000775 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000776 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000777 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000778 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000779 }
mihailim57c591a2008-06-23 21:26:05 +0000780 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000781 break;
782 }
drhfeac5f82004-08-01 00:10:45 +0000783 case MODE_Tcl: {
784 if( p->cnt++==0 && p->showHeader ){
785 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000786 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000787 fprintf(p->out, "%s", p->separator);
788 }
789 fprintf(p->out,"\n");
790 }
791 if( azArg==0 ) break;
792 for(i=0; i<nArg; i++){
793 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
794 fprintf(p->out, "%s", p->separator);
795 }
796 fprintf(p->out,"\n");
797 break;
798 }
drh8e64d1c2004-10-07 00:32:39 +0000799 case MODE_Csv: {
800 if( p->cnt++==0 && p->showHeader ){
801 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000802 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000803 }
804 fprintf(p->out,"\n");
805 }
806 if( azArg==0 ) break;
807 for(i=0; i<nArg; i++){
808 output_csv(p, azArg[i], i<nArg-1);
809 }
810 fprintf(p->out,"\n");
811 break;
812 }
drh28bd4bc2000-06-15 15:57:22 +0000813 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000814 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000815 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000816 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000817 for(i=0; i<nArg; i++){
818 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000819 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000820 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000821 }else if( aiType && aiType[i]==SQLITE_TEXT ){
822 if( zSep[0] ) fprintf(p->out,"%s",zSep);
823 output_quoted_string(p->out, azArg[i]);
824 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
825 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000826 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
827 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
828 int nBlob = sqlite3_column_bytes(p->pStmt, i);
829 if( zSep[0] ) fprintf(p->out,"%s",zSep);
830 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000831 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000832 fprintf(p->out,"%s%s",zSep, azArg[i]);
833 }else{
834 if( zSep[0] ) fprintf(p->out,"%s",zSep);
835 output_quoted_string(p->out, azArg[i]);
836 }
837 }
838 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000839 break;
drh28bd4bc2000-06-15 15:57:22 +0000840 }
persicom1d0b8722002-04-18 02:53:04 +0000841 }
drh75897232000-05-29 14:26:00 +0000842 return 0;
843}
844
845/*
shane626a6e42009-10-22 17:30:15 +0000846** This is the callback routine that the SQLite library
847** invokes for each row of a query result.
848*/
849static int callback(void *pArg, int nArg, char **azArg, char **azCol){
850 /* since we don't have type info, call the shell_callback with a NULL value */
851 return shell_callback(pArg, nArg, azArg, azCol, NULL);
852}
853
854/*
drh33048c02001-10-01 14:29:22 +0000855** Set the destination table field of the callback_data structure to
856** the name of the table given. Escape any quote characters in the
857** table name.
858*/
859static void set_table_name(struct callback_data *p, const char *zName){
860 int i, n;
861 int needQuote;
862 char *z;
863
864 if( p->zDestTable ){
865 free(p->zDestTable);
866 p->zDestTable = 0;
867 }
868 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000869 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000870 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000871 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000872 needQuote = 1;
873 if( zName[i]=='\'' ) n++;
874 }
875 }
876 if( needQuote ) n += 2;
877 z = p->zDestTable = malloc( n+1 );
878 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000879 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000880 exit(1);
881 }
882 n = 0;
883 if( needQuote ) z[n++] = '\'';
884 for(i=0; zName[i]; i++){
885 z[n++] = zName[i];
886 if( zName[i]=='\'' ) z[n++] = '\'';
887 }
888 if( needQuote ) z[n++] = '\'';
889 z[n] = 0;
890}
891
danielk19772a02e332004-06-05 08:04:36 +0000892/* zIn is either a pointer to a NULL-terminated string in memory obtained
893** from malloc(), or a NULL pointer. The string pointed to by zAppend is
894** added to zIn, and the result returned in memory obtained from malloc().
895** zIn, if it was not NULL, is freed.
896**
897** If the third argument, quote, is not '\0', then it is used as a
898** quote character for zAppend.
899*/
drhc28490c2006-10-26 14:25:58 +0000900static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000901 int len;
902 int i;
drh4f21c4a2008-12-10 22:15:00 +0000903 int nAppend = strlen30(zAppend);
904 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000905
906 len = nAppend+nIn+1;
907 if( quote ){
908 len += 2;
909 for(i=0; i<nAppend; i++){
910 if( zAppend[i]==quote ) len++;
911 }
912 }
913
914 zIn = (char *)realloc(zIn, len);
915 if( !zIn ){
916 return 0;
917 }
918
919 if( quote ){
920 char *zCsr = &zIn[nIn];
921 *zCsr++ = quote;
922 for(i=0; i<nAppend; i++){
923 *zCsr++ = zAppend[i];
924 if( zAppend[i]==quote ) *zCsr++ = quote;
925 }
926 *zCsr++ = quote;
927 *zCsr++ = '\0';
928 assert( (zCsr-zIn)==len );
929 }else{
930 memcpy(&zIn[nIn], zAppend, nAppend);
931 zIn[len-1] = '\0';
932 }
933
934 return zIn;
935}
936
drhdd3d4592004-08-30 01:54:05 +0000937
938/*
drhb21a8e42012-01-28 21:08:51 +0000939** Execute a query statement that will generate SQL output. Print
940** the result columns, comma-separated, on a line and then add a
941** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000942**
drhb21a8e42012-01-28 21:08:51 +0000943** If the number of columns is 1 and that column contains text "--"
944** then write the semicolon on a separate line. That way, if a
945** "--" comment occurs at the end of the statement, the comment
946** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000947*/
drh157e29a2009-05-21 15:15:00 +0000948static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000949 struct callback_data *p, /* Query context */
950 const char *zSelect, /* SELECT statement to extract content */
951 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000952){
drhdd3d4592004-08-30 01:54:05 +0000953 sqlite3_stmt *pSelect;
954 int rc;
drhb21a8e42012-01-28 21:08:51 +0000955 int nResult;
956 int i;
957 const char *z;
drh2f464a02011-10-13 00:41:49 +0000958 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000959 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000960 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
961 p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000962 return rc;
963 }
964 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000965 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000966 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000967 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000968 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000969 zFirstRow = 0;
970 }
drhb21a8e42012-01-28 21:08:51 +0000971 z = (const char*)sqlite3_column_text(pSelect, 0);
972 fprintf(p->out, "%s", z);
973 for(i=1; i<nResult; i++){
974 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
975 }
976 if( z==0 ) z = "";
977 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
978 if( z[0] ){
979 fprintf(p->out, "\n;\n");
980 }else{
981 fprintf(p->out, ";\n");
982 }
drhdd3d4592004-08-30 01:54:05 +0000983 rc = sqlite3_step(pSelect);
984 }
drh2f464a02011-10-13 00:41:49 +0000985 rc = sqlite3_finalize(pSelect);
986 if( rc!=SQLITE_OK ){
987 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
988 p->nErr++;
989 }
990 return rc;
drhdd3d4592004-08-30 01:54:05 +0000991}
992
shane626a6e42009-10-22 17:30:15 +0000993/*
994** Allocate space and save off current error string.
995*/
996static char *save_err_msg(
997 sqlite3 *db /* Database to query */
998){
999 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1000 char *zErrMsg = sqlite3_malloc(nErrMsg);
1001 if( zErrMsg ){
1002 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1003 }
1004 return zErrMsg;
1005}
1006
1007/*
shaneh642d8b82010-07-28 16:05:34 +00001008** Display memory stats.
1009*/
1010static int display_stats(
1011 sqlite3 *db, /* Database to query */
1012 struct callback_data *pArg, /* Pointer to struct callback_data */
1013 int bReset /* True to reset the stats */
1014){
1015 int iCur;
1016 int iHiwtr;
1017
1018 if( pArg && pArg->out ){
1019
1020 iHiwtr = iCur = -1;
1021 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001022 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001023 iHiwtr = iCur = -1;
1024 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001025 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001026/*
1027** Not currently used by the CLI.
1028** iHiwtr = iCur = -1;
1029** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1030** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1031*/
1032 iHiwtr = iCur = -1;
1033 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1034 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1035/*
1036** Not currently used by the CLI.
1037** iHiwtr = iCur = -1;
1038** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1039** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1040*/
1041 iHiwtr = iCur = -1;
1042 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1043 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1044 iHiwtr = iCur = -1;
1045 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1046 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1047 iHiwtr = iCur = -1;
1048 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1049 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1050 iHiwtr = iCur = -1;
1051 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1052 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1053#ifdef YYTRACKMAXSTACKDEPTH
1054 iHiwtr = iCur = -1;
1055 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1056 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1057#endif
1058 }
1059
1060 if( pArg && pArg->out && db ){
1061 iHiwtr = iCur = -1;
1062 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1063 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001064 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1065 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1066 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1067 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1068 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1069 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001070 iHiwtr = iCur = -1;
1071 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001072 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1073 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1074 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1075 iHiwtr = iCur = -1;
1076 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1077 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001078 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001079 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1080 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1081 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001082 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1083 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1084 iHiwtr = iCur = -1;
1085 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1086 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1087 }
1088
1089 if( pArg && pArg->out && db && pArg->pStmt ){
1090 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1091 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1092 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1093 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1094 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1095 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1096 }
1097
1098 return 0;
1099}
1100
1101/*
shane626a6e42009-10-22 17:30:15 +00001102** Execute a statement or set of statements. Print
1103** any result rows/columns depending on the current mode
1104** set via the supplied callback.
1105**
1106** This is very similar to SQLite's built-in sqlite3_exec()
1107** function except it takes a slightly different callback
1108** and callback data argument.
1109*/
1110static int shell_exec(
1111 sqlite3 *db, /* An open database */
1112 const char *zSql, /* SQL to be evaluated */
1113 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1114 /* (not the same as sqlite3_exec) */
1115 struct callback_data *pArg, /* Pointer to struct callback_data */
1116 char **pzErrMsg /* Error msg written here */
1117){
dan4564ced2010-01-05 04:59:56 +00001118 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1119 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001120 int rc2;
dan4564ced2010-01-05 04:59:56 +00001121 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001122
1123 if( pzErrMsg ){
1124 *pzErrMsg = NULL;
1125 }
1126
shaneb9fc17d2009-10-22 21:23:35 +00001127 while( zSql[0] && (SQLITE_OK == rc) ){
1128 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1129 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001130 if( pzErrMsg ){
1131 *pzErrMsg = save_err_msg(db);
1132 }
1133 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001134 if( !pStmt ){
1135 /* this happens for a comment or white-space */
1136 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001137 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001138 continue;
1139 }
shane626a6e42009-10-22 17:30:15 +00001140
shaneh642d8b82010-07-28 16:05:34 +00001141 /* save off the prepared statment handle and reset row count */
1142 if( pArg ){
1143 pArg->pStmt = pStmt;
1144 pArg->cnt = 0;
1145 }
1146
shanehb7977c52010-01-18 18:17:10 +00001147 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001148 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001149 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001150 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001151 }
shanehb7977c52010-01-18 18:17:10 +00001152
drh7e02e5e2011-12-06 19:44:51 +00001153 /* Output TESTCTRL_EXPLAIN text of requested */
1154 if( pArg && pArg->mode==MODE_Explain ){
1155 const char *zExplain = 0;
1156 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1157 if( zExplain && zExplain[0] ){
1158 fprintf(pArg->out, "%s", zExplain);
1159 }
1160 }
1161
shaneb9fc17d2009-10-22 21:23:35 +00001162 /* perform the first step. this will tell us if we
1163 ** have a result set or not and how wide it is.
1164 */
1165 rc = sqlite3_step(pStmt);
1166 /* if we have a result set... */
1167 if( SQLITE_ROW == rc ){
1168 /* if we have a callback... */
1169 if( xCallback ){
1170 /* allocate space for col name ptr, value ptr, and type */
1171 int nCol = sqlite3_column_count(pStmt);
1172 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1173 if( !pData ){
1174 rc = SQLITE_NOMEM;
1175 }else{
1176 char **azCols = (char **)pData; /* Names of result columns */
1177 char **azVals = &azCols[nCol]; /* Results */
1178 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1179 int i;
1180 assert(sizeof(int) <= sizeof(char *));
1181 /* save off ptrs to column names */
1182 for(i=0; i<nCol; i++){
1183 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1184 }
shaneb9fc17d2009-10-22 21:23:35 +00001185 do{
1186 /* extract the data and data types */
1187 for(i=0; i<nCol; i++){
1188 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1189 aiTypes[i] = sqlite3_column_type(pStmt, i);
1190 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1191 rc = SQLITE_NOMEM;
1192 break; /* from for */
1193 }
1194 } /* end for */
1195
1196 /* if data and types extracted successfully... */
1197 if( SQLITE_ROW == rc ){
1198 /* call the supplied callback with the result row data */
1199 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1200 rc = SQLITE_ABORT;
1201 }else{
1202 rc = sqlite3_step(pStmt);
1203 }
1204 }
1205 } while( SQLITE_ROW == rc );
1206 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001207 }
1208 }else{
1209 do{
1210 rc = sqlite3_step(pStmt);
1211 } while( rc == SQLITE_ROW );
1212 }
1213 }
1214
shaneh642d8b82010-07-28 16:05:34 +00001215 /* print usage stats if stats on */
1216 if( pArg && pArg->statsOn ){
1217 display_stats(db, pArg, 0);
1218 }
1219
dan4564ced2010-01-05 04:59:56 +00001220 /* Finalize the statement just executed. If this fails, save a
1221 ** copy of the error message. Otherwise, set zSql to point to the
1222 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001223 rc2 = sqlite3_finalize(pStmt);
1224 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001225 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001226 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001227 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001228 }else if( pzErrMsg ){
1229 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001230 }
shaneh642d8b82010-07-28 16:05:34 +00001231
1232 /* clear saved stmt handle */
1233 if( pArg ){
1234 pArg->pStmt = NULL;
1235 }
shane626a6e42009-10-22 17:30:15 +00001236 }
shaneb9fc17d2009-10-22 21:23:35 +00001237 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001238
1239 return rc;
1240}
1241
drhdd3d4592004-08-30 01:54:05 +00001242
drh33048c02001-10-01 14:29:22 +00001243/*
drh4c653a02000-06-07 01:27:47 +00001244** This is a different callback routine used for dumping the database.
1245** Each row received by this callback consists of a table name,
1246** the table type ("index" or "table") and SQL to create the table.
1247** This routine should print text sufficient to recreate the table.
1248*/
1249static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001250 int rc;
1251 const char *zTable;
1252 const char *zType;
1253 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001254 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001255 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001256
drh902b9ee2008-12-05 17:17:07 +00001257 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001258 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001259 zTable = azArg[0];
1260 zType = azArg[1];
1261 zSql = azArg[2];
1262
drh00b950d2005-09-11 02:03:03 +00001263 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001264 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001265 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1266 fprintf(p->out, "ANALYZE sqlite_master;\n");
1267 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1268 return 0;
drh45e29d82006-11-20 16:21:10 +00001269 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1270 char *zIns;
1271 if( !p->writableSchema ){
1272 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1273 p->writableSchema = 1;
1274 }
1275 zIns = sqlite3_mprintf(
1276 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1277 "VALUES('table','%q','%q',0,'%q');",
1278 zTable, zTable, zSql);
1279 fprintf(p->out, "%s\n", zIns);
1280 sqlite3_free(zIns);
1281 return 0;
drh00b950d2005-09-11 02:03:03 +00001282 }else{
1283 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001284 }
danielk19772a02e332004-06-05 08:04:36 +00001285
1286 if( strcmp(zType, "table")==0 ){
1287 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001288 char *zSelect = 0;
1289 char *zTableInfo = 0;
1290 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001291 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001292
1293 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1294 zTableInfo = appendText(zTableInfo, zTable, '"');
1295 zTableInfo = appendText(zTableInfo, ");", 0);
1296
1297 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001298 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001299 if( rc!=SQLITE_OK || !pTableInfo ){
1300 return 1;
1301 }
1302
1303 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001304 /* Always quote the table name, even if it appears to be pure ascii,
1305 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1306 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001307 if( zTmp ){
1308 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001309 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001310 }
1311 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1312 rc = sqlite3_step(pTableInfo);
1313 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001314 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001315 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001316 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001317 rc = sqlite3_step(pTableInfo);
1318 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001319 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001320 }else{
1321 zSelect = appendText(zSelect, ") ", 0);
1322 }
drh157e29a2009-05-21 15:15:00 +00001323 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001324 }
1325 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001326 if( rc!=SQLITE_OK || nRow==0 ){
1327 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001328 return 1;
1329 }
1330 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1331 zSelect = appendText(zSelect, zTable, '"');
1332
drh2f464a02011-10-13 00:41:49 +00001333 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001334 if( rc==SQLITE_CORRUPT ){
1335 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001336 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001337 }
drh85e72432012-04-11 11:38:53 +00001338 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001339 }
drh4c653a02000-06-07 01:27:47 +00001340 return 0;
1341}
1342
1343/*
drh45e29d82006-11-20 16:21:10 +00001344** Run zQuery. Use dump_callback() as the callback routine so that
1345** the contents of the query are output as SQL statements.
1346**
drhdd3d4592004-08-30 01:54:05 +00001347** If we get a SQLITE_CORRUPT error, rerun the query after appending
1348** "ORDER BY rowid DESC" to the end.
1349*/
1350static int run_schema_dump_query(
1351 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001352 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001353){
1354 int rc;
drh2f464a02011-10-13 00:41:49 +00001355 char *zErr = 0;
1356 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001357 if( rc==SQLITE_CORRUPT ){
1358 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001359 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001360 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1361 if( zErr ){
1362 fprintf(p->out, "/****** %s ******/\n", zErr);
1363 sqlite3_free(zErr);
1364 zErr = 0;
1365 }
drhdd3d4592004-08-30 01:54:05 +00001366 zQ2 = malloc( len+100 );
1367 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001368 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001369 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1370 if( rc ){
1371 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1372 }else{
1373 rc = SQLITE_CORRUPT;
1374 }
1375 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001376 free(zQ2);
1377 }
1378 return rc;
1379}
1380
1381/*
drh75897232000-05-29 14:26:00 +00001382** Text of a help message
1383*/
persicom1d0b8722002-04-18 02:53:04 +00001384static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001385 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001386 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001387 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001388 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001389 " If TABLE specified, only dump tables matching\n"
1390 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001391 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001392 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001393 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1394 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001395 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001396 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001397 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001398 ".indices ?TABLE? Show names of all indices\n"
1399 " If TABLE specified, only show indices for tables\n"
1400 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001401#ifdef SQLITE_ENABLE_IOTRACE
1402 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1403#endif
drh70df4fe2006-06-13 15:12:21 +00001404#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001405 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001406#endif
drh127f9d72010-02-23 01:47:00 +00001407 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001408 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001409 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001410 " column Left-aligned columns. (See .width)\n"
1411 " html HTML <table> code\n"
1412 " insert SQL insert statements for TABLE\n"
1413 " line One value per line\n"
1414 " list Values delimited by .separator string\n"
1415 " tabs Tab-separated values\n"
1416 " tcl TCL list elements\n"
1417 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001418 ".output FILENAME Send output to FILENAME\n"
1419 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001420 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001421 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001422 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001423 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001424 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001425 " If TABLE specified, only show tables matching\n"
1426 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001427 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001428 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001429 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001430 ".tables ?TABLE? List names of tables\n"
1431 " If TABLE specified, only list tables matching\n"
1432 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001433 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001434 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001435 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001436 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001437;
1438
shaneb320ccd2009-10-21 03:42:58 +00001439static char zTimerHelp[] =
1440 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1441;
1442
drhdaffd0e2001-04-11 14:28:42 +00001443/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001444static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001445
drh75897232000-05-29 14:26:00 +00001446/*
drh44c2eb12003-04-30 11:38:26 +00001447** Make sure the database is open. If it is not, then open it. If
1448** the database fails to open, print an error message and exit.
1449*/
1450static void open_db(struct callback_data *p){
1451 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001452 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001453 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001454 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001455 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1456 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1457 shellstaticFunc, 0, 0);
1458 }
1459 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001460 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001461 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001462 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001463 }
drhc2e87a32006-06-27 15:16:14 +00001464#ifndef SQLITE_OMIT_LOAD_EXTENSION
1465 sqlite3_enable_load_extension(p->db, 1);
1466#endif
drh44c2eb12003-04-30 11:38:26 +00001467 }
1468}
1469
1470/*
drhfeac5f82004-08-01 00:10:45 +00001471** Do C-language style dequoting.
1472**
1473** \t -> tab
1474** \n -> newline
1475** \r -> carriage return
1476** \NNN -> ascii character NNN in octal
1477** \\ -> backslash
1478*/
1479static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001480 int i, j;
1481 char c;
drhfeac5f82004-08-01 00:10:45 +00001482 for(i=j=0; (c = z[i])!=0; i++, j++){
1483 if( c=='\\' ){
1484 c = z[++i];
1485 if( c=='n' ){
1486 c = '\n';
1487 }else if( c=='t' ){
1488 c = '\t';
1489 }else if( c=='r' ){
1490 c = '\r';
1491 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001492 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001493 if( z[i+1]>='0' && z[i+1]<='7' ){
1494 i++;
1495 c = (c<<3) + z[i] - '0';
1496 if( z[i+1]>='0' && z[i+1]<='7' ){
1497 i++;
1498 c = (c<<3) + z[i] - '0';
1499 }
1500 }
1501 }
1502 }
1503 z[j] = c;
1504 }
1505 z[j] = 0;
1506}
1507
1508/*
drhc28490c2006-10-26 14:25:58 +00001509** Interpret zArg as a boolean value. Return either 0 or 1.
1510*/
1511static int booleanValue(char *zArg){
1512 int val = atoi(zArg);
1513 int j;
1514 for(j=0; zArg[j]; j++){
drhf0693c82011-10-11 20:41:54 +00001515 zArg[j] = ToLower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001516 }
1517 if( strcmp(zArg,"on")==0 ){
1518 val = 1;
1519 }else if( strcmp(zArg,"yes")==0 ){
1520 val = 1;
1521 }
1522 return val;
1523}
1524
1525/*
drh42f64e52012-04-04 16:56:23 +00001526** Close an output file, assuming it is not stderr or stdout
1527*/
1528static void output_file_close(FILE *f){
1529 if( f && f!=stdout && f!=stderr ) fclose(f);
1530}
1531
1532/*
1533** Try to open an output file. The names "stdout" and "stderr" are
1534** recognized and do the right thing. NULL is returned if the output
1535** filename is "off".
1536*/
1537static FILE *output_file_open(const char *zFile){
1538 FILE *f;
1539 if( strcmp(zFile,"stdout")==0 ){
1540 f = stdout;
1541 }else if( strcmp(zFile, "stderr")==0 ){
1542 f = stderr;
1543 }else if( strcmp(zFile, "off")==0 ){
1544 f = 0;
1545 }else{
1546 f = fopen(zFile, "wb");
1547 if( f==0 ){
1548 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1549 }
1550 }
1551 return f;
1552}
1553
1554/*
1555** A routine for handling output from sqlite3_trace().
1556*/
1557static void sql_trace_callback(void *pArg, const char *z){
1558 FILE *f = (FILE*)pArg;
1559 if( f ) fprintf(f, "%s\n", z);
1560}
1561
1562/*
drhd8621b92012-04-17 09:09:33 +00001563** A no-op routine that runs with the ".breakpoint" doc-command. This is
1564** a useful spot to set a debugger breakpoint.
1565*/
1566static void test_breakpoint(void){
1567 static int nCall = 0;
1568 nCall++;
1569}
1570
1571/*
drh75897232000-05-29 14:26:00 +00001572** If an input line begins with "." then invoke this routine to
1573** process that line.
drh67505e72002-04-19 12:34:06 +00001574**
drh47ad6842006-11-08 12:25:42 +00001575** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001576*/
drh44c2eb12003-04-30 11:38:26 +00001577static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001578 int i = 1;
1579 int nArg = 0;
1580 int n, c;
drh67505e72002-04-19 12:34:06 +00001581 int rc = 0;
drh75897232000-05-29 14:26:00 +00001582 char *azArg[50];
1583
1584 /* Parse the input line into tokens.
1585 */
1586 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001587 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001588 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001589 if( zLine[i]=='\'' || zLine[i]=='"' ){
1590 int delim = zLine[i++];
1591 azArg[nArg++] = &zLine[i];
1592 while( zLine[i] && zLine[i]!=delim ){ i++; }
1593 if( zLine[i]==delim ){
1594 zLine[i++] = 0;
1595 }
drhfeac5f82004-08-01 00:10:45 +00001596 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001597 }else{
1598 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001599 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001600 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001601 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001602 }
1603 }
1604
1605 /* Process the input line.
1606 */
shane9bd1b442009-10-23 01:27:39 +00001607 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001608 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001609 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001610 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001611 const char *zDestFile;
1612 const char *zDb;
1613 sqlite3 *pDest;
1614 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001615 if( nArg==2 ){
1616 zDestFile = azArg[1];
1617 zDb = "main";
1618 }else{
1619 zDestFile = azArg[2];
1620 zDb = azArg[1];
1621 }
1622 rc = sqlite3_open(zDestFile, &pDest);
1623 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001624 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001625 sqlite3_close(pDest);
1626 return 1;
1627 }
drhdc2c4912009-02-04 22:46:47 +00001628 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001629 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1630 if( pBackup==0 ){
1631 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1632 sqlite3_close(pDest);
1633 return 1;
1634 }
1635 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1636 sqlite3_backup_finish(pBackup);
1637 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001638 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001639 }else{
1640 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001641 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001642 }
1643 sqlite3_close(pDest);
1644 }else
1645
shanehe2aa9d72009-11-06 17:20:17 +00001646 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001647 bail_on_error = booleanValue(azArg[1]);
1648 }else
1649
drhd8621b92012-04-17 09:09:33 +00001650 /* The undocumented ".breakpoint" command causes a call to the no-op
1651 ** routine named test_breakpoint().
1652 */
1653 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1654 test_breakpoint();
1655 }else
1656
shanehe2aa9d72009-11-06 17:20:17 +00001657 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001658 struct callback_data data;
1659 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001660 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001661 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001662 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001663 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001664 data.colWidth[0] = 3;
1665 data.colWidth[1] = 15;
1666 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001667 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001668 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001669 if( zErrMsg ){
1670 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001671 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001672 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001673 }
1674 }else
1675
shanehe2aa9d72009-11-06 17:20:17 +00001676 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001677 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001678 /* When playing back a "dump", the content might appear in an order
1679 ** which causes immediate foreign key constraints to be violated.
1680 ** So disable foreign-key constraint enforcement to prevent problems. */
1681 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001682 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001683 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001684 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001685 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001686 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001687 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001688 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001689 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001690 );
1691 run_schema_dump_query(p,
1692 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001693 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001694 );
drh2f464a02011-10-13 00:41:49 +00001695 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001696 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001697 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001698 );
drh4c653a02000-06-07 01:27:47 +00001699 }else{
1700 int i;
drhdd3d4592004-08-30 01:54:05 +00001701 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001702 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001703 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001704 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001705 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001706 " AND sql NOT NULL");
1707 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001708 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001709 "WHERE sql NOT NULL"
1710 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001711 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001712 );
danielk1977bc6ada42004-06-30 08:20:16 +00001713 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001714 }
1715 }
drh45e29d82006-11-20 16:21:10 +00001716 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001717 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001718 p->writableSchema = 0;
1719 }
drh56197952011-10-13 16:30:13 +00001720 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1721 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001722 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001723 }else
drh75897232000-05-29 14:26:00 +00001724
shanehe2aa9d72009-11-06 17:20:17 +00001725 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001726 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001727 }else
1728
shanehe2aa9d72009-11-06 17:20:17 +00001729 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001730 rc = 2;
drh75897232000-05-29 14:26:00 +00001731 }else
1732
shanehe2aa9d72009-11-06 17:20:17 +00001733 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001734 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001735 if(val == 1) {
1736 if(!p->explainPrev.valid) {
1737 p->explainPrev.valid = 1;
1738 p->explainPrev.mode = p->mode;
1739 p->explainPrev.showHeader = p->showHeader;
1740 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1741 }
1742 /* We could put this code under the !p->explainValid
1743 ** condition so that it does not execute if we are already in
1744 ** explain mode. However, always executing it allows us an easy
1745 ** was to reset to explain mode in case the user previously
1746 ** did an .explain followed by a .width, .mode or .header
1747 ** command.
1748 */
danielk19770d78bae2008-01-03 07:09:48 +00001749 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001750 p->showHeader = 1;
1751 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001752 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001753 p->colWidth[1] = 13; /* opcode */
1754 p->colWidth[2] = 4; /* P1 */
1755 p->colWidth[3] = 4; /* P2 */
1756 p->colWidth[4] = 4; /* P3 */
1757 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001758 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001759 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001760 }else if (p->explainPrev.valid) {
1761 p->explainPrev.valid = 0;
1762 p->mode = p->explainPrev.mode;
1763 p->showHeader = p->explainPrev.showHeader;
1764 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1765 }
drh75897232000-05-29 14:26:00 +00001766 }else
1767
drhc28490c2006-10-26 14:25:58 +00001768 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001769 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001770 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001771 }else
1772
1773 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001774 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001775 if( HAS_TIMER ){
1776 fprintf(stderr,"%s",zTimerHelp);
1777 }
drh75897232000-05-29 14:26:00 +00001778 }else
1779
shanehe2aa9d72009-11-06 17:20:17 +00001780 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001781 char *zTable = azArg[2]; /* Insert data into this table */
1782 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001783 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001784 int nCol; /* Number of columns in the table */
1785 int nByte; /* Number of bytes in an SQL string */
1786 int i, j; /* Loop counters */
1787 int nSep; /* Number of bytes in p->separator[] */
1788 char *zSql; /* An SQL statement */
1789 char *zLine; /* A single line of input from the file */
1790 char **azCol; /* zLine[] broken up into columns */
1791 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001792 FILE *in; /* The input file */
1793 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001794
drha543c822006-06-08 16:10:14 +00001795 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001796 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001797 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001798 fprintf(stderr, "Error: non-null separator required for import\n");
1799 return 1;
drhfeac5f82004-08-01 00:10:45 +00001800 }
drh7b075e32011-09-28 01:10:00 +00001801 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00001802 if( zSql==0 ){
1803 fprintf(stderr, "Error: out of memory\n");
1804 return 1;
1805 }
drh4f21c4a2008-12-10 22:15:00 +00001806 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001807 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001808 sqlite3_free(zSql);
1809 if( rc ){
shane916f9612009-10-23 00:37:15 +00001810 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001811 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001812 return 1;
drhfeac5f82004-08-01 00:10:45 +00001813 }
shane916f9612009-10-23 00:37:15 +00001814 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001815 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001816 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001817 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001818 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001819 if( zSql==0 ){
1820 fprintf(stderr, "Error: out of memory\n");
1821 return 1;
1822 }
drh7b075e32011-09-28 01:10:00 +00001823 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001824 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001825 for(i=1; i<nCol; i++){
1826 zSql[j++] = ',';
1827 zSql[j++] = '?';
1828 }
1829 zSql[j++] = ')';
1830 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001831 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001832 free(zSql);
1833 if( rc ){
1834 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001835 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001836 return 1;
drhfeac5f82004-08-01 00:10:45 +00001837 }
1838 in = fopen(zFile, "rb");
1839 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001840 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001841 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001842 return 1;
drhfeac5f82004-08-01 00:10:45 +00001843 }
1844 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001845 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001846 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001847 fclose(in);
shane916f9612009-10-23 00:37:15 +00001848 sqlite3_finalize(pStmt);
1849 return 1;
drh43617e92006-03-06 20:55:46 +00001850 }
drhfeac5f82004-08-01 00:10:45 +00001851 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1852 zCommit = "COMMIT";
drh18f52e02012-01-16 16:56:31 +00001853 while( (zLine = local_getline(0, in, 1))!=0 ){
1854 char *z, c;
1855 int inQuote = 0;
drhb860bc92004-08-04 15:16:55 +00001856 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001857 azCol[0] = zLine;
drh18f52e02012-01-16 16:56:31 +00001858 for(i=0, z=zLine; (c = *z)!=0; z++){
1859 if( c=='"' ) inQuote = !inQuote;
1860 if( c=='\n' ) lineno++;
1861 if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001862 *z = 0;
1863 i++;
drhb860bc92004-08-04 15:16:55 +00001864 if( i<nCol ){
1865 azCol[i] = &z[nSep];
1866 z += nSep-1;
1867 }
drhfeac5f82004-08-01 00:10:45 +00001868 }
shane916f9612009-10-23 00:37:15 +00001869 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001870 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001871 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001872 fprintf(stderr,
1873 "Error: %s line %d: expected %d columns of data but found %d\n",
1874 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001875 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001876 free(zLine);
shane916f9612009-10-23 00:37:15 +00001877 rc = 1;
1878 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001879 }
drhfeac5f82004-08-01 00:10:45 +00001880 for(i=0; i<nCol; i++){
drh18f52e02012-01-16 16:56:31 +00001881 if( azCol[i][0]=='"' ){
1882 int k;
1883 for(z=azCol[i], j=1, k=0; z[j]; j++){
1884 if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1885 z[k++] = z[j];
1886 }
1887 z[k] = 0;
1888 }
drhfeac5f82004-08-01 00:10:45 +00001889 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1890 }
1891 sqlite3_step(pStmt);
1892 rc = sqlite3_reset(pStmt);
1893 free(zLine);
1894 if( rc!=SQLITE_OK ){
1895 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1896 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001897 rc = 1;
shane916f9612009-10-23 00:37:15 +00001898 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001899 }
shane916f9612009-10-23 00:37:15 +00001900 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001901 free(azCol);
1902 fclose(in);
1903 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001904 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001905 }else
1906
shanehe2aa9d72009-11-06 17:20:17 +00001907 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001908 struct callback_data data;
1909 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001910 open_db(p);
drh75897232000-05-29 14:26:00 +00001911 memcpy(&data, p, sizeof(data));
1912 data.showHeader = 0;
1913 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001914 if( nArg==1 ){
1915 rc = sqlite3_exec(p->db,
1916 "SELECT name FROM sqlite_master "
1917 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1918 "UNION ALL "
1919 "SELECT name FROM sqlite_temp_master "
1920 "WHERE type='index' "
1921 "ORDER BY 1",
1922 callback, &data, &zErrMsg
1923 );
1924 }else{
1925 zShellStatic = azArg[1];
1926 rc = sqlite3_exec(p->db,
1927 "SELECT name FROM sqlite_master "
1928 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1929 "UNION ALL "
1930 "SELECT name FROM sqlite_temp_master "
1931 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1932 "ORDER BY 1",
1933 callback, &data, &zErrMsg
1934 );
1935 zShellStatic = 0;
1936 }
drh75897232000-05-29 14:26:00 +00001937 if( zErrMsg ){
1938 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001939 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001940 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001941 }else if( rc != SQLITE_OK ){
1942 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1943 rc = 1;
drh75897232000-05-29 14:26:00 +00001944 }
1945 }else
1946
drhae5e4452007-05-03 17:18:36 +00001947#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001948 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001949 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001950 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1951 iotrace = 0;
1952 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001953 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001954 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001955 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001956 iotrace = stdout;
1957 }else{
1958 iotrace = fopen(azArg[1], "w");
1959 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001960 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001961 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001962 rc = 1;
drhb0603412007-02-28 04:47:26 +00001963 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001964 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001965 }
1966 }
1967 }else
drhae5e4452007-05-03 17:18:36 +00001968#endif
drhb0603412007-02-28 04:47:26 +00001969
drh70df4fe2006-06-13 15:12:21 +00001970#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001971 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1972 const char *zFile, *zProc;
1973 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001974 zFile = azArg[1];
1975 zProc = nArg>=3 ? azArg[2] : 0;
1976 open_db(p);
1977 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1978 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001979 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001980 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001981 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001982 }
1983 }else
drh70df4fe2006-06-13 15:12:21 +00001984#endif
drh1e397f82006-06-08 15:28:43 +00001985
drhc8ba2122011-03-23 11:16:22 +00001986 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00001987 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00001988 output_file_close(p->pLog);
1989 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00001990 }else
1991
shanehe2aa9d72009-11-06 17:20:17 +00001992 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001993 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001994 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001995 ||
shanehe2aa9d72009-11-06 17:20:17 +00001996 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001997 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001998 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001999 ||
shanehe2aa9d72009-11-06 17:20:17 +00002000 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002001 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002002 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002003 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002004 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002005 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002006 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002007 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00002008 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002009 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002010 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002011 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002012 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002013 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002014 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002015 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002016 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002017 }else {
shane9bd1b442009-10-23 01:27:39 +00002018 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002019 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002020 rc = 1;
drh75897232000-05-29 14:26:00 +00002021 }
2022 }else
2023
shanehe2aa9d72009-11-06 17:20:17 +00002024 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2025 int n2 = strlen30(azArg[1]);
2026 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2027 p->mode = MODE_Insert;
2028 set_table_name(p, azArg[2]);
2029 }else {
2030 fprintf(stderr, "Error: invalid arguments: "
2031 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2032 rc = 1;
2033 }
2034 }else
2035
persicom7e2dfdd2002-04-18 02:46:52 +00002036 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002037 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2038 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002039 }else
2040
drh75897232000-05-29 14:26:00 +00002041 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002042 if( p->outfile[0]=='|' ){
2043 pclose(p->out);
2044 }else{
2045 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002046 }
drh42f64e52012-04-04 16:56:23 +00002047 p->outfile[0] = 0;
2048 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002049 p->out = popen(&azArg[1][1], "w");
2050 if( p->out==0 ){
2051 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2052 p->out = stdout;
2053 rc = 1;
2054 }else{
2055 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2056 }
drh75897232000-05-29 14:26:00 +00002057 }else{
drh42f64e52012-04-04 16:56:23 +00002058 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002059 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002060 if( strcmp(azArg[1],"off")!=0 ){
2061 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2062 }
drh75897232000-05-29 14:26:00 +00002063 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002064 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002065 } else {
drh42f64e52012-04-04 16:56:23 +00002066 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002067 }
2068 }
2069 }else
2070
drhdd45df82002-04-18 12:39:03 +00002071 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002072 if( nArg >= 2) {
2073 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2074 }
2075 if( nArg >= 3) {
2076 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2077 }
2078 }else
2079
shanehe2aa9d72009-11-06 17:20:17 +00002080 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002081 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002082 }else
2083
drh9ff849f2009-02-04 20:55:57 +00002084 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002085 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002086 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002087 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2088 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002089 }else{
shane9bd1b442009-10-23 01:27:39 +00002090 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002091 fclose(alt);
2092 }
2093 }else
2094
shanehe2aa9d72009-11-06 17:20:17 +00002095 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002096 const char *zSrcFile;
2097 const char *zDb;
2098 sqlite3 *pSrc;
2099 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002100 int nTimeout = 0;
2101
drh9ff849f2009-02-04 20:55:57 +00002102 if( nArg==2 ){
2103 zSrcFile = azArg[1];
2104 zDb = "main";
2105 }else{
2106 zSrcFile = azArg[2];
2107 zDb = azArg[1];
2108 }
2109 rc = sqlite3_open(zSrcFile, &pSrc);
2110 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002111 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002112 sqlite3_close(pSrc);
2113 return 1;
2114 }
drhdc2c4912009-02-04 22:46:47 +00002115 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002116 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2117 if( pBackup==0 ){
2118 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2119 sqlite3_close(pSrc);
2120 return 1;
2121 }
drhdc2c4912009-02-04 22:46:47 +00002122 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2123 || rc==SQLITE_BUSY ){
2124 if( rc==SQLITE_BUSY ){
2125 if( nTimeout++ >= 3 ) break;
2126 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002127 }
2128 }
2129 sqlite3_backup_finish(pBackup);
2130 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002131 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002132 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002133 fprintf(stderr, "Error: source database is busy\n");
2134 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002135 }else{
2136 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002137 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002138 }
2139 sqlite3_close(pSrc);
2140 }else
2141
shanehe2aa9d72009-11-06 17:20:17 +00002142 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002143 struct callback_data data;
2144 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002145 open_db(p);
drh75897232000-05-29 14:26:00 +00002146 memcpy(&data, p, sizeof(data));
2147 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002148 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002149 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002150 int i;
drhf0693c82011-10-11 20:41:54 +00002151 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002152 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002153 char *new_argv[2], *new_colv[2];
2154 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2155 " type text,\n"
2156 " name text,\n"
2157 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002158 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002159 " sql text\n"
2160 ")";
2161 new_argv[1] = 0;
2162 new_colv[0] = "sql";
2163 new_colv[1] = 0;
2164 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002165 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002166 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002167 char *new_argv[2], *new_colv[2];
2168 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2169 " type text,\n"
2170 " name text,\n"
2171 " tbl_name text,\n"
2172 " rootpage integer,\n"
2173 " sql text\n"
2174 ")";
2175 new_argv[1] = 0;
2176 new_colv[0] = "sql";
2177 new_colv[1] = 0;
2178 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002179 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002180 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002181 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002182 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002183 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002184 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002185 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002186 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002187 "WHERE lower(tbl_name) LIKE shellstatic()"
2188 " AND type!='meta' AND sql NOTNULL "
drhac43e982012-05-21 03:15:06 +00002189 "ORDER BY substr(type,2,1), "
2190 " CASE type WHEN 'view' THEN rowid ELSE name END",
danielk1977bc6ada42004-06-30 08:20:16 +00002191 callback, &data, &zErrMsg);
2192 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002193 }
drh75897232000-05-29 14:26:00 +00002194 }else{
shane9bd1b442009-10-23 01:27:39 +00002195 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002196 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002197 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002198 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002199 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002200 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhac43e982012-05-21 03:15:06 +00002201 "ORDER BY substr(type,2,1),"
2202 " CASE type WHEN 'view' THEN rowid ELSE name END",
drha18c5682000-10-08 22:20:57 +00002203 callback, &data, &zErrMsg
2204 );
drh75897232000-05-29 14:26:00 +00002205 }
drh75897232000-05-29 14:26:00 +00002206 if( zErrMsg ){
2207 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002208 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002209 rc = 1;
2210 }else if( rc != SQLITE_OK ){
2211 fprintf(stderr,"Error: querying schema information\n");
2212 rc = 1;
2213 }else{
2214 rc = 0;
drh75897232000-05-29 14:26:00 +00002215 }
2216 }else
2217
2218 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002219 sqlite3_snprintf(sizeof(p->separator), p->separator,
2220 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002221 }else
2222
shanehe2aa9d72009-11-06 17:20:17 +00002223 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002224 int i;
2225 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002226 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002227 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002228 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002229 fprintf(p->out,"%9.9s: ", "nullvalue");
2230 output_c_string(p->out, p->nullvalue);
2231 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002232 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002233 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002234 fprintf(p->out,"%9.9s: ", "separator");
2235 output_c_string(p->out, p->separator);
2236 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002237 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002238 fprintf(p->out,"%9.9s: ","width");
2239 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002240 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002241 }
drhfeac5f82004-08-01 00:10:45 +00002242 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002243 }else
2244
shaneh642d8b82010-07-28 16:05:34 +00002245 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2246 p->statsOn = booleanValue(azArg[1]);
2247 }else
2248
shanehe2aa9d72009-11-06 17:20:17 +00002249 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002250 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002251 char **azResult;
drh98781232012-04-23 12:38:05 +00002252 int nRow, nAlloc;
2253 char *zSql = 0;
2254 int ii;
drh44c2eb12003-04-30 11:38:26 +00002255 open_db(p);
drh98781232012-04-23 12:38:05 +00002256 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2257 if( rc ) return rc;
2258 zSql = sqlite3_mprintf(
2259 "SELECT name FROM sqlite_master"
2260 " WHERE type IN ('table','view')"
2261 " AND name NOT LIKE 'sqlite_%%'"
2262 " AND name LIKE ?1");
2263 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2264 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2265 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2266 if( strcmp(zDbName,"temp")==0 ){
2267 zSql = sqlite3_mprintf(
2268 "%z UNION ALL "
2269 "SELECT 'temp.' || name FROM sqlite_temp_master"
2270 " WHERE type IN ('table','view')"
2271 " AND name NOT LIKE 'sqlite_%%'"
2272 " AND name LIKE ?1", zSql);
2273 }else{
2274 zSql = sqlite3_mprintf(
2275 "%z UNION ALL "
2276 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2277 " WHERE type IN ('table','view')"
2278 " AND name NOT LIKE 'sqlite_%%'"
2279 " AND name LIKE ?1", zSql, zDbName, zDbName);
2280 }
drha50da102000-08-08 20:19:09 +00002281 }
drh98781232012-04-23 12:38:05 +00002282 sqlite3_finalize(pStmt);
2283 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2284 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2285 sqlite3_free(zSql);
2286 if( rc ) return rc;
2287 nRow = nAlloc = 0;
2288 azResult = 0;
2289 if( nArg>1 ){
2290 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002291 }else{
drh98781232012-04-23 12:38:05 +00002292 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2293 }
2294 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2295 if( nRow>=nAlloc ){
2296 char **azNew;
2297 int n = nAlloc*2 + 10;
2298 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2299 if( azNew==0 ){
2300 fprintf(stderr, "Error: out of memory\n");
2301 break;
2302 }
2303 nAlloc = n;
2304 azResult = azNew;
2305 }
2306 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2307 if( azResult[nRow] ) nRow++;
2308 }
2309 sqlite3_finalize(pStmt);
2310 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002311 int len, maxlen = 0;
2312 int i, j;
2313 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002314 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002315 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002316 if( len>maxlen ) maxlen = len;
2317 }
2318 nPrintCol = 80/(maxlen+2);
2319 if( nPrintCol<1 ) nPrintCol = 1;
2320 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2321 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002322 for(j=i; j<nRow; j+=nPrintRow){
2323 char *zSp = j<nPrintRow ? "" : " ";
drhe3710332000-09-29 13:30:53 +00002324 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2325 }
2326 printf("\n");
2327 }
2328 }
drh98781232012-04-23 12:38:05 +00002329 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2330 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002331 }else
2332
shaneh96887e12011-02-10 21:08:58 +00002333 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002334 static const struct {
2335 const char *zCtrlName; /* Name of a test-control option */
2336 int ctrlCode; /* Integer code for that option */
2337 } aCtrl[] = {
2338 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2339 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2340 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2341 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2342 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2343 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2344 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2345 { "assert", SQLITE_TESTCTRL_ASSERT },
2346 { "always", SQLITE_TESTCTRL_ALWAYS },
2347 { "reserve", SQLITE_TESTCTRL_RESERVE },
2348 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2349 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002350 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2351 };
shaneh96887e12011-02-10 21:08:58 +00002352 int testctrl = -1;
2353 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002354 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002355 open_db(p);
2356
drhd416fe72011-03-17 16:45:50 +00002357 /* convert testctrl text option to value. allow any unique prefix
2358 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002359 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002360 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002361 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2362 if( testctrl<0 ){
2363 testctrl = aCtrl[i].ctrlCode;
2364 }else{
drhb07028f2011-10-14 21:49:18 +00002365 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002366 testctrl = -1;
2367 break;
2368 }
2369 }
2370 }
2371 if( testctrl<0 ) testctrl = atoi(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002372 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2373 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2374 }else{
2375 switch(testctrl){
2376
2377 /* sqlite3_test_control(int, db, int) */
2378 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2379 case SQLITE_TESTCTRL_RESERVE:
2380 if( nArg==3 ){
2381 int opt = (int)strtol(azArg[2], 0, 0);
2382 rc = sqlite3_test_control(testctrl, p->db, opt);
2383 printf("%d (0x%08x)\n", rc, rc);
2384 } else {
drhd416fe72011-03-17 16:45:50 +00002385 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2386 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002387 }
2388 break;
2389
2390 /* sqlite3_test_control(int) */
2391 case SQLITE_TESTCTRL_PRNG_SAVE:
2392 case SQLITE_TESTCTRL_PRNG_RESTORE:
2393 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002394 if( nArg==2 ){
2395 rc = sqlite3_test_control(testctrl);
2396 printf("%d (0x%08x)\n", rc, rc);
2397 } else {
2398 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2399 }
2400 break;
2401
2402 /* sqlite3_test_control(int, uint) */
2403 case SQLITE_TESTCTRL_PENDING_BYTE:
2404 if( nArg==3 ){
2405 unsigned int opt = (unsigned int)atoi(azArg[2]);
2406 rc = sqlite3_test_control(testctrl, opt);
2407 printf("%d (0x%08x)\n", rc, rc);
2408 } else {
drhd416fe72011-03-17 16:45:50 +00002409 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2410 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002411 }
2412 break;
2413
2414 /* sqlite3_test_control(int, int) */
2415 case SQLITE_TESTCTRL_ASSERT:
2416 case SQLITE_TESTCTRL_ALWAYS:
2417 if( nArg==3 ){
2418 int opt = atoi(azArg[2]);
2419 rc = sqlite3_test_control(testctrl, opt);
2420 printf("%d (0x%08x)\n", rc, rc);
2421 } else {
drhd416fe72011-03-17 16:45:50 +00002422 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2423 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002424 }
2425 break;
2426
2427 /* sqlite3_test_control(int, char *) */
2428#ifdef SQLITE_N_KEYWORD
2429 case SQLITE_TESTCTRL_ISKEYWORD:
2430 if( nArg==3 ){
2431 const char *opt = azArg[2];
2432 rc = sqlite3_test_control(testctrl, opt);
2433 printf("%d (0x%08x)\n", rc, rc);
2434 } else {
drhd416fe72011-03-17 16:45:50 +00002435 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2436 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002437 }
2438 break;
2439#endif
2440
2441 case SQLITE_TESTCTRL_BITVEC_TEST:
2442 case SQLITE_TESTCTRL_FAULT_INSTALL:
2443 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2444 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2445 default:
drhd416fe72011-03-17 16:45:50 +00002446 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2447 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002448 break;
2449 }
2450 }
2451 }else
2452
shanehe2aa9d72009-11-06 17:20:17 +00002453 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002454 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002455 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002456 }else
2457
drhd416fe72011-03-17 16:45:50 +00002458 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2459 && nArg==2
2460 ){
drh3b1a9882007-11-02 12:53:03 +00002461 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002462 }else
2463
drh42f64e52012-04-04 16:56:23 +00002464 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh98781232012-04-23 12:38:05 +00002465 open_db(p);
drh42f64e52012-04-04 16:56:23 +00002466 output_file_close(p->traceOut);
2467 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00002468#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002469 if( p->traceOut==0 ){
2470 sqlite3_trace(p->db, 0, 0);
2471 }else{
2472 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2473 }
2474#endif
2475 }else
2476
drh9fd301b2011-06-03 13:28:22 +00002477 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh743e0032011-12-12 16:51:50 +00002478 printf("SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002479 sqlite3_libversion(), sqlite3_sourceid());
2480 }else
2481
drhde60fc22011-12-14 17:53:36 +00002482 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2483 const char *zDbName = nArg==2 ? azArg[1] : "main";
2484 char *zVfsName = 0;
2485 if( p->db ){
2486 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2487 if( zVfsName ){
2488 printf("%s\n", zVfsName);
2489 sqlite3_free(zVfsName);
2490 }
2491 }
2492 }else
2493
shanehe2aa9d72009-11-06 17:20:17 +00002494 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002495 int j;
drh43617e92006-03-06 20:55:46 +00002496 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002497 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2498 p->colWidth[j-1] = atoi(azArg[j]);
2499 }
2500 }else
2501
2502 {
shane9bd1b442009-10-23 01:27:39 +00002503 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002504 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002505 rc = 1;
drh75897232000-05-29 14:26:00 +00002506 }
drh67505e72002-04-19 12:34:06 +00002507
2508 return rc;
drh75897232000-05-29 14:26:00 +00002509}
2510
drh67505e72002-04-19 12:34:06 +00002511/*
drh91a66392007-09-07 01:12:32 +00002512** Return TRUE if a semicolon occurs anywhere in the first N characters
2513** of string z[].
drh324ccef2003-02-05 14:06:20 +00002514*/
drh91a66392007-09-07 01:12:32 +00002515static int _contains_semicolon(const char *z, int N){
2516 int i;
2517 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2518 return 0;
drh324ccef2003-02-05 14:06:20 +00002519}
2520
2521/*
drh70c7a4b2003-04-26 03:03:06 +00002522** Test to see if a line consists entirely of whitespace.
2523*/
2524static int _all_whitespace(const char *z){
2525 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002526 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002527 if( *z=='/' && z[1]=='*' ){
2528 z += 2;
2529 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2530 if( *z==0 ) return 0;
2531 z++;
2532 continue;
2533 }
2534 if( *z=='-' && z[1]=='-' ){
2535 z += 2;
2536 while( *z && *z!='\n' ){ z++; }
2537 if( *z==0 ) return 1;
2538 continue;
2539 }
2540 return 0;
2541 }
2542 return 1;
2543}
2544
2545/*
drha9b17162003-04-29 18:01:28 +00002546** Return TRUE if the line typed in is an SQL command terminator other
2547** than a semi-colon. The SQL Server style "go" command is understood
2548** as is the Oracle "/".
2549*/
2550static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002551 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002552 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2553 return 1; /* Oracle */
2554 }
drhf0693c82011-10-11 20:41:54 +00002555 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002556 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002557 return 1; /* SQL Server */
2558 }
2559 return 0;
2560}
2561
2562/*
drh233a5312008-12-18 22:25:13 +00002563** Return true if zSql is a complete SQL statement. Return false if it
2564** ends in the middle of a string literal or C-style comment.
2565*/
2566static int _is_complete(char *zSql, int nSql){
2567 int rc;
2568 if( zSql==0 ) return 1;
2569 zSql[nSql] = ';';
2570 zSql[nSql+1] = 0;
2571 rc = sqlite3_complete(zSql);
2572 zSql[nSql] = 0;
2573 return rc;
2574}
2575
2576/*
drh67505e72002-04-19 12:34:06 +00002577** Read input from *in and process it. If *in==0 then input
2578** is interactive - the user is typing it it. Otherwise, input
2579** is coming from a file or device. A prompt is issued and history
2580** is saved only if input is interactive. An interrupt signal will
2581** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002582**
2583** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002584*/
drhc28490c2006-10-26 14:25:58 +00002585static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002586 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002587 char *zSql = 0;
2588 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002589 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002590 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002591 int rc;
2592 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002593 int lineno = 0;
2594 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002595
2596 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2597 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002598 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002599 zLine = one_input_line(zSql, in);
2600 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002601 /* End of input */
2602 if( stdin_is_interactive ) printf("\n");
2603 break;
drhc49f44e2006-10-26 18:15:42 +00002604 }
drh67505e72002-04-19 12:34:06 +00002605 if( seenInterrupt ){
2606 if( in!=0 ) break;
2607 seenInterrupt = 0;
2608 }
drhc28490c2006-10-26 14:25:58 +00002609 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002610 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002611 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002612 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002613 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002614 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002615 break;
2616 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002617 errCnt++;
2618 }
drhdaffd0e2001-04-11 14:28:42 +00002619 continue;
2620 }
drh233a5312008-12-18 22:25:13 +00002621 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002622 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002623 }
drh91a66392007-09-07 01:12:32 +00002624 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002625 if( zSql==0 ){
2626 int i;
drhf0693c82011-10-11 20:41:54 +00002627 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002628 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002629 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002630 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002631 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002632 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002633 exit(1);
2634 }
drh5bb3eb92007-05-04 13:15:55 +00002635 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002636 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002637 }
2638 }else{
drh4f21c4a2008-12-10 22:15:00 +00002639 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002640 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002641 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002642 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002643 exit(1);
2644 }
drh5bb3eb92007-05-04 13:15:55 +00002645 zSql[nSql++] = '\n';
2646 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002647 nSql += len;
2648 }
drh91a66392007-09-07 01:12:32 +00002649 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2650 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002651 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002652 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002653 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002654 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002655 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002656 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002657 char zPrefix[100];
2658 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002659 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002660 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002661 }else{
shane9bd1b442009-10-23 01:27:39 +00002662 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002663 }
drh7f953e22002-07-13 17:33:45 +00002664 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002665 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002666 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002667 zErrMsg = 0;
2668 }else{
shaned2bed1c2009-10-21 03:56:54 +00002669 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002670 }
drhc49f44e2006-10-26 18:15:42 +00002671 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002672 }
2673 free(zSql);
2674 zSql = 0;
2675 nSql = 0;
2676 }
2677 }
2678 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002679 if( !_all_whitespace(zSql) ){
2680 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2681 }
drhdaffd0e2001-04-11 14:28:42 +00002682 free(zSql);
2683 }
danielk19772ac27622007-07-03 05:31:16 +00002684 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002685 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002686}
2687
drh67505e72002-04-19 12:34:06 +00002688/*
2689** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002690** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002691*/
2692static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002693 static char *home_dir = NULL;
2694 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002695
drh83905c92012-06-21 13:00:37 +00002696#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00002697 {
2698 struct passwd *pwent;
2699 uid_t uid = getuid();
2700 if( (pwent=getpwuid(uid)) != NULL) {
2701 home_dir = pwent->pw_dir;
2702 }
drh67505e72002-04-19 12:34:06 +00002703 }
2704#endif
2705
chw65d3c132007-11-12 21:09:10 +00002706#if defined(_WIN32_WCE)
2707 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2708 */
drh85e72432012-04-11 11:38:53 +00002709 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00002710#else
2711
drh83905c92012-06-21 13:00:37 +00002712#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00002713 if (!home_dir) {
2714 home_dir = getenv("USERPROFILE");
2715 }
2716#endif
2717
drh67505e72002-04-19 12:34:06 +00002718 if (!home_dir) {
2719 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002720 }
2721
drh83905c92012-06-21 13:00:37 +00002722#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00002723 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002724 char *zDrive, *zPath;
2725 int n;
2726 zDrive = getenv("HOMEDRIVE");
2727 zPath = getenv("HOMEPATH");
2728 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002729 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002730 home_dir = malloc( n );
2731 if( home_dir==0 ) return 0;
2732 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2733 return home_dir;
2734 }
2735 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002736 }
2737#endif
2738
chw65d3c132007-11-12 21:09:10 +00002739#endif /* !_WIN32_WCE */
2740
drh67505e72002-04-19 12:34:06 +00002741 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002742 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002743 char *z = malloc( n );
2744 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002745 home_dir = z;
2746 }
drhe98d4fa2002-04-21 19:06:22 +00002747
drh67505e72002-04-19 12:34:06 +00002748 return home_dir;
2749}
2750
2751/*
2752** Read input from the file given by sqliterc_override. Or if that
2753** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002754**
2755** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002756*/
shane9bd1b442009-10-23 01:27:39 +00002757static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002758 struct callback_data *p, /* Configuration data */
2759 const char *sqliterc_override /* Name of config file. NULL to use default */
2760){
persicom7e2dfdd2002-04-18 02:46:52 +00002761 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002762 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002763 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002764 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00002765 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002766
2767 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002768 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002769 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002770#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002771 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002772#endif
shane9bd1b442009-10-23 01:27:39 +00002773 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002774 }
drh2f3de322012-06-27 16:41:31 +00002775 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00002776 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
2777 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002778 }
drha1f9b5e2004-02-14 16:31:02 +00002779 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002780 if( in ){
drhc28490c2006-10-26 14:25:58 +00002781 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002782 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002783 }
shane9bd1b442009-10-23 01:27:39 +00002784 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002785 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002786 }
drh85e72432012-04-11 11:38:53 +00002787 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002788 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002789}
2790
drh67505e72002-04-19 12:34:06 +00002791/*
drhe1e38c42003-05-04 18:30:59 +00002792** Show available command line options
2793*/
2794static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00002795 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00002796 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002797 " -column set output mode to 'column'\n"
drhcc3b4f82012-02-07 14:13:50 +00002798 " -cmd command run \"command\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00002799 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00002800 " -echo print commands before execution\n"
2801 " -init filename read/process named file\n"
2802 " -[no]header turn headers on or off\n"
2803 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002804 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00002805 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002806 " -line set output mode to 'line'\n"
2807 " -list set output mode to 'list'\n"
drhcc3b4f82012-02-07 14:13:50 +00002808#ifdef SQLITE_ENABLE_MULTIPLEX
2809 " -multiplex enable the multiplexor VFS\n"
2810#endif
2811 " -nullvalue 'text' set text string for NULL values\n"
drhe1e38c42003-05-04 18:30:59 +00002812 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002813 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002814 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002815 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00002816#ifdef SQLITE_ENABLE_VFSTRACE
2817 " -vfstrace enable tracing of all VFS calls\n"
2818#endif
drhe1e38c42003-05-04 18:30:59 +00002819;
2820static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002821 fprintf(stderr,
2822 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2823 "FILENAME is the name of an SQLite database. A new database is created\n"
2824 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002825 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002826 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002827 }else{
2828 fprintf(stderr, "Use the -help option for additional information\n");
2829 }
2830 exit(1);
2831}
2832
2833/*
drh67505e72002-04-19 12:34:06 +00002834** Initialize the state information in data
2835*/
drh0850b532006-01-31 19:31:43 +00002836static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002837 memset(data, 0, sizeof(*data));
2838 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002839 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002840 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00002841 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00002842 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002843 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2844 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002845 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002846}
2847
drh75897232000-05-29 14:26:00 +00002848int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002849 char *zErrMsg = 0;
2850 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002851 const char *zInitFile = 0;
2852 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002853 int i;
drhc28490c2006-10-26 14:25:58 +00002854 int rc = 0;
drh75897232000-05-29 14:26:00 +00002855
drh52784bd2011-05-18 17:15:06 +00002856 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
2857 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
2858 sqlite3_sourceid(), SQLITE_SOURCE_ID);
2859 exit(1);
2860 }
drhdaffd0e2001-04-11 14:28:42 +00002861 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002862 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002863 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002864
drh44c2eb12003-04-30 11:38:26 +00002865 /* Make sure we have a valid signal handler early, before anything
2866 ** else is done.
2867 */
drh4c504392000-10-16 22:06:40 +00002868#ifdef SIGINT
2869 signal(SIGINT, interrupt_handler);
2870#endif
drh44c2eb12003-04-30 11:38:26 +00002871
drh22fbcb82004-02-01 01:22:50 +00002872 /* Do an initial pass through the command-line argument to locate
2873 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002874 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002875 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002876 */
drh22fbcb82004-02-01 01:22:50 +00002877 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002878 char *z;
drh44c2eb12003-04-30 11:38:26 +00002879 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002880 z = argv[i];
drhcc3b4f82012-02-07 14:13:50 +00002881 if( z[1]=='-' ) z++;
2882 if( strcmp(z,"-separator")==0
2883 || strcmp(z,"-nullvalue")==0
2884 || strcmp(z,"-cmd")==0
2885 ){
drh44c2eb12003-04-30 11:38:26 +00002886 i++;
drhcc3b4f82012-02-07 14:13:50 +00002887 }else if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002888 i++;
2889 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002890 /* Need to check for batch mode here to so we can avoid printing
2891 ** informational messages (like from process_sqliterc) before
2892 ** we do the actual processing of arguments later in a second pass.
2893 */
drhcc3b4f82012-02-07 14:13:50 +00002894 }else if( strcmp(z,"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002895 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00002896 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00002897#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00002898 int j, c;
2899 const char *zSize;
2900 sqlite3_int64 szHeap;
2901
2902 zSize = argv[++i];
2903 szHeap = atoi(zSize);
2904 for(j=0; (c = zSize[j])!=0; j++){
2905 if( c=='M' ){ szHeap *= 1000000; break; }
2906 if( c=='K' ){ szHeap *= 1000; break; }
2907 if( c=='G' ){ szHeap *= 1000000000; break; }
2908 }
2909 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00002910 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2911#endif
drh97ae8ff2011-03-16 16:56:29 +00002912#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00002913 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00002914 extern int vfstrace_register(
2915 const char *zTraceName,
2916 const char *zOldVfsName,
2917 int (*xOut)(const char*,void*),
2918 void *pOutArg,
2919 int makeDefault
2920 );
drh2b625e22011-03-16 17:05:28 +00002921 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00002922#endif
drh6f25e892011-07-08 17:02:57 +00002923#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00002924 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00002925 extern int sqlite3_multiple_initialize(const char*,int);
2926 sqlite3_multiplex_initialize(0, 1);
2927#endif
drhcc3b4f82012-02-07 14:13:50 +00002928 }else if( strcmp(z,"-vfs")==0 ){
drh77ec9ba2011-03-15 18:35:44 +00002929 sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
drha7e61d82011-03-12 17:02:57 +00002930 if( pVfs ){
2931 sqlite3_vfs_register(pVfs, 1);
2932 }else{
2933 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
2934 exit(1);
2935 }
drh44c2eb12003-04-30 11:38:26 +00002936 }
2937 }
drh22fbcb82004-02-01 01:22:50 +00002938 if( i<argc ){
2939 data.zDbFilename = argv[i++];
2940 }else{
danielk197703aded42004-11-22 05:26:27 +00002941#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002942 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002943#else
2944 data.zDbFilename = 0;
2945#endif
drh22fbcb82004-02-01 01:22:50 +00002946 }
2947 if( i<argc ){
2948 zFirstCmd = argv[i++];
2949 }
shaneh5fc25012009-11-11 04:17:07 +00002950 if( i<argc ){
2951 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2952 fprintf(stderr,"Use -help for a list of options.\n");
2953 return 1;
2954 }
drh44c2eb12003-04-30 11:38:26 +00002955 data.out = stdout;
2956
drh01b41712005-08-29 23:06:23 +00002957#ifdef SQLITE_OMIT_MEMORYDB
2958 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002959 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2960 return 1;
drh01b41712005-08-29 23:06:23 +00002961 }
2962#endif
2963
drh44c2eb12003-04-30 11:38:26 +00002964 /* Go ahead and open the database file if it already exists. If the
2965 ** file does not exist, delay opening it. This prevents empty database
2966 ** files from being created if a user mistypes the database name argument
2967 ** to the sqlite command-line tool.
2968 */
drhc8d74412004-08-31 23:41:26 +00002969 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002970 open_db(&data);
2971 }
2972
drh22fbcb82004-02-01 01:22:50 +00002973 /* Process the initialization file if there is one. If no -init option
2974 ** is given on the command line, look for a file named ~/.sqliterc and
2975 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002976 */
shane86f5bdb2009-10-24 02:00:07 +00002977 rc = process_sqliterc(&data,zInitFile);
2978 if( rc>0 ){
2979 return rc;
2980 }
drh44c2eb12003-04-30 11:38:26 +00002981
drh22fbcb82004-02-01 01:22:50 +00002982 /* Make a second pass through the command-line argument and set
2983 ** options. This second pass is delayed until after the initialization
2984 ** file is processed so that the command-line arguments will override
2985 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002986 */
drh22fbcb82004-02-01 01:22:50 +00002987 for(i=1; i<argc && argv[i][0]=='-'; i++){
2988 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002989 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002990 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002991 i++;
2992 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002993 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002994 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002995 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002996 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002997 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002998 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002999 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003000 }else if( strcmp(z,"-csv")==0 ){
3001 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003002 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003003 }else if( strcmp(z,"-separator")==0 ){
3004 i++;
shaneh5fc25012009-11-11 04:17:07 +00003005 if(i>=argc){
drhcc3b4f82012-02-07 14:13:50 +00003006 fprintf(stderr,"%s: Error: missing argument for option: %s\n",
3007 Argv0, z);
shaneh5fc25012009-11-11 04:17:07 +00003008 fprintf(stderr,"Use -help for a list of options.\n");
3009 return 1;
3010 }
drh5bb3eb92007-05-04 13:15:55 +00003011 sqlite3_snprintf(sizeof(data.separator), data.separator,
3012 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003013 }else if( strcmp(z,"-nullvalue")==0 ){
3014 i++;
shaneh5fc25012009-11-11 04:17:07 +00003015 if(i>=argc){
drhcc3b4f82012-02-07 14:13:50 +00003016 fprintf(stderr,"%s: Error: missing argument for option: %s\n",
3017 Argv0, z);
shaneh5fc25012009-11-11 04:17:07 +00003018 fprintf(stderr,"Use -help for a list of options.\n");
3019 return 1;
3020 }
drh5bb3eb92007-05-04 13:15:55 +00003021 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
3022 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003023 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003024 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003025 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003026 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003027 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003028 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003029 }else if( strcmp(z,"-stats")==0 ){
3030 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003031 }else if( strcmp(z,"-bail")==0 ){
3032 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003033 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003034 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003035 return 0;
drhc28490c2006-10-26 14:25:58 +00003036 }else if( strcmp(z,"-interactive")==0 ){
3037 stdin_is_interactive = 1;
3038 }else if( strcmp(z,"-batch")==0 ){
3039 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003040 }else if( strcmp(z,"-heap")==0 ){
3041 i++;
drha7e61d82011-03-12 17:02:57 +00003042 }else if( strcmp(z,"-vfs")==0 ){
3043 i++;
drh6f25e892011-07-08 17:02:57 +00003044#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003045 }else if( strcmp(z,"-vfstrace")==0 ){
3046 i++;
drh6f25e892011-07-08 17:02:57 +00003047#endif
3048#ifdef SQLITE_ENABLE_MULTIPLEX
3049 }else if( strcmp(z,"-multiplex")==0 ){
3050 i++;
3051#endif
drhcc3b4f82012-02-07 14:13:50 +00003052 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003053 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003054 }else if( strcmp(z,"-cmd")==0 ){
3055 if( i==argc-1 ) break;
3056 i++;
3057 z = argv[i];
3058 if( z[0]=='.' ){
3059 rc = do_meta_command(z, &data);
3060 if( rc && bail_on_error ) return rc;
3061 }else{
3062 open_db(&data);
3063 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3064 if( zErrMsg!=0 ){
3065 fprintf(stderr,"Error: %s\n", zErrMsg);
3066 if( bail_on_error ) return rc!=0 ? rc : 1;
3067 }else if( rc!=0 ){
3068 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3069 if( bail_on_error ) return rc;
3070 }
3071 }
drh1e5d0e92000-05-31 23:33:17 +00003072 }else{
shane86f5bdb2009-10-24 02:00:07 +00003073 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003074 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003075 return 1;
3076 }
3077 }
drh44c2eb12003-04-30 11:38:26 +00003078
drh22fbcb82004-02-01 01:22:50 +00003079 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003080 /* Run just the command that follows the database name
3081 */
drh22fbcb82004-02-01 01:22:50 +00003082 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003083 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003084 }else{
drh44c2eb12003-04-30 11:38:26 +00003085 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003086 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003087 if( zErrMsg!=0 ){
3088 fprintf(stderr,"Error: %s\n", zErrMsg);
3089 return rc!=0 ? rc : 1;
3090 }else if( rc!=0 ){
3091 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3092 return rc;
drh6ff13852001-11-25 13:18:23 +00003093 }
drh75897232000-05-29 14:26:00 +00003094 }
3095 }else{
drh44c2eb12003-04-30 11:38:26 +00003096 /* Run commands received from standard input
3097 */
drhc28490c2006-10-26 14:25:58 +00003098 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003099 char *zHome;
3100 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003101 int nHistory;
drh75897232000-05-29 14:26:00 +00003102 printf(
drh743e0032011-12-12 16:51:50 +00003103 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003104 "Enter \".help\" for instructions\n"
3105 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003106 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003107 );
drh67505e72002-04-19 12:34:06 +00003108 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003109 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003110 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003111 if( (zHistory = malloc(nHistory))!=0 ){
3112 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3113 }
drh67505e72002-04-19 12:34:06 +00003114 }
danielk19774af00c62005-01-23 23:43:21 +00003115#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003116 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003117#endif
drhc28490c2006-10-26 14:25:58 +00003118 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003119 if( zHistory ){
3120 stifle_history(100);
3121 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003122 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003123 }
drhdaffd0e2001-04-11 14:28:42 +00003124 }else{
drhc28490c2006-10-26 14:25:58 +00003125 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003126 }
3127 }
drh33048c02001-10-01 14:29:22 +00003128 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003129 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003130 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003131 }
drhc28490c2006-10-26 14:25:58 +00003132 return rc;
drh75897232000-05-29 14:26:00 +00003133}