blob: 3fd0db3682315336e8ace8a8c439b09026ccb46d [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
shane18e526c2008-12-10 22:30:24 +000015#if defined(_WIN32) || defined(WIN32)
16/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh75897232000-05-29 14:26:00 +000020#include <stdlib.h>
21#include <string.h>
22#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000023#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000024#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000025#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000026#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000027
drh454ad582007-11-26 22:54:27 +000028#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000029# include <signal.h>
chw97185482008-11-17 08:05:31 +000030# if !defined(__RTP__) && !defined(_WRS_KERNEL)
31# include <pwd.h>
32# endif
drhdd45df82002-04-18 12:39:03 +000033# include <unistd.h>
34# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000035#endif
drh75897232000-05-29 14:26:00 +000036
drhcdb36b72006-06-12 12:57:45 +000037#ifdef __OS2__
38# include <unistd.h>
39#endif
40
drh81d7fd12010-12-08 00:02:26 +000041#ifdef HAVE_EDITLINE
42# include <editline/editline.h>
43#endif
drh16e59552000-07-31 11:57:37 +000044#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000045# include <readline/readline.h>
46# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000047#endif
48#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
drh9347b202003-07-18 01:30:59 +000049# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000050# define add_history(X)
drh67505e72002-04-19 12:34:06 +000051# define read_history(X)
52# define write_history(X)
53# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000054#endif
55
adamd2e8464a2006-09-06 21:39:40 +000056#if defined(_WIN32) || defined(WIN32)
57# include <io.h>
shane18e526c2008-12-10 22:30:24 +000058#define isatty(h) _isatty(h)
59#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000060#else
drh4328c8b2003-04-26 02:50:11 +000061/* Make sure isatty() has a prototype.
62*/
63extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000064#endif
drh4328c8b2003-04-26 02:50:11 +000065
chw65d3c132007-11-12 21:09:10 +000066#if defined(_WIN32_WCE)
67/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
68 * thus we always assume that we have a console. That can be
69 * overridden with the -batch command line option.
70 */
71#define isatty(x) 1
72#endif
73
chw97185482008-11-17 08:05:31 +000074#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000075#include <sys/time.h>
76#include <sys/resource.h>
77
drhda108222009-02-25 19:07:24 +000078/* Saved resource information for the beginning of an operation */
79static struct rusage sBegin;
80
81/* True if the timer is enabled */
82static int enableTimer = 0;
83
84/*
85** Begin timing an operation
86*/
87static void beginTimer(void){
88 if( enableTimer ){
89 getrusage(RUSAGE_SELF, &sBegin);
90 }
91}
92
93/* Return the difference of two time_structs in seconds */
94static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
95 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
96 (double)(pEnd->tv_sec - pStart->tv_sec);
97}
98
99/*
100** Print the timing results.
101*/
102static void endTimer(void){
103 if( enableTimer ){
104 struct rusage sEnd;
105 getrusage(RUSAGE_SELF, &sEnd);
106 printf("CPU Time: user %f sys %f\n",
107 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
108 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
109 }
110}
shaneb320ccd2009-10-21 03:42:58 +0000111
drhda108222009-02-25 19:07:24 +0000112#define BEGIN_TIMER beginTimer()
113#define END_TIMER endTimer()
114#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000115
116#elif (defined(_WIN32) || defined(WIN32))
117
118#include <windows.h>
119
120/* Saved resource information for the beginning of an operation */
121static HANDLE hProcess;
122static FILETIME ftKernelBegin;
123static FILETIME ftUserBegin;
124typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
125static GETPROCTIMES getProcessTimesAddr = NULL;
126
127/* True if the timer is enabled */
128static int enableTimer = 0;
129
130/*
131** Check to see if we have timer support. Return 1 if necessary
132** support found (or found previously).
133*/
134static int hasTimer(void){
135 if( getProcessTimesAddr ){
136 return 1;
137 } else {
138 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
139 ** See if the version we are running on has it, and if it does, save off
140 ** a pointer to it and the current process handle.
141 */
142 hProcess = GetCurrentProcess();
143 if( hProcess ){
144 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
145 if( NULL != hinstLib ){
146 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
147 if( NULL != getProcessTimesAddr ){
148 return 1;
149 }
150 FreeLibrary(hinstLib);
151 }
152 }
153 }
154 return 0;
155}
156
157/*
158** Begin timing an operation
159*/
160static void beginTimer(void){
161 if( enableTimer && getProcessTimesAddr ){
162 FILETIME ftCreation, ftExit;
163 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
164 }
165}
166
167/* Return the difference of two FILETIME structs in seconds */
168static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
169 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
170 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
171 return (double) ((i64End - i64Start) / 10000000.0);
172}
173
174/*
175** Print the timing results.
176*/
177static void endTimer(void){
178 if( enableTimer && getProcessTimesAddr){
179 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
180 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
181 printf("CPU Time: user %f sys %f\n",
182 timeDiff(&ftUserBegin, &ftUserEnd),
183 timeDiff(&ftKernelBegin, &ftKernelEnd));
184 }
185}
186
187#define BEGIN_TIMER beginTimer()
188#define END_TIMER endTimer()
189#define HAS_TIMER hasTimer()
190
drhda108222009-02-25 19:07:24 +0000191#else
192#define BEGIN_TIMER
193#define END_TIMER
194#define HAS_TIMER 0
195#endif
196
shanec0688ea2009-03-05 03:48:06 +0000197/*
198** Used to prevent warnings about unused parameters
199*/
200#define UNUSED_PARAMETER(x) (void)(x)
201
drhe91d16b2008-12-08 18:27:31 +0000202/*
drhc49f44e2006-10-26 18:15:42 +0000203** If the following flag is set, then command execution stops
204** at an error if we are not interactive.
205*/
206static int bail_on_error = 0;
207
208/*
drhc28490c2006-10-26 14:25:58 +0000209** Threat stdin as an interactive input if the following variable
210** is true. Otherwise, assume stdin is connected to a file or pipe.
211*/
212static int stdin_is_interactive = 1;
213
214/*
drh4c504392000-10-16 22:06:40 +0000215** The following is the open SQLite database. We make a pointer
216** to this database a static variable so that it can be accessed
217** by the SIGINT handler to interrupt database processing.
218*/
danielk197792f9a1b2004-06-19 09:08:16 +0000219static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000220
221/*
drh67505e72002-04-19 12:34:06 +0000222** True if an interrupt (Control-C) has been received.
223*/
drh43617e92006-03-06 20:55:46 +0000224static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000225
226/*
persicom7e2dfdd2002-04-18 02:46:52 +0000227** This is the name of our program. It is set in main(), used
228** in a number of other places, mostly for error messages.
229*/
230static char *Argv0;
231
232/*
233** Prompt strings. Initialized in main. Settable with
234** .prompt main continue
235*/
236static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
237static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
238
drhb0603412007-02-28 04:47:26 +0000239/*
240** Write I/O traces to the following stream.
241*/
rsebe0a9092007-07-30 18:24:38 +0000242#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000243static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000244#endif
drhb0603412007-02-28 04:47:26 +0000245
246/*
247** This routine works like printf in that its first argument is a
248** format string and subsequent arguments are values to be substituted
249** in place of % fields. The result of formatting this string
250** is written to iotrace.
251*/
rsebe0a9092007-07-30 18:24:38 +0000252#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000253static void iotracePrintf(const char *zFormat, ...){
254 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000255 char *z;
drhb0603412007-02-28 04:47:26 +0000256 if( iotrace==0 ) return;
257 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000258 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000259 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000260 fprintf(iotrace, "%s", z);
261 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000262}
rsebe0a9092007-07-30 18:24:38 +0000263#endif
drhb0603412007-02-28 04:47:26 +0000264
drh44c2eb12003-04-30 11:38:26 +0000265
persicom7e2dfdd2002-04-18 02:46:52 +0000266/*
drh83965662003-04-17 02:54:13 +0000267** Determines if a string is a number of not.
268*/
danielk19772e588c72005-12-09 14:25:08 +0000269static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000270 if( *z=='-' || *z=='+' ) z++;
271 if( !isdigit(*z) ){
272 return 0;
273 }
274 z++;
275 if( realnum ) *realnum = 0;
276 while( isdigit(*z) ){ z++; }
277 if( *z=='.' ){
278 z++;
279 if( !isdigit(*z) ) return 0;
280 while( isdigit(*z) ){ z++; }
281 if( realnum ) *realnum = 1;
282 }
283 if( *z=='e' || *z=='E' ){
284 z++;
285 if( *z=='+' || *z=='-' ) z++;
286 if( !isdigit(*z) ) return 0;
287 while( isdigit(*z) ){ z++; }
288 if( realnum ) *realnum = 1;
289 }
290 return *z==0;
291}
drh83965662003-04-17 02:54:13 +0000292
293/*
danielk1977bc6ada42004-06-30 08:20:16 +0000294** A global char* and an SQL function to access its current value
295** from within an SQL statement. This program used to use the
296** sqlite_exec_printf() API to substitue a string into an SQL statement.
297** The correct way to do this with sqlite3 is to use the bind API, but
298** since the shell is built around the callback paradigm it would be a lot
299** of work. Instead just use this hack, which is quite harmless.
300*/
301static const char *zShellStatic = 0;
302static void shellstaticFunc(
303 sqlite3_context *context,
304 int argc,
305 sqlite3_value **argv
306){
307 assert( 0==argc );
308 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000309 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000310 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000311 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
312}
313
314
315/*
drhfeac5f82004-08-01 00:10:45 +0000316** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000317** the text in memory obtained from malloc() and returns a pointer
318** to the text. NULL is returned at end of file, or if malloc()
319** fails.
320**
321** The interface is like "readline" but no command-line editing
322** is done.
323*/
drh9347b202003-07-18 01:30:59 +0000324static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000325 char *zLine;
326 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000327 int n;
328 int eol;
329
330 if( zPrompt && *zPrompt ){
331 printf("%s",zPrompt);
332 fflush(stdout);
333 }
334 nLine = 100;
335 zLine = malloc( nLine );
336 if( zLine==0 ) return 0;
337 n = 0;
338 eol = 0;
339 while( !eol ){
340 if( n+100>nLine ){
341 nLine = nLine*2 + 100;
342 zLine = realloc(zLine, nLine);
343 if( zLine==0 ) return 0;
344 }
drhdaffd0e2001-04-11 14:28:42 +0000345 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000346 if( n==0 ){
347 free(zLine);
348 return 0;
349 }
350 zLine[n] = 0;
351 eol = 1;
352 break;
353 }
354 while( zLine[n] ){ n++; }
355 if( n>0 && zLine[n-1]=='\n' ){
356 n--;
shaneh13b36022009-12-17 21:07:15 +0000357 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000358 zLine[n] = 0;
359 eol = 1;
360 }
361 }
362 zLine = realloc( zLine, n+1 );
363 return zLine;
364}
365
366/*
drhc28490c2006-10-26 14:25:58 +0000367** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000368**
369** zPrior is a string of prior text retrieved. If not the empty
370** string, then issue a continuation prompt.
371*/
drhdaffd0e2001-04-11 14:28:42 +0000372static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000373 char *zPrompt;
374 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000375 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000376 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000377 }
378 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000379 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000380 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000381 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000382 }
383 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000384#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000385 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000386#endif
drh8e7e7a22000-05-30 18:45:23 +0000387 return zResult;
388}
389
persicom7e2dfdd2002-04-18 02:46:52 +0000390struct previous_mode_data {
391 int valid; /* Is there legit data in here? */
392 int mode;
393 int showHeader;
394 int colWidth[100];
395};
drh45e29d82006-11-20 16:21:10 +0000396
drh8e7e7a22000-05-30 18:45:23 +0000397/*
drh75897232000-05-29 14:26:00 +0000398** An pointer to an instance of this structure is passed from
399** the main program to the callback. This is used to communicate
400** state and mode information.
401*/
402struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000403 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000404 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000405 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000406 int cnt; /* Number of records displayed so far */
407 FILE *out; /* Write results here */
408 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000409 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000410 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000411 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000412 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000413 int colWidth[100]; /* Requested width of each column when in column mode*/
414 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000415 char nullvalue[20]; /* The text to print when a NULL comes back from
416 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000417 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000418 /* Holds the mode information just before
419 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000420 char outfile[FILENAME_MAX]; /* Filename for *out */
421 const char *zDbFilename; /* name of the database file */
shane626a6e42009-10-22 17:30:15 +0000422 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000423 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000424};
425
426/*
427** These are the allowed modes.
428*/
drh967e8b72000-06-21 13:59:10 +0000429#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000430#define MODE_Column 1 /* One record per line in neat columns */
431#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000432#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
433#define MODE_Html 4 /* Generate an XHTML table */
434#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000435#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000436#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000437#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000438
drh66ce4d02008-02-15 17:38:06 +0000439static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000440 "line",
441 "column",
442 "list",
443 "semi",
444 "html",
drhfeac5f82004-08-01 00:10:45 +0000445 "insert",
446 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000447 "csv",
drh66ce4d02008-02-15 17:38:06 +0000448 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000449};
drh75897232000-05-29 14:26:00 +0000450
451/*
452** Number of elements in an array
453*/
drh902b9ee2008-12-05 17:17:07 +0000454#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000455
456/*
drhea678832008-12-10 19:26:22 +0000457** Compute a string length that is limited to what can be stored in
458** lower 30 bits of a 32-bit signed integer.
459*/
drh4f21c4a2008-12-10 22:15:00 +0000460static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000461 const char *z2 = z;
462 while( *z2 ){ z2++; }
463 return 0x3fffffff & (int)(z2 - z);
464}
465
466/*
drh127f9d72010-02-23 01:47:00 +0000467** A callback for the sqlite3_log() interface.
468*/
469static void shellLog(void *pArg, int iErrCode, const char *zMsg){
470 struct callback_data *p = (struct callback_data*)pArg;
471 if( p->pLog==0 ) return;
472 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
473 fflush(p->pLog);
474}
475
476/*
shane626a6e42009-10-22 17:30:15 +0000477** Output the given string as a hex-encoded blob (eg. X'1234' )
478*/
479static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
480 int i;
481 char *zBlob = (char *)pBlob;
482 fprintf(out,"X'");
483 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
484 fprintf(out,"'");
485}
486
487/*
drh28bd4bc2000-06-15 15:57:22 +0000488** Output the given string as a quoted string using SQL quoting conventions.
489*/
490static void output_quoted_string(FILE *out, const char *z){
491 int i;
492 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000493 for(i=0; z[i]; i++){
494 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000495 }
496 if( nSingle==0 ){
497 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000498 }else{
499 fprintf(out,"'");
500 while( *z ){
501 for(i=0; z[i] && z[i]!='\''; i++){}
502 if( i==0 ){
503 fprintf(out,"''");
504 z++;
505 }else if( z[i]=='\'' ){
506 fprintf(out,"%.*s''",i,z);
507 z += i+1;
508 }else{
drhcd7d2732002-02-26 23:24:26 +0000509 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000510 break;
511 }
512 }
drhcd7d2732002-02-26 23:24:26 +0000513 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000514 }
515}
516
517/*
drhfeac5f82004-08-01 00:10:45 +0000518** Output the given string as a quoted according to C or TCL quoting rules.
519*/
520static void output_c_string(FILE *out, const char *z){
521 unsigned int c;
522 fputc('"', out);
523 while( (c = *(z++))!=0 ){
524 if( c=='\\' ){
525 fputc(c, out);
526 fputc(c, out);
527 }else if( c=='\t' ){
528 fputc('\\', out);
529 fputc('t', out);
530 }else if( c=='\n' ){
531 fputc('\\', out);
532 fputc('n', out);
533 }else if( c=='\r' ){
534 fputc('\\', out);
535 fputc('r', out);
536 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000537 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000538 }else{
539 fputc(c, out);
540 }
541 }
542 fputc('"', out);
543}
544
545/*
drhc08a4f12000-06-15 16:49:48 +0000546** Output the given string with characters that are special to
547** HTML escaped.
548*/
549static void output_html_string(FILE *out, const char *z){
550 int i;
551 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000552 for(i=0; z[i]
553 && z[i]!='<'
554 && z[i]!='&'
555 && z[i]!='>'
556 && z[i]!='\"'
557 && z[i]!='\'';
558 i++){}
drhc08a4f12000-06-15 16:49:48 +0000559 if( i>0 ){
560 fprintf(out,"%.*s",i,z);
561 }
562 if( z[i]=='<' ){
563 fprintf(out,"&lt;");
564 }else if( z[i]=='&' ){
565 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000566 }else if( z[i]=='>' ){
567 fprintf(out,"&gt;");
568 }else if( z[i]=='\"' ){
569 fprintf(out,"&quot;");
570 }else if( z[i]=='\'' ){
571 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000572 }else{
573 break;
574 }
575 z += i + 1;
576 }
577}
578
579/*
drhc49f44e2006-10-26 18:15:42 +0000580** If a field contains any character identified by a 1 in the following
581** array, then the string must be quoted for CSV.
582*/
583static const char needCsvQuote[] = {
584 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
585 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
586 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
587 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
588 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
591 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
592 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
593 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
594 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
595 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
596 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
597 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
598 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
599 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
600};
601
602/*
drh8e64d1c2004-10-07 00:32:39 +0000603** Output a single term of CSV. Actually, p->separator is used for
604** the separator, which may or may not be a comma. p->nullvalue is
605** the null value. Strings are quoted using ANSI-C rules. Numbers
606** appear outside of quotes.
607*/
608static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000609 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000610 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000611 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000612 }else{
drhc49f44e2006-10-26 18:15:42 +0000613 int i;
drh4f21c4a2008-12-10 22:15:00 +0000614 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000615 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000616 if( needCsvQuote[((unsigned char*)z)[i]]
617 || (z[i]==p->separator[0] &&
618 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000619 i = 0;
620 break;
621 }
622 }
623 if( i==0 ){
624 putc('"', out);
625 for(i=0; z[i]; i++){
626 if( z[i]=='"' ) putc('"', out);
627 putc(z[i], out);
628 }
629 putc('"', out);
630 }else{
631 fprintf(out, "%s", z);
632 }
drh8e64d1c2004-10-07 00:32:39 +0000633 }
634 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000635 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000636 }
637}
638
danielk19774af00c62005-01-23 23:43:21 +0000639#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000640/*
drh4c504392000-10-16 22:06:40 +0000641** This routine runs when the user presses Ctrl-C
642*/
643static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000644 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000645 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000646 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000647}
danielk19774af00c62005-01-23 23:43:21 +0000648#endif
drh4c504392000-10-16 22:06:40 +0000649
650/*
shane626a6e42009-10-22 17:30:15 +0000651** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000652** invokes for each row of a query result.
653*/
shane626a6e42009-10-22 17:30:15 +0000654static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000655 int i;
656 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000657
drh75897232000-05-29 14:26:00 +0000658 switch( p->mode ){
659 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000660 int w = 5;
drh6a535342001-10-19 16:44:56 +0000661 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000662 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000663 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000664 if( len>w ) w = len;
665 }
drh75897232000-05-29 14:26:00 +0000666 if( p->cnt++>0 ) fprintf(p->out,"\n");
667 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000668 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000669 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000670 }
671 break;
672 }
danielk19770d78bae2008-01-03 07:09:48 +0000673 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000674 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000675 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000676 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000677 int w, n;
678 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000679 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000680 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000681 w = 0;
drh75897232000-05-29 14:26:00 +0000682 }
drha0c66f52000-07-29 13:20:21 +0000683 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000684 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000685 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000686 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000687 if( w<n ) w = n;
688 }
689 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000690 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000691 }
692 if( p->showHeader ){
693 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
694 }
695 }
696 if( p->showHeader ){
697 for(i=0; i<nArg; i++){
698 int w;
699 if( i<ArraySize(p->actualWidth) ){
700 w = p->actualWidth[i];
701 }else{
702 w = 10;
703 }
704 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
705 "----------------------------------------------------------",
706 i==nArg-1 ? "\n": " ");
707 }
drh75897232000-05-29 14:26:00 +0000708 }
709 }
drh6a535342001-10-19 16:44:56 +0000710 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000711 for(i=0; i<nArg; i++){
712 int w;
drha0c66f52000-07-29 13:20:21 +0000713 if( i<ArraySize(p->actualWidth) ){
714 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000715 }else{
716 w = 10;
717 }
drhea678832008-12-10 19:26:22 +0000718 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000719 strlen30(azArg[i])>w ){
720 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000721 }
drhc61053b2000-06-04 12:58:36 +0000722 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000723 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000724 }
725 break;
726 }
drhe3710332000-09-29 13:30:53 +0000727 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000728 case MODE_List: {
729 if( p->cnt++==0 && p->showHeader ){
730 for(i=0; i<nArg; i++){
731 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
732 }
733 }
drh6a535342001-10-19 16:44:56 +0000734 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000735 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000736 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000737 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000738 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000739 if( i<nArg-1 ){
740 fprintf(p->out, "%s", p->separator);
741 }else if( p->mode==MODE_Semi ){
742 fprintf(p->out, ";\n");
743 }else{
744 fprintf(p->out, "\n");
745 }
drh75897232000-05-29 14:26:00 +0000746 }
747 break;
748 }
drh1e5d0e92000-05-31 23:33:17 +0000749 case MODE_Html: {
750 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000751 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000752 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000753 fprintf(p->out,"<TH>");
754 output_html_string(p->out, azCol[i]);
755 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000756 }
mihailim57c591a2008-06-23 21:26:05 +0000757 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000758 }
drh6a535342001-10-19 16:44:56 +0000759 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000760 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000761 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000762 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000763 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000764 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000765 }
mihailim57c591a2008-06-23 21:26:05 +0000766 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000767 break;
768 }
drhfeac5f82004-08-01 00:10:45 +0000769 case MODE_Tcl: {
770 if( p->cnt++==0 && p->showHeader ){
771 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000772 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000773 fprintf(p->out, "%s", p->separator);
774 }
775 fprintf(p->out,"\n");
776 }
777 if( azArg==0 ) break;
778 for(i=0; i<nArg; i++){
779 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
780 fprintf(p->out, "%s", p->separator);
781 }
782 fprintf(p->out,"\n");
783 break;
784 }
drh8e64d1c2004-10-07 00:32:39 +0000785 case MODE_Csv: {
786 if( p->cnt++==0 && p->showHeader ){
787 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000788 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000789 }
790 fprintf(p->out,"\n");
791 }
792 if( azArg==0 ) break;
793 for(i=0; i<nArg; i++){
794 output_csv(p, azArg[i], i<nArg-1);
795 }
796 fprintf(p->out,"\n");
797 break;
798 }
drh28bd4bc2000-06-15 15:57:22 +0000799 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000800 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000801 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000802 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000803 for(i=0; i<nArg; i++){
804 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000805 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000806 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000807 }else if( aiType && aiType[i]==SQLITE_TEXT ){
808 if( zSep[0] ) fprintf(p->out,"%s",zSep);
809 output_quoted_string(p->out, azArg[i]);
810 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
811 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000812 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
813 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
814 int nBlob = sqlite3_column_bytes(p->pStmt, i);
815 if( zSep[0] ) fprintf(p->out,"%s",zSep);
816 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000817 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000818 fprintf(p->out,"%s%s",zSep, azArg[i]);
819 }else{
820 if( zSep[0] ) fprintf(p->out,"%s",zSep);
821 output_quoted_string(p->out, azArg[i]);
822 }
823 }
824 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000825 break;
drh28bd4bc2000-06-15 15:57:22 +0000826 }
persicom1d0b8722002-04-18 02:53:04 +0000827 }
drh75897232000-05-29 14:26:00 +0000828 return 0;
829}
830
831/*
shane626a6e42009-10-22 17:30:15 +0000832** This is the callback routine that the SQLite library
833** invokes for each row of a query result.
834*/
835static int callback(void *pArg, int nArg, char **azArg, char **azCol){
836 /* since we don't have type info, call the shell_callback with a NULL value */
837 return shell_callback(pArg, nArg, azArg, azCol, NULL);
838}
839
840/*
drh33048c02001-10-01 14:29:22 +0000841** Set the destination table field of the callback_data structure to
842** the name of the table given. Escape any quote characters in the
843** table name.
844*/
845static void set_table_name(struct callback_data *p, const char *zName){
846 int i, n;
847 int needQuote;
848 char *z;
849
850 if( p->zDestTable ){
851 free(p->zDestTable);
852 p->zDestTable = 0;
853 }
854 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000855 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000856 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000857 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000858 needQuote = 1;
859 if( zName[i]=='\'' ) n++;
860 }
861 }
862 if( needQuote ) n += 2;
863 z = p->zDestTable = malloc( n+1 );
864 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000865 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000866 exit(1);
867 }
868 n = 0;
869 if( needQuote ) z[n++] = '\'';
870 for(i=0; zName[i]; i++){
871 z[n++] = zName[i];
872 if( zName[i]=='\'' ) z[n++] = '\'';
873 }
874 if( needQuote ) z[n++] = '\'';
875 z[n] = 0;
876}
877
danielk19772a02e332004-06-05 08:04:36 +0000878/* zIn is either a pointer to a NULL-terminated string in memory obtained
879** from malloc(), or a NULL pointer. The string pointed to by zAppend is
880** added to zIn, and the result returned in memory obtained from malloc().
881** zIn, if it was not NULL, is freed.
882**
883** If the third argument, quote, is not '\0', then it is used as a
884** quote character for zAppend.
885*/
drhc28490c2006-10-26 14:25:58 +0000886static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000887 int len;
888 int i;
drh4f21c4a2008-12-10 22:15:00 +0000889 int nAppend = strlen30(zAppend);
890 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000891
892 len = nAppend+nIn+1;
893 if( quote ){
894 len += 2;
895 for(i=0; i<nAppend; i++){
896 if( zAppend[i]==quote ) len++;
897 }
898 }
899
900 zIn = (char *)realloc(zIn, len);
901 if( !zIn ){
902 return 0;
903 }
904
905 if( quote ){
906 char *zCsr = &zIn[nIn];
907 *zCsr++ = quote;
908 for(i=0; i<nAppend; i++){
909 *zCsr++ = zAppend[i];
910 if( zAppend[i]==quote ) *zCsr++ = quote;
911 }
912 *zCsr++ = quote;
913 *zCsr++ = '\0';
914 assert( (zCsr-zIn)==len );
915 }else{
916 memcpy(&zIn[nIn], zAppend, nAppend);
917 zIn[len-1] = '\0';
918 }
919
920 return zIn;
921}
922
drhdd3d4592004-08-30 01:54:05 +0000923
924/*
925** Execute a query statement that has a single result column. Print
926** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000927**
928** This is used, for example, to show the schema of the database by
929** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000930*/
drh157e29a2009-05-21 15:15:00 +0000931static int run_table_dump_query(
932 FILE *out, /* Send output here */
933 sqlite3 *db, /* Database to query */
934 const char *zSelect, /* SELECT statement to extract content */
935 const char *zFirstRow /* Print before first row, if not NULL */
936){
drhdd3d4592004-08-30 01:54:05 +0000937 sqlite3_stmt *pSelect;
938 int rc;
939 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
940 if( rc!=SQLITE_OK || !pSelect ){
941 return rc;
942 }
943 rc = sqlite3_step(pSelect);
944 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000945 if( zFirstRow ){
946 fprintf(out, "%s", zFirstRow);
947 zFirstRow = 0;
948 }
drhdd3d4592004-08-30 01:54:05 +0000949 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
950 rc = sqlite3_step(pSelect);
951 }
952 return sqlite3_finalize(pSelect);
953}
954
shane626a6e42009-10-22 17:30:15 +0000955/*
956** Allocate space and save off current error string.
957*/
958static char *save_err_msg(
959 sqlite3 *db /* Database to query */
960){
961 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
962 char *zErrMsg = sqlite3_malloc(nErrMsg);
963 if( zErrMsg ){
964 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
965 }
966 return zErrMsg;
967}
968
969/*
shaneh642d8b82010-07-28 16:05:34 +0000970** Display memory stats.
971*/
972static int display_stats(
973 sqlite3 *db, /* Database to query */
974 struct callback_data *pArg, /* Pointer to struct callback_data */
975 int bReset /* True to reset the stats */
976){
977 int iCur;
978 int iHiwtr;
979
980 if( pArg && pArg->out ){
981
982 iHiwtr = iCur = -1;
983 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +0000984 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000985 iHiwtr = iCur = -1;
986 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
987 fprintf(pArg->out, "Number of Allocations: %d (max %d)\n", iCur, iHiwtr);
988/*
989** Not currently used by the CLI.
990** iHiwtr = iCur = -1;
991** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
992** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
993*/
994 iHiwtr = iCur = -1;
995 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
996 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
997/*
998** Not currently used by the CLI.
999** iHiwtr = iCur = -1;
1000** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1001** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1002*/
1003 iHiwtr = iCur = -1;
1004 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1005 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1006 iHiwtr = iCur = -1;
1007 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1008 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1009 iHiwtr = iCur = -1;
1010 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1011 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1012 iHiwtr = iCur = -1;
1013 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1014 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1015#ifdef YYTRACKMAXSTACKDEPTH
1016 iHiwtr = iCur = -1;
1017 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1018 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1019#endif
1020 }
1021
1022 if( pArg && pArg->out && db ){
1023 iHiwtr = iCur = -1;
1024 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1025 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
1026 iHiwtr = iCur = -1;
1027 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh233f8162010-07-28 17:36:11 +00001028 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001029 iHiwtr = iCur = -1;
1030 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1031 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1032 iHiwtr = iCur = -1;
1033 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1034 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1035 }
1036
1037 if( pArg && pArg->out && db && pArg->pStmt ){
1038 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1039 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1040 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1041 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1042 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1043 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1044 }
1045
1046 return 0;
1047}
1048
1049/*
shane626a6e42009-10-22 17:30:15 +00001050** Execute a statement or set of statements. Print
1051** any result rows/columns depending on the current mode
1052** set via the supplied callback.
1053**
1054** This is very similar to SQLite's built-in sqlite3_exec()
1055** function except it takes a slightly different callback
1056** and callback data argument.
1057*/
1058static int shell_exec(
1059 sqlite3 *db, /* An open database */
1060 const char *zSql, /* SQL to be evaluated */
1061 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1062 /* (not the same as sqlite3_exec) */
1063 struct callback_data *pArg, /* Pointer to struct callback_data */
1064 char **pzErrMsg /* Error msg written here */
1065){
dan4564ced2010-01-05 04:59:56 +00001066 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1067 int rc = SQLITE_OK; /* Return Code */
1068 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001069
1070 if( pzErrMsg ){
1071 *pzErrMsg = NULL;
1072 }
1073
shaneb9fc17d2009-10-22 21:23:35 +00001074 while( zSql[0] && (SQLITE_OK == rc) ){
1075 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1076 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001077 if( pzErrMsg ){
1078 *pzErrMsg = save_err_msg(db);
1079 }
1080 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001081 if( !pStmt ){
1082 /* this happens for a comment or white-space */
1083 zSql = zLeftover;
1084 while( isspace(zSql[0]) ) zSql++;
1085 continue;
1086 }
shane626a6e42009-10-22 17:30:15 +00001087
shaneh642d8b82010-07-28 16:05:34 +00001088 /* save off the prepared statment handle and reset row count */
1089 if( pArg ){
1090 pArg->pStmt = pStmt;
1091 pArg->cnt = 0;
1092 }
1093
shanehb7977c52010-01-18 18:17:10 +00001094 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001095 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001096 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001097 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001098 }
shanehb7977c52010-01-18 18:17:10 +00001099
shaneb9fc17d2009-10-22 21:23:35 +00001100 /* perform the first step. this will tell us if we
1101 ** have a result set or not and how wide it is.
1102 */
1103 rc = sqlite3_step(pStmt);
1104 /* if we have a result set... */
1105 if( SQLITE_ROW == rc ){
1106 /* if we have a callback... */
1107 if( xCallback ){
1108 /* allocate space for col name ptr, value ptr, and type */
1109 int nCol = sqlite3_column_count(pStmt);
1110 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1111 if( !pData ){
1112 rc = SQLITE_NOMEM;
1113 }else{
1114 char **azCols = (char **)pData; /* Names of result columns */
1115 char **azVals = &azCols[nCol]; /* Results */
1116 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1117 int i;
1118 assert(sizeof(int) <= sizeof(char *));
1119 /* save off ptrs to column names */
1120 for(i=0; i<nCol; i++){
1121 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1122 }
shaneb9fc17d2009-10-22 21:23:35 +00001123 do{
1124 /* extract the data and data types */
1125 for(i=0; i<nCol; i++){
1126 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1127 aiTypes[i] = sqlite3_column_type(pStmt, i);
1128 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1129 rc = SQLITE_NOMEM;
1130 break; /* from for */
1131 }
1132 } /* end for */
1133
1134 /* if data and types extracted successfully... */
1135 if( SQLITE_ROW == rc ){
1136 /* call the supplied callback with the result row data */
1137 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1138 rc = SQLITE_ABORT;
1139 }else{
1140 rc = sqlite3_step(pStmt);
1141 }
1142 }
1143 } while( SQLITE_ROW == rc );
1144 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001145 }
1146 }else{
1147 do{
1148 rc = sqlite3_step(pStmt);
1149 } while( rc == SQLITE_ROW );
1150 }
1151 }
1152
shaneh642d8b82010-07-28 16:05:34 +00001153 /* print usage stats if stats on */
1154 if( pArg && pArg->statsOn ){
1155 display_stats(db, pArg, 0);
1156 }
1157
dan4564ced2010-01-05 04:59:56 +00001158 /* Finalize the statement just executed. If this fails, save a
1159 ** copy of the error message. Otherwise, set zSql to point to the
1160 ** next statement to execute. */
1161 rc = sqlite3_finalize(pStmt);
1162 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001163 zSql = zLeftover;
1164 while( isspace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001165 }else if( pzErrMsg ){
1166 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001167 }
shaneh642d8b82010-07-28 16:05:34 +00001168
1169 /* clear saved stmt handle */
1170 if( pArg ){
1171 pArg->pStmt = NULL;
1172 }
shane626a6e42009-10-22 17:30:15 +00001173 }
shaneb9fc17d2009-10-22 21:23:35 +00001174 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001175
1176 return rc;
1177}
1178
drhdd3d4592004-08-30 01:54:05 +00001179
drh33048c02001-10-01 14:29:22 +00001180/*
drh4c653a02000-06-07 01:27:47 +00001181** This is a different callback routine used for dumping the database.
1182** Each row received by this callback consists of a table name,
1183** the table type ("index" or "table") and SQL to create the table.
1184** This routine should print text sufficient to recreate the table.
1185*/
1186static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001187 int rc;
1188 const char *zTable;
1189 const char *zType;
1190 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001191 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001192 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001193
drh902b9ee2008-12-05 17:17:07 +00001194 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001195 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001196 zTable = azArg[0];
1197 zType = azArg[1];
1198 zSql = azArg[2];
1199
drh00b950d2005-09-11 02:03:03 +00001200 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001201 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001202 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1203 fprintf(p->out, "ANALYZE sqlite_master;\n");
1204 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1205 return 0;
drh45e29d82006-11-20 16:21:10 +00001206 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1207 char *zIns;
1208 if( !p->writableSchema ){
1209 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1210 p->writableSchema = 1;
1211 }
1212 zIns = sqlite3_mprintf(
1213 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1214 "VALUES('table','%q','%q',0,'%q');",
1215 zTable, zTable, zSql);
1216 fprintf(p->out, "%s\n", zIns);
1217 sqlite3_free(zIns);
1218 return 0;
drh00b950d2005-09-11 02:03:03 +00001219 }else{
1220 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001221 }
danielk19772a02e332004-06-05 08:04:36 +00001222
1223 if( strcmp(zType, "table")==0 ){
1224 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001225 char *zSelect = 0;
1226 char *zTableInfo = 0;
1227 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001228 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001229
1230 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1231 zTableInfo = appendText(zTableInfo, zTable, '"');
1232 zTableInfo = appendText(zTableInfo, ");", 0);
1233
1234 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001235 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001236 if( rc!=SQLITE_OK || !pTableInfo ){
1237 return 1;
1238 }
1239
1240 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1241 zTmp = appendText(zTmp, zTable, '"');
1242 if( zTmp ){
1243 zSelect = appendText(zSelect, zTmp, '\'');
1244 }
1245 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1246 rc = sqlite3_step(pTableInfo);
1247 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001248 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001249 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001250 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001251 rc = sqlite3_step(pTableInfo);
1252 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001253 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001254 }else{
1255 zSelect = appendText(zSelect, ") ", 0);
1256 }
drh157e29a2009-05-21 15:15:00 +00001257 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001258 }
1259 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001260 if( rc!=SQLITE_OK || nRow==0 ){
1261 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001262 return 1;
1263 }
1264 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1265 zSelect = appendText(zSelect, zTable, '"');
1266
drh157e29a2009-05-21 15:15:00 +00001267 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001268 if( rc==SQLITE_CORRUPT ){
1269 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001270 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001271 }
danielk19772a02e332004-06-05 08:04:36 +00001272 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001273 }
drh4c653a02000-06-07 01:27:47 +00001274 return 0;
1275}
1276
1277/*
drh45e29d82006-11-20 16:21:10 +00001278** Run zQuery. Use dump_callback() as the callback routine so that
1279** the contents of the query are output as SQL statements.
1280**
drhdd3d4592004-08-30 01:54:05 +00001281** If we get a SQLITE_CORRUPT error, rerun the query after appending
1282** "ORDER BY rowid DESC" to the end.
1283*/
1284static int run_schema_dump_query(
1285 struct callback_data *p,
1286 const char *zQuery,
1287 char **pzErrMsg
1288){
1289 int rc;
1290 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1291 if( rc==SQLITE_CORRUPT ){
1292 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001293 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001294 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1295 zQ2 = malloc( len+100 );
1296 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001297 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001298 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1299 free(zQ2);
1300 }
1301 return rc;
1302}
1303
1304/*
drh75897232000-05-29 14:26:00 +00001305** Text of a help message
1306*/
persicom1d0b8722002-04-18 02:53:04 +00001307static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001308 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001309 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001310 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001311 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001312 " If TABLE specified, only dump tables matching\n"
1313 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001314 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001315 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001316 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1317 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001318 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001319 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001320 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001321 ".indices ?TABLE? Show names of all indices\n"
1322 " If TABLE specified, only show indices for tables\n"
1323 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001324#ifdef SQLITE_ENABLE_IOTRACE
1325 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1326#endif
drh70df4fe2006-06-13 15:12:21 +00001327#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001328 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001329#endif
drh127f9d72010-02-23 01:47:00 +00001330 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001331 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001332 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001333 " column Left-aligned columns. (See .width)\n"
1334 " html HTML <table> code\n"
1335 " insert SQL insert statements for TABLE\n"
1336 " line One value per line\n"
1337 " list Values delimited by .separator string\n"
1338 " tabs Tab-separated values\n"
1339 " tcl TCL list elements\n"
1340 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001341 ".output FILENAME Send output to FILENAME\n"
1342 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001343 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001344 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001345 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001346 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001347 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001348 " If TABLE specified, only show tables matching\n"
1349 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001350 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001351 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001352 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001353 ".tables ?TABLE? List names of tables\n"
1354 " If TABLE specified, only list tables matching\n"
1355 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001356 ".timeout MS Try opening locked tables for MS milliseconds\n"
shanehe2aa9d72009-11-06 17:20:17 +00001357 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001358;
1359
shaneb320ccd2009-10-21 03:42:58 +00001360static char zTimerHelp[] =
1361 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1362;
1363
drhdaffd0e2001-04-11 14:28:42 +00001364/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001365static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001366
drh75897232000-05-29 14:26:00 +00001367/*
drh44c2eb12003-04-30 11:38:26 +00001368** Make sure the database is open. If it is not, then open it. If
1369** the database fails to open, print an error message and exit.
1370*/
1371static void open_db(struct callback_data *p){
1372 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001373 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001374 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001375 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1376 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1377 shellstaticFunc, 0, 0);
1378 }
1379 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001380 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001381 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001382 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001383 }
drhc2e87a32006-06-27 15:16:14 +00001384#ifndef SQLITE_OMIT_LOAD_EXTENSION
1385 sqlite3_enable_load_extension(p->db, 1);
1386#endif
drh44c2eb12003-04-30 11:38:26 +00001387 }
1388}
1389
1390/*
drhfeac5f82004-08-01 00:10:45 +00001391** Do C-language style dequoting.
1392**
1393** \t -> tab
1394** \n -> newline
1395** \r -> carriage return
1396** \NNN -> ascii character NNN in octal
1397** \\ -> backslash
1398*/
1399static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001400 int i, j;
1401 char c;
drhfeac5f82004-08-01 00:10:45 +00001402 for(i=j=0; (c = z[i])!=0; i++, j++){
1403 if( c=='\\' ){
1404 c = z[++i];
1405 if( c=='n' ){
1406 c = '\n';
1407 }else if( c=='t' ){
1408 c = '\t';
1409 }else if( c=='r' ){
1410 c = '\r';
1411 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001412 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001413 if( z[i+1]>='0' && z[i+1]<='7' ){
1414 i++;
1415 c = (c<<3) + z[i] - '0';
1416 if( z[i+1]>='0' && z[i+1]<='7' ){
1417 i++;
1418 c = (c<<3) + z[i] - '0';
1419 }
1420 }
1421 }
1422 }
1423 z[j] = c;
1424 }
1425 z[j] = 0;
1426}
1427
1428/*
drhc28490c2006-10-26 14:25:58 +00001429** Interpret zArg as a boolean value. Return either 0 or 1.
1430*/
1431static int booleanValue(char *zArg){
1432 int val = atoi(zArg);
1433 int j;
1434 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001435 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001436 }
1437 if( strcmp(zArg,"on")==0 ){
1438 val = 1;
1439 }else if( strcmp(zArg,"yes")==0 ){
1440 val = 1;
1441 }
1442 return val;
1443}
1444
1445/*
drh75897232000-05-29 14:26:00 +00001446** If an input line begins with "." then invoke this routine to
1447** process that line.
drh67505e72002-04-19 12:34:06 +00001448**
drh47ad6842006-11-08 12:25:42 +00001449** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001450*/
drh44c2eb12003-04-30 11:38:26 +00001451static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001452 int i = 1;
1453 int nArg = 0;
1454 int n, c;
drh67505e72002-04-19 12:34:06 +00001455 int rc = 0;
drh75897232000-05-29 14:26:00 +00001456 char *azArg[50];
1457
1458 /* Parse the input line into tokens.
1459 */
1460 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001461 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001462 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001463 if( zLine[i]=='\'' || zLine[i]=='"' ){
1464 int delim = zLine[i++];
1465 azArg[nArg++] = &zLine[i];
1466 while( zLine[i] && zLine[i]!=delim ){ i++; }
1467 if( zLine[i]==delim ){
1468 zLine[i++] = 0;
1469 }
drhfeac5f82004-08-01 00:10:45 +00001470 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001471 }else{
1472 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001473 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001474 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001475 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001476 }
1477 }
1478
1479 /* Process the input line.
1480 */
shane9bd1b442009-10-23 01:27:39 +00001481 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001482 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001483 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001484 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001485 const char *zDestFile;
1486 const char *zDb;
1487 sqlite3 *pDest;
1488 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001489 if( nArg==2 ){
1490 zDestFile = azArg[1];
1491 zDb = "main";
1492 }else{
1493 zDestFile = azArg[2];
1494 zDb = azArg[1];
1495 }
1496 rc = sqlite3_open(zDestFile, &pDest);
1497 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001498 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001499 sqlite3_close(pDest);
1500 return 1;
1501 }
drhdc2c4912009-02-04 22:46:47 +00001502 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001503 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1504 if( pBackup==0 ){
1505 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1506 sqlite3_close(pDest);
1507 return 1;
1508 }
1509 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1510 sqlite3_backup_finish(pBackup);
1511 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001512 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001513 }else{
1514 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001515 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001516 }
1517 sqlite3_close(pDest);
1518 }else
1519
shanehe2aa9d72009-11-06 17:20:17 +00001520 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001521 bail_on_error = booleanValue(azArg[1]);
1522 }else
1523
shanehe2aa9d72009-11-06 17:20:17 +00001524 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001525 struct callback_data data;
1526 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001527 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001528 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001529 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001530 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001531 data.colWidth[0] = 3;
1532 data.colWidth[1] = 15;
1533 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001534 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001535 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001536 if( zErrMsg ){
1537 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001538 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001539 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001540 }
1541 }else
1542
shanehe2aa9d72009-11-06 17:20:17 +00001543 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh4c653a02000-06-07 01:27:47 +00001544 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001545 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001546 /* When playing back a "dump", the content might appear in an order
1547 ** which causes immediate foreign key constraints to be violated.
1548 ** So disable foreign-key constraint enforcement to prevent problems. */
1549 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001550 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001551 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001552 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001553 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001554 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001555 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00001556 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1557 );
1558 run_schema_dump_query(p,
1559 "SELECT name, type, sql FROM sqlite_master "
1560 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00001561 );
1562 run_table_dump_query(p->out, p->db,
1563 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001564 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001565 );
drh4c653a02000-06-07 01:27:47 +00001566 }else{
1567 int i;
drhdd3d4592004-08-30 01:54:05 +00001568 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001569 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001570 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001571 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001572 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001573 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001574 run_table_dump_query(p->out, p->db,
1575 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001576 "WHERE sql NOT NULL"
1577 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001578 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001579 );
danielk1977bc6ada42004-06-30 08:20:16 +00001580 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001581 }
1582 }
drh45e29d82006-11-20 16:21:10 +00001583 if( p->writableSchema ){
1584 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1585 p->writableSchema = 0;
1586 }
drh93f41e52008-08-11 19:12:34 +00001587 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001588 if( zErrMsg ){
1589 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001590 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001591 }else{
1592 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001593 }
1594 }else
drh75897232000-05-29 14:26:00 +00001595
shanehe2aa9d72009-11-06 17:20:17 +00001596 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001597 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001598 }else
1599
shanehe2aa9d72009-11-06 17:20:17 +00001600 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001601 rc = 2;
drh75897232000-05-29 14:26:00 +00001602 }else
1603
shanehe2aa9d72009-11-06 17:20:17 +00001604 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001605 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001606 if(val == 1) {
1607 if(!p->explainPrev.valid) {
1608 p->explainPrev.valid = 1;
1609 p->explainPrev.mode = p->mode;
1610 p->explainPrev.showHeader = p->showHeader;
1611 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1612 }
1613 /* We could put this code under the !p->explainValid
1614 ** condition so that it does not execute if we are already in
1615 ** explain mode. However, always executing it allows us an easy
1616 ** was to reset to explain mode in case the user previously
1617 ** did an .explain followed by a .width, .mode or .header
1618 ** command.
1619 */
danielk19770d78bae2008-01-03 07:09:48 +00001620 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001621 p->showHeader = 1;
1622 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001623 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001624 p->colWidth[1] = 13; /* opcode */
1625 p->colWidth[2] = 4; /* P1 */
1626 p->colWidth[3] = 4; /* P2 */
1627 p->colWidth[4] = 4; /* P3 */
1628 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001629 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001630 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001631 }else if (p->explainPrev.valid) {
1632 p->explainPrev.valid = 0;
1633 p->mode = p->explainPrev.mode;
1634 p->showHeader = p->explainPrev.showHeader;
1635 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1636 }
drh75897232000-05-29 14:26:00 +00001637 }else
1638
drhc28490c2006-10-26 14:25:58 +00001639 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001640 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001641 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001642 }else
1643
1644 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001645 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001646 if( HAS_TIMER ){
1647 fprintf(stderr,"%s",zTimerHelp);
1648 }
drh75897232000-05-29 14:26:00 +00001649 }else
1650
shanehe2aa9d72009-11-06 17:20:17 +00001651 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001652 char *zTable = azArg[2]; /* Insert data into this table */
1653 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001654 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001655 int nCol; /* Number of columns in the table */
1656 int nByte; /* Number of bytes in an SQL string */
1657 int i, j; /* Loop counters */
1658 int nSep; /* Number of bytes in p->separator[] */
1659 char *zSql; /* An SQL statement */
1660 char *zLine; /* A single line of input from the file */
1661 char **azCol; /* zLine[] broken up into columns */
1662 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001663 FILE *in; /* The input file */
1664 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001665
drha543c822006-06-08 16:10:14 +00001666 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001667 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001668 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001669 fprintf(stderr, "Error: non-null separator required for import\n");
1670 return 1;
drhfeac5f82004-08-01 00:10:45 +00001671 }
1672 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
shane916f9612009-10-23 00:37:15 +00001673 if( zSql==0 ){
1674 fprintf(stderr, "Error: out of memory\n");
1675 return 1;
1676 }
drh4f21c4a2008-12-10 22:15:00 +00001677 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001678 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001679 sqlite3_free(zSql);
1680 if( rc ){
shane916f9612009-10-23 00:37:15 +00001681 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001682 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001683 return 1;
drhfeac5f82004-08-01 00:10:45 +00001684 }
shane916f9612009-10-23 00:37:15 +00001685 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001686 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001687 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001688 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001689 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001690 if( zSql==0 ){
1691 fprintf(stderr, "Error: out of memory\n");
1692 return 1;
1693 }
drhfeac5f82004-08-01 00:10:45 +00001694 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001695 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001696 for(i=1; i<nCol; i++){
1697 zSql[j++] = ',';
1698 zSql[j++] = '?';
1699 }
1700 zSql[j++] = ')';
1701 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001702 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001703 free(zSql);
1704 if( rc ){
1705 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001706 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001707 return 1;
drhfeac5f82004-08-01 00:10:45 +00001708 }
1709 in = fopen(zFile, "rb");
1710 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001711 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001712 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001713 return 1;
drhfeac5f82004-08-01 00:10:45 +00001714 }
1715 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001716 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001717 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001718 fclose(in);
shane916f9612009-10-23 00:37:15 +00001719 sqlite3_finalize(pStmt);
1720 return 1;
drh43617e92006-03-06 20:55:46 +00001721 }
drhfeac5f82004-08-01 00:10:45 +00001722 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1723 zCommit = "COMMIT";
1724 while( (zLine = local_getline(0, in))!=0 ){
1725 char *z;
1726 i = 0;
drhb860bc92004-08-04 15:16:55 +00001727 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001728 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001729 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001730 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1731 *z = 0;
1732 i++;
drhb860bc92004-08-04 15:16:55 +00001733 if( i<nCol ){
1734 azCol[i] = &z[nSep];
1735 z += nSep-1;
1736 }
drhfeac5f82004-08-01 00:10:45 +00001737 }
shane916f9612009-10-23 00:37:15 +00001738 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001739 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001740 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001741 fprintf(stderr,
1742 "Error: %s line %d: expected %d columns of data but found %d\n",
1743 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001744 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001745 free(zLine);
shane916f9612009-10-23 00:37:15 +00001746 rc = 1;
1747 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001748 }
drhfeac5f82004-08-01 00:10:45 +00001749 for(i=0; i<nCol; i++){
1750 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1751 }
1752 sqlite3_step(pStmt);
1753 rc = sqlite3_reset(pStmt);
1754 free(zLine);
1755 if( rc!=SQLITE_OK ){
1756 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1757 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001758 rc = 1;
shane916f9612009-10-23 00:37:15 +00001759 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001760 }
shane916f9612009-10-23 00:37:15 +00001761 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001762 free(azCol);
1763 fclose(in);
1764 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001765 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001766 }else
1767
shanehe2aa9d72009-11-06 17:20:17 +00001768 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001769 struct callback_data data;
1770 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001771 open_db(p);
drh75897232000-05-29 14:26:00 +00001772 memcpy(&data, p, sizeof(data));
1773 data.showHeader = 0;
1774 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001775 if( nArg==1 ){
1776 rc = sqlite3_exec(p->db,
1777 "SELECT name FROM sqlite_master "
1778 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1779 "UNION ALL "
1780 "SELECT name FROM sqlite_temp_master "
1781 "WHERE type='index' "
1782 "ORDER BY 1",
1783 callback, &data, &zErrMsg
1784 );
1785 }else{
1786 zShellStatic = azArg[1];
1787 rc = sqlite3_exec(p->db,
1788 "SELECT name FROM sqlite_master "
1789 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1790 "UNION ALL "
1791 "SELECT name FROM sqlite_temp_master "
1792 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1793 "ORDER BY 1",
1794 callback, &data, &zErrMsg
1795 );
1796 zShellStatic = 0;
1797 }
drh75897232000-05-29 14:26:00 +00001798 if( zErrMsg ){
1799 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001800 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001801 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001802 }else if( rc != SQLITE_OK ){
1803 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1804 rc = 1;
drh75897232000-05-29 14:26:00 +00001805 }
1806 }else
1807
drhae5e4452007-05-03 17:18:36 +00001808#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001809 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001810 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001811 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1812 iotrace = 0;
1813 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001814 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001815 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001816 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001817 iotrace = stdout;
1818 }else{
1819 iotrace = fopen(azArg[1], "w");
1820 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001821 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001822 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001823 rc = 1;
drhb0603412007-02-28 04:47:26 +00001824 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001825 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001826 }
1827 }
1828 }else
drhae5e4452007-05-03 17:18:36 +00001829#endif
drhb0603412007-02-28 04:47:26 +00001830
drh70df4fe2006-06-13 15:12:21 +00001831#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001832 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1833 const char *zFile, *zProc;
1834 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001835 zFile = azArg[1];
1836 zProc = nArg>=3 ? azArg[2] : 0;
1837 open_db(p);
1838 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1839 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001840 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001841 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001842 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001843 }
1844 }else
drh70df4fe2006-06-13 15:12:21 +00001845#endif
drh1e397f82006-06-08 15:28:43 +00001846
drh127f9d72010-02-23 01:47:00 +00001847 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=1 ){
1848 const char *zFile = azArg[1];
1849 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1850 fclose(p->pLog);
1851 p->pLog = 0;
1852 }
1853 if( strcmp(zFile,"stdout")==0 ){
1854 p->pLog = stdout;
1855 }else if( strcmp(zFile, "stderr")==0 ){
1856 p->pLog = stderr;
1857 }else if( strcmp(zFile, "off")==0 ){
1858 p->pLog = 0;
1859 }else{
1860 p->pLog = fopen(zFile, "w");
1861 if( p->pLog==0 ){
1862 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1863 }
1864 }
1865 }else
1866
shanehe2aa9d72009-11-06 17:20:17 +00001867 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001868 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001869 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001870 ||
shanehe2aa9d72009-11-06 17:20:17 +00001871 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001872 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001873 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001874 ||
shanehe2aa9d72009-11-06 17:20:17 +00001875 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001876 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001877 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001878 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001879 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001880 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001881 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001882 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001883 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001884 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001885 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001886 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001887 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001888 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001889 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001890 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001891 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001892 }else {
shane9bd1b442009-10-23 01:27:39 +00001893 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001894 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001895 rc = 1;
drh75897232000-05-29 14:26:00 +00001896 }
1897 }else
1898
shanehe2aa9d72009-11-06 17:20:17 +00001899 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1900 int n2 = strlen30(azArg[1]);
1901 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1902 p->mode = MODE_Insert;
1903 set_table_name(p, azArg[2]);
1904 }else {
1905 fprintf(stderr, "Error: invalid arguments: "
1906 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1907 rc = 1;
1908 }
1909 }else
1910
persicom7e2dfdd2002-04-18 02:46:52 +00001911 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001912 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1913 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001914 }else
1915
drh75897232000-05-29 14:26:00 +00001916 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1917 if( p->out!=stdout ){
1918 fclose(p->out);
1919 }
1920 if( strcmp(azArg[1],"stdout")==0 ){
1921 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001922 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001923 }else{
drha1f9b5e2004-02-14 16:31:02 +00001924 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001925 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00001926 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00001927 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00001928 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001929 } else {
drh5bb3eb92007-05-04 13:15:55 +00001930 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001931 }
1932 }
1933 }else
1934
drhdd45df82002-04-18 12:39:03 +00001935 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001936 if( nArg >= 2) {
1937 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1938 }
1939 if( nArg >= 3) {
1940 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1941 }
1942 }else
1943
shanehe2aa9d72009-11-06 17:20:17 +00001944 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001945 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001946 }else
1947
drh9ff849f2009-02-04 20:55:57 +00001948 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001949 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001950 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00001951 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1952 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00001953 }else{
shane9bd1b442009-10-23 01:27:39 +00001954 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00001955 fclose(alt);
1956 }
1957 }else
1958
shanehe2aa9d72009-11-06 17:20:17 +00001959 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001960 const char *zSrcFile;
1961 const char *zDb;
1962 sqlite3 *pSrc;
1963 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00001964 int nTimeout = 0;
1965
drh9ff849f2009-02-04 20:55:57 +00001966 if( nArg==2 ){
1967 zSrcFile = azArg[1];
1968 zDb = "main";
1969 }else{
1970 zSrcFile = azArg[2];
1971 zDb = azArg[1];
1972 }
1973 rc = sqlite3_open(zSrcFile, &pSrc);
1974 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001975 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00001976 sqlite3_close(pSrc);
1977 return 1;
1978 }
drhdc2c4912009-02-04 22:46:47 +00001979 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001980 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
1981 if( pBackup==0 ){
1982 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1983 sqlite3_close(pSrc);
1984 return 1;
1985 }
drhdc2c4912009-02-04 22:46:47 +00001986 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
1987 || rc==SQLITE_BUSY ){
1988 if( rc==SQLITE_BUSY ){
1989 if( nTimeout++ >= 3 ) break;
1990 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00001991 }
1992 }
1993 sqlite3_backup_finish(pBackup);
1994 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001995 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00001996 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00001997 fprintf(stderr, "Error: source database is busy\n");
1998 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001999 }else{
2000 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002001 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002002 }
2003 sqlite3_close(pSrc);
2004 }else
2005
shanehe2aa9d72009-11-06 17:20:17 +00002006 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002007 struct callback_data data;
2008 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002009 open_db(p);
drh75897232000-05-29 14:26:00 +00002010 memcpy(&data, p, sizeof(data));
2011 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002012 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002013 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002014 int i;
shane7d3846a2008-12-11 02:58:26 +00002015 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002016 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002017 char *new_argv[2], *new_colv[2];
2018 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2019 " type text,\n"
2020 " name text,\n"
2021 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002022 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002023 " sql text\n"
2024 ")";
2025 new_argv[1] = 0;
2026 new_colv[0] = "sql";
2027 new_colv[1] = 0;
2028 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002029 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002030 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002031 char *new_argv[2], *new_colv[2];
2032 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2033 " type text,\n"
2034 " name text,\n"
2035 " tbl_name text,\n"
2036 " rootpage integer,\n"
2037 " sql text\n"
2038 ")";
2039 new_argv[1] = 0;
2040 new_colv[0] = "sql";
2041 new_colv[1] = 0;
2042 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002043 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002044 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002045 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002046 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002047 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002048 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2049 " FROM sqlite_master UNION ALL"
2050 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002051 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002052 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002053 callback, &data, &zErrMsg);
2054 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002055 }
drh75897232000-05-29 14:26:00 +00002056 }else{
shane9bd1b442009-10-23 01:27:39 +00002057 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002058 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002059 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2060 " FROM sqlite_master UNION ALL"
2061 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002062 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002063 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002064 callback, &data, &zErrMsg
2065 );
drh75897232000-05-29 14:26:00 +00002066 }
drh75897232000-05-29 14:26:00 +00002067 if( zErrMsg ){
2068 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002069 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002070 rc = 1;
2071 }else if( rc != SQLITE_OK ){
2072 fprintf(stderr,"Error: querying schema information\n");
2073 rc = 1;
2074 }else{
2075 rc = 0;
drh75897232000-05-29 14:26:00 +00002076 }
2077 }else
2078
2079 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002080 sqlite3_snprintf(sizeof(p->separator), p->separator,
2081 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002082 }else
2083
shanehe2aa9d72009-11-06 17:20:17 +00002084 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002085 int i;
2086 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002087 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002088 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002089 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002090 fprintf(p->out,"%9.9s: ", "nullvalue");
2091 output_c_string(p->out, p->nullvalue);
2092 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002093 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002094 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002095 fprintf(p->out,"%9.9s: ", "separator");
2096 output_c_string(p->out, p->separator);
2097 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002098 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002099 fprintf(p->out,"%9.9s: ","width");
2100 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002101 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002102 }
drhfeac5f82004-08-01 00:10:45 +00002103 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002104 }else
2105
shaneh642d8b82010-07-28 16:05:34 +00002106 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2107 p->statsOn = booleanValue(azArg[1]);
2108 }else
2109
shanehe2aa9d72009-11-06 17:20:17 +00002110 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002111 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002112 int nRow;
drhe3710332000-09-29 13:30:53 +00002113 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002114 open_db(p);
drha50da102000-08-08 20:19:09 +00002115 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002116 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002117 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002118 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002119 "UNION ALL "
2120 "SELECT name FROM sqlite_temp_master "
2121 "WHERE type IN ('table','view') "
2122 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002123 &azResult, &nRow, 0, &zErrMsg
2124 );
drha50da102000-08-08 20:19:09 +00002125 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002126 zShellStatic = azArg[1];
2127 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002128 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002129 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002130 "UNION ALL "
2131 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002132 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002133 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002134 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002135 );
danielk1977bc6ada42004-06-30 08:20:16 +00002136 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002137 }
drh75897232000-05-29 14:26:00 +00002138 if( zErrMsg ){
2139 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002140 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002141 rc = 1;
2142 }else if( rc != SQLITE_OK ){
2143 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2144 rc = 1;
2145 }else{
drhe3710332000-09-29 13:30:53 +00002146 int len, maxlen = 0;
2147 int i, j;
2148 int nPrintCol, nPrintRow;
2149 for(i=1; i<=nRow; i++){
2150 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002151 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002152 if( len>maxlen ) maxlen = len;
2153 }
2154 nPrintCol = 80/(maxlen+2);
2155 if( nPrintCol<1 ) nPrintCol = 1;
2156 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2157 for(i=0; i<nPrintRow; i++){
2158 for(j=i+1; j<=nRow; j+=nPrintRow){
2159 char *zSp = j<=nPrintRow ? "" : " ";
2160 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2161 }
2162 printf("\n");
2163 }
2164 }
danielk19776f8a5032004-05-10 10:34:51 +00002165 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002166 }else
2167
shanehe2aa9d72009-11-06 17:20:17 +00002168 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002169 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002170 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002171 }else
2172
2173 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
drh3b1a9882007-11-02 12:53:03 +00002174 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002175 }else
2176
2177 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002178 int j;
drh43617e92006-03-06 20:55:46 +00002179 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002180 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2181 p->colWidth[j-1] = atoi(azArg[j]);
2182 }
2183 }else
2184
2185 {
shane9bd1b442009-10-23 01:27:39 +00002186 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002187 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002188 rc = 1;
drh75897232000-05-29 14:26:00 +00002189 }
drh67505e72002-04-19 12:34:06 +00002190
2191 return rc;
drh75897232000-05-29 14:26:00 +00002192}
2193
drh67505e72002-04-19 12:34:06 +00002194/*
drh91a66392007-09-07 01:12:32 +00002195** Return TRUE if a semicolon occurs anywhere in the first N characters
2196** of string z[].
drh324ccef2003-02-05 14:06:20 +00002197*/
drh91a66392007-09-07 01:12:32 +00002198static int _contains_semicolon(const char *z, int N){
2199 int i;
2200 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2201 return 0;
drh324ccef2003-02-05 14:06:20 +00002202}
2203
2204/*
drh70c7a4b2003-04-26 03:03:06 +00002205** Test to see if a line consists entirely of whitespace.
2206*/
2207static int _all_whitespace(const char *z){
2208 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002209 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002210 if( *z=='/' && z[1]=='*' ){
2211 z += 2;
2212 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2213 if( *z==0 ) return 0;
2214 z++;
2215 continue;
2216 }
2217 if( *z=='-' && z[1]=='-' ){
2218 z += 2;
2219 while( *z && *z!='\n' ){ z++; }
2220 if( *z==0 ) return 1;
2221 continue;
2222 }
2223 return 0;
2224 }
2225 return 1;
2226}
2227
2228/*
drha9b17162003-04-29 18:01:28 +00002229** Return TRUE if the line typed in is an SQL command terminator other
2230** than a semi-colon. The SQL Server style "go" command is understood
2231** as is the Oracle "/".
2232*/
2233static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002234 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002235 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2236 return 1; /* Oracle */
2237 }
drhc8d74412004-08-31 23:41:26 +00002238 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2239 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002240 return 1; /* SQL Server */
2241 }
2242 return 0;
2243}
2244
2245/*
drh233a5312008-12-18 22:25:13 +00002246** Return true if zSql is a complete SQL statement. Return false if it
2247** ends in the middle of a string literal or C-style comment.
2248*/
2249static int _is_complete(char *zSql, int nSql){
2250 int rc;
2251 if( zSql==0 ) return 1;
2252 zSql[nSql] = ';';
2253 zSql[nSql+1] = 0;
2254 rc = sqlite3_complete(zSql);
2255 zSql[nSql] = 0;
2256 return rc;
2257}
2258
2259/*
drh67505e72002-04-19 12:34:06 +00002260** Read input from *in and process it. If *in==0 then input
2261** is interactive - the user is typing it it. Otherwise, input
2262** is coming from a file or device. A prompt is issued and history
2263** is saved only if input is interactive. An interrupt signal will
2264** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002265**
2266** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002267*/
drhc28490c2006-10-26 14:25:58 +00002268static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002269 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002270 char *zSql = 0;
2271 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002272 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002273 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002274 int rc;
2275 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002276 int lineno = 0;
2277 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002278
2279 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2280 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002281 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002282 zLine = one_input_line(zSql, in);
2283 if( zLine==0 ){
2284 break; /* We have reached EOF */
2285 }
drh67505e72002-04-19 12:34:06 +00002286 if( seenInterrupt ){
2287 if( in!=0 ) break;
2288 seenInterrupt = 0;
2289 }
drhc28490c2006-10-26 14:25:58 +00002290 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002291 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002292 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002293 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002294 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002295 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002296 break;
2297 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002298 errCnt++;
2299 }
drhdaffd0e2001-04-11 14:28:42 +00002300 continue;
2301 }
drh233a5312008-12-18 22:25:13 +00002302 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002303 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002304 }
drh91a66392007-09-07 01:12:32 +00002305 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002306 if( zSql==0 ){
2307 int i;
drh4c755c02004-08-08 20:22:17 +00002308 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002309 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002310 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002311 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002312 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002313 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002314 exit(1);
2315 }
drh5bb3eb92007-05-04 13:15:55 +00002316 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002317 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002318 }
2319 }else{
drh4f21c4a2008-12-10 22:15:00 +00002320 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002321 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002322 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002323 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002324 exit(1);
2325 }
drh5bb3eb92007-05-04 13:15:55 +00002326 zSql[nSql++] = '\n';
2327 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002328 nSql += len;
2329 }
drh91a66392007-09-07 01:12:32 +00002330 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2331 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002332 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002333 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002334 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002335 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002336 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002337 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002338 char zPrefix[100];
2339 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002340 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002341 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002342 }else{
shane9bd1b442009-10-23 01:27:39 +00002343 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002344 }
drh7f953e22002-07-13 17:33:45 +00002345 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002346 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002347 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002348 zErrMsg = 0;
2349 }else{
shaned2bed1c2009-10-21 03:56:54 +00002350 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002351 }
drhc49f44e2006-10-26 18:15:42 +00002352 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002353 }
2354 free(zSql);
2355 zSql = 0;
2356 nSql = 0;
2357 }
2358 }
2359 if( zSql ){
shane86f5bdb2009-10-24 02:00:07 +00002360 if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002361 free(zSql);
2362 }
danielk19772ac27622007-07-03 05:31:16 +00002363 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002364 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002365}
2366
drh67505e72002-04-19 12:34:06 +00002367/*
2368** Return a pathname which is the user's home directory. A
2369** 0 return indicates an error of some kind. Space to hold the
2370** resulting string is obtained from malloc(). The calling
2371** function should free the result.
2372*/
2373static char *find_home_dir(void){
2374 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002375
chw97185482008-11-17 08:05:31 +00002376#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002377 struct passwd *pwent;
2378 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002379 if( (pwent=getpwuid(uid)) != NULL) {
2380 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002381 }
2382#endif
2383
chw65d3c132007-11-12 21:09:10 +00002384#if defined(_WIN32_WCE)
2385 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2386 */
2387 home_dir = strdup("/");
2388#else
2389
drh164a1b62006-08-19 11:15:20 +00002390#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2391 if (!home_dir) {
2392 home_dir = getenv("USERPROFILE");
2393 }
2394#endif
2395
drh67505e72002-04-19 12:34:06 +00002396 if (!home_dir) {
2397 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002398 }
2399
drhcdb36b72006-06-12 12:57:45 +00002400#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002401 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002402 char *zDrive, *zPath;
2403 int n;
2404 zDrive = getenv("HOMEDRIVE");
2405 zPath = getenv("HOMEPATH");
2406 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002407 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002408 home_dir = malloc( n );
2409 if( home_dir==0 ) return 0;
2410 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2411 return home_dir;
2412 }
2413 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002414 }
2415#endif
2416
chw65d3c132007-11-12 21:09:10 +00002417#endif /* !_WIN32_WCE */
2418
drh67505e72002-04-19 12:34:06 +00002419 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002420 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002421 char *z = malloc( n );
2422 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002423 home_dir = z;
2424 }
drhe98d4fa2002-04-21 19:06:22 +00002425
drh67505e72002-04-19 12:34:06 +00002426 return home_dir;
2427}
2428
2429/*
2430** Read input from the file given by sqliterc_override. Or if that
2431** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002432**
2433** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002434*/
shane9bd1b442009-10-23 01:27:39 +00002435static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002436 struct callback_data *p, /* Configuration data */
2437 const char *sqliterc_override /* Name of config file. NULL to use default */
2438){
persicom7e2dfdd2002-04-18 02:46:52 +00002439 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002440 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002441 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002442 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002443 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002444 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002445
2446 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002447 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002448 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002449#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002450 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002451#endif
shane9bd1b442009-10-23 01:27:39 +00002452 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002453 }
drh4f21c4a2008-12-10 22:15:00 +00002454 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002455 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002456 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002457 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2458 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002459 }
drha959ac42007-06-20 13:10:00 +00002460 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002461 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002462 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002463 }
drha1f9b5e2004-02-14 16:31:02 +00002464 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002465 if( in ){
drhc28490c2006-10-26 14:25:58 +00002466 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002467 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002468 }
shane9bd1b442009-10-23 01:27:39 +00002469 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002470 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002471 }
drh43617e92006-03-06 20:55:46 +00002472 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002473 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002474}
2475
drh67505e72002-04-19 12:34:06 +00002476/*
drhe1e38c42003-05-04 18:30:59 +00002477** Show available command line options
2478*/
2479static const char zOptions[] =
shaneh5fc25012009-11-11 04:17:07 +00002480 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002481 " -init filename read/process named file\n"
2482 " -echo print commands before execution\n"
2483 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002484 " -bail stop after hitting an error\n"
2485 " -interactive force interactive I/O\n"
2486 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002487 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002488 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002489 " -html set output mode to HTML\n"
2490 " -line set output mode to 'line'\n"
2491 " -list set output mode to 'list'\n"
2492 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002493 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002494 " -nullvalue 'text' set text string for NULL values\n"
2495 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002496;
2497static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002498 fprintf(stderr,
2499 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2500 "FILENAME is the name of an SQLite database. A new database is created\n"
2501 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002502 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002503 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002504 }else{
2505 fprintf(stderr, "Use the -help option for additional information\n");
2506 }
2507 exit(1);
2508}
2509
2510/*
drh67505e72002-04-19 12:34:06 +00002511** Initialize the state information in data
2512*/
drh0850b532006-01-31 19:31:43 +00002513static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002514 memset(data, 0, sizeof(*data));
2515 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002516 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002517 data->showHeader = 0;
drh127f9d72010-02-23 01:47:00 +00002518 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002519 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2520 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002521 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002522}
2523
drh75897232000-05-29 14:26:00 +00002524int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002525 char *zErrMsg = 0;
2526 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002527 const char *zInitFile = 0;
2528 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002529 int i;
drhc28490c2006-10-26 14:25:58 +00002530 int rc = 0;
drh75897232000-05-29 14:26:00 +00002531
drhdaffd0e2001-04-11 14:28:42 +00002532 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002533 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002534 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002535
drh44c2eb12003-04-30 11:38:26 +00002536 /* Make sure we have a valid signal handler early, before anything
2537 ** else is done.
2538 */
drh4c504392000-10-16 22:06:40 +00002539#ifdef SIGINT
2540 signal(SIGINT, interrupt_handler);
2541#endif
drh44c2eb12003-04-30 11:38:26 +00002542
drh22fbcb82004-02-01 01:22:50 +00002543 /* Do an initial pass through the command-line argument to locate
2544 ** the name of the database file, the name of the initialization file,
2545 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002546 */
drh22fbcb82004-02-01 01:22:50 +00002547 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002548 char *z;
drh44c2eb12003-04-30 11:38:26 +00002549 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002550 z = argv[i];
2551 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002552 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2553 i++;
drh22fbcb82004-02-01 01:22:50 +00002554 }else if( strcmp(argv[i],"-init")==0 ){
2555 i++;
2556 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002557 /* Need to check for batch mode here to so we can avoid printing
2558 ** informational messages (like from process_sqliterc) before
2559 ** we do the actual processing of arguments later in a second pass.
2560 */
2561 }else if( strcmp(argv[i],"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002562 stdin_is_interactive = 0;
drh44c2eb12003-04-30 11:38:26 +00002563 }
2564 }
drh22fbcb82004-02-01 01:22:50 +00002565 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002566#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002567 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2568#else
drh22fbcb82004-02-01 01:22:50 +00002569 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002570#endif
drh22fbcb82004-02-01 01:22:50 +00002571 }else{
danielk197703aded42004-11-22 05:26:27 +00002572#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002573 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002574#else
2575 data.zDbFilename = 0;
2576#endif
drh22fbcb82004-02-01 01:22:50 +00002577 }
2578 if( i<argc ){
2579 zFirstCmd = argv[i++];
2580 }
shaneh5fc25012009-11-11 04:17:07 +00002581 if( i<argc ){
2582 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2583 fprintf(stderr,"Use -help for a list of options.\n");
2584 return 1;
2585 }
drh44c2eb12003-04-30 11:38:26 +00002586 data.out = stdout;
2587
drh01b41712005-08-29 23:06:23 +00002588#ifdef SQLITE_OMIT_MEMORYDB
2589 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002590 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2591 return 1;
drh01b41712005-08-29 23:06:23 +00002592 }
2593#endif
2594
drh44c2eb12003-04-30 11:38:26 +00002595 /* Go ahead and open the database file if it already exists. If the
2596 ** file does not exist, delay opening it. This prevents empty database
2597 ** files from being created if a user mistypes the database name argument
2598 ** to the sqlite command-line tool.
2599 */
drhc8d74412004-08-31 23:41:26 +00002600 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002601 open_db(&data);
2602 }
2603
drh22fbcb82004-02-01 01:22:50 +00002604 /* Process the initialization file if there is one. If no -init option
2605 ** is given on the command line, look for a file named ~/.sqliterc and
2606 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002607 */
shane86f5bdb2009-10-24 02:00:07 +00002608 rc = process_sqliterc(&data,zInitFile);
2609 if( rc>0 ){
2610 return rc;
2611 }
drh44c2eb12003-04-30 11:38:26 +00002612
drh22fbcb82004-02-01 01:22:50 +00002613 /* Make a second pass through the command-line argument and set
2614 ** options. This second pass is delayed until after the initialization
2615 ** file is processed so that the command-line arguments will override
2616 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002617 */
drh22fbcb82004-02-01 01:22:50 +00002618 for(i=1; i<argc && argv[i][0]=='-'; i++){
2619 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002620 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002621 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002622 i++;
2623 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002624 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002625 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002626 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002627 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002628 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002629 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002630 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002631 }else if( strcmp(z,"-csv")==0 ){
2632 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002633 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002634 }else if( strcmp(z,"-separator")==0 ){
2635 i++;
shaneh5fc25012009-11-11 04:17:07 +00002636 if(i>=argc){
2637 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2638 fprintf(stderr,"Use -help for a list of options.\n");
2639 return 1;
2640 }
drh5bb3eb92007-05-04 13:15:55 +00002641 sqlite3_snprintf(sizeof(data.separator), data.separator,
2642 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002643 }else if( strcmp(z,"-nullvalue")==0 ){
2644 i++;
shaneh5fc25012009-11-11 04:17:07 +00002645 if(i>=argc){
2646 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2647 fprintf(stderr,"Use -help for a list of options.\n");
2648 return 1;
2649 }
drh5bb3eb92007-05-04 13:15:55 +00002650 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2651 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002652 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002653 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002654 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002655 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002656 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002657 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00002658 }else if( strcmp(z,"-stats")==0 ){
2659 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002660 }else if( strcmp(z,"-bail")==0 ){
2661 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002662 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002663 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002664 return 0;
drhc28490c2006-10-26 14:25:58 +00002665 }else if( strcmp(z,"-interactive")==0 ){
2666 stdin_is_interactive = 1;
2667 }else if( strcmp(z,"-batch")==0 ){
2668 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002669 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002670 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002671 }else{
shane86f5bdb2009-10-24 02:00:07 +00002672 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002673 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002674 return 1;
2675 }
2676 }
drh44c2eb12003-04-30 11:38:26 +00002677
drh22fbcb82004-02-01 01:22:50 +00002678 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002679 /* Run just the command that follows the database name
2680 */
drh22fbcb82004-02-01 01:22:50 +00002681 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00002682 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002683 }else{
drh44c2eb12003-04-30 11:38:26 +00002684 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00002685 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00002686 if( zErrMsg!=0 ){
2687 fprintf(stderr,"Error: %s\n", zErrMsg);
2688 return rc!=0 ? rc : 1;
2689 }else if( rc!=0 ){
2690 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
2691 return rc;
drh6ff13852001-11-25 13:18:23 +00002692 }
drh75897232000-05-29 14:26:00 +00002693 }
2694 }else{
drh44c2eb12003-04-30 11:38:26 +00002695 /* Run commands received from standard input
2696 */
drhc28490c2006-10-26 14:25:58 +00002697 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002698 char *zHome;
2699 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002700 int nHistory;
drh75897232000-05-29 14:26:00 +00002701 printf(
drhb217a572000-08-22 13:40:18 +00002702 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002703 "Enter \".help\" for instructions\n"
2704 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002705 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002706 );
drh67505e72002-04-19 12:34:06 +00002707 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002708 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002709 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002710 if( (zHistory = malloc(nHistory))!=0 ){
2711 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2712 }
drh67505e72002-04-19 12:34:06 +00002713 }
danielk19774af00c62005-01-23 23:43:21 +00002714#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002715 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002716#endif
drhc28490c2006-10-26 14:25:58 +00002717 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002718 if( zHistory ){
2719 stifle_history(100);
2720 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002721 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002722 }
adamd0a3daa32006-07-28 20:16:14 +00002723 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002724 }else{
drhc28490c2006-10-26 14:25:58 +00002725 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002726 }
2727 }
drh33048c02001-10-01 14:29:22 +00002728 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00002729 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00002730 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00002731 }
drhc28490c2006-10-26 14:25:58 +00002732 return rc;
drh75897232000-05-29 14:26:00 +00002733}