blob: 34e821ca3dda056cf52a53835db632271e9d81d2 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
shane18e526c2008-12-10 22:30:24 +000015#if defined(_WIN32) || defined(WIN32)
16/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh75897232000-05-29 14:26:00 +000020#include <stdlib.h>
21#include <string.h>
22#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000023#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000024#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000025#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000026#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000027
drh454ad582007-11-26 22:54:27 +000028#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000029# include <signal.h>
chw97185482008-11-17 08:05:31 +000030# if !defined(__RTP__) && !defined(_WRS_KERNEL)
31# include <pwd.h>
32# endif
drhdd45df82002-04-18 12:39:03 +000033# include <unistd.h>
34# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000035#endif
drh75897232000-05-29 14:26:00 +000036
drhcdb36b72006-06-12 12:57:45 +000037#ifdef __OS2__
38# include <unistd.h>
39#endif
40
drh81d7fd12010-12-08 00:02:26 +000041#ifdef HAVE_EDITLINE
42# include <editline/editline.h>
43#endif
drh16e59552000-07-31 11:57:37 +000044#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000045# include <readline/readline.h>
46# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000047#endif
48#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
drh9347b202003-07-18 01:30:59 +000049# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000050# define add_history(X)
drh67505e72002-04-19 12:34:06 +000051# define read_history(X)
52# define write_history(X)
53# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000054#endif
55
adamd2e8464a2006-09-06 21:39:40 +000056#if defined(_WIN32) || defined(WIN32)
57# include <io.h>
shane18e526c2008-12-10 22:30:24 +000058#define isatty(h) _isatty(h)
59#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000060#else
drh4328c8b2003-04-26 02:50:11 +000061/* Make sure isatty() has a prototype.
62*/
63extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000064#endif
drh4328c8b2003-04-26 02:50:11 +000065
chw65d3c132007-11-12 21:09:10 +000066#if defined(_WIN32_WCE)
67/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
68 * thus we always assume that we have a console. That can be
69 * overridden with the -batch command line option.
70 */
71#define isatty(x) 1
72#endif
73
chw97185482008-11-17 08:05:31 +000074#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000075#include <sys/time.h>
76#include <sys/resource.h>
77
drhda108222009-02-25 19:07:24 +000078/* Saved resource information for the beginning of an operation */
79static struct rusage sBegin;
80
81/* True if the timer is enabled */
82static int enableTimer = 0;
83
84/*
85** Begin timing an operation
86*/
87static void beginTimer(void){
88 if( enableTimer ){
89 getrusage(RUSAGE_SELF, &sBegin);
90 }
91}
92
93/* Return the difference of two time_structs in seconds */
94static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
95 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
96 (double)(pEnd->tv_sec - pStart->tv_sec);
97}
98
99/*
100** Print the timing results.
101*/
102static void endTimer(void){
103 if( enableTimer ){
104 struct rusage sEnd;
105 getrusage(RUSAGE_SELF, &sEnd);
106 printf("CPU Time: user %f sys %f\n",
107 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
108 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
109 }
110}
shaneb320ccd2009-10-21 03:42:58 +0000111
drhda108222009-02-25 19:07:24 +0000112#define BEGIN_TIMER beginTimer()
113#define END_TIMER endTimer()
114#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000115
116#elif (defined(_WIN32) || defined(WIN32))
117
118#include <windows.h>
119
120/* Saved resource information for the beginning of an operation */
121static HANDLE hProcess;
122static FILETIME ftKernelBegin;
123static FILETIME ftUserBegin;
124typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
125static GETPROCTIMES getProcessTimesAddr = NULL;
126
127/* True if the timer is enabled */
128static int enableTimer = 0;
129
130/*
131** Check to see if we have timer support. Return 1 if necessary
132** support found (or found previously).
133*/
134static int hasTimer(void){
135 if( getProcessTimesAddr ){
136 return 1;
137 } else {
138 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
139 ** See if the version we are running on has it, and if it does, save off
140 ** a pointer to it and the current process handle.
141 */
142 hProcess = GetCurrentProcess();
143 if( hProcess ){
144 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
145 if( NULL != hinstLib ){
146 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
147 if( NULL != getProcessTimesAddr ){
148 return 1;
149 }
150 FreeLibrary(hinstLib);
151 }
152 }
153 }
154 return 0;
155}
156
157/*
158** Begin timing an operation
159*/
160static void beginTimer(void){
161 if( enableTimer && getProcessTimesAddr ){
162 FILETIME ftCreation, ftExit;
163 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
164 }
165}
166
167/* Return the difference of two FILETIME structs in seconds */
168static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
169 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
170 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
171 return (double) ((i64End - i64Start) / 10000000.0);
172}
173
174/*
175** Print the timing results.
176*/
177static void endTimer(void){
178 if( enableTimer && getProcessTimesAddr){
179 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
180 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
181 printf("CPU Time: user %f sys %f\n",
182 timeDiff(&ftUserBegin, &ftUserEnd),
183 timeDiff(&ftKernelBegin, &ftKernelEnd));
184 }
185}
186
187#define BEGIN_TIMER beginTimer()
188#define END_TIMER endTimer()
189#define HAS_TIMER hasTimer()
190
drhda108222009-02-25 19:07:24 +0000191#else
192#define BEGIN_TIMER
193#define END_TIMER
194#define HAS_TIMER 0
195#endif
196
shanec0688ea2009-03-05 03:48:06 +0000197/*
198** Used to prevent warnings about unused parameters
199*/
200#define UNUSED_PARAMETER(x) (void)(x)
201
drhe91d16b2008-12-08 18:27:31 +0000202/*
drhc49f44e2006-10-26 18:15:42 +0000203** If the following flag is set, then command execution stops
204** at an error if we are not interactive.
205*/
206static int bail_on_error = 0;
207
208/*
drhc28490c2006-10-26 14:25:58 +0000209** Threat stdin as an interactive input if the following variable
210** is true. Otherwise, assume stdin is connected to a file or pipe.
211*/
212static int stdin_is_interactive = 1;
213
214/*
drh4c504392000-10-16 22:06:40 +0000215** The following is the open SQLite database. We make a pointer
216** to this database a static variable so that it can be accessed
217** by the SIGINT handler to interrupt database processing.
218*/
danielk197792f9a1b2004-06-19 09:08:16 +0000219static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000220
221/*
drh67505e72002-04-19 12:34:06 +0000222** True if an interrupt (Control-C) has been received.
223*/
drh43617e92006-03-06 20:55:46 +0000224static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000225
226/*
persicom7e2dfdd2002-04-18 02:46:52 +0000227** This is the name of our program. It is set in main(), used
228** in a number of other places, mostly for error messages.
229*/
230static char *Argv0;
231
232/*
233** Prompt strings. Initialized in main. Settable with
234** .prompt main continue
235*/
236static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
237static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
238
drhb0603412007-02-28 04:47:26 +0000239/*
240** Write I/O traces to the following stream.
241*/
rsebe0a9092007-07-30 18:24:38 +0000242#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000243static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000244#endif
drhb0603412007-02-28 04:47:26 +0000245
246/*
247** This routine works like printf in that its first argument is a
248** format string and subsequent arguments are values to be substituted
249** in place of % fields. The result of formatting this string
250** is written to iotrace.
251*/
rsebe0a9092007-07-30 18:24:38 +0000252#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000253static void iotracePrintf(const char *zFormat, ...){
254 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000255 char *z;
drhb0603412007-02-28 04:47:26 +0000256 if( iotrace==0 ) return;
257 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000258 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000259 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000260 fprintf(iotrace, "%s", z);
261 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000262}
rsebe0a9092007-07-30 18:24:38 +0000263#endif
drhb0603412007-02-28 04:47:26 +0000264
drh44c2eb12003-04-30 11:38:26 +0000265
persicom7e2dfdd2002-04-18 02:46:52 +0000266/*
drh83965662003-04-17 02:54:13 +0000267** Determines if a string is a number of not.
268*/
danielk19772e588c72005-12-09 14:25:08 +0000269static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000270 if( *z=='-' || *z=='+' ) z++;
271 if( !isdigit(*z) ){
272 return 0;
273 }
274 z++;
275 if( realnum ) *realnum = 0;
276 while( isdigit(*z) ){ z++; }
277 if( *z=='.' ){
278 z++;
279 if( !isdigit(*z) ) return 0;
280 while( isdigit(*z) ){ z++; }
281 if( realnum ) *realnum = 1;
282 }
283 if( *z=='e' || *z=='E' ){
284 z++;
285 if( *z=='+' || *z=='-' ) z++;
286 if( !isdigit(*z) ) return 0;
287 while( isdigit(*z) ){ z++; }
288 if( realnum ) *realnum = 1;
289 }
290 return *z==0;
291}
drh83965662003-04-17 02:54:13 +0000292
293/*
danielk1977bc6ada42004-06-30 08:20:16 +0000294** A global char* and an SQL function to access its current value
295** from within an SQL statement. This program used to use the
296** sqlite_exec_printf() API to substitue a string into an SQL statement.
297** The correct way to do this with sqlite3 is to use the bind API, but
298** since the shell is built around the callback paradigm it would be a lot
299** of work. Instead just use this hack, which is quite harmless.
300*/
301static const char *zShellStatic = 0;
302static void shellstaticFunc(
303 sqlite3_context *context,
304 int argc,
305 sqlite3_value **argv
306){
307 assert( 0==argc );
308 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000309 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000310 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000311 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
312}
313
314
315/*
drhfeac5f82004-08-01 00:10:45 +0000316** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000317** the text in memory obtained from malloc() and returns a pointer
318** to the text. NULL is returned at end of file, or if malloc()
319** fails.
320**
321** The interface is like "readline" but no command-line editing
322** is done.
323*/
drh9347b202003-07-18 01:30:59 +0000324static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000325 char *zLine;
326 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000327 int n;
328 int eol;
329
330 if( zPrompt && *zPrompt ){
331 printf("%s",zPrompt);
332 fflush(stdout);
333 }
334 nLine = 100;
335 zLine = malloc( nLine );
336 if( zLine==0 ) return 0;
337 n = 0;
338 eol = 0;
339 while( !eol ){
340 if( n+100>nLine ){
341 nLine = nLine*2 + 100;
342 zLine = realloc(zLine, nLine);
343 if( zLine==0 ) return 0;
344 }
drhdaffd0e2001-04-11 14:28:42 +0000345 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000346 if( n==0 ){
347 free(zLine);
348 return 0;
349 }
350 zLine[n] = 0;
351 eol = 1;
352 break;
353 }
354 while( zLine[n] ){ n++; }
355 if( n>0 && zLine[n-1]=='\n' ){
356 n--;
shaneh13b36022009-12-17 21:07:15 +0000357 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000358 zLine[n] = 0;
359 eol = 1;
360 }
361 }
362 zLine = realloc( zLine, n+1 );
363 return zLine;
364}
365
366/*
drhc28490c2006-10-26 14:25:58 +0000367** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000368**
369** zPrior is a string of prior text retrieved. If not the empty
370** string, then issue a continuation prompt.
371*/
drhdaffd0e2001-04-11 14:28:42 +0000372static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000373 char *zPrompt;
374 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000375 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000376 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000377 }
378 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000379 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000380 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000381 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000382 }
383 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000384#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000385 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000386#endif
drh8e7e7a22000-05-30 18:45:23 +0000387 return zResult;
388}
389
persicom7e2dfdd2002-04-18 02:46:52 +0000390struct previous_mode_data {
391 int valid; /* Is there legit data in here? */
392 int mode;
393 int showHeader;
394 int colWidth[100];
395};
drh45e29d82006-11-20 16:21:10 +0000396
drh8e7e7a22000-05-30 18:45:23 +0000397/*
drh75897232000-05-29 14:26:00 +0000398** An pointer to an instance of this structure is passed from
399** the main program to the callback. This is used to communicate
400** state and mode information.
401*/
402struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000403 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000404 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000405 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000406 int cnt; /* Number of records displayed so far */
407 FILE *out; /* Write results here */
408 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000409 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000410 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000411 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000412 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000413 int colWidth[100]; /* Requested width of each column when in column mode*/
414 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000415 char nullvalue[20]; /* The text to print when a NULL comes back from
416 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000417 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000418 /* Holds the mode information just before
419 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000420 char outfile[FILENAME_MAX]; /* Filename for *out */
421 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000422 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000423 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000424 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000425};
426
427/*
428** These are the allowed modes.
429*/
drh967e8b72000-06-21 13:59:10 +0000430#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000431#define MODE_Column 1 /* One record per line in neat columns */
432#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000433#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
434#define MODE_Html 4 /* Generate an XHTML table */
435#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000436#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000437#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000438#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000439
drh66ce4d02008-02-15 17:38:06 +0000440static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000441 "line",
442 "column",
443 "list",
444 "semi",
445 "html",
drhfeac5f82004-08-01 00:10:45 +0000446 "insert",
447 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000448 "csv",
drh66ce4d02008-02-15 17:38:06 +0000449 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000450};
drh75897232000-05-29 14:26:00 +0000451
452/*
453** Number of elements in an array
454*/
drh902b9ee2008-12-05 17:17:07 +0000455#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000456
457/*
drhea678832008-12-10 19:26:22 +0000458** Compute a string length that is limited to what can be stored in
459** lower 30 bits of a 32-bit signed integer.
460*/
drh4f21c4a2008-12-10 22:15:00 +0000461static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000462 const char *z2 = z;
463 while( *z2 ){ z2++; }
464 return 0x3fffffff & (int)(z2 - z);
465}
466
467/*
drh127f9d72010-02-23 01:47:00 +0000468** A callback for the sqlite3_log() interface.
469*/
470static void shellLog(void *pArg, int iErrCode, const char *zMsg){
471 struct callback_data *p = (struct callback_data*)pArg;
472 if( p->pLog==0 ) return;
473 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
474 fflush(p->pLog);
475}
476
477/*
shane626a6e42009-10-22 17:30:15 +0000478** Output the given string as a hex-encoded blob (eg. X'1234' )
479*/
480static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
481 int i;
482 char *zBlob = (char *)pBlob;
483 fprintf(out,"X'");
484 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
485 fprintf(out,"'");
486}
487
488/*
drh28bd4bc2000-06-15 15:57:22 +0000489** Output the given string as a quoted string using SQL quoting conventions.
490*/
491static void output_quoted_string(FILE *out, const char *z){
492 int i;
493 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000494 for(i=0; z[i]; i++){
495 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000496 }
497 if( nSingle==0 ){
498 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000499 }else{
500 fprintf(out,"'");
501 while( *z ){
502 for(i=0; z[i] && z[i]!='\''; i++){}
503 if( i==0 ){
504 fprintf(out,"''");
505 z++;
506 }else if( z[i]=='\'' ){
507 fprintf(out,"%.*s''",i,z);
508 z += i+1;
509 }else{
drhcd7d2732002-02-26 23:24:26 +0000510 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000511 break;
512 }
513 }
drhcd7d2732002-02-26 23:24:26 +0000514 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000515 }
516}
517
518/*
drhfeac5f82004-08-01 00:10:45 +0000519** Output the given string as a quoted according to C or TCL quoting rules.
520*/
521static void output_c_string(FILE *out, const char *z){
522 unsigned int c;
523 fputc('"', out);
524 while( (c = *(z++))!=0 ){
525 if( c=='\\' ){
526 fputc(c, out);
527 fputc(c, out);
528 }else if( c=='\t' ){
529 fputc('\\', out);
530 fputc('t', out);
531 }else if( c=='\n' ){
532 fputc('\\', out);
533 fputc('n', out);
534 }else if( c=='\r' ){
535 fputc('\\', out);
536 fputc('r', out);
537 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000538 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000539 }else{
540 fputc(c, out);
541 }
542 }
543 fputc('"', out);
544}
545
546/*
drhc08a4f12000-06-15 16:49:48 +0000547** Output the given string with characters that are special to
548** HTML escaped.
549*/
550static void output_html_string(FILE *out, const char *z){
551 int i;
552 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000553 for(i=0; z[i]
554 && z[i]!='<'
555 && z[i]!='&'
556 && z[i]!='>'
557 && z[i]!='\"'
558 && z[i]!='\'';
559 i++){}
drhc08a4f12000-06-15 16:49:48 +0000560 if( i>0 ){
561 fprintf(out,"%.*s",i,z);
562 }
563 if( z[i]=='<' ){
564 fprintf(out,"&lt;");
565 }else if( z[i]=='&' ){
566 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000567 }else if( z[i]=='>' ){
568 fprintf(out,"&gt;");
569 }else if( z[i]=='\"' ){
570 fprintf(out,"&quot;");
571 }else if( z[i]=='\'' ){
572 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000573 }else{
574 break;
575 }
576 z += i + 1;
577 }
578}
579
580/*
drhc49f44e2006-10-26 18:15:42 +0000581** If a field contains any character identified by a 1 in the following
582** array, then the string must be quoted for CSV.
583*/
584static const char needCsvQuote[] = {
585 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
586 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
587 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
588 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
591 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
592 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
593 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
594 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
595 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
596 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
597 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
598 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
599 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
600 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
601};
602
603/*
drh8e64d1c2004-10-07 00:32:39 +0000604** Output a single term of CSV. Actually, p->separator is used for
605** the separator, which may or may not be a comma. p->nullvalue is
606** the null value. Strings are quoted using ANSI-C rules. Numbers
607** appear outside of quotes.
608*/
609static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000610 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000611 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000612 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000613 }else{
drhc49f44e2006-10-26 18:15:42 +0000614 int i;
drh4f21c4a2008-12-10 22:15:00 +0000615 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000616 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000617 if( needCsvQuote[((unsigned char*)z)[i]]
618 || (z[i]==p->separator[0] &&
619 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000620 i = 0;
621 break;
622 }
623 }
624 if( i==0 ){
625 putc('"', out);
626 for(i=0; z[i]; i++){
627 if( z[i]=='"' ) putc('"', out);
628 putc(z[i], out);
629 }
630 putc('"', out);
631 }else{
632 fprintf(out, "%s", z);
633 }
drh8e64d1c2004-10-07 00:32:39 +0000634 }
635 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000636 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000637 }
638}
639
danielk19774af00c62005-01-23 23:43:21 +0000640#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000641/*
drh4c504392000-10-16 22:06:40 +0000642** This routine runs when the user presses Ctrl-C
643*/
644static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000645 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000646 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000647 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000648}
danielk19774af00c62005-01-23 23:43:21 +0000649#endif
drh4c504392000-10-16 22:06:40 +0000650
651/*
shane626a6e42009-10-22 17:30:15 +0000652** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000653** invokes for each row of a query result.
654*/
shane626a6e42009-10-22 17:30:15 +0000655static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000656 int i;
657 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000658
drh75897232000-05-29 14:26:00 +0000659 switch( p->mode ){
660 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000661 int w = 5;
drh6a535342001-10-19 16:44:56 +0000662 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000663 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000664 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000665 if( len>w ) w = len;
666 }
drh75897232000-05-29 14:26:00 +0000667 if( p->cnt++>0 ) fprintf(p->out,"\n");
668 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000669 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000670 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000671 }
672 break;
673 }
danielk19770d78bae2008-01-03 07:09:48 +0000674 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000675 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000676 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000677 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000678 int w, n;
679 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000680 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000681 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000682 w = 0;
drh75897232000-05-29 14:26:00 +0000683 }
drha0c66f52000-07-29 13:20:21 +0000684 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000685 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000686 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000687 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000688 if( w<n ) w = n;
689 }
690 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000691 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000692 }
693 if( p->showHeader ){
694 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
695 }
696 }
697 if( p->showHeader ){
698 for(i=0; i<nArg; i++){
699 int w;
700 if( i<ArraySize(p->actualWidth) ){
701 w = p->actualWidth[i];
702 }else{
703 w = 10;
704 }
705 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
706 "----------------------------------------------------------",
707 i==nArg-1 ? "\n": " ");
708 }
drh75897232000-05-29 14:26:00 +0000709 }
710 }
drh6a535342001-10-19 16:44:56 +0000711 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000712 for(i=0; i<nArg; i++){
713 int w;
drha0c66f52000-07-29 13:20:21 +0000714 if( i<ArraySize(p->actualWidth) ){
715 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000716 }else{
717 w = 10;
718 }
drhea678832008-12-10 19:26:22 +0000719 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000720 strlen30(azArg[i])>w ){
721 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000722 }
drhc61053b2000-06-04 12:58:36 +0000723 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000724 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000725 }
726 break;
727 }
drhe3710332000-09-29 13:30:53 +0000728 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000729 case MODE_List: {
730 if( p->cnt++==0 && p->showHeader ){
731 for(i=0; i<nArg; i++){
732 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
733 }
734 }
drh6a535342001-10-19 16:44:56 +0000735 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000736 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000737 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000738 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000739 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000740 if( i<nArg-1 ){
741 fprintf(p->out, "%s", p->separator);
742 }else if( p->mode==MODE_Semi ){
743 fprintf(p->out, ";\n");
744 }else{
745 fprintf(p->out, "\n");
746 }
drh75897232000-05-29 14:26:00 +0000747 }
748 break;
749 }
drh1e5d0e92000-05-31 23:33:17 +0000750 case MODE_Html: {
751 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000752 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000753 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000754 fprintf(p->out,"<TH>");
755 output_html_string(p->out, azCol[i]);
756 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000757 }
mihailim57c591a2008-06-23 21:26:05 +0000758 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000759 }
drh6a535342001-10-19 16:44:56 +0000760 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000761 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000762 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000763 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000764 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000765 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000766 }
mihailim57c591a2008-06-23 21:26:05 +0000767 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000768 break;
769 }
drhfeac5f82004-08-01 00:10:45 +0000770 case MODE_Tcl: {
771 if( p->cnt++==0 && p->showHeader ){
772 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000773 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000774 fprintf(p->out, "%s", p->separator);
775 }
776 fprintf(p->out,"\n");
777 }
778 if( azArg==0 ) break;
779 for(i=0; i<nArg; i++){
780 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
781 fprintf(p->out, "%s", p->separator);
782 }
783 fprintf(p->out,"\n");
784 break;
785 }
drh8e64d1c2004-10-07 00:32:39 +0000786 case MODE_Csv: {
787 if( p->cnt++==0 && p->showHeader ){
788 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000789 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000790 }
791 fprintf(p->out,"\n");
792 }
793 if( azArg==0 ) break;
794 for(i=0; i<nArg; i++){
795 output_csv(p, azArg[i], i<nArg-1);
796 }
797 fprintf(p->out,"\n");
798 break;
799 }
drh28bd4bc2000-06-15 15:57:22 +0000800 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000801 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000802 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000803 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000804 for(i=0; i<nArg; i++){
805 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000806 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000807 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000808 }else if( aiType && aiType[i]==SQLITE_TEXT ){
809 if( zSep[0] ) fprintf(p->out,"%s",zSep);
810 output_quoted_string(p->out, azArg[i]);
811 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
812 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000813 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
814 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
815 int nBlob = sqlite3_column_bytes(p->pStmt, i);
816 if( zSep[0] ) fprintf(p->out,"%s",zSep);
817 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000818 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000819 fprintf(p->out,"%s%s",zSep, azArg[i]);
820 }else{
821 if( zSep[0] ) fprintf(p->out,"%s",zSep);
822 output_quoted_string(p->out, azArg[i]);
823 }
824 }
825 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000826 break;
drh28bd4bc2000-06-15 15:57:22 +0000827 }
persicom1d0b8722002-04-18 02:53:04 +0000828 }
drh75897232000-05-29 14:26:00 +0000829 return 0;
830}
831
832/*
shane626a6e42009-10-22 17:30:15 +0000833** This is the callback routine that the SQLite library
834** invokes for each row of a query result.
835*/
836static int callback(void *pArg, int nArg, char **azArg, char **azCol){
837 /* since we don't have type info, call the shell_callback with a NULL value */
838 return shell_callback(pArg, nArg, azArg, azCol, NULL);
839}
840
841/*
drh33048c02001-10-01 14:29:22 +0000842** Set the destination table field of the callback_data structure to
843** the name of the table given. Escape any quote characters in the
844** table name.
845*/
846static void set_table_name(struct callback_data *p, const char *zName){
847 int i, n;
848 int needQuote;
849 char *z;
850
851 if( p->zDestTable ){
852 free(p->zDestTable);
853 p->zDestTable = 0;
854 }
855 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000856 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000857 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000858 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000859 needQuote = 1;
860 if( zName[i]=='\'' ) n++;
861 }
862 }
863 if( needQuote ) n += 2;
864 z = p->zDestTable = malloc( n+1 );
865 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000866 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000867 exit(1);
868 }
869 n = 0;
870 if( needQuote ) z[n++] = '\'';
871 for(i=0; zName[i]; i++){
872 z[n++] = zName[i];
873 if( zName[i]=='\'' ) z[n++] = '\'';
874 }
875 if( needQuote ) z[n++] = '\'';
876 z[n] = 0;
877}
878
danielk19772a02e332004-06-05 08:04:36 +0000879/* zIn is either a pointer to a NULL-terminated string in memory obtained
880** from malloc(), or a NULL pointer. The string pointed to by zAppend is
881** added to zIn, and the result returned in memory obtained from malloc().
882** zIn, if it was not NULL, is freed.
883**
884** If the third argument, quote, is not '\0', then it is used as a
885** quote character for zAppend.
886*/
drhc28490c2006-10-26 14:25:58 +0000887static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000888 int len;
889 int i;
drh4f21c4a2008-12-10 22:15:00 +0000890 int nAppend = strlen30(zAppend);
891 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000892
893 len = nAppend+nIn+1;
894 if( quote ){
895 len += 2;
896 for(i=0; i<nAppend; i++){
897 if( zAppend[i]==quote ) len++;
898 }
899 }
900
901 zIn = (char *)realloc(zIn, len);
902 if( !zIn ){
903 return 0;
904 }
905
906 if( quote ){
907 char *zCsr = &zIn[nIn];
908 *zCsr++ = quote;
909 for(i=0; i<nAppend; i++){
910 *zCsr++ = zAppend[i];
911 if( zAppend[i]==quote ) *zCsr++ = quote;
912 }
913 *zCsr++ = quote;
914 *zCsr++ = '\0';
915 assert( (zCsr-zIn)==len );
916 }else{
917 memcpy(&zIn[nIn], zAppend, nAppend);
918 zIn[len-1] = '\0';
919 }
920
921 return zIn;
922}
923
drhdd3d4592004-08-30 01:54:05 +0000924
925/*
926** Execute a query statement that has a single result column. Print
927** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000928**
929** This is used, for example, to show the schema of the database by
930** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000931*/
drh157e29a2009-05-21 15:15:00 +0000932static int run_table_dump_query(
933 FILE *out, /* Send output here */
934 sqlite3 *db, /* Database to query */
935 const char *zSelect, /* SELECT statement to extract content */
936 const char *zFirstRow /* Print before first row, if not NULL */
937){
drhdd3d4592004-08-30 01:54:05 +0000938 sqlite3_stmt *pSelect;
939 int rc;
940 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
941 if( rc!=SQLITE_OK || !pSelect ){
942 return rc;
943 }
944 rc = sqlite3_step(pSelect);
945 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000946 if( zFirstRow ){
947 fprintf(out, "%s", zFirstRow);
948 zFirstRow = 0;
949 }
drhdd3d4592004-08-30 01:54:05 +0000950 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
951 rc = sqlite3_step(pSelect);
952 }
953 return sqlite3_finalize(pSelect);
954}
955
shane626a6e42009-10-22 17:30:15 +0000956/*
957** Allocate space and save off current error string.
958*/
959static char *save_err_msg(
960 sqlite3 *db /* Database to query */
961){
962 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
963 char *zErrMsg = sqlite3_malloc(nErrMsg);
964 if( zErrMsg ){
965 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
966 }
967 return zErrMsg;
968}
969
970/*
shaneh642d8b82010-07-28 16:05:34 +0000971** Display memory stats.
972*/
973static int display_stats(
974 sqlite3 *db, /* Database to query */
975 struct callback_data *pArg, /* Pointer to struct callback_data */
976 int bReset /* True to reset the stats */
977){
978 int iCur;
979 int iHiwtr;
980
981 if( pArg && pArg->out ){
982
983 iHiwtr = iCur = -1;
984 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +0000985 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000986 iHiwtr = iCur = -1;
987 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +0000988 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +0000989/*
990** Not currently used by the CLI.
991** iHiwtr = iCur = -1;
992** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
993** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
994*/
995 iHiwtr = iCur = -1;
996 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
997 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
998/*
999** Not currently used by the CLI.
1000** iHiwtr = iCur = -1;
1001** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1002** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1003*/
1004 iHiwtr = iCur = -1;
1005 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1006 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1007 iHiwtr = iCur = -1;
1008 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1009 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1010 iHiwtr = iCur = -1;
1011 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1012 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1013 iHiwtr = iCur = -1;
1014 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1015 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1016#ifdef YYTRACKMAXSTACKDEPTH
1017 iHiwtr = iCur = -1;
1018 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1019 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1020#endif
1021 }
1022
1023 if( pArg && pArg->out && db ){
1024 iHiwtr = iCur = -1;
1025 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1026 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001027 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1028 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1029 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1030 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1031 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1032 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001033 iHiwtr = iCur = -1;
1034 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh233f8162010-07-28 17:36:11 +00001035 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001036 iHiwtr = iCur = -1;
1037 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1038 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1039 iHiwtr = iCur = -1;
1040 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1041 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1042 }
1043
1044 if( pArg && pArg->out && db && pArg->pStmt ){
1045 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1046 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1047 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1048 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1049 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1050 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1051 }
1052
1053 return 0;
1054}
1055
1056/*
shane626a6e42009-10-22 17:30:15 +00001057** Execute a statement or set of statements. Print
1058** any result rows/columns depending on the current mode
1059** set via the supplied callback.
1060**
1061** This is very similar to SQLite's built-in sqlite3_exec()
1062** function except it takes a slightly different callback
1063** and callback data argument.
1064*/
1065static int shell_exec(
1066 sqlite3 *db, /* An open database */
1067 const char *zSql, /* SQL to be evaluated */
1068 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1069 /* (not the same as sqlite3_exec) */
1070 struct callback_data *pArg, /* Pointer to struct callback_data */
1071 char **pzErrMsg /* Error msg written here */
1072){
dan4564ced2010-01-05 04:59:56 +00001073 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1074 int rc = SQLITE_OK; /* Return Code */
1075 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001076
1077 if( pzErrMsg ){
1078 *pzErrMsg = NULL;
1079 }
1080
shaneb9fc17d2009-10-22 21:23:35 +00001081 while( zSql[0] && (SQLITE_OK == rc) ){
1082 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1083 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001084 if( pzErrMsg ){
1085 *pzErrMsg = save_err_msg(db);
1086 }
1087 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001088 if( !pStmt ){
1089 /* this happens for a comment or white-space */
1090 zSql = zLeftover;
1091 while( isspace(zSql[0]) ) zSql++;
1092 continue;
1093 }
shane626a6e42009-10-22 17:30:15 +00001094
shaneh642d8b82010-07-28 16:05:34 +00001095 /* save off the prepared statment handle and reset row count */
1096 if( pArg ){
1097 pArg->pStmt = pStmt;
1098 pArg->cnt = 0;
1099 }
1100
shanehb7977c52010-01-18 18:17:10 +00001101 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001102 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001103 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001104 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001105 }
shanehb7977c52010-01-18 18:17:10 +00001106
shaneb9fc17d2009-10-22 21:23:35 +00001107 /* perform the first step. this will tell us if we
1108 ** have a result set or not and how wide it is.
1109 */
1110 rc = sqlite3_step(pStmt);
1111 /* if we have a result set... */
1112 if( SQLITE_ROW == rc ){
1113 /* if we have a callback... */
1114 if( xCallback ){
1115 /* allocate space for col name ptr, value ptr, and type */
1116 int nCol = sqlite3_column_count(pStmt);
1117 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1118 if( !pData ){
1119 rc = SQLITE_NOMEM;
1120 }else{
1121 char **azCols = (char **)pData; /* Names of result columns */
1122 char **azVals = &azCols[nCol]; /* Results */
1123 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1124 int i;
1125 assert(sizeof(int) <= sizeof(char *));
1126 /* save off ptrs to column names */
1127 for(i=0; i<nCol; i++){
1128 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1129 }
shaneb9fc17d2009-10-22 21:23:35 +00001130 do{
1131 /* extract the data and data types */
1132 for(i=0; i<nCol; i++){
1133 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1134 aiTypes[i] = sqlite3_column_type(pStmt, i);
1135 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1136 rc = SQLITE_NOMEM;
1137 break; /* from for */
1138 }
1139 } /* end for */
1140
1141 /* if data and types extracted successfully... */
1142 if( SQLITE_ROW == rc ){
1143 /* call the supplied callback with the result row data */
1144 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1145 rc = SQLITE_ABORT;
1146 }else{
1147 rc = sqlite3_step(pStmt);
1148 }
1149 }
1150 } while( SQLITE_ROW == rc );
1151 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001152 }
1153 }else{
1154 do{
1155 rc = sqlite3_step(pStmt);
1156 } while( rc == SQLITE_ROW );
1157 }
1158 }
1159
shaneh642d8b82010-07-28 16:05:34 +00001160 /* print usage stats if stats on */
1161 if( pArg && pArg->statsOn ){
1162 display_stats(db, pArg, 0);
1163 }
1164
dan4564ced2010-01-05 04:59:56 +00001165 /* Finalize the statement just executed. If this fails, save a
1166 ** copy of the error message. Otherwise, set zSql to point to the
1167 ** next statement to execute. */
1168 rc = sqlite3_finalize(pStmt);
1169 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001170 zSql = zLeftover;
1171 while( isspace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001172 }else if( pzErrMsg ){
1173 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001174 }
shaneh642d8b82010-07-28 16:05:34 +00001175
1176 /* clear saved stmt handle */
1177 if( pArg ){
1178 pArg->pStmt = NULL;
1179 }
shane626a6e42009-10-22 17:30:15 +00001180 }
shaneb9fc17d2009-10-22 21:23:35 +00001181 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001182
1183 return rc;
1184}
1185
drhdd3d4592004-08-30 01:54:05 +00001186
drh33048c02001-10-01 14:29:22 +00001187/*
drh4c653a02000-06-07 01:27:47 +00001188** This is a different callback routine used for dumping the database.
1189** Each row received by this callback consists of a table name,
1190** the table type ("index" or "table") and SQL to create the table.
1191** This routine should print text sufficient to recreate the table.
1192*/
1193static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001194 int rc;
1195 const char *zTable;
1196 const char *zType;
1197 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001198 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001199 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001200
drh902b9ee2008-12-05 17:17:07 +00001201 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001202 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001203 zTable = azArg[0];
1204 zType = azArg[1];
1205 zSql = azArg[2];
1206
drh00b950d2005-09-11 02:03:03 +00001207 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001208 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001209 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1210 fprintf(p->out, "ANALYZE sqlite_master;\n");
1211 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1212 return 0;
drh45e29d82006-11-20 16:21:10 +00001213 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1214 char *zIns;
1215 if( !p->writableSchema ){
1216 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1217 p->writableSchema = 1;
1218 }
1219 zIns = sqlite3_mprintf(
1220 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1221 "VALUES('table','%q','%q',0,'%q');",
1222 zTable, zTable, zSql);
1223 fprintf(p->out, "%s\n", zIns);
1224 sqlite3_free(zIns);
1225 return 0;
drh00b950d2005-09-11 02:03:03 +00001226 }else{
1227 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001228 }
danielk19772a02e332004-06-05 08:04:36 +00001229
1230 if( strcmp(zType, "table")==0 ){
1231 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001232 char *zSelect = 0;
1233 char *zTableInfo = 0;
1234 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001235 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001236
1237 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1238 zTableInfo = appendText(zTableInfo, zTable, '"');
1239 zTableInfo = appendText(zTableInfo, ");", 0);
1240
1241 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001242 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001243 if( rc!=SQLITE_OK || !pTableInfo ){
1244 return 1;
1245 }
1246
1247 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1248 zTmp = appendText(zTmp, zTable, '"');
1249 if( zTmp ){
1250 zSelect = appendText(zSelect, zTmp, '\'');
1251 }
1252 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1253 rc = sqlite3_step(pTableInfo);
1254 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001255 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001256 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001257 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001258 rc = sqlite3_step(pTableInfo);
1259 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +00001260 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001261 }else{
1262 zSelect = appendText(zSelect, ") ", 0);
1263 }
drh157e29a2009-05-21 15:15:00 +00001264 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001265 }
1266 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001267 if( rc!=SQLITE_OK || nRow==0 ){
1268 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001269 return 1;
1270 }
1271 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1272 zSelect = appendText(zSelect, zTable, '"');
1273
drh157e29a2009-05-21 15:15:00 +00001274 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001275 if( rc==SQLITE_CORRUPT ){
1276 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh157e29a2009-05-21 15:15:00 +00001277 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001278 }
danielk19772a02e332004-06-05 08:04:36 +00001279 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001280 }
drh4c653a02000-06-07 01:27:47 +00001281 return 0;
1282}
1283
1284/*
drh45e29d82006-11-20 16:21:10 +00001285** Run zQuery. Use dump_callback() as the callback routine so that
1286** the contents of the query are output as SQL statements.
1287**
drhdd3d4592004-08-30 01:54:05 +00001288** If we get a SQLITE_CORRUPT error, rerun the query after appending
1289** "ORDER BY rowid DESC" to the end.
1290*/
1291static int run_schema_dump_query(
1292 struct callback_data *p,
1293 const char *zQuery,
1294 char **pzErrMsg
1295){
1296 int rc;
1297 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1298 if( rc==SQLITE_CORRUPT ){
1299 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001300 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +00001301 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1302 zQ2 = malloc( len+100 );
1303 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001304 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +00001305 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1306 free(zQ2);
1307 }
1308 return rc;
1309}
1310
1311/*
drh75897232000-05-29 14:26:00 +00001312** Text of a help message
1313*/
persicom1d0b8722002-04-18 02:53:04 +00001314static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001315 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001316 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001317 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001318 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001319 " If TABLE specified, only dump tables matching\n"
1320 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001321 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001322 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001323 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1324 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001325 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001326 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001327 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001328 ".indices ?TABLE? Show names of all indices\n"
1329 " If TABLE specified, only show indices for tables\n"
1330 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001331#ifdef SQLITE_ENABLE_IOTRACE
1332 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1333#endif
drh70df4fe2006-06-13 15:12:21 +00001334#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001335 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001336#endif
drh127f9d72010-02-23 01:47:00 +00001337 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001338 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001339 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001340 " column Left-aligned columns. (See .width)\n"
1341 " html HTML <table> code\n"
1342 " insert SQL insert statements for TABLE\n"
1343 " line One value per line\n"
1344 " list Values delimited by .separator string\n"
1345 " tabs Tab-separated values\n"
1346 " tcl TCL list elements\n"
1347 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001348 ".output FILENAME Send output to FILENAME\n"
1349 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001350 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001351 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001352 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001353 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001354 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001355 " If TABLE specified, only show tables matching\n"
1356 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001357 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001358 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001359 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001360 ".tables ?TABLE? List names of tables\n"
1361 " If TABLE specified, only list tables matching\n"
1362 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001363 ".timeout MS Try opening locked tables for MS milliseconds\n"
shanehe2aa9d72009-11-06 17:20:17 +00001364 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001365;
1366
shaneb320ccd2009-10-21 03:42:58 +00001367static char zTimerHelp[] =
1368 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1369;
1370
drhdaffd0e2001-04-11 14:28:42 +00001371/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001372static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001373
drh75897232000-05-29 14:26:00 +00001374/*
drh44c2eb12003-04-30 11:38:26 +00001375** Make sure the database is open. If it is not, then open it. If
1376** the database fails to open, print an error message and exit.
1377*/
1378static void open_db(struct callback_data *p){
1379 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001380 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001381 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001382 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1383 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1384 shellstaticFunc, 0, 0);
1385 }
1386 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001387 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001388 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001389 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001390 }
drhc2e87a32006-06-27 15:16:14 +00001391#ifndef SQLITE_OMIT_LOAD_EXTENSION
1392 sqlite3_enable_load_extension(p->db, 1);
1393#endif
drh44c2eb12003-04-30 11:38:26 +00001394 }
1395}
1396
1397/*
drhfeac5f82004-08-01 00:10:45 +00001398** Do C-language style dequoting.
1399**
1400** \t -> tab
1401** \n -> newline
1402** \r -> carriage return
1403** \NNN -> ascii character NNN in octal
1404** \\ -> backslash
1405*/
1406static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001407 int i, j;
1408 char c;
drhfeac5f82004-08-01 00:10:45 +00001409 for(i=j=0; (c = z[i])!=0; i++, j++){
1410 if( c=='\\' ){
1411 c = z[++i];
1412 if( c=='n' ){
1413 c = '\n';
1414 }else if( c=='t' ){
1415 c = '\t';
1416 }else if( c=='r' ){
1417 c = '\r';
1418 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001419 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001420 if( z[i+1]>='0' && z[i+1]<='7' ){
1421 i++;
1422 c = (c<<3) + z[i] - '0';
1423 if( z[i+1]>='0' && z[i+1]<='7' ){
1424 i++;
1425 c = (c<<3) + z[i] - '0';
1426 }
1427 }
1428 }
1429 }
1430 z[j] = c;
1431 }
1432 z[j] = 0;
1433}
1434
1435/*
drhc28490c2006-10-26 14:25:58 +00001436** Interpret zArg as a boolean value. Return either 0 or 1.
1437*/
1438static int booleanValue(char *zArg){
1439 int val = atoi(zArg);
1440 int j;
1441 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001442 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001443 }
1444 if( strcmp(zArg,"on")==0 ){
1445 val = 1;
1446 }else if( strcmp(zArg,"yes")==0 ){
1447 val = 1;
1448 }
1449 return val;
1450}
1451
1452/*
drh75897232000-05-29 14:26:00 +00001453** If an input line begins with "." then invoke this routine to
1454** process that line.
drh67505e72002-04-19 12:34:06 +00001455**
drh47ad6842006-11-08 12:25:42 +00001456** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001457*/
drh44c2eb12003-04-30 11:38:26 +00001458static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001459 int i = 1;
1460 int nArg = 0;
1461 int n, c;
drh67505e72002-04-19 12:34:06 +00001462 int rc = 0;
drh75897232000-05-29 14:26:00 +00001463 char *azArg[50];
1464
1465 /* Parse the input line into tokens.
1466 */
1467 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001468 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001469 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001470 if( zLine[i]=='\'' || zLine[i]=='"' ){
1471 int delim = zLine[i++];
1472 azArg[nArg++] = &zLine[i];
1473 while( zLine[i] && zLine[i]!=delim ){ i++; }
1474 if( zLine[i]==delim ){
1475 zLine[i++] = 0;
1476 }
drhfeac5f82004-08-01 00:10:45 +00001477 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001478 }else{
1479 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001480 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001481 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001482 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001483 }
1484 }
1485
1486 /* Process the input line.
1487 */
shane9bd1b442009-10-23 01:27:39 +00001488 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001489 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001490 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001491 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001492 const char *zDestFile;
1493 const char *zDb;
1494 sqlite3 *pDest;
1495 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001496 if( nArg==2 ){
1497 zDestFile = azArg[1];
1498 zDb = "main";
1499 }else{
1500 zDestFile = azArg[2];
1501 zDb = azArg[1];
1502 }
1503 rc = sqlite3_open(zDestFile, &pDest);
1504 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001505 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001506 sqlite3_close(pDest);
1507 return 1;
1508 }
drhdc2c4912009-02-04 22:46:47 +00001509 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001510 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1511 if( pBackup==0 ){
1512 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1513 sqlite3_close(pDest);
1514 return 1;
1515 }
1516 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1517 sqlite3_backup_finish(pBackup);
1518 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001519 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001520 }else{
1521 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001522 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001523 }
1524 sqlite3_close(pDest);
1525 }else
1526
shanehe2aa9d72009-11-06 17:20:17 +00001527 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001528 bail_on_error = booleanValue(azArg[1]);
1529 }else
1530
shanehe2aa9d72009-11-06 17:20:17 +00001531 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001532 struct callback_data data;
1533 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001534 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001535 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001536 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001537 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001538 data.colWidth[0] = 3;
1539 data.colWidth[1] = 15;
1540 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001541 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001542 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001543 if( zErrMsg ){
1544 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001545 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001546 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001547 }
1548 }else
1549
shanehe2aa9d72009-11-06 17:20:17 +00001550 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh4c653a02000-06-07 01:27:47 +00001551 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001552 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001553 /* When playing back a "dump", the content might appear in an order
1554 ** which causes immediate foreign key constraints to be violated.
1555 ** So disable foreign-key constraint enforcement to prevent problems. */
1556 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001557 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001558 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001559 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001560 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001561 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001562 "SELECT name, type, sql FROM sqlite_master "
drh4f324762009-05-21 14:51:03 +00001563 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1564 );
1565 run_schema_dump_query(p,
1566 "SELECT name, type, sql FROM sqlite_master "
1567 "WHERE name=='sqlite_sequence'", 0
drh0b9a5942006-09-13 20:22:02 +00001568 );
1569 run_table_dump_query(p->out, p->db,
1570 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001571 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001572 );
drh4c653a02000-06-07 01:27:47 +00001573 }else{
1574 int i;
drhdd3d4592004-08-30 01:54:05 +00001575 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001576 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001577 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001578 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001579 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001580 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001581 run_table_dump_query(p->out, p->db,
1582 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001583 "WHERE sql NOT NULL"
1584 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001585 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001586 );
danielk1977bc6ada42004-06-30 08:20:16 +00001587 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001588 }
1589 }
drh45e29d82006-11-20 16:21:10 +00001590 if( p->writableSchema ){
1591 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1592 p->writableSchema = 0;
1593 }
drh93f41e52008-08-11 19:12:34 +00001594 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001595 if( zErrMsg ){
1596 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001597 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001598 }else{
1599 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001600 }
1601 }else
drh75897232000-05-29 14:26:00 +00001602
shanehe2aa9d72009-11-06 17:20:17 +00001603 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001604 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001605 }else
1606
shanehe2aa9d72009-11-06 17:20:17 +00001607 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001608 rc = 2;
drh75897232000-05-29 14:26:00 +00001609 }else
1610
shanehe2aa9d72009-11-06 17:20:17 +00001611 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001612 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001613 if(val == 1) {
1614 if(!p->explainPrev.valid) {
1615 p->explainPrev.valid = 1;
1616 p->explainPrev.mode = p->mode;
1617 p->explainPrev.showHeader = p->showHeader;
1618 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1619 }
1620 /* We could put this code under the !p->explainValid
1621 ** condition so that it does not execute if we are already in
1622 ** explain mode. However, always executing it allows us an easy
1623 ** was to reset to explain mode in case the user previously
1624 ** did an .explain followed by a .width, .mode or .header
1625 ** command.
1626 */
danielk19770d78bae2008-01-03 07:09:48 +00001627 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001628 p->showHeader = 1;
1629 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001630 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001631 p->colWidth[1] = 13; /* opcode */
1632 p->colWidth[2] = 4; /* P1 */
1633 p->colWidth[3] = 4; /* P2 */
1634 p->colWidth[4] = 4; /* P3 */
1635 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001636 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001637 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001638 }else if (p->explainPrev.valid) {
1639 p->explainPrev.valid = 0;
1640 p->mode = p->explainPrev.mode;
1641 p->showHeader = p->explainPrev.showHeader;
1642 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1643 }
drh75897232000-05-29 14:26:00 +00001644 }else
1645
drhc28490c2006-10-26 14:25:58 +00001646 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001647 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001648 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001649 }else
1650
1651 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001652 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001653 if( HAS_TIMER ){
1654 fprintf(stderr,"%s",zTimerHelp);
1655 }
drh75897232000-05-29 14:26:00 +00001656 }else
1657
shanehe2aa9d72009-11-06 17:20:17 +00001658 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001659 char *zTable = azArg[2]; /* Insert data into this table */
1660 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001661 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001662 int nCol; /* Number of columns in the table */
1663 int nByte; /* Number of bytes in an SQL string */
1664 int i, j; /* Loop counters */
1665 int nSep; /* Number of bytes in p->separator[] */
1666 char *zSql; /* An SQL statement */
1667 char *zLine; /* A single line of input from the file */
1668 char **azCol; /* zLine[] broken up into columns */
1669 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001670 FILE *in; /* The input file */
1671 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001672
drha543c822006-06-08 16:10:14 +00001673 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001674 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001675 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001676 fprintf(stderr, "Error: non-null separator required for import\n");
1677 return 1;
drhfeac5f82004-08-01 00:10:45 +00001678 }
1679 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
shane916f9612009-10-23 00:37:15 +00001680 if( zSql==0 ){
1681 fprintf(stderr, "Error: out of memory\n");
1682 return 1;
1683 }
drh4f21c4a2008-12-10 22:15:00 +00001684 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001685 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001686 sqlite3_free(zSql);
1687 if( rc ){
shane916f9612009-10-23 00:37:15 +00001688 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001689 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001690 return 1;
drhfeac5f82004-08-01 00:10:45 +00001691 }
shane916f9612009-10-23 00:37:15 +00001692 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001693 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001694 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001695 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001696 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001697 if( zSql==0 ){
1698 fprintf(stderr, "Error: out of memory\n");
1699 return 1;
1700 }
drhfeac5f82004-08-01 00:10:45 +00001701 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001702 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001703 for(i=1; i<nCol; i++){
1704 zSql[j++] = ',';
1705 zSql[j++] = '?';
1706 }
1707 zSql[j++] = ')';
1708 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001709 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001710 free(zSql);
1711 if( rc ){
1712 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001713 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001714 return 1;
drhfeac5f82004-08-01 00:10:45 +00001715 }
1716 in = fopen(zFile, "rb");
1717 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001718 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001719 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001720 return 1;
drhfeac5f82004-08-01 00:10:45 +00001721 }
1722 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001723 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001724 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001725 fclose(in);
shane916f9612009-10-23 00:37:15 +00001726 sqlite3_finalize(pStmt);
1727 return 1;
drh43617e92006-03-06 20:55:46 +00001728 }
drhfeac5f82004-08-01 00:10:45 +00001729 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1730 zCommit = "COMMIT";
1731 while( (zLine = local_getline(0, in))!=0 ){
1732 char *z;
1733 i = 0;
drhb860bc92004-08-04 15:16:55 +00001734 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001735 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001736 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001737 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1738 *z = 0;
1739 i++;
drhb860bc92004-08-04 15:16:55 +00001740 if( i<nCol ){
1741 azCol[i] = &z[nSep];
1742 z += nSep-1;
1743 }
drhfeac5f82004-08-01 00:10:45 +00001744 }
shane916f9612009-10-23 00:37:15 +00001745 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001746 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001747 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001748 fprintf(stderr,
1749 "Error: %s line %d: expected %d columns of data but found %d\n",
1750 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001751 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001752 free(zLine);
shane916f9612009-10-23 00:37:15 +00001753 rc = 1;
1754 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001755 }
drhfeac5f82004-08-01 00:10:45 +00001756 for(i=0; i<nCol; i++){
1757 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1758 }
1759 sqlite3_step(pStmt);
1760 rc = sqlite3_reset(pStmt);
1761 free(zLine);
1762 if( rc!=SQLITE_OK ){
1763 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1764 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001765 rc = 1;
shane916f9612009-10-23 00:37:15 +00001766 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001767 }
shane916f9612009-10-23 00:37:15 +00001768 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001769 free(azCol);
1770 fclose(in);
1771 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001772 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001773 }else
1774
shanehe2aa9d72009-11-06 17:20:17 +00001775 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001776 struct callback_data data;
1777 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001778 open_db(p);
drh75897232000-05-29 14:26:00 +00001779 memcpy(&data, p, sizeof(data));
1780 data.showHeader = 0;
1781 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001782 if( nArg==1 ){
1783 rc = sqlite3_exec(p->db,
1784 "SELECT name FROM sqlite_master "
1785 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1786 "UNION ALL "
1787 "SELECT name FROM sqlite_temp_master "
1788 "WHERE type='index' "
1789 "ORDER BY 1",
1790 callback, &data, &zErrMsg
1791 );
1792 }else{
1793 zShellStatic = azArg[1];
1794 rc = sqlite3_exec(p->db,
1795 "SELECT name FROM sqlite_master "
1796 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1797 "UNION ALL "
1798 "SELECT name FROM sqlite_temp_master "
1799 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1800 "ORDER BY 1",
1801 callback, &data, &zErrMsg
1802 );
1803 zShellStatic = 0;
1804 }
drh75897232000-05-29 14:26:00 +00001805 if( zErrMsg ){
1806 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001807 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001808 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001809 }else if( rc != SQLITE_OK ){
1810 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1811 rc = 1;
drh75897232000-05-29 14:26:00 +00001812 }
1813 }else
1814
drhae5e4452007-05-03 17:18:36 +00001815#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001816 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001817 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001818 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1819 iotrace = 0;
1820 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001821 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001822 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001823 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001824 iotrace = stdout;
1825 }else{
1826 iotrace = fopen(azArg[1], "w");
1827 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001828 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001829 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001830 rc = 1;
drhb0603412007-02-28 04:47:26 +00001831 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001832 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001833 }
1834 }
1835 }else
drhae5e4452007-05-03 17:18:36 +00001836#endif
drhb0603412007-02-28 04:47:26 +00001837
drh70df4fe2006-06-13 15:12:21 +00001838#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001839 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1840 const char *zFile, *zProc;
1841 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001842 zFile = azArg[1];
1843 zProc = nArg>=3 ? azArg[2] : 0;
1844 open_db(p);
1845 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1846 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001847 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001848 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001849 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001850 }
1851 }else
drh70df4fe2006-06-13 15:12:21 +00001852#endif
drh1e397f82006-06-08 15:28:43 +00001853
drh127f9d72010-02-23 01:47:00 +00001854 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=1 ){
1855 const char *zFile = azArg[1];
1856 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1857 fclose(p->pLog);
1858 p->pLog = 0;
1859 }
1860 if( strcmp(zFile,"stdout")==0 ){
1861 p->pLog = stdout;
1862 }else if( strcmp(zFile, "stderr")==0 ){
1863 p->pLog = stderr;
1864 }else if( strcmp(zFile, "off")==0 ){
1865 p->pLog = 0;
1866 }else{
1867 p->pLog = fopen(zFile, "w");
1868 if( p->pLog==0 ){
1869 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1870 }
1871 }
1872 }else
1873
shanehe2aa9d72009-11-06 17:20:17 +00001874 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001875 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001876 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001877 ||
shanehe2aa9d72009-11-06 17:20:17 +00001878 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001879 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001880 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001881 ||
shanehe2aa9d72009-11-06 17:20:17 +00001882 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001883 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001884 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001885 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001886 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001887 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001888 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001889 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001890 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001891 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001892 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001893 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001894 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001895 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001896 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001897 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001898 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001899 }else {
shane9bd1b442009-10-23 01:27:39 +00001900 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001901 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001902 rc = 1;
drh75897232000-05-29 14:26:00 +00001903 }
1904 }else
1905
shanehe2aa9d72009-11-06 17:20:17 +00001906 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1907 int n2 = strlen30(azArg[1]);
1908 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1909 p->mode = MODE_Insert;
1910 set_table_name(p, azArg[2]);
1911 }else {
1912 fprintf(stderr, "Error: invalid arguments: "
1913 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1914 rc = 1;
1915 }
1916 }else
1917
persicom7e2dfdd2002-04-18 02:46:52 +00001918 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001919 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1920 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001921 }else
1922
drh75897232000-05-29 14:26:00 +00001923 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1924 if( p->out!=stdout ){
1925 fclose(p->out);
1926 }
1927 if( strcmp(azArg[1],"stdout")==0 ){
1928 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001929 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001930 }else{
drha1f9b5e2004-02-14 16:31:02 +00001931 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001932 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00001933 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00001934 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00001935 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001936 } else {
drh5bb3eb92007-05-04 13:15:55 +00001937 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001938 }
1939 }
1940 }else
1941
drhdd45df82002-04-18 12:39:03 +00001942 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001943 if( nArg >= 2) {
1944 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1945 }
1946 if( nArg >= 3) {
1947 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1948 }
1949 }else
1950
shanehe2aa9d72009-11-06 17:20:17 +00001951 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001952 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001953 }else
1954
drh9ff849f2009-02-04 20:55:57 +00001955 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001956 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001957 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00001958 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1959 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00001960 }else{
shane9bd1b442009-10-23 01:27:39 +00001961 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00001962 fclose(alt);
1963 }
1964 }else
1965
shanehe2aa9d72009-11-06 17:20:17 +00001966 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001967 const char *zSrcFile;
1968 const char *zDb;
1969 sqlite3 *pSrc;
1970 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00001971 int nTimeout = 0;
1972
drh9ff849f2009-02-04 20:55:57 +00001973 if( nArg==2 ){
1974 zSrcFile = azArg[1];
1975 zDb = "main";
1976 }else{
1977 zSrcFile = azArg[2];
1978 zDb = azArg[1];
1979 }
1980 rc = sqlite3_open(zSrcFile, &pSrc);
1981 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001982 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00001983 sqlite3_close(pSrc);
1984 return 1;
1985 }
drhdc2c4912009-02-04 22:46:47 +00001986 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001987 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
1988 if( pBackup==0 ){
1989 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1990 sqlite3_close(pSrc);
1991 return 1;
1992 }
drhdc2c4912009-02-04 22:46:47 +00001993 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
1994 || rc==SQLITE_BUSY ){
1995 if( rc==SQLITE_BUSY ){
1996 if( nTimeout++ >= 3 ) break;
1997 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00001998 }
1999 }
2000 sqlite3_backup_finish(pBackup);
2001 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002002 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002003 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002004 fprintf(stderr, "Error: source database is busy\n");
2005 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002006 }else{
2007 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002008 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002009 }
2010 sqlite3_close(pSrc);
2011 }else
2012
shanehe2aa9d72009-11-06 17:20:17 +00002013 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002014 struct callback_data data;
2015 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002016 open_db(p);
drh75897232000-05-29 14:26:00 +00002017 memcpy(&data, p, sizeof(data));
2018 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002019 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002020 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002021 int i;
shane7d3846a2008-12-11 02:58:26 +00002022 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002023 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002024 char *new_argv[2], *new_colv[2];
2025 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2026 " type text,\n"
2027 " name text,\n"
2028 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002029 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002030 " sql text\n"
2031 ")";
2032 new_argv[1] = 0;
2033 new_colv[0] = "sql";
2034 new_colv[1] = 0;
2035 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002036 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002037 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002038 char *new_argv[2], *new_colv[2];
2039 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2040 " type text,\n"
2041 " name text,\n"
2042 " tbl_name text,\n"
2043 " rootpage integer,\n"
2044 " sql text\n"
2045 ")";
2046 new_argv[1] = 0;
2047 new_colv[0] = "sql";
2048 new_colv[1] = 0;
2049 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002050 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002051 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002052 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002053 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002054 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002055 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2056 " FROM sqlite_master UNION ALL"
2057 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00002058 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002059 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002060 callback, &data, &zErrMsg);
2061 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002062 }
drh75897232000-05-29 14:26:00 +00002063 }else{
shane9bd1b442009-10-23 01:27:39 +00002064 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002065 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002066 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2067 " FROM sqlite_master UNION ALL"
2068 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002069 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002070 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002071 callback, &data, &zErrMsg
2072 );
drh75897232000-05-29 14:26:00 +00002073 }
drh75897232000-05-29 14:26:00 +00002074 if( zErrMsg ){
2075 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002076 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002077 rc = 1;
2078 }else if( rc != SQLITE_OK ){
2079 fprintf(stderr,"Error: querying schema information\n");
2080 rc = 1;
2081 }else{
2082 rc = 0;
drh75897232000-05-29 14:26:00 +00002083 }
2084 }else
2085
2086 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002087 sqlite3_snprintf(sizeof(p->separator), p->separator,
2088 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002089 }else
2090
shanehe2aa9d72009-11-06 17:20:17 +00002091 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002092 int i;
2093 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002094 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002095 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002096 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002097 fprintf(p->out,"%9.9s: ", "nullvalue");
2098 output_c_string(p->out, p->nullvalue);
2099 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002100 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002101 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002102 fprintf(p->out,"%9.9s: ", "separator");
2103 output_c_string(p->out, p->separator);
2104 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002105 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002106 fprintf(p->out,"%9.9s: ","width");
2107 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002108 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002109 }
drhfeac5f82004-08-01 00:10:45 +00002110 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002111 }else
2112
shaneh642d8b82010-07-28 16:05:34 +00002113 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2114 p->statsOn = booleanValue(azArg[1]);
2115 }else
2116
shanehe2aa9d72009-11-06 17:20:17 +00002117 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002118 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002119 int nRow;
drhe3710332000-09-29 13:30:53 +00002120 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002121 open_db(p);
drha50da102000-08-08 20:19:09 +00002122 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002123 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002124 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002125 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002126 "UNION ALL "
2127 "SELECT name FROM sqlite_temp_master "
2128 "WHERE type IN ('table','view') "
2129 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002130 &azResult, &nRow, 0, &zErrMsg
2131 );
drha50da102000-08-08 20:19:09 +00002132 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002133 zShellStatic = azArg[1];
2134 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002135 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002136 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002137 "UNION ALL "
2138 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002139 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002140 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002141 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002142 );
danielk1977bc6ada42004-06-30 08:20:16 +00002143 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002144 }
drh75897232000-05-29 14:26:00 +00002145 if( zErrMsg ){
2146 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002147 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002148 rc = 1;
2149 }else if( rc != SQLITE_OK ){
2150 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2151 rc = 1;
2152 }else{
drhe3710332000-09-29 13:30:53 +00002153 int len, maxlen = 0;
2154 int i, j;
2155 int nPrintCol, nPrintRow;
2156 for(i=1; i<=nRow; i++){
2157 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002158 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002159 if( len>maxlen ) maxlen = len;
2160 }
2161 nPrintCol = 80/(maxlen+2);
2162 if( nPrintCol<1 ) nPrintCol = 1;
2163 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2164 for(i=0; i<nPrintRow; i++){
2165 for(j=i+1; j<=nRow; j+=nPrintRow){
2166 char *zSp = j<=nPrintRow ? "" : " ";
2167 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2168 }
2169 printf("\n");
2170 }
2171 }
danielk19776f8a5032004-05-10 10:34:51 +00002172 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002173 }else
2174
shaneh96887e12011-02-10 21:08:58 +00002175 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
2176 int testctrl = -1;
2177 int rc = 0;
2178 open_db(p);
2179
2180 /* convert testctrl text option to value. allow only the first
2181 ** three characters of the option to be used or the numerical
2182 ** value. */
2183 if( strncmp( azArg[1], "prng_save", 6 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_SAVE;
2184 else if( strncmp( azArg[1], "prng_restore", 10 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_RESTORE;
2185 else if( strncmp( azArg[1], "prng_reset", 10 )==0 ) testctrl = SQLITE_TESTCTRL_PRNG_RESET;
2186 else if( strncmp( azArg[1], "bitvec_test", 6 )==3 ) testctrl = SQLITE_TESTCTRL_BITVEC_TEST;
2187 else if( strncmp( azArg[1], "fault_install", 6 )==3 ) testctrl = SQLITE_TESTCTRL_FAULT_INSTALL;
2188 else if( strncmp( azArg[1], "benign_malloc_hooks", 3 )==0 ) testctrl = SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS;
2189 else if( strncmp( azArg[1], "pending_byte", 3 )==0 ) testctrl = SQLITE_TESTCTRL_PENDING_BYTE;
2190 else if( strncmp( azArg[1], "assert", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ASSERT;
2191 else if( strncmp( azArg[1], "always", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ALWAYS;
2192 else if( strncmp( azArg[1], "reserve", 3 )==0 ) testctrl = SQLITE_TESTCTRL_RESERVE;
2193 else if( strncmp( azArg[1], "optimizations", 3 )==0 ) testctrl = SQLITE_TESTCTRL_OPTIMIZATIONS;
2194 else if( strncmp( azArg[1], "iskeyword", 3 )==0 ) testctrl = SQLITE_TESTCTRL_ISKEYWORD;
2195 else if( strncmp( azArg[1], "pghdrsz", 3 )==0 ) testctrl = SQLITE_TESTCTRL_PGHDRSZ;
2196 else if( strncmp( azArg[1], "scratchmalloc", 3 )==0 ) testctrl = SQLITE_TESTCTRL_SCRATCHMALLOC;
2197 else testctrl = atoi(azArg[1]);
2198
2199 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2200 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2201 }else{
2202 switch(testctrl){
2203
2204 /* sqlite3_test_control(int, db, int) */
2205 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2206 case SQLITE_TESTCTRL_RESERVE:
2207 if( nArg==3 ){
2208 int opt = (int)strtol(azArg[2], 0, 0);
2209 rc = sqlite3_test_control(testctrl, p->db, opt);
2210 printf("%d (0x%08x)\n", rc, rc);
2211 } else {
2212 fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]);
2213 }
2214 break;
2215
2216 /* sqlite3_test_control(int) */
2217 case SQLITE_TESTCTRL_PRNG_SAVE:
2218 case SQLITE_TESTCTRL_PRNG_RESTORE:
2219 case SQLITE_TESTCTRL_PRNG_RESET:
2220 case SQLITE_TESTCTRL_PGHDRSZ:
2221 if( nArg==2 ){
2222 rc = sqlite3_test_control(testctrl);
2223 printf("%d (0x%08x)\n", rc, rc);
2224 } else {
2225 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2226 }
2227 break;
2228
2229 /* sqlite3_test_control(int, uint) */
2230 case SQLITE_TESTCTRL_PENDING_BYTE:
2231 if( nArg==3 ){
2232 unsigned int opt = (unsigned int)atoi(azArg[2]);
2233 rc = sqlite3_test_control(testctrl, opt);
2234 printf("%d (0x%08x)\n", rc, rc);
2235 } else {
2236 fprintf(stderr,"Error: testctrl %s takes a single unsigned int option\n", azArg[1]);
2237 }
2238 break;
2239
2240 /* sqlite3_test_control(int, int) */
2241 case SQLITE_TESTCTRL_ASSERT:
2242 case SQLITE_TESTCTRL_ALWAYS:
2243 if( nArg==3 ){
2244 int opt = atoi(azArg[2]);
2245 rc = sqlite3_test_control(testctrl, opt);
2246 printf("%d (0x%08x)\n", rc, rc);
2247 } else {
2248 fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]);
2249 }
2250 break;
2251
2252 /* sqlite3_test_control(int, char *) */
2253#ifdef SQLITE_N_KEYWORD
2254 case SQLITE_TESTCTRL_ISKEYWORD:
2255 if( nArg==3 ){
2256 const char *opt = azArg[2];
2257 rc = sqlite3_test_control(testctrl, opt);
2258 printf("%d (0x%08x)\n", rc, rc);
2259 } else {
2260 fprintf(stderr,"Error: testctrl %s takes a single char * option\n", azArg[1]);
2261 }
2262 break;
2263#endif
2264
2265 case SQLITE_TESTCTRL_BITVEC_TEST:
2266 case SQLITE_TESTCTRL_FAULT_INSTALL:
2267 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2268 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2269 default:
2270 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", azArg[1]);
2271 break;
2272 }
2273 }
2274 }else
2275
shanehe2aa9d72009-11-06 17:20:17 +00002276 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002277 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002278 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002279 }else
2280
2281 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
drh3b1a9882007-11-02 12:53:03 +00002282 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002283 }else
2284
2285 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002286 int j;
drh43617e92006-03-06 20:55:46 +00002287 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002288 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2289 p->colWidth[j-1] = atoi(azArg[j]);
2290 }
2291 }else
2292
2293 {
shane9bd1b442009-10-23 01:27:39 +00002294 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002295 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002296 rc = 1;
drh75897232000-05-29 14:26:00 +00002297 }
drh67505e72002-04-19 12:34:06 +00002298
2299 return rc;
drh75897232000-05-29 14:26:00 +00002300}
2301
drh67505e72002-04-19 12:34:06 +00002302/*
drh91a66392007-09-07 01:12:32 +00002303** Return TRUE if a semicolon occurs anywhere in the first N characters
2304** of string z[].
drh324ccef2003-02-05 14:06:20 +00002305*/
drh91a66392007-09-07 01:12:32 +00002306static int _contains_semicolon(const char *z, int N){
2307 int i;
2308 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2309 return 0;
drh324ccef2003-02-05 14:06:20 +00002310}
2311
2312/*
drh70c7a4b2003-04-26 03:03:06 +00002313** Test to see if a line consists entirely of whitespace.
2314*/
2315static int _all_whitespace(const char *z){
2316 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00002317 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002318 if( *z=='/' && z[1]=='*' ){
2319 z += 2;
2320 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2321 if( *z==0 ) return 0;
2322 z++;
2323 continue;
2324 }
2325 if( *z=='-' && z[1]=='-' ){
2326 z += 2;
2327 while( *z && *z!='\n' ){ z++; }
2328 if( *z==0 ) return 1;
2329 continue;
2330 }
2331 return 0;
2332 }
2333 return 1;
2334}
2335
2336/*
drha9b17162003-04-29 18:01:28 +00002337** Return TRUE if the line typed in is an SQL command terminator other
2338** than a semi-colon. The SQL Server style "go" command is understood
2339** as is the Oracle "/".
2340*/
2341static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00002342 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002343 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2344 return 1; /* Oracle */
2345 }
drhc8d74412004-08-31 23:41:26 +00002346 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2347 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002348 return 1; /* SQL Server */
2349 }
2350 return 0;
2351}
2352
2353/*
drh233a5312008-12-18 22:25:13 +00002354** Return true if zSql is a complete SQL statement. Return false if it
2355** ends in the middle of a string literal or C-style comment.
2356*/
2357static int _is_complete(char *zSql, int nSql){
2358 int rc;
2359 if( zSql==0 ) return 1;
2360 zSql[nSql] = ';';
2361 zSql[nSql+1] = 0;
2362 rc = sqlite3_complete(zSql);
2363 zSql[nSql] = 0;
2364 return rc;
2365}
2366
2367/*
drh67505e72002-04-19 12:34:06 +00002368** Read input from *in and process it. If *in==0 then input
2369** is interactive - the user is typing it it. Otherwise, input
2370** is coming from a file or device. A prompt is issued and history
2371** is saved only if input is interactive. An interrupt signal will
2372** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002373**
2374** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002375*/
drhc28490c2006-10-26 14:25:58 +00002376static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002377 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002378 char *zSql = 0;
2379 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002380 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002381 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002382 int rc;
2383 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002384 int lineno = 0;
2385 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002386
2387 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2388 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002389 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002390 zLine = one_input_line(zSql, in);
2391 if( zLine==0 ){
2392 break; /* We have reached EOF */
2393 }
drh67505e72002-04-19 12:34:06 +00002394 if( seenInterrupt ){
2395 if( in!=0 ) break;
2396 seenInterrupt = 0;
2397 }
drhc28490c2006-10-26 14:25:58 +00002398 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002399 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002400 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002401 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002402 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002403 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002404 break;
2405 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002406 errCnt++;
2407 }
drhdaffd0e2001-04-11 14:28:42 +00002408 continue;
2409 }
drh233a5312008-12-18 22:25:13 +00002410 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002411 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002412 }
drh91a66392007-09-07 01:12:32 +00002413 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002414 if( zSql==0 ){
2415 int i;
drh4c755c02004-08-08 20:22:17 +00002416 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002417 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002418 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002419 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002420 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002421 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002422 exit(1);
2423 }
drh5bb3eb92007-05-04 13:15:55 +00002424 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002425 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002426 }
2427 }else{
drh4f21c4a2008-12-10 22:15:00 +00002428 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002429 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002430 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002431 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002432 exit(1);
2433 }
drh5bb3eb92007-05-04 13:15:55 +00002434 zSql[nSql++] = '\n';
2435 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002436 nSql += len;
2437 }
drh91a66392007-09-07 01:12:32 +00002438 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2439 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002440 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002441 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002442 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002443 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002444 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002445 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002446 char zPrefix[100];
2447 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002448 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002449 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002450 }else{
shane9bd1b442009-10-23 01:27:39 +00002451 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002452 }
drh7f953e22002-07-13 17:33:45 +00002453 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002454 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002455 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002456 zErrMsg = 0;
2457 }else{
shaned2bed1c2009-10-21 03:56:54 +00002458 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002459 }
drhc49f44e2006-10-26 18:15:42 +00002460 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002461 }
2462 free(zSql);
2463 zSql = 0;
2464 nSql = 0;
2465 }
2466 }
2467 if( zSql ){
shane86f5bdb2009-10-24 02:00:07 +00002468 if( !_all_whitespace(zSql) ) fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00002469 free(zSql);
2470 }
danielk19772ac27622007-07-03 05:31:16 +00002471 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002472 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002473}
2474
drh67505e72002-04-19 12:34:06 +00002475/*
2476** Return a pathname which is the user's home directory. A
2477** 0 return indicates an error of some kind. Space to hold the
2478** resulting string is obtained from malloc(). The calling
2479** function should free the result.
2480*/
2481static char *find_home_dir(void){
2482 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002483
chw97185482008-11-17 08:05:31 +00002484#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002485 struct passwd *pwent;
2486 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002487 if( (pwent=getpwuid(uid)) != NULL) {
2488 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002489 }
2490#endif
2491
chw65d3c132007-11-12 21:09:10 +00002492#if defined(_WIN32_WCE)
2493 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2494 */
2495 home_dir = strdup("/");
2496#else
2497
drh164a1b62006-08-19 11:15:20 +00002498#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2499 if (!home_dir) {
2500 home_dir = getenv("USERPROFILE");
2501 }
2502#endif
2503
drh67505e72002-04-19 12:34:06 +00002504 if (!home_dir) {
2505 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002506 }
2507
drhcdb36b72006-06-12 12:57:45 +00002508#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002509 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002510 char *zDrive, *zPath;
2511 int n;
2512 zDrive = getenv("HOMEDRIVE");
2513 zPath = getenv("HOMEPATH");
2514 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002515 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002516 home_dir = malloc( n );
2517 if( home_dir==0 ) return 0;
2518 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2519 return home_dir;
2520 }
2521 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002522 }
2523#endif
2524
chw65d3c132007-11-12 21:09:10 +00002525#endif /* !_WIN32_WCE */
2526
drh67505e72002-04-19 12:34:06 +00002527 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002528 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002529 char *z = malloc( n );
2530 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002531 home_dir = z;
2532 }
drhe98d4fa2002-04-21 19:06:22 +00002533
drh67505e72002-04-19 12:34:06 +00002534 return home_dir;
2535}
2536
2537/*
2538** Read input from the file given by sqliterc_override. Or if that
2539** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002540**
2541** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002542*/
shane9bd1b442009-10-23 01:27:39 +00002543static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002544 struct callback_data *p, /* Configuration data */
2545 const char *sqliterc_override /* Name of config file. NULL to use default */
2546){
persicom7e2dfdd2002-04-18 02:46:52 +00002547 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002548 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002549 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002550 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002551 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002552 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002553
2554 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002555 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002556 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002557#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002558 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002559#endif
shane9bd1b442009-10-23 01:27:39 +00002560 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002561 }
drh4f21c4a2008-12-10 22:15:00 +00002562 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002563 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002564 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002565 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2566 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002567 }
drha959ac42007-06-20 13:10:00 +00002568 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002569 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002570 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002571 }
drha1f9b5e2004-02-14 16:31:02 +00002572 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002573 if( in ){
drhc28490c2006-10-26 14:25:58 +00002574 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002575 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002576 }
shane9bd1b442009-10-23 01:27:39 +00002577 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002578 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002579 }
drh43617e92006-03-06 20:55:46 +00002580 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002581 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002582}
2583
drh67505e72002-04-19 12:34:06 +00002584/*
drhe1e38c42003-05-04 18:30:59 +00002585** Show available command line options
2586*/
2587static const char zOptions[] =
shaneh5fc25012009-11-11 04:17:07 +00002588 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002589 " -init filename read/process named file\n"
2590 " -echo print commands before execution\n"
2591 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002592 " -bail stop after hitting an error\n"
2593 " -interactive force interactive I/O\n"
2594 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002595 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002596 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002597 " -html set output mode to HTML\n"
2598 " -line set output mode to 'line'\n"
2599 " -list set output mode to 'list'\n"
2600 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002601 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002602 " -nullvalue 'text' set text string for NULL values\n"
2603 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002604 " -vfs NAME use NAME as the default VFS\n"
drhe1e38c42003-05-04 18:30:59 +00002605;
2606static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002607 fprintf(stderr,
2608 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2609 "FILENAME is the name of an SQLite database. A new database is created\n"
2610 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002611 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002612 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002613 }else{
2614 fprintf(stderr, "Use the -help option for additional information\n");
2615 }
2616 exit(1);
2617}
2618
2619/*
drh67505e72002-04-19 12:34:06 +00002620** Initialize the state information in data
2621*/
drh0850b532006-01-31 19:31:43 +00002622static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002623 memset(data, 0, sizeof(*data));
2624 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002625 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002626 data->showHeader = 0;
drh127f9d72010-02-23 01:47:00 +00002627 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002628 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2629 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002630 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002631}
2632
drh75897232000-05-29 14:26:00 +00002633int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002634 char *zErrMsg = 0;
2635 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002636 const char *zInitFile = 0;
2637 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002638 int i;
drhc28490c2006-10-26 14:25:58 +00002639 int rc = 0;
drh75897232000-05-29 14:26:00 +00002640
drhdaffd0e2001-04-11 14:28:42 +00002641 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002642 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002643 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002644
drh44c2eb12003-04-30 11:38:26 +00002645 /* Make sure we have a valid signal handler early, before anything
2646 ** else is done.
2647 */
drh4c504392000-10-16 22:06:40 +00002648#ifdef SIGINT
2649 signal(SIGINT, interrupt_handler);
2650#endif
drh44c2eb12003-04-30 11:38:26 +00002651
drh22fbcb82004-02-01 01:22:50 +00002652 /* Do an initial pass through the command-line argument to locate
2653 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002654 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002655 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002656 */
drh22fbcb82004-02-01 01:22:50 +00002657 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002658 char *z;
drh44c2eb12003-04-30 11:38:26 +00002659 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002660 z = argv[i];
2661 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002662 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2663 i++;
drh22fbcb82004-02-01 01:22:50 +00002664 }else if( strcmp(argv[i],"-init")==0 ){
2665 i++;
2666 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002667 /* Need to check for batch mode here to so we can avoid printing
2668 ** informational messages (like from process_sqliterc) before
2669 ** we do the actual processing of arguments later in a second pass.
2670 */
2671 }else if( strcmp(argv[i],"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002672 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002673 }else if( strcmp(argv[i],"-heap")==0 ){
2674 int j, c;
2675 const char *zSize;
2676 sqlite3_int64 szHeap;
2677
2678 zSize = argv[++i];
2679 szHeap = atoi(zSize);
2680 for(j=0; (c = zSize[j])!=0; j++){
2681 if( c=='M' ){ szHeap *= 1000000; break; }
2682 if( c=='K' ){ szHeap *= 1000; break; }
2683 if( c=='G' ){ szHeap *= 1000000000; break; }
2684 }
2685 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
2686#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2687 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2688#endif
drha7e61d82011-03-12 17:02:57 +00002689 }else if( strcmp(argv[i],"-vfs")==0 ){
drh77ec9ba2011-03-15 18:35:44 +00002690 sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
drha7e61d82011-03-12 17:02:57 +00002691 if( pVfs ){
2692 sqlite3_vfs_register(pVfs, 1);
2693 }else{
2694 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
2695 exit(1);
2696 }
drh44c2eb12003-04-30 11:38:26 +00002697 }
2698 }
drh22fbcb82004-02-01 01:22:50 +00002699 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002700#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002701 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2702#else
drh22fbcb82004-02-01 01:22:50 +00002703 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002704#endif
drh22fbcb82004-02-01 01:22:50 +00002705 }else{
danielk197703aded42004-11-22 05:26:27 +00002706#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002707 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002708#else
2709 data.zDbFilename = 0;
2710#endif
drh22fbcb82004-02-01 01:22:50 +00002711 }
2712 if( i<argc ){
2713 zFirstCmd = argv[i++];
2714 }
shaneh5fc25012009-11-11 04:17:07 +00002715 if( i<argc ){
2716 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2717 fprintf(stderr,"Use -help for a list of options.\n");
2718 return 1;
2719 }
drh44c2eb12003-04-30 11:38:26 +00002720 data.out = stdout;
2721
drh01b41712005-08-29 23:06:23 +00002722#ifdef SQLITE_OMIT_MEMORYDB
2723 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002724 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2725 return 1;
drh01b41712005-08-29 23:06:23 +00002726 }
2727#endif
2728
drh44c2eb12003-04-30 11:38:26 +00002729 /* Go ahead and open the database file if it already exists. If the
2730 ** file does not exist, delay opening it. This prevents empty database
2731 ** files from being created if a user mistypes the database name argument
2732 ** to the sqlite command-line tool.
2733 */
drhc8d74412004-08-31 23:41:26 +00002734 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002735 open_db(&data);
2736 }
2737
drh22fbcb82004-02-01 01:22:50 +00002738 /* Process the initialization file if there is one. If no -init option
2739 ** is given on the command line, look for a file named ~/.sqliterc and
2740 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002741 */
shane86f5bdb2009-10-24 02:00:07 +00002742 rc = process_sqliterc(&data,zInitFile);
2743 if( rc>0 ){
2744 return rc;
2745 }
drh44c2eb12003-04-30 11:38:26 +00002746
drh22fbcb82004-02-01 01:22:50 +00002747 /* Make a second pass through the command-line argument and set
2748 ** options. This second pass is delayed until after the initialization
2749 ** file is processed so that the command-line arguments will override
2750 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002751 */
drh22fbcb82004-02-01 01:22:50 +00002752 for(i=1; i<argc && argv[i][0]=='-'; i++){
2753 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002754 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002755 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002756 i++;
2757 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002758 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002759 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002760 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002761 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002762 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002763 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002764 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002765 }else if( strcmp(z,"-csv")==0 ){
2766 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002767 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002768 }else if( strcmp(z,"-separator")==0 ){
2769 i++;
shaneh5fc25012009-11-11 04:17:07 +00002770 if(i>=argc){
2771 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2772 fprintf(stderr,"Use -help for a list of options.\n");
2773 return 1;
2774 }
drh5bb3eb92007-05-04 13:15:55 +00002775 sqlite3_snprintf(sizeof(data.separator), data.separator,
2776 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002777 }else if( strcmp(z,"-nullvalue")==0 ){
2778 i++;
shaneh5fc25012009-11-11 04:17:07 +00002779 if(i>=argc){
2780 fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z);
2781 fprintf(stderr,"Use -help for a list of options.\n");
2782 return 1;
2783 }
drh5bb3eb92007-05-04 13:15:55 +00002784 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2785 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002786 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002787 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002788 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002789 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002790 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002791 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00002792 }else if( strcmp(z,"-stats")==0 ){
2793 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002794 }else if( strcmp(z,"-bail")==0 ){
2795 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002796 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002797 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002798 return 0;
drhc28490c2006-10-26 14:25:58 +00002799 }else if( strcmp(z,"-interactive")==0 ){
2800 stdin_is_interactive = 1;
2801 }else if( strcmp(z,"-batch")==0 ){
2802 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002803 }else if( strcmp(z,"-heap")==0 ){
2804 i++;
drha7e61d82011-03-12 17:02:57 +00002805 }else if( strcmp(z,"-vfs")==0 ){
2806 i++;
drh80e8be92006-08-29 12:04:19 +00002807 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002808 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002809 }else{
shane86f5bdb2009-10-24 02:00:07 +00002810 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002811 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002812 return 1;
2813 }
2814 }
drh44c2eb12003-04-30 11:38:26 +00002815
drh22fbcb82004-02-01 01:22:50 +00002816 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002817 /* Run just the command that follows the database name
2818 */
drh22fbcb82004-02-01 01:22:50 +00002819 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00002820 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002821 }else{
drh44c2eb12003-04-30 11:38:26 +00002822 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00002823 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00002824 if( zErrMsg!=0 ){
2825 fprintf(stderr,"Error: %s\n", zErrMsg);
2826 return rc!=0 ? rc : 1;
2827 }else if( rc!=0 ){
2828 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
2829 return rc;
drh6ff13852001-11-25 13:18:23 +00002830 }
drh75897232000-05-29 14:26:00 +00002831 }
2832 }else{
drh44c2eb12003-04-30 11:38:26 +00002833 /* Run commands received from standard input
2834 */
drhc28490c2006-10-26 14:25:58 +00002835 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002836 char *zHome;
2837 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002838 int nHistory;
drh75897232000-05-29 14:26:00 +00002839 printf(
drhb217a572000-08-22 13:40:18 +00002840 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002841 "Enter \".help\" for instructions\n"
2842 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002843 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002844 );
drh67505e72002-04-19 12:34:06 +00002845 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002846 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002847 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002848 if( (zHistory = malloc(nHistory))!=0 ){
2849 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2850 }
drh67505e72002-04-19 12:34:06 +00002851 }
danielk19774af00c62005-01-23 23:43:21 +00002852#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002853 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002854#endif
drhc28490c2006-10-26 14:25:58 +00002855 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002856 if( zHistory ){
2857 stifle_history(100);
2858 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002859 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002860 }
adamd0a3daa32006-07-28 20:16:14 +00002861 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002862 }else{
drhc28490c2006-10-26 14:25:58 +00002863 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002864 }
2865 }
drh33048c02001-10-01 14:29:22 +00002866 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00002867 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00002868 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00002869 }
drhc28490c2006-10-26 14:25:58 +00002870 return rc;
drh75897232000-05-29 14:26:00 +00002871}