blob: 78788a5bb91b418d28fdee4bd2b4da1eea98f743 [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 */
drha7e61d82011-03-12 17:02:57 +0000422 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000423 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000424 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000425};
426
427/*
428** These are the allowed modes.
429*/
drh967e8b72000-06-21 13:59:10 +0000430#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000431#define MODE_Column 1 /* One record per line in neat columns */
432#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000433#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
434#define MODE_Html 4 /* Generate an XHTML table */
435#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000436#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000437#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000438#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000439
drh66ce4d02008-02-15 17:38:06 +0000440static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000441 "line",
442 "column",
443 "list",
444 "semi",
445 "html",
drhfeac5f82004-08-01 00:10:45 +0000446 "insert",
447 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000448 "csv",
drh66ce4d02008-02-15 17:38:06 +0000449 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000450};
drh75897232000-05-29 14:26:00 +0000451
452/*
453** Number of elements in an array
454*/
drh902b9ee2008-12-05 17:17:07 +0000455#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000456
457/*
drhea678832008-12-10 19:26:22 +0000458** Compute a string length that is limited to what can be stored in
459** lower 30 bits of a 32-bit signed integer.
460*/
drh4f21c4a2008-12-10 22:15:00 +0000461static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000462 const char *z2 = z;
463 while( *z2 ){ z2++; }
464 return 0x3fffffff & (int)(z2 - z);
465}
466
467/*
drh127f9d72010-02-23 01:47:00 +0000468** A callback for the sqlite3_log() interface.
469*/
470static void shellLog(void *pArg, int iErrCode, const char *zMsg){
471 struct callback_data *p = (struct callback_data*)pArg;
472 if( p->pLog==0 ) return;
473 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
474 fflush(p->pLog);
475}
476
477/*
shane626a6e42009-10-22 17:30:15 +0000478** Output the given string as a hex-encoded blob (eg. X'1234' )
479*/
480static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
481 int i;
482 char *zBlob = (char *)pBlob;
483 fprintf(out,"X'");
484 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
485 fprintf(out,"'");
486}
487
488/*
drh28bd4bc2000-06-15 15:57:22 +0000489** Output the given string as a quoted string using SQL quoting conventions.
490*/
491static void output_quoted_string(FILE *out, const char *z){
492 int i;
493 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000494 for(i=0; z[i]; i++){
495 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000496 }
497 if( nSingle==0 ){
498 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000499 }else{
500 fprintf(out,"'");
501 while( *z ){
502 for(i=0; z[i] && z[i]!='\''; i++){}
503 if( i==0 ){
504 fprintf(out,"''");
505 z++;
506 }else if( z[i]=='\'' ){
507 fprintf(out,"%.*s''",i,z);
508 z += i+1;
509 }else{
drhcd7d2732002-02-26 23:24:26 +0000510 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000511 break;
512 }
513 }
drhcd7d2732002-02-26 23:24:26 +0000514 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000515 }
516}
517
518/*
drhfeac5f82004-08-01 00:10:45 +0000519** Output the given string as a quoted according to C or TCL quoting rules.
520*/
521static void output_c_string(FILE *out, const char *z){
522 unsigned int c;
523 fputc('"', out);
524 while( (c = *(z++))!=0 ){
525 if( c=='\\' ){
526 fputc(c, out);
527 fputc(c, out);
528 }else if( c=='\t' ){
529 fputc('\\', out);
530 fputc('t', out);
531 }else if( c=='\n' ){
532 fputc('\\', out);
533 fputc('n', out);
534 }else if( c=='\r' ){
535 fputc('\\', out);
536 fputc('r', out);
537 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000538 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000539 }else{
540 fputc(c, out);
541 }
542 }
543 fputc('"', out);
544}
545
546/*
drhc08a4f12000-06-15 16:49:48 +0000547** Output the given string with characters that are special to
548** HTML escaped.
549*/
550static void output_html_string(FILE *out, const char *z){
551 int i;
552 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000553 for(i=0; z[i]
554 && z[i]!='<'
555 && z[i]!='&'
556 && z[i]!='>'
557 && z[i]!='\"'
558 && z[i]!='\'';
559 i++){}
drhc08a4f12000-06-15 16:49:48 +0000560 if( i>0 ){
561 fprintf(out,"%.*s",i,z);
562 }
563 if( z[i]=='<' ){
564 fprintf(out,"&lt;");
565 }else if( z[i]=='&' ){
566 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000567 }else if( z[i]=='>' ){
568 fprintf(out,"&gt;");
569 }else if( z[i]=='\"' ){
570 fprintf(out,"&quot;");
571 }else if( z[i]=='\'' ){
572 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000573 }else{
574 break;
575 }
576 z += i + 1;
577 }
578}
579
580/*
drhc49f44e2006-10-26 18:15:42 +0000581** If a field contains any character identified by a 1 in the following
582** array, then the string must be quoted for CSV.
583*/
584static const char needCsvQuote[] = {
585 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
586 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
587 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
592 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
601};
602
603/*
drh8e64d1c2004-10-07 00:32:39 +0000604** Output a single term of CSV. Actually, p->separator is used for
605** the separator, which may or may not be a comma. p->nullvalue is
606** the null value. Strings are quoted using ANSI-C rules. Numbers
607** appear outside of quotes.
608*/
609static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000610 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000611 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000612 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000613 }else{
drhc49f44e2006-10-26 18:15:42 +0000614 int i;
drh4f21c4a2008-12-10 22:15:00 +0000615 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000616 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000617 if( needCsvQuote[((unsigned char*)z)[i]]
618 || (z[i]==p->separator[0] &&
619 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000620 i = 0;
621 break;
622 }
623 }
624 if( i==0 ){
625 putc('"', out);
626 for(i=0; z[i]; i++){
627 if( z[i]=='"' ) putc('"', out);
628 putc(z[i], out);
629 }
630 putc('"', out);
631 }else{
632 fprintf(out, "%s", z);
633 }
drh8e64d1c2004-10-07 00:32:39 +0000634 }
635 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000636 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000637 }
638}
639
danielk19774af00c62005-01-23 23:43:21 +0000640#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000641/*
drh4c504392000-10-16 22:06:40 +0000642** This routine runs when the user presses Ctrl-C
643*/
644static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000645 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000646 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000647 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000648}
danielk19774af00c62005-01-23 23:43:21 +0000649#endif
drh4c504392000-10-16 22:06:40 +0000650
651/*
shane626a6e42009-10-22 17:30:15 +0000652** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000653** invokes for each row of a query result.
654*/
shane626a6e42009-10-22 17:30:15 +0000655static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000656 int i;
657 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000658
drh75897232000-05-29 14:26:00 +0000659 switch( p->mode ){
660 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000661 int w = 5;
drh6a535342001-10-19 16:44:56 +0000662 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000663 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000664 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000665 if( len>w ) w = len;
666 }
drh75897232000-05-29 14:26:00 +0000667 if( p->cnt++>0 ) fprintf(p->out,"\n");
668 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000669 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000670 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000671 }
672 break;
673 }
danielk19770d78bae2008-01-03 07:09:48 +0000674 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000675 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000676 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000677 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000678 int w, n;
679 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000680 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000681 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000682 w = 0;
drh75897232000-05-29 14:26:00 +0000683 }
drha0c66f52000-07-29 13:20:21 +0000684 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000685 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000686 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000687 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000688 if( w<n ) w = n;
689 }
690 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000691 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000692 }
693 if( p->showHeader ){
694 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
695 }
696 }
697 if( p->showHeader ){
698 for(i=0; i<nArg; i++){
699 int w;
700 if( i<ArraySize(p->actualWidth) ){
701 w = p->actualWidth[i];
702 }else{
703 w = 10;
704 }
705 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
706 "----------------------------------------------------------",
707 i==nArg-1 ? "\n": " ");
708 }
drh75897232000-05-29 14:26:00 +0000709 }
710 }
drh6a535342001-10-19 16:44:56 +0000711 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000712 for(i=0; i<nArg; i++){
713 int w;
drha0c66f52000-07-29 13:20:21 +0000714 if( i<ArraySize(p->actualWidth) ){
715 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000716 }else{
717 w = 10;
718 }
drhea678832008-12-10 19:26:22 +0000719 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000720 strlen30(azArg[i])>w ){
721 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000722 }
drhc61053b2000-06-04 12:58:36 +0000723 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000724 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000725 }
726 break;
727 }
drhe3710332000-09-29 13:30:53 +0000728 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000729 case MODE_List: {
730 if( p->cnt++==0 && p->showHeader ){
731 for(i=0; i<nArg; i++){
732 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
733 }
734 }
drh6a535342001-10-19 16:44:56 +0000735 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000736 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000737 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000738 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000739 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000740 if( i<nArg-1 ){
741 fprintf(p->out, "%s", p->separator);
742 }else if( p->mode==MODE_Semi ){
743 fprintf(p->out, ";\n");
744 }else{
745 fprintf(p->out, "\n");
746 }
drh75897232000-05-29 14:26:00 +0000747 }
748 break;
749 }
drh1e5d0e92000-05-31 23:33:17 +0000750 case MODE_Html: {
751 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000752 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000753 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000754 fprintf(p->out,"<TH>");
755 output_html_string(p->out, azCol[i]);
756 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000757 }
mihailim57c591a2008-06-23 21:26:05 +0000758 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000759 }
drh6a535342001-10-19 16:44:56 +0000760 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000761 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000762 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000763 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000764 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000765 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000766 }
mihailim57c591a2008-06-23 21:26:05 +0000767 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000768 break;
769 }
drhfeac5f82004-08-01 00:10:45 +0000770 case MODE_Tcl: {
771 if( p->cnt++==0 && p->showHeader ){
772 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000773 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000774 fprintf(p->out, "%s", p->separator);
775 }
776 fprintf(p->out,"\n");
777 }
778 if( azArg==0 ) break;
779 for(i=0; i<nArg; i++){
780 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
781 fprintf(p->out, "%s", p->separator);
782 }
783 fprintf(p->out,"\n");
784 break;
785 }
drh8e64d1c2004-10-07 00:32:39 +0000786 case MODE_Csv: {
787 if( p->cnt++==0 && p->showHeader ){
788 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000789 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000790 }
791 fprintf(p->out,"\n");
792 }
793 if( azArg==0 ) break;
794 for(i=0; i<nArg; i++){
795 output_csv(p, azArg[i], i<nArg-1);
796 }
797 fprintf(p->out,"\n");
798 break;
799 }
drh28bd4bc2000-06-15 15:57:22 +0000800 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000801 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000802 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000803 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000804 for(i=0; i<nArg; i++){
805 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000806 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000807 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000808 }else if( aiType && aiType[i]==SQLITE_TEXT ){
809 if( zSep[0] ) fprintf(p->out,"%s",zSep);
810 output_quoted_string(p->out, azArg[i]);
811 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
812 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000813 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
814 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
815 int nBlob = sqlite3_column_bytes(p->pStmt, i);
816 if( zSep[0] ) fprintf(p->out,"%s",zSep);
817 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000818 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000819 fprintf(p->out,"%s%s",zSep, azArg[i]);
820 }else{
821 if( zSep[0] ) fprintf(p->out,"%s",zSep);
822 output_quoted_string(p->out, azArg[i]);
823 }
824 }
825 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000826 break;
drh28bd4bc2000-06-15 15:57:22 +0000827 }
persicom1d0b8722002-04-18 02:53:04 +0000828 }
drh75897232000-05-29 14:26:00 +0000829 return 0;
830}
831
832/*
shane626a6e42009-10-22 17:30:15 +0000833** This is the callback routine that the SQLite library
834** invokes for each row of a query result.
835*/
836static int callback(void *pArg, int nArg, char **azArg, char **azCol){
837 /* since we don't have type info, call the shell_callback with a NULL value */
838 return shell_callback(pArg, nArg, azArg, azCol, NULL);
839}
840
841/*
drh33048c02001-10-01 14:29:22 +0000842** Set the destination table field of the callback_data structure to
843** the name of the table given. Escape any quote characters in the
844** table name.
845*/
846static void set_table_name(struct callback_data *p, const char *zName){
847 int i, n;
848 int needQuote;
849 char *z;
850
851 if( p->zDestTable ){
852 free(p->zDestTable);
853 p->zDestTable = 0;
854 }
855 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000856 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000857 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000858 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000859 needQuote = 1;
860 if( zName[i]=='\'' ) n++;
861 }
862 }
863 if( needQuote ) n += 2;
864 z = p->zDestTable = malloc( n+1 );
865 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000866 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000867 exit(1);
868 }
869 n = 0;
870 if( needQuote ) z[n++] = '\'';
871 for(i=0; zName[i]; i++){
872 z[n++] = zName[i];
873 if( zName[i]=='\'' ) z[n++] = '\'';
874 }
875 if( needQuote ) z[n++] = '\'';
876 z[n] = 0;
877}
878
danielk19772a02e332004-06-05 08:04:36 +0000879/* zIn is either a pointer to a NULL-terminated string in memory obtained
880** from malloc(), or a NULL pointer. The string pointed to by zAppend is
881** added to zIn, and the result returned in memory obtained from malloc().
882** zIn, if it was not NULL, is freed.
883**
884** If the third argument, quote, is not '\0', then it is used as a
885** quote character for zAppend.
886*/
drhc28490c2006-10-26 14:25:58 +0000887static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000888 int len;
889 int i;
drh4f21c4a2008-12-10 22:15:00 +0000890 int nAppend = strlen30(zAppend);
891 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000892
893 len = nAppend+nIn+1;
894 if( quote ){
895 len += 2;
896 for(i=0; i<nAppend; i++){
897 if( zAppend[i]==quote ) len++;
898 }
899 }
900
901 zIn = (char *)realloc(zIn, len);
902 if( !zIn ){
903 return 0;
904 }
905
906 if( quote ){
907 char *zCsr = &zIn[nIn];
908 *zCsr++ = quote;
909 for(i=0; i<nAppend; i++){
910 *zCsr++ = zAppend[i];
911 if( zAppend[i]==quote ) *zCsr++ = quote;
912 }
913 *zCsr++ = quote;
914 *zCsr++ = '\0';
915 assert( (zCsr-zIn)==len );
916 }else{
917 memcpy(&zIn[nIn], zAppend, nAppend);
918 zIn[len-1] = '\0';
919 }
920
921 return zIn;
922}
923
drhdd3d4592004-08-30 01:54:05 +0000924
925/*
926** Execute a query statement that has a single result column. Print
927** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000928**
929** This is used, for example, to show the schema of the database by
930** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000931*/
drh157e29a2009-05-21 15:15:00 +0000932static int run_table_dump_query(
933 FILE *out, /* Send output here */
934 sqlite3 *db, /* Database to query */
935 const char *zSelect, /* SELECT statement to extract content */
936 const char *zFirstRow /* Print before first row, if not NULL */
937){
drhdd3d4592004-08-30 01:54:05 +0000938 sqlite3_stmt *pSelect;
939 int rc;
940 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
941 if( rc!=SQLITE_OK || !pSelect ){
942 return rc;
943 }
944 rc = sqlite3_step(pSelect);
945 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000946 if( zFirstRow ){
947 fprintf(out, "%s", zFirstRow);
948 zFirstRow = 0;
949 }
drhdd3d4592004-08-30 01:54:05 +0000950 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
951 rc = sqlite3_step(pSelect);
952 }
953 return sqlite3_finalize(pSelect);
954}
955
shane626a6e42009-10-22 17:30:15 +0000956/*
957** Allocate space and save off current error string.
958*/
959static char *save_err_msg(
960 sqlite3 *db /* Database to query */
961){
962 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
963 char *zErrMsg = sqlite3_malloc(nErrMsg);
964 if( zErrMsg ){
965 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
966 }
967 return zErrMsg;
968}
969
970/*
shaneh642d8b82010-07-28 16:05:34 +0000971** Display memory stats.
972*/
973static int display_stats(
974 sqlite3 *db, /* Database to query */
975 struct callback_data *pArg, /* Pointer to struct callback_data */
976 int bReset /* True to reset the stats */
977){
978 int iCur;
979 int iHiwtr;
980
981 if( pArg && pArg->out ){
982
983 iHiwtr = iCur = -1;
984 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +0000985 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000986 iHiwtr = iCur = -1;
987 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +0000988 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000989/*
990** Not currently used by the CLI.
991** iHiwtr = iCur = -1;
992** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
993** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
994*/
995 iHiwtr = iCur = -1;
996 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
997 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
998/*
999** Not currently used by the CLI.
1000** iHiwtr = iCur = -1;
1001** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1002** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1003*/
1004 iHiwtr = iCur = -1;
1005 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1006 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1007 iHiwtr = iCur = -1;
1008 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1009 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1010 iHiwtr = iCur = -1;
1011 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1012 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1013 iHiwtr = iCur = -1;
1014 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1015 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1016#ifdef YYTRACKMAXSTACKDEPTH
1017 iHiwtr = iCur = -1;
1018 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1019 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1020#endif
1021 }
1022
1023 if( pArg && pArg->out && db ){
1024 iHiwtr = iCur = -1;
1025 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1026 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001027 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1028 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1029 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1030 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1031 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1032 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001033 iHiwtr = iCur = -1;
1034 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh233f8162010-07-28 17:36:11 +00001035 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001036 iHiwtr = iCur = -1;
1037 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1038 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1039 iHiwtr = iCur = -1;
1040 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1041 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1042 }
1043
1044 if( pArg && pArg->out && db && pArg->pStmt ){
1045 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1046 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1047 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1048 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1049 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1050 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1051 }
1052
1053 return 0;
1054}
1055
1056/*
shane626a6e42009-10-22 17:30:15 +00001057** Execute a statement or set of statements. Print
1058** any result rows/columns depending on the current mode
1059** set via the supplied callback.
1060**
1061** This is very similar to SQLite's built-in sqlite3_exec()
1062** function except it takes a slightly different callback
1063** and callback data argument.
1064*/
1065static int shell_exec(
1066 sqlite3 *db, /* An open database */
1067 const char *zSql, /* SQL to be evaluated */
1068 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1069 /* (not the same as sqlite3_exec) */
1070 struct callback_data *pArg, /* Pointer to struct callback_data */
1071 char **pzErrMsg /* Error msg written here */
1072){
dan4564ced2010-01-05 04:59:56 +00001073 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1074 int rc = SQLITE_OK; /* Return Code */
1075 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001076
1077 if( pzErrMsg ){
1078 *pzErrMsg = NULL;
1079 }
1080
shaneb9fc17d2009-10-22 21:23:35 +00001081 while( zSql[0] && (SQLITE_OK == rc) ){
1082 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1083 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001084 if( pzErrMsg ){
1085 *pzErrMsg = save_err_msg(db);
1086 }
1087 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001088 if( !pStmt ){
1089 /* this happens for a comment or white-space */
1090 zSql = zLeftover;
1091 while( isspace(zSql[0]) ) zSql++;
1092 continue;
1093 }
shane626a6e42009-10-22 17:30:15 +00001094
shaneh642d8b82010-07-28 16:05:34 +00001095 /* save off the prepared statment handle and reset row count */
1096 if( pArg ){
1097 pArg->pStmt = pStmt;
1098 pArg->cnt = 0;
1099 }
1100
shanehb7977c52010-01-18 18:17:10 +00001101 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001102 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001103 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001104 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001105 }
shanehb7977c52010-01-18 18:17:10 +00001106
shaneb9fc17d2009-10-22 21:23:35 +00001107 /* perform the first step. this will tell us if we
1108 ** have a result set or not and how wide it is.
1109 */
1110 rc = sqlite3_step(pStmt);
1111 /* if we have a result set... */
1112 if( SQLITE_ROW == rc ){
1113 /* if we have a callback... */
1114 if( xCallback ){
1115 /* allocate space for col name ptr, value ptr, and type */
1116 int nCol = sqlite3_column_count(pStmt);
1117 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1118 if( !pData ){
1119 rc = SQLITE_NOMEM;
1120 }else{
1121 char **azCols = (char **)pData; /* Names of result columns */
1122 char **azVals = &azCols[nCol]; /* Results */
1123 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1124 int i;
1125 assert(sizeof(int) <= sizeof(char *));
1126 /* save off ptrs to column names */
1127 for(i=0; i<nCol; i++){
1128 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1129 }
shaneb9fc17d2009-10-22 21:23:35 +00001130 do{
1131 /* extract the data and data types */
1132 for(i=0; i<nCol; i++){
1133 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1134 aiTypes[i] = sqlite3_column_type(pStmt, i);
1135 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1136 rc = SQLITE_NOMEM;
1137 break; /* from for */
1138 }
1139 } /* end for */
1140
1141 /* if data and types extracted successfully... */
1142 if( SQLITE_ROW == rc ){
1143 /* call the supplied callback with the result row data */
1144 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1145 rc = SQLITE_ABORT;
1146 }else{
1147 rc = sqlite3_step(pStmt);
1148 }
1149 }
1150 } while( SQLITE_ROW == rc );
1151 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001152 }
1153 }else{
1154 do{
1155 rc = sqlite3_step(pStmt);
1156 } while( rc == SQLITE_ROW );
1157 }
1158 }
1159
shaneh642d8b82010-07-28 16:05:34 +00001160 /* print usage stats if stats on */
1161 if( pArg && pArg->statsOn ){
1162 display_stats(db, pArg, 0);
1163 }
1164
dan4564ced2010-01-05 04:59:56 +00001165 /* Finalize the statement just executed. If this fails, save a
1166 ** copy of the error message. Otherwise, set zSql to point to the
1167 ** next statement to execute. */
1168 rc = sqlite3_finalize(pStmt);
1169 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001170 zSql = zLeftover;
1171 while( isspace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001172 }else if( pzErrMsg ){
1173 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001174 }
shaneh642d8b82010-07-28 16:05:34 +00001175
1176 /* clear saved stmt handle */
1177 if( pArg ){
1178 pArg->pStmt = NULL;
1179 }
shane626a6e42009-10-22 17:30:15 +00001180 }
shaneb9fc17d2009-10-22 21:23:35 +00001181 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001182
1183 return rc;
1184}
1185
drhdd3d4592004-08-30 01:54:05 +00001186
drh33048c02001-10-01 14:29:22 +00001187/*
drh4c653a02000-06-07 01:27:47 +00001188** This is a different callback routine used for dumping the database.
1189** Each row received by this callback consists of a table name,
1190** the table type ("index" or "table") and SQL to create the table.
1191** This routine should print text sufficient to recreate the table.
1192*/
1193static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001194 int rc;
1195 const char *zTable;
1196 const char *zType;
1197 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001198 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001199 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001200
drh902b9ee2008-12-05 17:17:07 +00001201 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001202 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001203 zTable = azArg[0];
1204 zType = azArg[1];
1205 zSql = azArg[2];
1206
drh00b950d2005-09-11 02:03:03 +00001207 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001208 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001209 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1210 fprintf(p->out, "ANALYZE sqlite_master;\n");
1211 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1212 return 0;
drh45e29d82006-11-20 16:21:10 +00001213 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1214 char *zIns;
1215 if( !p->writableSchema ){
1216 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1217 p->writableSchema = 1;
1218 }
1219 zIns = sqlite3_mprintf(
1220 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1221 "VALUES('table','%q','%q',0,'%q');",
1222 zTable, zTable, zSql);
1223 fprintf(p->out, "%s\n", zIns);
1224 sqlite3_free(zIns);
1225 return 0;
drh00b950d2005-09-11 02:03:03 +00001226 }else{
1227 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001228 }
danielk19772a02e332004-06-05 08:04:36 +00001229
1230 if( strcmp(zType, "table")==0 ){
1231 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001232 char *zSelect = 0;
1233 char *zTableInfo = 0;
1234 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001235 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001236
1237 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1238 zTableInfo = appendText(zTableInfo, zTable, '"');
1239 zTableInfo = appendText(zTableInfo, ");", 0);
1240
1241 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001242 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001243 if( rc!=SQLITE_OK || !pTableInfo ){
1244 return 1;
1245 }
1246
1247 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1248 zTmp = appendText(zTmp, zTable, '"');
1249 if( zTmp ){
1250 zSelect = appendText(zSelect, zTmp, '\'');
1251 }
1252 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1253 rc = sqlite3_step(pTableInfo);
1254 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001255 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001256 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001257 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001258 rc = sqlite3_step(pTableInfo);
1259 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001260 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001261 }else{
1262 zSelect = appendText(zSelect, ") ", 0);
1263 }
drh157e29a2009-05-21 15:15:00 +00001264 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001265 }
1266 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001267 if( rc!=SQLITE_OK || nRow==0 ){
1268 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001269 return 1;
1270 }
1271 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1272 zSelect = appendText(zSelect, zTable, '"');
1273
drh157e29a2009-05-21 15:15:00 +00001274 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001275 if( rc==SQLITE_CORRUPT ){
1276 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001277 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001278 }
danielk19772a02e332004-06-05 08:04:36 +00001279 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001280 }
drh4c653a02000-06-07 01:27:47 +00001281 return 0;
1282}
1283
1284/*
drh45e29d82006-11-20 16:21:10 +00001285** Run zQuery. Use dump_callback() as the callback routine so that
1286** the contents of the query are output as SQL statements.
1287**
drhdd3d4592004-08-30 01:54:05 +00001288** If we get a SQLITE_CORRUPT error, rerun the query after appending
1289** "ORDER BY rowid DESC" to the end.
1290*/
1291static int run_schema_dump_query(
1292 struct callback_data *p,
1293 const char *zQuery,
1294 char **pzErrMsg
1295){
1296 int rc;
1297 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1298 if( rc==SQLITE_CORRUPT ){
1299 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001300 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001301 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1302 zQ2 = malloc( len+100 );
1303 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001304 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001305 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1306 free(zQ2);
1307 }
1308 return rc;
1309}
1310
1311/*
drh75897232000-05-29 14:26:00 +00001312** Text of a help message
1313*/
persicom1d0b8722002-04-18 02:53:04 +00001314static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001315 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001316 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001317 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001318 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001319 " If TABLE specified, only dump tables matching\n"
1320 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001321 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001322 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001323 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1324 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001325 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001326 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001327 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001328 ".indices ?TABLE? Show names of all indices\n"
1329 " If TABLE specified, only show indices for tables\n"
1330 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001331#ifdef SQLITE_ENABLE_IOTRACE
1332 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1333#endif
drh70df4fe2006-06-13 15:12:21 +00001334#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001335 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001336#endif
drh127f9d72010-02-23 01:47:00 +00001337 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001338 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001339 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001340 " column Left-aligned columns. (See .width)\n"
1341 " html HTML <table> code\n"
1342 " insert SQL insert statements for TABLE\n"
1343 " line One value per line\n"
1344 " list Values delimited by .separator string\n"
1345 " tabs Tab-separated values\n"
1346 " tcl TCL list elements\n"
1347 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001348 ".output FILENAME Send output to FILENAME\n"
1349 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001350 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001351 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001352 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001353 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001354 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001355 " If TABLE specified, only show tables matching\n"
1356 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001357 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001358 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001359 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001360 ".tables ?TABLE? List names of tables\n"
1361 " If TABLE specified, only list tables matching\n"
1362 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001363 ".timeout MS Try opening locked tables for MS milliseconds\n"
shanehe2aa9d72009-11-06 17:20:17 +00001364 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001365;
1366
shaneb320ccd2009-10-21 03:42:58 +00001367static char zTimerHelp[] =
1368 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1369;
1370
drhdaffd0e2001-04-11 14:28:42 +00001371/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001372static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001373
drh75897232000-05-29 14:26:00 +00001374/*
drh44c2eb12003-04-30 11:38:26 +00001375** Make sure the database is open. If it is not, then open it. If
1376** the database fails to open, print an error message and exit.
1377*/
1378static void open_db(struct callback_data *p){
1379 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001380 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001381 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001382 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1383 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1384 shellstaticFunc, 0, 0);
1385 }
1386 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001387 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001388 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001389 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001390 }
drhc2e87a32006-06-27 15:16:14 +00001391#ifndef SQLITE_OMIT_LOAD_EXTENSION
1392 sqlite3_enable_load_extension(p->db, 1);
1393#endif
drh44c2eb12003-04-30 11:38:26 +00001394 }
1395}
1396
1397/*
drhfeac5f82004-08-01 00:10:45 +00001398** Do C-language style dequoting.
1399**
1400** \t -> tab
1401** \n -> newline
1402** \r -> carriage return
1403** \NNN -> ascii character NNN in octal
1404** \\ -> backslash
1405*/
1406static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001407 int i, j;
1408 char c;
drhfeac5f82004-08-01 00:10:45 +00001409 for(i=j=0; (c = z[i])!=0; i++, j++){
1410 if( c=='\\' ){
1411 c = z[++i];
1412 if( c=='n' ){
1413 c = '\n';
1414 }else if( c=='t' ){
1415 c = '\t';
1416 }else if( c=='r' ){
1417 c = '\r';
1418 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001419 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001420 if( z[i+1]>='0' && z[i+1]<='7' ){
1421 i++;
1422 c = (c<<3) + z[i] - '0';
1423 if( z[i+1]>='0' && z[i+1]<='7' ){
1424 i++;
1425 c = (c<<3) + z[i] - '0';
1426 }
1427 }
1428 }
1429 }
1430 z[j] = c;
1431 }
1432 z[j] = 0;
1433}
1434
1435/*
drhc28490c2006-10-26 14:25:58 +00001436** Interpret zArg as a boolean value. Return either 0 or 1.
1437*/
1438static int booleanValue(char *zArg){
1439 int val = atoi(zArg);
1440 int j;
1441 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001442 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001443 }
1444 if( strcmp(zArg,"on")==0 ){
1445 val = 1;
1446 }else if( strcmp(zArg,"yes")==0 ){
1447 val = 1;
1448 }
1449 return val;
1450}
1451
1452/*
drh75897232000-05-29 14:26:00 +00001453** If an input line begins with "." then invoke this routine to
1454** process that line.
drh67505e72002-04-19 12:34:06 +00001455**
drh47ad6842006-11-08 12:25:42 +00001456** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001457*/
drh44c2eb12003-04-30 11:38:26 +00001458static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001459 int i = 1;
1460 int nArg = 0;
1461 int n, c;
drh67505e72002-04-19 12:34:06 +00001462 int rc = 0;
drh75897232000-05-29 14:26:00 +00001463 char *azArg[50];
1464
1465 /* Parse the input line into tokens.
1466 */
1467 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001468 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001469 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001470 if( zLine[i]=='\'' || zLine[i]=='"' ){
1471 int delim = zLine[i++];
1472 azArg[nArg++] = &zLine[i];
1473 while( zLine[i] && zLine[i]!=delim ){ i++; }
1474 if( zLine[i]==delim ){
1475 zLine[i++] = 0;
1476 }
drhfeac5f82004-08-01 00:10:45 +00001477 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001478 }else{
1479 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001480 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001481 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001482 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001483 }
1484 }
1485
1486 /* Process the input line.
1487 */
shane9bd1b442009-10-23 01:27:39 +00001488 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001489 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001490 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001491 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001492 const char *zDestFile;
1493 const char *zDb;
1494 sqlite3 *pDest;
1495 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001496 if( nArg==2 ){
1497 zDestFile = azArg[1];
1498 zDb = "main";
1499 }else{
1500 zDestFile = azArg[2];
1501 zDb = azArg[1];
1502 }
1503 rc = sqlite3_open(zDestFile, &pDest);
1504 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001505 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001506 sqlite3_close(pDest);
1507 return 1;
1508 }
drhdc2c4912009-02-04 22:46:47 +00001509 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001510 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1511 if( pBackup==0 ){
1512 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1513 sqlite3_close(pDest);
1514 return 1;
1515 }
1516 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1517 sqlite3_backup_finish(pBackup);
1518 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001519 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001520 }else{
1521 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001522 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001523 }
1524 sqlite3_close(pDest);
1525 }else
1526
shanehe2aa9d72009-11-06 17:20:17 +00001527 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001528 bail_on_error = booleanValue(azArg[1]);
1529 }else
1530
shanehe2aa9d72009-11-06 17:20:17 +00001531 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001532 struct callback_data data;
1533 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001534 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001535 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001536 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001537 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001538 data.colWidth[0] = 3;
1539 data.colWidth[1] = 15;
1540 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001541 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001542 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001543 if( zErrMsg ){
1544 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001545 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001546 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001547 }
1548 }else
1549
shanehe2aa9d72009-11-06 17:20:17 +00001550 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh4c653a02000-06-07 01:27:47 +00001551 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001552 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001553 /* When playing back a "dump", the content might appear in an order
1554 ** which causes immediate foreign key constraints to be violated.
1555 ** So disable foreign-key constraint enforcement to prevent problems. */
1556 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001557 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001558 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001559 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001560 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001561 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001562 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00001563 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1564 );
1565 run_schema_dump_query(p,
1566 "SELECT name, type, sql FROM sqlite_master "
1567 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00001568 );
1569 run_table_dump_query(p->out, p->db,
1570 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001571 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001572 );
drh4c653a02000-06-07 01:27:47 +00001573 }else{
1574 int i;
drhdd3d4592004-08-30 01:54:05 +00001575 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001576 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001577 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001578 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001579 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001580 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001581 run_table_dump_query(p->out, p->db,
1582 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001583 "WHERE sql NOT NULL"
1584 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001585 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001586 );
danielk1977bc6ada42004-06-30 08:20:16 +00001587 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001588 }
1589 }
drh45e29d82006-11-20 16:21:10 +00001590 if( p->writableSchema ){
1591 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1592 p->writableSchema = 0;
1593 }
drh93f41e52008-08-11 19:12:34 +00001594 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001595 if( zErrMsg ){
1596 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001597 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001598 }else{
1599 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001600 }
1601 }else
drh75897232000-05-29 14:26:00 +00001602
shanehe2aa9d72009-11-06 17:20:17 +00001603 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001604 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001605 }else
1606
shanehe2aa9d72009-11-06 17:20:17 +00001607 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001608 rc = 2;
drh75897232000-05-29 14:26:00 +00001609 }else
1610
shanehe2aa9d72009-11-06 17:20:17 +00001611 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001612 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001613 if(val == 1) {
1614 if(!p->explainPrev.valid) {
1615 p->explainPrev.valid = 1;
1616 p->explainPrev.mode = p->mode;
1617 p->explainPrev.showHeader = p->showHeader;
1618 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1619 }
1620 /* We could put this code under the !p->explainValid
1621 ** condition so that it does not execute if we are already in
1622 ** explain mode. However, always executing it allows us an easy
1623 ** was to reset to explain mode in case the user previously
1624 ** did an .explain followed by a .width, .mode or .header
1625 ** command.
1626 */
danielk19770d78bae2008-01-03 07:09:48 +00001627 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001628 p->showHeader = 1;
1629 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001630 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001631 p->colWidth[1] = 13; /* opcode */
1632 p->colWidth[2] = 4; /* P1 */
1633 p->colWidth[3] = 4; /* P2 */
1634 p->colWidth[4] = 4; /* P3 */
1635 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001636 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001637 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001638 }else if (p->explainPrev.valid) {
1639 p->explainPrev.valid = 0;
1640 p->mode = p->explainPrev.mode;
1641 p->showHeader = p->explainPrev.showHeader;
1642 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1643 }
drh75897232000-05-29 14:26:00 +00001644 }else
1645
drhc28490c2006-10-26 14:25:58 +00001646 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001647 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001648 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001649 }else
1650
1651 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001652 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001653 if( HAS_TIMER ){
1654 fprintf(stderr,"%s",zTimerHelp);
1655 }
drh75897232000-05-29 14:26:00 +00001656 }else
1657
shanehe2aa9d72009-11-06 17:20:17 +00001658 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001659 char *zTable = azArg[2]; /* Insert data into this table */
1660 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001661 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001662 int nCol; /* Number of columns in the table */
1663 int nByte; /* Number of bytes in an SQL string */
1664 int i, j; /* Loop counters */
1665 int nSep; /* Number of bytes in p->separator[] */
1666 char *zSql; /* An SQL statement */
1667 char *zLine; /* A single line of input from the file */
1668 char **azCol; /* zLine[] broken up into columns */
1669 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001670 FILE *in; /* The input file */
1671 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001672
drha543c822006-06-08 16:10:14 +00001673 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001674 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001675 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001676 fprintf(stderr, "Error: non-null separator required for import\n");
1677 return 1;
drhfeac5f82004-08-01 00:10:45 +00001678 }
1679 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
shane916f9612009-10-23 00:37:15 +00001680 if( zSql==0 ){
1681 fprintf(stderr, "Error: out of memory\n");
1682 return 1;
1683 }
drh4f21c4a2008-12-10 22:15:00 +00001684 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001685 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001686 sqlite3_free(zSql);
1687 if( rc ){
shane916f9612009-10-23 00:37:15 +00001688 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001689 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001690 return 1;
drhfeac5f82004-08-01 00:10:45 +00001691 }
shane916f9612009-10-23 00:37:15 +00001692 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001693 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001694 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001695 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001696 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001697 if( zSql==0 ){
1698 fprintf(stderr, "Error: out of memory\n");
1699 return 1;
1700 }
drhfeac5f82004-08-01 00:10:45 +00001701 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001702 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001703 for(i=1; i<nCol; i++){
1704 zSql[j++] = ',';
1705 zSql[j++] = '?';
1706 }
1707 zSql[j++] = ')';
1708 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001709 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001710 free(zSql);
1711 if( rc ){
1712 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001713 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001714 return 1;
drhfeac5f82004-08-01 00:10:45 +00001715 }
1716 in = fopen(zFile, "rb");
1717 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001718 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001719 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001720 return 1;
drhfeac5f82004-08-01 00:10:45 +00001721 }
1722 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001723 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001724 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001725 fclose(in);
shane916f9612009-10-23 00:37:15 +00001726 sqlite3_finalize(pStmt);
1727 return 1;
drh43617e92006-03-06 20:55:46 +00001728 }
drhfeac5f82004-08-01 00:10:45 +00001729 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1730 zCommit = "COMMIT";
1731 while( (zLine = local_getline(0, in))!=0 ){
1732 char *z;
1733 i = 0;
drhb860bc92004-08-04 15:16:55 +00001734 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001735 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001736 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001737 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1738 *z = 0;
1739 i++;
drhb860bc92004-08-04 15:16:55 +00001740 if( i<nCol ){
1741 azCol[i] = &z[nSep];
1742 z += nSep-1;
1743 }
drhfeac5f82004-08-01 00:10:45 +00001744 }
shane916f9612009-10-23 00:37:15 +00001745 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001746 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001747 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001748 fprintf(stderr,
1749 "Error: %s line %d: expected %d columns of data but found %d\n",
1750 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001751 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001752 free(zLine);
shane916f9612009-10-23 00:37:15 +00001753 rc = 1;
1754 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001755 }
drhfeac5f82004-08-01 00:10:45 +00001756 for(i=0; i<nCol; i++){
1757 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1758 }
1759 sqlite3_step(pStmt);
1760 rc = sqlite3_reset(pStmt);
1761 free(zLine);
1762 if( rc!=SQLITE_OK ){
1763 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1764 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001765 rc = 1;
shane916f9612009-10-23 00:37:15 +00001766 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001767 }
shane916f9612009-10-23 00:37:15 +00001768 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001769 free(azCol);
1770 fclose(in);
1771 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001772 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001773 }else
1774
shanehe2aa9d72009-11-06 17:20:17 +00001775 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001776 struct callback_data data;
1777 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001778 open_db(p);
drh75897232000-05-29 14:26:00 +00001779 memcpy(&data, p, sizeof(data));
1780 data.showHeader = 0;
1781 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001782 if( nArg==1 ){
1783 rc = sqlite3_exec(p->db,
1784 "SELECT name FROM sqlite_master "
1785 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1786 "UNION ALL "
1787 "SELECT name FROM sqlite_temp_master "
1788 "WHERE type='index' "
1789 "ORDER BY 1",
1790 callback, &data, &zErrMsg
1791 );
1792 }else{
1793 zShellStatic = azArg[1];
1794 rc = sqlite3_exec(p->db,
1795 "SELECT name FROM sqlite_master "
1796 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1797 "UNION ALL "
1798 "SELECT name FROM sqlite_temp_master "
1799 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1800 "ORDER BY 1",
1801 callback, &data, &zErrMsg
1802 );
1803 zShellStatic = 0;
1804 }
drh75897232000-05-29 14:26:00 +00001805 if( zErrMsg ){
1806 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001807 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001808 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001809 }else if( rc != SQLITE_OK ){
1810 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1811 rc = 1;
drh75897232000-05-29 14:26:00 +00001812 }
1813 }else
1814
drhae5e4452007-05-03 17:18:36 +00001815#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001816 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001817 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001818 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1819 iotrace = 0;
1820 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001821 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001822 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001823 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001824 iotrace = stdout;
1825 }else{
1826 iotrace = fopen(azArg[1], "w");
1827 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001828 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001829 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001830 rc = 1;
drhb0603412007-02-28 04:47:26 +00001831 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001832 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001833 }
1834 }
1835 }else
drhae5e4452007-05-03 17:18:36 +00001836#endif
drhb0603412007-02-28 04:47:26 +00001837
drh70df4fe2006-06-13 15:12:21 +00001838#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001839 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1840 const char *zFile, *zProc;
1841 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001842 zFile = azArg[1];
1843 zProc = nArg>=3 ? azArg[2] : 0;
1844 open_db(p);
1845 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1846 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001847 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001848 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001849 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001850 }
1851 }else
drh70df4fe2006-06-13 15:12:21 +00001852#endif
drh1e397f82006-06-08 15:28:43 +00001853
drhc8ba2122011-03-23 11:16:22 +00001854 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00001855 const char *zFile = azArg[1];
1856 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1857 fclose(p->pLog);
1858 p->pLog = 0;
1859 }
1860 if( strcmp(zFile,"stdout")==0 ){
1861 p->pLog = stdout;
1862 }else if( strcmp(zFile, "stderr")==0 ){
1863 p->pLog = stderr;
1864 }else if( strcmp(zFile, "off")==0 ){
1865 p->pLog = 0;
1866 }else{
1867 p->pLog = fopen(zFile, "w");
1868 if( p->pLog==0 ){
1869 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1870 }
1871 }
1872 }else
1873
shanehe2aa9d72009-11-06 17:20:17 +00001874 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001875 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001876 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001877 ||
shanehe2aa9d72009-11-06 17:20:17 +00001878 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001879 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001880 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001881 ||
shanehe2aa9d72009-11-06 17:20:17 +00001882 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001883 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001884 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001885 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001886 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001887 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001888 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001889 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001890 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001891 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001892 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001893 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001894 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001895 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001896 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001897 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001898 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001899 }else {
shane9bd1b442009-10-23 01:27:39 +00001900 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001901 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001902 rc = 1;
drh75897232000-05-29 14:26:00 +00001903 }
1904 }else
1905
shanehe2aa9d72009-11-06 17:20:17 +00001906 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1907 int n2 = strlen30(azArg[1]);
1908 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1909 p->mode = MODE_Insert;
1910 set_table_name(p, azArg[2]);
1911 }else {
1912 fprintf(stderr, "Error: invalid arguments: "
1913 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1914 rc = 1;
1915 }
1916 }else
1917
persicom7e2dfdd2002-04-18 02:46:52 +00001918 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001919 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1920 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001921 }else
1922
drh75897232000-05-29 14:26:00 +00001923 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1924 if( p->out!=stdout ){
1925 fclose(p->out);
1926 }
1927 if( strcmp(azArg[1],"stdout")==0 ){
1928 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001929 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001930 }else{
drha1f9b5e2004-02-14 16:31:02 +00001931 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001932 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00001933 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00001934 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00001935 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001936 } else {
drh5bb3eb92007-05-04 13:15:55 +00001937 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001938 }
1939 }
1940 }else
1941
drhdd45df82002-04-18 12:39:03 +00001942 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001943 if( nArg >= 2) {
1944 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1945 }
1946 if( nArg >= 3) {
1947 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1948 }
1949 }else
1950
shanehe2aa9d72009-11-06 17:20:17 +00001951 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001952 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001953 }else
1954
drh9ff849f2009-02-04 20:55:57 +00001955 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001956 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001957 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00001958 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1959 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00001960 }else{
shane9bd1b442009-10-23 01:27:39 +00001961 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00001962 fclose(alt);
1963 }
1964 }else
1965
shanehe2aa9d72009-11-06 17:20:17 +00001966 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001967 const char *zSrcFile;
1968 const char *zDb;
1969 sqlite3 *pSrc;
1970 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00001971 int nTimeout = 0;
1972
drh9ff849f2009-02-04 20:55:57 +00001973 if( nArg==2 ){
1974 zSrcFile = azArg[1];
1975 zDb = "main";
1976 }else{
1977 zSrcFile = azArg[2];
1978 zDb = azArg[1];
1979 }
1980 rc = sqlite3_open(zSrcFile, &pSrc);
1981 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001982 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00001983 sqlite3_close(pSrc);
1984 return 1;
1985 }
drhdc2c4912009-02-04 22:46:47 +00001986 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001987 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
1988 if( pBackup==0 ){
1989 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1990 sqlite3_close(pSrc);
1991 return 1;
1992 }
drhdc2c4912009-02-04 22:46:47 +00001993 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
1994 || rc==SQLITE_BUSY ){
1995 if( rc==SQLITE_BUSY ){
1996 if( nTimeout++ >= 3 ) break;
1997 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00001998 }
1999 }
2000 sqlite3_backup_finish(pBackup);
2001 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002002 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002003 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002004 fprintf(stderr, "Error: source database is busy\n");
2005 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002006 }else{
2007 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002008 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002009 }
2010 sqlite3_close(pSrc);
2011 }else
2012
shanehe2aa9d72009-11-06 17:20:17 +00002013 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002014 struct callback_data data;
2015 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002016 open_db(p);
drh75897232000-05-29 14:26:00 +00002017 memcpy(&data, p, sizeof(data));
2018 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002019 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002020 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002021 int i;
shane7d3846a2008-12-11 02:58:26 +00002022 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002023 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002024 char *new_argv[2], *new_colv[2];
2025 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2026 " type text,\n"
2027 " name text,\n"
2028 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002029 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002030 " sql text\n"
2031 ")";
2032 new_argv[1] = 0;
2033 new_colv[0] = "sql";
2034 new_colv[1] = 0;
2035 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002036 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002037 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002038 char *new_argv[2], *new_colv[2];
2039 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2040 " type text,\n"
2041 " name text,\n"
2042 " tbl_name text,\n"
2043 " rootpage integer,\n"
2044 " sql text\n"
2045 ")";
2046 new_argv[1] = 0;
2047 new_colv[0] = "sql";
2048 new_colv[1] = 0;
2049 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002050 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002051 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002052 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002053 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002054 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002055 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2056 " FROM sqlite_master UNION ALL"
2057 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002058 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002059 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002060 callback, &data, &zErrMsg);
2061 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002062 }
drh75897232000-05-29 14:26:00 +00002063 }else{
shane9bd1b442009-10-23 01:27:39 +00002064 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002065 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002066 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2067 " FROM sqlite_master UNION ALL"
2068 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002069 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002070 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002071 callback, &data, &zErrMsg
2072 );
drh75897232000-05-29 14:26:00 +00002073 }
drh75897232000-05-29 14:26:00 +00002074 if( zErrMsg ){
2075 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002076 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002077 rc = 1;
2078 }else if( rc != SQLITE_OK ){
2079 fprintf(stderr,"Error: querying schema information\n");
2080 rc = 1;
2081 }else{
2082 rc = 0;
drh75897232000-05-29 14:26:00 +00002083 }
2084 }else
2085
2086 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002087 sqlite3_snprintf(sizeof(p->separator), p->separator,
2088 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002089 }else
2090
shanehe2aa9d72009-11-06 17:20:17 +00002091 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002092 int i;
2093 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002094 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002095 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002096 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002097 fprintf(p->out,"%9.9s: ", "nullvalue");
2098 output_c_string(p->out, p->nullvalue);
2099 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002100 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002101 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002102 fprintf(p->out,"%9.9s: ", "separator");
2103 output_c_string(p->out, p->separator);
2104 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002105 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002106 fprintf(p->out,"%9.9s: ","width");
2107 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002108 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002109 }
drhfeac5f82004-08-01 00:10:45 +00002110 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002111 }else
2112
shaneh642d8b82010-07-28 16:05:34 +00002113 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2114 p->statsOn = booleanValue(azArg[1]);
2115 }else
2116
shanehe2aa9d72009-11-06 17:20:17 +00002117 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002118 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002119 int nRow;
drhe3710332000-09-29 13:30:53 +00002120 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002121 open_db(p);
drha50da102000-08-08 20:19:09 +00002122 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002123 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002124 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002125 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002126 "UNION ALL "
2127 "SELECT name FROM sqlite_temp_master "
2128 "WHERE type IN ('table','view') "
2129 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002130 &azResult, &nRow, 0, &zErrMsg
2131 );
drha50da102000-08-08 20:19:09 +00002132 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002133 zShellStatic = azArg[1];
2134 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002135 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002136 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002137 "UNION ALL "
2138 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002139 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002140 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002141 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002142 );
danielk1977bc6ada42004-06-30 08:20:16 +00002143 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002144 }
drh75897232000-05-29 14:26:00 +00002145 if( zErrMsg ){
2146 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002147 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002148 rc = 1;
2149 }else if( rc != SQLITE_OK ){
2150 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2151 rc = 1;
2152 }else{
drhe3710332000-09-29 13:30:53 +00002153 int len, maxlen = 0;
2154 int i, j;
2155 int nPrintCol, nPrintRow;
2156 for(i=1; i<=nRow; i++){
2157 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002158 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002159 if( len>maxlen ) maxlen = len;
2160 }
2161 nPrintCol = 80/(maxlen+2);
2162 if( nPrintCol<1 ) nPrintCol = 1;
2163 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2164 for(i=0; i<nPrintRow; i++){
2165 for(j=i+1; j<=nRow; j+=nPrintRow){
2166 char *zSp = j<=nPrintRow ? "" : " ";
2167 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2168 }
2169 printf("\n");
2170 }
2171 }
danielk19776f8a5032004-05-10 10:34:51 +00002172 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002173 }else
2174
shaneh96887e12011-02-10 21:08:58 +00002175 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002176 static const struct {
2177 const char *zCtrlName; /* Name of a test-control option */
2178 int ctrlCode; /* Integer code for that option */
2179 } aCtrl[] = {
2180 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2181 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2182 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2183 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2184 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2185 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2186 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2187 { "assert", SQLITE_TESTCTRL_ASSERT },
2188 { "always", SQLITE_TESTCTRL_ALWAYS },
2189 { "reserve", SQLITE_TESTCTRL_RESERVE },
2190 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2191 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
2192 { "pghdrsz", SQLITE_TESTCTRL_PGHDRSZ },
2193 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2194 };
shaneh96887e12011-02-10 21:08:58 +00002195 int testctrl = -1;
2196 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002197 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002198 open_db(p);
2199
drhd416fe72011-03-17 16:45:50 +00002200 /* convert testctrl text option to value. allow any unique prefix
2201 ** of the option name, or a numerical value. */
2202 n = strlen(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002203 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002204 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2205 if( testctrl<0 ){
2206 testctrl = aCtrl[i].ctrlCode;
2207 }else{
2208 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
2209 testctrl = -1;
2210 break;
2211 }
2212 }
2213 }
2214 if( testctrl<0 ) testctrl = atoi(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002215 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2216 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2217 }else{
2218 switch(testctrl){
2219
2220 /* sqlite3_test_control(int, db, int) */
2221 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2222 case SQLITE_TESTCTRL_RESERVE:
2223 if( nArg==3 ){
2224 int opt = (int)strtol(azArg[2], 0, 0);
2225 rc = sqlite3_test_control(testctrl, p->db, opt);
2226 printf("%d (0x%08x)\n", rc, rc);
2227 } else {
drhd416fe72011-03-17 16:45:50 +00002228 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2229 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002230 }
2231 break;
2232
2233 /* sqlite3_test_control(int) */
2234 case SQLITE_TESTCTRL_PRNG_SAVE:
2235 case SQLITE_TESTCTRL_PRNG_RESTORE:
2236 case SQLITE_TESTCTRL_PRNG_RESET:
2237 case SQLITE_TESTCTRL_PGHDRSZ:
2238 if( nArg==2 ){
2239 rc = sqlite3_test_control(testctrl);
2240 printf("%d (0x%08x)\n", rc, rc);
2241 } else {
2242 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2243 }
2244 break;
2245
2246 /* sqlite3_test_control(int, uint) */
2247 case SQLITE_TESTCTRL_PENDING_BYTE:
2248 if( nArg==3 ){
2249 unsigned int opt = (unsigned int)atoi(azArg[2]);
2250 rc = sqlite3_test_control(testctrl, opt);
2251 printf("%d (0x%08x)\n", rc, rc);
2252 } else {
drhd416fe72011-03-17 16:45:50 +00002253 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2254 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002255 }
2256 break;
2257
2258 /* sqlite3_test_control(int, int) */
2259 case SQLITE_TESTCTRL_ASSERT:
2260 case SQLITE_TESTCTRL_ALWAYS:
2261 if( nArg==3 ){
2262 int opt = atoi(azArg[2]);
2263 rc = sqlite3_test_control(testctrl, opt);
2264 printf("%d (0x%08x)\n", rc, rc);
2265 } else {
drhd416fe72011-03-17 16:45:50 +00002266 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2267 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002268 }
2269 break;
2270
2271 /* sqlite3_test_control(int, char *) */
2272#ifdef SQLITE_N_KEYWORD
2273 case SQLITE_TESTCTRL_ISKEYWORD:
2274 if( nArg==3 ){
2275 const char *opt = azArg[2];
2276 rc = sqlite3_test_control(testctrl, opt);
2277 printf("%d (0x%08x)\n", rc, rc);
2278 } else {
drhd416fe72011-03-17 16:45:50 +00002279 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2280 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002281 }
2282 break;
2283#endif
2284
2285 case SQLITE_TESTCTRL_BITVEC_TEST:
2286 case SQLITE_TESTCTRL_FAULT_INSTALL:
2287 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2288 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2289 default:
drhd416fe72011-03-17 16:45:50 +00002290 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2291 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002292 break;
2293 }
2294 }
2295 }else
2296
shanehe2aa9d72009-11-06 17:20:17 +00002297 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002298 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002299 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002300 }else
2301
drhd416fe72011-03-17 16:45:50 +00002302 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2303 && nArg==2
2304 ){
drh3b1a9882007-11-02 12:53:03 +00002305 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002306 }else
2307
2308 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002309 int j;
drh43617e92006-03-06 20:55:46 +00002310 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002311 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2312 p->colWidth[j-1] = atoi(azArg[j]);
2313 }
2314 }else
2315
2316 {
shane9bd1b442009-10-23 01:27:39 +00002317 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002318 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002319 rc = 1;
drh75897232000-05-29 14:26:00 +00002320 }
drh67505e72002-04-19 12:34:06 +00002321
2322 return rc;
drh75897232000-05-29 14:26:00 +00002323}
2324
drh67505e72002-04-19 12:34:06 +00002325/*
drh91a66392007-09-07 01:12:32 +00002326** Return TRUE if a semicolon occurs anywhere in the first N characters
2327** of string z[].
drh324ccef2003-02-05 14:06:20 +00002328*/
drh91a66392007-09-07 01:12:32 +00002329static int _contains_semicolon(const char *z, int N){
2330 int i;
2331 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2332 return 0;
drh324ccef2003-02-05 14:06:20 +00002333}
2334
2335/*
drh70c7a4b2003-04-26 03:03:06 +00002336** Test to see if a line consists entirely of whitespace.
2337*/
2338static int _all_whitespace(const char *z){
2339 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002340 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002341 if( *z=='/' && z[1]=='*' ){
2342 z += 2;
2343 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2344 if( *z==0 ) return 0;
2345 z++;
2346 continue;
2347 }
2348 if( *z=='-' && z[1]=='-' ){
2349 z += 2;
2350 while( *z && *z!='\n' ){ z++; }
2351 if( *z==0 ) return 1;
2352 continue;
2353 }
2354 return 0;
2355 }
2356 return 1;
2357}
2358
2359/*
drha9b17162003-04-29 18:01:28 +00002360** Return TRUE if the line typed in is an SQL command terminator other
2361** than a semi-colon. The SQL Server style "go" command is understood
2362** as is the Oracle "/".
2363*/
2364static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002365 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002366 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2367 return 1; /* Oracle */
2368 }
drhc8d74412004-08-31 23:41:26 +00002369 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2370 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002371 return 1; /* SQL Server */
2372 }
2373 return 0;
2374}
2375
2376/*
drh233a5312008-12-18 22:25:13 +00002377** Return true if zSql is a complete SQL statement. Return false if it
2378** ends in the middle of a string literal or C-style comment.
2379*/
2380static int _is_complete(char *zSql, int nSql){
2381 int rc;
2382 if( zSql==0 ) return 1;
2383 zSql[nSql] = ';';
2384 zSql[nSql+1] = 0;
2385 rc = sqlite3_complete(zSql);
2386 zSql[nSql] = 0;
2387 return rc;
2388}
2389
2390/*
drh67505e72002-04-19 12:34:06 +00002391** Read input from *in and process it. If *in==0 then input
2392** is interactive - the user is typing it it. Otherwise, input
2393** is coming from a file or device. A prompt is issued and history
2394** is saved only if input is interactive. An interrupt signal will
2395** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002396**
2397** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002398*/
drhc28490c2006-10-26 14:25:58 +00002399static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002400 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002401 char *zSql = 0;
2402 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002403 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002404 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002405 int rc;
2406 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002407 int lineno = 0;
2408 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002409
2410 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2411 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002412 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002413 zLine = one_input_line(zSql, in);
2414 if( zLine==0 ){
2415 break; /* We have reached EOF */
2416 }
drh67505e72002-04-19 12:34:06 +00002417 if( seenInterrupt ){
2418 if( in!=0 ) break;
2419 seenInterrupt = 0;
2420 }
drhc28490c2006-10-26 14:25:58 +00002421 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002422 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002423 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002424 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002425 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002426 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002427 break;
2428 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002429 errCnt++;
2430 }
drhdaffd0e2001-04-11 14:28:42 +00002431 continue;
2432 }
drh233a5312008-12-18 22:25:13 +00002433 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002434 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002435 }
drh91a66392007-09-07 01:12:32 +00002436 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002437 if( zSql==0 ){
2438 int i;
drh4c755c02004-08-08 20:22:17 +00002439 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002440 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002441 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002442 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002443 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002444 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002445 exit(1);
2446 }
drh5bb3eb92007-05-04 13:15:55 +00002447 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002448 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002449 }
2450 }else{
drh4f21c4a2008-12-10 22:15:00 +00002451 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002452 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002453 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002454 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002455 exit(1);
2456 }
drh5bb3eb92007-05-04 13:15:55 +00002457 zSql[nSql++] = '\n';
2458 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002459 nSql += len;
2460 }
drh91a66392007-09-07 01:12:32 +00002461 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2462 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002463 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002464 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002465 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002466 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002467 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002468 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002469 char zPrefix[100];
2470 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002471 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002472 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002473 }else{
shane9bd1b442009-10-23 01:27:39 +00002474 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002475 }
drh7f953e22002-07-13 17:33:45 +00002476 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002477 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002478 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002479 zErrMsg = 0;
2480 }else{
shaned2bed1c2009-10-21 03:56:54 +00002481 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002482 }
drhc49f44e2006-10-26 18:15:42 +00002483 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002484 }
2485 free(zSql);
2486 zSql = 0;
2487 nSql = 0;
2488 }
2489 }
2490 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002491 if( !_all_whitespace(zSql) ){
2492 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2493 }
drhdaffd0e2001-04-11 14:28:42 +00002494 free(zSql);
2495 }
danielk19772ac27622007-07-03 05:31:16 +00002496 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002497 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002498}
2499
drh67505e72002-04-19 12:34:06 +00002500/*
2501** Return a pathname which is the user's home directory. A
2502** 0 return indicates an error of some kind. Space to hold the
2503** resulting string is obtained from malloc(). The calling
2504** function should free the result.
2505*/
2506static char *find_home_dir(void){
2507 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002508
chw97185482008-11-17 08:05:31 +00002509#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002510 struct passwd *pwent;
2511 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002512 if( (pwent=getpwuid(uid)) != NULL) {
2513 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002514 }
2515#endif
2516
chw65d3c132007-11-12 21:09:10 +00002517#if defined(_WIN32_WCE)
2518 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2519 */
2520 home_dir = strdup("/");
2521#else
2522
drh164a1b62006-08-19 11:15:20 +00002523#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2524 if (!home_dir) {
2525 home_dir = getenv("USERPROFILE");
2526 }
2527#endif
2528
drh67505e72002-04-19 12:34:06 +00002529 if (!home_dir) {
2530 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002531 }
2532
drhcdb36b72006-06-12 12:57:45 +00002533#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002534 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002535 char *zDrive, *zPath;
2536 int n;
2537 zDrive = getenv("HOMEDRIVE");
2538 zPath = getenv("HOMEPATH");
2539 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002540 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002541 home_dir = malloc( n );
2542 if( home_dir==0 ) return 0;
2543 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2544 return home_dir;
2545 }
2546 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002547 }
2548#endif
2549
chw65d3c132007-11-12 21:09:10 +00002550#endif /* !_WIN32_WCE */
2551
drh67505e72002-04-19 12:34:06 +00002552 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002553 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002554 char *z = malloc( n );
2555 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002556 home_dir = z;
2557 }
drhe98d4fa2002-04-21 19:06:22 +00002558
drh67505e72002-04-19 12:34:06 +00002559 return home_dir;
2560}
2561
2562/*
2563** Read input from the file given by sqliterc_override. Or if that
2564** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002565**
2566** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002567*/
shane9bd1b442009-10-23 01:27:39 +00002568static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002569 struct callback_data *p, /* Configuration data */
2570 const char *sqliterc_override /* Name of config file. NULL to use default */
2571){
persicom7e2dfdd2002-04-18 02:46:52 +00002572 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002573 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002574 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002575 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002576 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002577 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002578
2579 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002580 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002581 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002582#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002583 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002584#endif
shane9bd1b442009-10-23 01:27:39 +00002585 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002586 }
drh4f21c4a2008-12-10 22:15:00 +00002587 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002588 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002589 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002590 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2591 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002592 }
drha959ac42007-06-20 13:10:00 +00002593 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002594 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002595 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002596 }
drha1f9b5e2004-02-14 16:31:02 +00002597 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002598 if( in ){
drhc28490c2006-10-26 14:25:58 +00002599 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002600 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002601 }
shane9bd1b442009-10-23 01:27:39 +00002602 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002603 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002604 }
drh43617e92006-03-06 20:55:46 +00002605 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002606 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002607}
2608
drh67505e72002-04-19 12:34:06 +00002609/*
drhe1e38c42003-05-04 18:30:59 +00002610** Show available command line options
2611*/
2612static const char zOptions[] =
shaneh5fc25012009-11-11 04:17:07 +00002613 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002614 " -init filename read/process named file\n"
2615 " -echo print commands before execution\n"
2616 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002617 " -bail stop after hitting an error\n"
2618 " -interactive force interactive I/O\n"
2619 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002620 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002621 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002622 " -html set output mode to HTML\n"
2623 " -line set output mode to 'line'\n"
2624 " -list set output mode to 'list'\n"
2625 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002626 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002627 " -nullvalue 'text' set text string for NULL values\n"
2628 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002629 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00002630#ifdef SQLITE_ENABLE_VFSTRACE
2631 " -vfstrace enable tracing of all VFS calls\n"
2632#endif
drhe1e38c42003-05-04 18:30:59 +00002633;
2634static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002635 fprintf(stderr,
2636 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2637 "FILENAME is the name of an SQLite database. A new database is created\n"
2638 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002639 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002640 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002641 }else{
2642 fprintf(stderr, "Use the -help option for additional information\n");
2643 }
2644 exit(1);
2645}
2646
2647/*
drh67505e72002-04-19 12:34:06 +00002648** Initialize the state information in data
2649*/
drh0850b532006-01-31 19:31:43 +00002650static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002651 memset(data, 0, sizeof(*data));
2652 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002653 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002654 data->showHeader = 0;
drh127f9d72010-02-23 01:47:00 +00002655 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002656 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2657 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002658 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002659}
2660
drh75897232000-05-29 14:26:00 +00002661int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002662 char *zErrMsg = 0;
2663 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002664 const char *zInitFile = 0;
2665 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002666 int i;
drhc28490c2006-10-26 14:25:58 +00002667 int rc = 0;
drh75897232000-05-29 14:26:00 +00002668
drhdaffd0e2001-04-11 14:28:42 +00002669 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002670 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002671 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002672
drh44c2eb12003-04-30 11:38:26 +00002673 /* Make sure we have a valid signal handler early, before anything
2674 ** else is done.
2675 */
drh4c504392000-10-16 22:06:40 +00002676#ifdef SIGINT
2677 signal(SIGINT, interrupt_handler);
2678#endif
drh44c2eb12003-04-30 11:38:26 +00002679
drh22fbcb82004-02-01 01:22:50 +00002680 /* Do an initial pass through the command-line argument to locate
2681 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002682 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002683 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002684 */
drh22fbcb82004-02-01 01:22:50 +00002685 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002686 char *z;
drh44c2eb12003-04-30 11:38:26 +00002687 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002688 z = argv[i];
2689 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002690 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2691 i++;
drh22fbcb82004-02-01 01:22:50 +00002692 }else if( strcmp(argv[i],"-init")==0 ){
2693 i++;
2694 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002695 /* Need to check for batch mode here to so we can avoid printing
2696 ** informational messages (like from process_sqliterc) before
2697 ** we do the actual processing of arguments later in a second pass.
2698 */
2699 }else if( strcmp(argv[i],"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002700 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002701 }else if( strcmp(argv[i],"-heap")==0 ){
2702 int j, c;
2703 const char *zSize;
2704 sqlite3_int64 szHeap;
2705
2706 zSize = argv[++i];
2707 szHeap = atoi(zSize);
2708 for(j=0; (c = zSize[j])!=0; j++){
2709 if( c=='M' ){ szHeap *= 1000000; break; }
2710 if( c=='K' ){ szHeap *= 1000; break; }
2711 if( c=='G' ){ szHeap *= 1000000000; break; }
2712 }
2713 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
2714#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2715 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2716#endif
drh97ae8ff2011-03-16 16:56:29 +00002717#ifdef SQLITE_ENABLE_VFSTRACE
2718 }else if( strcmp(argv[i],"-vfstrace")==0 ){
2719 extern int vfstrace_register(
2720 const char *zTraceName,
2721 const char *zOldVfsName,
2722 int (*xOut)(const char*,void*),
2723 void *pOutArg,
2724 int makeDefault
2725 );
drh2b625e22011-03-16 17:05:28 +00002726 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00002727#endif
drha7e61d82011-03-12 17:02:57 +00002728 }else if( strcmp(argv[i],"-vfs")==0 ){
drh77ec9ba2011-03-15 18:35:44 +00002729 sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
drha7e61d82011-03-12 17:02:57 +00002730 if( pVfs ){
2731 sqlite3_vfs_register(pVfs, 1);
2732 }else{
2733 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
2734 exit(1);
2735 }
drh44c2eb12003-04-30 11:38:26 +00002736 }
2737 }
drh22fbcb82004-02-01 01:22:50 +00002738 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002739#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002740 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2741#else
drh22fbcb82004-02-01 01:22:50 +00002742 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002743#endif
drh22fbcb82004-02-01 01:22:50 +00002744 }else{
danielk197703aded42004-11-22 05:26:27 +00002745#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002746 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002747#else
2748 data.zDbFilename = 0;
2749#endif
drh22fbcb82004-02-01 01:22:50 +00002750 }
2751 if( i<argc ){
2752 zFirstCmd = argv[i++];
2753 }
shaneh5fc25012009-11-11 04:17:07 +00002754 if( i<argc ){
2755 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2756 fprintf(stderr,"Use -help for a list of options.\n");
2757 return 1;
2758 }
drh44c2eb12003-04-30 11:38:26 +00002759 data.out = stdout;
2760
drh01b41712005-08-29 23:06:23 +00002761#ifdef SQLITE_OMIT_MEMORYDB
2762 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002763 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2764 return 1;
drh01b41712005-08-29 23:06:23 +00002765 }
2766#endif
2767
drh44c2eb12003-04-30 11:38:26 +00002768 /* Go ahead and open the database file if it already exists. If the
2769 ** file does not exist, delay opening it. This prevents empty database
2770 ** files from being created if a user mistypes the database name argument
2771 ** to the sqlite command-line tool.
2772 */
drhc8d74412004-08-31 23:41:26 +00002773 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002774 open_db(&data);
2775 }
2776
drh22fbcb82004-02-01 01:22:50 +00002777 /* Process the initialization file if there is one. If no -init option
2778 ** is given on the command line, look for a file named ~/.sqliterc and
2779 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002780 */
shane86f5bdb2009-10-24 02:00:07 +00002781 rc = process_sqliterc(&data,zInitFile);
2782 if( rc>0 ){
2783 return rc;
2784 }
drh44c2eb12003-04-30 11:38:26 +00002785
drh22fbcb82004-02-01 01:22:50 +00002786 /* Make a second pass through the command-line argument and set
2787 ** options. This second pass is delayed until after the initialization
2788 ** file is processed so that the command-line arguments will override
2789 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002790 */
drh22fbcb82004-02-01 01:22:50 +00002791 for(i=1; i<argc && argv[i][0]=='-'; i++){
2792 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002793 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002794 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002795 i++;
2796 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002797 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002798 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002799 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002800 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002801 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002802 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002803 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002804 }else if( strcmp(z,"-csv")==0 ){
2805 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002806 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002807 }else if( strcmp(z,"-separator")==0 ){
2808 i++;
shaneh5fc25012009-11-11 04:17:07 +00002809 if(i>=argc){
2810 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2811 fprintf(stderr,"Use -help for a list of options.\n");
2812 return 1;
2813 }
drh5bb3eb92007-05-04 13:15:55 +00002814 sqlite3_snprintf(sizeof(data.separator), data.separator,
2815 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002816 }else if( strcmp(z,"-nullvalue")==0 ){
2817 i++;
shaneh5fc25012009-11-11 04:17:07 +00002818 if(i>=argc){
2819 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2820 fprintf(stderr,"Use -help for a list of options.\n");
2821 return 1;
2822 }
drh5bb3eb92007-05-04 13:15:55 +00002823 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2824 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002825 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002826 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002827 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002828 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002829 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002830 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00002831 }else if( strcmp(z,"-stats")==0 ){
2832 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002833 }else if( strcmp(z,"-bail")==0 ){
2834 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002835 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002836 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002837 return 0;
drhc28490c2006-10-26 14:25:58 +00002838 }else if( strcmp(z,"-interactive")==0 ){
2839 stdin_is_interactive = 1;
2840 }else if( strcmp(z,"-batch")==0 ){
2841 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002842 }else if( strcmp(z,"-heap")==0 ){
2843 i++;
drha7e61d82011-03-12 17:02:57 +00002844 }else if( strcmp(z,"-vfs")==0 ){
2845 i++;
drh97ae8ff2011-03-16 16:56:29 +00002846 }else if( strcmp(z,"-vfstrace")==0 ){
2847 i++;
drh80e8be92006-08-29 12:04:19 +00002848 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002849 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002850 }else{
shane86f5bdb2009-10-24 02:00:07 +00002851 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002852 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002853 return 1;
2854 }
2855 }
drh44c2eb12003-04-30 11:38:26 +00002856
drh22fbcb82004-02-01 01:22:50 +00002857 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002858 /* Run just the command that follows the database name
2859 */
drh22fbcb82004-02-01 01:22:50 +00002860 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00002861 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002862 }else{
drh44c2eb12003-04-30 11:38:26 +00002863 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00002864 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00002865 if( zErrMsg!=0 ){
2866 fprintf(stderr,"Error: %s\n", zErrMsg);
2867 return rc!=0 ? rc : 1;
2868 }else if( rc!=0 ){
2869 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
2870 return rc;
drh6ff13852001-11-25 13:18:23 +00002871 }
drh75897232000-05-29 14:26:00 +00002872 }
2873 }else{
drh44c2eb12003-04-30 11:38:26 +00002874 /* Run commands received from standard input
2875 */
drhc28490c2006-10-26 14:25:58 +00002876 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002877 char *zHome;
2878 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002879 int nHistory;
drh75897232000-05-29 14:26:00 +00002880 printf(
drhb217a572000-08-22 13:40:18 +00002881 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002882 "Enter \".help\" for instructions\n"
2883 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002884 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002885 );
drh67505e72002-04-19 12:34:06 +00002886 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002887 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002888 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002889 if( (zHistory = malloc(nHistory))!=0 ){
2890 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2891 }
drh67505e72002-04-19 12:34:06 +00002892 }
danielk19774af00c62005-01-23 23:43:21 +00002893#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002894 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002895#endif
drhc28490c2006-10-26 14:25:58 +00002896 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002897 if( zHistory ){
2898 stifle_history(100);
2899 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002900 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002901 }
adamd0a3daa32006-07-28 20:16:14 +00002902 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002903 }else{
drhc28490c2006-10-26 14:25:58 +00002904 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002905 }
2906 }
drh33048c02001-10-01 14:29:22 +00002907 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00002908 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00002909 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00002910 }
drhc28490c2006-10-26 14:25:58 +00002911 return rc;
drh75897232000-05-29 14:26:00 +00002912}