blob: 801ad2ca27ebc2585e0e52bd552eff3439604840 [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
drh454ad582007-11-26 22:54:27 +000039#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
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
drhcdb36b72006-06-12 12:57:45 +000048#ifdef __OS2__
49# include <unistd.h>
50#endif
51
drh81d7fd12010-12-08 00:02:26 +000052#ifdef HAVE_EDITLINE
53# include <editline/editline.h>
54#endif
drh16e59552000-07-31 11:57:37 +000055#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000056# include <readline/readline.h>
57# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000058#endif
59#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
drh18f52e02012-01-16 16:56:31 +000060# define readline(p) local_getline(p,stdin,0)
persicom1d0b8722002-04-18 02:53:04 +000061# define add_history(X)
drh67505e72002-04-19 12:34:06 +000062# define read_history(X)
63# define write_history(X)
64# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000065#endif
66
adamd2e8464a2006-09-06 21:39:40 +000067#if defined(_WIN32) || defined(WIN32)
68# include <io.h>
shane18e526c2008-12-10 22:30:24 +000069#define isatty(h) _isatty(h)
70#define access(f,m) _access((f),(m))
drhe1da8fa2012-03-30 00:05:57 +000071#define popen(a,b) _popen((a),(b))
72#define pclose(x) _pclose(x)
adamd2e8464a2006-09-06 21:39:40 +000073#else
drh4328c8b2003-04-26 02:50:11 +000074/* Make sure isatty() has a prototype.
75*/
drhb2acc3b2011-10-13 16:36:29 +000076extern int isatty(int);
adamd2e8464a2006-09-06 21:39:40 +000077#endif
drh4328c8b2003-04-26 02:50:11 +000078
chw65d3c132007-11-12 21:09:10 +000079#if defined(_WIN32_WCE)
80/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
81 * thus we always assume that we have a console. That can be
82 * overridden with the -batch command line option.
83 */
84#define isatty(x) 1
85#endif
86
drhc6e41722011-04-11 15:36:26 +000087/* True if the timer is enabled */
88static int enableTimer = 0;
89
drhf0693c82011-10-11 20:41:54 +000090/* ctype macros that work with signed characters */
91#define IsSpace(X) isspace((unsigned char)X)
92#define IsDigit(X) isdigit((unsigned char)X)
93#define ToLower(X) (char)tolower((unsigned char)X)
94
chw97185482008-11-17 08:05:31 +000095#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000096#include <sys/time.h>
97#include <sys/resource.h>
98
drhda108222009-02-25 19:07:24 +000099/* Saved resource information for the beginning of an operation */
100static struct rusage sBegin;
101
drhda108222009-02-25 19:07:24 +0000102/*
103** Begin timing an operation
104*/
105static void beginTimer(void){
106 if( enableTimer ){
107 getrusage(RUSAGE_SELF, &sBegin);
108 }
109}
110
111/* Return the difference of two time_structs in seconds */
112static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
113 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
114 (double)(pEnd->tv_sec - pStart->tv_sec);
115}
116
117/*
118** Print the timing results.
119*/
120static void endTimer(void){
121 if( enableTimer ){
122 struct rusage sEnd;
123 getrusage(RUSAGE_SELF, &sEnd);
124 printf("CPU Time: user %f sys %f\n",
125 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
126 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
127 }
128}
shaneb320ccd2009-10-21 03:42:58 +0000129
drhda108222009-02-25 19:07:24 +0000130#define BEGIN_TIMER beginTimer()
131#define END_TIMER endTimer()
132#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000133
134#elif (defined(_WIN32) || defined(WIN32))
135
136#include <windows.h>
137
138/* Saved resource information for the beginning of an operation */
139static HANDLE hProcess;
140static FILETIME ftKernelBegin;
141static FILETIME ftUserBegin;
142typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
143static GETPROCTIMES getProcessTimesAddr = NULL;
144
shaneb320ccd2009-10-21 03:42:58 +0000145/*
146** Check to see if we have timer support. Return 1 if necessary
147** support found (or found previously).
148*/
149static int hasTimer(void){
150 if( getProcessTimesAddr ){
151 return 1;
152 } else {
153 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
154 ** See if the version we are running on has it, and if it does, save off
155 ** a pointer to it and the current process handle.
156 */
157 hProcess = GetCurrentProcess();
158 if( hProcess ){
159 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
160 if( NULL != hinstLib ){
161 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
162 if( NULL != getProcessTimesAddr ){
163 return 1;
164 }
165 FreeLibrary(hinstLib);
166 }
167 }
168 }
169 return 0;
170}
171
172/*
173** Begin timing an operation
174*/
175static void beginTimer(void){
176 if( enableTimer && getProcessTimesAddr ){
177 FILETIME ftCreation, ftExit;
178 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
179 }
180}
181
182/* Return the difference of two FILETIME structs in seconds */
183static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
184 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
185 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
186 return (double) ((i64End - i64Start) / 10000000.0);
187}
188
189/*
190** Print the timing results.
191*/
192static void endTimer(void){
193 if( enableTimer && getProcessTimesAddr){
194 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
195 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
196 printf("CPU Time: user %f sys %f\n",
197 timeDiff(&ftUserBegin, &ftUserEnd),
198 timeDiff(&ftKernelBegin, &ftKernelEnd));
199 }
200}
201
202#define BEGIN_TIMER beginTimer()
203#define END_TIMER endTimer()
204#define HAS_TIMER hasTimer()
205
drhda108222009-02-25 19:07:24 +0000206#else
207#define BEGIN_TIMER
208#define END_TIMER
209#define HAS_TIMER 0
210#endif
211
shanec0688ea2009-03-05 03:48:06 +0000212/*
213** Used to prevent warnings about unused parameters
214*/
215#define UNUSED_PARAMETER(x) (void)(x)
216
drhe91d16b2008-12-08 18:27:31 +0000217/*
drhc49f44e2006-10-26 18:15:42 +0000218** If the following flag is set, then command execution stops
219** at an error if we are not interactive.
220*/
221static int bail_on_error = 0;
222
223/*
drhc28490c2006-10-26 14:25:58 +0000224** Threat stdin as an interactive input if the following variable
225** is true. Otherwise, assume stdin is connected to a file or pipe.
226*/
227static int stdin_is_interactive = 1;
228
229/*
drh4c504392000-10-16 22:06:40 +0000230** The following is the open SQLite database. We make a pointer
231** to this database a static variable so that it can be accessed
232** by the SIGINT handler to interrupt database processing.
233*/
danielk197792f9a1b2004-06-19 09:08:16 +0000234static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000235
236/*
drh67505e72002-04-19 12:34:06 +0000237** True if an interrupt (Control-C) has been received.
238*/
drh43617e92006-03-06 20:55:46 +0000239static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000240
241/*
persicom7e2dfdd2002-04-18 02:46:52 +0000242** This is the name of our program. It is set in main(), used
243** in a number of other places, mostly for error messages.
244*/
245static char *Argv0;
246
247/*
248** Prompt strings. Initialized in main. Settable with
249** .prompt main continue
250*/
251static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
252static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
253
drhb0603412007-02-28 04:47:26 +0000254/*
255** Write I/O traces to the following stream.
256*/
rsebe0a9092007-07-30 18:24:38 +0000257#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000258static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000259#endif
drhb0603412007-02-28 04:47:26 +0000260
261/*
262** This routine works like printf in that its first argument is a
263** format string and subsequent arguments are values to be substituted
264** in place of % fields. The result of formatting this string
265** is written to iotrace.
266*/
rsebe0a9092007-07-30 18:24:38 +0000267#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000268static void iotracePrintf(const char *zFormat, ...){
269 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000270 char *z;
drhb0603412007-02-28 04:47:26 +0000271 if( iotrace==0 ) return;
272 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000273 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000274 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000275 fprintf(iotrace, "%s", z);
276 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000277}
rsebe0a9092007-07-30 18:24:38 +0000278#endif
drhb0603412007-02-28 04:47:26 +0000279
drh44c2eb12003-04-30 11:38:26 +0000280
persicom7e2dfdd2002-04-18 02:46:52 +0000281/*
drh83965662003-04-17 02:54:13 +0000282** Determines if a string is a number of not.
283*/
danielk19772e588c72005-12-09 14:25:08 +0000284static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000285 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000286 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000287 return 0;
288 }
289 z++;
290 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000291 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000292 if( *z=='.' ){
293 z++;
drhf0693c82011-10-11 20:41:54 +0000294 if( !IsDigit(*z) ) return 0;
295 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000296 if( realnum ) *realnum = 1;
297 }
298 if( *z=='e' || *z=='E' ){
299 z++;
300 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000301 if( !IsDigit(*z) ) return 0;
302 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000303 if( realnum ) *realnum = 1;
304 }
305 return *z==0;
306}
drh83965662003-04-17 02:54:13 +0000307
308/*
danielk1977bc6ada42004-06-30 08:20:16 +0000309** A global char* and an SQL function to access its current value
310** from within an SQL statement. This program used to use the
311** sqlite_exec_printf() API to substitue a string into an SQL statement.
312** The correct way to do this with sqlite3 is to use the bind API, but
313** since the shell is built around the callback paradigm it would be a lot
314** of work. Instead just use this hack, which is quite harmless.
315*/
316static const char *zShellStatic = 0;
317static void shellstaticFunc(
318 sqlite3_context *context,
319 int argc,
320 sqlite3_value **argv
321){
322 assert( 0==argc );
323 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000324 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000325 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000326 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
327}
328
329
330/*
drhfeac5f82004-08-01 00:10:45 +0000331** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000332** the text in memory obtained from malloc() and returns a pointer
333** to the text. NULL is returned at end of file, or if malloc()
334** fails.
335**
336** The interface is like "readline" but no command-line editing
337** is done.
338*/
drh18f52e02012-01-16 16:56:31 +0000339static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
drh8e7e7a22000-05-30 18:45:23 +0000340 char *zLine;
341 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000342 int n;
drh18f52e02012-01-16 16:56:31 +0000343 int inQuote = 0;
drh8e7e7a22000-05-30 18:45:23 +0000344
345 if( zPrompt && *zPrompt ){
346 printf("%s",zPrompt);
347 fflush(stdout);
348 }
349 nLine = 100;
350 zLine = malloc( nLine );
351 if( zLine==0 ) return 0;
352 n = 0;
drhb07028f2011-10-14 21:49:18 +0000353 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000354 if( n+100>nLine ){
355 nLine = nLine*2 + 100;
356 zLine = realloc(zLine, nLine);
357 if( zLine==0 ) return 0;
358 }
drhdaffd0e2001-04-11 14:28:42 +0000359 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000360 if( n==0 ){
361 free(zLine);
362 return 0;
363 }
364 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000365 break;
366 }
drh18f52e02012-01-16 16:56:31 +0000367 while( zLine[n] ){
368 if( zLine[n]=='"' ) inQuote = !inQuote;
369 n++;
370 }
371 if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
drh8e7e7a22000-05-30 18:45:23 +0000372 n--;
shaneh13b36022009-12-17 21:07:15 +0000373 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000374 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000375 break;
drh8e7e7a22000-05-30 18:45:23 +0000376 }
377 }
378 zLine = realloc( zLine, n+1 );
379 return zLine;
380}
381
382/*
drhc28490c2006-10-26 14:25:58 +0000383** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000384**
385** zPrior is a string of prior text retrieved. If not the empty
386** string, then issue a continuation prompt.
387*/
drhdaffd0e2001-04-11 14:28:42 +0000388static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000389 char *zPrompt;
390 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000391 if( in!=0 ){
drh18f52e02012-01-16 16:56:31 +0000392 return local_getline(0, in, 0);
drh8e7e7a22000-05-30 18:45:23 +0000393 }
394 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000395 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000396 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000397 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000398 }
399 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000400#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000401 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000402#endif
drh8e7e7a22000-05-30 18:45:23 +0000403 return zResult;
404}
405
persicom7e2dfdd2002-04-18 02:46:52 +0000406struct previous_mode_data {
407 int valid; /* Is there legit data in here? */
408 int mode;
409 int showHeader;
410 int colWidth[100];
411};
drh45e29d82006-11-20 16:21:10 +0000412
drh8e7e7a22000-05-30 18:45:23 +0000413/*
drh75897232000-05-29 14:26:00 +0000414** An pointer to an instance of this structure is passed from
415** the main program to the callback. This is used to communicate
416** state and mode information.
417*/
418struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000419 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000420 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000421 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000422 int cnt; /* Number of records displayed so far */
423 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000424 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000425 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000426 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000427 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000428 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000429 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000430 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000431 int colWidth[100]; /* Requested width of each column when in column mode*/
432 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000433 char nullvalue[20]; /* The text to print when a NULL comes back from
434 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000435 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000436 /* Holds the mode information just before
437 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000438 char outfile[FILENAME_MAX]; /* Filename for *out */
439 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000440 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000441 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000442 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000443};
444
445/*
446** These are the allowed modes.
447*/
drh967e8b72000-06-21 13:59:10 +0000448#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000449#define MODE_Column 1 /* One record per line in neat columns */
450#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000451#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
452#define MODE_Html 4 /* Generate an XHTML table */
453#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000454#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000455#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000456#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000457
drh66ce4d02008-02-15 17:38:06 +0000458static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000459 "line",
460 "column",
461 "list",
462 "semi",
463 "html",
drhfeac5f82004-08-01 00:10:45 +0000464 "insert",
465 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000466 "csv",
drh66ce4d02008-02-15 17:38:06 +0000467 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000468};
drh75897232000-05-29 14:26:00 +0000469
470/*
471** Number of elements in an array
472*/
drh902b9ee2008-12-05 17:17:07 +0000473#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000474
475/*
drhea678832008-12-10 19:26:22 +0000476** Compute a string length that is limited to what can be stored in
477** lower 30 bits of a 32-bit signed integer.
478*/
drh4f21c4a2008-12-10 22:15:00 +0000479static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000480 const char *z2 = z;
481 while( *z2 ){ z2++; }
482 return 0x3fffffff & (int)(z2 - z);
483}
484
485/*
drh127f9d72010-02-23 01:47:00 +0000486** A callback for the sqlite3_log() interface.
487*/
488static void shellLog(void *pArg, int iErrCode, const char *zMsg){
489 struct callback_data *p = (struct callback_data*)pArg;
490 if( p->pLog==0 ) return;
491 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
492 fflush(p->pLog);
493}
494
495/*
shane626a6e42009-10-22 17:30:15 +0000496** Output the given string as a hex-encoded blob (eg. X'1234' )
497*/
498static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
499 int i;
500 char *zBlob = (char *)pBlob;
501 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000502 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000503 fprintf(out,"'");
504}
505
506/*
drh28bd4bc2000-06-15 15:57:22 +0000507** Output the given string as a quoted string using SQL quoting conventions.
508*/
509static void output_quoted_string(FILE *out, const char *z){
510 int i;
511 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000512 for(i=0; z[i]; i++){
513 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000514 }
515 if( nSingle==0 ){
516 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000517 }else{
518 fprintf(out,"'");
519 while( *z ){
520 for(i=0; z[i] && z[i]!='\''; i++){}
521 if( i==0 ){
522 fprintf(out,"''");
523 z++;
524 }else if( z[i]=='\'' ){
525 fprintf(out,"%.*s''",i,z);
526 z += i+1;
527 }else{
drhcd7d2732002-02-26 23:24:26 +0000528 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000529 break;
530 }
531 }
drhcd7d2732002-02-26 23:24:26 +0000532 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000533 }
534}
535
536/*
drhfeac5f82004-08-01 00:10:45 +0000537** Output the given string as a quoted according to C or TCL quoting rules.
538*/
539static void output_c_string(FILE *out, const char *z){
540 unsigned int c;
541 fputc('"', out);
542 while( (c = *(z++))!=0 ){
543 if( c=='\\' ){
544 fputc(c, out);
545 fputc(c, out);
546 }else if( c=='\t' ){
547 fputc('\\', out);
548 fputc('t', out);
549 }else if( c=='\n' ){
550 fputc('\\', out);
551 fputc('n', out);
552 }else if( c=='\r' ){
553 fputc('\\', out);
554 fputc('r', out);
555 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000556 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000557 }else{
558 fputc(c, out);
559 }
560 }
561 fputc('"', out);
562}
563
564/*
drhc08a4f12000-06-15 16:49:48 +0000565** Output the given string with characters that are special to
566** HTML escaped.
567*/
568static void output_html_string(FILE *out, const char *z){
569 int i;
570 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000571 for(i=0; z[i]
572 && z[i]!='<'
573 && z[i]!='&'
574 && z[i]!='>'
575 && z[i]!='\"'
576 && z[i]!='\'';
577 i++){}
drhc08a4f12000-06-15 16:49:48 +0000578 if( i>0 ){
579 fprintf(out,"%.*s",i,z);
580 }
581 if( z[i]=='<' ){
582 fprintf(out,"&lt;");
583 }else if( z[i]=='&' ){
584 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000585 }else if( z[i]=='>' ){
586 fprintf(out,"&gt;");
587 }else if( z[i]=='\"' ){
588 fprintf(out,"&quot;");
589 }else if( z[i]=='\'' ){
590 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000591 }else{
592 break;
593 }
594 z += i + 1;
595 }
596}
597
598/*
drhc49f44e2006-10-26 18:15:42 +0000599** If a field contains any character identified by a 1 in the following
600** array, then the string must be quoted for CSV.
601*/
602static const char needCsvQuote[] = {
603 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
604 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
605 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
606 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
607 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
608 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
609 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
610 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
616 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
617 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
618 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
619};
620
621/*
drh8e64d1c2004-10-07 00:32:39 +0000622** Output a single term of CSV. Actually, p->separator is used for
623** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000624** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000625*/
626static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000627 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000628 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000629 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000630 }else{
drhc49f44e2006-10-26 18:15:42 +0000631 int i;
drh4f21c4a2008-12-10 22:15:00 +0000632 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000633 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000634 if( needCsvQuote[((unsigned char*)z)[i]]
635 || (z[i]==p->separator[0] &&
636 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000637 i = 0;
638 break;
639 }
640 }
641 if( i==0 ){
642 putc('"', out);
643 for(i=0; z[i]; i++){
644 if( z[i]=='"' ) putc('"', out);
645 putc(z[i], out);
646 }
647 putc('"', out);
648 }else{
649 fprintf(out, "%s", z);
650 }
drh8e64d1c2004-10-07 00:32:39 +0000651 }
652 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000653 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000654 }
655}
656
danielk19774af00c62005-01-23 23:43:21 +0000657#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000658/*
drh4c504392000-10-16 22:06:40 +0000659** This routine runs when the user presses Ctrl-C
660*/
661static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000662 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000663 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000664 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000665}
danielk19774af00c62005-01-23 23:43:21 +0000666#endif
drh4c504392000-10-16 22:06:40 +0000667
668/*
shane626a6e42009-10-22 17:30:15 +0000669** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000670** invokes for each row of a query result.
671*/
shane626a6e42009-10-22 17:30:15 +0000672static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000673 int i;
674 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000675
drh75897232000-05-29 14:26:00 +0000676 switch( p->mode ){
677 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000678 int w = 5;
drh6a535342001-10-19 16:44:56 +0000679 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000680 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000681 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000682 if( len>w ) w = len;
683 }
drh75897232000-05-29 14:26:00 +0000684 if( p->cnt++>0 ) fprintf(p->out,"\n");
685 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000686 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000687 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000688 }
689 break;
690 }
danielk19770d78bae2008-01-03 07:09:48 +0000691 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000692 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000693 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000694 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000695 int w, n;
696 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000697 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000698 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000699 w = 0;
drh75897232000-05-29 14:26:00 +0000700 }
drha0c66f52000-07-29 13:20:21 +0000701 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000702 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000703 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000704 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000705 if( w<n ) w = n;
706 }
707 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000708 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000709 }
710 if( p->showHeader ){
711 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
712 }
713 }
714 if( p->showHeader ){
715 for(i=0; i<nArg; i++){
716 int w;
717 if( i<ArraySize(p->actualWidth) ){
718 w = p->actualWidth[i];
719 }else{
720 w = 10;
721 }
722 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
723 "----------------------------------------------------------",
724 i==nArg-1 ? "\n": " ");
725 }
drh75897232000-05-29 14:26:00 +0000726 }
727 }
drh6a535342001-10-19 16:44:56 +0000728 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000729 for(i=0; i<nArg; i++){
730 int w;
drha0c66f52000-07-29 13:20:21 +0000731 if( i<ArraySize(p->actualWidth) ){
732 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000733 }else{
734 w = 10;
735 }
drhea678832008-12-10 19:26:22 +0000736 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000737 strlen30(azArg[i])>w ){
738 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000739 }
drhc61053b2000-06-04 12:58:36 +0000740 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000741 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000742 }
743 break;
744 }
drhe3710332000-09-29 13:30:53 +0000745 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000746 case MODE_List: {
747 if( p->cnt++==0 && p->showHeader ){
748 for(i=0; i<nArg; i++){
749 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
750 }
751 }
drh6a535342001-10-19 16:44:56 +0000752 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000753 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000754 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000755 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000756 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000757 if( i<nArg-1 ){
758 fprintf(p->out, "%s", p->separator);
759 }else if( p->mode==MODE_Semi ){
760 fprintf(p->out, ";\n");
761 }else{
762 fprintf(p->out, "\n");
763 }
drh75897232000-05-29 14:26:00 +0000764 }
765 break;
766 }
drh1e5d0e92000-05-31 23:33:17 +0000767 case MODE_Html: {
768 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000769 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000770 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000771 fprintf(p->out,"<TH>");
772 output_html_string(p->out, azCol[i]);
773 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000774 }
mihailim57c591a2008-06-23 21:26:05 +0000775 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000776 }
drh6a535342001-10-19 16:44:56 +0000777 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000778 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000779 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000780 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000781 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000782 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000783 }
mihailim57c591a2008-06-23 21:26:05 +0000784 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000785 break;
786 }
drhfeac5f82004-08-01 00:10:45 +0000787 case MODE_Tcl: {
788 if( p->cnt++==0 && p->showHeader ){
789 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000790 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000791 fprintf(p->out, "%s", p->separator);
792 }
793 fprintf(p->out,"\n");
794 }
795 if( azArg==0 ) break;
796 for(i=0; i<nArg; i++){
797 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
798 fprintf(p->out, "%s", p->separator);
799 }
800 fprintf(p->out,"\n");
801 break;
802 }
drh8e64d1c2004-10-07 00:32:39 +0000803 case MODE_Csv: {
804 if( p->cnt++==0 && p->showHeader ){
805 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000806 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000807 }
808 fprintf(p->out,"\n");
809 }
810 if( azArg==0 ) break;
811 for(i=0; i<nArg; i++){
812 output_csv(p, azArg[i], i<nArg-1);
813 }
814 fprintf(p->out,"\n");
815 break;
816 }
drh28bd4bc2000-06-15 15:57:22 +0000817 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000818 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000819 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000820 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000821 for(i=0; i<nArg; i++){
822 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000823 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000824 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000825 }else if( aiType && aiType[i]==SQLITE_TEXT ){
826 if( zSep[0] ) fprintf(p->out,"%s",zSep);
827 output_quoted_string(p->out, azArg[i]);
828 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
829 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000830 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
831 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
832 int nBlob = sqlite3_column_bytes(p->pStmt, i);
833 if( zSep[0] ) fprintf(p->out,"%s",zSep);
834 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000835 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000836 fprintf(p->out,"%s%s",zSep, azArg[i]);
837 }else{
838 if( zSep[0] ) fprintf(p->out,"%s",zSep);
839 output_quoted_string(p->out, azArg[i]);
840 }
841 }
842 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000843 break;
drh28bd4bc2000-06-15 15:57:22 +0000844 }
persicom1d0b8722002-04-18 02:53:04 +0000845 }
drh75897232000-05-29 14:26:00 +0000846 return 0;
847}
848
849/*
shane626a6e42009-10-22 17:30:15 +0000850** This is the callback routine that the SQLite library
851** invokes for each row of a query result.
852*/
853static int callback(void *pArg, int nArg, char **azArg, char **azCol){
854 /* since we don't have type info, call the shell_callback with a NULL value */
855 return shell_callback(pArg, nArg, azArg, azCol, NULL);
856}
857
858/*
drh33048c02001-10-01 14:29:22 +0000859** Set the destination table field of the callback_data structure to
860** the name of the table given. Escape any quote characters in the
861** table name.
862*/
863static void set_table_name(struct callback_data *p, const char *zName){
864 int i, n;
865 int needQuote;
866 char *z;
867
868 if( p->zDestTable ){
869 free(p->zDestTable);
870 p->zDestTable = 0;
871 }
872 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000873 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000874 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000875 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000876 needQuote = 1;
877 if( zName[i]=='\'' ) n++;
878 }
879 }
880 if( needQuote ) n += 2;
881 z = p->zDestTable = malloc( n+1 );
882 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000883 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000884 exit(1);
885 }
886 n = 0;
887 if( needQuote ) z[n++] = '\'';
888 for(i=0; zName[i]; i++){
889 z[n++] = zName[i];
890 if( zName[i]=='\'' ) z[n++] = '\'';
891 }
892 if( needQuote ) z[n++] = '\'';
893 z[n] = 0;
894}
895
danielk19772a02e332004-06-05 08:04:36 +0000896/* zIn is either a pointer to a NULL-terminated string in memory obtained
897** from malloc(), or a NULL pointer. The string pointed to by zAppend is
898** added to zIn, and the result returned in memory obtained from malloc().
899** zIn, if it was not NULL, is freed.
900**
901** If the third argument, quote, is not '\0', then it is used as a
902** quote character for zAppend.
903*/
drhc28490c2006-10-26 14:25:58 +0000904static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000905 int len;
906 int i;
drh4f21c4a2008-12-10 22:15:00 +0000907 int nAppend = strlen30(zAppend);
908 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000909
910 len = nAppend+nIn+1;
911 if( quote ){
912 len += 2;
913 for(i=0; i<nAppend; i++){
914 if( zAppend[i]==quote ) len++;
915 }
916 }
917
918 zIn = (char *)realloc(zIn, len);
919 if( !zIn ){
920 return 0;
921 }
922
923 if( quote ){
924 char *zCsr = &zIn[nIn];
925 *zCsr++ = quote;
926 for(i=0; i<nAppend; i++){
927 *zCsr++ = zAppend[i];
928 if( zAppend[i]==quote ) *zCsr++ = quote;
929 }
930 *zCsr++ = quote;
931 *zCsr++ = '\0';
932 assert( (zCsr-zIn)==len );
933 }else{
934 memcpy(&zIn[nIn], zAppend, nAppend);
935 zIn[len-1] = '\0';
936 }
937
938 return zIn;
939}
940
drhdd3d4592004-08-30 01:54:05 +0000941
942/*
drhb21a8e42012-01-28 21:08:51 +0000943** Execute a query statement that will generate SQL output. Print
944** the result columns, comma-separated, on a line and then add a
945** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000946**
drhb21a8e42012-01-28 21:08:51 +0000947** If the number of columns is 1 and that column contains text "--"
948** then write the semicolon on a separate line. That way, if a
949** "--" comment occurs at the end of the statement, the comment
950** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000951*/
drh157e29a2009-05-21 15:15:00 +0000952static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000953 struct callback_data *p, /* Query context */
954 const char *zSelect, /* SELECT statement to extract content */
955 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000956){
drhdd3d4592004-08-30 01:54:05 +0000957 sqlite3_stmt *pSelect;
958 int rc;
drhb21a8e42012-01-28 21:08:51 +0000959 int nResult;
960 int i;
961 const char *z;
drh2f464a02011-10-13 00:41:49 +0000962 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000963 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000964 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
965 p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000966 return rc;
967 }
968 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000969 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000970 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000971 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000972 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000973 zFirstRow = 0;
974 }
drhb21a8e42012-01-28 21:08:51 +0000975 z = (const char*)sqlite3_column_text(pSelect, 0);
976 fprintf(p->out, "%s", z);
977 for(i=1; i<nResult; i++){
978 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
979 }
980 if( z==0 ) z = "";
981 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
982 if( z[0] ){
983 fprintf(p->out, "\n;\n");
984 }else{
985 fprintf(p->out, ";\n");
986 }
drhdd3d4592004-08-30 01:54:05 +0000987 rc = sqlite3_step(pSelect);
988 }
drh2f464a02011-10-13 00:41:49 +0000989 rc = sqlite3_finalize(pSelect);
990 if( rc!=SQLITE_OK ){
991 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
992 p->nErr++;
993 }
994 return rc;
drhdd3d4592004-08-30 01:54:05 +0000995}
996
shane626a6e42009-10-22 17:30:15 +0000997/*
998** Allocate space and save off current error string.
999*/
1000static char *save_err_msg(
1001 sqlite3 *db /* Database to query */
1002){
1003 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1004 char *zErrMsg = sqlite3_malloc(nErrMsg);
1005 if( zErrMsg ){
1006 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1007 }
1008 return zErrMsg;
1009}
1010
1011/*
shaneh642d8b82010-07-28 16:05:34 +00001012** Display memory stats.
1013*/
1014static int display_stats(
1015 sqlite3 *db, /* Database to query */
1016 struct callback_data *pArg, /* Pointer to struct callback_data */
1017 int bReset /* True to reset the stats */
1018){
1019 int iCur;
1020 int iHiwtr;
1021
1022 if( pArg && pArg->out ){
1023
1024 iHiwtr = iCur = -1;
1025 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001026 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001027 iHiwtr = iCur = -1;
1028 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001029 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001030/*
1031** Not currently used by the CLI.
1032** iHiwtr = iCur = -1;
1033** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1034** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1035*/
1036 iHiwtr = iCur = -1;
1037 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1038 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1039/*
1040** Not currently used by the CLI.
1041** iHiwtr = iCur = -1;
1042** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1043** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1044*/
1045 iHiwtr = iCur = -1;
1046 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1047 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1048 iHiwtr = iCur = -1;
1049 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1050 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1051 iHiwtr = iCur = -1;
1052 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1053 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1054 iHiwtr = iCur = -1;
1055 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1056 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1057#ifdef YYTRACKMAXSTACKDEPTH
1058 iHiwtr = iCur = -1;
1059 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1060 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1061#endif
1062 }
1063
1064 if( pArg && pArg->out && db ){
1065 iHiwtr = iCur = -1;
1066 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1067 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001068 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1069 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1070 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1071 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1072 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1073 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001074 iHiwtr = iCur = -1;
1075 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001076 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1077 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1078 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1079 iHiwtr = iCur = -1;
1080 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1081 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001082 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001083 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1084 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1085 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001086 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1087 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1088 iHiwtr = iCur = -1;
1089 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1090 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1091 }
1092
1093 if( pArg && pArg->out && db && pArg->pStmt ){
1094 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1095 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1096 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1097 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1098 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1099 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1100 }
1101
1102 return 0;
1103}
1104
1105/*
shane626a6e42009-10-22 17:30:15 +00001106** Execute a statement or set of statements. Print
1107** any result rows/columns depending on the current mode
1108** set via the supplied callback.
1109**
1110** This is very similar to SQLite's built-in sqlite3_exec()
1111** function except it takes a slightly different callback
1112** and callback data argument.
1113*/
1114static int shell_exec(
1115 sqlite3 *db, /* An open database */
1116 const char *zSql, /* SQL to be evaluated */
1117 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1118 /* (not the same as sqlite3_exec) */
1119 struct callback_data *pArg, /* Pointer to struct callback_data */
1120 char **pzErrMsg /* Error msg written here */
1121){
dan4564ced2010-01-05 04:59:56 +00001122 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1123 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001124 int rc2;
dan4564ced2010-01-05 04:59:56 +00001125 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001126
1127 if( pzErrMsg ){
1128 *pzErrMsg = NULL;
1129 }
1130
shaneb9fc17d2009-10-22 21:23:35 +00001131 while( zSql[0] && (SQLITE_OK == rc) ){
1132 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1133 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001134 if( pzErrMsg ){
1135 *pzErrMsg = save_err_msg(db);
1136 }
1137 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001138 if( !pStmt ){
1139 /* this happens for a comment or white-space */
1140 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001141 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001142 continue;
1143 }
shane626a6e42009-10-22 17:30:15 +00001144
shaneh642d8b82010-07-28 16:05:34 +00001145 /* save off the prepared statment handle and reset row count */
1146 if( pArg ){
1147 pArg->pStmt = pStmt;
1148 pArg->cnt = 0;
1149 }
1150
shanehb7977c52010-01-18 18:17:10 +00001151 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001152 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001153 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001154 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001155 }
shanehb7977c52010-01-18 18:17:10 +00001156
drh7e02e5e2011-12-06 19:44:51 +00001157 /* Output TESTCTRL_EXPLAIN text of requested */
1158 if( pArg && pArg->mode==MODE_Explain ){
1159 const char *zExplain = 0;
1160 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1161 if( zExplain && zExplain[0] ){
1162 fprintf(pArg->out, "%s", zExplain);
1163 }
1164 }
1165
shaneb9fc17d2009-10-22 21:23:35 +00001166 /* perform the first step. this will tell us if we
1167 ** have a result set or not and how wide it is.
1168 */
1169 rc = sqlite3_step(pStmt);
1170 /* if we have a result set... */
1171 if( SQLITE_ROW == rc ){
1172 /* if we have a callback... */
1173 if( xCallback ){
1174 /* allocate space for col name ptr, value ptr, and type */
1175 int nCol = sqlite3_column_count(pStmt);
1176 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1177 if( !pData ){
1178 rc = SQLITE_NOMEM;
1179 }else{
1180 char **azCols = (char **)pData; /* Names of result columns */
1181 char **azVals = &azCols[nCol]; /* Results */
1182 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1183 int i;
1184 assert(sizeof(int) <= sizeof(char *));
1185 /* save off ptrs to column names */
1186 for(i=0; i<nCol; i++){
1187 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1188 }
shaneb9fc17d2009-10-22 21:23:35 +00001189 do{
1190 /* extract the data and data types */
1191 for(i=0; i<nCol; i++){
1192 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1193 aiTypes[i] = sqlite3_column_type(pStmt, i);
1194 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1195 rc = SQLITE_NOMEM;
1196 break; /* from for */
1197 }
1198 } /* end for */
1199
1200 /* if data and types extracted successfully... */
1201 if( SQLITE_ROW == rc ){
1202 /* call the supplied callback with the result row data */
1203 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1204 rc = SQLITE_ABORT;
1205 }else{
1206 rc = sqlite3_step(pStmt);
1207 }
1208 }
1209 } while( SQLITE_ROW == rc );
1210 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001211 }
1212 }else{
1213 do{
1214 rc = sqlite3_step(pStmt);
1215 } while( rc == SQLITE_ROW );
1216 }
1217 }
1218
shaneh642d8b82010-07-28 16:05:34 +00001219 /* print usage stats if stats on */
1220 if( pArg && pArg->statsOn ){
1221 display_stats(db, pArg, 0);
1222 }
1223
dan4564ced2010-01-05 04:59:56 +00001224 /* Finalize the statement just executed. If this fails, save a
1225 ** copy of the error message. Otherwise, set zSql to point to the
1226 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001227 rc2 = sqlite3_finalize(pStmt);
1228 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001229 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001230 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001231 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001232 }else if( pzErrMsg ){
1233 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001234 }
shaneh642d8b82010-07-28 16:05:34 +00001235
1236 /* clear saved stmt handle */
1237 if( pArg ){
1238 pArg->pStmt = NULL;
1239 }
shane626a6e42009-10-22 17:30:15 +00001240 }
shaneb9fc17d2009-10-22 21:23:35 +00001241 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001242
1243 return rc;
1244}
1245
drhdd3d4592004-08-30 01:54:05 +00001246
drh33048c02001-10-01 14:29:22 +00001247/*
drh4c653a02000-06-07 01:27:47 +00001248** This is a different callback routine used for dumping the database.
1249** Each row received by this callback consists of a table name,
1250** the table type ("index" or "table") and SQL to create the table.
1251** This routine should print text sufficient to recreate the table.
1252*/
1253static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001254 int rc;
1255 const char *zTable;
1256 const char *zType;
1257 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001258 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001259 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001260
drh902b9ee2008-12-05 17:17:07 +00001261 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001262 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001263 zTable = azArg[0];
1264 zType = azArg[1];
1265 zSql = azArg[2];
1266
drh00b950d2005-09-11 02:03:03 +00001267 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001268 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001269 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1270 fprintf(p->out, "ANALYZE sqlite_master;\n");
1271 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1272 return 0;
drh45e29d82006-11-20 16:21:10 +00001273 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1274 char *zIns;
1275 if( !p->writableSchema ){
1276 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1277 p->writableSchema = 1;
1278 }
1279 zIns = sqlite3_mprintf(
1280 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1281 "VALUES('table','%q','%q',0,'%q');",
1282 zTable, zTable, zSql);
1283 fprintf(p->out, "%s\n", zIns);
1284 sqlite3_free(zIns);
1285 return 0;
drh00b950d2005-09-11 02:03:03 +00001286 }else{
1287 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001288 }
danielk19772a02e332004-06-05 08:04:36 +00001289
1290 if( strcmp(zType, "table")==0 ){
1291 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001292 char *zSelect = 0;
1293 char *zTableInfo = 0;
1294 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001295 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001296
1297 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1298 zTableInfo = appendText(zTableInfo, zTable, '"');
1299 zTableInfo = appendText(zTableInfo, ");", 0);
1300
1301 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001302 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001303 if( rc!=SQLITE_OK || !pTableInfo ){
1304 return 1;
1305 }
1306
1307 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001308 /* Always quote the table name, even if it appears to be pure ascii,
1309 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1310 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001311 if( zTmp ){
1312 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001313 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001314 }
1315 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1316 rc = sqlite3_step(pTableInfo);
1317 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001318 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001319 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001320 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001321 rc = sqlite3_step(pTableInfo);
1322 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001323 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001324 }else{
1325 zSelect = appendText(zSelect, ") ", 0);
1326 }
drh157e29a2009-05-21 15:15:00 +00001327 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001328 }
1329 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001330 if( rc!=SQLITE_OK || nRow==0 ){
1331 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001332 return 1;
1333 }
1334 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1335 zSelect = appendText(zSelect, zTable, '"');
1336
drh2f464a02011-10-13 00:41:49 +00001337 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001338 if( rc==SQLITE_CORRUPT ){
1339 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001340 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001341 }
drh85e72432012-04-11 11:38:53 +00001342 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001343 }
drh4c653a02000-06-07 01:27:47 +00001344 return 0;
1345}
1346
1347/*
drh45e29d82006-11-20 16:21:10 +00001348** Run zQuery. Use dump_callback() as the callback routine so that
1349** the contents of the query are output as SQL statements.
1350**
drhdd3d4592004-08-30 01:54:05 +00001351** If we get a SQLITE_CORRUPT error, rerun the query after appending
1352** "ORDER BY rowid DESC" to the end.
1353*/
1354static int run_schema_dump_query(
1355 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001356 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001357){
1358 int rc;
drh2f464a02011-10-13 00:41:49 +00001359 char *zErr = 0;
1360 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001361 if( rc==SQLITE_CORRUPT ){
1362 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001363 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001364 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1365 if( zErr ){
1366 fprintf(p->out, "/****** %s ******/\n", zErr);
1367 sqlite3_free(zErr);
1368 zErr = 0;
1369 }
drhdd3d4592004-08-30 01:54:05 +00001370 zQ2 = malloc( len+100 );
1371 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001372 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001373 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1374 if( rc ){
1375 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1376 }else{
1377 rc = SQLITE_CORRUPT;
1378 }
1379 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001380 free(zQ2);
1381 }
1382 return rc;
1383}
1384
1385/*
drh75897232000-05-29 14:26:00 +00001386** Text of a help message
1387*/
persicom1d0b8722002-04-18 02:53:04 +00001388static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001389 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001390 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001391 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001392 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001393 " If TABLE specified, only dump tables matching\n"
1394 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001395 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001396 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001397 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1398 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001399 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001400 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001401 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001402 ".indices ?TABLE? Show names of all indices\n"
1403 " If TABLE specified, only show indices for tables\n"
1404 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001405#ifdef SQLITE_ENABLE_IOTRACE
1406 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1407#endif
drh70df4fe2006-06-13 15:12:21 +00001408#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001409 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001410#endif
drh127f9d72010-02-23 01:47:00 +00001411 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001412 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001413 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001414 " column Left-aligned columns. (See .width)\n"
1415 " html HTML <table> code\n"
1416 " insert SQL insert statements for TABLE\n"
1417 " line One value per line\n"
1418 " list Values delimited by .separator string\n"
1419 " tabs Tab-separated values\n"
1420 " tcl TCL list elements\n"
1421 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001422 ".output FILENAME Send output to FILENAME\n"
1423 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001424 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001425 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001426 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001427 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001428 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001429 " If TABLE specified, only show tables matching\n"
1430 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001431 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001432 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001433 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001434 ".tables ?TABLE? List names of tables\n"
1435 " If TABLE specified, only list tables matching\n"
1436 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001437 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001438 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001439 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001440 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001441;
1442
shaneb320ccd2009-10-21 03:42:58 +00001443static char zTimerHelp[] =
1444 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1445;
1446
drhdaffd0e2001-04-11 14:28:42 +00001447/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001448static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001449
drh75897232000-05-29 14:26:00 +00001450/*
drh44c2eb12003-04-30 11:38:26 +00001451** Make sure the database is open. If it is not, then open it. If
1452** the database fails to open, print an error message and exit.
1453*/
1454static void open_db(struct callback_data *p){
1455 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001456 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001457 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001458 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1459 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1460 shellstaticFunc, 0, 0);
1461 }
1462 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001463 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001464 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001465 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001466 }
drhc2e87a32006-06-27 15:16:14 +00001467#ifndef SQLITE_OMIT_LOAD_EXTENSION
1468 sqlite3_enable_load_extension(p->db, 1);
1469#endif
drh44c2eb12003-04-30 11:38:26 +00001470 }
1471}
1472
1473/*
drhfeac5f82004-08-01 00:10:45 +00001474** Do C-language style dequoting.
1475**
1476** \t -> tab
1477** \n -> newline
1478** \r -> carriage return
1479** \NNN -> ascii character NNN in octal
1480** \\ -> backslash
1481*/
1482static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001483 int i, j;
1484 char c;
drhfeac5f82004-08-01 00:10:45 +00001485 for(i=j=0; (c = z[i])!=0; i++, j++){
1486 if( c=='\\' ){
1487 c = z[++i];
1488 if( c=='n' ){
1489 c = '\n';
1490 }else if( c=='t' ){
1491 c = '\t';
1492 }else if( c=='r' ){
1493 c = '\r';
1494 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001495 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001496 if( z[i+1]>='0' && z[i+1]<='7' ){
1497 i++;
1498 c = (c<<3) + z[i] - '0';
1499 if( z[i+1]>='0' && z[i+1]<='7' ){
1500 i++;
1501 c = (c<<3) + z[i] - '0';
1502 }
1503 }
1504 }
1505 }
1506 z[j] = c;
1507 }
1508 z[j] = 0;
1509}
1510
1511/*
drhc28490c2006-10-26 14:25:58 +00001512** Interpret zArg as a boolean value. Return either 0 or 1.
1513*/
1514static int booleanValue(char *zArg){
1515 int val = atoi(zArg);
1516 int j;
1517 for(j=0; zArg[j]; j++){
drhf0693c82011-10-11 20:41:54 +00001518 zArg[j] = ToLower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001519 }
1520 if( strcmp(zArg,"on")==0 ){
1521 val = 1;
1522 }else if( strcmp(zArg,"yes")==0 ){
1523 val = 1;
1524 }
1525 return val;
1526}
1527
1528/*
drh42f64e52012-04-04 16:56:23 +00001529** Close an output file, assuming it is not stderr or stdout
1530*/
1531static void output_file_close(FILE *f){
1532 if( f && f!=stdout && f!=stderr ) fclose(f);
1533}
1534
1535/*
1536** Try to open an output file. The names "stdout" and "stderr" are
1537** recognized and do the right thing. NULL is returned if the output
1538** filename is "off".
1539*/
1540static FILE *output_file_open(const char *zFile){
1541 FILE *f;
1542 if( strcmp(zFile,"stdout")==0 ){
1543 f = stdout;
1544 }else if( strcmp(zFile, "stderr")==0 ){
1545 f = stderr;
1546 }else if( strcmp(zFile, "off")==0 ){
1547 f = 0;
1548 }else{
1549 f = fopen(zFile, "wb");
1550 if( f==0 ){
1551 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1552 }
1553 }
1554 return f;
1555}
1556
1557/*
1558** A routine for handling output from sqlite3_trace().
1559*/
1560static void sql_trace_callback(void *pArg, const char *z){
1561 FILE *f = (FILE*)pArg;
1562 if( f ) fprintf(f, "%s\n", z);
1563}
1564
1565/*
drhd8621b92012-04-17 09:09:33 +00001566** A no-op routine that runs with the ".breakpoint" doc-command. This is
1567** a useful spot to set a debugger breakpoint.
1568*/
1569static void test_breakpoint(void){
1570 static int nCall = 0;
1571 nCall++;
1572}
1573
1574/*
drh75897232000-05-29 14:26:00 +00001575** If an input line begins with "." then invoke this routine to
1576** process that line.
drh67505e72002-04-19 12:34:06 +00001577**
drh47ad6842006-11-08 12:25:42 +00001578** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001579*/
drh44c2eb12003-04-30 11:38:26 +00001580static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001581 int i = 1;
1582 int nArg = 0;
1583 int n, c;
drh67505e72002-04-19 12:34:06 +00001584 int rc = 0;
drh75897232000-05-29 14:26:00 +00001585 char *azArg[50];
1586
1587 /* Parse the input line into tokens.
1588 */
1589 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001590 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001591 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001592 if( zLine[i]=='\'' || zLine[i]=='"' ){
1593 int delim = zLine[i++];
1594 azArg[nArg++] = &zLine[i];
1595 while( zLine[i] && zLine[i]!=delim ){ i++; }
1596 if( zLine[i]==delim ){
1597 zLine[i++] = 0;
1598 }
drhfeac5f82004-08-01 00:10:45 +00001599 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001600 }else{
1601 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001602 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001603 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001604 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001605 }
1606 }
1607
1608 /* Process the input line.
1609 */
shane9bd1b442009-10-23 01:27:39 +00001610 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001611 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001612 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001613 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001614 const char *zDestFile;
1615 const char *zDb;
1616 sqlite3 *pDest;
1617 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001618 if( nArg==2 ){
1619 zDestFile = azArg[1];
1620 zDb = "main";
1621 }else{
1622 zDestFile = azArg[2];
1623 zDb = azArg[1];
1624 }
1625 rc = sqlite3_open(zDestFile, &pDest);
1626 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001627 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001628 sqlite3_close(pDest);
1629 return 1;
1630 }
drhdc2c4912009-02-04 22:46:47 +00001631 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001632 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1633 if( pBackup==0 ){
1634 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1635 sqlite3_close(pDest);
1636 return 1;
1637 }
1638 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1639 sqlite3_backup_finish(pBackup);
1640 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001641 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001642 }else{
1643 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001644 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001645 }
1646 sqlite3_close(pDest);
1647 }else
1648
shanehe2aa9d72009-11-06 17:20:17 +00001649 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001650 bail_on_error = booleanValue(azArg[1]);
1651 }else
1652
drhd8621b92012-04-17 09:09:33 +00001653 /* The undocumented ".breakpoint" command causes a call to the no-op
1654 ** routine named test_breakpoint().
1655 */
1656 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1657 test_breakpoint();
1658 }else
1659
shanehe2aa9d72009-11-06 17:20:17 +00001660 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001661 struct callback_data data;
1662 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001663 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001664 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001665 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001666 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001667 data.colWidth[0] = 3;
1668 data.colWidth[1] = 15;
1669 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001670 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001671 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001672 if( zErrMsg ){
1673 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001674 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001675 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001676 }
1677 }else
1678
shanehe2aa9d72009-11-06 17:20:17 +00001679 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001680 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001681 /* When playing back a "dump", the content might appear in an order
1682 ** which causes immediate foreign key constraints to be violated.
1683 ** So disable foreign-key constraint enforcement to prevent problems. */
1684 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001685 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001686 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001687 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001688 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001689 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001690 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001691 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001692 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001693 );
1694 run_schema_dump_query(p,
1695 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001696 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001697 );
drh2f464a02011-10-13 00:41:49 +00001698 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001699 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001700 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001701 );
drh4c653a02000-06-07 01:27:47 +00001702 }else{
1703 int i;
drhdd3d4592004-08-30 01:54:05 +00001704 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001705 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001706 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001707 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001708 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001709 " AND sql NOT NULL");
1710 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001711 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001712 "WHERE sql NOT NULL"
1713 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001714 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001715 );
danielk1977bc6ada42004-06-30 08:20:16 +00001716 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001717 }
1718 }
drh45e29d82006-11-20 16:21:10 +00001719 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001720 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001721 p->writableSchema = 0;
1722 }
drh56197952011-10-13 16:30:13 +00001723 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1724 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001725 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001726 }else
drh75897232000-05-29 14:26:00 +00001727
shanehe2aa9d72009-11-06 17:20:17 +00001728 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001729 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001730 }else
1731
shanehe2aa9d72009-11-06 17:20:17 +00001732 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001733 rc = 2;
drh75897232000-05-29 14:26:00 +00001734 }else
1735
shanehe2aa9d72009-11-06 17:20:17 +00001736 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001737 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001738 if(val == 1) {
1739 if(!p->explainPrev.valid) {
1740 p->explainPrev.valid = 1;
1741 p->explainPrev.mode = p->mode;
1742 p->explainPrev.showHeader = p->showHeader;
1743 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1744 }
1745 /* We could put this code under the !p->explainValid
1746 ** condition so that it does not execute if we are already in
1747 ** explain mode. However, always executing it allows us an easy
1748 ** was to reset to explain mode in case the user previously
1749 ** did an .explain followed by a .width, .mode or .header
1750 ** command.
1751 */
danielk19770d78bae2008-01-03 07:09:48 +00001752 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001753 p->showHeader = 1;
1754 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001755 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001756 p->colWidth[1] = 13; /* opcode */
1757 p->colWidth[2] = 4; /* P1 */
1758 p->colWidth[3] = 4; /* P2 */
1759 p->colWidth[4] = 4; /* P3 */
1760 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001761 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001762 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001763 }else if (p->explainPrev.valid) {
1764 p->explainPrev.valid = 0;
1765 p->mode = p->explainPrev.mode;
1766 p->showHeader = p->explainPrev.showHeader;
1767 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1768 }
drh75897232000-05-29 14:26:00 +00001769 }else
1770
drhc28490c2006-10-26 14:25:58 +00001771 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001772 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001773 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001774 }else
1775
1776 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001777 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001778 if( HAS_TIMER ){
1779 fprintf(stderr,"%s",zTimerHelp);
1780 }
drh75897232000-05-29 14:26:00 +00001781 }else
1782
shanehe2aa9d72009-11-06 17:20:17 +00001783 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001784 char *zTable = azArg[2]; /* Insert data into this table */
1785 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001786 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001787 int nCol; /* Number of columns in the table */
1788 int nByte; /* Number of bytes in an SQL string */
1789 int i, j; /* Loop counters */
1790 int nSep; /* Number of bytes in p->separator[] */
1791 char *zSql; /* An SQL statement */
1792 char *zLine; /* A single line of input from the file */
1793 char **azCol; /* zLine[] broken up into columns */
1794 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001795 FILE *in; /* The input file */
1796 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001797
drha543c822006-06-08 16:10:14 +00001798 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001799 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001800 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001801 fprintf(stderr, "Error: non-null separator required for import\n");
1802 return 1;
drhfeac5f82004-08-01 00:10:45 +00001803 }
drh7b075e32011-09-28 01:10:00 +00001804 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00001805 if( zSql==0 ){
1806 fprintf(stderr, "Error: out of memory\n");
1807 return 1;
1808 }
drh4f21c4a2008-12-10 22:15:00 +00001809 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001810 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001811 sqlite3_free(zSql);
1812 if( rc ){
shane916f9612009-10-23 00:37:15 +00001813 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001814 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001815 return 1;
drhfeac5f82004-08-01 00:10:45 +00001816 }
shane916f9612009-10-23 00:37:15 +00001817 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001818 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001819 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001820 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001821 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001822 if( zSql==0 ){
1823 fprintf(stderr, "Error: out of memory\n");
1824 return 1;
1825 }
drh7b075e32011-09-28 01:10:00 +00001826 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001827 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001828 for(i=1; i<nCol; i++){
1829 zSql[j++] = ',';
1830 zSql[j++] = '?';
1831 }
1832 zSql[j++] = ')';
1833 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001834 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001835 free(zSql);
1836 if( rc ){
1837 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001838 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001839 return 1;
drhfeac5f82004-08-01 00:10:45 +00001840 }
1841 in = fopen(zFile, "rb");
1842 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001843 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001844 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001845 return 1;
drhfeac5f82004-08-01 00:10:45 +00001846 }
1847 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001848 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001849 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001850 fclose(in);
shane916f9612009-10-23 00:37:15 +00001851 sqlite3_finalize(pStmt);
1852 return 1;
drh43617e92006-03-06 20:55:46 +00001853 }
drhfeac5f82004-08-01 00:10:45 +00001854 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1855 zCommit = "COMMIT";
drh18f52e02012-01-16 16:56:31 +00001856 while( (zLine = local_getline(0, in, 1))!=0 ){
1857 char *z, c;
1858 int inQuote = 0;
drhb860bc92004-08-04 15:16:55 +00001859 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001860 azCol[0] = zLine;
drh18f52e02012-01-16 16:56:31 +00001861 for(i=0, z=zLine; (c = *z)!=0; z++){
1862 if( c=='"' ) inQuote = !inQuote;
1863 if( c=='\n' ) lineno++;
1864 if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001865 *z = 0;
1866 i++;
drhb860bc92004-08-04 15:16:55 +00001867 if( i<nCol ){
1868 azCol[i] = &z[nSep];
1869 z += nSep-1;
1870 }
drhfeac5f82004-08-01 00:10:45 +00001871 }
shane916f9612009-10-23 00:37:15 +00001872 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001873 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001874 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001875 fprintf(stderr,
1876 "Error: %s line %d: expected %d columns of data but found %d\n",
1877 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001878 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001879 free(zLine);
shane916f9612009-10-23 00:37:15 +00001880 rc = 1;
1881 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001882 }
drhfeac5f82004-08-01 00:10:45 +00001883 for(i=0; i<nCol; i++){
drh18f52e02012-01-16 16:56:31 +00001884 if( azCol[i][0]=='"' ){
1885 int k;
1886 for(z=azCol[i], j=1, k=0; z[j]; j++){
1887 if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1888 z[k++] = z[j];
1889 }
1890 z[k] = 0;
1891 }
drhfeac5f82004-08-01 00:10:45 +00001892 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1893 }
1894 sqlite3_step(pStmt);
1895 rc = sqlite3_reset(pStmt);
1896 free(zLine);
1897 if( rc!=SQLITE_OK ){
1898 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1899 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001900 rc = 1;
shane916f9612009-10-23 00:37:15 +00001901 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001902 }
shane916f9612009-10-23 00:37:15 +00001903 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001904 free(azCol);
1905 fclose(in);
1906 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001907 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001908 }else
1909
shanehe2aa9d72009-11-06 17:20:17 +00001910 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001911 struct callback_data data;
1912 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001913 open_db(p);
drh75897232000-05-29 14:26:00 +00001914 memcpy(&data, p, sizeof(data));
1915 data.showHeader = 0;
1916 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001917 if( nArg==1 ){
1918 rc = sqlite3_exec(p->db,
1919 "SELECT name FROM sqlite_master "
1920 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1921 "UNION ALL "
1922 "SELECT name FROM sqlite_temp_master "
1923 "WHERE type='index' "
1924 "ORDER BY 1",
1925 callback, &data, &zErrMsg
1926 );
1927 }else{
1928 zShellStatic = azArg[1];
1929 rc = sqlite3_exec(p->db,
1930 "SELECT name FROM sqlite_master "
1931 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1932 "UNION ALL "
1933 "SELECT name FROM sqlite_temp_master "
1934 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1935 "ORDER BY 1",
1936 callback, &data, &zErrMsg
1937 );
1938 zShellStatic = 0;
1939 }
drh75897232000-05-29 14:26:00 +00001940 if( zErrMsg ){
1941 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001942 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001943 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001944 }else if( rc != SQLITE_OK ){
1945 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1946 rc = 1;
drh75897232000-05-29 14:26:00 +00001947 }
1948 }else
1949
drhae5e4452007-05-03 17:18:36 +00001950#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001951 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001952 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001953 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1954 iotrace = 0;
1955 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001956 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001957 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001958 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001959 iotrace = stdout;
1960 }else{
1961 iotrace = fopen(azArg[1], "w");
1962 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001963 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001964 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001965 rc = 1;
drhb0603412007-02-28 04:47:26 +00001966 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001967 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001968 }
1969 }
1970 }else
drhae5e4452007-05-03 17:18:36 +00001971#endif
drhb0603412007-02-28 04:47:26 +00001972
drh70df4fe2006-06-13 15:12:21 +00001973#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001974 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1975 const char *zFile, *zProc;
1976 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001977 zFile = azArg[1];
1978 zProc = nArg>=3 ? azArg[2] : 0;
1979 open_db(p);
1980 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1981 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001982 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001983 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001984 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001985 }
1986 }else
drh70df4fe2006-06-13 15:12:21 +00001987#endif
drh1e397f82006-06-08 15:28:43 +00001988
drhc8ba2122011-03-23 11:16:22 +00001989 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00001990 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00001991 output_file_close(p->pLog);
1992 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00001993 }else
1994
shanehe2aa9d72009-11-06 17:20:17 +00001995 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001996 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001997 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001998 ||
shanehe2aa9d72009-11-06 17:20:17 +00001999 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002000 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002001 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002002 ||
shanehe2aa9d72009-11-06 17:20:17 +00002003 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002004 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002005 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002006 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002007 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002008 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002009 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002010 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00002011 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002012 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002013 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002014 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002015 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002016 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002017 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002018 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002019 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002020 }else {
shane9bd1b442009-10-23 01:27:39 +00002021 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002022 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002023 rc = 1;
drh75897232000-05-29 14:26:00 +00002024 }
2025 }else
2026
shanehe2aa9d72009-11-06 17:20:17 +00002027 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2028 int n2 = strlen30(azArg[1]);
2029 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2030 p->mode = MODE_Insert;
2031 set_table_name(p, azArg[2]);
2032 }else {
2033 fprintf(stderr, "Error: invalid arguments: "
2034 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2035 rc = 1;
2036 }
2037 }else
2038
persicom7e2dfdd2002-04-18 02:46:52 +00002039 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002040 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2041 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002042 }else
2043
drh75897232000-05-29 14:26:00 +00002044 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002045 if( p->outfile[0]=='|' ){
2046 pclose(p->out);
2047 }else{
2048 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002049 }
drh42f64e52012-04-04 16:56:23 +00002050 p->outfile[0] = 0;
2051 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002052 p->out = popen(&azArg[1][1], "w");
2053 if( p->out==0 ){
2054 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2055 p->out = stdout;
2056 rc = 1;
2057 }else{
2058 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2059 }
drh75897232000-05-29 14:26:00 +00002060 }else{
drh42f64e52012-04-04 16:56:23 +00002061 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002062 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002063 if( strcmp(azArg[1],"off")!=0 ){
2064 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2065 }
drh75897232000-05-29 14:26:00 +00002066 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002067 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002068 } else {
drh42f64e52012-04-04 16:56:23 +00002069 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002070 }
2071 }
2072 }else
2073
drhdd45df82002-04-18 12:39:03 +00002074 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002075 if( nArg >= 2) {
2076 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2077 }
2078 if( nArg >= 3) {
2079 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2080 }
2081 }else
2082
shanehe2aa9d72009-11-06 17:20:17 +00002083 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002084 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002085 }else
2086
drh9ff849f2009-02-04 20:55:57 +00002087 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002088 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002089 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002090 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2091 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002092 }else{
shane9bd1b442009-10-23 01:27:39 +00002093 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002094 fclose(alt);
2095 }
2096 }else
2097
shanehe2aa9d72009-11-06 17:20:17 +00002098 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002099 const char *zSrcFile;
2100 const char *zDb;
2101 sqlite3 *pSrc;
2102 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002103 int nTimeout = 0;
2104
drh9ff849f2009-02-04 20:55:57 +00002105 if( nArg==2 ){
2106 zSrcFile = azArg[1];
2107 zDb = "main";
2108 }else{
2109 zSrcFile = azArg[2];
2110 zDb = azArg[1];
2111 }
2112 rc = sqlite3_open(zSrcFile, &pSrc);
2113 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002114 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002115 sqlite3_close(pSrc);
2116 return 1;
2117 }
drhdc2c4912009-02-04 22:46:47 +00002118 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002119 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2120 if( pBackup==0 ){
2121 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2122 sqlite3_close(pSrc);
2123 return 1;
2124 }
drhdc2c4912009-02-04 22:46:47 +00002125 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2126 || rc==SQLITE_BUSY ){
2127 if( rc==SQLITE_BUSY ){
2128 if( nTimeout++ >= 3 ) break;
2129 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002130 }
2131 }
2132 sqlite3_backup_finish(pBackup);
2133 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002134 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002135 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002136 fprintf(stderr, "Error: source database is busy\n");
2137 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002138 }else{
2139 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002140 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002141 }
2142 sqlite3_close(pSrc);
2143 }else
2144
shanehe2aa9d72009-11-06 17:20:17 +00002145 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002146 struct callback_data data;
2147 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002148 open_db(p);
drh75897232000-05-29 14:26:00 +00002149 memcpy(&data, p, sizeof(data));
2150 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002151 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002152 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002153 int i;
drhf0693c82011-10-11 20:41:54 +00002154 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002155 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002156 char *new_argv[2], *new_colv[2];
2157 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2158 " type text,\n"
2159 " name text,\n"
2160 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002161 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002162 " sql text\n"
2163 ")";
2164 new_argv[1] = 0;
2165 new_colv[0] = "sql";
2166 new_colv[1] = 0;
2167 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002168 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002169 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002170 char *new_argv[2], *new_colv[2];
2171 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2172 " type text,\n"
2173 " name text,\n"
2174 " tbl_name text,\n"
2175 " rootpage integer,\n"
2176 " sql text\n"
2177 ")";
2178 new_argv[1] = 0;
2179 new_colv[0] = "sql";
2180 new_colv[1] = 0;
2181 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002182 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002183 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002184 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002185 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002186 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002187 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002188 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002189 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002190 "WHERE lower(tbl_name) LIKE shellstatic()"
2191 " AND type!='meta' AND sql NOTNULL "
drhac43e982012-05-21 03:15:06 +00002192 "ORDER BY substr(type,2,1), "
2193 " CASE type WHEN 'view' THEN rowid ELSE name END",
danielk1977bc6ada42004-06-30 08:20:16 +00002194 callback, &data, &zErrMsg);
2195 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002196 }
drh75897232000-05-29 14:26:00 +00002197 }else{
shane9bd1b442009-10-23 01:27:39 +00002198 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002199 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002200 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002201 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002202 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002203 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhac43e982012-05-21 03:15:06 +00002204 "ORDER BY substr(type,2,1),"
2205 " CASE type WHEN 'view' THEN rowid ELSE name END",
drha18c5682000-10-08 22:20:57 +00002206 callback, &data, &zErrMsg
2207 );
drh75897232000-05-29 14:26:00 +00002208 }
drh75897232000-05-29 14:26:00 +00002209 if( zErrMsg ){
2210 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002211 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002212 rc = 1;
2213 }else if( rc != SQLITE_OK ){
2214 fprintf(stderr,"Error: querying schema information\n");
2215 rc = 1;
2216 }else{
2217 rc = 0;
drh75897232000-05-29 14:26:00 +00002218 }
2219 }else
2220
2221 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002222 sqlite3_snprintf(sizeof(p->separator), p->separator,
2223 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002224 }else
2225
shanehe2aa9d72009-11-06 17:20:17 +00002226 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002227 int i;
2228 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002229 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002230 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002231 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002232 fprintf(p->out,"%9.9s: ", "nullvalue");
2233 output_c_string(p->out, p->nullvalue);
2234 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002235 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002236 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002237 fprintf(p->out,"%9.9s: ", "separator");
2238 output_c_string(p->out, p->separator);
2239 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002240 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002241 fprintf(p->out,"%9.9s: ","width");
2242 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002243 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002244 }
drhfeac5f82004-08-01 00:10:45 +00002245 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002246 }else
2247
shaneh642d8b82010-07-28 16:05:34 +00002248 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2249 p->statsOn = booleanValue(azArg[1]);
2250 }else
2251
shanehe2aa9d72009-11-06 17:20:17 +00002252 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002253 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002254 char **azResult;
drh98781232012-04-23 12:38:05 +00002255 int nRow, nAlloc;
2256 char *zSql = 0;
2257 int ii;
drh44c2eb12003-04-30 11:38:26 +00002258 open_db(p);
drh98781232012-04-23 12:38:05 +00002259 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2260 if( rc ) return rc;
2261 zSql = sqlite3_mprintf(
2262 "SELECT name FROM sqlite_master"
2263 " WHERE type IN ('table','view')"
2264 " AND name NOT LIKE 'sqlite_%%'"
2265 " AND name LIKE ?1");
2266 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2267 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2268 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2269 if( strcmp(zDbName,"temp")==0 ){
2270 zSql = sqlite3_mprintf(
2271 "%z UNION ALL "
2272 "SELECT 'temp.' || name FROM sqlite_temp_master"
2273 " WHERE type IN ('table','view')"
2274 " AND name NOT LIKE 'sqlite_%%'"
2275 " AND name LIKE ?1", zSql);
2276 }else{
2277 zSql = sqlite3_mprintf(
2278 "%z UNION ALL "
2279 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2280 " WHERE type IN ('table','view')"
2281 " AND name NOT LIKE 'sqlite_%%'"
2282 " AND name LIKE ?1", zSql, zDbName, zDbName);
2283 }
drha50da102000-08-08 20:19:09 +00002284 }
drh98781232012-04-23 12:38:05 +00002285 sqlite3_finalize(pStmt);
2286 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2287 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2288 sqlite3_free(zSql);
2289 if( rc ) return rc;
2290 nRow = nAlloc = 0;
2291 azResult = 0;
2292 if( nArg>1 ){
2293 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002294 }else{
drh98781232012-04-23 12:38:05 +00002295 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2296 }
2297 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2298 if( nRow>=nAlloc ){
2299 char **azNew;
2300 int n = nAlloc*2 + 10;
2301 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2302 if( azNew==0 ){
2303 fprintf(stderr, "Error: out of memory\n");
2304 break;
2305 }
2306 nAlloc = n;
2307 azResult = azNew;
2308 }
2309 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2310 if( azResult[nRow] ) nRow++;
2311 }
2312 sqlite3_finalize(pStmt);
2313 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002314 int len, maxlen = 0;
2315 int i, j;
2316 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002317 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002318 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002319 if( len>maxlen ) maxlen = len;
2320 }
2321 nPrintCol = 80/(maxlen+2);
2322 if( nPrintCol<1 ) nPrintCol = 1;
2323 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2324 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002325 for(j=i; j<nRow; j+=nPrintRow){
2326 char *zSp = j<nPrintRow ? "" : " ";
drhe3710332000-09-29 13:30:53 +00002327 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2328 }
2329 printf("\n");
2330 }
2331 }
drh98781232012-04-23 12:38:05 +00002332 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2333 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002334 }else
2335
shaneh96887e12011-02-10 21:08:58 +00002336 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002337 static const struct {
2338 const char *zCtrlName; /* Name of a test-control option */
2339 int ctrlCode; /* Integer code for that option */
2340 } aCtrl[] = {
2341 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2342 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2343 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2344 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2345 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2346 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2347 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2348 { "assert", SQLITE_TESTCTRL_ASSERT },
2349 { "always", SQLITE_TESTCTRL_ALWAYS },
2350 { "reserve", SQLITE_TESTCTRL_RESERVE },
2351 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2352 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002353 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2354 };
shaneh96887e12011-02-10 21:08:58 +00002355 int testctrl = -1;
2356 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002357 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002358 open_db(p);
2359
drhd416fe72011-03-17 16:45:50 +00002360 /* convert testctrl text option to value. allow any unique prefix
2361 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002362 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002363 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002364 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2365 if( testctrl<0 ){
2366 testctrl = aCtrl[i].ctrlCode;
2367 }else{
drhb07028f2011-10-14 21:49:18 +00002368 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002369 testctrl = -1;
2370 break;
2371 }
2372 }
2373 }
2374 if( testctrl<0 ) testctrl = atoi(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002375 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2376 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2377 }else{
2378 switch(testctrl){
2379
2380 /* sqlite3_test_control(int, db, int) */
2381 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2382 case SQLITE_TESTCTRL_RESERVE:
2383 if( nArg==3 ){
2384 int opt = (int)strtol(azArg[2], 0, 0);
2385 rc = sqlite3_test_control(testctrl, p->db, opt);
2386 printf("%d (0x%08x)\n", rc, rc);
2387 } else {
drhd416fe72011-03-17 16:45:50 +00002388 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2389 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002390 }
2391 break;
2392
2393 /* sqlite3_test_control(int) */
2394 case SQLITE_TESTCTRL_PRNG_SAVE:
2395 case SQLITE_TESTCTRL_PRNG_RESTORE:
2396 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002397 if( nArg==2 ){
2398 rc = sqlite3_test_control(testctrl);
2399 printf("%d (0x%08x)\n", rc, rc);
2400 } else {
2401 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2402 }
2403 break;
2404
2405 /* sqlite3_test_control(int, uint) */
2406 case SQLITE_TESTCTRL_PENDING_BYTE:
2407 if( nArg==3 ){
2408 unsigned int opt = (unsigned int)atoi(azArg[2]);
2409 rc = sqlite3_test_control(testctrl, opt);
2410 printf("%d (0x%08x)\n", rc, rc);
2411 } else {
drhd416fe72011-03-17 16:45:50 +00002412 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2413 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002414 }
2415 break;
2416
2417 /* sqlite3_test_control(int, int) */
2418 case SQLITE_TESTCTRL_ASSERT:
2419 case SQLITE_TESTCTRL_ALWAYS:
2420 if( nArg==3 ){
2421 int opt = atoi(azArg[2]);
2422 rc = sqlite3_test_control(testctrl, opt);
2423 printf("%d (0x%08x)\n", rc, rc);
2424 } else {
drhd416fe72011-03-17 16:45:50 +00002425 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2426 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002427 }
2428 break;
2429
2430 /* sqlite3_test_control(int, char *) */
2431#ifdef SQLITE_N_KEYWORD
2432 case SQLITE_TESTCTRL_ISKEYWORD:
2433 if( nArg==3 ){
2434 const char *opt = azArg[2];
2435 rc = sqlite3_test_control(testctrl, opt);
2436 printf("%d (0x%08x)\n", rc, rc);
2437 } else {
drhd416fe72011-03-17 16:45:50 +00002438 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2439 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002440 }
2441 break;
2442#endif
2443
2444 case SQLITE_TESTCTRL_BITVEC_TEST:
2445 case SQLITE_TESTCTRL_FAULT_INSTALL:
2446 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2447 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2448 default:
drhd416fe72011-03-17 16:45:50 +00002449 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2450 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002451 break;
2452 }
2453 }
2454 }else
2455
shanehe2aa9d72009-11-06 17:20:17 +00002456 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002457 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002458 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002459 }else
2460
drhd416fe72011-03-17 16:45:50 +00002461 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2462 && nArg==2
2463 ){
drh3b1a9882007-11-02 12:53:03 +00002464 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002465 }else
2466
drh42f64e52012-04-04 16:56:23 +00002467 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh98781232012-04-23 12:38:05 +00002468 open_db(p);
drh42f64e52012-04-04 16:56:23 +00002469 output_file_close(p->traceOut);
2470 p->traceOut = output_file_open(azArg[1]);
2471#ifndef SQLITE_OMIT_TRACE
2472 if( p->traceOut==0 ){
2473 sqlite3_trace(p->db, 0, 0);
2474 }else{
2475 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2476 }
2477#endif
2478 }else
2479
drh9fd301b2011-06-03 13:28:22 +00002480 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh743e0032011-12-12 16:51:50 +00002481 printf("SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002482 sqlite3_libversion(), sqlite3_sourceid());
2483 }else
2484
drhde60fc22011-12-14 17:53:36 +00002485 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2486 const char *zDbName = nArg==2 ? azArg[1] : "main";
2487 char *zVfsName = 0;
2488 if( p->db ){
2489 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2490 if( zVfsName ){
2491 printf("%s\n", zVfsName);
2492 sqlite3_free(zVfsName);
2493 }
2494 }
2495 }else
2496
shanehe2aa9d72009-11-06 17:20:17 +00002497 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002498 int j;
drh43617e92006-03-06 20:55:46 +00002499 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002500 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2501 p->colWidth[j-1] = atoi(azArg[j]);
2502 }
2503 }else
2504
2505 {
shane9bd1b442009-10-23 01:27:39 +00002506 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002507 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002508 rc = 1;
drh75897232000-05-29 14:26:00 +00002509 }
drh67505e72002-04-19 12:34:06 +00002510
2511 return rc;
drh75897232000-05-29 14:26:00 +00002512}
2513
drh67505e72002-04-19 12:34:06 +00002514/*
drh91a66392007-09-07 01:12:32 +00002515** Return TRUE if a semicolon occurs anywhere in the first N characters
2516** of string z[].
drh324ccef2003-02-05 14:06:20 +00002517*/
drh91a66392007-09-07 01:12:32 +00002518static int _contains_semicolon(const char *z, int N){
2519 int i;
2520 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2521 return 0;
drh324ccef2003-02-05 14:06:20 +00002522}
2523
2524/*
drh70c7a4b2003-04-26 03:03:06 +00002525** Test to see if a line consists entirely of whitespace.
2526*/
2527static int _all_whitespace(const char *z){
2528 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002529 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002530 if( *z=='/' && z[1]=='*' ){
2531 z += 2;
2532 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2533 if( *z==0 ) return 0;
2534 z++;
2535 continue;
2536 }
2537 if( *z=='-' && z[1]=='-' ){
2538 z += 2;
2539 while( *z && *z!='\n' ){ z++; }
2540 if( *z==0 ) return 1;
2541 continue;
2542 }
2543 return 0;
2544 }
2545 return 1;
2546}
2547
2548/*
drha9b17162003-04-29 18:01:28 +00002549** Return TRUE if the line typed in is an SQL command terminator other
2550** than a semi-colon. The SQL Server style "go" command is understood
2551** as is the Oracle "/".
2552*/
2553static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002554 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002555 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2556 return 1; /* Oracle */
2557 }
drhf0693c82011-10-11 20:41:54 +00002558 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002559 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002560 return 1; /* SQL Server */
2561 }
2562 return 0;
2563}
2564
2565/*
drh233a5312008-12-18 22:25:13 +00002566** Return true if zSql is a complete SQL statement. Return false if it
2567** ends in the middle of a string literal or C-style comment.
2568*/
2569static int _is_complete(char *zSql, int nSql){
2570 int rc;
2571 if( zSql==0 ) return 1;
2572 zSql[nSql] = ';';
2573 zSql[nSql+1] = 0;
2574 rc = sqlite3_complete(zSql);
2575 zSql[nSql] = 0;
2576 return rc;
2577}
2578
2579/*
drh67505e72002-04-19 12:34:06 +00002580** Read input from *in and process it. If *in==0 then input
2581** is interactive - the user is typing it it. Otherwise, input
2582** is coming from a file or device. A prompt is issued and history
2583** is saved only if input is interactive. An interrupt signal will
2584** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002585**
2586** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002587*/
drhc28490c2006-10-26 14:25:58 +00002588static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002589 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002590 char *zSql = 0;
2591 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002592 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002593 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002594 int rc;
2595 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002596 int lineno = 0;
2597 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002598
2599 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2600 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002601 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002602 zLine = one_input_line(zSql, in);
2603 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002604 /* End of input */
2605 if( stdin_is_interactive ) printf("\n");
2606 break;
drhc49f44e2006-10-26 18:15:42 +00002607 }
drh67505e72002-04-19 12:34:06 +00002608 if( seenInterrupt ){
2609 if( in!=0 ) break;
2610 seenInterrupt = 0;
2611 }
drhc28490c2006-10-26 14:25:58 +00002612 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002613 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002614 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002615 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002616 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002617 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002618 break;
2619 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002620 errCnt++;
2621 }
drhdaffd0e2001-04-11 14:28:42 +00002622 continue;
2623 }
drh233a5312008-12-18 22:25:13 +00002624 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002625 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002626 }
drh91a66392007-09-07 01:12:32 +00002627 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002628 if( zSql==0 ){
2629 int i;
drhf0693c82011-10-11 20:41:54 +00002630 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002631 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002632 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002633 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002634 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002635 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002636 exit(1);
2637 }
drh5bb3eb92007-05-04 13:15:55 +00002638 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002639 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002640 }
2641 }else{
drh4f21c4a2008-12-10 22:15:00 +00002642 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002643 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002644 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002645 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002646 exit(1);
2647 }
drh5bb3eb92007-05-04 13:15:55 +00002648 zSql[nSql++] = '\n';
2649 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002650 nSql += len;
2651 }
drh91a66392007-09-07 01:12:32 +00002652 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2653 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002654 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002655 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002656 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002657 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002658 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002659 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002660 char zPrefix[100];
2661 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002662 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002663 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002664 }else{
shane9bd1b442009-10-23 01:27:39 +00002665 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002666 }
drh7f953e22002-07-13 17:33:45 +00002667 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002668 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002669 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002670 zErrMsg = 0;
2671 }else{
shaned2bed1c2009-10-21 03:56:54 +00002672 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002673 }
drhc49f44e2006-10-26 18:15:42 +00002674 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002675 }
2676 free(zSql);
2677 zSql = 0;
2678 nSql = 0;
2679 }
2680 }
2681 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002682 if( !_all_whitespace(zSql) ){
2683 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2684 }
drhdaffd0e2001-04-11 14:28:42 +00002685 free(zSql);
2686 }
danielk19772ac27622007-07-03 05:31:16 +00002687 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002688 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002689}
2690
drh67505e72002-04-19 12:34:06 +00002691/*
2692** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002693** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002694*/
2695static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002696 static char *home_dir = NULL;
2697 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002698
chw97185482008-11-17 08:05:31 +00002699#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002700 struct passwd *pwent;
2701 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002702 if( (pwent=getpwuid(uid)) != NULL) {
2703 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002704 }
2705#endif
2706
chw65d3c132007-11-12 21:09:10 +00002707#if defined(_WIN32_WCE)
2708 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2709 */
drh85e72432012-04-11 11:38:53 +00002710 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00002711#else
2712
drh164a1b62006-08-19 11:15:20 +00002713#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2714 if (!home_dir) {
2715 home_dir = getenv("USERPROFILE");
2716 }
2717#endif
2718
drh67505e72002-04-19 12:34:06 +00002719 if (!home_dir) {
2720 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002721 }
2722
drhcdb36b72006-06-12 12:57:45 +00002723#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002724 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002725 char *zDrive, *zPath;
2726 int n;
2727 zDrive = getenv("HOMEDRIVE");
2728 zPath = getenv("HOMEPATH");
2729 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002730 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002731 home_dir = malloc( n );
2732 if( home_dir==0 ) return 0;
2733 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2734 return home_dir;
2735 }
2736 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002737 }
2738#endif
2739
chw65d3c132007-11-12 21:09:10 +00002740#endif /* !_WIN32_WCE */
2741
drh67505e72002-04-19 12:34:06 +00002742 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002743 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002744 char *z = malloc( n );
2745 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002746 home_dir = z;
2747 }
drhe98d4fa2002-04-21 19:06:22 +00002748
drh67505e72002-04-19 12:34:06 +00002749 return home_dir;
2750}
2751
2752/*
2753** Read input from the file given by sqliterc_override. Or if that
2754** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002755**
2756** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002757*/
shane9bd1b442009-10-23 01:27:39 +00002758static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002759 struct callback_data *p, /* Configuration data */
2760 const char *sqliterc_override /* Name of config file. NULL to use default */
2761){
persicom7e2dfdd2002-04-18 02:46:52 +00002762 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002763 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002764 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002765 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00002766 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002767
2768 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002769 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002770 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002771#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002772 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002773#endif
shane9bd1b442009-10-23 01:27:39 +00002774 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002775 }
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 ){
danielk197729bafea2008-06-26 10:41:19 +00002939#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002940 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2941#else
drh22fbcb82004-02-01 01:22:50 +00002942 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002943#endif
drh22fbcb82004-02-01 01:22:50 +00002944 }else{
danielk197703aded42004-11-22 05:26:27 +00002945#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002946 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002947#else
2948 data.zDbFilename = 0;
2949#endif
drh22fbcb82004-02-01 01:22:50 +00002950 }
2951 if( i<argc ){
2952 zFirstCmd = argv[i++];
2953 }
shaneh5fc25012009-11-11 04:17:07 +00002954 if( i<argc ){
2955 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2956 fprintf(stderr,"Use -help for a list of options.\n");
2957 return 1;
2958 }
drh44c2eb12003-04-30 11:38:26 +00002959 data.out = stdout;
2960
drh01b41712005-08-29 23:06:23 +00002961#ifdef SQLITE_OMIT_MEMORYDB
2962 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002963 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2964 return 1;
drh01b41712005-08-29 23:06:23 +00002965 }
2966#endif
2967
drh44c2eb12003-04-30 11:38:26 +00002968 /* Go ahead and open the database file if it already exists. If the
2969 ** file does not exist, delay opening it. This prevents empty database
2970 ** files from being created if a user mistypes the database name argument
2971 ** to the sqlite command-line tool.
2972 */
drhc8d74412004-08-31 23:41:26 +00002973 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002974 open_db(&data);
2975 }
2976
drh22fbcb82004-02-01 01:22:50 +00002977 /* Process the initialization file if there is one. If no -init option
2978 ** is given on the command line, look for a file named ~/.sqliterc and
2979 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002980 */
shane86f5bdb2009-10-24 02:00:07 +00002981 rc = process_sqliterc(&data,zInitFile);
2982 if( rc>0 ){
2983 return rc;
2984 }
drh44c2eb12003-04-30 11:38:26 +00002985
drh22fbcb82004-02-01 01:22:50 +00002986 /* Make a second pass through the command-line argument and set
2987 ** options. This second pass is delayed until after the initialization
2988 ** file is processed so that the command-line arguments will override
2989 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002990 */
drh22fbcb82004-02-01 01:22:50 +00002991 for(i=1; i<argc && argv[i][0]=='-'; i++){
2992 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002993 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002994 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002995 i++;
2996 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002997 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002998 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002999 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003000 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003001 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003002 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003003 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003004 }else if( strcmp(z,"-csv")==0 ){
3005 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003006 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003007 }else if( strcmp(z,"-separator")==0 ){
3008 i++;
shaneh5fc25012009-11-11 04:17:07 +00003009 if(i>=argc){
drhcc3b4f82012-02-07 14:13:50 +00003010 fprintf(stderr,"%s: Error: missing argument for option: %s\n",
3011 Argv0, z);
shaneh5fc25012009-11-11 04:17:07 +00003012 fprintf(stderr,"Use -help for a list of options.\n");
3013 return 1;
3014 }
drh5bb3eb92007-05-04 13:15:55 +00003015 sqlite3_snprintf(sizeof(data.separator), data.separator,
3016 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003017 }else if( strcmp(z,"-nullvalue")==0 ){
3018 i++;
shaneh5fc25012009-11-11 04:17:07 +00003019 if(i>=argc){
drhcc3b4f82012-02-07 14:13:50 +00003020 fprintf(stderr,"%s: Error: missing argument for option: %s\n",
3021 Argv0, z);
shaneh5fc25012009-11-11 04:17:07 +00003022 fprintf(stderr,"Use -help for a list of options.\n");
3023 return 1;
3024 }
drh5bb3eb92007-05-04 13:15:55 +00003025 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
3026 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00003027 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003028 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003029 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003030 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003031 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003032 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003033 }else if( strcmp(z,"-stats")==0 ){
3034 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003035 }else if( strcmp(z,"-bail")==0 ){
3036 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003037 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003038 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003039 return 0;
drhc28490c2006-10-26 14:25:58 +00003040 }else if( strcmp(z,"-interactive")==0 ){
3041 stdin_is_interactive = 1;
3042 }else if( strcmp(z,"-batch")==0 ){
3043 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003044 }else if( strcmp(z,"-heap")==0 ){
3045 i++;
drha7e61d82011-03-12 17:02:57 +00003046 }else if( strcmp(z,"-vfs")==0 ){
3047 i++;
drh6f25e892011-07-08 17:02:57 +00003048#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003049 }else if( strcmp(z,"-vfstrace")==0 ){
3050 i++;
drh6f25e892011-07-08 17:02:57 +00003051#endif
3052#ifdef SQLITE_ENABLE_MULTIPLEX
3053 }else if( strcmp(z,"-multiplex")==0 ){
3054 i++;
3055#endif
drhcc3b4f82012-02-07 14:13:50 +00003056 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003057 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003058 }else if( strcmp(z,"-cmd")==0 ){
3059 if( i==argc-1 ) break;
3060 i++;
3061 z = argv[i];
3062 if( z[0]=='.' ){
3063 rc = do_meta_command(z, &data);
3064 if( rc && bail_on_error ) return rc;
3065 }else{
3066 open_db(&data);
3067 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3068 if( zErrMsg!=0 ){
3069 fprintf(stderr,"Error: %s\n", zErrMsg);
3070 if( bail_on_error ) return rc!=0 ? rc : 1;
3071 }else if( rc!=0 ){
3072 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3073 if( bail_on_error ) return rc;
3074 }
3075 }
drh1e5d0e92000-05-31 23:33:17 +00003076 }else{
shane86f5bdb2009-10-24 02:00:07 +00003077 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003078 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003079 return 1;
3080 }
3081 }
drh44c2eb12003-04-30 11:38:26 +00003082
drh22fbcb82004-02-01 01:22:50 +00003083 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003084 /* Run just the command that follows the database name
3085 */
drh22fbcb82004-02-01 01:22:50 +00003086 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003087 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003088 }else{
drh44c2eb12003-04-30 11:38:26 +00003089 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003090 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003091 if( zErrMsg!=0 ){
3092 fprintf(stderr,"Error: %s\n", zErrMsg);
3093 return rc!=0 ? rc : 1;
3094 }else if( rc!=0 ){
3095 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3096 return rc;
drh6ff13852001-11-25 13:18:23 +00003097 }
drh75897232000-05-29 14:26:00 +00003098 }
3099 }else{
drh44c2eb12003-04-30 11:38:26 +00003100 /* Run commands received from standard input
3101 */
drhc28490c2006-10-26 14:25:58 +00003102 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003103 char *zHome;
3104 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003105 int nHistory;
drh75897232000-05-29 14:26:00 +00003106 printf(
drh743e0032011-12-12 16:51:50 +00003107 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003108 "Enter \".help\" for instructions\n"
3109 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003110 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003111 );
drh67505e72002-04-19 12:34:06 +00003112 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003113 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003114 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003115 if( (zHistory = malloc(nHistory))!=0 ){
3116 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3117 }
drh67505e72002-04-19 12:34:06 +00003118 }
danielk19774af00c62005-01-23 23:43:21 +00003119#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003120 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003121#endif
drhc28490c2006-10-26 14:25:58 +00003122 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003123 if( zHistory ){
3124 stifle_history(100);
3125 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003126 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003127 }
drhdaffd0e2001-04-11 14:28:42 +00003128 }else{
drhc28490c2006-10-26 14:25:58 +00003129 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003130 }
3131 }
drh33048c02001-10-01 14:29:22 +00003132 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003133 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003134 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003135 }
drhc28490c2006-10-26 14:25:58 +00003136 return rc;
drh75897232000-05-29 14:26:00 +00003137}