blob: 9759e93b0055a8fad869bfde18f7a80574eb9a70 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
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
drhc6e41722011-04-11 15:36:26 +000074/* True if the timer is enabled */
75static int enableTimer = 0;
76
chw97185482008-11-17 08:05:31 +000077#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000078#include <sys/time.h>
79#include <sys/resource.h>
80
drhda108222009-02-25 19:07:24 +000081/* Saved resource information for the beginning of an operation */
82static struct rusage sBegin;
83
drhda108222009-02-25 19:07:24 +000084/*
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
shaneb320ccd2009-10-21 03:42:58 +0000127/*
128** Check to see if we have timer support. Return 1 if necessary
129** support found (or found previously).
130*/
131static int hasTimer(void){
132 if( getProcessTimesAddr ){
133 return 1;
134 } else {
135 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
136 ** See if the version we are running on has it, and if it does, save off
137 ** a pointer to it and the current process handle.
138 */
139 hProcess = GetCurrentProcess();
140 if( hProcess ){
141 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
142 if( NULL != hinstLib ){
143 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
144 if( NULL != getProcessTimesAddr ){
145 return 1;
146 }
147 FreeLibrary(hinstLib);
148 }
149 }
150 }
151 return 0;
152}
153
154/*
155** Begin timing an operation
156*/
157static void beginTimer(void){
158 if( enableTimer && getProcessTimesAddr ){
159 FILETIME ftCreation, ftExit;
160 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
161 }
162}
163
164/* Return the difference of two FILETIME structs in seconds */
165static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
166 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
167 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
168 return (double) ((i64End - i64Start) / 10000000.0);
169}
170
171/*
172** Print the timing results.
173*/
174static void endTimer(void){
175 if( enableTimer && getProcessTimesAddr){
176 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
177 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
178 printf("CPU Time: user %f sys %f\n",
179 timeDiff(&ftUserBegin, &ftUserEnd),
180 timeDiff(&ftKernelBegin, &ftKernelEnd));
181 }
182}
183
184#define BEGIN_TIMER beginTimer()
185#define END_TIMER endTimer()
186#define HAS_TIMER hasTimer()
187
drhda108222009-02-25 19:07:24 +0000188#else
189#define BEGIN_TIMER
190#define END_TIMER
191#define HAS_TIMER 0
192#endif
193
shanec0688ea2009-03-05 03:48:06 +0000194/*
195** Used to prevent warnings about unused parameters
196*/
197#define UNUSED_PARAMETER(x) (void)(x)
198
drhe91d16b2008-12-08 18:27:31 +0000199/*
drhc49f44e2006-10-26 18:15:42 +0000200** If the following flag is set, then command execution stops
201** at an error if we are not interactive.
202*/
203static int bail_on_error = 0;
204
205/*
drhc28490c2006-10-26 14:25:58 +0000206** Threat stdin as an interactive input if the following variable
207** is true. Otherwise, assume stdin is connected to a file or pipe.
208*/
209static int stdin_is_interactive = 1;
210
211/*
drh4c504392000-10-16 22:06:40 +0000212** The following is the open SQLite database. We make a pointer
213** to this database a static variable so that it can be accessed
214** by the SIGINT handler to interrupt database processing.
215*/
danielk197792f9a1b2004-06-19 09:08:16 +0000216static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000217
218/*
drh67505e72002-04-19 12:34:06 +0000219** True if an interrupt (Control-C) has been received.
220*/
drh43617e92006-03-06 20:55:46 +0000221static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000222
223/*
persicom7e2dfdd2002-04-18 02:46:52 +0000224** This is the name of our program. It is set in main(), used
225** in a number of other places, mostly for error messages.
226*/
227static char *Argv0;
228
229/*
230** Prompt strings. Initialized in main. Settable with
231** .prompt main continue
232*/
233static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
234static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
235
drhb0603412007-02-28 04:47:26 +0000236/*
237** Write I/O traces to the following stream.
238*/
rsebe0a9092007-07-30 18:24:38 +0000239#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000240static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000241#endif
drhb0603412007-02-28 04:47:26 +0000242
243/*
244** This routine works like printf in that its first argument is a
245** format string and subsequent arguments are values to be substituted
246** in place of % fields. The result of formatting this string
247** is written to iotrace.
248*/
rsebe0a9092007-07-30 18:24:38 +0000249#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000250static void iotracePrintf(const char *zFormat, ...){
251 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000252 char *z;
drhb0603412007-02-28 04:47:26 +0000253 if( iotrace==0 ) return;
254 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000255 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000256 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000257 fprintf(iotrace, "%s", z);
258 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000259}
rsebe0a9092007-07-30 18:24:38 +0000260#endif
drhb0603412007-02-28 04:47:26 +0000261
drh44c2eb12003-04-30 11:38:26 +0000262
persicom7e2dfdd2002-04-18 02:46:52 +0000263/*
drh83965662003-04-17 02:54:13 +0000264** Determines if a string is a number of not.
265*/
danielk19772e588c72005-12-09 14:25:08 +0000266static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000267 if( *z=='-' || *z=='+' ) z++;
268 if( !isdigit(*z) ){
269 return 0;
270 }
271 z++;
272 if( realnum ) *realnum = 0;
273 while( isdigit(*z) ){ z++; }
274 if( *z=='.' ){
275 z++;
276 if( !isdigit(*z) ) return 0;
277 while( isdigit(*z) ){ z++; }
278 if( realnum ) *realnum = 1;
279 }
280 if( *z=='e' || *z=='E' ){
281 z++;
282 if( *z=='+' || *z=='-' ) z++;
283 if( !isdigit(*z) ) return 0;
284 while( isdigit(*z) ){ z++; }
285 if( realnum ) *realnum = 1;
286 }
287 return *z==0;
288}
drh83965662003-04-17 02:54:13 +0000289
290/*
danielk1977bc6ada42004-06-30 08:20:16 +0000291** A global char* and an SQL function to access its current value
292** from within an SQL statement. This program used to use the
293** sqlite_exec_printf() API to substitue a string into an SQL statement.
294** The correct way to do this with sqlite3 is to use the bind API, but
295** since the shell is built around the callback paradigm it would be a lot
296** of work. Instead just use this hack, which is quite harmless.
297*/
298static const char *zShellStatic = 0;
299static void shellstaticFunc(
300 sqlite3_context *context,
301 int argc,
302 sqlite3_value **argv
303){
304 assert( 0==argc );
305 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000306 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000307 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000308 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
309}
310
311
312/*
drhfeac5f82004-08-01 00:10:45 +0000313** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000314** the text in memory obtained from malloc() and returns a pointer
315** to the text. NULL is returned at end of file, or if malloc()
316** fails.
317**
318** The interface is like "readline" but no command-line editing
319** is done.
320*/
drh9347b202003-07-18 01:30:59 +0000321static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000322 char *zLine;
323 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000324 int n;
325 int eol;
326
327 if( zPrompt && *zPrompt ){
328 printf("%s",zPrompt);
329 fflush(stdout);
330 }
331 nLine = 100;
332 zLine = malloc( nLine );
333 if( zLine==0 ) return 0;
334 n = 0;
335 eol = 0;
336 while( !eol ){
337 if( n+100>nLine ){
338 nLine = nLine*2 + 100;
339 zLine = realloc(zLine, nLine);
340 if( zLine==0 ) return 0;
341 }
drhdaffd0e2001-04-11 14:28:42 +0000342 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000343 if( n==0 ){
344 free(zLine);
345 return 0;
346 }
347 zLine[n] = 0;
348 eol = 1;
349 break;
350 }
351 while( zLine[n] ){ n++; }
352 if( n>0 && zLine[n-1]=='\n' ){
353 n--;
shaneh13b36022009-12-17 21:07:15 +0000354 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000355 zLine[n] = 0;
356 eol = 1;
357 }
358 }
359 zLine = realloc( zLine, n+1 );
360 return zLine;
361}
362
363/*
drhc28490c2006-10-26 14:25:58 +0000364** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000365**
366** zPrior is a string of prior text retrieved. If not the empty
367** string, then issue a continuation prompt.
368*/
drhdaffd0e2001-04-11 14:28:42 +0000369static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000370 char *zPrompt;
371 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000372 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000373 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000374 }
375 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000376 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000377 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000378 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000379 }
380 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000381#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000382 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000383#endif
drh8e7e7a22000-05-30 18:45:23 +0000384 return zResult;
385}
386
persicom7e2dfdd2002-04-18 02:46:52 +0000387struct previous_mode_data {
388 int valid; /* Is there legit data in here? */
389 int mode;
390 int showHeader;
391 int colWidth[100];
392};
drh45e29d82006-11-20 16:21:10 +0000393
drh8e7e7a22000-05-30 18:45:23 +0000394/*
drh75897232000-05-29 14:26:00 +0000395** An pointer to an instance of this structure is passed from
396** the main program to the callback. This is used to communicate
397** state and mode information.
398*/
399struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000400 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000401 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000402 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000403 int cnt; /* Number of records displayed so far */
404 FILE *out; /* Write results here */
405 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000406 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000407 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000408 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000409 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000410 int colWidth[100]; /* Requested width of each column when in column mode*/
411 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000412 char nullvalue[20]; /* The text to print when a NULL comes back from
413 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000414 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000415 /* Holds the mode information just before
416 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000417 char outfile[FILENAME_MAX]; /* Filename for *out */
418 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000419 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000420 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000421 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000422};
423
424/*
425** These are the allowed modes.
426*/
drh967e8b72000-06-21 13:59:10 +0000427#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000428#define MODE_Column 1 /* One record per line in neat columns */
429#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000430#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
431#define MODE_Html 4 /* Generate an XHTML table */
432#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000433#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000434#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000435#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000436
drh66ce4d02008-02-15 17:38:06 +0000437static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000438 "line",
439 "column",
440 "list",
441 "semi",
442 "html",
drhfeac5f82004-08-01 00:10:45 +0000443 "insert",
444 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000445 "csv",
drh66ce4d02008-02-15 17:38:06 +0000446 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000447};
drh75897232000-05-29 14:26:00 +0000448
449/*
450** Number of elements in an array
451*/
drh902b9ee2008-12-05 17:17:07 +0000452#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000453
454/*
drhea678832008-12-10 19:26:22 +0000455** Compute a string length that is limited to what can be stored in
456** lower 30 bits of a 32-bit signed integer.
457*/
drh4f21c4a2008-12-10 22:15:00 +0000458static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000459 const char *z2 = z;
460 while( *z2 ){ z2++; }
461 return 0x3fffffff & (int)(z2 - z);
462}
463
464/*
drh127f9d72010-02-23 01:47:00 +0000465** A callback for the sqlite3_log() interface.
466*/
467static void shellLog(void *pArg, int iErrCode, const char *zMsg){
468 struct callback_data *p = (struct callback_data*)pArg;
469 if( p->pLog==0 ) return;
470 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
471 fflush(p->pLog);
472}
473
474/*
shane626a6e42009-10-22 17:30:15 +0000475** Output the given string as a hex-encoded blob (eg. X'1234' )
476*/
477static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
478 int i;
479 char *zBlob = (char *)pBlob;
480 fprintf(out,"X'");
481 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
482 fprintf(out,"'");
483}
484
485/*
drh28bd4bc2000-06-15 15:57:22 +0000486** Output the given string as a quoted string using SQL quoting conventions.
487*/
488static void output_quoted_string(FILE *out, const char *z){
489 int i;
490 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000491 for(i=0; z[i]; i++){
492 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000493 }
494 if( nSingle==0 ){
495 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000496 }else{
497 fprintf(out,"'");
498 while( *z ){
499 for(i=0; z[i] && z[i]!='\''; i++){}
500 if( i==0 ){
501 fprintf(out,"''");
502 z++;
503 }else if( z[i]=='\'' ){
504 fprintf(out,"%.*s''",i,z);
505 z += i+1;
506 }else{
drhcd7d2732002-02-26 23:24:26 +0000507 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000508 break;
509 }
510 }
drhcd7d2732002-02-26 23:24:26 +0000511 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000512 }
513}
514
515/*
drhfeac5f82004-08-01 00:10:45 +0000516** Output the given string as a quoted according to C or TCL quoting rules.
517*/
518static void output_c_string(FILE *out, const char *z){
519 unsigned int c;
520 fputc('"', out);
521 while( (c = *(z++))!=0 ){
522 if( c=='\\' ){
523 fputc(c, out);
524 fputc(c, out);
525 }else if( c=='\t' ){
526 fputc('\\', out);
527 fputc('t', out);
528 }else if( c=='\n' ){
529 fputc('\\', out);
530 fputc('n', out);
531 }else if( c=='\r' ){
532 fputc('\\', out);
533 fputc('r', out);
534 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000535 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000536 }else{
537 fputc(c, out);
538 }
539 }
540 fputc('"', out);
541}
542
543/*
drhc08a4f12000-06-15 16:49:48 +0000544** Output the given string with characters that are special to
545** HTML escaped.
546*/
547static void output_html_string(FILE *out, const char *z){
548 int i;
549 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000550 for(i=0; z[i]
551 && z[i]!='<'
552 && z[i]!='&'
553 && z[i]!='>'
554 && z[i]!='\"'
555 && z[i]!='\'';
556 i++){}
drhc08a4f12000-06-15 16:49:48 +0000557 if( i>0 ){
558 fprintf(out,"%.*s",i,z);
559 }
560 if( z[i]=='<' ){
561 fprintf(out,"&lt;");
562 }else if( z[i]=='&' ){
563 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000564 }else if( z[i]=='>' ){
565 fprintf(out,"&gt;");
566 }else if( z[i]=='\"' ){
567 fprintf(out,"&quot;");
568 }else if( z[i]=='\'' ){
569 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000570 }else{
571 break;
572 }
573 z += i + 1;
574 }
575}
576
577/*
drhc49f44e2006-10-26 18:15:42 +0000578** If a field contains any character identified by a 1 in the following
579** array, then the string must be quoted for CSV.
580*/
581static const char needCsvQuote[] = {
582 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
583 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
584 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
585 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
587 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,
590 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
591 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
592 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
593 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
594 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
595 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
596 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};
599
600/*
drh8e64d1c2004-10-07 00:32:39 +0000601** Output a single term of CSV. Actually, p->separator is used for
602** the separator, which may or may not be a comma. p->nullvalue is
603** the null value. Strings are quoted using ANSI-C rules. Numbers
604** appear outside of quotes.
605*/
606static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000607 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000608 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000609 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000610 }else{
drhc49f44e2006-10-26 18:15:42 +0000611 int i;
drh4f21c4a2008-12-10 22:15:00 +0000612 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000613 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000614 if( needCsvQuote[((unsigned char*)z)[i]]
615 || (z[i]==p->separator[0] &&
616 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000617 i = 0;
618 break;
619 }
620 }
621 if( i==0 ){
622 putc('"', out);
623 for(i=0; z[i]; i++){
624 if( z[i]=='"' ) putc('"', out);
625 putc(z[i], out);
626 }
627 putc('"', out);
628 }else{
629 fprintf(out, "%s", z);
630 }
drh8e64d1c2004-10-07 00:32:39 +0000631 }
632 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000633 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000634 }
635}
636
danielk19774af00c62005-01-23 23:43:21 +0000637#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000638/*
drh4c504392000-10-16 22:06:40 +0000639** This routine runs when the user presses Ctrl-C
640*/
641static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000642 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000643 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000644 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000645}
danielk19774af00c62005-01-23 23:43:21 +0000646#endif
drh4c504392000-10-16 22:06:40 +0000647
648/*
shane626a6e42009-10-22 17:30:15 +0000649** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000650** invokes for each row of a query result.
651*/
shane626a6e42009-10-22 17:30:15 +0000652static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000653 int i;
654 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000655
drh75897232000-05-29 14:26:00 +0000656 switch( p->mode ){
657 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000658 int w = 5;
drh6a535342001-10-19 16:44:56 +0000659 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000660 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000661 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000662 if( len>w ) w = len;
663 }
drh75897232000-05-29 14:26:00 +0000664 if( p->cnt++>0 ) fprintf(p->out,"\n");
665 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000666 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000667 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000668 }
669 break;
670 }
danielk19770d78bae2008-01-03 07:09:48 +0000671 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000672 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000673 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000674 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000675 int w, n;
676 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000677 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000678 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000679 w = 0;
drh75897232000-05-29 14:26:00 +0000680 }
drha0c66f52000-07-29 13:20:21 +0000681 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000682 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000683 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000684 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000685 if( w<n ) w = n;
686 }
687 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000688 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000689 }
690 if( p->showHeader ){
691 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
692 }
693 }
694 if( p->showHeader ){
695 for(i=0; i<nArg; i++){
696 int w;
697 if( i<ArraySize(p->actualWidth) ){
698 w = p->actualWidth[i];
699 }else{
700 w = 10;
701 }
702 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
703 "----------------------------------------------------------",
704 i==nArg-1 ? "\n": " ");
705 }
drh75897232000-05-29 14:26:00 +0000706 }
707 }
drh6a535342001-10-19 16:44:56 +0000708 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000709 for(i=0; i<nArg; i++){
710 int w;
drha0c66f52000-07-29 13:20:21 +0000711 if( i<ArraySize(p->actualWidth) ){
712 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000713 }else{
714 w = 10;
715 }
drhea678832008-12-10 19:26:22 +0000716 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000717 strlen30(azArg[i])>w ){
718 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000719 }
drhc61053b2000-06-04 12:58:36 +0000720 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000721 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000722 }
723 break;
724 }
drhe3710332000-09-29 13:30:53 +0000725 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000726 case MODE_List: {
727 if( p->cnt++==0 && p->showHeader ){
728 for(i=0; i<nArg; i++){
729 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
730 }
731 }
drh6a535342001-10-19 16:44:56 +0000732 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000733 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000734 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000735 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000736 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000737 if( i<nArg-1 ){
738 fprintf(p->out, "%s", p->separator);
739 }else if( p->mode==MODE_Semi ){
740 fprintf(p->out, ";\n");
741 }else{
742 fprintf(p->out, "\n");
743 }
drh75897232000-05-29 14:26:00 +0000744 }
745 break;
746 }
drh1e5d0e92000-05-31 23:33:17 +0000747 case MODE_Html: {
748 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000749 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000750 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000751 fprintf(p->out,"<TH>");
752 output_html_string(p->out, azCol[i]);
753 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000754 }
mihailim57c591a2008-06-23 21:26:05 +0000755 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000756 }
drh6a535342001-10-19 16:44:56 +0000757 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000758 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000759 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000760 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000761 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000762 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000763 }
mihailim57c591a2008-06-23 21:26:05 +0000764 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000765 break;
766 }
drhfeac5f82004-08-01 00:10:45 +0000767 case MODE_Tcl: {
768 if( p->cnt++==0 && p->showHeader ){
769 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000770 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000771 fprintf(p->out, "%s", p->separator);
772 }
773 fprintf(p->out,"\n");
774 }
775 if( azArg==0 ) break;
776 for(i=0; i<nArg; i++){
777 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
778 fprintf(p->out, "%s", p->separator);
779 }
780 fprintf(p->out,"\n");
781 break;
782 }
drh8e64d1c2004-10-07 00:32:39 +0000783 case MODE_Csv: {
784 if( p->cnt++==0 && p->showHeader ){
785 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000786 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000787 }
788 fprintf(p->out,"\n");
789 }
790 if( azArg==0 ) break;
791 for(i=0; i<nArg; i++){
792 output_csv(p, azArg[i], i<nArg-1);
793 }
794 fprintf(p->out,"\n");
795 break;
796 }
drh28bd4bc2000-06-15 15:57:22 +0000797 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000798 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000799 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000800 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000801 for(i=0; i<nArg; i++){
802 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000803 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000804 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000805 }else if( aiType && aiType[i]==SQLITE_TEXT ){
806 if( zSep[0] ) fprintf(p->out,"%s",zSep);
807 output_quoted_string(p->out, azArg[i]);
808 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
809 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000810 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
811 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
812 int nBlob = sqlite3_column_bytes(p->pStmt, i);
813 if( zSep[0] ) fprintf(p->out,"%s",zSep);
814 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000815 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000816 fprintf(p->out,"%s%s",zSep, azArg[i]);
817 }else{
818 if( zSep[0] ) fprintf(p->out,"%s",zSep);
819 output_quoted_string(p->out, azArg[i]);
820 }
821 }
822 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000823 break;
drh28bd4bc2000-06-15 15:57:22 +0000824 }
persicom1d0b8722002-04-18 02:53:04 +0000825 }
drh75897232000-05-29 14:26:00 +0000826 return 0;
827}
828
829/*
shane626a6e42009-10-22 17:30:15 +0000830** This is the callback routine that the SQLite library
831** invokes for each row of a query result.
832*/
833static int callback(void *pArg, int nArg, char **azArg, char **azCol){
834 /* since we don't have type info, call the shell_callback with a NULL value */
835 return shell_callback(pArg, nArg, azArg, azCol, NULL);
836}
837
838/*
drh33048c02001-10-01 14:29:22 +0000839** Set the destination table field of the callback_data structure to
840** the name of the table given. Escape any quote characters in the
841** table name.
842*/
843static void set_table_name(struct callback_data *p, const char *zName){
844 int i, n;
845 int needQuote;
846 char *z;
847
848 if( p->zDestTable ){
849 free(p->zDestTable);
850 p->zDestTable = 0;
851 }
852 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000853 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000854 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000855 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000856 needQuote = 1;
857 if( zName[i]=='\'' ) n++;
858 }
859 }
860 if( needQuote ) n += 2;
861 z = p->zDestTable = malloc( n+1 );
862 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000863 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000864 exit(1);
865 }
866 n = 0;
867 if( needQuote ) z[n++] = '\'';
868 for(i=0; zName[i]; i++){
869 z[n++] = zName[i];
870 if( zName[i]=='\'' ) z[n++] = '\'';
871 }
872 if( needQuote ) z[n++] = '\'';
873 z[n] = 0;
874}
875
danielk19772a02e332004-06-05 08:04:36 +0000876/* zIn is either a pointer to a NULL-terminated string in memory obtained
877** from malloc(), or a NULL pointer. The string pointed to by zAppend is
878** added to zIn, and the result returned in memory obtained from malloc().
879** zIn, if it was not NULL, is freed.
880**
881** If the third argument, quote, is not '\0', then it is used as a
882** quote character for zAppend.
883*/
drhc28490c2006-10-26 14:25:58 +0000884static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000885 int len;
886 int i;
drh4f21c4a2008-12-10 22:15:00 +0000887 int nAppend = strlen30(zAppend);
888 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000889
890 len = nAppend+nIn+1;
891 if( quote ){
892 len += 2;
893 for(i=0; i<nAppend; i++){
894 if( zAppend[i]==quote ) len++;
895 }
896 }
897
898 zIn = (char *)realloc(zIn, len);
899 if( !zIn ){
900 return 0;
901 }
902
903 if( quote ){
904 char *zCsr = &zIn[nIn];
905 *zCsr++ = quote;
906 for(i=0; i<nAppend; i++){
907 *zCsr++ = zAppend[i];
908 if( zAppend[i]==quote ) *zCsr++ = quote;
909 }
910 *zCsr++ = quote;
911 *zCsr++ = '\0';
912 assert( (zCsr-zIn)==len );
913 }else{
914 memcpy(&zIn[nIn], zAppend, nAppend);
915 zIn[len-1] = '\0';
916 }
917
918 return zIn;
919}
920
drhdd3d4592004-08-30 01:54:05 +0000921
922/*
923** Execute a query statement that has a single result column. Print
924** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000925**
926** This is used, for example, to show the schema of the database by
927** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000928*/
drh157e29a2009-05-21 15:15:00 +0000929static int run_table_dump_query(
930 FILE *out, /* Send output here */
931 sqlite3 *db, /* Database to query */
932 const char *zSelect, /* SELECT statement to extract content */
933 const char *zFirstRow /* Print before first row, if not NULL */
934){
drhdd3d4592004-08-30 01:54:05 +0000935 sqlite3_stmt *pSelect;
936 int rc;
937 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
938 if( rc!=SQLITE_OK || !pSelect ){
939 return rc;
940 }
941 rc = sqlite3_step(pSelect);
942 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000943 if( zFirstRow ){
944 fprintf(out, "%s", zFirstRow);
945 zFirstRow = 0;
946 }
drhdd3d4592004-08-30 01:54:05 +0000947 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
948 rc = sqlite3_step(pSelect);
949 }
950 return sqlite3_finalize(pSelect);
951}
952
shane626a6e42009-10-22 17:30:15 +0000953/*
954** Allocate space and save off current error string.
955*/
956static char *save_err_msg(
957 sqlite3 *db /* Database to query */
958){
959 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
960 char *zErrMsg = sqlite3_malloc(nErrMsg);
961 if( zErrMsg ){
962 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
963 }
964 return zErrMsg;
965}
966
967/*
shaneh642d8b82010-07-28 16:05:34 +0000968** Display memory stats.
969*/
970static int display_stats(
971 sqlite3 *db, /* Database to query */
972 struct callback_data *pArg, /* Pointer to struct callback_data */
973 int bReset /* True to reset the stats */
974){
975 int iCur;
976 int iHiwtr;
977
978 if( pArg && pArg->out ){
979
980 iHiwtr = iCur = -1;
981 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +0000982 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000983 iHiwtr = iCur = -1;
984 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +0000985 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000986/*
987** Not currently used by the CLI.
988** iHiwtr = iCur = -1;
989** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
990** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
991*/
992 iHiwtr = iCur = -1;
993 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
994 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
995/*
996** Not currently used by the CLI.
997** iHiwtr = iCur = -1;
998** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
999** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1000*/
1001 iHiwtr = iCur = -1;
1002 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1003 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1004 iHiwtr = iCur = -1;
1005 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1006 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1007 iHiwtr = iCur = -1;
1008 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1009 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1010 iHiwtr = iCur = -1;
1011 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1012 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1013#ifdef YYTRACKMAXSTACKDEPTH
1014 iHiwtr = iCur = -1;
1015 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1016 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1017#endif
1018 }
1019
1020 if( pArg && pArg->out && db ){
1021 iHiwtr = iCur = -1;
1022 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1023 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001024 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1025 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1026 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1027 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1028 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1029 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001030 iHiwtr = iCur = -1;
1031 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh233f8162010-07-28 17:36:11 +00001032 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001033 iHiwtr = iCur = -1;
1034 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1035 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1036 iHiwtr = iCur = -1;
1037 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1038 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1039 }
1040
1041 if( pArg && pArg->out && db && pArg->pStmt ){
1042 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1043 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1044 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1045 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1046 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1047 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1048 }
1049
1050 return 0;
1051}
1052
1053/*
shane626a6e42009-10-22 17:30:15 +00001054** Execute a statement or set of statements. Print
1055** any result rows/columns depending on the current mode
1056** set via the supplied callback.
1057**
1058** This is very similar to SQLite's built-in sqlite3_exec()
1059** function except it takes a slightly different callback
1060** and callback data argument.
1061*/
1062static int shell_exec(
1063 sqlite3 *db, /* An open database */
1064 const char *zSql, /* SQL to be evaluated */
1065 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1066 /* (not the same as sqlite3_exec) */
1067 struct callback_data *pArg, /* Pointer to struct callback_data */
1068 char **pzErrMsg /* Error msg written here */
1069){
dan4564ced2010-01-05 04:59:56 +00001070 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1071 int rc = SQLITE_OK; /* Return Code */
1072 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001073
1074 if( pzErrMsg ){
1075 *pzErrMsg = NULL;
1076 }
1077
shaneb9fc17d2009-10-22 21:23:35 +00001078 while( zSql[0] && (SQLITE_OK == rc) ){
1079 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1080 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001081 if( pzErrMsg ){
1082 *pzErrMsg = save_err_msg(db);
1083 }
1084 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001085 if( !pStmt ){
1086 /* this happens for a comment or white-space */
1087 zSql = zLeftover;
1088 while( isspace(zSql[0]) ) zSql++;
1089 continue;
1090 }
shane626a6e42009-10-22 17:30:15 +00001091
shaneh642d8b82010-07-28 16:05:34 +00001092 /* save off the prepared statment handle and reset row count */
1093 if( pArg ){
1094 pArg->pStmt = pStmt;
1095 pArg->cnt = 0;
1096 }
1097
shanehb7977c52010-01-18 18:17:10 +00001098 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001099 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001100 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001101 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001102 }
shanehb7977c52010-01-18 18:17:10 +00001103
shaneb9fc17d2009-10-22 21:23:35 +00001104 /* perform the first step. this will tell us if we
1105 ** have a result set or not and how wide it is.
1106 */
1107 rc = sqlite3_step(pStmt);
1108 /* if we have a result set... */
1109 if( SQLITE_ROW == rc ){
1110 /* if we have a callback... */
1111 if( xCallback ){
1112 /* allocate space for col name ptr, value ptr, and type */
1113 int nCol = sqlite3_column_count(pStmt);
1114 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1115 if( !pData ){
1116 rc = SQLITE_NOMEM;
1117 }else{
1118 char **azCols = (char **)pData; /* Names of result columns */
1119 char **azVals = &azCols[nCol]; /* Results */
1120 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1121 int i;
1122 assert(sizeof(int) <= sizeof(char *));
1123 /* save off ptrs to column names */
1124 for(i=0; i<nCol; i++){
1125 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1126 }
shaneb9fc17d2009-10-22 21:23:35 +00001127 do{
1128 /* extract the data and data types */
1129 for(i=0; i<nCol; i++){
1130 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1131 aiTypes[i] = sqlite3_column_type(pStmt, i);
1132 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1133 rc = SQLITE_NOMEM;
1134 break; /* from for */
1135 }
1136 } /* end for */
1137
1138 /* if data and types extracted successfully... */
1139 if( SQLITE_ROW == rc ){
1140 /* call the supplied callback with the result row data */
1141 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1142 rc = SQLITE_ABORT;
1143 }else{
1144 rc = sqlite3_step(pStmt);
1145 }
1146 }
1147 } while( SQLITE_ROW == rc );
1148 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001149 }
1150 }else{
1151 do{
1152 rc = sqlite3_step(pStmt);
1153 } while( rc == SQLITE_ROW );
1154 }
1155 }
1156
shaneh642d8b82010-07-28 16:05:34 +00001157 /* print usage stats if stats on */
1158 if( pArg && pArg->statsOn ){
1159 display_stats(db, pArg, 0);
1160 }
1161
dan4564ced2010-01-05 04:59:56 +00001162 /* Finalize the statement just executed. If this fails, save a
1163 ** copy of the error message. Otherwise, set zSql to point to the
1164 ** next statement to execute. */
1165 rc = sqlite3_finalize(pStmt);
1166 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001167 zSql = zLeftover;
1168 while( isspace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001169 }else if( pzErrMsg ){
1170 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001171 }
shaneh642d8b82010-07-28 16:05:34 +00001172
1173 /* clear saved stmt handle */
1174 if( pArg ){
1175 pArg->pStmt = NULL;
1176 }
shane626a6e42009-10-22 17:30:15 +00001177 }
shaneb9fc17d2009-10-22 21:23:35 +00001178 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001179
1180 return rc;
1181}
1182
drhdd3d4592004-08-30 01:54:05 +00001183
drh33048c02001-10-01 14:29:22 +00001184/*
drh4c653a02000-06-07 01:27:47 +00001185** This is a different callback routine used for dumping the database.
1186** Each row received by this callback consists of a table name,
1187** the table type ("index" or "table") and SQL to create the table.
1188** This routine should print text sufficient to recreate the table.
1189*/
1190static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001191 int rc;
1192 const char *zTable;
1193 const char *zType;
1194 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001195 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001196 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001197
drh902b9ee2008-12-05 17:17:07 +00001198 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001199 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001200 zTable = azArg[0];
1201 zType = azArg[1];
1202 zSql = azArg[2];
1203
drh00b950d2005-09-11 02:03:03 +00001204 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001205 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001206 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1207 fprintf(p->out, "ANALYZE sqlite_master;\n");
1208 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1209 return 0;
drh45e29d82006-11-20 16:21:10 +00001210 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1211 char *zIns;
1212 if( !p->writableSchema ){
1213 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1214 p->writableSchema = 1;
1215 }
1216 zIns = sqlite3_mprintf(
1217 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1218 "VALUES('table','%q','%q',0,'%q');",
1219 zTable, zTable, zSql);
1220 fprintf(p->out, "%s\n", zIns);
1221 sqlite3_free(zIns);
1222 return 0;
drh00b950d2005-09-11 02:03:03 +00001223 }else{
1224 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001225 }
danielk19772a02e332004-06-05 08:04:36 +00001226
1227 if( strcmp(zType, "table")==0 ){
1228 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001229 char *zSelect = 0;
1230 char *zTableInfo = 0;
1231 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001232 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001233
1234 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1235 zTableInfo = appendText(zTableInfo, zTable, '"');
1236 zTableInfo = appendText(zTableInfo, ");", 0);
1237
1238 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001239 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001240 if( rc!=SQLITE_OK || !pTableInfo ){
1241 return 1;
1242 }
1243
1244 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1245 zTmp = appendText(zTmp, zTable, '"');
1246 if( zTmp ){
1247 zSelect = appendText(zSelect, zTmp, '\'');
1248 }
1249 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1250 rc = sqlite3_step(pTableInfo);
1251 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001252 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001253 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001254 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001255 rc = sqlite3_step(pTableInfo);
1256 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001257 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001258 }else{
1259 zSelect = appendText(zSelect, ") ", 0);
1260 }
drh157e29a2009-05-21 15:15:00 +00001261 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001262 }
1263 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001264 if( rc!=SQLITE_OK || nRow==0 ){
1265 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001266 return 1;
1267 }
1268 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1269 zSelect = appendText(zSelect, zTable, '"');
1270
drh157e29a2009-05-21 15:15:00 +00001271 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001272 if( rc==SQLITE_CORRUPT ){
1273 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001274 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001275 }
danielk19772a02e332004-06-05 08:04:36 +00001276 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001277 }
drh4c653a02000-06-07 01:27:47 +00001278 return 0;
1279}
1280
1281/*
drh45e29d82006-11-20 16:21:10 +00001282** Run zQuery. Use dump_callback() as the callback routine so that
1283** the contents of the query are output as SQL statements.
1284**
drhdd3d4592004-08-30 01:54:05 +00001285** If we get a SQLITE_CORRUPT error, rerun the query after appending
1286** "ORDER BY rowid DESC" to the end.
1287*/
1288static int run_schema_dump_query(
1289 struct callback_data *p,
1290 const char *zQuery,
1291 char **pzErrMsg
1292){
1293 int rc;
1294 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1295 if( rc==SQLITE_CORRUPT ){
1296 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001297 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001298 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1299 zQ2 = malloc( len+100 );
1300 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001301 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001302 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1303 free(zQ2);
1304 }
1305 return rc;
1306}
1307
1308/*
drh75897232000-05-29 14:26:00 +00001309** Text of a help message
1310*/
persicom1d0b8722002-04-18 02:53:04 +00001311static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001312 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001313 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001314 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001315 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001316 " If TABLE specified, only dump tables matching\n"
1317 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001318 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001319 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001320 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1321 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001322 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001323 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001324 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001325 ".indices ?TABLE? Show names of all indices\n"
1326 " If TABLE specified, only show indices for tables\n"
1327 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001328#ifdef SQLITE_ENABLE_IOTRACE
1329 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1330#endif
drh70df4fe2006-06-13 15:12:21 +00001331#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001332 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001333#endif
drh127f9d72010-02-23 01:47:00 +00001334 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001335 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001336 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001337 " column Left-aligned columns. (See .width)\n"
1338 " html HTML <table> code\n"
1339 " insert SQL insert statements for TABLE\n"
1340 " line One value per line\n"
1341 " list Values delimited by .separator string\n"
1342 " tabs Tab-separated values\n"
1343 " tcl TCL list elements\n"
1344 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001345 ".output FILENAME Send output to FILENAME\n"
1346 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001347 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001348 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001349 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001350 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001351 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001352 " If TABLE specified, only show tables matching\n"
1353 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001354 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001355 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001356 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001357 ".tables ?TABLE? List names of tables\n"
1358 " If TABLE specified, only list tables matching\n"
1359 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001360 ".timeout MS Try opening locked tables for MS milliseconds\n"
shanehe2aa9d72009-11-06 17:20:17 +00001361 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001362;
1363
shaneb320ccd2009-10-21 03:42:58 +00001364static char zTimerHelp[] =
1365 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1366;
1367
drhdaffd0e2001-04-11 14:28:42 +00001368/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001369static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001370
drh75897232000-05-29 14:26:00 +00001371/*
drh44c2eb12003-04-30 11:38:26 +00001372** Make sure the database is open. If it is not, then open it. If
1373** the database fails to open, print an error message and exit.
1374*/
1375static void open_db(struct callback_data *p){
1376 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001377 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001378 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001379 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1380 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1381 shellstaticFunc, 0, 0);
1382 }
1383 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001384 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001385 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001386 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001387 }
drhc2e87a32006-06-27 15:16:14 +00001388#ifndef SQLITE_OMIT_LOAD_EXTENSION
1389 sqlite3_enable_load_extension(p->db, 1);
1390#endif
drh44c2eb12003-04-30 11:38:26 +00001391 }
1392}
1393
1394/*
drhfeac5f82004-08-01 00:10:45 +00001395** Do C-language style dequoting.
1396**
1397** \t -> tab
1398** \n -> newline
1399** \r -> carriage return
1400** \NNN -> ascii character NNN in octal
1401** \\ -> backslash
1402*/
1403static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001404 int i, j;
1405 char c;
drhfeac5f82004-08-01 00:10:45 +00001406 for(i=j=0; (c = z[i])!=0; i++, j++){
1407 if( c=='\\' ){
1408 c = z[++i];
1409 if( c=='n' ){
1410 c = '\n';
1411 }else if( c=='t' ){
1412 c = '\t';
1413 }else if( c=='r' ){
1414 c = '\r';
1415 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001416 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001417 if( z[i+1]>='0' && z[i+1]<='7' ){
1418 i++;
1419 c = (c<<3) + z[i] - '0';
1420 if( z[i+1]>='0' && z[i+1]<='7' ){
1421 i++;
1422 c = (c<<3) + z[i] - '0';
1423 }
1424 }
1425 }
1426 }
1427 z[j] = c;
1428 }
1429 z[j] = 0;
1430}
1431
1432/*
drhc28490c2006-10-26 14:25:58 +00001433** Interpret zArg as a boolean value. Return either 0 or 1.
1434*/
1435static int booleanValue(char *zArg){
1436 int val = atoi(zArg);
1437 int j;
1438 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001439 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001440 }
1441 if( strcmp(zArg,"on")==0 ){
1442 val = 1;
1443 }else if( strcmp(zArg,"yes")==0 ){
1444 val = 1;
1445 }
1446 return val;
1447}
1448
1449/*
drh75897232000-05-29 14:26:00 +00001450** If an input line begins with "." then invoke this routine to
1451** process that line.
drh67505e72002-04-19 12:34:06 +00001452**
drh47ad6842006-11-08 12:25:42 +00001453** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001454*/
drh44c2eb12003-04-30 11:38:26 +00001455static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001456 int i = 1;
1457 int nArg = 0;
1458 int n, c;
drh67505e72002-04-19 12:34:06 +00001459 int rc = 0;
drh75897232000-05-29 14:26:00 +00001460 char *azArg[50];
1461
1462 /* Parse the input line into tokens.
1463 */
1464 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001465 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001466 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001467 if( zLine[i]=='\'' || zLine[i]=='"' ){
1468 int delim = zLine[i++];
1469 azArg[nArg++] = &zLine[i];
1470 while( zLine[i] && zLine[i]!=delim ){ i++; }
1471 if( zLine[i]==delim ){
1472 zLine[i++] = 0;
1473 }
drhfeac5f82004-08-01 00:10:45 +00001474 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001475 }else{
1476 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001477 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001478 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001479 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001480 }
1481 }
1482
1483 /* Process the input line.
1484 */
shane9bd1b442009-10-23 01:27:39 +00001485 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001486 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001487 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001488 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001489 const char *zDestFile;
1490 const char *zDb;
1491 sqlite3 *pDest;
1492 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001493 if( nArg==2 ){
1494 zDestFile = azArg[1];
1495 zDb = "main";
1496 }else{
1497 zDestFile = azArg[2];
1498 zDb = azArg[1];
1499 }
1500 rc = sqlite3_open(zDestFile, &pDest);
1501 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001502 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001503 sqlite3_close(pDest);
1504 return 1;
1505 }
drhdc2c4912009-02-04 22:46:47 +00001506 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001507 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1508 if( pBackup==0 ){
1509 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1510 sqlite3_close(pDest);
1511 return 1;
1512 }
1513 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1514 sqlite3_backup_finish(pBackup);
1515 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001516 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001517 }else{
1518 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001519 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001520 }
1521 sqlite3_close(pDest);
1522 }else
1523
shanehe2aa9d72009-11-06 17:20:17 +00001524 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001525 bail_on_error = booleanValue(azArg[1]);
1526 }else
1527
shanehe2aa9d72009-11-06 17:20:17 +00001528 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001529 struct callback_data data;
1530 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001531 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001532 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001533 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001534 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001535 data.colWidth[0] = 3;
1536 data.colWidth[1] = 15;
1537 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001538 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001539 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001540 if( zErrMsg ){
1541 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001542 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001543 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001544 }
1545 }else
1546
shanehe2aa9d72009-11-06 17:20:17 +00001547 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh4c653a02000-06-07 01:27:47 +00001548 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001549 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001550 /* When playing back a "dump", the content might appear in an order
1551 ** which causes immediate foreign key constraints to be violated.
1552 ** So disable foreign-key constraint enforcement to prevent problems. */
1553 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001554 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001555 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001556 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001557 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001558 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001559 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00001560 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1561 );
1562 run_schema_dump_query(p,
1563 "SELECT name, type, sql FROM sqlite_master "
1564 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00001565 );
1566 run_table_dump_query(p->out, p->db,
1567 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001568 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001569 );
drh4c653a02000-06-07 01:27:47 +00001570 }else{
1571 int i;
drhdd3d4592004-08-30 01:54:05 +00001572 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001573 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001574 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001575 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001576 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001577 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001578 run_table_dump_query(p->out, p->db,
1579 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001580 "WHERE sql NOT NULL"
1581 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001582 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001583 );
danielk1977bc6ada42004-06-30 08:20:16 +00001584 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001585 }
1586 }
drh45e29d82006-11-20 16:21:10 +00001587 if( p->writableSchema ){
1588 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1589 p->writableSchema = 0;
1590 }
drh93f41e52008-08-11 19:12:34 +00001591 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001592 if( zErrMsg ){
1593 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001594 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001595 }else{
1596 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001597 }
1598 }else
drh75897232000-05-29 14:26:00 +00001599
shanehe2aa9d72009-11-06 17:20:17 +00001600 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001601 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001602 }else
1603
shanehe2aa9d72009-11-06 17:20:17 +00001604 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001605 rc = 2;
drh75897232000-05-29 14:26:00 +00001606 }else
1607
shanehe2aa9d72009-11-06 17:20:17 +00001608 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001609 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001610 if(val == 1) {
1611 if(!p->explainPrev.valid) {
1612 p->explainPrev.valid = 1;
1613 p->explainPrev.mode = p->mode;
1614 p->explainPrev.showHeader = p->showHeader;
1615 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1616 }
1617 /* We could put this code under the !p->explainValid
1618 ** condition so that it does not execute if we are already in
1619 ** explain mode. However, always executing it allows us an easy
1620 ** was to reset to explain mode in case the user previously
1621 ** did an .explain followed by a .width, .mode or .header
1622 ** command.
1623 */
danielk19770d78bae2008-01-03 07:09:48 +00001624 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001625 p->showHeader = 1;
1626 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001627 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001628 p->colWidth[1] = 13; /* opcode */
1629 p->colWidth[2] = 4; /* P1 */
1630 p->colWidth[3] = 4; /* P2 */
1631 p->colWidth[4] = 4; /* P3 */
1632 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001633 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001634 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001635 }else if (p->explainPrev.valid) {
1636 p->explainPrev.valid = 0;
1637 p->mode = p->explainPrev.mode;
1638 p->showHeader = p->explainPrev.showHeader;
1639 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1640 }
drh75897232000-05-29 14:26:00 +00001641 }else
1642
drhc28490c2006-10-26 14:25:58 +00001643 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001644 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001645 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001646 }else
1647
1648 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001649 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001650 if( HAS_TIMER ){
1651 fprintf(stderr,"%s",zTimerHelp);
1652 }
drh75897232000-05-29 14:26:00 +00001653 }else
1654
shanehe2aa9d72009-11-06 17:20:17 +00001655 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001656 char *zTable = azArg[2]; /* Insert data into this table */
1657 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001658 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001659 int nCol; /* Number of columns in the table */
1660 int nByte; /* Number of bytes in an SQL string */
1661 int i, j; /* Loop counters */
1662 int nSep; /* Number of bytes in p->separator[] */
1663 char *zSql; /* An SQL statement */
1664 char *zLine; /* A single line of input from the file */
1665 char **azCol; /* zLine[] broken up into columns */
1666 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001667 FILE *in; /* The input file */
1668 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001669
drha543c822006-06-08 16:10:14 +00001670 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001671 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001672 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001673 fprintf(stderr, "Error: non-null separator required for import\n");
1674 return 1;
drhfeac5f82004-08-01 00:10:45 +00001675 }
1676 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
shane916f9612009-10-23 00:37:15 +00001677 if( zSql==0 ){
1678 fprintf(stderr, "Error: out of memory\n");
1679 return 1;
1680 }
drh4f21c4a2008-12-10 22:15:00 +00001681 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001682 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001683 sqlite3_free(zSql);
1684 if( rc ){
shane916f9612009-10-23 00:37:15 +00001685 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001686 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001687 return 1;
drhfeac5f82004-08-01 00:10:45 +00001688 }
shane916f9612009-10-23 00:37:15 +00001689 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001690 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001691 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001692 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001693 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001694 if( zSql==0 ){
1695 fprintf(stderr, "Error: out of memory\n");
1696 return 1;
1697 }
drhfeac5f82004-08-01 00:10:45 +00001698 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001699 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001700 for(i=1; i<nCol; i++){
1701 zSql[j++] = ',';
1702 zSql[j++] = '?';
1703 }
1704 zSql[j++] = ')';
1705 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001706 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001707 free(zSql);
1708 if( rc ){
1709 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001710 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001711 return 1;
drhfeac5f82004-08-01 00:10:45 +00001712 }
1713 in = fopen(zFile, "rb");
1714 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001715 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001716 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001717 return 1;
drhfeac5f82004-08-01 00:10:45 +00001718 }
1719 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001720 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001721 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001722 fclose(in);
shane916f9612009-10-23 00:37:15 +00001723 sqlite3_finalize(pStmt);
1724 return 1;
drh43617e92006-03-06 20:55:46 +00001725 }
drhfeac5f82004-08-01 00:10:45 +00001726 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1727 zCommit = "COMMIT";
1728 while( (zLine = local_getline(0, in))!=0 ){
1729 char *z;
1730 i = 0;
drhb860bc92004-08-04 15:16:55 +00001731 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001732 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001733 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001734 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1735 *z = 0;
1736 i++;
drhb860bc92004-08-04 15:16:55 +00001737 if( i<nCol ){
1738 azCol[i] = &z[nSep];
1739 z += nSep-1;
1740 }
drhfeac5f82004-08-01 00:10:45 +00001741 }
shane916f9612009-10-23 00:37:15 +00001742 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001743 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001744 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001745 fprintf(stderr,
1746 "Error: %s line %d: expected %d columns of data but found %d\n",
1747 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001748 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001749 free(zLine);
shane916f9612009-10-23 00:37:15 +00001750 rc = 1;
1751 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001752 }
drhfeac5f82004-08-01 00:10:45 +00001753 for(i=0; i<nCol; i++){
1754 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1755 }
1756 sqlite3_step(pStmt);
1757 rc = sqlite3_reset(pStmt);
1758 free(zLine);
1759 if( rc!=SQLITE_OK ){
1760 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1761 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001762 rc = 1;
shane916f9612009-10-23 00:37:15 +00001763 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001764 }
shane916f9612009-10-23 00:37:15 +00001765 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001766 free(azCol);
1767 fclose(in);
1768 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001769 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001770 }else
1771
shanehe2aa9d72009-11-06 17:20:17 +00001772 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001773 struct callback_data data;
1774 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001775 open_db(p);
drh75897232000-05-29 14:26:00 +00001776 memcpy(&data, p, sizeof(data));
1777 data.showHeader = 0;
1778 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001779 if( nArg==1 ){
1780 rc = sqlite3_exec(p->db,
1781 "SELECT name FROM sqlite_master "
1782 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1783 "UNION ALL "
1784 "SELECT name FROM sqlite_temp_master "
1785 "WHERE type='index' "
1786 "ORDER BY 1",
1787 callback, &data, &zErrMsg
1788 );
1789 }else{
1790 zShellStatic = azArg[1];
1791 rc = sqlite3_exec(p->db,
1792 "SELECT name FROM sqlite_master "
1793 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1794 "UNION ALL "
1795 "SELECT name FROM sqlite_temp_master "
1796 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1797 "ORDER BY 1",
1798 callback, &data, &zErrMsg
1799 );
1800 zShellStatic = 0;
1801 }
drh75897232000-05-29 14:26:00 +00001802 if( zErrMsg ){
1803 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001804 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001805 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001806 }else if( rc != SQLITE_OK ){
1807 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1808 rc = 1;
drh75897232000-05-29 14:26:00 +00001809 }
1810 }else
1811
drhae5e4452007-05-03 17:18:36 +00001812#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001813 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001814 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001815 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1816 iotrace = 0;
1817 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001818 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001819 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001820 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001821 iotrace = stdout;
1822 }else{
1823 iotrace = fopen(azArg[1], "w");
1824 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001825 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001826 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001827 rc = 1;
drhb0603412007-02-28 04:47:26 +00001828 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001829 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001830 }
1831 }
1832 }else
drhae5e4452007-05-03 17:18:36 +00001833#endif
drhb0603412007-02-28 04:47:26 +00001834
drh70df4fe2006-06-13 15:12:21 +00001835#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001836 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1837 const char *zFile, *zProc;
1838 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001839 zFile = azArg[1];
1840 zProc = nArg>=3 ? azArg[2] : 0;
1841 open_db(p);
1842 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1843 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001844 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001845 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001846 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001847 }
1848 }else
drh70df4fe2006-06-13 15:12:21 +00001849#endif
drh1e397f82006-06-08 15:28:43 +00001850
drhc8ba2122011-03-23 11:16:22 +00001851 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00001852 const char *zFile = azArg[1];
1853 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1854 fclose(p->pLog);
1855 p->pLog = 0;
1856 }
1857 if( strcmp(zFile,"stdout")==0 ){
1858 p->pLog = stdout;
1859 }else if( strcmp(zFile, "stderr")==0 ){
1860 p->pLog = stderr;
1861 }else if( strcmp(zFile, "off")==0 ){
1862 p->pLog = 0;
1863 }else{
1864 p->pLog = fopen(zFile, "w");
1865 if( p->pLog==0 ){
1866 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1867 }
1868 }
1869 }else
1870
shanehe2aa9d72009-11-06 17:20:17 +00001871 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001872 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001873 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001874 ||
shanehe2aa9d72009-11-06 17:20:17 +00001875 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001876 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001877 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001878 ||
shanehe2aa9d72009-11-06 17:20:17 +00001879 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001880 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001881 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001882 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001883 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001884 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001885 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001886 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001887 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001888 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001889 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001890 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001891 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001892 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001893 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001894 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001895 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001896 }else {
shane9bd1b442009-10-23 01:27:39 +00001897 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001898 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001899 rc = 1;
drh75897232000-05-29 14:26:00 +00001900 }
1901 }else
1902
shanehe2aa9d72009-11-06 17:20:17 +00001903 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1904 int n2 = strlen30(azArg[1]);
1905 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1906 p->mode = MODE_Insert;
1907 set_table_name(p, azArg[2]);
1908 }else {
1909 fprintf(stderr, "Error: invalid arguments: "
1910 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1911 rc = 1;
1912 }
1913 }else
1914
persicom7e2dfdd2002-04-18 02:46:52 +00001915 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001916 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1917 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001918 }else
1919
drh75897232000-05-29 14:26:00 +00001920 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1921 if( p->out!=stdout ){
1922 fclose(p->out);
1923 }
1924 if( strcmp(azArg[1],"stdout")==0 ){
1925 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001926 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001927 }else{
drha1f9b5e2004-02-14 16:31:02 +00001928 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001929 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00001930 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00001931 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00001932 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001933 } else {
drh5bb3eb92007-05-04 13:15:55 +00001934 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001935 }
1936 }
1937 }else
1938
drhdd45df82002-04-18 12:39:03 +00001939 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001940 if( nArg >= 2) {
1941 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1942 }
1943 if( nArg >= 3) {
1944 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1945 }
1946 }else
1947
shanehe2aa9d72009-11-06 17:20:17 +00001948 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001949 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001950 }else
1951
drh9ff849f2009-02-04 20:55:57 +00001952 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001953 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001954 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00001955 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1956 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00001957 }else{
shane9bd1b442009-10-23 01:27:39 +00001958 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00001959 fclose(alt);
1960 }
1961 }else
1962
shanehe2aa9d72009-11-06 17:20:17 +00001963 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001964 const char *zSrcFile;
1965 const char *zDb;
1966 sqlite3 *pSrc;
1967 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00001968 int nTimeout = 0;
1969
drh9ff849f2009-02-04 20:55:57 +00001970 if( nArg==2 ){
1971 zSrcFile = azArg[1];
1972 zDb = "main";
1973 }else{
1974 zSrcFile = azArg[2];
1975 zDb = azArg[1];
1976 }
1977 rc = sqlite3_open(zSrcFile, &pSrc);
1978 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001979 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00001980 sqlite3_close(pSrc);
1981 return 1;
1982 }
drhdc2c4912009-02-04 22:46:47 +00001983 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001984 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
1985 if( pBackup==0 ){
1986 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1987 sqlite3_close(pSrc);
1988 return 1;
1989 }
drhdc2c4912009-02-04 22:46:47 +00001990 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
1991 || rc==SQLITE_BUSY ){
1992 if( rc==SQLITE_BUSY ){
1993 if( nTimeout++ >= 3 ) break;
1994 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00001995 }
1996 }
1997 sqlite3_backup_finish(pBackup);
1998 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001999 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002000 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002001 fprintf(stderr, "Error: source database is busy\n");
2002 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002003 }else{
2004 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002005 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002006 }
2007 sqlite3_close(pSrc);
2008 }else
2009
shanehe2aa9d72009-11-06 17:20:17 +00002010 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002011 struct callback_data data;
2012 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002013 open_db(p);
drh75897232000-05-29 14:26:00 +00002014 memcpy(&data, p, sizeof(data));
2015 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002016 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002017 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002018 int i;
shane7d3846a2008-12-11 02:58:26 +00002019 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002020 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002021 char *new_argv[2], *new_colv[2];
2022 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2023 " type text,\n"
2024 " name text,\n"
2025 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002026 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002027 " sql text\n"
2028 ")";
2029 new_argv[1] = 0;
2030 new_colv[0] = "sql";
2031 new_colv[1] = 0;
2032 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002033 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002034 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002035 char *new_argv[2], *new_colv[2];
2036 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2037 " type text,\n"
2038 " name text,\n"
2039 " tbl_name text,\n"
2040 " rootpage integer,\n"
2041 " sql text\n"
2042 ")";
2043 new_argv[1] = 0;
2044 new_colv[0] = "sql";
2045 new_colv[1] = 0;
2046 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002047 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002048 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002049 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002050 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002051 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002052 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2053 " FROM sqlite_master UNION ALL"
2054 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002055 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002056 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002057 callback, &data, &zErrMsg);
2058 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002059 }
drh75897232000-05-29 14:26:00 +00002060 }else{
shane9bd1b442009-10-23 01:27:39 +00002061 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002062 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002063 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2064 " FROM sqlite_master UNION ALL"
2065 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002066 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002067 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002068 callback, &data, &zErrMsg
2069 );
drh75897232000-05-29 14:26:00 +00002070 }
drh75897232000-05-29 14:26:00 +00002071 if( zErrMsg ){
2072 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002073 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002074 rc = 1;
2075 }else if( rc != SQLITE_OK ){
2076 fprintf(stderr,"Error: querying schema information\n");
2077 rc = 1;
2078 }else{
2079 rc = 0;
drh75897232000-05-29 14:26:00 +00002080 }
2081 }else
2082
2083 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002084 sqlite3_snprintf(sizeof(p->separator), p->separator,
2085 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002086 }else
2087
shanehe2aa9d72009-11-06 17:20:17 +00002088 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002089 int i;
2090 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002091 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002092 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002093 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002094 fprintf(p->out,"%9.9s: ", "nullvalue");
2095 output_c_string(p->out, p->nullvalue);
2096 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002097 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002098 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002099 fprintf(p->out,"%9.9s: ", "separator");
2100 output_c_string(p->out, p->separator);
2101 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002102 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002103 fprintf(p->out,"%9.9s: ","width");
2104 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002105 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002106 }
drhfeac5f82004-08-01 00:10:45 +00002107 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002108 }else
2109
shaneh642d8b82010-07-28 16:05:34 +00002110 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2111 p->statsOn = booleanValue(azArg[1]);
2112 }else
2113
shanehe2aa9d72009-11-06 17:20:17 +00002114 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002115 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002116 int nRow;
drhe3710332000-09-29 13:30:53 +00002117 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002118 open_db(p);
drha50da102000-08-08 20:19:09 +00002119 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002120 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002121 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002122 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002123 "UNION ALL "
2124 "SELECT name FROM sqlite_temp_master "
2125 "WHERE type IN ('table','view') "
2126 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002127 &azResult, &nRow, 0, &zErrMsg
2128 );
drha50da102000-08-08 20:19:09 +00002129 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002130 zShellStatic = azArg[1];
2131 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002132 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002133 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002134 "UNION ALL "
2135 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002136 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002137 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002138 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002139 );
danielk1977bc6ada42004-06-30 08:20:16 +00002140 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002141 }
drh75897232000-05-29 14:26:00 +00002142 if( zErrMsg ){
2143 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002144 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002145 rc = 1;
2146 }else if( rc != SQLITE_OK ){
2147 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2148 rc = 1;
2149 }else{
drhe3710332000-09-29 13:30:53 +00002150 int len, maxlen = 0;
2151 int i, j;
2152 int nPrintCol, nPrintRow;
2153 for(i=1; i<=nRow; i++){
2154 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002155 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002156 if( len>maxlen ) maxlen = len;
2157 }
2158 nPrintCol = 80/(maxlen+2);
2159 if( nPrintCol<1 ) nPrintCol = 1;
2160 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2161 for(i=0; i<nPrintRow; i++){
2162 for(j=i+1; j<=nRow; j+=nPrintRow){
2163 char *zSp = j<=nPrintRow ? "" : " ";
2164 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2165 }
2166 printf("\n");
2167 }
2168 }
danielk19776f8a5032004-05-10 10:34:51 +00002169 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002170 }else
2171
shaneh96887e12011-02-10 21:08:58 +00002172 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002173 static const struct {
2174 const char *zCtrlName; /* Name of a test-control option */
2175 int ctrlCode; /* Integer code for that option */
2176 } aCtrl[] = {
2177 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2178 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2179 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2180 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2181 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2182 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2183 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2184 { "assert", SQLITE_TESTCTRL_ASSERT },
2185 { "always", SQLITE_TESTCTRL_ALWAYS },
2186 { "reserve", SQLITE_TESTCTRL_RESERVE },
2187 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2188 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
2189 { "pghdrsz", SQLITE_TESTCTRL_PGHDRSZ },
2190 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2191 };
shaneh96887e12011-02-10 21:08:58 +00002192 int testctrl = -1;
2193 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002194 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002195 open_db(p);
2196
drhd416fe72011-03-17 16:45:50 +00002197 /* convert testctrl text option to value. allow any unique prefix
2198 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002199 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002200 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002201 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2202 if( testctrl<0 ){
2203 testctrl = aCtrl[i].ctrlCode;
2204 }else{
2205 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
2206 testctrl = -1;
2207 break;
2208 }
2209 }
2210 }
2211 if( testctrl<0 ) testctrl = atoi(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002212 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2213 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2214 }else{
2215 switch(testctrl){
2216
2217 /* sqlite3_test_control(int, db, int) */
2218 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2219 case SQLITE_TESTCTRL_RESERVE:
2220 if( nArg==3 ){
2221 int opt = (int)strtol(azArg[2], 0, 0);
2222 rc = sqlite3_test_control(testctrl, p->db, opt);
2223 printf("%d (0x%08x)\n", rc, rc);
2224 } else {
drhd416fe72011-03-17 16:45:50 +00002225 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2226 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002227 }
2228 break;
2229
2230 /* sqlite3_test_control(int) */
2231 case SQLITE_TESTCTRL_PRNG_SAVE:
2232 case SQLITE_TESTCTRL_PRNG_RESTORE:
2233 case SQLITE_TESTCTRL_PRNG_RESET:
2234 case SQLITE_TESTCTRL_PGHDRSZ:
2235 if( nArg==2 ){
2236 rc = sqlite3_test_control(testctrl);
2237 printf("%d (0x%08x)\n", rc, rc);
2238 } else {
2239 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2240 }
2241 break;
2242
2243 /* sqlite3_test_control(int, uint) */
2244 case SQLITE_TESTCTRL_PENDING_BYTE:
2245 if( nArg==3 ){
2246 unsigned int opt = (unsigned int)atoi(azArg[2]);
2247 rc = sqlite3_test_control(testctrl, opt);
2248 printf("%d (0x%08x)\n", rc, rc);
2249 } else {
drhd416fe72011-03-17 16:45:50 +00002250 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2251 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002252 }
2253 break;
2254
2255 /* sqlite3_test_control(int, int) */
2256 case SQLITE_TESTCTRL_ASSERT:
2257 case SQLITE_TESTCTRL_ALWAYS:
2258 if( nArg==3 ){
2259 int opt = atoi(azArg[2]);
2260 rc = sqlite3_test_control(testctrl, opt);
2261 printf("%d (0x%08x)\n", rc, rc);
2262 } else {
drhd416fe72011-03-17 16:45:50 +00002263 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2264 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002265 }
2266 break;
2267
2268 /* sqlite3_test_control(int, char *) */
2269#ifdef SQLITE_N_KEYWORD
2270 case SQLITE_TESTCTRL_ISKEYWORD:
2271 if( nArg==3 ){
2272 const char *opt = azArg[2];
2273 rc = sqlite3_test_control(testctrl, opt);
2274 printf("%d (0x%08x)\n", rc, rc);
2275 } else {
drhd416fe72011-03-17 16:45:50 +00002276 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2277 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002278 }
2279 break;
2280#endif
2281
2282 case SQLITE_TESTCTRL_BITVEC_TEST:
2283 case SQLITE_TESTCTRL_FAULT_INSTALL:
2284 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2285 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2286 default:
drhd416fe72011-03-17 16:45:50 +00002287 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2288 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002289 break;
2290 }
2291 }
2292 }else
2293
shanehe2aa9d72009-11-06 17:20:17 +00002294 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002295 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002296 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002297 }else
2298
drhd416fe72011-03-17 16:45:50 +00002299 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2300 && nArg==2
2301 ){
drh3b1a9882007-11-02 12:53:03 +00002302 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002303 }else
2304
drh9fd301b2011-06-03 13:28:22 +00002305 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
2306 printf("SQLite %s %s\n",
2307 sqlite3_libversion(), sqlite3_sourceid());
2308 }else
2309
shanehe2aa9d72009-11-06 17:20:17 +00002310 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002311 int j;
drh43617e92006-03-06 20:55:46 +00002312 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002313 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2314 p->colWidth[j-1] = atoi(azArg[j]);
2315 }
2316 }else
2317
2318 {
shane9bd1b442009-10-23 01:27:39 +00002319 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002320 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002321 rc = 1;
drh75897232000-05-29 14:26:00 +00002322 }
drh67505e72002-04-19 12:34:06 +00002323
2324 return rc;
drh75897232000-05-29 14:26:00 +00002325}
2326
drh67505e72002-04-19 12:34:06 +00002327/*
drh91a66392007-09-07 01:12:32 +00002328** Return TRUE if a semicolon occurs anywhere in the first N characters
2329** of string z[].
drh324ccef2003-02-05 14:06:20 +00002330*/
drh91a66392007-09-07 01:12:32 +00002331static int _contains_semicolon(const char *z, int N){
2332 int i;
2333 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2334 return 0;
drh324ccef2003-02-05 14:06:20 +00002335}
2336
2337/*
drh70c7a4b2003-04-26 03:03:06 +00002338** Test to see if a line consists entirely of whitespace.
2339*/
2340static int _all_whitespace(const char *z){
2341 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002342 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002343 if( *z=='/' && z[1]=='*' ){
2344 z += 2;
2345 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2346 if( *z==0 ) return 0;
2347 z++;
2348 continue;
2349 }
2350 if( *z=='-' && z[1]=='-' ){
2351 z += 2;
2352 while( *z && *z!='\n' ){ z++; }
2353 if( *z==0 ) return 1;
2354 continue;
2355 }
2356 return 0;
2357 }
2358 return 1;
2359}
2360
2361/*
drha9b17162003-04-29 18:01:28 +00002362** Return TRUE if the line typed in is an SQL command terminator other
2363** than a semi-colon. The SQL Server style "go" command is understood
2364** as is the Oracle "/".
2365*/
2366static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002367 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002368 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2369 return 1; /* Oracle */
2370 }
drhc8d74412004-08-31 23:41:26 +00002371 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2372 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002373 return 1; /* SQL Server */
2374 }
2375 return 0;
2376}
2377
2378/*
drh233a5312008-12-18 22:25:13 +00002379** Return true if zSql is a complete SQL statement. Return false if it
2380** ends in the middle of a string literal or C-style comment.
2381*/
2382static int _is_complete(char *zSql, int nSql){
2383 int rc;
2384 if( zSql==0 ) return 1;
2385 zSql[nSql] = ';';
2386 zSql[nSql+1] = 0;
2387 rc = sqlite3_complete(zSql);
2388 zSql[nSql] = 0;
2389 return rc;
2390}
2391
2392/*
drh67505e72002-04-19 12:34:06 +00002393** Read input from *in and process it. If *in==0 then input
2394** is interactive - the user is typing it it. Otherwise, input
2395** is coming from a file or device. A prompt is issued and history
2396** is saved only if input is interactive. An interrupt signal will
2397** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002398**
2399** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002400*/
drhc28490c2006-10-26 14:25:58 +00002401static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002402 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002403 char *zSql = 0;
2404 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002405 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002406 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002407 int rc;
2408 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002409 int lineno = 0;
2410 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002411
2412 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2413 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002414 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002415 zLine = one_input_line(zSql, in);
2416 if( zLine==0 ){
2417 break; /* We have reached EOF */
2418 }
drh67505e72002-04-19 12:34:06 +00002419 if( seenInterrupt ){
2420 if( in!=0 ) break;
2421 seenInterrupt = 0;
2422 }
drhc28490c2006-10-26 14:25:58 +00002423 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002424 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002425 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002426 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002427 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002428 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002429 break;
2430 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002431 errCnt++;
2432 }
drhdaffd0e2001-04-11 14:28:42 +00002433 continue;
2434 }
drh233a5312008-12-18 22:25:13 +00002435 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002436 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002437 }
drh91a66392007-09-07 01:12:32 +00002438 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002439 if( zSql==0 ){
2440 int i;
drh4c755c02004-08-08 20:22:17 +00002441 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002442 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002443 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002444 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002445 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002446 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002447 exit(1);
2448 }
drh5bb3eb92007-05-04 13:15:55 +00002449 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002450 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002451 }
2452 }else{
drh4f21c4a2008-12-10 22:15:00 +00002453 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002454 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002455 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002456 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002457 exit(1);
2458 }
drh5bb3eb92007-05-04 13:15:55 +00002459 zSql[nSql++] = '\n';
2460 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002461 nSql += len;
2462 }
drh91a66392007-09-07 01:12:32 +00002463 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2464 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002465 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002466 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002467 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002468 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002469 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002470 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002471 char zPrefix[100];
2472 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002473 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002474 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002475 }else{
shane9bd1b442009-10-23 01:27:39 +00002476 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002477 }
drh7f953e22002-07-13 17:33:45 +00002478 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002479 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002480 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002481 zErrMsg = 0;
2482 }else{
shaned2bed1c2009-10-21 03:56:54 +00002483 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002484 }
drhc49f44e2006-10-26 18:15:42 +00002485 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002486 }
2487 free(zSql);
2488 zSql = 0;
2489 nSql = 0;
2490 }
2491 }
2492 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002493 if( !_all_whitespace(zSql) ){
2494 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2495 }
drhdaffd0e2001-04-11 14:28:42 +00002496 free(zSql);
2497 }
danielk19772ac27622007-07-03 05:31:16 +00002498 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002499 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002500}
2501
drh67505e72002-04-19 12:34:06 +00002502/*
2503** Return a pathname which is the user's home directory. A
2504** 0 return indicates an error of some kind. Space to hold the
2505** resulting string is obtained from malloc(). The calling
2506** function should free the result.
2507*/
2508static char *find_home_dir(void){
2509 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002510
chw97185482008-11-17 08:05:31 +00002511#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002512 struct passwd *pwent;
2513 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002514 if( (pwent=getpwuid(uid)) != NULL) {
2515 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002516 }
2517#endif
2518
chw65d3c132007-11-12 21:09:10 +00002519#if defined(_WIN32_WCE)
2520 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2521 */
2522 home_dir = strdup("/");
2523#else
2524
drh164a1b62006-08-19 11:15:20 +00002525#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2526 if (!home_dir) {
2527 home_dir = getenv("USERPROFILE");
2528 }
2529#endif
2530
drh67505e72002-04-19 12:34:06 +00002531 if (!home_dir) {
2532 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002533 }
2534
drhcdb36b72006-06-12 12:57:45 +00002535#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002536 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002537 char *zDrive, *zPath;
2538 int n;
2539 zDrive = getenv("HOMEDRIVE");
2540 zPath = getenv("HOMEPATH");
2541 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002542 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002543 home_dir = malloc( n );
2544 if( home_dir==0 ) return 0;
2545 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2546 return home_dir;
2547 }
2548 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002549 }
2550#endif
2551
chw65d3c132007-11-12 21:09:10 +00002552#endif /* !_WIN32_WCE */
2553
drh67505e72002-04-19 12:34:06 +00002554 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002555 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002556 char *z = malloc( n );
2557 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002558 home_dir = z;
2559 }
drhe98d4fa2002-04-21 19:06:22 +00002560
drh67505e72002-04-19 12:34:06 +00002561 return home_dir;
2562}
2563
2564/*
2565** Read input from the file given by sqliterc_override. Or if that
2566** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002567**
2568** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002569*/
shane9bd1b442009-10-23 01:27:39 +00002570static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002571 struct callback_data *p, /* Configuration data */
2572 const char *sqliterc_override /* Name of config file. NULL to use default */
2573){
persicom7e2dfdd2002-04-18 02:46:52 +00002574 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002575 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002576 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002577 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002578 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002579 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002580
2581 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002582 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002583 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002584#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002585 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002586#endif
shane9bd1b442009-10-23 01:27:39 +00002587 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002588 }
drh4f21c4a2008-12-10 22:15:00 +00002589 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002590 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002591 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002592 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2593 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002594 }
drha959ac42007-06-20 13:10:00 +00002595 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002596 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002597 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002598 }
drha1f9b5e2004-02-14 16:31:02 +00002599 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002600 if( in ){
drhc28490c2006-10-26 14:25:58 +00002601 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002602 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002603 }
shane9bd1b442009-10-23 01:27:39 +00002604 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002605 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002606 }
drh43617e92006-03-06 20:55:46 +00002607 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002608 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002609}
2610
drh67505e72002-04-19 12:34:06 +00002611/*
drhe1e38c42003-05-04 18:30:59 +00002612** Show available command line options
2613*/
2614static const char zOptions[] =
shaneh5fc25012009-11-11 04:17:07 +00002615 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002616 " -init filename read/process named file\n"
2617 " -echo print commands before execution\n"
2618 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002619 " -bail stop after hitting an error\n"
2620 " -interactive force interactive I/O\n"
2621 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002622 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002623 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002624 " -html set output mode to HTML\n"
2625 " -line set output mode to 'line'\n"
2626 " -list set output mode to 'list'\n"
2627 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002628 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002629 " -nullvalue 'text' set text string for NULL values\n"
2630 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002631 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00002632#ifdef SQLITE_ENABLE_VFSTRACE
2633 " -vfstrace enable tracing of all VFS calls\n"
2634#endif
drh6f25e892011-07-08 17:02:57 +00002635#ifdef SQLITE_ENABLE_MULTIPLEX
2636 " -multiplex enable the multiplexor VFS\n"
2637#endif
drhe1e38c42003-05-04 18:30:59 +00002638;
2639static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002640 fprintf(stderr,
2641 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2642 "FILENAME is the name of an SQLite database. A new database is created\n"
2643 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002644 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002645 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002646 }else{
2647 fprintf(stderr, "Use the -help option for additional information\n");
2648 }
2649 exit(1);
2650}
2651
2652/*
drh67505e72002-04-19 12:34:06 +00002653** Initialize the state information in data
2654*/
drh0850b532006-01-31 19:31:43 +00002655static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002656 memset(data, 0, sizeof(*data));
2657 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002658 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002659 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00002660 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00002661 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002662 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2663 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002664 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002665}
2666
drh75897232000-05-29 14:26:00 +00002667int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002668 char *zErrMsg = 0;
2669 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002670 const char *zInitFile = 0;
2671 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002672 int i;
drhc28490c2006-10-26 14:25:58 +00002673 int rc = 0;
drh75897232000-05-29 14:26:00 +00002674
drh52784bd2011-05-18 17:15:06 +00002675 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
2676 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
2677 sqlite3_sourceid(), SQLITE_SOURCE_ID);
2678 exit(1);
2679 }
drhdaffd0e2001-04-11 14:28:42 +00002680 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002681 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002682 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002683
drh44c2eb12003-04-30 11:38:26 +00002684 /* Make sure we have a valid signal handler early, before anything
2685 ** else is done.
2686 */
drh4c504392000-10-16 22:06:40 +00002687#ifdef SIGINT
2688 signal(SIGINT, interrupt_handler);
2689#endif
drh44c2eb12003-04-30 11:38:26 +00002690
drh22fbcb82004-02-01 01:22:50 +00002691 /* Do an initial pass through the command-line argument to locate
2692 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002693 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002694 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002695 */
drh22fbcb82004-02-01 01:22:50 +00002696 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002697 char *z;
drh44c2eb12003-04-30 11:38:26 +00002698 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002699 z = argv[i];
2700 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002701 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2702 i++;
drh22fbcb82004-02-01 01:22:50 +00002703 }else if( strcmp(argv[i],"-init")==0 ){
2704 i++;
2705 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002706 /* Need to check for batch mode here to so we can avoid printing
2707 ** informational messages (like from process_sqliterc) before
2708 ** we do the actual processing of arguments later in a second pass.
2709 */
2710 }else if( strcmp(argv[i],"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002711 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002712 }else if( strcmp(argv[i],"-heap")==0 ){
2713 int j, c;
2714 const char *zSize;
2715 sqlite3_int64 szHeap;
2716
2717 zSize = argv[++i];
2718 szHeap = atoi(zSize);
2719 for(j=0; (c = zSize[j])!=0; j++){
2720 if( c=='M' ){ szHeap *= 1000000; break; }
2721 if( c=='K' ){ szHeap *= 1000; break; }
2722 if( c=='G' ){ szHeap *= 1000000000; break; }
2723 }
2724 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
2725#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2726 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2727#endif
drh97ae8ff2011-03-16 16:56:29 +00002728#ifdef SQLITE_ENABLE_VFSTRACE
2729 }else if( strcmp(argv[i],"-vfstrace")==0 ){
2730 extern int vfstrace_register(
2731 const char *zTraceName,
2732 const char *zOldVfsName,
2733 int (*xOut)(const char*,void*),
2734 void *pOutArg,
2735 int makeDefault
2736 );
drh2b625e22011-03-16 17:05:28 +00002737 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00002738#endif
drh6f25e892011-07-08 17:02:57 +00002739#ifdef SQLITE_ENABLE_MULTIPLEX
2740 }else if( strcmp(argv[i],"-multiplex")==0 ){
2741 extern int sqlite3_multiple_initialize(const char*,int);
2742 sqlite3_multiplex_initialize(0, 1);
2743#endif
drha7e61d82011-03-12 17:02:57 +00002744 }else if( strcmp(argv[i],"-vfs")==0 ){
drh77ec9ba2011-03-15 18:35:44 +00002745 sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
drha7e61d82011-03-12 17:02:57 +00002746 if( pVfs ){
2747 sqlite3_vfs_register(pVfs, 1);
2748 }else{
2749 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
2750 exit(1);
2751 }
drh44c2eb12003-04-30 11:38:26 +00002752 }
2753 }
drh22fbcb82004-02-01 01:22:50 +00002754 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002755#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002756 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2757#else
drh22fbcb82004-02-01 01:22:50 +00002758 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002759#endif
drh22fbcb82004-02-01 01:22:50 +00002760 }else{
danielk197703aded42004-11-22 05:26:27 +00002761#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002762 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002763#else
2764 data.zDbFilename = 0;
2765#endif
drh22fbcb82004-02-01 01:22:50 +00002766 }
2767 if( i<argc ){
2768 zFirstCmd = argv[i++];
2769 }
shaneh5fc25012009-11-11 04:17:07 +00002770 if( i<argc ){
2771 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2772 fprintf(stderr,"Use -help for a list of options.\n");
2773 return 1;
2774 }
drh44c2eb12003-04-30 11:38:26 +00002775 data.out = stdout;
2776
drh01b41712005-08-29 23:06:23 +00002777#ifdef SQLITE_OMIT_MEMORYDB
2778 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002779 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2780 return 1;
drh01b41712005-08-29 23:06:23 +00002781 }
2782#endif
2783
drh44c2eb12003-04-30 11:38:26 +00002784 /* Go ahead and open the database file if it already exists. If the
2785 ** file does not exist, delay opening it. This prevents empty database
2786 ** files from being created if a user mistypes the database name argument
2787 ** to the sqlite command-line tool.
2788 */
drhc8d74412004-08-31 23:41:26 +00002789 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002790 open_db(&data);
2791 }
2792
drh22fbcb82004-02-01 01:22:50 +00002793 /* Process the initialization file if there is one. If no -init option
2794 ** is given on the command line, look for a file named ~/.sqliterc and
2795 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002796 */
shane86f5bdb2009-10-24 02:00:07 +00002797 rc = process_sqliterc(&data,zInitFile);
2798 if( rc>0 ){
2799 return rc;
2800 }
drh44c2eb12003-04-30 11:38:26 +00002801
drh22fbcb82004-02-01 01:22:50 +00002802 /* Make a second pass through the command-line argument and set
2803 ** options. This second pass is delayed until after the initialization
2804 ** file is processed so that the command-line arguments will override
2805 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002806 */
drh22fbcb82004-02-01 01:22:50 +00002807 for(i=1; i<argc && argv[i][0]=='-'; i++){
2808 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002809 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002810 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002811 i++;
2812 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002813 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002814 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002815 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002816 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002817 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002818 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002819 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002820 }else if( strcmp(z,"-csv")==0 ){
2821 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002822 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002823 }else if( strcmp(z,"-separator")==0 ){
2824 i++;
shaneh5fc25012009-11-11 04:17:07 +00002825 if(i>=argc){
2826 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2827 fprintf(stderr,"Use -help for a list of options.\n");
2828 return 1;
2829 }
drh5bb3eb92007-05-04 13:15:55 +00002830 sqlite3_snprintf(sizeof(data.separator), data.separator,
2831 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002832 }else if( strcmp(z,"-nullvalue")==0 ){
2833 i++;
shaneh5fc25012009-11-11 04:17:07 +00002834 if(i>=argc){
2835 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2836 fprintf(stderr,"Use -help for a list of options.\n");
2837 return 1;
2838 }
drh5bb3eb92007-05-04 13:15:55 +00002839 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2840 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002841 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002842 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002843 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002844 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002845 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002846 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00002847 }else if( strcmp(z,"-stats")==0 ){
2848 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002849 }else if( strcmp(z,"-bail")==0 ){
2850 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002851 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00002852 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00002853 return 0;
drhc28490c2006-10-26 14:25:58 +00002854 }else if( strcmp(z,"-interactive")==0 ){
2855 stdin_is_interactive = 1;
2856 }else if( strcmp(z,"-batch")==0 ){
2857 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002858 }else if( strcmp(z,"-heap")==0 ){
2859 i++;
drha7e61d82011-03-12 17:02:57 +00002860 }else if( strcmp(z,"-vfs")==0 ){
2861 i++;
drh6f25e892011-07-08 17:02:57 +00002862#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00002863 }else if( strcmp(z,"-vfstrace")==0 ){
2864 i++;
drh6f25e892011-07-08 17:02:57 +00002865#endif
2866#ifdef SQLITE_ENABLE_MULTIPLEX
2867 }else if( strcmp(z,"-multiplex")==0 ){
2868 i++;
2869#endif
drh80e8be92006-08-29 12:04:19 +00002870 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002871 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002872 }else{
shane86f5bdb2009-10-24 02:00:07 +00002873 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002874 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002875 return 1;
2876 }
2877 }
drh44c2eb12003-04-30 11:38:26 +00002878
drh22fbcb82004-02-01 01:22:50 +00002879 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002880 /* Run just the command that follows the database name
2881 */
drh22fbcb82004-02-01 01:22:50 +00002882 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00002883 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002884 }else{
drh44c2eb12003-04-30 11:38:26 +00002885 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00002886 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00002887 if( zErrMsg!=0 ){
2888 fprintf(stderr,"Error: %s\n", zErrMsg);
2889 return rc!=0 ? rc : 1;
2890 }else if( rc!=0 ){
2891 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
2892 return rc;
drh6ff13852001-11-25 13:18:23 +00002893 }
drh75897232000-05-29 14:26:00 +00002894 }
2895 }else{
drh44c2eb12003-04-30 11:38:26 +00002896 /* Run commands received from standard input
2897 */
drhc28490c2006-10-26 14:25:58 +00002898 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002899 char *zHome;
2900 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002901 int nHistory;
drh75897232000-05-29 14:26:00 +00002902 printf(
drh9fd301b2011-06-03 13:28:22 +00002903 "SQLite version %s %.19s\n"
mihailim65df9db2008-06-28 11:29:22 +00002904 "Enter \".help\" for instructions\n"
2905 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00002906 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00002907 );
drh67505e72002-04-19 12:34:06 +00002908 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002909 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002910 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002911 if( (zHistory = malloc(nHistory))!=0 ){
2912 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2913 }
drh67505e72002-04-19 12:34:06 +00002914 }
danielk19774af00c62005-01-23 23:43:21 +00002915#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002916 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002917#endif
drhc28490c2006-10-26 14:25:58 +00002918 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002919 if( zHistory ){
2920 stifle_history(100);
2921 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002922 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002923 }
adamd0a3daa32006-07-28 20:16:14 +00002924 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002925 }else{
drhc28490c2006-10-26 14:25:58 +00002926 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002927 }
2928 }
drh33048c02001-10-01 14:29:22 +00002929 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00002930 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00002931 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00002932 }
drhc28490c2006-10-26 14:25:58 +00002933 return rc;
drh75897232000-05-29 14:26:00 +00002934}