blob: 23099b94a40852b01dfa8afda9d46e2706640d02 [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 */
drh28bd4bc2000-06-15 15:57:22 +0000401 int cnt; /* Number of records displayed so far */
402 FILE *out; /* Write results here */
403 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000404 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000405 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000406 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000407 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000408 int colWidth[100]; /* Requested width of each column when in column mode*/
409 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000410 char nullvalue[20]; /* The text to print when a NULL comes back from
411 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000412 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000413 /* Holds the mode information just before
414 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000415 char outfile[FILENAME_MAX]; /* Filename for *out */
416 const char *zDbFilename; /* name of the database file */
shane626a6e42009-10-22 17:30:15 +0000417 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000418 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000419};
420
421/*
422** These are the allowed modes.
423*/
drh967e8b72000-06-21 13:59:10 +0000424#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000425#define MODE_Column 1 /* One record per line in neat columns */
426#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000427#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
428#define MODE_Html 4 /* Generate an XHTML table */
429#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000430#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000431#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000432#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000433
drh66ce4d02008-02-15 17:38:06 +0000434static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000435 "line",
436 "column",
437 "list",
438 "semi",
439 "html",
drhfeac5f82004-08-01 00:10:45 +0000440 "insert",
441 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000442 "csv",
drh66ce4d02008-02-15 17:38:06 +0000443 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000444};
drh75897232000-05-29 14:26:00 +0000445
446/*
447** Number of elements in an array
448*/
drh902b9ee2008-12-05 17:17:07 +0000449#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000450
451/*
drhea678832008-12-10 19:26:22 +0000452** Compute a string length that is limited to what can be stored in
453** lower 30 bits of a 32-bit signed integer.
454*/
drh4f21c4a2008-12-10 22:15:00 +0000455static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000456 const char *z2 = z;
457 while( *z2 ){ z2++; }
458 return 0x3fffffff & (int)(z2 - z);
459}
460
461/*
drh127f9d72010-02-23 01:47:00 +0000462** A callback for the sqlite3_log() interface.
463*/
464static void shellLog(void *pArg, int iErrCode, const char *zMsg){
465 struct callback_data *p = (struct callback_data*)pArg;
466 if( p->pLog==0 ) return;
467 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
468 fflush(p->pLog);
469}
470
471/*
shane626a6e42009-10-22 17:30:15 +0000472** Output the given string as a hex-encoded blob (eg. X'1234' )
473*/
474static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
475 int i;
476 char *zBlob = (char *)pBlob;
477 fprintf(out,"X'");
478 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
479 fprintf(out,"'");
480}
481
482/*
drh28bd4bc2000-06-15 15:57:22 +0000483** Output the given string as a quoted string using SQL quoting conventions.
484*/
485static void output_quoted_string(FILE *out, const char *z){
486 int i;
487 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000488 for(i=0; z[i]; i++){
489 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000490 }
491 if( nSingle==0 ){
492 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000493 }else{
494 fprintf(out,"'");
495 while( *z ){
496 for(i=0; z[i] && z[i]!='\''; i++){}
497 if( i==0 ){
498 fprintf(out,"''");
499 z++;
500 }else if( z[i]=='\'' ){
501 fprintf(out,"%.*s''",i,z);
502 z += i+1;
503 }else{
drhcd7d2732002-02-26 23:24:26 +0000504 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000505 break;
506 }
507 }
drhcd7d2732002-02-26 23:24:26 +0000508 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000509 }
510}
511
512/*
drhfeac5f82004-08-01 00:10:45 +0000513** Output the given string as a quoted according to C or TCL quoting rules.
514*/
515static void output_c_string(FILE *out, const char *z){
516 unsigned int c;
517 fputc('"', out);
518 while( (c = *(z++))!=0 ){
519 if( c=='\\' ){
520 fputc(c, out);
521 fputc(c, out);
522 }else if( c=='\t' ){
523 fputc('\\', out);
524 fputc('t', out);
525 }else if( c=='\n' ){
526 fputc('\\', out);
527 fputc('n', out);
528 }else if( c=='\r' ){
529 fputc('\\', out);
530 fputc('r', out);
531 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000532 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000533 }else{
534 fputc(c, out);
535 }
536 }
537 fputc('"', out);
538}
539
540/*
drhc08a4f12000-06-15 16:49:48 +0000541** Output the given string with characters that are special to
542** HTML escaped.
543*/
544static void output_html_string(FILE *out, const char *z){
545 int i;
546 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000547 for(i=0; z[i]
548 && z[i]!='<'
549 && z[i]!='&'
550 && z[i]!='>'
551 && z[i]!='\"'
552 && z[i]!='\'';
553 i++){}
drhc08a4f12000-06-15 16:49:48 +0000554 if( i>0 ){
555 fprintf(out,"%.*s",i,z);
556 }
557 if( z[i]=='<' ){
558 fprintf(out,"&lt;");
559 }else if( z[i]=='&' ){
560 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000561 }else if( z[i]=='>' ){
562 fprintf(out,"&gt;");
563 }else if( z[i]=='\"' ){
564 fprintf(out,"&quot;");
565 }else if( z[i]=='\'' ){
566 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000567 }else{
568 break;
569 }
570 z += i + 1;
571 }
572}
573
574/*
drhc49f44e2006-10-26 18:15:42 +0000575** If a field contains any character identified by a 1 in the following
576** array, then the string must be quoted for CSV.
577*/
578static const char needCsvQuote[] = {
579 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
580 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
581 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
582 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,
587 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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};
596
597/*
drh8e64d1c2004-10-07 00:32:39 +0000598** Output a single term of CSV. Actually, p->separator is used for
599** the separator, which may or may not be a comma. p->nullvalue is
600** the null value. Strings are quoted using ANSI-C rules. Numbers
601** appear outside of quotes.
602*/
603static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000604 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000605 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000606 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000607 }else{
drhc49f44e2006-10-26 18:15:42 +0000608 int i;
drh4f21c4a2008-12-10 22:15:00 +0000609 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000610 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000611 if( needCsvQuote[((unsigned char*)z)[i]]
612 || (z[i]==p->separator[0] &&
613 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000614 i = 0;
615 break;
616 }
617 }
618 if( i==0 ){
619 putc('"', out);
620 for(i=0; z[i]; i++){
621 if( z[i]=='"' ) putc('"', out);
622 putc(z[i], out);
623 }
624 putc('"', out);
625 }else{
626 fprintf(out, "%s", z);
627 }
drh8e64d1c2004-10-07 00:32:39 +0000628 }
629 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000630 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000631 }
632}
633
danielk19774af00c62005-01-23 23:43:21 +0000634#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000635/*
drh4c504392000-10-16 22:06:40 +0000636** This routine runs when the user presses Ctrl-C
637*/
638static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000639 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000640 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000641 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000642}
danielk19774af00c62005-01-23 23:43:21 +0000643#endif
drh4c504392000-10-16 22:06:40 +0000644
645/*
shane626a6e42009-10-22 17:30:15 +0000646** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000647** invokes for each row of a query result.
648*/
shane626a6e42009-10-22 17:30:15 +0000649static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000650 int i;
651 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000652
drh75897232000-05-29 14:26:00 +0000653 switch( p->mode ){
654 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000655 int w = 5;
drh6a535342001-10-19 16:44:56 +0000656 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000657 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000658 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000659 if( len>w ) w = len;
660 }
drh75897232000-05-29 14:26:00 +0000661 if( p->cnt++>0 ) fprintf(p->out,"\n");
662 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000663 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000664 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000665 }
666 break;
667 }
danielk19770d78bae2008-01-03 07:09:48 +0000668 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000669 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000670 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000671 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000672 int w, n;
673 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000674 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000675 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000676 w = 0;
drh75897232000-05-29 14:26:00 +0000677 }
drha0c66f52000-07-29 13:20:21 +0000678 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000679 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000680 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000681 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000682 if( w<n ) w = n;
683 }
684 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000685 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000686 }
687 if( p->showHeader ){
688 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
689 }
690 }
691 if( p->showHeader ){
692 for(i=0; i<nArg; i++){
693 int w;
694 if( i<ArraySize(p->actualWidth) ){
695 w = p->actualWidth[i];
696 }else{
697 w = 10;
698 }
699 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
700 "----------------------------------------------------------",
701 i==nArg-1 ? "\n": " ");
702 }
drh75897232000-05-29 14:26:00 +0000703 }
704 }
drh6a535342001-10-19 16:44:56 +0000705 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000706 for(i=0; i<nArg; i++){
707 int w;
drha0c66f52000-07-29 13:20:21 +0000708 if( i<ArraySize(p->actualWidth) ){
709 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000710 }else{
711 w = 10;
712 }
drhea678832008-12-10 19:26:22 +0000713 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000714 strlen30(azArg[i])>w ){
715 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000716 }
drhc61053b2000-06-04 12:58:36 +0000717 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000718 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000719 }
720 break;
721 }
drhe3710332000-09-29 13:30:53 +0000722 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000723 case MODE_List: {
724 if( p->cnt++==0 && p->showHeader ){
725 for(i=0; i<nArg; i++){
726 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
727 }
728 }
drh6a535342001-10-19 16:44:56 +0000729 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000730 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000731 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000732 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000733 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000734 if( i<nArg-1 ){
735 fprintf(p->out, "%s", p->separator);
736 }else if( p->mode==MODE_Semi ){
737 fprintf(p->out, ";\n");
738 }else{
739 fprintf(p->out, "\n");
740 }
drh75897232000-05-29 14:26:00 +0000741 }
742 break;
743 }
drh1e5d0e92000-05-31 23:33:17 +0000744 case MODE_Html: {
745 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000746 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000747 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000748 fprintf(p->out,"<TH>");
749 output_html_string(p->out, azCol[i]);
750 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000751 }
mihailim57c591a2008-06-23 21:26:05 +0000752 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000753 }
drh6a535342001-10-19 16:44:56 +0000754 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000755 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000756 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000757 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000758 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000759 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000760 }
mihailim57c591a2008-06-23 21:26:05 +0000761 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000762 break;
763 }
drhfeac5f82004-08-01 00:10:45 +0000764 case MODE_Tcl: {
765 if( p->cnt++==0 && p->showHeader ){
766 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000767 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000768 fprintf(p->out, "%s", p->separator);
769 }
770 fprintf(p->out,"\n");
771 }
772 if( azArg==0 ) break;
773 for(i=0; i<nArg; i++){
774 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
775 fprintf(p->out, "%s", p->separator);
776 }
777 fprintf(p->out,"\n");
778 break;
779 }
drh8e64d1c2004-10-07 00:32:39 +0000780 case MODE_Csv: {
781 if( p->cnt++==0 && p->showHeader ){
782 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000783 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000784 }
785 fprintf(p->out,"\n");
786 }
787 if( azArg==0 ) break;
788 for(i=0; i<nArg; i++){
789 output_csv(p, azArg[i], i<nArg-1);
790 }
791 fprintf(p->out,"\n");
792 break;
793 }
drh28bd4bc2000-06-15 15:57:22 +0000794 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000795 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000796 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000797 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000798 for(i=0; i<nArg; i++){
799 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000800 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000801 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000802 }else if( aiType && aiType[i]==SQLITE_TEXT ){
803 if( zSep[0] ) fprintf(p->out,"%s",zSep);
804 output_quoted_string(p->out, azArg[i]);
805 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
806 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000807 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
808 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
809 int nBlob = sqlite3_column_bytes(p->pStmt, i);
810 if( zSep[0] ) fprintf(p->out,"%s",zSep);
811 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000812 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000813 fprintf(p->out,"%s%s",zSep, azArg[i]);
814 }else{
815 if( zSep[0] ) fprintf(p->out,"%s",zSep);
816 output_quoted_string(p->out, azArg[i]);
817 }
818 }
819 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000820 break;
drh28bd4bc2000-06-15 15:57:22 +0000821 }
persicom1d0b8722002-04-18 02:53:04 +0000822 }
drh75897232000-05-29 14:26:00 +0000823 return 0;
824}
825
826/*
shane626a6e42009-10-22 17:30:15 +0000827** This is the callback routine that the SQLite library
828** invokes for each row of a query result.
829*/
830static int callback(void *pArg, int nArg, char **azArg, char **azCol){
831 /* since we don't have type info, call the shell_callback with a NULL value */
832 return shell_callback(pArg, nArg, azArg, azCol, NULL);
833}
834
835/*
drh33048c02001-10-01 14:29:22 +0000836** Set the destination table field of the callback_data structure to
837** the name of the table given. Escape any quote characters in the
838** table name.
839*/
840static void set_table_name(struct callback_data *p, const char *zName){
841 int i, n;
842 int needQuote;
843 char *z;
844
845 if( p->zDestTable ){
846 free(p->zDestTable);
847 p->zDestTable = 0;
848 }
849 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000850 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000851 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000852 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000853 needQuote = 1;
854 if( zName[i]=='\'' ) n++;
855 }
856 }
857 if( needQuote ) n += 2;
858 z = p->zDestTable = malloc( n+1 );
859 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000860 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000861 exit(1);
862 }
863 n = 0;
864 if( needQuote ) z[n++] = '\'';
865 for(i=0; zName[i]; i++){
866 z[n++] = zName[i];
867 if( zName[i]=='\'' ) z[n++] = '\'';
868 }
869 if( needQuote ) z[n++] = '\'';
870 z[n] = 0;
871}
872
danielk19772a02e332004-06-05 08:04:36 +0000873/* zIn is either a pointer to a NULL-terminated string in memory obtained
874** from malloc(), or a NULL pointer. The string pointed to by zAppend is
875** added to zIn, and the result returned in memory obtained from malloc().
876** zIn, if it was not NULL, is freed.
877**
878** If the third argument, quote, is not '\0', then it is used as a
879** quote character for zAppend.
880*/
drhc28490c2006-10-26 14:25:58 +0000881static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000882 int len;
883 int i;
drh4f21c4a2008-12-10 22:15:00 +0000884 int nAppend = strlen30(zAppend);
885 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000886
887 len = nAppend+nIn+1;
888 if( quote ){
889 len += 2;
890 for(i=0; i<nAppend; i++){
891 if( zAppend[i]==quote ) len++;
892 }
893 }
894
895 zIn = (char *)realloc(zIn, len);
896 if( !zIn ){
897 return 0;
898 }
899
900 if( quote ){
901 char *zCsr = &zIn[nIn];
902 *zCsr++ = quote;
903 for(i=0; i<nAppend; i++){
904 *zCsr++ = zAppend[i];
905 if( zAppend[i]==quote ) *zCsr++ = quote;
906 }
907 *zCsr++ = quote;
908 *zCsr++ = '\0';
909 assert( (zCsr-zIn)==len );
910 }else{
911 memcpy(&zIn[nIn], zAppend, nAppend);
912 zIn[len-1] = '\0';
913 }
914
915 return zIn;
916}
917
drhdd3d4592004-08-30 01:54:05 +0000918
919/*
920** Execute a query statement that has a single result column. Print
921** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000922**
923** This is used, for example, to show the schema of the database by
924** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000925*/
drh157e29a2009-05-21 15:15:00 +0000926static int run_table_dump_query(
927 FILE *out, /* Send output here */
928 sqlite3 *db, /* Database to query */
929 const char *zSelect, /* SELECT statement to extract content */
930 const char *zFirstRow /* Print before first row, if not NULL */
931){
drhdd3d4592004-08-30 01:54:05 +0000932 sqlite3_stmt *pSelect;
933 int rc;
934 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
935 if( rc!=SQLITE_OK || !pSelect ){
936 return rc;
937 }
938 rc = sqlite3_step(pSelect);
939 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000940 if( zFirstRow ){
941 fprintf(out, "%s", zFirstRow);
942 zFirstRow = 0;
943 }
drhdd3d4592004-08-30 01:54:05 +0000944 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
945 rc = sqlite3_step(pSelect);
946 }
947 return sqlite3_finalize(pSelect);
948}
949
shane626a6e42009-10-22 17:30:15 +0000950/*
951** Allocate space and save off current error string.
952*/
953static char *save_err_msg(
954 sqlite3 *db /* Database to query */
955){
956 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
957 char *zErrMsg = sqlite3_malloc(nErrMsg);
958 if( zErrMsg ){
959 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
960 }
961 return zErrMsg;
962}
963
964/*
965** Execute a statement or set of statements. Print
966** any result rows/columns depending on the current mode
967** set via the supplied callback.
968**
969** This is very similar to SQLite's built-in sqlite3_exec()
970** function except it takes a slightly different callback
971** and callback data argument.
972*/
973static int shell_exec(
974 sqlite3 *db, /* An open database */
975 const char *zSql, /* SQL to be evaluated */
976 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
977 /* (not the same as sqlite3_exec) */
978 struct callback_data *pArg, /* Pointer to struct callback_data */
979 char **pzErrMsg /* Error msg written here */
980){
dan4564ced2010-01-05 04:59:56 +0000981 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
982 int rc = SQLITE_OK; /* Return Code */
983 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +0000984
985 if( pzErrMsg ){
986 *pzErrMsg = NULL;
987 }
988
shaneb9fc17d2009-10-22 21:23:35 +0000989 while( zSql[0] && (SQLITE_OK == rc) ){
990 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
991 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +0000992 if( pzErrMsg ){
993 *pzErrMsg = save_err_msg(db);
994 }
995 }else{
shaneb9fc17d2009-10-22 21:23:35 +0000996 if( !pStmt ){
997 /* this happens for a comment or white-space */
998 zSql = zLeftover;
999 while( isspace(zSql[0]) ) zSql++;
1000 continue;
1001 }
shane626a6e42009-10-22 17:30:15 +00001002
shanehb7977c52010-01-18 18:17:10 +00001003 /* echo the sql statement if echo on */
1004 if( pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001005 const char *zStmtSql = sqlite3_sql(pStmt);
shanehb7977c52010-01-18 18:17:10 +00001006 fprintf(pArg->out,"%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001007 }
shanehb7977c52010-01-18 18:17:10 +00001008
shaneb9fc17d2009-10-22 21:23:35 +00001009 /* perform the first step. this will tell us if we
1010 ** have a result set or not and how wide it is.
1011 */
1012 rc = sqlite3_step(pStmt);
1013 /* if we have a result set... */
1014 if( SQLITE_ROW == rc ){
1015 /* if we have a callback... */
1016 if( xCallback ){
1017 /* allocate space for col name ptr, value ptr, and type */
1018 int nCol = sqlite3_column_count(pStmt);
1019 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1020 if( !pData ){
1021 rc = SQLITE_NOMEM;
1022 }else{
1023 char **azCols = (char **)pData; /* Names of result columns */
1024 char **azVals = &azCols[nCol]; /* Results */
1025 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1026 int i;
1027 assert(sizeof(int) <= sizeof(char *));
1028 /* save off ptrs to column names */
1029 for(i=0; i<nCol; i++){
1030 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1031 }
1032 /* save off the prepared statment handle and reset row count */
1033 if( pArg ){
1034 pArg->pStmt = pStmt;
1035 pArg->cnt = 0;
1036 }
1037 do{
1038 /* extract the data and data types */
1039 for(i=0; i<nCol; i++){
1040 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1041 aiTypes[i] = sqlite3_column_type(pStmt, i);
1042 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1043 rc = SQLITE_NOMEM;
1044 break; /* from for */
1045 }
1046 } /* end for */
1047
1048 /* if data and types extracted successfully... */
1049 if( SQLITE_ROW == rc ){
1050 /* call the supplied callback with the result row data */
1051 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1052 rc = SQLITE_ABORT;
1053 }else{
1054 rc = sqlite3_step(pStmt);
1055 }
1056 }
1057 } while( SQLITE_ROW == rc );
1058 sqlite3_free(pData);
1059 if( pArg ){
1060 pArg->pStmt = NULL;
1061 }
1062 }
1063 }else{
1064 do{
1065 rc = sqlite3_step(pStmt);
1066 } while( rc == SQLITE_ROW );
1067 }
1068 }
1069
dan4564ced2010-01-05 04:59:56 +00001070 /* Finalize the statement just executed. If this fails, save a
1071 ** copy of the error message. Otherwise, set zSql to point to the
1072 ** next statement to execute. */
1073 rc = sqlite3_finalize(pStmt);
1074 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001075 zSql = zLeftover;
1076 while( isspace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001077 }else if( pzErrMsg ){
1078 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001079 }
1080 }
shaneb9fc17d2009-10-22 21:23:35 +00001081 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001082
1083 return rc;
1084}
1085
drhdd3d4592004-08-30 01:54:05 +00001086
drh33048c02001-10-01 14:29:22 +00001087/*
drh4c653a02000-06-07 01:27:47 +00001088** This is a different callback routine used for dumping the database.
1089** Each row received by this callback consists of a table name,
1090** the table type ("index" or "table") and SQL to create the table.
1091** This routine should print text sufficient to recreate the table.
1092*/
1093static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001094 int rc;
1095 const char *zTable;
1096 const char *zType;
1097 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001098 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001099 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001100
drh902b9ee2008-12-05 17:17:07 +00001101 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001102 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001103 zTable = azArg[0];
1104 zType = azArg[1];
1105 zSql = azArg[2];
1106
drh00b950d2005-09-11 02:03:03 +00001107 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001108 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001109 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1110 fprintf(p->out, "ANALYZE sqlite_master;\n");
1111 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1112 return 0;
drh45e29d82006-11-20 16:21:10 +00001113 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1114 char *zIns;
1115 if( !p->writableSchema ){
1116 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1117 p->writableSchema = 1;
1118 }
1119 zIns = sqlite3_mprintf(
1120 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1121 "VALUES('table','%q','%q',0,'%q');",
1122 zTable, zTable, zSql);
1123 fprintf(p->out, "%s\n", zIns);
1124 sqlite3_free(zIns);
1125 return 0;
drh00b950d2005-09-11 02:03:03 +00001126 }else{
1127 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001128 }
danielk19772a02e332004-06-05 08:04:36 +00001129
1130 if( strcmp(zType, "table")==0 ){
1131 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001132 char *zSelect = 0;
1133 char *zTableInfo = 0;
1134 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001135 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001136
1137 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1138 zTableInfo = appendText(zTableInfo, zTable, '"');
1139 zTableInfo = appendText(zTableInfo, ");", 0);
1140
1141 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001142 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001143 if( rc!=SQLITE_OK || !pTableInfo ){
1144 return 1;
1145 }
1146
1147 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1148 zTmp = appendText(zTmp, zTable, '"');
1149 if( zTmp ){
1150 zSelect = appendText(zSelect, zTmp, '\'');
1151 }
1152 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1153 rc = sqlite3_step(pTableInfo);
1154 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001155 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001156 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001157 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001158 rc = sqlite3_step(pTableInfo);
1159 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001160 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001161 }else{
1162 zSelect = appendText(zSelect, ") ", 0);
1163 }
drh157e29a2009-05-21 15:15:00 +00001164 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001165 }
1166 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001167 if( rc!=SQLITE_OK || nRow==0 ){
1168 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001169 return 1;
1170 }
1171 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1172 zSelect = appendText(zSelect, zTable, '"');
1173
drh157e29a2009-05-21 15:15:00 +00001174 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001175 if( rc==SQLITE_CORRUPT ){
1176 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001177 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001178 }
danielk19772a02e332004-06-05 08:04:36 +00001179 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001180 }
drh4c653a02000-06-07 01:27:47 +00001181 return 0;
1182}
1183
1184/*
drh45e29d82006-11-20 16:21:10 +00001185** Run zQuery. Use dump_callback() as the callback routine so that
1186** the contents of the query are output as SQL statements.
1187**
drhdd3d4592004-08-30 01:54:05 +00001188** If we get a SQLITE_CORRUPT error, rerun the query after appending
1189** "ORDER BY rowid DESC" to the end.
1190*/
1191static int run_schema_dump_query(
1192 struct callback_data *p,
1193 const char *zQuery,
1194 char **pzErrMsg
1195){
1196 int rc;
1197 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1198 if( rc==SQLITE_CORRUPT ){
1199 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001200 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001201 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1202 zQ2 = malloc( len+100 );
1203 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001204 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001205 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1206 free(zQ2);
1207 }
1208 return rc;
1209}
1210
1211/*
drh75897232000-05-29 14:26:00 +00001212** Text of a help message
1213*/
persicom1d0b8722002-04-18 02:53:04 +00001214static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001215 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001216 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001217 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001218 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001219 " If TABLE specified, only dump tables matching\n"
1220 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001221 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001222 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001223 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1224 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001225 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001226 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001227 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001228 ".indices ?TABLE? Show names of all indices\n"
1229 " If TABLE specified, only show indices for tables\n"
1230 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001231#ifdef SQLITE_ENABLE_IOTRACE
1232 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1233#endif
drh70df4fe2006-06-13 15:12:21 +00001234#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001235 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001236#endif
drh127f9d72010-02-23 01:47:00 +00001237 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001238 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001239 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001240 " column Left-aligned columns. (See .width)\n"
1241 " html HTML <table> code\n"
1242 " insert SQL insert statements for TABLE\n"
1243 " line One value per line\n"
1244 " list Values delimited by .separator string\n"
1245 " tabs Tab-separated values\n"
1246 " tcl TCL list elements\n"
1247 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001248 ".output FILENAME Send output to FILENAME\n"
1249 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001250 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001251 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001252 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001253 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001254 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001255 " If TABLE specified, only show tables matching\n"
1256 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001257 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001258 ".show Show the current values for various settings\n"
shane86f5bdb2009-10-24 02:00:07 +00001259 ".tables ?TABLE? List names of tables\n"
1260 " If TABLE specified, only list tables matching\n"
1261 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001262 ".timeout MS Try opening locked tables for MS milliseconds\n"
shanehe2aa9d72009-11-06 17:20:17 +00001263 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001264;
1265
shaneb320ccd2009-10-21 03:42:58 +00001266static char zTimerHelp[] =
1267 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1268;
1269
drhdaffd0e2001-04-11 14:28:42 +00001270/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001271static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001272
drh75897232000-05-29 14:26:00 +00001273/*
drh44c2eb12003-04-30 11:38:26 +00001274** Make sure the database is open. If it is not, then open it. If
1275** the database fails to open, print an error message and exit.
1276*/
1277static void open_db(struct callback_data *p){
1278 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001279 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001280 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001281 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1282 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1283 shellstaticFunc, 0, 0);
1284 }
1285 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001286 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001287 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001288 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001289 }
drhc2e87a32006-06-27 15:16:14 +00001290#ifndef SQLITE_OMIT_LOAD_EXTENSION
1291 sqlite3_enable_load_extension(p->db, 1);
1292#endif
drh44c2eb12003-04-30 11:38:26 +00001293 }
1294}
1295
1296/*
drhfeac5f82004-08-01 00:10:45 +00001297** Do C-language style dequoting.
1298**
1299** \t -> tab
1300** \n -> newline
1301** \r -> carriage return
1302** \NNN -> ascii character NNN in octal
1303** \\ -> backslash
1304*/
1305static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001306 int i, j;
1307 char c;
drhfeac5f82004-08-01 00:10:45 +00001308 for(i=j=0; (c = z[i])!=0; i++, j++){
1309 if( c=='\\' ){
1310 c = z[++i];
1311 if( c=='n' ){
1312 c = '\n';
1313 }else if( c=='t' ){
1314 c = '\t';
1315 }else if( c=='r' ){
1316 c = '\r';
1317 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001318 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001319 if( z[i+1]>='0' && z[i+1]<='7' ){
1320 i++;
1321 c = (c<<3) + z[i] - '0';
1322 if( z[i+1]>='0' && z[i+1]<='7' ){
1323 i++;
1324 c = (c<<3) + z[i] - '0';
1325 }
1326 }
1327 }
1328 }
1329 z[j] = c;
1330 }
1331 z[j] = 0;
1332}
1333
1334/*
drhc28490c2006-10-26 14:25:58 +00001335** Interpret zArg as a boolean value. Return either 0 or 1.
1336*/
1337static int booleanValue(char *zArg){
1338 int val = atoi(zArg);
1339 int j;
1340 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001341 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001342 }
1343 if( strcmp(zArg,"on")==0 ){
1344 val = 1;
1345 }else if( strcmp(zArg,"yes")==0 ){
1346 val = 1;
1347 }
1348 return val;
1349}
1350
1351/*
drh75897232000-05-29 14:26:00 +00001352** If an input line begins with "." then invoke this routine to
1353** process that line.
drh67505e72002-04-19 12:34:06 +00001354**
drh47ad6842006-11-08 12:25:42 +00001355** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001356*/
drh44c2eb12003-04-30 11:38:26 +00001357static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001358 int i = 1;
1359 int nArg = 0;
1360 int n, c;
drh67505e72002-04-19 12:34:06 +00001361 int rc = 0;
drh75897232000-05-29 14:26:00 +00001362 char *azArg[50];
1363
1364 /* Parse the input line into tokens.
1365 */
1366 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001367 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001368 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001369 if( zLine[i]=='\'' || zLine[i]=='"' ){
1370 int delim = zLine[i++];
1371 azArg[nArg++] = &zLine[i];
1372 while( zLine[i] && zLine[i]!=delim ){ i++; }
1373 if( zLine[i]==delim ){
1374 zLine[i++] = 0;
1375 }
drhfeac5f82004-08-01 00:10:45 +00001376 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001377 }else{
1378 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001379 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001380 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001381 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001382 }
1383 }
1384
1385 /* Process the input line.
1386 */
shane9bd1b442009-10-23 01:27:39 +00001387 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001388 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001389 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001390 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001391 const char *zDestFile;
1392 const char *zDb;
1393 sqlite3 *pDest;
1394 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001395 if( nArg==2 ){
1396 zDestFile = azArg[1];
1397 zDb = "main";
1398 }else{
1399 zDestFile = azArg[2];
1400 zDb = azArg[1];
1401 }
1402 rc = sqlite3_open(zDestFile, &pDest);
1403 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001404 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001405 sqlite3_close(pDest);
1406 return 1;
1407 }
drhdc2c4912009-02-04 22:46:47 +00001408 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001409 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1410 if( pBackup==0 ){
1411 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1412 sqlite3_close(pDest);
1413 return 1;
1414 }
1415 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1416 sqlite3_backup_finish(pBackup);
1417 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001418 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001419 }else{
1420 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001421 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001422 }
1423 sqlite3_close(pDest);
1424 }else
1425
shanehe2aa9d72009-11-06 17:20:17 +00001426 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001427 bail_on_error = booleanValue(azArg[1]);
1428 }else
1429
shanehe2aa9d72009-11-06 17:20:17 +00001430 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001431 struct callback_data data;
1432 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001433 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001434 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001435 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001436 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001437 data.colWidth[0] = 3;
1438 data.colWidth[1] = 15;
1439 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001440 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001441 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001442 if( zErrMsg ){
1443 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001444 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001445 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001446 }
1447 }else
1448
shanehe2aa9d72009-11-06 17:20:17 +00001449 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh4c653a02000-06-07 01:27:47 +00001450 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001451 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001452 /* When playing back a "dump", the content might appear in an order
1453 ** which causes immediate foreign key constraints to be violated.
1454 ** So disable foreign-key constraint enforcement to prevent problems. */
1455 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001456 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001457 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001458 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001459 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001460 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001461 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00001462 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1463 );
1464 run_schema_dump_query(p,
1465 "SELECT name, type, sql FROM sqlite_master "
1466 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00001467 );
1468 run_table_dump_query(p->out, p->db,
1469 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001470 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001471 );
drh4c653a02000-06-07 01:27:47 +00001472 }else{
1473 int i;
drhdd3d4592004-08-30 01:54:05 +00001474 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001475 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001476 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001477 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001478 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001479 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001480 run_table_dump_query(p->out, p->db,
1481 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001482 "WHERE sql NOT NULL"
1483 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001484 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001485 );
danielk1977bc6ada42004-06-30 08:20:16 +00001486 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001487 }
1488 }
drh45e29d82006-11-20 16:21:10 +00001489 if( p->writableSchema ){
1490 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1491 p->writableSchema = 0;
1492 }
drh93f41e52008-08-11 19:12:34 +00001493 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001494 if( zErrMsg ){
1495 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001496 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001497 }else{
1498 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001499 }
1500 }else
drh75897232000-05-29 14:26:00 +00001501
shanehe2aa9d72009-11-06 17:20:17 +00001502 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001503 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001504 }else
1505
shanehe2aa9d72009-11-06 17:20:17 +00001506 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001507 rc = 2;
drh75897232000-05-29 14:26:00 +00001508 }else
1509
shanehe2aa9d72009-11-06 17:20:17 +00001510 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001511 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001512 if(val == 1) {
1513 if(!p->explainPrev.valid) {
1514 p->explainPrev.valid = 1;
1515 p->explainPrev.mode = p->mode;
1516 p->explainPrev.showHeader = p->showHeader;
1517 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1518 }
1519 /* We could put this code under the !p->explainValid
1520 ** condition so that it does not execute if we are already in
1521 ** explain mode. However, always executing it allows us an easy
1522 ** was to reset to explain mode in case the user previously
1523 ** did an .explain followed by a .width, .mode or .header
1524 ** command.
1525 */
danielk19770d78bae2008-01-03 07:09:48 +00001526 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001527 p->showHeader = 1;
1528 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001529 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001530 p->colWidth[1] = 13; /* opcode */
1531 p->colWidth[2] = 4; /* P1 */
1532 p->colWidth[3] = 4; /* P2 */
1533 p->colWidth[4] = 4; /* P3 */
1534 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001535 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001536 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001537 }else if (p->explainPrev.valid) {
1538 p->explainPrev.valid = 0;
1539 p->mode = p->explainPrev.mode;
1540 p->showHeader = p->explainPrev.showHeader;
1541 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1542 }
drh75897232000-05-29 14:26:00 +00001543 }else
1544
drhc28490c2006-10-26 14:25:58 +00001545 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001546 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001547 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001548 }else
1549
1550 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001551 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001552 if( HAS_TIMER ){
1553 fprintf(stderr,"%s",zTimerHelp);
1554 }
drh75897232000-05-29 14:26:00 +00001555 }else
1556
shanehe2aa9d72009-11-06 17:20:17 +00001557 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001558 char *zTable = azArg[2]; /* Insert data into this table */
1559 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001560 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001561 int nCol; /* Number of columns in the table */
1562 int nByte; /* Number of bytes in an SQL string */
1563 int i, j; /* Loop counters */
1564 int nSep; /* Number of bytes in p->separator[] */
1565 char *zSql; /* An SQL statement */
1566 char *zLine; /* A single line of input from the file */
1567 char **azCol; /* zLine[] broken up into columns */
1568 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001569 FILE *in; /* The input file */
1570 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001571
drha543c822006-06-08 16:10:14 +00001572 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001573 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001574 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001575 fprintf(stderr, "Error: non-null separator required for import\n");
1576 return 1;
drhfeac5f82004-08-01 00:10:45 +00001577 }
1578 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
shane916f9612009-10-23 00:37:15 +00001579 if( zSql==0 ){
1580 fprintf(stderr, "Error: out of memory\n");
1581 return 1;
1582 }
drh4f21c4a2008-12-10 22:15:00 +00001583 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001584 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001585 sqlite3_free(zSql);
1586 if( rc ){
shane916f9612009-10-23 00:37:15 +00001587 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001588 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001589 return 1;
drhfeac5f82004-08-01 00:10:45 +00001590 }
shane916f9612009-10-23 00:37:15 +00001591 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001592 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001593 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001594 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001595 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001596 if( zSql==0 ){
1597 fprintf(stderr, "Error: out of memory\n");
1598 return 1;
1599 }
drhfeac5f82004-08-01 00:10:45 +00001600 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001601 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001602 for(i=1; i<nCol; i++){
1603 zSql[j++] = ',';
1604 zSql[j++] = '?';
1605 }
1606 zSql[j++] = ')';
1607 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001608 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001609 free(zSql);
1610 if( rc ){
1611 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001612 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001613 return 1;
drhfeac5f82004-08-01 00:10:45 +00001614 }
1615 in = fopen(zFile, "rb");
1616 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001617 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001618 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001619 return 1;
drhfeac5f82004-08-01 00:10:45 +00001620 }
1621 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001622 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001623 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001624 fclose(in);
shane916f9612009-10-23 00:37:15 +00001625 sqlite3_finalize(pStmt);
1626 return 1;
drh43617e92006-03-06 20:55:46 +00001627 }
drhfeac5f82004-08-01 00:10:45 +00001628 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1629 zCommit = "COMMIT";
1630 while( (zLine = local_getline(0, in))!=0 ){
1631 char *z;
1632 i = 0;
drhb860bc92004-08-04 15:16:55 +00001633 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001634 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001635 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001636 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1637 *z = 0;
1638 i++;
drhb860bc92004-08-04 15:16:55 +00001639 if( i<nCol ){
1640 azCol[i] = &z[nSep];
1641 z += nSep-1;
1642 }
drhfeac5f82004-08-01 00:10:45 +00001643 }
shane916f9612009-10-23 00:37:15 +00001644 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001645 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001646 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001647 fprintf(stderr,
1648 "Error: %s line %d: expected %d columns of data but found %d\n",
1649 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001650 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001651 free(zLine);
shane916f9612009-10-23 00:37:15 +00001652 rc = 1;
1653 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001654 }
drhfeac5f82004-08-01 00:10:45 +00001655 for(i=0; i<nCol; i++){
1656 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1657 }
1658 sqlite3_step(pStmt);
1659 rc = sqlite3_reset(pStmt);
1660 free(zLine);
1661 if( rc!=SQLITE_OK ){
1662 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1663 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001664 rc = 1;
shane916f9612009-10-23 00:37:15 +00001665 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001666 }
shane916f9612009-10-23 00:37:15 +00001667 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001668 free(azCol);
1669 fclose(in);
1670 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001671 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001672 }else
1673
shanehe2aa9d72009-11-06 17:20:17 +00001674 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001675 struct callback_data data;
1676 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001677 open_db(p);
drh75897232000-05-29 14:26:00 +00001678 memcpy(&data, p, sizeof(data));
1679 data.showHeader = 0;
1680 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001681 if( nArg==1 ){
1682 rc = sqlite3_exec(p->db,
1683 "SELECT name FROM sqlite_master "
1684 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1685 "UNION ALL "
1686 "SELECT name FROM sqlite_temp_master "
1687 "WHERE type='index' "
1688 "ORDER BY 1",
1689 callback, &data, &zErrMsg
1690 );
1691 }else{
1692 zShellStatic = azArg[1];
1693 rc = sqlite3_exec(p->db,
1694 "SELECT name FROM sqlite_master "
1695 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1696 "UNION ALL "
1697 "SELECT name FROM sqlite_temp_master "
1698 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1699 "ORDER BY 1",
1700 callback, &data, &zErrMsg
1701 );
1702 zShellStatic = 0;
1703 }
drh75897232000-05-29 14:26:00 +00001704 if( zErrMsg ){
1705 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001706 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001707 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001708 }else if( rc != SQLITE_OK ){
1709 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1710 rc = 1;
drh75897232000-05-29 14:26:00 +00001711 }
1712 }else
1713
drhae5e4452007-05-03 17:18:36 +00001714#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001715 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001716 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001717 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1718 iotrace = 0;
1719 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001720 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001721 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001722 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001723 iotrace = stdout;
1724 }else{
1725 iotrace = fopen(azArg[1], "w");
1726 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001727 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001728 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001729 rc = 1;
drhb0603412007-02-28 04:47:26 +00001730 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001731 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001732 }
1733 }
1734 }else
drhae5e4452007-05-03 17:18:36 +00001735#endif
drhb0603412007-02-28 04:47:26 +00001736
drh70df4fe2006-06-13 15:12:21 +00001737#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001738 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1739 const char *zFile, *zProc;
1740 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001741 zFile = azArg[1];
1742 zProc = nArg>=3 ? azArg[2] : 0;
1743 open_db(p);
1744 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1745 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001746 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001747 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001748 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001749 }
1750 }else
drh70df4fe2006-06-13 15:12:21 +00001751#endif
drh1e397f82006-06-08 15:28:43 +00001752
drh127f9d72010-02-23 01:47:00 +00001753 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=1 ){
1754 const char *zFile = azArg[1];
1755 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1756 fclose(p->pLog);
1757 p->pLog = 0;
1758 }
1759 if( strcmp(zFile,"stdout")==0 ){
1760 p->pLog = stdout;
1761 }else if( strcmp(zFile, "stderr")==0 ){
1762 p->pLog = stderr;
1763 }else if( strcmp(zFile, "off")==0 ){
1764 p->pLog = 0;
1765 }else{
1766 p->pLog = fopen(zFile, "w");
1767 if( p->pLog==0 ){
1768 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1769 }
1770 }
1771 }else
1772
shanehe2aa9d72009-11-06 17:20:17 +00001773 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001774 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001775 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001776 ||
shanehe2aa9d72009-11-06 17:20:17 +00001777 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001778 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001779 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001780 ||
shanehe2aa9d72009-11-06 17:20:17 +00001781 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001782 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001783 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001784 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001785 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001786 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001787 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001788 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001789 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001790 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001791 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001792 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001793 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001794 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001795 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001796 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001797 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001798 }else {
shane9bd1b442009-10-23 01:27:39 +00001799 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001800 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001801 rc = 1;
drh75897232000-05-29 14:26:00 +00001802 }
1803 }else
1804
shanehe2aa9d72009-11-06 17:20:17 +00001805 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1806 int n2 = strlen30(azArg[1]);
1807 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1808 p->mode = MODE_Insert;
1809 set_table_name(p, azArg[2]);
1810 }else {
1811 fprintf(stderr, "Error: invalid arguments: "
1812 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1813 rc = 1;
1814 }
1815 }else
1816
persicom7e2dfdd2002-04-18 02:46:52 +00001817 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001818 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1819 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001820 }else
1821
drh75897232000-05-29 14:26:00 +00001822 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1823 if( p->out!=stdout ){
1824 fclose(p->out);
1825 }
1826 if( strcmp(azArg[1],"stdout")==0 ){
1827 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001828 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001829 }else{
drha1f9b5e2004-02-14 16:31:02 +00001830 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001831 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00001832 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00001833 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00001834 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001835 } else {
drh5bb3eb92007-05-04 13:15:55 +00001836 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001837 }
1838 }
1839 }else
1840
drhdd45df82002-04-18 12:39:03 +00001841 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001842 if( nArg >= 2) {
1843 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1844 }
1845 if( nArg >= 3) {
1846 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1847 }
1848 }else
1849
shanehe2aa9d72009-11-06 17:20:17 +00001850 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001851 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001852 }else
1853
drh9ff849f2009-02-04 20:55:57 +00001854 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001855 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001856 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00001857 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1858 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00001859 }else{
shane9bd1b442009-10-23 01:27:39 +00001860 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00001861 fclose(alt);
1862 }
1863 }else
1864
shanehe2aa9d72009-11-06 17:20:17 +00001865 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001866 const char *zSrcFile;
1867 const char *zDb;
1868 sqlite3 *pSrc;
1869 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00001870 int nTimeout = 0;
1871
drh9ff849f2009-02-04 20:55:57 +00001872 if( nArg==2 ){
1873 zSrcFile = azArg[1];
1874 zDb = "main";
1875 }else{
1876 zSrcFile = azArg[2];
1877 zDb = azArg[1];
1878 }
1879 rc = sqlite3_open(zSrcFile, &pSrc);
1880 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001881 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00001882 sqlite3_close(pSrc);
1883 return 1;
1884 }
drhdc2c4912009-02-04 22:46:47 +00001885 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001886 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
1887 if( pBackup==0 ){
1888 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1889 sqlite3_close(pSrc);
1890 return 1;
1891 }
drhdc2c4912009-02-04 22:46:47 +00001892 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
1893 || rc==SQLITE_BUSY ){
1894 if( rc==SQLITE_BUSY ){
1895 if( nTimeout++ >= 3 ) break;
1896 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00001897 }
1898 }
1899 sqlite3_backup_finish(pBackup);
1900 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001901 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00001902 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00001903 fprintf(stderr, "Error: source database is busy\n");
1904 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001905 }else{
1906 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00001907 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001908 }
1909 sqlite3_close(pSrc);
1910 }else
1911
shanehe2aa9d72009-11-06 17:20:17 +00001912 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001913 struct callback_data data;
1914 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001915 open_db(p);
drh75897232000-05-29 14:26:00 +00001916 memcpy(&data, p, sizeof(data));
1917 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001918 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001919 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001920 int i;
shane7d3846a2008-12-11 02:58:26 +00001921 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00001922 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001923 char *new_argv[2], *new_colv[2];
1924 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1925 " type text,\n"
1926 " name text,\n"
1927 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001928 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001929 " sql text\n"
1930 ")";
1931 new_argv[1] = 0;
1932 new_colv[0] = "sql";
1933 new_colv[1] = 0;
1934 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00001935 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00001936 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001937 char *new_argv[2], *new_colv[2];
1938 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1939 " type text,\n"
1940 " name text,\n"
1941 " tbl_name text,\n"
1942 " rootpage integer,\n"
1943 " sql text\n"
1944 ")";
1945 new_argv[1] = 0;
1946 new_colv[0] = "sql";
1947 new_colv[1] = 0;
1948 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00001949 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00001950 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001951 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00001952 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001953 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00001954 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
1955 " FROM sqlite_master UNION ALL"
1956 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001957 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001958 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001959 callback, &data, &zErrMsg);
1960 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001961 }
drh75897232000-05-29 14:26:00 +00001962 }else{
shane9bd1b442009-10-23 01:27:39 +00001963 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001964 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00001965 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
1966 " FROM sqlite_master UNION ALL"
1967 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001968 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001969 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001970 callback, &data, &zErrMsg
1971 );
drh75897232000-05-29 14:26:00 +00001972 }
drh75897232000-05-29 14:26:00 +00001973 if( zErrMsg ){
1974 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001975 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001976 rc = 1;
1977 }else if( rc != SQLITE_OK ){
1978 fprintf(stderr,"Error: querying schema information\n");
1979 rc = 1;
1980 }else{
1981 rc = 0;
drh75897232000-05-29 14:26:00 +00001982 }
1983 }else
1984
1985 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001986 sqlite3_snprintf(sizeof(p->separator), p->separator,
1987 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001988 }else
1989
shanehe2aa9d72009-11-06 17:20:17 +00001990 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001991 int i;
1992 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001993 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001994 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001995 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001996 fprintf(p->out,"%9.9s: ", "nullvalue");
1997 output_c_string(p->out, p->nullvalue);
1998 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001999 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002000 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002001 fprintf(p->out,"%9.9s: ", "separator");
2002 output_c_string(p->out, p->separator);
2003 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002004 fprintf(p->out,"%9.9s: ","width");
2005 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002006 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002007 }
drhfeac5f82004-08-01 00:10:45 +00002008 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002009 }else
2010
shanehe2aa9d72009-11-06 17:20:17 +00002011 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002012 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002013 int nRow;
drhe3710332000-09-29 13:30:53 +00002014 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002015 open_db(p);
drha50da102000-08-08 20:19:09 +00002016 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002017 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002018 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002019 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002020 "UNION ALL "
2021 "SELECT name FROM sqlite_temp_master "
2022 "WHERE type IN ('table','view') "
2023 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002024 &azResult, &nRow, 0, &zErrMsg
2025 );
drha50da102000-08-08 20:19:09 +00002026 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002027 zShellStatic = azArg[1];
2028 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002029 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002030 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002031 "UNION ALL "
2032 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002033 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002034 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002035 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002036 );
danielk1977bc6ada42004-06-30 08:20:16 +00002037 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002038 }
drh75897232000-05-29 14:26:00 +00002039 if( zErrMsg ){
2040 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002041 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002042 rc = 1;
2043 }else if( rc != SQLITE_OK ){
2044 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2045 rc = 1;
2046 }else{
drhe3710332000-09-29 13:30:53 +00002047 int len, maxlen = 0;
2048 int i, j;
2049 int nPrintCol, nPrintRow;
2050 for(i=1; i<=nRow; i++){
2051 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002052 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002053 if( len>maxlen ) maxlen = len;
2054 }
2055 nPrintCol = 80/(maxlen+2);
2056 if( nPrintCol<1 ) nPrintCol = 1;
2057 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2058 for(i=0; i<nPrintRow; i++){
2059 for(j=i+1; j<=nRow; j+=nPrintRow){
2060 char *zSp = j<=nPrintRow ? "" : " ";
2061 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2062 }
2063 printf("\n");
2064 }
2065 }
danielk19776f8a5032004-05-10 10:34:51 +00002066 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002067 }else
2068
shanehe2aa9d72009-11-06 17:20:17 +00002069 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002070 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002071 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002072 }else
2073
2074 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
drh3b1a9882007-11-02 12:53:03 +00002075 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002076 }else
2077
2078 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002079 int j;
drh43617e92006-03-06 20:55:46 +00002080 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002081 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2082 p->colWidth[j-1] = atoi(azArg[j]);
2083 }
2084 }else
2085
2086 {
shane9bd1b442009-10-23 01:27:39 +00002087 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002088 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002089 rc = 1;
drh75897232000-05-29 14:26:00 +00002090 }
drh67505e72002-04-19 12:34:06 +00002091
2092 return rc;
drh75897232000-05-29 14:26:00 +00002093}
2094
drh67505e72002-04-19 12:34:06 +00002095/*
drh91a66392007-09-07 01:12:32 +00002096** Return TRUE if a semicolon occurs anywhere in the first N characters
2097** of string z[].
drh324ccef2003-02-05 14:06:20 +00002098*/
drh91a66392007-09-07 01:12:32 +00002099static int _contains_semicolon(const char *z, int N){
2100 int i;
2101 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2102 return 0;
drh324ccef2003-02-05 14:06:20 +00002103}
2104
2105/*
drh70c7a4b2003-04-26 03:03:06 +00002106** Test to see if a line consists entirely of whitespace.
2107*/
2108static int _all_whitespace(const char *z){
2109 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002110 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002111 if( *z=='/' && z[1]=='*' ){
2112 z += 2;
2113 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2114 if( *z==0 ) return 0;
2115 z++;
2116 continue;
2117 }
2118 if( *z=='-' && z[1]=='-' ){
2119 z += 2;
2120 while( *z && *z!='\n' ){ z++; }
2121 if( *z==0 ) return 1;
2122 continue;
2123 }
2124 return 0;
2125 }
2126 return 1;
2127}
2128
2129/*
drha9b17162003-04-29 18:01:28 +00002130** Return TRUE if the line typed in is an SQL command terminator other
2131** than a semi-colon. The SQL Server style "go" command is understood
2132** as is the Oracle "/".
2133*/
2134static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002135 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002136 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2137 return 1; /* Oracle */
2138 }
drhc8d74412004-08-31 23:41:26 +00002139 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2140 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002141 return 1; /* SQL Server */
2142 }
2143 return 0;
2144}
2145
2146/*
drh233a5312008-12-18 22:25:13 +00002147** Return true if zSql is a complete SQL statement. Return false if it
2148** ends in the middle of a string literal or C-style comment.
2149*/
2150static int _is_complete(char *zSql, int nSql){
2151 int rc;
2152 if( zSql==0 ) return 1;
2153 zSql[nSql] = ';';
2154 zSql[nSql+1] = 0;
2155 rc = sqlite3_complete(zSql);
2156 zSql[nSql] = 0;
2157 return rc;
2158}
2159
2160/*
drh67505e72002-04-19 12:34:06 +00002161** Read input from *in and process it. If *in==0 then input
2162** is interactive - the user is typing it it. Otherwise, input
2163** is coming from a file or device. A prompt is issued and history
2164** is saved only if input is interactive. An interrupt signal will
2165** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002166**
2167** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002168*/
drhc28490c2006-10-26 14:25:58 +00002169static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002170 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002171 char *zSql = 0;
2172 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002173 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002174 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002175 int rc;
2176 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002177 int lineno = 0;
2178 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002179
2180 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2181 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002182 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002183 zLine = one_input_line(zSql, in);
2184 if( zLine==0 ){
2185 break; /* We have reached EOF */
2186 }
drh67505e72002-04-19 12:34:06 +00002187 if( seenInterrupt ){
2188 if( in!=0 ) break;
2189 seenInterrupt = 0;
2190 }
drhc28490c2006-10-26 14:25:58 +00002191 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002192 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002193 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002194 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002195 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002196 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002197 break;
2198 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002199 errCnt++;
2200 }
drhdaffd0e2001-04-11 14:28:42 +00002201 continue;
2202 }
drh233a5312008-12-18 22:25:13 +00002203 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002204 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002205 }
drh91a66392007-09-07 01:12:32 +00002206 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002207 if( zSql==0 ){
2208 int i;
drh4c755c02004-08-08 20:22:17 +00002209 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002210 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002211 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002212 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002213 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002214 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002215 exit(1);
2216 }
drh5bb3eb92007-05-04 13:15:55 +00002217 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002218 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002219 }
2220 }else{
drh4f21c4a2008-12-10 22:15:00 +00002221 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002222 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002223 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002224 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002225 exit(1);
2226 }
drh5bb3eb92007-05-04 13:15:55 +00002227 zSql[nSql++] = '\n';
2228 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002229 nSql += len;
2230 }
drh91a66392007-09-07 01:12:32 +00002231 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2232 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002233 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002234 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002235 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002236 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002237 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002238 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002239 char zPrefix[100];
2240 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002241 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002242 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002243 }else{
shane9bd1b442009-10-23 01:27:39 +00002244 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002245 }
drh7f953e22002-07-13 17:33:45 +00002246 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002247 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002248 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002249 zErrMsg = 0;
2250 }else{
shaned2bed1c2009-10-21 03:56:54 +00002251 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002252 }
drhc49f44e2006-10-26 18:15:42 +00002253 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002254 }
2255 free(zSql);
2256 zSql = 0;
2257 nSql = 0;
2258 }
2259 }
2260 if( zSql ){
shane86f5bdb2009-10-24 02:00:07 +00002261 if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002262 free(zSql);
2263 }
danielk19772ac27622007-07-03 05:31:16 +00002264 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002265 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002266}
2267
drh67505e72002-04-19 12:34:06 +00002268/*
2269** Return a pathname which is the user's home directory. A
2270** 0 return indicates an error of some kind. Space to hold the
2271** resulting string is obtained from malloc(). The calling
2272** function should free the result.
2273*/
2274static char *find_home_dir(void){
2275 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002276
chw97185482008-11-17 08:05:31 +00002277#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002278 struct passwd *pwent;
2279 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002280 if( (pwent=getpwuid(uid)) != NULL) {
2281 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002282 }
2283#endif
2284
chw65d3c132007-11-12 21:09:10 +00002285#if defined(_WIN32_WCE)
2286 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2287 */
2288 home_dir = strdup("/");
2289#else
2290
drh164a1b62006-08-19 11:15:20 +00002291#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2292 if (!home_dir) {
2293 home_dir = getenv("USERPROFILE");
2294 }
2295#endif
2296
drh67505e72002-04-19 12:34:06 +00002297 if (!home_dir) {
2298 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002299 }
2300
drhcdb36b72006-06-12 12:57:45 +00002301#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002302 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002303 char *zDrive, *zPath;
2304 int n;
2305 zDrive = getenv("HOMEDRIVE");
2306 zPath = getenv("HOMEPATH");
2307 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002308 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002309 home_dir = malloc( n );
2310 if( home_dir==0 ) return 0;
2311 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2312 return home_dir;
2313 }
2314 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002315 }
2316#endif
2317
chw65d3c132007-11-12 21:09:10 +00002318#endif /* !_WIN32_WCE */
2319
drh67505e72002-04-19 12:34:06 +00002320 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002321 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002322 char *z = malloc( n );
2323 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002324 home_dir = z;
2325 }
drhe98d4fa2002-04-21 19:06:22 +00002326
drh67505e72002-04-19 12:34:06 +00002327 return home_dir;
2328}
2329
2330/*
2331** Read input from the file given by sqliterc_override. Or if that
2332** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002333**
2334** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002335*/
shane9bd1b442009-10-23 01:27:39 +00002336static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002337 struct callback_data *p, /* Configuration data */
2338 const char *sqliterc_override /* Name of config file. NULL to use default */
2339){
persicom7e2dfdd2002-04-18 02:46:52 +00002340 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002341 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002342 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002343 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002344 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002345 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002346
2347 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002348 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002349 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002350#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002351 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002352#endif
shane9bd1b442009-10-23 01:27:39 +00002353 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002354 }
drh4f21c4a2008-12-10 22:15:00 +00002355 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002356 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002357 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002358 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2359 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002360 }
drha959ac42007-06-20 13:10:00 +00002361 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002362 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002363 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002364 }
drha1f9b5e2004-02-14 16:31:02 +00002365 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002366 if( in ){
drhc28490c2006-10-26 14:25:58 +00002367 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002368 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002369 }
shane9bd1b442009-10-23 01:27:39 +00002370 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002371 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002372 }
drh43617e92006-03-06 20:55:46 +00002373 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002374 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002375}
2376
drh67505e72002-04-19 12:34:06 +00002377/*
drhe1e38c42003-05-04 18:30:59 +00002378** Show available command line options
2379*/
2380static const char zOptions[] =
shaneh5fc25012009-11-11 04:17:07 +00002381 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002382 " -init filename read/process named file\n"
2383 " -echo print commands before execution\n"
2384 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002385 " -bail stop after hitting an error\n"
2386 " -interactive force interactive I/O\n"
2387 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002388 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002389 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002390 " -html set output mode to HTML\n"
2391 " -line set output mode to 'line'\n"
2392 " -list set output mode to 'list'\n"
2393 " -separator 'x' set output field separator (|)\n"
2394 " -nullvalue 'text' set text string for NULL values\n"
2395 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002396;
2397static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002398 fprintf(stderr,
2399 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2400 "FILENAME is the name of an SQLite database. A new database is created\n"
2401 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002402 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002403 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002404 }else{
2405 fprintf(stderr, "Use the -help option for additional information\n");
2406 }
2407 exit(1);
2408}
2409
2410/*
drh67505e72002-04-19 12:34:06 +00002411** Initialize the state information in data
2412*/
drh0850b532006-01-31 19:31:43 +00002413static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002414 memset(data, 0, sizeof(*data));
2415 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002416 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002417 data->showHeader = 0;
drh127f9d72010-02-23 01:47:00 +00002418 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002419 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2420 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002421 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002422}
2423
drh75897232000-05-29 14:26:00 +00002424int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002425 char *zErrMsg = 0;
2426 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002427 const char *zInitFile = 0;
2428 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002429 int i;
drhc28490c2006-10-26 14:25:58 +00002430 int rc = 0;
drh75897232000-05-29 14:26:00 +00002431
drhdaffd0e2001-04-11 14:28:42 +00002432 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002433 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002434 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002435
drh44c2eb12003-04-30 11:38:26 +00002436 /* Make sure we have a valid signal handler early, before anything
2437 ** else is done.
2438 */
drh4c504392000-10-16 22:06:40 +00002439#ifdef SIGINT
2440 signal(SIGINT, interrupt_handler);
2441#endif
drh44c2eb12003-04-30 11:38:26 +00002442
drh22fbcb82004-02-01 01:22:50 +00002443 /* Do an initial pass through the command-line argument to locate
2444 ** the name of the database file, the name of the initialization file,
2445 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002446 */
drh22fbcb82004-02-01 01:22:50 +00002447 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002448 char *z;
drh44c2eb12003-04-30 11:38:26 +00002449 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002450 z = argv[i];
2451 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002452 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2453 i++;
drh22fbcb82004-02-01 01:22:50 +00002454 }else if( strcmp(argv[i],"-init")==0 ){
2455 i++;
2456 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002457 /* Need to check for batch mode here to so we can avoid printing
2458 ** informational messages (like from process_sqliterc) before
2459 ** we do the actual processing of arguments later in a second pass.
2460 */
2461 }else if( strcmp(argv[i],"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002462 stdin_is_interactive = 0;
drh44c2eb12003-04-30 11:38:26 +00002463 }
2464 }
drh22fbcb82004-02-01 01:22:50 +00002465 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002466#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002467 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2468#else
drh22fbcb82004-02-01 01:22:50 +00002469 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002470#endif
drh22fbcb82004-02-01 01:22:50 +00002471 }else{
danielk197703aded42004-11-22 05:26:27 +00002472#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002473 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002474#else
2475 data.zDbFilename = 0;
2476#endif
drh22fbcb82004-02-01 01:22:50 +00002477 }
2478 if( i<argc ){
2479 zFirstCmd = argv[i++];
2480 }
shaneh5fc25012009-11-11 04:17:07 +00002481 if( i<argc ){
2482 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2483 fprintf(stderr,"Use -help for a list of options.\n");
2484 return 1;
2485 }
drh44c2eb12003-04-30 11:38:26 +00002486 data.out = stdout;
2487
drh01b41712005-08-29 23:06:23 +00002488#ifdef SQLITE_OMIT_MEMORYDB
2489 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002490 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2491 return 1;
drh01b41712005-08-29 23:06:23 +00002492 }
2493#endif
2494
drh44c2eb12003-04-30 11:38:26 +00002495 /* Go ahead and open the database file if it already exists. If the
2496 ** file does not exist, delay opening it. This prevents empty database
2497 ** files from being created if a user mistypes the database name argument
2498 ** to the sqlite command-line tool.
2499 */
drhc8d74412004-08-31 23:41:26 +00002500 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002501 open_db(&data);
2502 }
2503
drh22fbcb82004-02-01 01:22:50 +00002504 /* Process the initialization file if there is one. If no -init option
2505 ** is given on the command line, look for a file named ~/.sqliterc and
2506 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002507 */
shane86f5bdb2009-10-24 02:00:07 +00002508 rc = process_sqliterc(&data,zInitFile);
2509 if( rc>0 ){
2510 return rc;
2511 }
drh44c2eb12003-04-30 11:38:26 +00002512
drh22fbcb82004-02-01 01:22:50 +00002513 /* Make a second pass through the command-line argument and set
2514 ** options. This second pass is delayed until after the initialization
2515 ** file is processed so that the command-line arguments will override
2516 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002517 */
drh22fbcb82004-02-01 01:22:50 +00002518 for(i=1; i<argc && argv[i][0]=='-'; i++){
2519 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002520 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002521 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002522 i++;
2523 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002524 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002525 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002526 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002527 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002528 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002529 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002530 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002531 }else if( strcmp(z,"-csv")==0 ){
2532 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002533 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002534 }else if( strcmp(z,"-separator")==0 ){
2535 i++;
shaneh5fc25012009-11-11 04:17:07 +00002536 if(i>=argc){
2537 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2538 fprintf(stderr,"Use -help for a list of options.\n");
2539 return 1;
2540 }
drh5bb3eb92007-05-04 13:15:55 +00002541 sqlite3_snprintf(sizeof(data.separator), data.separator,
2542 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002543 }else if( strcmp(z,"-nullvalue")==0 ){
2544 i++;
shaneh5fc25012009-11-11 04:17:07 +00002545 if(i>=argc){
2546 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2547 fprintf(stderr,"Use -help for a list of options.\n");
2548 return 1;
2549 }
drh5bb3eb92007-05-04 13:15:55 +00002550 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2551 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002552 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002553 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002554 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002555 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002556 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002557 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002558 }else if( strcmp(z,"-bail")==0 ){
2559 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002560 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002561 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002562 return 0;
drhc28490c2006-10-26 14:25:58 +00002563 }else if( strcmp(z,"-interactive")==0 ){
2564 stdin_is_interactive = 1;
2565 }else if( strcmp(z,"-batch")==0 ){
2566 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002567 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002568 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002569 }else{
shane86f5bdb2009-10-24 02:00:07 +00002570 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002571 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002572 return 1;
2573 }
2574 }
drh44c2eb12003-04-30 11:38:26 +00002575
drh22fbcb82004-02-01 01:22:50 +00002576 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002577 /* Run just the command that follows the database name
2578 */
drh22fbcb82004-02-01 01:22:50 +00002579 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00002580 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002581 }else{
drh44c2eb12003-04-30 11:38:26 +00002582 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00002583 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00002584 if( zErrMsg!=0 ){
2585 fprintf(stderr,"Error: %s\n", zErrMsg);
2586 return rc!=0 ? rc : 1;
2587 }else if( rc!=0 ){
2588 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
2589 return rc;
drh6ff13852001-11-25 13:18:23 +00002590 }
drh75897232000-05-29 14:26:00 +00002591 }
2592 }else{
drh44c2eb12003-04-30 11:38:26 +00002593 /* Run commands received from standard input
2594 */
drhc28490c2006-10-26 14:25:58 +00002595 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002596 char *zHome;
2597 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002598 int nHistory;
drh75897232000-05-29 14:26:00 +00002599 printf(
drhb217a572000-08-22 13:40:18 +00002600 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002601 "Enter \".help\" for instructions\n"
2602 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002603 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002604 );
drh67505e72002-04-19 12:34:06 +00002605 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002606 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002607 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002608 if( (zHistory = malloc(nHistory))!=0 ){
2609 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2610 }
drh67505e72002-04-19 12:34:06 +00002611 }
danielk19774af00c62005-01-23 23:43:21 +00002612#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002613 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002614#endif
drhc28490c2006-10-26 14:25:58 +00002615 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002616 if( zHistory ){
2617 stifle_history(100);
2618 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002619 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002620 }
adamd0a3daa32006-07-28 20:16:14 +00002621 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002622 }else{
drhc28490c2006-10-26 14:25:58 +00002623 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002624 }
2625 }
drh33048c02001-10-01 14:29:22 +00002626 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00002627 if( data.db ){
2628 if( sqlite3_close(data.db)!=SQLITE_OK ){
2629 fprintf(stderr,"Error: cannot close database \"%s\"\n",
2630 sqlite3_errmsg(db));
shane86f5bdb2009-10-24 02:00:07 +00002631 rc++;
adamd0a3daa32006-07-28 20:16:14 +00002632 }
2633 }
drhc28490c2006-10-26 14:25:58 +00002634 return rc;
drh75897232000-05-29 14:26:00 +00002635}