blob: 1212d38caf2563d5c53a9cd57941e1edd8ac1800 [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*/
shane18e526c2008-12-10 22:30:24 +000015#if defined(_WIN32) || defined(WIN32)
16/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh75897232000-05-29 14:26:00 +000020#include <stdlib.h>
21#include <string.h>
22#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000023#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000024#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000025#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000026#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000027
drh454ad582007-11-26 22:54:27 +000028#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000029# include <signal.h>
chw97185482008-11-17 08:05:31 +000030# if !defined(__RTP__) && !defined(_WRS_KERNEL)
31# include <pwd.h>
32# endif
drhdd45df82002-04-18 12:39:03 +000033# include <unistd.h>
34# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000035#endif
drh75897232000-05-29 14:26:00 +000036
drhcdb36b72006-06-12 12:57:45 +000037#ifdef __OS2__
38# include <unistd.h>
39#endif
40
drh16e59552000-07-31 11:57:37 +000041#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000042# include <readline/readline.h>
43# include <readline/history.h>
44#else
drh9347b202003-07-18 01:30:59 +000045# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000046# define add_history(X)
drh67505e72002-04-19 12:34:06 +000047# define read_history(X)
48# define write_history(X)
49# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000050#endif
51
adamd2e8464a2006-09-06 21:39:40 +000052#if defined(_WIN32) || defined(WIN32)
53# include <io.h>
shane18e526c2008-12-10 22:30:24 +000054#define isatty(h) _isatty(h)
55#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000056#else
drh4328c8b2003-04-26 02:50:11 +000057/* Make sure isatty() has a prototype.
58*/
59extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000060#endif
drh4328c8b2003-04-26 02:50:11 +000061
chw65d3c132007-11-12 21:09:10 +000062#if defined(_WIN32_WCE)
63/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
64 * thus we always assume that we have a console. That can be
65 * overridden with the -batch command line option.
66 */
67#define isatty(x) 1
68#endif
69
chw97185482008-11-17 08:05:31 +000070#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000071#include <sys/time.h>
72#include <sys/resource.h>
73
drhda108222009-02-25 19:07:24 +000074/* Saved resource information for the beginning of an operation */
75static struct rusage sBegin;
76
77/* True if the timer is enabled */
78static int enableTimer = 0;
79
80/*
81** Begin timing an operation
82*/
83static void beginTimer(void){
84 if( enableTimer ){
85 getrusage(RUSAGE_SELF, &sBegin);
86 }
87}
88
89/* Return the difference of two time_structs in seconds */
90static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
91 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
92 (double)(pEnd->tv_sec - pStart->tv_sec);
93}
94
95/*
96** Print the timing results.
97*/
98static void endTimer(void){
99 if( enableTimer ){
100 struct rusage sEnd;
101 getrusage(RUSAGE_SELF, &sEnd);
102 printf("CPU Time: user %f sys %f\n",
103 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
104 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
105 }
106}
shaneb320ccd2009-10-21 03:42:58 +0000107
drhda108222009-02-25 19:07:24 +0000108#define BEGIN_TIMER beginTimer()
109#define END_TIMER endTimer()
110#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000111
112#elif (defined(_WIN32) || defined(WIN32))
113
114#include <windows.h>
115
116/* Saved resource information for the beginning of an operation */
117static HANDLE hProcess;
118static FILETIME ftKernelBegin;
119static FILETIME ftUserBegin;
120typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
121static GETPROCTIMES getProcessTimesAddr = NULL;
122
123/* True if the timer is enabled */
124static int enableTimer = 0;
125
126/*
127** Check to see if we have timer support. Return 1 if necessary
128** support found (or found previously).
129*/
130static int hasTimer(void){
131 if( getProcessTimesAddr ){
132 return 1;
133 } else {
134 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
135 ** See if the version we are running on has it, and if it does, save off
136 ** a pointer to it and the current process handle.
137 */
138 hProcess = GetCurrentProcess();
139 if( hProcess ){
140 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
141 if( NULL != hinstLib ){
142 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
143 if( NULL != getProcessTimesAddr ){
144 return 1;
145 }
146 FreeLibrary(hinstLib);
147 }
148 }
149 }
150 return 0;
151}
152
153/*
154** Begin timing an operation
155*/
156static void beginTimer(void){
157 if( enableTimer && getProcessTimesAddr ){
158 FILETIME ftCreation, ftExit;
159 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
160 }
161}
162
163/* Return the difference of two FILETIME structs in seconds */
164static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
165 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
166 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
167 return (double) ((i64End - i64Start) / 10000000.0);
168}
169
170/*
171** Print the timing results.
172*/
173static void endTimer(void){
174 if( enableTimer && getProcessTimesAddr){
175 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
176 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
177 printf("CPU Time: user %f sys %f\n",
178 timeDiff(&ftUserBegin, &ftUserEnd),
179 timeDiff(&ftKernelBegin, &ftKernelEnd));
180 }
181}
182
183#define BEGIN_TIMER beginTimer()
184#define END_TIMER endTimer()
185#define HAS_TIMER hasTimer()
186
drhda108222009-02-25 19:07:24 +0000187#else
188#define BEGIN_TIMER
189#define END_TIMER
190#define HAS_TIMER 0
191#endif
192
shanec0688ea2009-03-05 03:48:06 +0000193/*
194** Used to prevent warnings about unused parameters
195*/
196#define UNUSED_PARAMETER(x) (void)(x)
197
drhe91d16b2008-12-08 18:27:31 +0000198/*
drhc49f44e2006-10-26 18:15:42 +0000199** If the following flag is set, then command execution stops
200** at an error if we are not interactive.
201*/
202static int bail_on_error = 0;
203
204/*
drhc28490c2006-10-26 14:25:58 +0000205** Threat stdin as an interactive input if the following variable
206** is true. Otherwise, assume stdin is connected to a file or pipe.
207*/
208static int stdin_is_interactive = 1;
209
210/*
drh4c504392000-10-16 22:06:40 +0000211** The following is the open SQLite database. We make a pointer
212** to this database a static variable so that it can be accessed
213** by the SIGINT handler to interrupt database processing.
214*/
danielk197792f9a1b2004-06-19 09:08:16 +0000215static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000216
217/*
drh67505e72002-04-19 12:34:06 +0000218** True if an interrupt (Control-C) has been received.
219*/
drh43617e92006-03-06 20:55:46 +0000220static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000221
222/*
persicom7e2dfdd2002-04-18 02:46:52 +0000223** This is the name of our program. It is set in main(), used
224** in a number of other places, mostly for error messages.
225*/
226static char *Argv0;
227
228/*
229** Prompt strings. Initialized in main. Settable with
230** .prompt main continue
231*/
232static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
233static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
234
drhb0603412007-02-28 04:47:26 +0000235/*
236** Write I/O traces to the following stream.
237*/
rsebe0a9092007-07-30 18:24:38 +0000238#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000239static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000240#endif
drhb0603412007-02-28 04:47:26 +0000241
242/*
243** This routine works like printf in that its first argument is a
244** format string and subsequent arguments are values to be substituted
245** in place of % fields. The result of formatting this string
246** is written to iotrace.
247*/
rsebe0a9092007-07-30 18:24:38 +0000248#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000249static void iotracePrintf(const char *zFormat, ...){
250 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000251 char *z;
drhb0603412007-02-28 04:47:26 +0000252 if( iotrace==0 ) return;
253 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000254 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000255 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000256 fprintf(iotrace, "%s", z);
257 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000258}
rsebe0a9092007-07-30 18:24:38 +0000259#endif
drhb0603412007-02-28 04:47:26 +0000260
drh44c2eb12003-04-30 11:38:26 +0000261
persicom7e2dfdd2002-04-18 02:46:52 +0000262/*
drh83965662003-04-17 02:54:13 +0000263** Determines if a string is a number of not.
264*/
danielk19772e588c72005-12-09 14:25:08 +0000265static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000266 if( *z=='-' || *z=='+' ) z++;
267 if( !isdigit(*z) ){
268 return 0;
269 }
270 z++;
271 if( realnum ) *realnum = 0;
272 while( isdigit(*z) ){ z++; }
273 if( *z=='.' ){
274 z++;
275 if( !isdigit(*z) ) return 0;
276 while( isdigit(*z) ){ z++; }
277 if( realnum ) *realnum = 1;
278 }
279 if( *z=='e' || *z=='E' ){
280 z++;
281 if( *z=='+' || *z=='-' ) z++;
282 if( !isdigit(*z) ) return 0;
283 while( isdigit(*z) ){ z++; }
284 if( realnum ) *realnum = 1;
285 }
286 return *z==0;
287}
drh83965662003-04-17 02:54:13 +0000288
289/*
danielk1977bc6ada42004-06-30 08:20:16 +0000290** A global char* and an SQL function to access its current value
291** from within an SQL statement. This program used to use the
292** sqlite_exec_printf() API to substitue a string into an SQL statement.
293** The correct way to do this with sqlite3 is to use the bind API, but
294** since the shell is built around the callback paradigm it would be a lot
295** of work. Instead just use this hack, which is quite harmless.
296*/
297static const char *zShellStatic = 0;
298static void shellstaticFunc(
299 sqlite3_context *context,
300 int argc,
301 sqlite3_value **argv
302){
303 assert( 0==argc );
304 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000305 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000306 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000307 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
308}
309
310
311/*
drhfeac5f82004-08-01 00:10:45 +0000312** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000313** the text in memory obtained from malloc() and returns a pointer
314** to the text. NULL is returned at end of file, or if malloc()
315** fails.
316**
317** The interface is like "readline" but no command-line editing
318** is done.
319*/
drh9347b202003-07-18 01:30:59 +0000320static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000321 char *zLine;
322 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000323 int n;
324 int eol;
325
326 if( zPrompt && *zPrompt ){
327 printf("%s",zPrompt);
328 fflush(stdout);
329 }
330 nLine = 100;
331 zLine = malloc( nLine );
332 if( zLine==0 ) return 0;
333 n = 0;
334 eol = 0;
335 while( !eol ){
336 if( n+100>nLine ){
337 nLine = nLine*2 + 100;
338 zLine = realloc(zLine, nLine);
339 if( zLine==0 ) return 0;
340 }
drhdaffd0e2001-04-11 14:28:42 +0000341 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000342 if( n==0 ){
343 free(zLine);
344 return 0;
345 }
346 zLine[n] = 0;
347 eol = 1;
348 break;
349 }
350 while( zLine[n] ){ n++; }
351 if( n>0 && zLine[n-1]=='\n' ){
352 n--;
shaneh13b36022009-12-17 21:07:15 +0000353 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000354 zLine[n] = 0;
355 eol = 1;
356 }
357 }
358 zLine = realloc( zLine, n+1 );
359 return zLine;
360}
361
362/*
drhc28490c2006-10-26 14:25:58 +0000363** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000364**
365** zPrior is a string of prior text retrieved. If not the empty
366** string, then issue a continuation prompt.
367*/
drhdaffd0e2001-04-11 14:28:42 +0000368static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000369 char *zPrompt;
370 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000371 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000372 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000373 }
374 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000375 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000376 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000377 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000378 }
379 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000380#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000381 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000382#endif
drh8e7e7a22000-05-30 18:45:23 +0000383 return zResult;
384}
385
persicom7e2dfdd2002-04-18 02:46:52 +0000386struct previous_mode_data {
387 int valid; /* Is there legit data in here? */
388 int mode;
389 int showHeader;
390 int colWidth[100];
391};
drh45e29d82006-11-20 16:21:10 +0000392
drh8e7e7a22000-05-30 18:45:23 +0000393/*
drh75897232000-05-29 14:26:00 +0000394** An pointer to an instance of this structure is passed from
395** the main program to the callback. This is used to communicate
396** state and mode information.
397*/
398struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000399 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000400 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000401 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000402 int cnt; /* Number of records displayed so far */
403 FILE *out; /* Write results here */
404 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000405 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000406 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000407 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000408 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000409 int colWidth[100]; /* Requested width of each column when in column mode*/
410 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000411 char nullvalue[20]; /* The text to print when a NULL comes back from
412 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000413 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000414 /* Holds the mode information just before
415 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000416 char outfile[FILENAME_MAX]; /* Filename for *out */
417 const char *zDbFilename; /* name of the database file */
shane626a6e42009-10-22 17:30:15 +0000418 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000419 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000420};
421
422/*
423** These are the allowed modes.
424*/
drh967e8b72000-06-21 13:59:10 +0000425#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000426#define MODE_Column 1 /* One record per line in neat columns */
427#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000428#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
429#define MODE_Html 4 /* Generate an XHTML table */
430#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000431#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000432#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000433#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000434
drh66ce4d02008-02-15 17:38:06 +0000435static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000436 "line",
437 "column",
438 "list",
439 "semi",
440 "html",
drhfeac5f82004-08-01 00:10:45 +0000441 "insert",
442 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000443 "csv",
drh66ce4d02008-02-15 17:38:06 +0000444 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000445};
drh75897232000-05-29 14:26:00 +0000446
447/*
448** Number of elements in an array
449*/
drh902b9ee2008-12-05 17:17:07 +0000450#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000451
452/*
drhea678832008-12-10 19:26:22 +0000453** Compute a string length that is limited to what can be stored in
454** lower 30 bits of a 32-bit signed integer.
455*/
drh4f21c4a2008-12-10 22:15:00 +0000456static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000457 const char *z2 = z;
458 while( *z2 ){ z2++; }
459 return 0x3fffffff & (int)(z2 - z);
460}
461
462/*
drh127f9d72010-02-23 01:47:00 +0000463** A callback for the sqlite3_log() interface.
464*/
465static void shellLog(void *pArg, int iErrCode, const char *zMsg){
466 struct callback_data *p = (struct callback_data*)pArg;
467 if( p->pLog==0 ) return;
468 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
469 fflush(p->pLog);
470}
471
472/*
shane626a6e42009-10-22 17:30:15 +0000473** Output the given string as a hex-encoded blob (eg. X'1234' )
474*/
475static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
476 int i;
477 char *zBlob = (char *)pBlob;
478 fprintf(out,"X'");
479 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
480 fprintf(out,"'");
481}
482
483/*
drh28bd4bc2000-06-15 15:57:22 +0000484** Output the given string as a quoted string using SQL quoting conventions.
485*/
486static void output_quoted_string(FILE *out, const char *z){
487 int i;
488 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000489 for(i=0; z[i]; i++){
490 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000491 }
492 if( nSingle==0 ){
493 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000494 }else{
495 fprintf(out,"'");
496 while( *z ){
497 for(i=0; z[i] && z[i]!='\''; i++){}
498 if( i==0 ){
499 fprintf(out,"''");
500 z++;
501 }else if( z[i]=='\'' ){
502 fprintf(out,"%.*s''",i,z);
503 z += i+1;
504 }else{
drhcd7d2732002-02-26 23:24:26 +0000505 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000506 break;
507 }
508 }
drhcd7d2732002-02-26 23:24:26 +0000509 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000510 }
511}
512
513/*
drhfeac5f82004-08-01 00:10:45 +0000514** Output the given string as a quoted according to C or TCL quoting rules.
515*/
516static void output_c_string(FILE *out, const char *z){
517 unsigned int c;
518 fputc('"', out);
519 while( (c = *(z++))!=0 ){
520 if( c=='\\' ){
521 fputc(c, out);
522 fputc(c, out);
523 }else if( c=='\t' ){
524 fputc('\\', out);
525 fputc('t', out);
526 }else if( c=='\n' ){
527 fputc('\\', out);
528 fputc('n', out);
529 }else if( c=='\r' ){
530 fputc('\\', out);
531 fputc('r', out);
532 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000533 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000534 }else{
535 fputc(c, out);
536 }
537 }
538 fputc('"', out);
539}
540
541/*
drhc08a4f12000-06-15 16:49:48 +0000542** Output the given string with characters that are special to
543** HTML escaped.
544*/
545static void output_html_string(FILE *out, const char *z){
546 int i;
547 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000548 for(i=0; z[i]
549 && z[i]!='<'
550 && z[i]!='&'
551 && z[i]!='>'
552 && z[i]!='\"'
553 && z[i]!='\'';
554 i++){}
drhc08a4f12000-06-15 16:49:48 +0000555 if( i>0 ){
556 fprintf(out,"%.*s",i,z);
557 }
558 if( z[i]=='<' ){
559 fprintf(out,"&lt;");
560 }else if( z[i]=='&' ){
561 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000562 }else if( z[i]=='>' ){
563 fprintf(out,"&gt;");
564 }else if( z[i]=='\"' ){
565 fprintf(out,"&quot;");
566 }else if( z[i]=='\'' ){
567 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000568 }else{
569 break;
570 }
571 z += i + 1;
572 }
573}
574
575/*
drhc49f44e2006-10-26 18:15:42 +0000576** If a field contains any character identified by a 1 in the following
577** array, then the string must be quoted for CSV.
578*/
579static const char needCsvQuote[] = {
580 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
581 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
582 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
583 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
584 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
585 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
587 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
588 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
589 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
590 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
591 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
592 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
593 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
594 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
595 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
596};
597
598/*
drh8e64d1c2004-10-07 00:32:39 +0000599** Output a single term of CSV. Actually, p->separator is used for
600** the separator, which may or may not be a comma. p->nullvalue is
601** the null value. Strings are quoted using ANSI-C rules. Numbers
602** appear outside of quotes.
603*/
604static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000605 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000606 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000607 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000608 }else{
drhc49f44e2006-10-26 18:15:42 +0000609 int i;
drh4f21c4a2008-12-10 22:15:00 +0000610 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000611 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000612 if( needCsvQuote[((unsigned char*)z)[i]]
613 || (z[i]==p->separator[0] &&
614 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000615 i = 0;
616 break;
617 }
618 }
619 if( i==0 ){
620 putc('"', out);
621 for(i=0; z[i]; i++){
622 if( z[i]=='"' ) putc('"', out);
623 putc(z[i], out);
624 }
625 putc('"', out);
626 }else{
627 fprintf(out, "%s", z);
628 }
drh8e64d1c2004-10-07 00:32:39 +0000629 }
630 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000631 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000632 }
633}
634
danielk19774af00c62005-01-23 23:43:21 +0000635#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000636/*
drh4c504392000-10-16 22:06:40 +0000637** This routine runs when the user presses Ctrl-C
638*/
639static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000640 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000641 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000642 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000643}
danielk19774af00c62005-01-23 23:43:21 +0000644#endif
drh4c504392000-10-16 22:06:40 +0000645
646/*
shane626a6e42009-10-22 17:30:15 +0000647** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000648** invokes for each row of a query result.
649*/
shane626a6e42009-10-22 17:30:15 +0000650static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000651 int i;
652 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000653
drh75897232000-05-29 14:26:00 +0000654 switch( p->mode ){
655 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000656 int w = 5;
drh6a535342001-10-19 16:44:56 +0000657 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000658 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000659 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000660 if( len>w ) w = len;
661 }
drh75897232000-05-29 14:26:00 +0000662 if( p->cnt++>0 ) fprintf(p->out,"\n");
663 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000664 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000665 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000666 }
667 break;
668 }
danielk19770d78bae2008-01-03 07:09:48 +0000669 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000670 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000671 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000672 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000673 int w, n;
674 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000675 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000676 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000677 w = 0;
drh75897232000-05-29 14:26:00 +0000678 }
drha0c66f52000-07-29 13:20:21 +0000679 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000680 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000681 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000682 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000683 if( w<n ) w = n;
684 }
685 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000686 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000687 }
688 if( p->showHeader ){
689 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
690 }
691 }
692 if( p->showHeader ){
693 for(i=0; i<nArg; i++){
694 int w;
695 if( i<ArraySize(p->actualWidth) ){
696 w = p->actualWidth[i];
697 }else{
698 w = 10;
699 }
700 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
701 "----------------------------------------------------------",
702 i==nArg-1 ? "\n": " ");
703 }
drh75897232000-05-29 14:26:00 +0000704 }
705 }
drh6a535342001-10-19 16:44:56 +0000706 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000707 for(i=0; i<nArg; i++){
708 int w;
drha0c66f52000-07-29 13:20:21 +0000709 if( i<ArraySize(p->actualWidth) ){
710 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000711 }else{
712 w = 10;
713 }
drhea678832008-12-10 19:26:22 +0000714 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000715 strlen30(azArg[i])>w ){
716 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000717 }
drhc61053b2000-06-04 12:58:36 +0000718 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000719 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000720 }
721 break;
722 }
drhe3710332000-09-29 13:30:53 +0000723 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000724 case MODE_List: {
725 if( p->cnt++==0 && p->showHeader ){
726 for(i=0; i<nArg; i++){
727 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
728 }
729 }
drh6a535342001-10-19 16:44:56 +0000730 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000731 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000732 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000733 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000734 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000735 if( i<nArg-1 ){
736 fprintf(p->out, "%s", p->separator);
737 }else if( p->mode==MODE_Semi ){
738 fprintf(p->out, ";\n");
739 }else{
740 fprintf(p->out, "\n");
741 }
drh75897232000-05-29 14:26:00 +0000742 }
743 break;
744 }
drh1e5d0e92000-05-31 23:33:17 +0000745 case MODE_Html: {
746 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000747 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000748 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000749 fprintf(p->out,"<TH>");
750 output_html_string(p->out, azCol[i]);
751 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000752 }
mihailim57c591a2008-06-23 21:26:05 +0000753 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000754 }
drh6a535342001-10-19 16:44:56 +0000755 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000756 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000757 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000758 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000759 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000760 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000761 }
mihailim57c591a2008-06-23 21:26:05 +0000762 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000763 break;
764 }
drhfeac5f82004-08-01 00:10:45 +0000765 case MODE_Tcl: {
766 if( p->cnt++==0 && p->showHeader ){
767 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000768 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000769 fprintf(p->out, "%s", p->separator);
770 }
771 fprintf(p->out,"\n");
772 }
773 if( azArg==0 ) break;
774 for(i=0; i<nArg; i++){
775 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
776 fprintf(p->out, "%s", p->separator);
777 }
778 fprintf(p->out,"\n");
779 break;
780 }
drh8e64d1c2004-10-07 00:32:39 +0000781 case MODE_Csv: {
782 if( p->cnt++==0 && p->showHeader ){
783 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000784 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000785 }
786 fprintf(p->out,"\n");
787 }
788 if( azArg==0 ) break;
789 for(i=0; i<nArg; i++){
790 output_csv(p, azArg[i], i<nArg-1);
791 }
792 fprintf(p->out,"\n");
793 break;
794 }
drh28bd4bc2000-06-15 15:57:22 +0000795 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000796 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000797 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000798 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000799 for(i=0; i<nArg; i++){
800 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000801 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000802 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000803 }else if( aiType && aiType[i]==SQLITE_TEXT ){
804 if( zSep[0] ) fprintf(p->out,"%s",zSep);
805 output_quoted_string(p->out, azArg[i]);
806 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
807 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000808 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
809 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
810 int nBlob = sqlite3_column_bytes(p->pStmt, i);
811 if( zSep[0] ) fprintf(p->out,"%s",zSep);
812 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000813 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000814 fprintf(p->out,"%s%s",zSep, azArg[i]);
815 }else{
816 if( zSep[0] ) fprintf(p->out,"%s",zSep);
817 output_quoted_string(p->out, azArg[i]);
818 }
819 }
820 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000821 break;
drh28bd4bc2000-06-15 15:57:22 +0000822 }
persicom1d0b8722002-04-18 02:53:04 +0000823 }
drh75897232000-05-29 14:26:00 +0000824 return 0;
825}
826
827/*
shane626a6e42009-10-22 17:30:15 +0000828** This is the callback routine that the SQLite library
829** invokes for each row of a query result.
830*/
831static int callback(void *pArg, int nArg, char **azArg, char **azCol){
832 /* since we don't have type info, call the shell_callback with a NULL value */
833 return shell_callback(pArg, nArg, azArg, azCol, NULL);
834}
835
836/*
drh33048c02001-10-01 14:29:22 +0000837** Set the destination table field of the callback_data structure to
838** the name of the table given. Escape any quote characters in the
839** table name.
840*/
841static void set_table_name(struct callback_data *p, const char *zName){
842 int i, n;
843 int needQuote;
844 char *z;
845
846 if( p->zDestTable ){
847 free(p->zDestTable);
848 p->zDestTable = 0;
849 }
850 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000851 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000852 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000853 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000854 needQuote = 1;
855 if( zName[i]=='\'' ) n++;
856 }
857 }
858 if( needQuote ) n += 2;
859 z = p->zDestTable = malloc( n+1 );
860 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000861 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000862 exit(1);
863 }
864 n = 0;
865 if( needQuote ) z[n++] = '\'';
866 for(i=0; zName[i]; i++){
867 z[n++] = zName[i];
868 if( zName[i]=='\'' ) z[n++] = '\'';
869 }
870 if( needQuote ) z[n++] = '\'';
871 z[n] = 0;
872}
873
danielk19772a02e332004-06-05 08:04:36 +0000874/* zIn is either a pointer to a NULL-terminated string in memory obtained
875** from malloc(), or a NULL pointer. The string pointed to by zAppend is
876** added to zIn, and the result returned in memory obtained from malloc().
877** zIn, if it was not NULL, is freed.
878**
879** If the third argument, quote, is not '\0', then it is used as a
880** quote character for zAppend.
881*/
drhc28490c2006-10-26 14:25:58 +0000882static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000883 int len;
884 int i;
drh4f21c4a2008-12-10 22:15:00 +0000885 int nAppend = strlen30(zAppend);
886 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000887
888 len = nAppend+nIn+1;
889 if( quote ){
890 len += 2;
891 for(i=0; i<nAppend; i++){
892 if( zAppend[i]==quote ) len++;
893 }
894 }
895
896 zIn = (char *)realloc(zIn, len);
897 if( !zIn ){
898 return 0;
899 }
900
901 if( quote ){
902 char *zCsr = &zIn[nIn];
903 *zCsr++ = quote;
904 for(i=0; i<nAppend; i++){
905 *zCsr++ = zAppend[i];
906 if( zAppend[i]==quote ) *zCsr++ = quote;
907 }
908 *zCsr++ = quote;
909 *zCsr++ = '\0';
910 assert( (zCsr-zIn)==len );
911 }else{
912 memcpy(&zIn[nIn], zAppend, nAppend);
913 zIn[len-1] = '\0';
914 }
915
916 return zIn;
917}
918
drhdd3d4592004-08-30 01:54:05 +0000919
920/*
921** Execute a query statement that has a single result column. Print
922** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000923**
924** This is used, for example, to show the schema of the database by
925** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000926*/
drh157e29a2009-05-21 15:15:00 +0000927static int run_table_dump_query(
928 FILE *out, /* Send output here */
929 sqlite3 *db, /* Database to query */
930 const char *zSelect, /* SELECT statement to extract content */
931 const char *zFirstRow /* Print before first row, if not NULL */
932){
drhdd3d4592004-08-30 01:54:05 +0000933 sqlite3_stmt *pSelect;
934 int rc;
935 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
936 if( rc!=SQLITE_OK || !pSelect ){
937 return rc;
938 }
939 rc = sqlite3_step(pSelect);
940 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000941 if( zFirstRow ){
942 fprintf(out, "%s", zFirstRow);
943 zFirstRow = 0;
944 }
drhdd3d4592004-08-30 01:54:05 +0000945 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
946 rc = sqlite3_step(pSelect);
947 }
948 return sqlite3_finalize(pSelect);
949}
950
shane626a6e42009-10-22 17:30:15 +0000951/*
952** Allocate space and save off current error string.
953*/
954static char *save_err_msg(
955 sqlite3 *db /* Database to query */
956){
957 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
958 char *zErrMsg = sqlite3_malloc(nErrMsg);
959 if( zErrMsg ){
960 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
961 }
962 return zErrMsg;
963}
964
965/*
shaneh642d8b82010-07-28 16:05:34 +0000966** Display memory stats.
967*/
968static int display_stats(
969 sqlite3 *db, /* Database to query */
970 struct callback_data *pArg, /* Pointer to struct callback_data */
971 int bReset /* True to reset the stats */
972){
973 int iCur;
974 int iHiwtr;
975
976 if( pArg && pArg->out ){
977
978 iHiwtr = iCur = -1;
979 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
980 fprintf(pArg->out, "Mem Used (Excludes Scratch/Pcache): %d (max %d) bytes\n", iCur, iHiwtr);
981 iHiwtr = iCur = -1;
982 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
983 fprintf(pArg->out, "Number of Allocations: %d (max %d)\n", iCur, iHiwtr);
984/*
985** Not currently used by the CLI.
986** iHiwtr = iCur = -1;
987** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
988** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
989*/
990 iHiwtr = iCur = -1;
991 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
992 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
993/*
994** Not currently used by the CLI.
995** iHiwtr = iCur = -1;
996** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
997** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
998*/
999 iHiwtr = iCur = -1;
1000 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1001 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1002 iHiwtr = iCur = -1;
1003 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1004 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1005 iHiwtr = iCur = -1;
1006 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1007 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1008 iHiwtr = iCur = -1;
1009 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1010 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1011#ifdef YYTRACKMAXSTACKDEPTH
1012 iHiwtr = iCur = -1;
1013 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1014 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1015#endif
1016 }
1017
1018 if( pArg && pArg->out && db ){
1019 iHiwtr = iCur = -1;
1020 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1021 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
1022 iHiwtr = iCur = -1;
1023 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
1024 fprintf(pArg->out, "Pcache Heap Usage: %d bytes\n", iCur);
1025 iHiwtr = iCur = -1;
1026 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1027 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1028 iHiwtr = iCur = -1;
1029 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1030 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1031 }
1032
1033 if( pArg && pArg->out && db && pArg->pStmt ){
1034 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1035 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1036 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1037 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1038 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1039 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1040 }
1041
1042 return 0;
1043}
1044
1045/*
shane626a6e42009-10-22 17:30:15 +00001046** Execute a statement or set of statements. Print
1047** any result rows/columns depending on the current mode
1048** set via the supplied callback.
1049**
1050** This is very similar to SQLite's built-in sqlite3_exec()
1051** function except it takes a slightly different callback
1052** and callback data argument.
1053*/
1054static int shell_exec(
1055 sqlite3 *db, /* An open database */
1056 const char *zSql, /* SQL to be evaluated */
1057 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1058 /* (not the same as sqlite3_exec) */
1059 struct callback_data *pArg, /* Pointer to struct callback_data */
1060 char **pzErrMsg /* Error msg written here */
1061){
dan4564ced2010-01-05 04:59:56 +00001062 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1063 int rc = SQLITE_OK; /* Return Code */
1064 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001065
1066 if( pzErrMsg ){
1067 *pzErrMsg = NULL;
1068 }
1069
shaneb9fc17d2009-10-22 21:23:35 +00001070 while( zSql[0] && (SQLITE_OK == rc) ){
1071 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1072 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001073 if( pzErrMsg ){
1074 *pzErrMsg = save_err_msg(db);
1075 }
1076 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001077 if( !pStmt ){
1078 /* this happens for a comment or white-space */
1079 zSql = zLeftover;
1080 while( isspace(zSql[0]) ) zSql++;
1081 continue;
1082 }
shane626a6e42009-10-22 17:30:15 +00001083
shaneh642d8b82010-07-28 16:05:34 +00001084 /* save off the prepared statment handle and reset row count */
1085 if( pArg ){
1086 pArg->pStmt = pStmt;
1087 pArg->cnt = 0;
1088 }
1089
shanehb7977c52010-01-18 18:17:10 +00001090 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001091 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001092 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001093 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001094 }
shanehb7977c52010-01-18 18:17:10 +00001095
shaneb9fc17d2009-10-22 21:23:35 +00001096 /* perform the first step. this will tell us if we
1097 ** have a result set or not and how wide it is.
1098 */
1099 rc = sqlite3_step(pStmt);
1100 /* if we have a result set... */
1101 if( SQLITE_ROW == rc ){
1102 /* if we have a callback... */
1103 if( xCallback ){
1104 /* allocate space for col name ptr, value ptr, and type */
1105 int nCol = sqlite3_column_count(pStmt);
1106 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1107 if( !pData ){
1108 rc = SQLITE_NOMEM;
1109 }else{
1110 char **azCols = (char **)pData; /* Names of result columns */
1111 char **azVals = &azCols[nCol]; /* Results */
1112 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1113 int i;
1114 assert(sizeof(int) <= sizeof(char *));
1115 /* save off ptrs to column names */
1116 for(i=0; i<nCol; i++){
1117 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1118 }
shaneb9fc17d2009-10-22 21:23:35 +00001119 do{
1120 /* extract the data and data types */
1121 for(i=0; i<nCol; i++){
1122 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1123 aiTypes[i] = sqlite3_column_type(pStmt, i);
1124 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1125 rc = SQLITE_NOMEM;
1126 break; /* from for */
1127 }
1128 } /* end for */
1129
1130 /* if data and types extracted successfully... */
1131 if( SQLITE_ROW == rc ){
1132 /* call the supplied callback with the result row data */
1133 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1134 rc = SQLITE_ABORT;
1135 }else{
1136 rc = sqlite3_step(pStmt);
1137 }
1138 }
1139 } while( SQLITE_ROW == rc );
1140 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001141 }
1142 }else{
1143 do{
1144 rc = sqlite3_step(pStmt);
1145 } while( rc == SQLITE_ROW );
1146 }
1147 }
1148
shaneh642d8b82010-07-28 16:05:34 +00001149 /* print usage stats if stats on */
1150 if( pArg && pArg->statsOn ){
1151 display_stats(db, pArg, 0);
1152 }
1153
dan4564ced2010-01-05 04:59:56 +00001154 /* Finalize the statement just executed. If this fails, save a
1155 ** copy of the error message. Otherwise, set zSql to point to the
1156 ** next statement to execute. */
1157 rc = sqlite3_finalize(pStmt);
1158 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001159 zSql = zLeftover;
1160 while( isspace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001161 }else if( pzErrMsg ){
1162 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001163 }
shaneh642d8b82010-07-28 16:05:34 +00001164
1165 /* clear saved stmt handle */
1166 if( pArg ){
1167 pArg->pStmt = NULL;
1168 }
shane626a6e42009-10-22 17:30:15 +00001169 }
shaneb9fc17d2009-10-22 21:23:35 +00001170 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001171
1172 return rc;
1173}
1174
drhdd3d4592004-08-30 01:54:05 +00001175
drh33048c02001-10-01 14:29:22 +00001176/*
drh4c653a02000-06-07 01:27:47 +00001177** This is a different callback routine used for dumping the database.
1178** Each row received by this callback consists of a table name,
1179** the table type ("index" or "table") and SQL to create the table.
1180** This routine should print text sufficient to recreate the table.
1181*/
1182static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001183 int rc;
1184 const char *zTable;
1185 const char *zType;
1186 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001187 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001188 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001189
drh902b9ee2008-12-05 17:17:07 +00001190 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001191 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001192 zTable = azArg[0];
1193 zType = azArg[1];
1194 zSql = azArg[2];
1195
drh00b950d2005-09-11 02:03:03 +00001196 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001197 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001198 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1199 fprintf(p->out, "ANALYZE sqlite_master;\n");
1200 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1201 return 0;
drh45e29d82006-11-20 16:21:10 +00001202 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1203 char *zIns;
1204 if( !p->writableSchema ){
1205 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1206 p->writableSchema = 1;
1207 }
1208 zIns = sqlite3_mprintf(
1209 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1210 "VALUES('table','%q','%q',0,'%q');",
1211 zTable, zTable, zSql);
1212 fprintf(p->out, "%s\n", zIns);
1213 sqlite3_free(zIns);
1214 return 0;
drh00b950d2005-09-11 02:03:03 +00001215 }else{
1216 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001217 }
danielk19772a02e332004-06-05 08:04:36 +00001218
1219 if( strcmp(zType, "table")==0 ){
1220 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001221 char *zSelect = 0;
1222 char *zTableInfo = 0;
1223 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001224 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001225
1226 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1227 zTableInfo = appendText(zTableInfo, zTable, '"');
1228 zTableInfo = appendText(zTableInfo, ");", 0);
1229
1230 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001231 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001232 if( rc!=SQLITE_OK || !pTableInfo ){
1233 return 1;
1234 }
1235
1236 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1237 zTmp = appendText(zTmp, zTable, '"');
1238 if( zTmp ){
1239 zSelect = appendText(zSelect, zTmp, '\'');
1240 }
1241 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1242 rc = sqlite3_step(pTableInfo);
1243 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001244 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001245 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001246 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001247 rc = sqlite3_step(pTableInfo);
1248 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001249 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001250 }else{
1251 zSelect = appendText(zSelect, ") ", 0);
1252 }
drh157e29a2009-05-21 15:15:00 +00001253 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001254 }
1255 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001256 if( rc!=SQLITE_OK || nRow==0 ){
1257 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001258 return 1;
1259 }
1260 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1261 zSelect = appendText(zSelect, zTable, '"');
1262
drh157e29a2009-05-21 15:15:00 +00001263 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001264 if( rc==SQLITE_CORRUPT ){
1265 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001266 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001267 }
danielk19772a02e332004-06-05 08:04:36 +00001268 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001269 }
drh4c653a02000-06-07 01:27:47 +00001270 return 0;
1271}
1272
1273/*
drh45e29d82006-11-20 16:21:10 +00001274** Run zQuery. Use dump_callback() as the callback routine so that
1275** the contents of the query are output as SQL statements.
1276**
drhdd3d4592004-08-30 01:54:05 +00001277** If we get a SQLITE_CORRUPT error, rerun the query after appending
1278** "ORDER BY rowid DESC" to the end.
1279*/
1280static int run_schema_dump_query(
1281 struct callback_data *p,
1282 const char *zQuery,
1283 char **pzErrMsg
1284){
1285 int rc;
1286 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1287 if( rc==SQLITE_CORRUPT ){
1288 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001289 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001290 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1291 zQ2 = malloc( len+100 );
1292 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001293 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001294 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1295 free(zQ2);
1296 }
1297 return rc;
1298}
1299
1300/*
drh75897232000-05-29 14:26:00 +00001301** Text of a help message
1302*/
persicom1d0b8722002-04-18 02:53:04 +00001303static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001304 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001305 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001306 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001307 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001308 " If TABLE specified, only dump tables matching\n"
1309 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001310 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001311 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001312 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1313 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001314 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001315 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001316 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001317 ".indices ?TABLE? Show names of all indices\n"
1318 " If TABLE specified, only show indices for tables\n"
1319 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001320#ifdef SQLITE_ENABLE_IOTRACE
1321 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1322#endif
drh70df4fe2006-06-13 15:12:21 +00001323#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001324 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001325#endif
drh127f9d72010-02-23 01:47:00 +00001326 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001327 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001328 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001329 " column Left-aligned columns. (See .width)\n"
1330 " html HTML <table> code\n"
1331 " insert SQL insert statements for TABLE\n"
1332 " line One value per line\n"
1333 " list Values delimited by .separator string\n"
1334 " tabs Tab-separated values\n"
1335 " tcl TCL list elements\n"
1336 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001337 ".output FILENAME Send output to FILENAME\n"
1338 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001339 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001340 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001341 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001342 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001343 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001344 " If TABLE specified, only show tables matching\n"
1345 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001346 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001347 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001348 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001349 ".tables ?TABLE? List names of tables\n"
1350 " If TABLE specified, only list tables matching\n"
1351 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001352 ".timeout MS Try opening locked tables for MS milliseconds\n"
shanehe2aa9d72009-11-06 17:20:17 +00001353 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001354;
1355
shaneb320ccd2009-10-21 03:42:58 +00001356static char zTimerHelp[] =
1357 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1358;
1359
drhdaffd0e2001-04-11 14:28:42 +00001360/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001361static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001362
drh75897232000-05-29 14:26:00 +00001363/*
drh44c2eb12003-04-30 11:38:26 +00001364** Make sure the database is open. If it is not, then open it. If
1365** the database fails to open, print an error message and exit.
1366*/
1367static void open_db(struct callback_data *p){
1368 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001369 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001370 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001371 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1372 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1373 shellstaticFunc, 0, 0);
1374 }
1375 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001376 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001377 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001378 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001379 }
drhc2e87a32006-06-27 15:16:14 +00001380#ifndef SQLITE_OMIT_LOAD_EXTENSION
1381 sqlite3_enable_load_extension(p->db, 1);
1382#endif
drh44c2eb12003-04-30 11:38:26 +00001383 }
1384}
1385
1386/*
drhfeac5f82004-08-01 00:10:45 +00001387** Do C-language style dequoting.
1388**
1389** \t -> tab
1390** \n -> newline
1391** \r -> carriage return
1392** \NNN -> ascii character NNN in octal
1393** \\ -> backslash
1394*/
1395static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001396 int i, j;
1397 char c;
drhfeac5f82004-08-01 00:10:45 +00001398 for(i=j=0; (c = z[i])!=0; i++, j++){
1399 if( c=='\\' ){
1400 c = z[++i];
1401 if( c=='n' ){
1402 c = '\n';
1403 }else if( c=='t' ){
1404 c = '\t';
1405 }else if( c=='r' ){
1406 c = '\r';
1407 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001408 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001409 if( z[i+1]>='0' && z[i+1]<='7' ){
1410 i++;
1411 c = (c<<3) + z[i] - '0';
1412 if( z[i+1]>='0' && z[i+1]<='7' ){
1413 i++;
1414 c = (c<<3) + z[i] - '0';
1415 }
1416 }
1417 }
1418 }
1419 z[j] = c;
1420 }
1421 z[j] = 0;
1422}
1423
1424/*
drhc28490c2006-10-26 14:25:58 +00001425** Interpret zArg as a boolean value. Return either 0 or 1.
1426*/
1427static int booleanValue(char *zArg){
1428 int val = atoi(zArg);
1429 int j;
1430 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001431 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001432 }
1433 if( strcmp(zArg,"on")==0 ){
1434 val = 1;
1435 }else if( strcmp(zArg,"yes")==0 ){
1436 val = 1;
1437 }
1438 return val;
1439}
1440
1441/*
drh75897232000-05-29 14:26:00 +00001442** If an input line begins with "." then invoke this routine to
1443** process that line.
drh67505e72002-04-19 12:34:06 +00001444**
drh47ad6842006-11-08 12:25:42 +00001445** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001446*/
drh44c2eb12003-04-30 11:38:26 +00001447static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001448 int i = 1;
1449 int nArg = 0;
1450 int n, c;
drh67505e72002-04-19 12:34:06 +00001451 int rc = 0;
drh75897232000-05-29 14:26:00 +00001452 char *azArg[50];
1453
1454 /* Parse the input line into tokens.
1455 */
1456 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001457 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001458 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001459 if( zLine[i]=='\'' || zLine[i]=='"' ){
1460 int delim = zLine[i++];
1461 azArg[nArg++] = &zLine[i];
1462 while( zLine[i] && zLine[i]!=delim ){ i++; }
1463 if( zLine[i]==delim ){
1464 zLine[i++] = 0;
1465 }
drhfeac5f82004-08-01 00:10:45 +00001466 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001467 }else{
1468 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001469 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001470 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001471 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001472 }
1473 }
1474
1475 /* Process the input line.
1476 */
shane9bd1b442009-10-23 01:27:39 +00001477 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001478 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001479 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001480 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001481 const char *zDestFile;
1482 const char *zDb;
1483 sqlite3 *pDest;
1484 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001485 if( nArg==2 ){
1486 zDestFile = azArg[1];
1487 zDb = "main";
1488 }else{
1489 zDestFile = azArg[2];
1490 zDb = azArg[1];
1491 }
1492 rc = sqlite3_open(zDestFile, &pDest);
1493 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001494 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001495 sqlite3_close(pDest);
1496 return 1;
1497 }
drhdc2c4912009-02-04 22:46:47 +00001498 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001499 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1500 if( pBackup==0 ){
1501 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1502 sqlite3_close(pDest);
1503 return 1;
1504 }
1505 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1506 sqlite3_backup_finish(pBackup);
1507 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001508 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001509 }else{
1510 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001511 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001512 }
1513 sqlite3_close(pDest);
1514 }else
1515
shanehe2aa9d72009-11-06 17:20:17 +00001516 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001517 bail_on_error = booleanValue(azArg[1]);
1518 }else
1519
shanehe2aa9d72009-11-06 17:20:17 +00001520 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001521 struct callback_data data;
1522 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001523 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001524 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001525 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001526 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001527 data.colWidth[0] = 3;
1528 data.colWidth[1] = 15;
1529 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001530 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001531 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001532 if( zErrMsg ){
1533 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001534 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001535 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001536 }
1537 }else
1538
shanehe2aa9d72009-11-06 17:20:17 +00001539 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh4c653a02000-06-07 01:27:47 +00001540 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001541 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001542 /* When playing back a "dump", the content might appear in an order
1543 ** which causes immediate foreign key constraints to be violated.
1544 ** So disable foreign-key constraint enforcement to prevent problems. */
1545 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001546 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001547 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001548 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001549 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001550 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001551 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00001552 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1553 );
1554 run_schema_dump_query(p,
1555 "SELECT name, type, sql FROM sqlite_master "
1556 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00001557 );
1558 run_table_dump_query(p->out, p->db,
1559 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001560 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001561 );
drh4c653a02000-06-07 01:27:47 +00001562 }else{
1563 int i;
drhdd3d4592004-08-30 01:54:05 +00001564 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001565 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001566 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001567 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001568 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001569 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001570 run_table_dump_query(p->out, p->db,
1571 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001572 "WHERE sql NOT NULL"
1573 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001574 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001575 );
danielk1977bc6ada42004-06-30 08:20:16 +00001576 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001577 }
1578 }
drh45e29d82006-11-20 16:21:10 +00001579 if( p->writableSchema ){
1580 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1581 p->writableSchema = 0;
1582 }
drh93f41e52008-08-11 19:12:34 +00001583 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001584 if( zErrMsg ){
1585 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001586 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001587 }else{
1588 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001589 }
1590 }else
drh75897232000-05-29 14:26:00 +00001591
shanehe2aa9d72009-11-06 17:20:17 +00001592 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001593 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001594 }else
1595
shanehe2aa9d72009-11-06 17:20:17 +00001596 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001597 rc = 2;
drh75897232000-05-29 14:26:00 +00001598 }else
1599
shanehe2aa9d72009-11-06 17:20:17 +00001600 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001601 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001602 if(val == 1) {
1603 if(!p->explainPrev.valid) {
1604 p->explainPrev.valid = 1;
1605 p->explainPrev.mode = p->mode;
1606 p->explainPrev.showHeader = p->showHeader;
1607 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1608 }
1609 /* We could put this code under the !p->explainValid
1610 ** condition so that it does not execute if we are already in
1611 ** explain mode. However, always executing it allows us an easy
1612 ** was to reset to explain mode in case the user previously
1613 ** did an .explain followed by a .width, .mode or .header
1614 ** command.
1615 */
danielk19770d78bae2008-01-03 07:09:48 +00001616 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001617 p->showHeader = 1;
1618 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001619 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001620 p->colWidth[1] = 13; /* opcode */
1621 p->colWidth[2] = 4; /* P1 */
1622 p->colWidth[3] = 4; /* P2 */
1623 p->colWidth[4] = 4; /* P3 */
1624 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001625 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001626 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001627 }else if (p->explainPrev.valid) {
1628 p->explainPrev.valid = 0;
1629 p->mode = p->explainPrev.mode;
1630 p->showHeader = p->explainPrev.showHeader;
1631 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1632 }
drh75897232000-05-29 14:26:00 +00001633 }else
1634
drhc28490c2006-10-26 14:25:58 +00001635 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001636 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001637 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001638 }else
1639
1640 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001641 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001642 if( HAS_TIMER ){
1643 fprintf(stderr,"%s",zTimerHelp);
1644 }
drh75897232000-05-29 14:26:00 +00001645 }else
1646
shanehe2aa9d72009-11-06 17:20:17 +00001647 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001648 char *zTable = azArg[2]; /* Insert data into this table */
1649 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001650 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001651 int nCol; /* Number of columns in the table */
1652 int nByte; /* Number of bytes in an SQL string */
1653 int i, j; /* Loop counters */
1654 int nSep; /* Number of bytes in p->separator[] */
1655 char *zSql; /* An SQL statement */
1656 char *zLine; /* A single line of input from the file */
1657 char **azCol; /* zLine[] broken up into columns */
1658 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001659 FILE *in; /* The input file */
1660 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001661
drha543c822006-06-08 16:10:14 +00001662 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001663 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001664 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001665 fprintf(stderr, "Error: non-null separator required for import\n");
1666 return 1;
drhfeac5f82004-08-01 00:10:45 +00001667 }
1668 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
shane916f9612009-10-23 00:37:15 +00001669 if( zSql==0 ){
1670 fprintf(stderr, "Error: out of memory\n");
1671 return 1;
1672 }
drh4f21c4a2008-12-10 22:15:00 +00001673 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001674 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001675 sqlite3_free(zSql);
1676 if( rc ){
shane916f9612009-10-23 00:37:15 +00001677 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001678 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001679 return 1;
drhfeac5f82004-08-01 00:10:45 +00001680 }
shane916f9612009-10-23 00:37:15 +00001681 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001682 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001683 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001684 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001685 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001686 if( zSql==0 ){
1687 fprintf(stderr, "Error: out of memory\n");
1688 return 1;
1689 }
drhfeac5f82004-08-01 00:10:45 +00001690 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001691 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001692 for(i=1; i<nCol; i++){
1693 zSql[j++] = ',';
1694 zSql[j++] = '?';
1695 }
1696 zSql[j++] = ')';
1697 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001698 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001699 free(zSql);
1700 if( rc ){
1701 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001702 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001703 return 1;
drhfeac5f82004-08-01 00:10:45 +00001704 }
1705 in = fopen(zFile, "rb");
1706 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001707 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001708 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001709 return 1;
drhfeac5f82004-08-01 00:10:45 +00001710 }
1711 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001712 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001713 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001714 fclose(in);
shane916f9612009-10-23 00:37:15 +00001715 sqlite3_finalize(pStmt);
1716 return 1;
drh43617e92006-03-06 20:55:46 +00001717 }
drhfeac5f82004-08-01 00:10:45 +00001718 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1719 zCommit = "COMMIT";
1720 while( (zLine = local_getline(0, in))!=0 ){
1721 char *z;
1722 i = 0;
drhb860bc92004-08-04 15:16:55 +00001723 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001724 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001725 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001726 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1727 *z = 0;
1728 i++;
drhb860bc92004-08-04 15:16:55 +00001729 if( i<nCol ){
1730 azCol[i] = &z[nSep];
1731 z += nSep-1;
1732 }
drhfeac5f82004-08-01 00:10:45 +00001733 }
shane916f9612009-10-23 00:37:15 +00001734 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001735 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001736 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001737 fprintf(stderr,
1738 "Error: %s line %d: expected %d columns of data but found %d\n",
1739 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001740 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001741 free(zLine);
shane916f9612009-10-23 00:37:15 +00001742 rc = 1;
1743 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001744 }
drhfeac5f82004-08-01 00:10:45 +00001745 for(i=0; i<nCol; i++){
1746 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1747 }
1748 sqlite3_step(pStmt);
1749 rc = sqlite3_reset(pStmt);
1750 free(zLine);
1751 if( rc!=SQLITE_OK ){
1752 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1753 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001754 rc = 1;
shane916f9612009-10-23 00:37:15 +00001755 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001756 }
shane916f9612009-10-23 00:37:15 +00001757 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001758 free(azCol);
1759 fclose(in);
1760 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001761 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001762 }else
1763
shanehe2aa9d72009-11-06 17:20:17 +00001764 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001765 struct callback_data data;
1766 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001767 open_db(p);
drh75897232000-05-29 14:26:00 +00001768 memcpy(&data, p, sizeof(data));
1769 data.showHeader = 0;
1770 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001771 if( nArg==1 ){
1772 rc = sqlite3_exec(p->db,
1773 "SELECT name FROM sqlite_master "
1774 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1775 "UNION ALL "
1776 "SELECT name FROM sqlite_temp_master "
1777 "WHERE type='index' "
1778 "ORDER BY 1",
1779 callback, &data, &zErrMsg
1780 );
1781 }else{
1782 zShellStatic = azArg[1];
1783 rc = sqlite3_exec(p->db,
1784 "SELECT name FROM sqlite_master "
1785 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1786 "UNION ALL "
1787 "SELECT name FROM sqlite_temp_master "
1788 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1789 "ORDER BY 1",
1790 callback, &data, &zErrMsg
1791 );
1792 zShellStatic = 0;
1793 }
drh75897232000-05-29 14:26:00 +00001794 if( zErrMsg ){
1795 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001796 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001797 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001798 }else if( rc != SQLITE_OK ){
1799 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1800 rc = 1;
drh75897232000-05-29 14:26:00 +00001801 }
1802 }else
1803
drhae5e4452007-05-03 17:18:36 +00001804#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001805 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001806 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001807 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1808 iotrace = 0;
1809 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001810 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001811 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001812 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001813 iotrace = stdout;
1814 }else{
1815 iotrace = fopen(azArg[1], "w");
1816 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001817 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001818 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001819 rc = 1;
drhb0603412007-02-28 04:47:26 +00001820 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001821 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001822 }
1823 }
1824 }else
drhae5e4452007-05-03 17:18:36 +00001825#endif
drhb0603412007-02-28 04:47:26 +00001826
drh70df4fe2006-06-13 15:12:21 +00001827#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001828 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1829 const char *zFile, *zProc;
1830 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001831 zFile = azArg[1];
1832 zProc = nArg>=3 ? azArg[2] : 0;
1833 open_db(p);
1834 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1835 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001836 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001837 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001838 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001839 }
1840 }else
drh70df4fe2006-06-13 15:12:21 +00001841#endif
drh1e397f82006-06-08 15:28:43 +00001842
drh127f9d72010-02-23 01:47:00 +00001843 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=1 ){
1844 const char *zFile = azArg[1];
1845 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1846 fclose(p->pLog);
1847 p->pLog = 0;
1848 }
1849 if( strcmp(zFile,"stdout")==0 ){
1850 p->pLog = stdout;
1851 }else if( strcmp(zFile, "stderr")==0 ){
1852 p->pLog = stderr;
1853 }else if( strcmp(zFile, "off")==0 ){
1854 p->pLog = 0;
1855 }else{
1856 p->pLog = fopen(zFile, "w");
1857 if( p->pLog==0 ){
1858 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1859 }
1860 }
1861 }else
1862
shanehe2aa9d72009-11-06 17:20:17 +00001863 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001864 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001865 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001866 ||
shanehe2aa9d72009-11-06 17:20:17 +00001867 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001868 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001869 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001870 ||
shanehe2aa9d72009-11-06 17:20:17 +00001871 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001872 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001873 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001874 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001875 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001876 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001877 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001878 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001879 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001880 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001881 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001882 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001883 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001884 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001885 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001886 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001887 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001888 }else {
shane9bd1b442009-10-23 01:27:39 +00001889 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001890 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001891 rc = 1;
drh75897232000-05-29 14:26:00 +00001892 }
1893 }else
1894
shanehe2aa9d72009-11-06 17:20:17 +00001895 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1896 int n2 = strlen30(azArg[1]);
1897 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1898 p->mode = MODE_Insert;
1899 set_table_name(p, azArg[2]);
1900 }else {
1901 fprintf(stderr, "Error: invalid arguments: "
1902 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1903 rc = 1;
1904 }
1905 }else
1906
persicom7e2dfdd2002-04-18 02:46:52 +00001907 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001908 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1909 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001910 }else
1911
drh75897232000-05-29 14:26:00 +00001912 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1913 if( p->out!=stdout ){
1914 fclose(p->out);
1915 }
1916 if( strcmp(azArg[1],"stdout")==0 ){
1917 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001918 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001919 }else{
drha1f9b5e2004-02-14 16:31:02 +00001920 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001921 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00001922 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00001923 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00001924 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001925 } else {
drh5bb3eb92007-05-04 13:15:55 +00001926 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001927 }
1928 }
1929 }else
1930
drhdd45df82002-04-18 12:39:03 +00001931 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001932 if( nArg >= 2) {
1933 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1934 }
1935 if( nArg >= 3) {
1936 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1937 }
1938 }else
1939
shanehe2aa9d72009-11-06 17:20:17 +00001940 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001941 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001942 }else
1943
drh9ff849f2009-02-04 20:55:57 +00001944 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001945 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001946 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00001947 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1948 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00001949 }else{
shane9bd1b442009-10-23 01:27:39 +00001950 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00001951 fclose(alt);
1952 }
1953 }else
1954
shanehe2aa9d72009-11-06 17:20:17 +00001955 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001956 const char *zSrcFile;
1957 const char *zDb;
1958 sqlite3 *pSrc;
1959 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00001960 int nTimeout = 0;
1961
drh9ff849f2009-02-04 20:55:57 +00001962 if( nArg==2 ){
1963 zSrcFile = azArg[1];
1964 zDb = "main";
1965 }else{
1966 zSrcFile = azArg[2];
1967 zDb = azArg[1];
1968 }
1969 rc = sqlite3_open(zSrcFile, &pSrc);
1970 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001971 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00001972 sqlite3_close(pSrc);
1973 return 1;
1974 }
drhdc2c4912009-02-04 22:46:47 +00001975 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001976 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
1977 if( pBackup==0 ){
1978 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1979 sqlite3_close(pSrc);
1980 return 1;
1981 }
drhdc2c4912009-02-04 22:46:47 +00001982 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
1983 || rc==SQLITE_BUSY ){
1984 if( rc==SQLITE_BUSY ){
1985 if( nTimeout++ >= 3 ) break;
1986 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00001987 }
1988 }
1989 sqlite3_backup_finish(pBackup);
1990 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001991 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00001992 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00001993 fprintf(stderr, "Error: source database is busy\n");
1994 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001995 }else{
1996 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00001997 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001998 }
1999 sqlite3_close(pSrc);
2000 }else
2001
shanehe2aa9d72009-11-06 17:20:17 +00002002 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002003 struct callback_data data;
2004 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002005 open_db(p);
drh75897232000-05-29 14:26:00 +00002006 memcpy(&data, p, sizeof(data));
2007 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002008 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002009 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002010 int i;
shane7d3846a2008-12-11 02:58:26 +00002011 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002012 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002013 char *new_argv[2], *new_colv[2];
2014 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2015 " type text,\n"
2016 " name text,\n"
2017 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002018 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002019 " sql text\n"
2020 ")";
2021 new_argv[1] = 0;
2022 new_colv[0] = "sql";
2023 new_colv[1] = 0;
2024 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002025 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002026 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002027 char *new_argv[2], *new_colv[2];
2028 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2029 " type text,\n"
2030 " name text,\n"
2031 " tbl_name text,\n"
2032 " rootpage integer,\n"
2033 " sql text\n"
2034 ")";
2035 new_argv[1] = 0;
2036 new_colv[0] = "sql";
2037 new_colv[1] = 0;
2038 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002039 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002040 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002041 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002042 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002043 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002044 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2045 " FROM sqlite_master UNION ALL"
2046 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002047 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002048 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002049 callback, &data, &zErrMsg);
2050 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002051 }
drh75897232000-05-29 14:26:00 +00002052 }else{
shane9bd1b442009-10-23 01:27:39 +00002053 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002054 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002055 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2056 " FROM sqlite_master UNION ALL"
2057 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002058 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002059 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002060 callback, &data, &zErrMsg
2061 );
drh75897232000-05-29 14:26:00 +00002062 }
drh75897232000-05-29 14:26:00 +00002063 if( zErrMsg ){
2064 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002065 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002066 rc = 1;
2067 }else if( rc != SQLITE_OK ){
2068 fprintf(stderr,"Error: querying schema information\n");
2069 rc = 1;
2070 }else{
2071 rc = 0;
drh75897232000-05-29 14:26:00 +00002072 }
2073 }else
2074
2075 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002076 sqlite3_snprintf(sizeof(p->separator), p->separator,
2077 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002078 }else
2079
shanehe2aa9d72009-11-06 17:20:17 +00002080 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002081 int i;
2082 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002083 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002084 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002085 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002086 fprintf(p->out,"%9.9s: ", "nullvalue");
2087 output_c_string(p->out, p->nullvalue);
2088 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002089 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002090 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002091 fprintf(p->out,"%9.9s: ", "separator");
2092 output_c_string(p->out, p->separator);
2093 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002094 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002095 fprintf(p->out,"%9.9s: ","width");
2096 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002097 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002098 }
drhfeac5f82004-08-01 00:10:45 +00002099 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002100 }else
2101
shaneh642d8b82010-07-28 16:05:34 +00002102 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2103 p->statsOn = booleanValue(azArg[1]);
2104 }else
2105
shanehe2aa9d72009-11-06 17:20:17 +00002106 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002107 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002108 int nRow;
drhe3710332000-09-29 13:30:53 +00002109 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002110 open_db(p);
drha50da102000-08-08 20:19:09 +00002111 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002112 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002113 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002114 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002115 "UNION ALL "
2116 "SELECT name FROM sqlite_temp_master "
2117 "WHERE type IN ('table','view') "
2118 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002119 &azResult, &nRow, 0, &zErrMsg
2120 );
drha50da102000-08-08 20:19:09 +00002121 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002122 zShellStatic = azArg[1];
2123 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002124 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002125 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002126 "UNION ALL "
2127 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002128 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002129 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002130 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002131 );
danielk1977bc6ada42004-06-30 08:20:16 +00002132 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002133 }
drh75897232000-05-29 14:26:00 +00002134 if( zErrMsg ){
2135 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002136 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002137 rc = 1;
2138 }else if( rc != SQLITE_OK ){
2139 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2140 rc = 1;
2141 }else{
drhe3710332000-09-29 13:30:53 +00002142 int len, maxlen = 0;
2143 int i, j;
2144 int nPrintCol, nPrintRow;
2145 for(i=1; i<=nRow; i++){
2146 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002147 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002148 if( len>maxlen ) maxlen = len;
2149 }
2150 nPrintCol = 80/(maxlen+2);
2151 if( nPrintCol<1 ) nPrintCol = 1;
2152 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2153 for(i=0; i<nPrintRow; i++){
2154 for(j=i+1; j<=nRow; j+=nPrintRow){
2155 char *zSp = j<=nPrintRow ? "" : " ";
2156 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2157 }
2158 printf("\n");
2159 }
2160 }
danielk19776f8a5032004-05-10 10:34:51 +00002161 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002162 }else
2163
shanehe2aa9d72009-11-06 17:20:17 +00002164 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002165 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002166 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002167 }else
2168
2169 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
drh3b1a9882007-11-02 12:53:03 +00002170 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002171 }else
2172
2173 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002174 int j;
drh43617e92006-03-06 20:55:46 +00002175 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002176 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2177 p->colWidth[j-1] = atoi(azArg[j]);
2178 }
2179 }else
2180
2181 {
shane9bd1b442009-10-23 01:27:39 +00002182 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002183 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002184 rc = 1;
drh75897232000-05-29 14:26:00 +00002185 }
drh67505e72002-04-19 12:34:06 +00002186
2187 return rc;
drh75897232000-05-29 14:26:00 +00002188}
2189
drh67505e72002-04-19 12:34:06 +00002190/*
drh91a66392007-09-07 01:12:32 +00002191** Return TRUE if a semicolon occurs anywhere in the first N characters
2192** of string z[].
drh324ccef2003-02-05 14:06:20 +00002193*/
drh91a66392007-09-07 01:12:32 +00002194static int _contains_semicolon(const char *z, int N){
2195 int i;
2196 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2197 return 0;
drh324ccef2003-02-05 14:06:20 +00002198}
2199
2200/*
drh70c7a4b2003-04-26 03:03:06 +00002201** Test to see if a line consists entirely of whitespace.
2202*/
2203static int _all_whitespace(const char *z){
2204 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002205 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002206 if( *z=='/' && z[1]=='*' ){
2207 z += 2;
2208 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2209 if( *z==0 ) return 0;
2210 z++;
2211 continue;
2212 }
2213 if( *z=='-' && z[1]=='-' ){
2214 z += 2;
2215 while( *z && *z!='\n' ){ z++; }
2216 if( *z==0 ) return 1;
2217 continue;
2218 }
2219 return 0;
2220 }
2221 return 1;
2222}
2223
2224/*
drha9b17162003-04-29 18:01:28 +00002225** Return TRUE if the line typed in is an SQL command terminator other
2226** than a semi-colon. The SQL Server style "go" command is understood
2227** as is the Oracle "/".
2228*/
2229static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002230 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002231 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2232 return 1; /* Oracle */
2233 }
drhc8d74412004-08-31 23:41:26 +00002234 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2235 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002236 return 1; /* SQL Server */
2237 }
2238 return 0;
2239}
2240
2241/*
drh233a5312008-12-18 22:25:13 +00002242** Return true if zSql is a complete SQL statement. Return false if it
2243** ends in the middle of a string literal or C-style comment.
2244*/
2245static int _is_complete(char *zSql, int nSql){
2246 int rc;
2247 if( zSql==0 ) return 1;
2248 zSql[nSql] = ';';
2249 zSql[nSql+1] = 0;
2250 rc = sqlite3_complete(zSql);
2251 zSql[nSql] = 0;
2252 return rc;
2253}
2254
2255/*
drh67505e72002-04-19 12:34:06 +00002256** Read input from *in and process it. If *in==0 then input
2257** is interactive - the user is typing it it. Otherwise, input
2258** is coming from a file or device. A prompt is issued and history
2259** is saved only if input is interactive. An interrupt signal will
2260** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002261**
2262** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002263*/
drhc28490c2006-10-26 14:25:58 +00002264static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002265 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002266 char *zSql = 0;
2267 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002268 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002269 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002270 int rc;
2271 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002272 int lineno = 0;
2273 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002274
2275 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2276 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002277 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002278 zLine = one_input_line(zSql, in);
2279 if( zLine==0 ){
2280 break; /* We have reached EOF */
2281 }
drh67505e72002-04-19 12:34:06 +00002282 if( seenInterrupt ){
2283 if( in!=0 ) break;
2284 seenInterrupt = 0;
2285 }
drhc28490c2006-10-26 14:25:58 +00002286 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002287 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002288 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002289 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002290 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002291 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002292 break;
2293 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002294 errCnt++;
2295 }
drhdaffd0e2001-04-11 14:28:42 +00002296 continue;
2297 }
drh233a5312008-12-18 22:25:13 +00002298 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002299 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002300 }
drh91a66392007-09-07 01:12:32 +00002301 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002302 if( zSql==0 ){
2303 int i;
drh4c755c02004-08-08 20:22:17 +00002304 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002305 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002306 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002307 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002308 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002309 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002310 exit(1);
2311 }
drh5bb3eb92007-05-04 13:15:55 +00002312 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002313 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002314 }
2315 }else{
drh4f21c4a2008-12-10 22:15:00 +00002316 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002317 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002318 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002319 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002320 exit(1);
2321 }
drh5bb3eb92007-05-04 13:15:55 +00002322 zSql[nSql++] = '\n';
2323 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002324 nSql += len;
2325 }
drh91a66392007-09-07 01:12:32 +00002326 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2327 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002328 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002329 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002330 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002331 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002332 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002333 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002334 char zPrefix[100];
2335 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002336 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002337 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002338 }else{
shane9bd1b442009-10-23 01:27:39 +00002339 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002340 }
drh7f953e22002-07-13 17:33:45 +00002341 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002342 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002343 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002344 zErrMsg = 0;
2345 }else{
shaned2bed1c2009-10-21 03:56:54 +00002346 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002347 }
drhc49f44e2006-10-26 18:15:42 +00002348 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002349 }
2350 free(zSql);
2351 zSql = 0;
2352 nSql = 0;
2353 }
2354 }
2355 if( zSql ){
shane86f5bdb2009-10-24 02:00:07 +00002356 if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002357 free(zSql);
2358 }
danielk19772ac27622007-07-03 05:31:16 +00002359 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002360 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002361}
2362
drh67505e72002-04-19 12:34:06 +00002363/*
2364** Return a pathname which is the user's home directory. A
2365** 0 return indicates an error of some kind. Space to hold the
2366** resulting string is obtained from malloc(). The calling
2367** function should free the result.
2368*/
2369static char *find_home_dir(void){
2370 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002371
chw97185482008-11-17 08:05:31 +00002372#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002373 struct passwd *pwent;
2374 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002375 if( (pwent=getpwuid(uid)) != NULL) {
2376 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002377 }
2378#endif
2379
chw65d3c132007-11-12 21:09:10 +00002380#if defined(_WIN32_WCE)
2381 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2382 */
2383 home_dir = strdup("/");
2384#else
2385
drh164a1b62006-08-19 11:15:20 +00002386#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2387 if (!home_dir) {
2388 home_dir = getenv("USERPROFILE");
2389 }
2390#endif
2391
drh67505e72002-04-19 12:34:06 +00002392 if (!home_dir) {
2393 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002394 }
2395
drhcdb36b72006-06-12 12:57:45 +00002396#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002397 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002398 char *zDrive, *zPath;
2399 int n;
2400 zDrive = getenv("HOMEDRIVE");
2401 zPath = getenv("HOMEPATH");
2402 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002403 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002404 home_dir = malloc( n );
2405 if( home_dir==0 ) return 0;
2406 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2407 return home_dir;
2408 }
2409 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002410 }
2411#endif
2412
chw65d3c132007-11-12 21:09:10 +00002413#endif /* !_WIN32_WCE */
2414
drh67505e72002-04-19 12:34:06 +00002415 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002416 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002417 char *z = malloc( n );
2418 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002419 home_dir = z;
2420 }
drhe98d4fa2002-04-21 19:06:22 +00002421
drh67505e72002-04-19 12:34:06 +00002422 return home_dir;
2423}
2424
2425/*
2426** Read input from the file given by sqliterc_override. Or if that
2427** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002428**
2429** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002430*/
shane9bd1b442009-10-23 01:27:39 +00002431static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002432 struct callback_data *p, /* Configuration data */
2433 const char *sqliterc_override /* Name of config file. NULL to use default */
2434){
persicom7e2dfdd2002-04-18 02:46:52 +00002435 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002436 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002437 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002438 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002439 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002440 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002441
2442 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002443 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002444 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002445#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002446 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002447#endif
shane9bd1b442009-10-23 01:27:39 +00002448 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002449 }
drh4f21c4a2008-12-10 22:15:00 +00002450 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002451 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002452 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002453 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2454 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002455 }
drha959ac42007-06-20 13:10:00 +00002456 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002457 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002458 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002459 }
drha1f9b5e2004-02-14 16:31:02 +00002460 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002461 if( in ){
drhc28490c2006-10-26 14:25:58 +00002462 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002463 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002464 }
shane9bd1b442009-10-23 01:27:39 +00002465 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002466 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002467 }
drh43617e92006-03-06 20:55:46 +00002468 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002469 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002470}
2471
drh67505e72002-04-19 12:34:06 +00002472/*
drhe1e38c42003-05-04 18:30:59 +00002473** Show available command line options
2474*/
2475static const char zOptions[] =
shaneh5fc25012009-11-11 04:17:07 +00002476 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002477 " -init filename read/process named file\n"
2478 " -echo print commands before execution\n"
2479 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002480 " -bail stop after hitting an error\n"
2481 " -interactive force interactive I/O\n"
2482 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002483 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002484 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002485 " -html set output mode to HTML\n"
2486 " -line set output mode to 'line'\n"
2487 " -list set output mode to 'list'\n"
2488 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002489 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002490 " -nullvalue 'text' set text string for NULL values\n"
2491 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002492;
2493static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002494 fprintf(stderr,
2495 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2496 "FILENAME is the name of an SQLite database. A new database is created\n"
2497 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002498 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002499 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002500 }else{
2501 fprintf(stderr, "Use the -help option for additional information\n");
2502 }
2503 exit(1);
2504}
2505
2506/*
drh67505e72002-04-19 12:34:06 +00002507** Initialize the state information in data
2508*/
drh0850b532006-01-31 19:31:43 +00002509static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002510 memset(data, 0, sizeof(*data));
2511 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002512 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002513 data->showHeader = 0;
drh127f9d72010-02-23 01:47:00 +00002514 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002515 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2516 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002517 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002518}
2519
drh75897232000-05-29 14:26:00 +00002520int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002521 char *zErrMsg = 0;
2522 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002523 const char *zInitFile = 0;
2524 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002525 int i;
drhc28490c2006-10-26 14:25:58 +00002526 int rc = 0;
drh75897232000-05-29 14:26:00 +00002527
drhdaffd0e2001-04-11 14:28:42 +00002528 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002529 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002530 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002531
drh44c2eb12003-04-30 11:38:26 +00002532 /* Make sure we have a valid signal handler early, before anything
2533 ** else is done.
2534 */
drh4c504392000-10-16 22:06:40 +00002535#ifdef SIGINT
2536 signal(SIGINT, interrupt_handler);
2537#endif
drh44c2eb12003-04-30 11:38:26 +00002538
drh22fbcb82004-02-01 01:22:50 +00002539 /* Do an initial pass through the command-line argument to locate
2540 ** the name of the database file, the name of the initialization file,
2541 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002542 */
drh22fbcb82004-02-01 01:22:50 +00002543 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002544 char *z;
drh44c2eb12003-04-30 11:38:26 +00002545 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002546 z = argv[i];
2547 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002548 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2549 i++;
drh22fbcb82004-02-01 01:22:50 +00002550 }else if( strcmp(argv[i],"-init")==0 ){
2551 i++;
2552 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002553 /* Need to check for batch mode here to so we can avoid printing
2554 ** informational messages (like from process_sqliterc) before
2555 ** we do the actual processing of arguments later in a second pass.
2556 */
2557 }else if( strcmp(argv[i],"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002558 stdin_is_interactive = 0;
drh44c2eb12003-04-30 11:38:26 +00002559 }
2560 }
drh22fbcb82004-02-01 01:22:50 +00002561 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002562#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002563 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2564#else
drh22fbcb82004-02-01 01:22:50 +00002565 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002566#endif
drh22fbcb82004-02-01 01:22:50 +00002567 }else{
danielk197703aded42004-11-22 05:26:27 +00002568#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002569 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002570#else
2571 data.zDbFilename = 0;
2572#endif
drh22fbcb82004-02-01 01:22:50 +00002573 }
2574 if( i<argc ){
2575 zFirstCmd = argv[i++];
2576 }
shaneh5fc25012009-11-11 04:17:07 +00002577 if( i<argc ){
2578 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2579 fprintf(stderr,"Use -help for a list of options.\n");
2580 return 1;
2581 }
drh44c2eb12003-04-30 11:38:26 +00002582 data.out = stdout;
2583
drh01b41712005-08-29 23:06:23 +00002584#ifdef SQLITE_OMIT_MEMORYDB
2585 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002586 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2587 return 1;
drh01b41712005-08-29 23:06:23 +00002588 }
2589#endif
2590
drh44c2eb12003-04-30 11:38:26 +00002591 /* Go ahead and open the database file if it already exists. If the
2592 ** file does not exist, delay opening it. This prevents empty database
2593 ** files from being created if a user mistypes the database name argument
2594 ** to the sqlite command-line tool.
2595 */
drhc8d74412004-08-31 23:41:26 +00002596 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002597 open_db(&data);
2598 }
2599
drh22fbcb82004-02-01 01:22:50 +00002600 /* Process the initialization file if there is one. If no -init option
2601 ** is given on the command line, look for a file named ~/.sqliterc and
2602 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002603 */
shane86f5bdb2009-10-24 02:00:07 +00002604 rc = process_sqliterc(&data,zInitFile);
2605 if( rc>0 ){
2606 return rc;
2607 }
drh44c2eb12003-04-30 11:38:26 +00002608
drh22fbcb82004-02-01 01:22:50 +00002609 /* Make a second pass through the command-line argument and set
2610 ** options. This second pass is delayed until after the initialization
2611 ** file is processed so that the command-line arguments will override
2612 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002613 */
drh22fbcb82004-02-01 01:22:50 +00002614 for(i=1; i<argc && argv[i][0]=='-'; i++){
2615 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002616 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002617 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002618 i++;
2619 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002620 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002621 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002622 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002623 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002624 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002625 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002626 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002627 }else if( strcmp(z,"-csv")==0 ){
2628 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002629 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002630 }else if( strcmp(z,"-separator")==0 ){
2631 i++;
shaneh5fc25012009-11-11 04:17:07 +00002632 if(i>=argc){
2633 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2634 fprintf(stderr,"Use -help for a list of options.\n");
2635 return 1;
2636 }
drh5bb3eb92007-05-04 13:15:55 +00002637 sqlite3_snprintf(sizeof(data.separator), data.separator,
2638 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002639 }else if( strcmp(z,"-nullvalue")==0 ){
2640 i++;
shaneh5fc25012009-11-11 04:17:07 +00002641 if(i>=argc){
2642 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2643 fprintf(stderr,"Use -help for a list of options.\n");
2644 return 1;
2645 }
drh5bb3eb92007-05-04 13:15:55 +00002646 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2647 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002648 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002649 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002650 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002651 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002652 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002653 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00002654 }else if( strcmp(z,"-stats")==0 ){
2655 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002656 }else if( strcmp(z,"-bail")==0 ){
2657 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002658 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002659 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002660 return 0;
drhc28490c2006-10-26 14:25:58 +00002661 }else if( strcmp(z,"-interactive")==0 ){
2662 stdin_is_interactive = 1;
2663 }else if( strcmp(z,"-batch")==0 ){
2664 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002665 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002666 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002667 }else{
shane86f5bdb2009-10-24 02:00:07 +00002668 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002669 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002670 return 1;
2671 }
2672 }
drh44c2eb12003-04-30 11:38:26 +00002673
drh22fbcb82004-02-01 01:22:50 +00002674 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002675 /* Run just the command that follows the database name
2676 */
drh22fbcb82004-02-01 01:22:50 +00002677 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00002678 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002679 }else{
drh44c2eb12003-04-30 11:38:26 +00002680 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00002681 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00002682 if( zErrMsg!=0 ){
2683 fprintf(stderr,"Error: %s\n", zErrMsg);
2684 return rc!=0 ? rc : 1;
2685 }else if( rc!=0 ){
2686 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
2687 return rc;
drh6ff13852001-11-25 13:18:23 +00002688 }
drh75897232000-05-29 14:26:00 +00002689 }
2690 }else{
drh44c2eb12003-04-30 11:38:26 +00002691 /* Run commands received from standard input
2692 */
drhc28490c2006-10-26 14:25:58 +00002693 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002694 char *zHome;
2695 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002696 int nHistory;
drh75897232000-05-29 14:26:00 +00002697 printf(
drhb217a572000-08-22 13:40:18 +00002698 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002699 "Enter \".help\" for instructions\n"
2700 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002701 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002702 );
drh67505e72002-04-19 12:34:06 +00002703 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002704 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002705 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002706 if( (zHistory = malloc(nHistory))!=0 ){
2707 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2708 }
drh67505e72002-04-19 12:34:06 +00002709 }
danielk19774af00c62005-01-23 23:43:21 +00002710#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002711 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002712#endif
drhc28490c2006-10-26 14:25:58 +00002713 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002714 if( zHistory ){
2715 stifle_history(100);
2716 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002717 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002718 }
adamd0a3daa32006-07-28 20:16:14 +00002719 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002720 }else{
drhc28490c2006-10-26 14:25:58 +00002721 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002722 }
2723 }
drh33048c02001-10-01 14:29:22 +00002724 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00002725 if( data.db ){
2726 if( sqlite3_close(data.db)!=SQLITE_OK ){
2727 fprintf(stderr,"Error: cannot close database \"%s\"\n",
2728 sqlite3_errmsg(db));
shane86f5bdb2009-10-24 02:00:07 +00002729 rc++;
adamd0a3daa32006-07-28 20:16:14 +00002730 }
2731 }
drhc28490c2006-10-26 14:25:58 +00002732 return rc;
drh75897232000-05-29 14:26:00 +00002733}