blob: 82bb20f5e0ca268fdc2ee45765f47d2eb301ad0a [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
drh81d7fd12010-12-08 00:02:26 +000041#ifdef HAVE_EDITLINE
42# include <editline/editline.h>
43#endif
drh16e59552000-07-31 11:57:37 +000044#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000045# include <readline/readline.h>
46# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000047#endif
48#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
drh9347b202003-07-18 01:30:59 +000049# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000050# define add_history(X)
drh67505e72002-04-19 12:34:06 +000051# define read_history(X)
52# define write_history(X)
53# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000054#endif
55
adamd2e8464a2006-09-06 21:39:40 +000056#if defined(_WIN32) || defined(WIN32)
57# include <io.h>
shane18e526c2008-12-10 22:30:24 +000058#define isatty(h) _isatty(h)
59#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000060#else
drh4328c8b2003-04-26 02:50:11 +000061/* Make sure isatty() has a prototype.
62*/
63extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000064#endif
drh4328c8b2003-04-26 02:50:11 +000065
chw65d3c132007-11-12 21:09:10 +000066#if defined(_WIN32_WCE)
67/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
68 * thus we always assume that we have a console. That can be
69 * overridden with the -batch command line option.
70 */
71#define isatty(x) 1
72#endif
73
chw97185482008-11-17 08:05:31 +000074#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000075#include <sys/time.h>
76#include <sys/resource.h>
77
drhda108222009-02-25 19:07:24 +000078/* Saved resource information for the beginning of an operation */
79static struct rusage sBegin;
80
81/* True if the timer is enabled */
82static int enableTimer = 0;
83
84/*
85** Begin timing an operation
86*/
87static void beginTimer(void){
88 if( enableTimer ){
89 getrusage(RUSAGE_SELF, &sBegin);
90 }
91}
92
93/* Return the difference of two time_structs in seconds */
94static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
95 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
96 (double)(pEnd->tv_sec - pStart->tv_sec);
97}
98
99/*
100** Print the timing results.
101*/
102static void endTimer(void){
103 if( enableTimer ){
104 struct rusage sEnd;
105 getrusage(RUSAGE_SELF, &sEnd);
106 printf("CPU Time: user %f sys %f\n",
107 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
108 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
109 }
110}
shaneb320ccd2009-10-21 03:42:58 +0000111
drhda108222009-02-25 19:07:24 +0000112#define BEGIN_TIMER beginTimer()
113#define END_TIMER endTimer()
114#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000115
116#elif (defined(_WIN32) || defined(WIN32))
117
118#include <windows.h>
119
120/* Saved resource information for the beginning of an operation */
121static HANDLE hProcess;
122static FILETIME ftKernelBegin;
123static FILETIME ftUserBegin;
124typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
125static GETPROCTIMES getProcessTimesAddr = NULL;
126
127/* True if the timer is enabled */
128static int enableTimer = 0;
129
130/*
131** Check to see if we have timer support. Return 1 if necessary
132** support found (or found previously).
133*/
134static int hasTimer(void){
135 if( getProcessTimesAddr ){
136 return 1;
137 } else {
138 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
139 ** See if the version we are running on has it, and if it does, save off
140 ** a pointer to it and the current process handle.
141 */
142 hProcess = GetCurrentProcess();
143 if( hProcess ){
144 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
145 if( NULL != hinstLib ){
146 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
147 if( NULL != getProcessTimesAddr ){
148 return 1;
149 }
150 FreeLibrary(hinstLib);
151 }
152 }
153 }
154 return 0;
155}
156
157/*
158** Begin timing an operation
159*/
160static void beginTimer(void){
161 if( enableTimer && getProcessTimesAddr ){
162 FILETIME ftCreation, ftExit;
163 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
164 }
165}
166
167/* Return the difference of two FILETIME structs in seconds */
168static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
169 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
170 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
171 return (double) ((i64End - i64Start) / 10000000.0);
172}
173
174/*
175** Print the timing results.
176*/
177static void endTimer(void){
178 if( enableTimer && getProcessTimesAddr){
179 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
180 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
181 printf("CPU Time: user %f sys %f\n",
182 timeDiff(&ftUserBegin, &ftUserEnd),
183 timeDiff(&ftKernelBegin, &ftKernelEnd));
184 }
185}
186
187#define BEGIN_TIMER beginTimer()
188#define END_TIMER endTimer()
189#define HAS_TIMER hasTimer()
190
drhda108222009-02-25 19:07:24 +0000191#else
192#define BEGIN_TIMER
193#define END_TIMER
194#define HAS_TIMER 0
195#endif
196
shanec0688ea2009-03-05 03:48:06 +0000197/*
198** Used to prevent warnings about unused parameters
199*/
200#define UNUSED_PARAMETER(x) (void)(x)
201
drhe91d16b2008-12-08 18:27:31 +0000202/*
drhc49f44e2006-10-26 18:15:42 +0000203** If the following flag is set, then command execution stops
204** at an error if we are not interactive.
205*/
206static int bail_on_error = 0;
207
208/*
drhc28490c2006-10-26 14:25:58 +0000209** Threat stdin as an interactive input if the following variable
210** is true. Otherwise, assume stdin is connected to a file or pipe.
211*/
212static int stdin_is_interactive = 1;
213
214/*
drh4c504392000-10-16 22:06:40 +0000215** The following is the open SQLite database. We make a pointer
216** to this database a static variable so that it can be accessed
217** by the SIGINT handler to interrupt database processing.
218*/
danielk197792f9a1b2004-06-19 09:08:16 +0000219static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000220
221/*
drh67505e72002-04-19 12:34:06 +0000222** True if an interrupt (Control-C) has been received.
223*/
drh43617e92006-03-06 20:55:46 +0000224static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000225
226/*
persicom7e2dfdd2002-04-18 02:46:52 +0000227** This is the name of our program. It is set in main(), used
228** in a number of other places, mostly for error messages.
229*/
230static char *Argv0;
231
232/*
233** Prompt strings. Initialized in main. Settable with
234** .prompt main continue
235*/
236static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
237static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
238
drhb0603412007-02-28 04:47:26 +0000239/*
240** Write I/O traces to the following stream.
241*/
rsebe0a9092007-07-30 18:24:38 +0000242#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000243static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000244#endif
drhb0603412007-02-28 04:47:26 +0000245
246/*
247** This routine works like printf in that its first argument is a
248** format string and subsequent arguments are values to be substituted
249** in place of % fields. The result of formatting this string
250** is written to iotrace.
251*/
rsebe0a9092007-07-30 18:24:38 +0000252#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000253static void iotracePrintf(const char *zFormat, ...){
254 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000255 char *z;
drhb0603412007-02-28 04:47:26 +0000256 if( iotrace==0 ) return;
257 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000258 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000259 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000260 fprintf(iotrace, "%s", z);
261 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000262}
rsebe0a9092007-07-30 18:24:38 +0000263#endif
drhb0603412007-02-28 04:47:26 +0000264
drh44c2eb12003-04-30 11:38:26 +0000265
persicom7e2dfdd2002-04-18 02:46:52 +0000266/*
drh83965662003-04-17 02:54:13 +0000267** Determines if a string is a number of not.
268*/
danielk19772e588c72005-12-09 14:25:08 +0000269static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000270 if( *z=='-' || *z=='+' ) z++;
271 if( !isdigit(*z) ){
272 return 0;
273 }
274 z++;
275 if( realnum ) *realnum = 0;
276 while( isdigit(*z) ){ z++; }
277 if( *z=='.' ){
278 z++;
279 if( !isdigit(*z) ) return 0;
280 while( isdigit(*z) ){ z++; }
281 if( realnum ) *realnum = 1;
282 }
283 if( *z=='e' || *z=='E' ){
284 z++;
285 if( *z=='+' || *z=='-' ) z++;
286 if( !isdigit(*z) ) return 0;
287 while( isdigit(*z) ){ z++; }
288 if( realnum ) *realnum = 1;
289 }
290 return *z==0;
291}
drh83965662003-04-17 02:54:13 +0000292
293/*
danielk1977bc6ada42004-06-30 08:20:16 +0000294** A global char* and an SQL function to access its current value
295** from within an SQL statement. This program used to use the
296** sqlite_exec_printf() API to substitue a string into an SQL statement.
297** The correct way to do this with sqlite3 is to use the bind API, but
298** since the shell is built around the callback paradigm it would be a lot
299** of work. Instead just use this hack, which is quite harmless.
300*/
301static const char *zShellStatic = 0;
302static void shellstaticFunc(
303 sqlite3_context *context,
304 int argc,
305 sqlite3_value **argv
306){
307 assert( 0==argc );
308 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000309 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000310 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000311 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
312}
313
314
315/*
drhfeac5f82004-08-01 00:10:45 +0000316** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000317** the text in memory obtained from malloc() and returns a pointer
318** to the text. NULL is returned at end of file, or if malloc()
319** fails.
320**
321** The interface is like "readline" but no command-line editing
322** is done.
323*/
drh9347b202003-07-18 01:30:59 +0000324static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000325 char *zLine;
326 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000327 int n;
328 int eol;
329
330 if( zPrompt && *zPrompt ){
331 printf("%s",zPrompt);
332 fflush(stdout);
333 }
334 nLine = 100;
335 zLine = malloc( nLine );
336 if( zLine==0 ) return 0;
337 n = 0;
338 eol = 0;
339 while( !eol ){
340 if( n+100>nLine ){
341 nLine = nLine*2 + 100;
342 zLine = realloc(zLine, nLine);
343 if( zLine==0 ) return 0;
344 }
drhdaffd0e2001-04-11 14:28:42 +0000345 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000346 if( n==0 ){
347 free(zLine);
348 return 0;
349 }
350 zLine[n] = 0;
351 eol = 1;
352 break;
353 }
354 while( zLine[n] ){ n++; }
355 if( n>0 && zLine[n-1]=='\n' ){
356 n--;
shaneh13b36022009-12-17 21:07:15 +0000357 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000358 zLine[n] = 0;
359 eol = 1;
360 }
361 }
362 zLine = realloc( zLine, n+1 );
363 return zLine;
364}
365
366/*
drhc28490c2006-10-26 14:25:58 +0000367** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000368**
369** zPrior is a string of prior text retrieved. If not the empty
370** string, then issue a continuation prompt.
371*/
drhdaffd0e2001-04-11 14:28:42 +0000372static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000373 char *zPrompt;
374 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000375 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000376 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000377 }
378 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000379 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000380 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000381 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000382 }
383 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000384#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000385 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000386#endif
drh8e7e7a22000-05-30 18:45:23 +0000387 return zResult;
388}
389
persicom7e2dfdd2002-04-18 02:46:52 +0000390struct previous_mode_data {
391 int valid; /* Is there legit data in here? */
392 int mode;
393 int showHeader;
394 int colWidth[100];
395};
drh45e29d82006-11-20 16:21:10 +0000396
drh8e7e7a22000-05-30 18:45:23 +0000397/*
drh75897232000-05-29 14:26:00 +0000398** An pointer to an instance of this structure is passed from
399** the main program to the callback. This is used to communicate
400** state and mode information.
401*/
402struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000403 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000404 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000405 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000406 int cnt; /* Number of records displayed so far */
407 FILE *out; /* Write results here */
408 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000409 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000410 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000411 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000412 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000413 int colWidth[100]; /* Requested width of each column when in column mode*/
414 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000415 char nullvalue[20]; /* The text to print when a NULL comes back from
416 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000417 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000418 /* Holds the mode information just before
419 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000420 char outfile[FILENAME_MAX]; /* Filename for *out */
421 const char *zDbFilename; /* name of the database file */
shane626a6e42009-10-22 17:30:15 +0000422 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000423 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000424};
425
426/*
427** These are the allowed modes.
428*/
drh967e8b72000-06-21 13:59:10 +0000429#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000430#define MODE_Column 1 /* One record per line in neat columns */
431#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000432#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
433#define MODE_Html 4 /* Generate an XHTML table */
434#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000435#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000436#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000437#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000438
drh66ce4d02008-02-15 17:38:06 +0000439static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000440 "line",
441 "column",
442 "list",
443 "semi",
444 "html",
drhfeac5f82004-08-01 00:10:45 +0000445 "insert",
446 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000447 "csv",
drh66ce4d02008-02-15 17:38:06 +0000448 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000449};
drh75897232000-05-29 14:26:00 +0000450
451/*
452** Number of elements in an array
453*/
drh902b9ee2008-12-05 17:17:07 +0000454#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000455
456/*
drhea678832008-12-10 19:26:22 +0000457** Compute a string length that is limited to what can be stored in
458** lower 30 bits of a 32-bit signed integer.
459*/
drh4f21c4a2008-12-10 22:15:00 +0000460static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000461 const char *z2 = z;
462 while( *z2 ){ z2++; }
463 return 0x3fffffff & (int)(z2 - z);
464}
465
466/*
drh127f9d72010-02-23 01:47:00 +0000467** A callback for the sqlite3_log() interface.
468*/
469static void shellLog(void *pArg, int iErrCode, const char *zMsg){
470 struct callback_data *p = (struct callback_data*)pArg;
471 if( p->pLog==0 ) return;
472 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
473 fflush(p->pLog);
474}
475
476/*
shane626a6e42009-10-22 17:30:15 +0000477** Output the given string as a hex-encoded blob (eg. X'1234' )
478*/
479static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
480 int i;
481 char *zBlob = (char *)pBlob;
482 fprintf(out,"X'");
483 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
484 fprintf(out,"'");
485}
486
487/*
drh28bd4bc2000-06-15 15:57:22 +0000488** Output the given string as a quoted string using SQL quoting conventions.
489*/
490static void output_quoted_string(FILE *out, const char *z){
491 int i;
492 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000493 for(i=0; z[i]; i++){
494 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000495 }
496 if( nSingle==0 ){
497 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000498 }else{
499 fprintf(out,"'");
500 while( *z ){
501 for(i=0; z[i] && z[i]!='\''; i++){}
502 if( i==0 ){
503 fprintf(out,"''");
504 z++;
505 }else if( z[i]=='\'' ){
506 fprintf(out,"%.*s''",i,z);
507 z += i+1;
508 }else{
drhcd7d2732002-02-26 23:24:26 +0000509 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000510 break;
511 }
512 }
drhcd7d2732002-02-26 23:24:26 +0000513 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000514 }
515}
516
517/*
drhfeac5f82004-08-01 00:10:45 +0000518** Output the given string as a quoted according to C or TCL quoting rules.
519*/
520static void output_c_string(FILE *out, const char *z){
521 unsigned int c;
522 fputc('"', out);
523 while( (c = *(z++))!=0 ){
524 if( c=='\\' ){
525 fputc(c, out);
526 fputc(c, out);
527 }else if( c=='\t' ){
528 fputc('\\', out);
529 fputc('t', out);
530 }else if( c=='\n' ){
531 fputc('\\', out);
532 fputc('n', out);
533 }else if( c=='\r' ){
534 fputc('\\', out);
535 fputc('r', out);
536 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000537 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000538 }else{
539 fputc(c, out);
540 }
541 }
542 fputc('"', out);
543}
544
545/*
drhc08a4f12000-06-15 16:49:48 +0000546** Output the given string with characters that are special to
547** HTML escaped.
548*/
549static void output_html_string(FILE *out, const char *z){
550 int i;
551 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000552 for(i=0; z[i]
553 && z[i]!='<'
554 && z[i]!='&'
555 && z[i]!='>'
556 && z[i]!='\"'
557 && z[i]!='\'';
558 i++){}
drhc08a4f12000-06-15 16:49:48 +0000559 if( i>0 ){
560 fprintf(out,"%.*s",i,z);
561 }
562 if( z[i]=='<' ){
563 fprintf(out,"&lt;");
564 }else if( z[i]=='&' ){
565 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000566 }else if( z[i]=='>' ){
567 fprintf(out,"&gt;");
568 }else if( z[i]=='\"' ){
569 fprintf(out,"&quot;");
570 }else if( z[i]=='\'' ){
571 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000572 }else{
573 break;
574 }
575 z += i + 1;
576 }
577}
578
579/*
drhc49f44e2006-10-26 18:15:42 +0000580** If a field contains any character identified by a 1 in the following
581** array, then the string must be quoted for CSV.
582*/
583static const char needCsvQuote[] = {
584 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
585 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
586 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
587 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
588 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
591 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
592 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
593 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
594 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
595 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
596 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
597 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
598 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
599 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
600};
601
602/*
drh8e64d1c2004-10-07 00:32:39 +0000603** Output a single term of CSV. Actually, p->separator is used for
604** the separator, which may or may not be a comma. p->nullvalue is
605** the null value. Strings are quoted using ANSI-C rules. Numbers
606** appear outside of quotes.
607*/
608static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000609 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000610 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000611 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000612 }else{
drhc49f44e2006-10-26 18:15:42 +0000613 int i;
drh4f21c4a2008-12-10 22:15:00 +0000614 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000615 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000616 if( needCsvQuote[((unsigned char*)z)[i]]
617 || (z[i]==p->separator[0] &&
618 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000619 i = 0;
620 break;
621 }
622 }
623 if( i==0 ){
624 putc('"', out);
625 for(i=0; z[i]; i++){
626 if( z[i]=='"' ) putc('"', out);
627 putc(z[i], out);
628 }
629 putc('"', out);
630 }else{
631 fprintf(out, "%s", z);
632 }
drh8e64d1c2004-10-07 00:32:39 +0000633 }
634 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000635 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000636 }
637}
638
danielk19774af00c62005-01-23 23:43:21 +0000639#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000640/*
drh4c504392000-10-16 22:06:40 +0000641** This routine runs when the user presses Ctrl-C
642*/
643static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000644 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000645 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000646 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000647}
danielk19774af00c62005-01-23 23:43:21 +0000648#endif
drh4c504392000-10-16 22:06:40 +0000649
650/*
shane626a6e42009-10-22 17:30:15 +0000651** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000652** invokes for each row of a query result.
653*/
shane626a6e42009-10-22 17:30:15 +0000654static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000655 int i;
656 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000657
drh75897232000-05-29 14:26:00 +0000658 switch( p->mode ){
659 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000660 int w = 5;
drh6a535342001-10-19 16:44:56 +0000661 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000662 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000663 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000664 if( len>w ) w = len;
665 }
drh75897232000-05-29 14:26:00 +0000666 if( p->cnt++>0 ) fprintf(p->out,"\n");
667 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000668 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000669 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000670 }
671 break;
672 }
danielk19770d78bae2008-01-03 07:09:48 +0000673 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000674 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000675 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000676 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000677 int w, n;
678 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000679 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000680 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000681 w = 0;
drh75897232000-05-29 14:26:00 +0000682 }
drha0c66f52000-07-29 13:20:21 +0000683 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000684 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000685 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000686 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000687 if( w<n ) w = n;
688 }
689 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000690 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000691 }
692 if( p->showHeader ){
693 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
694 }
695 }
696 if( p->showHeader ){
697 for(i=0; i<nArg; i++){
698 int w;
699 if( i<ArraySize(p->actualWidth) ){
700 w = p->actualWidth[i];
701 }else{
702 w = 10;
703 }
704 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
705 "----------------------------------------------------------",
706 i==nArg-1 ? "\n": " ");
707 }
drh75897232000-05-29 14:26:00 +0000708 }
709 }
drh6a535342001-10-19 16:44:56 +0000710 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000711 for(i=0; i<nArg; i++){
712 int w;
drha0c66f52000-07-29 13:20:21 +0000713 if( i<ArraySize(p->actualWidth) ){
714 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000715 }else{
716 w = 10;
717 }
drhea678832008-12-10 19:26:22 +0000718 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000719 strlen30(azArg[i])>w ){
720 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000721 }
drhc61053b2000-06-04 12:58:36 +0000722 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000723 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000724 }
725 break;
726 }
drhe3710332000-09-29 13:30:53 +0000727 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000728 case MODE_List: {
729 if( p->cnt++==0 && p->showHeader ){
730 for(i=0; i<nArg; i++){
731 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
732 }
733 }
drh6a535342001-10-19 16:44:56 +0000734 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000735 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000736 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000737 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000738 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000739 if( i<nArg-1 ){
740 fprintf(p->out, "%s", p->separator);
741 }else if( p->mode==MODE_Semi ){
742 fprintf(p->out, ";\n");
743 }else{
744 fprintf(p->out, "\n");
745 }
drh75897232000-05-29 14:26:00 +0000746 }
747 break;
748 }
drh1e5d0e92000-05-31 23:33:17 +0000749 case MODE_Html: {
750 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000751 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000752 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000753 fprintf(p->out,"<TH>");
754 output_html_string(p->out, azCol[i]);
755 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000756 }
mihailim57c591a2008-06-23 21:26:05 +0000757 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000758 }
drh6a535342001-10-19 16:44:56 +0000759 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000760 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000761 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000762 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000763 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000764 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000765 }
mihailim57c591a2008-06-23 21:26:05 +0000766 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000767 break;
768 }
drhfeac5f82004-08-01 00:10:45 +0000769 case MODE_Tcl: {
770 if( p->cnt++==0 && p->showHeader ){
771 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000772 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000773 fprintf(p->out, "%s", p->separator);
774 }
775 fprintf(p->out,"\n");
776 }
777 if( azArg==0 ) break;
778 for(i=0; i<nArg; i++){
779 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
780 fprintf(p->out, "%s", p->separator);
781 }
782 fprintf(p->out,"\n");
783 break;
784 }
drh8e64d1c2004-10-07 00:32:39 +0000785 case MODE_Csv: {
786 if( p->cnt++==0 && p->showHeader ){
787 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000788 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000789 }
790 fprintf(p->out,"\n");
791 }
792 if( azArg==0 ) break;
793 for(i=0; i<nArg; i++){
794 output_csv(p, azArg[i], i<nArg-1);
795 }
796 fprintf(p->out,"\n");
797 break;
798 }
drh28bd4bc2000-06-15 15:57:22 +0000799 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000800 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000801 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000802 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000803 for(i=0; i<nArg; i++){
804 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000805 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000806 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000807 }else if( aiType && aiType[i]==SQLITE_TEXT ){
808 if( zSep[0] ) fprintf(p->out,"%s",zSep);
809 output_quoted_string(p->out, azArg[i]);
810 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
811 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000812 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
813 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
814 int nBlob = sqlite3_column_bytes(p->pStmt, i);
815 if( zSep[0] ) fprintf(p->out,"%s",zSep);
816 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000817 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000818 fprintf(p->out,"%s%s",zSep, azArg[i]);
819 }else{
820 if( zSep[0] ) fprintf(p->out,"%s",zSep);
821 output_quoted_string(p->out, azArg[i]);
822 }
823 }
824 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000825 break;
drh28bd4bc2000-06-15 15:57:22 +0000826 }
persicom1d0b8722002-04-18 02:53:04 +0000827 }
drh75897232000-05-29 14:26:00 +0000828 return 0;
829}
830
831/*
shane626a6e42009-10-22 17:30:15 +0000832** This is the callback routine that the SQLite library
833** invokes for each row of a query result.
834*/
835static int callback(void *pArg, int nArg, char **azArg, char **azCol){
836 /* since we don't have type info, call the shell_callback with a NULL value */
837 return shell_callback(pArg, nArg, azArg, azCol, NULL);
838}
839
840/*
drh33048c02001-10-01 14:29:22 +0000841** Set the destination table field of the callback_data structure to
842** the name of the table given. Escape any quote characters in the
843** table name.
844*/
845static void set_table_name(struct callback_data *p, const char *zName){
846 int i, n;
847 int needQuote;
848 char *z;
849
850 if( p->zDestTable ){
851 free(p->zDestTable);
852 p->zDestTable = 0;
853 }
854 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000855 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000856 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000857 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000858 needQuote = 1;
859 if( zName[i]=='\'' ) n++;
860 }
861 }
862 if( needQuote ) n += 2;
863 z = p->zDestTable = malloc( n+1 );
864 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000865 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000866 exit(1);
867 }
868 n = 0;
869 if( needQuote ) z[n++] = '\'';
870 for(i=0; zName[i]; i++){
871 z[n++] = zName[i];
872 if( zName[i]=='\'' ) z[n++] = '\'';
873 }
874 if( needQuote ) z[n++] = '\'';
875 z[n] = 0;
876}
877
danielk19772a02e332004-06-05 08:04:36 +0000878/* zIn is either a pointer to a NULL-terminated string in memory obtained
879** from malloc(), or a NULL pointer. The string pointed to by zAppend is
880** added to zIn, and the result returned in memory obtained from malloc().
881** zIn, if it was not NULL, is freed.
882**
883** If the third argument, quote, is not '\0', then it is used as a
884** quote character for zAppend.
885*/
drhc28490c2006-10-26 14:25:58 +0000886static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000887 int len;
888 int i;
drh4f21c4a2008-12-10 22:15:00 +0000889 int nAppend = strlen30(zAppend);
890 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000891
892 len = nAppend+nIn+1;
893 if( quote ){
894 len += 2;
895 for(i=0; i<nAppend; i++){
896 if( zAppend[i]==quote ) len++;
897 }
898 }
899
900 zIn = (char *)realloc(zIn, len);
901 if( !zIn ){
902 return 0;
903 }
904
905 if( quote ){
906 char *zCsr = &zIn[nIn];
907 *zCsr++ = quote;
908 for(i=0; i<nAppend; i++){
909 *zCsr++ = zAppend[i];
910 if( zAppend[i]==quote ) *zCsr++ = quote;
911 }
912 *zCsr++ = quote;
913 *zCsr++ = '\0';
914 assert( (zCsr-zIn)==len );
915 }else{
916 memcpy(&zIn[nIn], zAppend, nAppend);
917 zIn[len-1] = '\0';
918 }
919
920 return zIn;
921}
922
drhdd3d4592004-08-30 01:54:05 +0000923
924/*
925** Execute a query statement that has a single result column. Print
926** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000927**
928** This is used, for example, to show the schema of the database by
929** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000930*/
drh157e29a2009-05-21 15:15:00 +0000931static int run_table_dump_query(
932 FILE *out, /* Send output here */
933 sqlite3 *db, /* Database to query */
934 const char *zSelect, /* SELECT statement to extract content */
935 const char *zFirstRow /* Print before first row, if not NULL */
936){
drhdd3d4592004-08-30 01:54:05 +0000937 sqlite3_stmt *pSelect;
938 int rc;
939 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
940 if( rc!=SQLITE_OK || !pSelect ){
941 return rc;
942 }
943 rc = sqlite3_step(pSelect);
944 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000945 if( zFirstRow ){
946 fprintf(out, "%s", zFirstRow);
947 zFirstRow = 0;
948 }
drhdd3d4592004-08-30 01:54:05 +0000949 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
950 rc = sqlite3_step(pSelect);
951 }
952 return sqlite3_finalize(pSelect);
953}
954
shane626a6e42009-10-22 17:30:15 +0000955/*
956** Allocate space and save off current error string.
957*/
958static char *save_err_msg(
959 sqlite3 *db /* Database to query */
960){
961 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
962 char *zErrMsg = sqlite3_malloc(nErrMsg);
963 if( zErrMsg ){
964 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
965 }
966 return zErrMsg;
967}
968
969/*
shaneh642d8b82010-07-28 16:05:34 +0000970** Display memory stats.
971*/
972static int display_stats(
973 sqlite3 *db, /* Database to query */
974 struct callback_data *pArg, /* Pointer to struct callback_data */
975 int bReset /* True to reset the stats */
976){
977 int iCur;
978 int iHiwtr;
979
980 if( pArg && pArg->out ){
981
982 iHiwtr = iCur = -1;
983 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +0000984 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000985 iHiwtr = iCur = -1;
986 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +0000987 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000988/*
989** Not currently used by the CLI.
990** iHiwtr = iCur = -1;
991** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
992** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
993*/
994 iHiwtr = iCur = -1;
995 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
996 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
997/*
998** Not currently used by the CLI.
999** iHiwtr = iCur = -1;
1000** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1001** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1002*/
1003 iHiwtr = iCur = -1;
1004 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1005 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1006 iHiwtr = iCur = -1;
1007 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1008 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1009 iHiwtr = iCur = -1;
1010 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1011 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1012 iHiwtr = iCur = -1;
1013 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1014 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1015#ifdef YYTRACKMAXSTACKDEPTH
1016 iHiwtr = iCur = -1;
1017 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1018 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1019#endif
1020 }
1021
1022 if( pArg && pArg->out && db ){
1023 iHiwtr = iCur = -1;
1024 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1025 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001026 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1027 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1028 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1029 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1030 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1031 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001032 iHiwtr = iCur = -1;
1033 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh233f8162010-07-28 17:36:11 +00001034 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001035 iHiwtr = iCur = -1;
1036 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1037 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1038 iHiwtr = iCur = -1;
1039 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1040 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1041 }
1042
1043 if( pArg && pArg->out && db && pArg->pStmt ){
1044 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1045 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1046 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1047 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1048 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1049 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1050 }
1051
1052 return 0;
1053}
1054
1055/*
shane626a6e42009-10-22 17:30:15 +00001056** Execute a statement or set of statements. Print
1057** any result rows/columns depending on the current mode
1058** set via the supplied callback.
1059**
1060** This is very similar to SQLite's built-in sqlite3_exec()
1061** function except it takes a slightly different callback
1062** and callback data argument.
1063*/
1064static int shell_exec(
1065 sqlite3 *db, /* An open database */
1066 const char *zSql, /* SQL to be evaluated */
1067 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1068 /* (not the same as sqlite3_exec) */
1069 struct callback_data *pArg, /* Pointer to struct callback_data */
1070 char **pzErrMsg /* Error msg written here */
1071){
dan4564ced2010-01-05 04:59:56 +00001072 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1073 int rc = SQLITE_OK; /* Return Code */
1074 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001075
1076 if( pzErrMsg ){
1077 *pzErrMsg = NULL;
1078 }
1079
shaneb9fc17d2009-10-22 21:23:35 +00001080 while( zSql[0] && (SQLITE_OK == rc) ){
1081 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1082 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001083 if( pzErrMsg ){
1084 *pzErrMsg = save_err_msg(db);
1085 }
1086 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001087 if( !pStmt ){
1088 /* this happens for a comment or white-space */
1089 zSql = zLeftover;
1090 while( isspace(zSql[0]) ) zSql++;
1091 continue;
1092 }
shane626a6e42009-10-22 17:30:15 +00001093
shaneh642d8b82010-07-28 16:05:34 +00001094 /* save off the prepared statment handle and reset row count */
1095 if( pArg ){
1096 pArg->pStmt = pStmt;
1097 pArg->cnt = 0;
1098 }
1099
shanehb7977c52010-01-18 18:17:10 +00001100 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001101 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001102 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001103 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001104 }
shanehb7977c52010-01-18 18:17:10 +00001105
shaneb9fc17d2009-10-22 21:23:35 +00001106 /* perform the first step. this will tell us if we
1107 ** have a result set or not and how wide it is.
1108 */
1109 rc = sqlite3_step(pStmt);
1110 /* if we have a result set... */
1111 if( SQLITE_ROW == rc ){
1112 /* if we have a callback... */
1113 if( xCallback ){
1114 /* allocate space for col name ptr, value ptr, and type */
1115 int nCol = sqlite3_column_count(pStmt);
1116 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1117 if( !pData ){
1118 rc = SQLITE_NOMEM;
1119 }else{
1120 char **azCols = (char **)pData; /* Names of result columns */
1121 char **azVals = &azCols[nCol]; /* Results */
1122 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1123 int i;
1124 assert(sizeof(int) <= sizeof(char *));
1125 /* save off ptrs to column names */
1126 for(i=0; i<nCol; i++){
1127 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1128 }
shaneb9fc17d2009-10-22 21:23:35 +00001129 do{
1130 /* extract the data and data types */
1131 for(i=0; i<nCol; i++){
1132 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1133 aiTypes[i] = sqlite3_column_type(pStmt, i);
1134 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1135 rc = SQLITE_NOMEM;
1136 break; /* from for */
1137 }
1138 } /* end for */
1139
1140 /* if data and types extracted successfully... */
1141 if( SQLITE_ROW == rc ){
1142 /* call the supplied callback with the result row data */
1143 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1144 rc = SQLITE_ABORT;
1145 }else{
1146 rc = sqlite3_step(pStmt);
1147 }
1148 }
1149 } while( SQLITE_ROW == rc );
1150 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001151 }
1152 }else{
1153 do{
1154 rc = sqlite3_step(pStmt);
1155 } while( rc == SQLITE_ROW );
1156 }
1157 }
1158
shaneh642d8b82010-07-28 16:05:34 +00001159 /* print usage stats if stats on */
1160 if( pArg && pArg->statsOn ){
1161 display_stats(db, pArg, 0);
1162 }
1163
dan4564ced2010-01-05 04:59:56 +00001164 /* Finalize the statement just executed. If this fails, save a
1165 ** copy of the error message. Otherwise, set zSql to point to the
1166 ** next statement to execute. */
1167 rc = sqlite3_finalize(pStmt);
1168 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001169 zSql = zLeftover;
1170 while( isspace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001171 }else if( pzErrMsg ){
1172 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001173 }
shaneh642d8b82010-07-28 16:05:34 +00001174
1175 /* clear saved stmt handle */
1176 if( pArg ){
1177 pArg->pStmt = NULL;
1178 }
shane626a6e42009-10-22 17:30:15 +00001179 }
shaneb9fc17d2009-10-22 21:23:35 +00001180 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001181
1182 return rc;
1183}
1184
drhdd3d4592004-08-30 01:54:05 +00001185
drh33048c02001-10-01 14:29:22 +00001186/*
drh4c653a02000-06-07 01:27:47 +00001187** This is a different callback routine used for dumping the database.
1188** Each row received by this callback consists of a table name,
1189** the table type ("index" or "table") and SQL to create the table.
1190** This routine should print text sufficient to recreate the table.
1191*/
1192static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001193 int rc;
1194 const char *zTable;
1195 const char *zType;
1196 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001197 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001198 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001199
drh902b9ee2008-12-05 17:17:07 +00001200 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001201 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001202 zTable = azArg[0];
1203 zType = azArg[1];
1204 zSql = azArg[2];
1205
drh00b950d2005-09-11 02:03:03 +00001206 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001207 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001208 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1209 fprintf(p->out, "ANALYZE sqlite_master;\n");
1210 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1211 return 0;
drh45e29d82006-11-20 16:21:10 +00001212 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1213 char *zIns;
1214 if( !p->writableSchema ){
1215 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1216 p->writableSchema = 1;
1217 }
1218 zIns = sqlite3_mprintf(
1219 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1220 "VALUES('table','%q','%q',0,'%q');",
1221 zTable, zTable, zSql);
1222 fprintf(p->out, "%s\n", zIns);
1223 sqlite3_free(zIns);
1224 return 0;
drh00b950d2005-09-11 02:03:03 +00001225 }else{
1226 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001227 }
danielk19772a02e332004-06-05 08:04:36 +00001228
1229 if( strcmp(zType, "table")==0 ){
1230 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001231 char *zSelect = 0;
1232 char *zTableInfo = 0;
1233 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001234 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001235
1236 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1237 zTableInfo = appendText(zTableInfo, zTable, '"');
1238 zTableInfo = appendText(zTableInfo, ");", 0);
1239
1240 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001241 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001242 if( rc!=SQLITE_OK || !pTableInfo ){
1243 return 1;
1244 }
1245
1246 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1247 zTmp = appendText(zTmp, zTable, '"');
1248 if( zTmp ){
1249 zSelect = appendText(zSelect, zTmp, '\'');
1250 }
1251 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1252 rc = sqlite3_step(pTableInfo);
1253 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001254 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001255 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001256 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001257 rc = sqlite3_step(pTableInfo);
1258 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001259 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001260 }else{
1261 zSelect = appendText(zSelect, ") ", 0);
1262 }
drh157e29a2009-05-21 15:15:00 +00001263 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001264 }
1265 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001266 if( rc!=SQLITE_OK || nRow==0 ){
1267 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001268 return 1;
1269 }
1270 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1271 zSelect = appendText(zSelect, zTable, '"');
1272
drh157e29a2009-05-21 15:15:00 +00001273 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001274 if( rc==SQLITE_CORRUPT ){
1275 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001276 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001277 }
danielk19772a02e332004-06-05 08:04:36 +00001278 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001279 }
drh4c653a02000-06-07 01:27:47 +00001280 return 0;
1281}
1282
1283/*
drh45e29d82006-11-20 16:21:10 +00001284** Run zQuery. Use dump_callback() as the callback routine so that
1285** the contents of the query are output as SQL statements.
1286**
drhdd3d4592004-08-30 01:54:05 +00001287** If we get a SQLITE_CORRUPT error, rerun the query after appending
1288** "ORDER BY rowid DESC" to the end.
1289*/
1290static int run_schema_dump_query(
1291 struct callback_data *p,
1292 const char *zQuery,
1293 char **pzErrMsg
1294){
1295 int rc;
1296 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1297 if( rc==SQLITE_CORRUPT ){
1298 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001299 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001300 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1301 zQ2 = malloc( len+100 );
1302 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001303 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001304 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1305 free(zQ2);
1306 }
1307 return rc;
1308}
1309
1310/*
drh75897232000-05-29 14:26:00 +00001311** Text of a help message
1312*/
persicom1d0b8722002-04-18 02:53:04 +00001313static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001314 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001315 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001316 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001317 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001318 " If TABLE specified, only dump tables matching\n"
1319 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001320 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001321 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001322 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1323 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001324 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001325 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001326 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001327 ".indices ?TABLE? Show names of all indices\n"
1328 " If TABLE specified, only show indices for tables\n"
1329 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001330#ifdef SQLITE_ENABLE_IOTRACE
1331 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1332#endif
drh70df4fe2006-06-13 15:12:21 +00001333#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001334 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001335#endif
drh127f9d72010-02-23 01:47:00 +00001336 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001337 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001338 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001339 " column Left-aligned columns. (See .width)\n"
1340 " html HTML <table> code\n"
1341 " insert SQL insert statements for TABLE\n"
1342 " line One value per line\n"
1343 " list Values delimited by .separator string\n"
1344 " tabs Tab-separated values\n"
1345 " tcl TCL list elements\n"
1346 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001347 ".output FILENAME Send output to FILENAME\n"
1348 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001349 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001350 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001351 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001352 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001353 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001354 " If TABLE specified, only show tables matching\n"
1355 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001356 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001357 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001358 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001359 ".tables ?TABLE? List names of tables\n"
1360 " If TABLE specified, only list tables matching\n"
1361 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001362 ".timeout MS Try opening locked tables for MS milliseconds\n"
shanehe2aa9d72009-11-06 17:20:17 +00001363 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001364;
1365
shaneb320ccd2009-10-21 03:42:58 +00001366static char zTimerHelp[] =
1367 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1368;
1369
drhdaffd0e2001-04-11 14:28:42 +00001370/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001371static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001372
drh75897232000-05-29 14:26:00 +00001373/*
drh44c2eb12003-04-30 11:38:26 +00001374** Make sure the database is open. If it is not, then open it. If
1375** the database fails to open, print an error message and exit.
1376*/
1377static void open_db(struct callback_data *p){
1378 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001379 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001380 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001381 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1382 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1383 shellstaticFunc, 0, 0);
1384 }
1385 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001386 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001387 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001388 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001389 }
drhc2e87a32006-06-27 15:16:14 +00001390#ifndef SQLITE_OMIT_LOAD_EXTENSION
1391 sqlite3_enable_load_extension(p->db, 1);
1392#endif
drh44c2eb12003-04-30 11:38:26 +00001393 }
1394}
1395
1396/*
drhfeac5f82004-08-01 00:10:45 +00001397** Do C-language style dequoting.
1398**
1399** \t -> tab
1400** \n -> newline
1401** \r -> carriage return
1402** \NNN -> ascii character NNN in octal
1403** \\ -> backslash
1404*/
1405static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001406 int i, j;
1407 char c;
drhfeac5f82004-08-01 00:10:45 +00001408 for(i=j=0; (c = z[i])!=0; i++, j++){
1409 if( c=='\\' ){
1410 c = z[++i];
1411 if( c=='n' ){
1412 c = '\n';
1413 }else if( c=='t' ){
1414 c = '\t';
1415 }else if( c=='r' ){
1416 c = '\r';
1417 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001418 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001419 if( z[i+1]>='0' && z[i+1]<='7' ){
1420 i++;
1421 c = (c<<3) + z[i] - '0';
1422 if( z[i+1]>='0' && z[i+1]<='7' ){
1423 i++;
1424 c = (c<<3) + z[i] - '0';
1425 }
1426 }
1427 }
1428 }
1429 z[j] = c;
1430 }
1431 z[j] = 0;
1432}
1433
1434/*
drhc28490c2006-10-26 14:25:58 +00001435** Interpret zArg as a boolean value. Return either 0 or 1.
1436*/
1437static int booleanValue(char *zArg){
1438 int val = atoi(zArg);
1439 int j;
1440 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001441 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001442 }
1443 if( strcmp(zArg,"on")==0 ){
1444 val = 1;
1445 }else if( strcmp(zArg,"yes")==0 ){
1446 val = 1;
1447 }
1448 return val;
1449}
1450
1451/*
drh75897232000-05-29 14:26:00 +00001452** If an input line begins with "." then invoke this routine to
1453** process that line.
drh67505e72002-04-19 12:34:06 +00001454**
drh47ad6842006-11-08 12:25:42 +00001455** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001456*/
drh44c2eb12003-04-30 11:38:26 +00001457static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001458 int i = 1;
1459 int nArg = 0;
1460 int n, c;
drh67505e72002-04-19 12:34:06 +00001461 int rc = 0;
drh75897232000-05-29 14:26:00 +00001462 char *azArg[50];
1463
1464 /* Parse the input line into tokens.
1465 */
1466 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001467 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001468 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001469 if( zLine[i]=='\'' || zLine[i]=='"' ){
1470 int delim = zLine[i++];
1471 azArg[nArg++] = &zLine[i];
1472 while( zLine[i] && zLine[i]!=delim ){ i++; }
1473 if( zLine[i]==delim ){
1474 zLine[i++] = 0;
1475 }
drhfeac5f82004-08-01 00:10:45 +00001476 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001477 }else{
1478 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001479 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001480 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001481 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001482 }
1483 }
1484
1485 /* Process the input line.
1486 */
shane9bd1b442009-10-23 01:27:39 +00001487 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001488 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001489 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001490 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001491 const char *zDestFile;
1492 const char *zDb;
1493 sqlite3 *pDest;
1494 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001495 if( nArg==2 ){
1496 zDestFile = azArg[1];
1497 zDb = "main";
1498 }else{
1499 zDestFile = azArg[2];
1500 zDb = azArg[1];
1501 }
1502 rc = sqlite3_open(zDestFile, &pDest);
1503 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001504 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001505 sqlite3_close(pDest);
1506 return 1;
1507 }
drhdc2c4912009-02-04 22:46:47 +00001508 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001509 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1510 if( pBackup==0 ){
1511 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1512 sqlite3_close(pDest);
1513 return 1;
1514 }
1515 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1516 sqlite3_backup_finish(pBackup);
1517 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001518 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001519 }else{
1520 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001521 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001522 }
1523 sqlite3_close(pDest);
1524 }else
1525
shanehe2aa9d72009-11-06 17:20:17 +00001526 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001527 bail_on_error = booleanValue(azArg[1]);
1528 }else
1529
shanehe2aa9d72009-11-06 17:20:17 +00001530 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001531 struct callback_data data;
1532 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001533 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001534 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001535 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001536 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001537 data.colWidth[0] = 3;
1538 data.colWidth[1] = 15;
1539 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001540 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001541 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001542 if( zErrMsg ){
1543 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001544 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001545 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001546 }
1547 }else
1548
shanehe2aa9d72009-11-06 17:20:17 +00001549 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh4c653a02000-06-07 01:27:47 +00001550 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001551 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001552 /* When playing back a "dump", the content might appear in an order
1553 ** which causes immediate foreign key constraints to be violated.
1554 ** So disable foreign-key constraint enforcement to prevent problems. */
1555 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001556 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001557 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001558 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001559 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001560 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001561 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00001562 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1563 );
1564 run_schema_dump_query(p,
1565 "SELECT name, type, sql FROM sqlite_master "
1566 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00001567 );
1568 run_table_dump_query(p->out, p->db,
1569 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001570 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001571 );
drh4c653a02000-06-07 01:27:47 +00001572 }else{
1573 int i;
drhdd3d4592004-08-30 01:54:05 +00001574 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001575 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001576 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001577 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001578 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001579 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001580 run_table_dump_query(p->out, p->db,
1581 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001582 "WHERE sql NOT NULL"
1583 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001584 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001585 );
danielk1977bc6ada42004-06-30 08:20:16 +00001586 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001587 }
1588 }
drh45e29d82006-11-20 16:21:10 +00001589 if( p->writableSchema ){
1590 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1591 p->writableSchema = 0;
1592 }
drh93f41e52008-08-11 19:12:34 +00001593 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001594 if( zErrMsg ){
1595 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001596 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001597 }else{
1598 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001599 }
1600 }else
drh75897232000-05-29 14:26:00 +00001601
shanehe2aa9d72009-11-06 17:20:17 +00001602 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001603 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001604 }else
1605
shanehe2aa9d72009-11-06 17:20:17 +00001606 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001607 rc = 2;
drh75897232000-05-29 14:26:00 +00001608 }else
1609
shanehe2aa9d72009-11-06 17:20:17 +00001610 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001611 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001612 if(val == 1) {
1613 if(!p->explainPrev.valid) {
1614 p->explainPrev.valid = 1;
1615 p->explainPrev.mode = p->mode;
1616 p->explainPrev.showHeader = p->showHeader;
1617 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1618 }
1619 /* We could put this code under the !p->explainValid
1620 ** condition so that it does not execute if we are already in
1621 ** explain mode. However, always executing it allows us an easy
1622 ** was to reset to explain mode in case the user previously
1623 ** did an .explain followed by a .width, .mode or .header
1624 ** command.
1625 */
danielk19770d78bae2008-01-03 07:09:48 +00001626 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001627 p->showHeader = 1;
1628 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001629 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001630 p->colWidth[1] = 13; /* opcode */
1631 p->colWidth[2] = 4; /* P1 */
1632 p->colWidth[3] = 4; /* P2 */
1633 p->colWidth[4] = 4; /* P3 */
1634 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001635 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001636 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001637 }else if (p->explainPrev.valid) {
1638 p->explainPrev.valid = 0;
1639 p->mode = p->explainPrev.mode;
1640 p->showHeader = p->explainPrev.showHeader;
1641 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1642 }
drh75897232000-05-29 14:26:00 +00001643 }else
1644
drhc28490c2006-10-26 14:25:58 +00001645 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001646 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001647 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001648 }else
1649
1650 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001651 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001652 if( HAS_TIMER ){
1653 fprintf(stderr,"%s",zTimerHelp);
1654 }
drh75897232000-05-29 14:26:00 +00001655 }else
1656
shanehe2aa9d72009-11-06 17:20:17 +00001657 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001658 char *zTable = azArg[2]; /* Insert data into this table */
1659 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001660 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001661 int nCol; /* Number of columns in the table */
1662 int nByte; /* Number of bytes in an SQL string */
1663 int i, j; /* Loop counters */
1664 int nSep; /* Number of bytes in p->separator[] */
1665 char *zSql; /* An SQL statement */
1666 char *zLine; /* A single line of input from the file */
1667 char **azCol; /* zLine[] broken up into columns */
1668 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001669 FILE *in; /* The input file */
1670 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001671
drha543c822006-06-08 16:10:14 +00001672 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001673 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001674 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001675 fprintf(stderr, "Error: non-null separator required for import\n");
1676 return 1;
drhfeac5f82004-08-01 00:10:45 +00001677 }
1678 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
shane916f9612009-10-23 00:37:15 +00001679 if( zSql==0 ){
1680 fprintf(stderr, "Error: out of memory\n");
1681 return 1;
1682 }
drh4f21c4a2008-12-10 22:15:00 +00001683 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001684 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001685 sqlite3_free(zSql);
1686 if( rc ){
shane916f9612009-10-23 00:37:15 +00001687 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001688 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001689 return 1;
drhfeac5f82004-08-01 00:10:45 +00001690 }
shane916f9612009-10-23 00:37:15 +00001691 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001692 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001693 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001694 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001695 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001696 if( zSql==0 ){
1697 fprintf(stderr, "Error: out of memory\n");
1698 return 1;
1699 }
drhfeac5f82004-08-01 00:10:45 +00001700 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001701 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001702 for(i=1; i<nCol; i++){
1703 zSql[j++] = ',';
1704 zSql[j++] = '?';
1705 }
1706 zSql[j++] = ')';
1707 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001708 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001709 free(zSql);
1710 if( rc ){
1711 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001712 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001713 return 1;
drhfeac5f82004-08-01 00:10:45 +00001714 }
1715 in = fopen(zFile, "rb");
1716 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001717 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001718 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001719 return 1;
drhfeac5f82004-08-01 00:10:45 +00001720 }
1721 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001722 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001723 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001724 fclose(in);
shane916f9612009-10-23 00:37:15 +00001725 sqlite3_finalize(pStmt);
1726 return 1;
drh43617e92006-03-06 20:55:46 +00001727 }
drhfeac5f82004-08-01 00:10:45 +00001728 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1729 zCommit = "COMMIT";
1730 while( (zLine = local_getline(0, in))!=0 ){
1731 char *z;
1732 i = 0;
drhb860bc92004-08-04 15:16:55 +00001733 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001734 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001735 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001736 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1737 *z = 0;
1738 i++;
drhb860bc92004-08-04 15:16:55 +00001739 if( i<nCol ){
1740 azCol[i] = &z[nSep];
1741 z += nSep-1;
1742 }
drhfeac5f82004-08-01 00:10:45 +00001743 }
shane916f9612009-10-23 00:37:15 +00001744 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001745 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001746 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001747 fprintf(stderr,
1748 "Error: %s line %d: expected %d columns of data but found %d\n",
1749 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001750 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001751 free(zLine);
shane916f9612009-10-23 00:37:15 +00001752 rc = 1;
1753 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001754 }
drhfeac5f82004-08-01 00:10:45 +00001755 for(i=0; i<nCol; i++){
1756 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1757 }
1758 sqlite3_step(pStmt);
1759 rc = sqlite3_reset(pStmt);
1760 free(zLine);
1761 if( rc!=SQLITE_OK ){
1762 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1763 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001764 rc = 1;
shane916f9612009-10-23 00:37:15 +00001765 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001766 }
shane916f9612009-10-23 00:37:15 +00001767 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001768 free(azCol);
1769 fclose(in);
1770 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001771 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001772 }else
1773
shanehe2aa9d72009-11-06 17:20:17 +00001774 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001775 struct callback_data data;
1776 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001777 open_db(p);
drh75897232000-05-29 14:26:00 +00001778 memcpy(&data, p, sizeof(data));
1779 data.showHeader = 0;
1780 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001781 if( nArg==1 ){
1782 rc = sqlite3_exec(p->db,
1783 "SELECT name FROM sqlite_master "
1784 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1785 "UNION ALL "
1786 "SELECT name FROM sqlite_temp_master "
1787 "WHERE type='index' "
1788 "ORDER BY 1",
1789 callback, &data, &zErrMsg
1790 );
1791 }else{
1792 zShellStatic = azArg[1];
1793 rc = sqlite3_exec(p->db,
1794 "SELECT name FROM sqlite_master "
1795 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1796 "UNION ALL "
1797 "SELECT name FROM sqlite_temp_master "
1798 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1799 "ORDER BY 1",
1800 callback, &data, &zErrMsg
1801 );
1802 zShellStatic = 0;
1803 }
drh75897232000-05-29 14:26:00 +00001804 if( zErrMsg ){
1805 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001806 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001807 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001808 }else if( rc != SQLITE_OK ){
1809 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1810 rc = 1;
drh75897232000-05-29 14:26:00 +00001811 }
1812 }else
1813
drhae5e4452007-05-03 17:18:36 +00001814#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001815 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001816 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001817 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1818 iotrace = 0;
1819 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001820 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001821 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001822 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001823 iotrace = stdout;
1824 }else{
1825 iotrace = fopen(azArg[1], "w");
1826 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001827 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001828 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001829 rc = 1;
drhb0603412007-02-28 04:47:26 +00001830 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001831 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001832 }
1833 }
1834 }else
drhae5e4452007-05-03 17:18:36 +00001835#endif
drhb0603412007-02-28 04:47:26 +00001836
drh70df4fe2006-06-13 15:12:21 +00001837#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001838 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1839 const char *zFile, *zProc;
1840 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001841 zFile = azArg[1];
1842 zProc = nArg>=3 ? azArg[2] : 0;
1843 open_db(p);
1844 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1845 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001846 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001847 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001848 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001849 }
1850 }else
drh70df4fe2006-06-13 15:12:21 +00001851#endif
drh1e397f82006-06-08 15:28:43 +00001852
drh127f9d72010-02-23 01:47:00 +00001853 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=1 ){
1854 const char *zFile = azArg[1];
1855 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1856 fclose(p->pLog);
1857 p->pLog = 0;
1858 }
1859 if( strcmp(zFile,"stdout")==0 ){
1860 p->pLog = stdout;
1861 }else if( strcmp(zFile, "stderr")==0 ){
1862 p->pLog = stderr;
1863 }else if( strcmp(zFile, "off")==0 ){
1864 p->pLog = 0;
1865 }else{
1866 p->pLog = fopen(zFile, "w");
1867 if( p->pLog==0 ){
1868 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1869 }
1870 }
1871 }else
1872
shanehe2aa9d72009-11-06 17:20:17 +00001873 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001874 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001875 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001876 ||
shanehe2aa9d72009-11-06 17:20:17 +00001877 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001878 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001879 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001880 ||
shanehe2aa9d72009-11-06 17:20:17 +00001881 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001882 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001883 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001884 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001885 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001886 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001887 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001888 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001889 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001890 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001891 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001892 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001893 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001894 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001895 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001896 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001897 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001898 }else {
shane9bd1b442009-10-23 01:27:39 +00001899 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001900 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001901 rc = 1;
drh75897232000-05-29 14:26:00 +00001902 }
1903 }else
1904
shanehe2aa9d72009-11-06 17:20:17 +00001905 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1906 int n2 = strlen30(azArg[1]);
1907 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1908 p->mode = MODE_Insert;
1909 set_table_name(p, azArg[2]);
1910 }else {
1911 fprintf(stderr, "Error: invalid arguments: "
1912 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1913 rc = 1;
1914 }
1915 }else
1916
persicom7e2dfdd2002-04-18 02:46:52 +00001917 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001918 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1919 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001920 }else
1921
drh75897232000-05-29 14:26:00 +00001922 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1923 if( p->out!=stdout ){
1924 fclose(p->out);
1925 }
1926 if( strcmp(azArg[1],"stdout")==0 ){
1927 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001928 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001929 }else{
drha1f9b5e2004-02-14 16:31:02 +00001930 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001931 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00001932 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00001933 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00001934 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001935 } else {
drh5bb3eb92007-05-04 13:15:55 +00001936 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001937 }
1938 }
1939 }else
1940
drhdd45df82002-04-18 12:39:03 +00001941 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001942 if( nArg >= 2) {
1943 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1944 }
1945 if( nArg >= 3) {
1946 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1947 }
1948 }else
1949
shanehe2aa9d72009-11-06 17:20:17 +00001950 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001951 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001952 }else
1953
drh9ff849f2009-02-04 20:55:57 +00001954 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001955 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001956 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00001957 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1958 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00001959 }else{
shane9bd1b442009-10-23 01:27:39 +00001960 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00001961 fclose(alt);
1962 }
1963 }else
1964
shanehe2aa9d72009-11-06 17:20:17 +00001965 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001966 const char *zSrcFile;
1967 const char *zDb;
1968 sqlite3 *pSrc;
1969 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00001970 int nTimeout = 0;
1971
drh9ff849f2009-02-04 20:55:57 +00001972 if( nArg==2 ){
1973 zSrcFile = azArg[1];
1974 zDb = "main";
1975 }else{
1976 zSrcFile = azArg[2];
1977 zDb = azArg[1];
1978 }
1979 rc = sqlite3_open(zSrcFile, &pSrc);
1980 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001981 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00001982 sqlite3_close(pSrc);
1983 return 1;
1984 }
drhdc2c4912009-02-04 22:46:47 +00001985 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001986 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
1987 if( pBackup==0 ){
1988 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1989 sqlite3_close(pSrc);
1990 return 1;
1991 }
drhdc2c4912009-02-04 22:46:47 +00001992 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
1993 || rc==SQLITE_BUSY ){
1994 if( rc==SQLITE_BUSY ){
1995 if( nTimeout++ >= 3 ) break;
1996 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00001997 }
1998 }
1999 sqlite3_backup_finish(pBackup);
2000 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002001 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002002 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002003 fprintf(stderr, "Error: source database is busy\n");
2004 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002005 }else{
2006 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002007 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002008 }
2009 sqlite3_close(pSrc);
2010 }else
2011
shanehe2aa9d72009-11-06 17:20:17 +00002012 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002013 struct callback_data data;
2014 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002015 open_db(p);
drh75897232000-05-29 14:26:00 +00002016 memcpy(&data, p, sizeof(data));
2017 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002018 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002019 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002020 int i;
shane7d3846a2008-12-11 02:58:26 +00002021 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002022 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002023 char *new_argv[2], *new_colv[2];
2024 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2025 " type text,\n"
2026 " name text,\n"
2027 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002028 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002029 " sql text\n"
2030 ")";
2031 new_argv[1] = 0;
2032 new_colv[0] = "sql";
2033 new_colv[1] = 0;
2034 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002035 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002036 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002037 char *new_argv[2], *new_colv[2];
2038 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2039 " type text,\n"
2040 " name text,\n"
2041 " tbl_name text,\n"
2042 " rootpage integer,\n"
2043 " sql text\n"
2044 ")";
2045 new_argv[1] = 0;
2046 new_colv[0] = "sql";
2047 new_colv[1] = 0;
2048 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002049 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002050 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002051 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002052 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002053 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002054 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2055 " FROM sqlite_master UNION ALL"
2056 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002057 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002058 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002059 callback, &data, &zErrMsg);
2060 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002061 }
drh75897232000-05-29 14:26:00 +00002062 }else{
shane9bd1b442009-10-23 01:27:39 +00002063 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002064 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002065 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2066 " FROM sqlite_master UNION ALL"
2067 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002068 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002069 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002070 callback, &data, &zErrMsg
2071 );
drh75897232000-05-29 14:26:00 +00002072 }
drh75897232000-05-29 14:26:00 +00002073 if( zErrMsg ){
2074 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002075 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002076 rc = 1;
2077 }else if( rc != SQLITE_OK ){
2078 fprintf(stderr,"Error: querying schema information\n");
2079 rc = 1;
2080 }else{
2081 rc = 0;
drh75897232000-05-29 14:26:00 +00002082 }
2083 }else
2084
2085 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002086 sqlite3_snprintf(sizeof(p->separator), p->separator,
2087 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002088 }else
2089
shanehe2aa9d72009-11-06 17:20:17 +00002090 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002091 int i;
2092 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002093 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002094 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002095 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002096 fprintf(p->out,"%9.9s: ", "nullvalue");
2097 output_c_string(p->out, p->nullvalue);
2098 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002099 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002100 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002101 fprintf(p->out,"%9.9s: ", "separator");
2102 output_c_string(p->out, p->separator);
2103 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002104 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002105 fprintf(p->out,"%9.9s: ","width");
2106 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002107 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002108 }
drhfeac5f82004-08-01 00:10:45 +00002109 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002110 }else
2111
shaneh642d8b82010-07-28 16:05:34 +00002112 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2113 p->statsOn = booleanValue(azArg[1]);
2114 }else
2115
shanehe2aa9d72009-11-06 17:20:17 +00002116 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002117 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002118 int nRow;
drhe3710332000-09-29 13:30:53 +00002119 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002120 open_db(p);
drha50da102000-08-08 20:19:09 +00002121 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002122 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002123 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002124 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002125 "UNION ALL "
2126 "SELECT name FROM sqlite_temp_master "
2127 "WHERE type IN ('table','view') "
2128 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002129 &azResult, &nRow, 0, &zErrMsg
2130 );
drha50da102000-08-08 20:19:09 +00002131 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002132 zShellStatic = azArg[1];
2133 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002134 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002135 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002136 "UNION ALL "
2137 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002138 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002139 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002140 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002141 );
danielk1977bc6ada42004-06-30 08:20:16 +00002142 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002143 }
drh75897232000-05-29 14:26:00 +00002144 if( zErrMsg ){
2145 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002146 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002147 rc = 1;
2148 }else if( rc != SQLITE_OK ){
2149 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2150 rc = 1;
2151 }else{
drhe3710332000-09-29 13:30:53 +00002152 int len, maxlen = 0;
2153 int i, j;
2154 int nPrintCol, nPrintRow;
2155 for(i=1; i<=nRow; i++){
2156 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002157 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002158 if( len>maxlen ) maxlen = len;
2159 }
2160 nPrintCol = 80/(maxlen+2);
2161 if( nPrintCol<1 ) nPrintCol = 1;
2162 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2163 for(i=0; i<nPrintRow; i++){
2164 for(j=i+1; j<=nRow; j+=nPrintRow){
2165 char *zSp = j<=nPrintRow ? "" : " ";
2166 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2167 }
2168 printf("\n");
2169 }
2170 }
danielk19776f8a5032004-05-10 10:34:51 +00002171 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002172 }else
2173
shaneh96887e12011-02-10 21:08:58 +00002174 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
2175 int testctrl = -1;
2176 int rc = 0;
2177 open_db(p);
2178
2179 /* convert testctrl text option to value. allow only the first
2180 ** three characters of the option to be used or the numerical
2181 ** value. */
2182 if( strncmp( azArg[1], "prng_save", 6 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_SAVE;
2183 else if( strncmp( azArg[1], "prng_restore", 10 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_RESTORE;
2184 else if( strncmp( azArg[1], "prng_reset", 10 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_RESET;
2185 else if( strncmp( azArg[1], "bitvec_test", 6 )==3 ) testctrl = SQLITE_TESTCTRL_BITVEC_TEST;
2186 else if( strncmp( azArg[1], "fault_install", 6 )==3 ) testctrl = SQLITE_TESTCTRL_FAULT_INSTALL;
2187 else if( strncmp( azArg[1], "benign_malloc_hooks", 3 )==0 ) testctrl = SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS;
2188 else if( strncmp( azArg[1], "pending_byte", 3 )==0 ) testctrl = SQLITE_TESTCTRL_PENDING_BYTE;
2189 else if( strncmp( azArg[1], "assert", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ASSERT;
2190 else if( strncmp( azArg[1], "always", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ALWAYS;
2191 else if( strncmp( azArg[1], "reserve", 3 )==0 ) testctrl = SQLITE_TESTCTRL_RESERVE;
2192 else if( strncmp( azArg[1], "optimizations", 3 )==0 ) testctrl = SQLITE_TESTCTRL_OPTIMIZATIONS;
2193 else if( strncmp( azArg[1], "iskeyword", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ISKEYWORD;
2194 else if( strncmp( azArg[1], "pghdrsz", 3 )==0 ) testctrl = SQLITE_TESTCTRL_PGHDRSZ;
2195 else if( strncmp( azArg[1], "scratchmalloc", 3 )==0 ) testctrl = SQLITE_TESTCTRL_SCRATCHMALLOC;
2196 else testctrl = atoi(azArg[1]);
2197
2198 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2199 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2200 }else{
2201 switch(testctrl){
2202
2203 /* sqlite3_test_control(int, db, int) */
2204 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2205 case SQLITE_TESTCTRL_RESERVE:
2206 if( nArg==3 ){
2207 int opt = (int)strtol(azArg[2], 0, 0);
2208 rc = sqlite3_test_control(testctrl, p->db, opt);
2209 printf("%d (0x%08x)\n", rc, rc);
2210 } else {
2211 fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]);
2212 }
2213 break;
2214
2215 /* sqlite3_test_control(int) */
2216 case SQLITE_TESTCTRL_PRNG_SAVE:
2217 case SQLITE_TESTCTRL_PRNG_RESTORE:
2218 case SQLITE_TESTCTRL_PRNG_RESET:
2219 case SQLITE_TESTCTRL_PGHDRSZ:
2220 if( nArg==2 ){
2221 rc = sqlite3_test_control(testctrl);
2222 printf("%d (0x%08x)\n", rc, rc);
2223 } else {
2224 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2225 }
2226 break;
2227
2228 /* sqlite3_test_control(int, uint) */
2229 case SQLITE_TESTCTRL_PENDING_BYTE:
2230 if( nArg==3 ){
2231 unsigned int opt = (unsigned int)atoi(azArg[2]);
2232 rc = sqlite3_test_control(testctrl, opt);
2233 printf("%d (0x%08x)\n", rc, rc);
2234 } else {
2235 fprintf(stderr,"Error: testctrl %s takes a single unsigned int option\n", azArg[1]);
2236 }
2237 break;
2238
2239 /* sqlite3_test_control(int, int) */
2240 case SQLITE_TESTCTRL_ASSERT:
2241 case SQLITE_TESTCTRL_ALWAYS:
2242 if( nArg==3 ){
2243 int opt = atoi(azArg[2]);
2244 rc = sqlite3_test_control(testctrl, opt);
2245 printf("%d (0x%08x)\n", rc, rc);
2246 } else {
2247 fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]);
2248 }
2249 break;
2250
2251 /* sqlite3_test_control(int, char *) */
2252#ifdef SQLITE_N_KEYWORD
2253 case SQLITE_TESTCTRL_ISKEYWORD:
2254 if( nArg==3 ){
2255 const char *opt = azArg[2];
2256 rc = sqlite3_test_control(testctrl, opt);
2257 printf("%d (0x%08x)\n", rc, rc);
2258 } else {
2259 fprintf(stderr,"Error: testctrl %s takes a single char * option\n", azArg[1]);
2260 }
2261 break;
2262#endif
2263
2264 case SQLITE_TESTCTRL_BITVEC_TEST:
2265 case SQLITE_TESTCTRL_FAULT_INSTALL:
2266 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2267 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2268 default:
2269 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", azArg[1]);
2270 break;
2271 }
2272 }
2273 }else
2274
shanehe2aa9d72009-11-06 17:20:17 +00002275 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002276 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002277 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002278 }else
2279
2280 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
drh3b1a9882007-11-02 12:53:03 +00002281 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002282 }else
2283
2284 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002285 int j;
drh43617e92006-03-06 20:55:46 +00002286 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002287 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2288 p->colWidth[j-1] = atoi(azArg[j]);
2289 }
2290 }else
2291
2292 {
shane9bd1b442009-10-23 01:27:39 +00002293 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002294 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002295 rc = 1;
drh75897232000-05-29 14:26:00 +00002296 }
drh67505e72002-04-19 12:34:06 +00002297
2298 return rc;
drh75897232000-05-29 14:26:00 +00002299}
2300
drh67505e72002-04-19 12:34:06 +00002301/*
drh91a66392007-09-07 01:12:32 +00002302** Return TRUE if a semicolon occurs anywhere in the first N characters
2303** of string z[].
drh324ccef2003-02-05 14:06:20 +00002304*/
drh91a66392007-09-07 01:12:32 +00002305static int _contains_semicolon(const char *z, int N){
2306 int i;
2307 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2308 return 0;
drh324ccef2003-02-05 14:06:20 +00002309}
2310
2311/*
drh70c7a4b2003-04-26 03:03:06 +00002312** Test to see if a line consists entirely of whitespace.
2313*/
2314static int _all_whitespace(const char *z){
2315 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002316 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002317 if( *z=='/' && z[1]=='*' ){
2318 z += 2;
2319 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2320 if( *z==0 ) return 0;
2321 z++;
2322 continue;
2323 }
2324 if( *z=='-' && z[1]=='-' ){
2325 z += 2;
2326 while( *z && *z!='\n' ){ z++; }
2327 if( *z==0 ) return 1;
2328 continue;
2329 }
2330 return 0;
2331 }
2332 return 1;
2333}
2334
2335/*
drha9b17162003-04-29 18:01:28 +00002336** Return TRUE if the line typed in is an SQL command terminator other
2337** than a semi-colon. The SQL Server style "go" command is understood
2338** as is the Oracle "/".
2339*/
2340static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002341 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002342 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2343 return 1; /* Oracle */
2344 }
drhc8d74412004-08-31 23:41:26 +00002345 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2346 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002347 return 1; /* SQL Server */
2348 }
2349 return 0;
2350}
2351
2352/*
drh233a5312008-12-18 22:25:13 +00002353** Return true if zSql is a complete SQL statement. Return false if it
2354** ends in the middle of a string literal or C-style comment.
2355*/
2356static int _is_complete(char *zSql, int nSql){
2357 int rc;
2358 if( zSql==0 ) return 1;
2359 zSql[nSql] = ';';
2360 zSql[nSql+1] = 0;
2361 rc = sqlite3_complete(zSql);
2362 zSql[nSql] = 0;
2363 return rc;
2364}
2365
2366/*
drh67505e72002-04-19 12:34:06 +00002367** Read input from *in and process it. If *in==0 then input
2368** is interactive - the user is typing it it. Otherwise, input
2369** is coming from a file or device. A prompt is issued and history
2370** is saved only if input is interactive. An interrupt signal will
2371** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002372**
2373** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002374*/
drhc28490c2006-10-26 14:25:58 +00002375static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002376 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002377 char *zSql = 0;
2378 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002379 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002380 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002381 int rc;
2382 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002383 int lineno = 0;
2384 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002385
2386 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2387 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002388 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002389 zLine = one_input_line(zSql, in);
2390 if( zLine==0 ){
2391 break; /* We have reached EOF */
2392 }
drh67505e72002-04-19 12:34:06 +00002393 if( seenInterrupt ){
2394 if( in!=0 ) break;
2395 seenInterrupt = 0;
2396 }
drhc28490c2006-10-26 14:25:58 +00002397 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002398 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002399 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002400 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002401 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002402 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002403 break;
2404 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002405 errCnt++;
2406 }
drhdaffd0e2001-04-11 14:28:42 +00002407 continue;
2408 }
drh233a5312008-12-18 22:25:13 +00002409 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002410 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002411 }
drh91a66392007-09-07 01:12:32 +00002412 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002413 if( zSql==0 ){
2414 int i;
drh4c755c02004-08-08 20:22:17 +00002415 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002416 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002417 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002418 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002419 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002420 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002421 exit(1);
2422 }
drh5bb3eb92007-05-04 13:15:55 +00002423 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002424 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002425 }
2426 }else{
drh4f21c4a2008-12-10 22:15:00 +00002427 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002428 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002429 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002430 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002431 exit(1);
2432 }
drh5bb3eb92007-05-04 13:15:55 +00002433 zSql[nSql++] = '\n';
2434 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002435 nSql += len;
2436 }
drh91a66392007-09-07 01:12:32 +00002437 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2438 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002439 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002440 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002441 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002442 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002443 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002444 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002445 char zPrefix[100];
2446 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002447 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002448 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002449 }else{
shane9bd1b442009-10-23 01:27:39 +00002450 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002451 }
drh7f953e22002-07-13 17:33:45 +00002452 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002453 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002454 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002455 zErrMsg = 0;
2456 }else{
shaned2bed1c2009-10-21 03:56:54 +00002457 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002458 }
drhc49f44e2006-10-26 18:15:42 +00002459 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002460 }
2461 free(zSql);
2462 zSql = 0;
2463 nSql = 0;
2464 }
2465 }
2466 if( zSql ){
shane86f5bdb2009-10-24 02:00:07 +00002467 if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002468 free(zSql);
2469 }
danielk19772ac27622007-07-03 05:31:16 +00002470 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002471 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002472}
2473
drh67505e72002-04-19 12:34:06 +00002474/*
2475** Return a pathname which is the user's home directory. A
2476** 0 return indicates an error of some kind. Space to hold the
2477** resulting string is obtained from malloc(). The calling
2478** function should free the result.
2479*/
2480static char *find_home_dir(void){
2481 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002482
chw97185482008-11-17 08:05:31 +00002483#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002484 struct passwd *pwent;
2485 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002486 if( (pwent=getpwuid(uid)) != NULL) {
2487 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002488 }
2489#endif
2490
chw65d3c132007-11-12 21:09:10 +00002491#if defined(_WIN32_WCE)
2492 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2493 */
2494 home_dir = strdup("/");
2495#else
2496
drh164a1b62006-08-19 11:15:20 +00002497#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2498 if (!home_dir) {
2499 home_dir = getenv("USERPROFILE");
2500 }
2501#endif
2502
drh67505e72002-04-19 12:34:06 +00002503 if (!home_dir) {
2504 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002505 }
2506
drhcdb36b72006-06-12 12:57:45 +00002507#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002508 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002509 char *zDrive, *zPath;
2510 int n;
2511 zDrive = getenv("HOMEDRIVE");
2512 zPath = getenv("HOMEPATH");
2513 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002514 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002515 home_dir = malloc( n );
2516 if( home_dir==0 ) return 0;
2517 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2518 return home_dir;
2519 }
2520 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002521 }
2522#endif
2523
chw65d3c132007-11-12 21:09:10 +00002524#endif /* !_WIN32_WCE */
2525
drh67505e72002-04-19 12:34:06 +00002526 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002527 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002528 char *z = malloc( n );
2529 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002530 home_dir = z;
2531 }
drhe98d4fa2002-04-21 19:06:22 +00002532
drh67505e72002-04-19 12:34:06 +00002533 return home_dir;
2534}
2535
2536/*
2537** Read input from the file given by sqliterc_override. Or if that
2538** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002539**
2540** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002541*/
shane9bd1b442009-10-23 01:27:39 +00002542static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002543 struct callback_data *p, /* Configuration data */
2544 const char *sqliterc_override /* Name of config file. NULL to use default */
2545){
persicom7e2dfdd2002-04-18 02:46:52 +00002546 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002547 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002548 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002549 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002550 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002551 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002552
2553 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002554 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002555 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002556#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002557 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002558#endif
shane9bd1b442009-10-23 01:27:39 +00002559 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002560 }
drh4f21c4a2008-12-10 22:15:00 +00002561 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002562 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002563 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002564 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2565 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002566 }
drha959ac42007-06-20 13:10:00 +00002567 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002568 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002569 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002570 }
drha1f9b5e2004-02-14 16:31:02 +00002571 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002572 if( in ){
drhc28490c2006-10-26 14:25:58 +00002573 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002574 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002575 }
shane9bd1b442009-10-23 01:27:39 +00002576 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002577 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002578 }
drh43617e92006-03-06 20:55:46 +00002579 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002580 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002581}
2582
drh67505e72002-04-19 12:34:06 +00002583/*
drhe1e38c42003-05-04 18:30:59 +00002584** Show available command line options
2585*/
2586static const char zOptions[] =
shaneh5fc25012009-11-11 04:17:07 +00002587 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002588 " -init filename read/process named file\n"
2589 " -echo print commands before execution\n"
2590 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002591 " -bail stop after hitting an error\n"
2592 " -interactive force interactive I/O\n"
2593 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002594 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002595 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002596 " -html set output mode to HTML\n"
2597 " -line set output mode to 'line'\n"
2598 " -list set output mode to 'list'\n"
2599 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002600 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002601 " -nullvalue 'text' set text string for NULL values\n"
2602 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002603;
2604static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002605 fprintf(stderr,
2606 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2607 "FILENAME is the name of an SQLite database. A new database is created\n"
2608 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002609 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002610 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002611 }else{
2612 fprintf(stderr, "Use the -help option for additional information\n");
2613 }
2614 exit(1);
2615}
2616
2617/*
drh67505e72002-04-19 12:34:06 +00002618** Initialize the state information in data
2619*/
drh0850b532006-01-31 19:31:43 +00002620static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002621 memset(data, 0, sizeof(*data));
2622 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002623 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002624 data->showHeader = 0;
drh127f9d72010-02-23 01:47:00 +00002625 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002626 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2627 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002628 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002629}
2630
drh75897232000-05-29 14:26:00 +00002631int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002632 char *zErrMsg = 0;
2633 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002634 const char *zInitFile = 0;
2635 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002636 int i;
drhc28490c2006-10-26 14:25:58 +00002637 int rc = 0;
drh75897232000-05-29 14:26:00 +00002638
drhdaffd0e2001-04-11 14:28:42 +00002639 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002640 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002641 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002642
drh44c2eb12003-04-30 11:38:26 +00002643 /* Make sure we have a valid signal handler early, before anything
2644 ** else is done.
2645 */
drh4c504392000-10-16 22:06:40 +00002646#ifdef SIGINT
2647 signal(SIGINT, interrupt_handler);
2648#endif
drh44c2eb12003-04-30 11:38:26 +00002649
drh22fbcb82004-02-01 01:22:50 +00002650 /* Do an initial pass through the command-line argument to locate
2651 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002652 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002653 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002654 */
drh22fbcb82004-02-01 01:22:50 +00002655 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002656 char *z;
drh44c2eb12003-04-30 11:38:26 +00002657 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002658 z = argv[i];
2659 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002660 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2661 i++;
drh22fbcb82004-02-01 01:22:50 +00002662 }else if( strcmp(argv[i],"-init")==0 ){
2663 i++;
2664 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002665 /* Need to check for batch mode here to so we can avoid printing
2666 ** informational messages (like from process_sqliterc) before
2667 ** we do the actual processing of arguments later in a second pass.
2668 */
2669 }else if( strcmp(argv[i],"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002670 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002671 }else if( strcmp(argv[i],"-heap")==0 ){
2672 int j, c;
2673 const char *zSize;
2674 sqlite3_int64 szHeap;
2675
2676 zSize = argv[++i];
2677 szHeap = atoi(zSize);
2678 for(j=0; (c = zSize[j])!=0; j++){
2679 if( c=='M' ){ szHeap *= 1000000; break; }
2680 if( c=='K' ){ szHeap *= 1000; break; }
2681 if( c=='G' ){ szHeap *= 1000000000; break; }
2682 }
2683 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
2684#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2685 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2686#endif
drh44c2eb12003-04-30 11:38:26 +00002687 }
2688 }
drh22fbcb82004-02-01 01:22:50 +00002689 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002690#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002691 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2692#else
drh22fbcb82004-02-01 01:22:50 +00002693 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002694#endif
drh22fbcb82004-02-01 01:22:50 +00002695 }else{
danielk197703aded42004-11-22 05:26:27 +00002696#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002697 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002698#else
2699 data.zDbFilename = 0;
2700#endif
drh22fbcb82004-02-01 01:22:50 +00002701 }
2702 if( i<argc ){
2703 zFirstCmd = argv[i++];
2704 }
shaneh5fc25012009-11-11 04:17:07 +00002705 if( i<argc ){
2706 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2707 fprintf(stderr,"Use -help for a list of options.\n");
2708 return 1;
2709 }
drh44c2eb12003-04-30 11:38:26 +00002710 data.out = stdout;
2711
drh01b41712005-08-29 23:06:23 +00002712#ifdef SQLITE_OMIT_MEMORYDB
2713 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002714 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2715 return 1;
drh01b41712005-08-29 23:06:23 +00002716 }
2717#endif
2718
drh44c2eb12003-04-30 11:38:26 +00002719 /* Go ahead and open the database file if it already exists. If the
2720 ** file does not exist, delay opening it. This prevents empty database
2721 ** files from being created if a user mistypes the database name argument
2722 ** to the sqlite command-line tool.
2723 */
drhc8d74412004-08-31 23:41:26 +00002724 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002725 open_db(&data);
2726 }
2727
drh22fbcb82004-02-01 01:22:50 +00002728 /* Process the initialization file if there is one. If no -init option
2729 ** is given on the command line, look for a file named ~/.sqliterc and
2730 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002731 */
shane86f5bdb2009-10-24 02:00:07 +00002732 rc = process_sqliterc(&data,zInitFile);
2733 if( rc>0 ){
2734 return rc;
2735 }
drh44c2eb12003-04-30 11:38:26 +00002736
drh22fbcb82004-02-01 01:22:50 +00002737 /* Make a second pass through the command-line argument and set
2738 ** options. This second pass is delayed until after the initialization
2739 ** file is processed so that the command-line arguments will override
2740 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002741 */
drh22fbcb82004-02-01 01:22:50 +00002742 for(i=1; i<argc && argv[i][0]=='-'; i++){
2743 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002744 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002745 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002746 i++;
2747 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002748 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002749 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002750 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002751 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002752 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002753 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002754 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002755 }else if( strcmp(z,"-csv")==0 ){
2756 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002757 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002758 }else if( strcmp(z,"-separator")==0 ){
2759 i++;
shaneh5fc25012009-11-11 04:17:07 +00002760 if(i>=argc){
2761 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2762 fprintf(stderr,"Use -help for a list of options.\n");
2763 return 1;
2764 }
drh5bb3eb92007-05-04 13:15:55 +00002765 sqlite3_snprintf(sizeof(data.separator), data.separator,
2766 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002767 }else if( strcmp(z,"-nullvalue")==0 ){
2768 i++;
shaneh5fc25012009-11-11 04:17:07 +00002769 if(i>=argc){
2770 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2771 fprintf(stderr,"Use -help for a list of options.\n");
2772 return 1;
2773 }
drh5bb3eb92007-05-04 13:15:55 +00002774 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2775 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002776 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002777 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002778 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002779 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002780 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002781 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00002782 }else if( strcmp(z,"-stats")==0 ){
2783 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002784 }else if( strcmp(z,"-bail")==0 ){
2785 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002786 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002787 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002788 return 0;
drhc28490c2006-10-26 14:25:58 +00002789 }else if( strcmp(z,"-interactive")==0 ){
2790 stdin_is_interactive = 1;
2791 }else if( strcmp(z,"-batch")==0 ){
2792 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002793 }else if( strcmp(z,"-heap")==0 ){
2794 i++;
drh80e8be92006-08-29 12:04:19 +00002795 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002796 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002797 }else{
shane86f5bdb2009-10-24 02:00:07 +00002798 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002799 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002800 return 1;
2801 }
2802 }
drh44c2eb12003-04-30 11:38:26 +00002803
drh22fbcb82004-02-01 01:22:50 +00002804 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002805 /* Run just the command that follows the database name
2806 */
drh22fbcb82004-02-01 01:22:50 +00002807 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00002808 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002809 }else{
drh44c2eb12003-04-30 11:38:26 +00002810 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00002811 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00002812 if( zErrMsg!=0 ){
2813 fprintf(stderr,"Error: %s\n", zErrMsg);
2814 return rc!=0 ? rc : 1;
2815 }else if( rc!=0 ){
2816 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
2817 return rc;
drh6ff13852001-11-25 13:18:23 +00002818 }
drh75897232000-05-29 14:26:00 +00002819 }
2820 }else{
drh44c2eb12003-04-30 11:38:26 +00002821 /* Run commands received from standard input
2822 */
drhc28490c2006-10-26 14:25:58 +00002823 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002824 char *zHome;
2825 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002826 int nHistory;
drh75897232000-05-29 14:26:00 +00002827 printf(
drhb217a572000-08-22 13:40:18 +00002828 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002829 "Enter \".help\" for instructions\n"
2830 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002831 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002832 );
drh67505e72002-04-19 12:34:06 +00002833 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002834 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002835 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002836 if( (zHistory = malloc(nHistory))!=0 ){
2837 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2838 }
drh67505e72002-04-19 12:34:06 +00002839 }
danielk19774af00c62005-01-23 23:43:21 +00002840#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002841 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002842#endif
drhc28490c2006-10-26 14:25:58 +00002843 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002844 if( zHistory ){
2845 stifle_history(100);
2846 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002847 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002848 }
adamd0a3daa32006-07-28 20:16:14 +00002849 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002850 }else{
drhc28490c2006-10-26 14:25:58 +00002851 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002852 }
2853 }
drh33048c02001-10-01 14:29:22 +00002854 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00002855 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00002856 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00002857 }
drhc28490c2006-10-26 14:25:58 +00002858 return rc;
drh75897232000-05-29 14:26:00 +00002859}