blob: d3ddfa95360758a0ffa1e15120f9124c9907937c [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
21** Enable large-file support for fopen() and friends on unix.
22*/
23#ifndef SQLITE_DISABLE_LFS
24# define _LARGE_FILE 1
25# ifndef _FILE_OFFSET_BITS
26# define _FILE_OFFSET_BITS 64
27# endif
28# define _LARGEFILE_SOURCE 1
29#endif
30
drh75897232000-05-29 14:26:00 +000031#include <stdlib.h>
32#include <string.h>
33#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000034#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000035#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000036#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000037#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000038
drh454ad582007-11-26 22:54:27 +000039#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000040# include <signal.h>
chw97185482008-11-17 08:05:31 +000041# if !defined(__RTP__) && !defined(_WRS_KERNEL)
42# include <pwd.h>
43# endif
drhdd45df82002-04-18 12:39:03 +000044# include <unistd.h>
45# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000046#endif
drh75897232000-05-29 14:26:00 +000047
drhcdb36b72006-06-12 12:57:45 +000048#ifdef __OS2__
49# include <unistd.h>
50#endif
51
drh81d7fd12010-12-08 00:02:26 +000052#ifdef HAVE_EDITLINE
53# include <editline/editline.h>
54#endif
drh16e59552000-07-31 11:57:37 +000055#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000056# include <readline/readline.h>
57# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000058#endif
59#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
drh18f52e02012-01-16 16:56:31 +000060# define readline(p) local_getline(p,stdin,0)
persicom1d0b8722002-04-18 02:53:04 +000061# define add_history(X)
drh67505e72002-04-19 12:34:06 +000062# define read_history(X)
63# define write_history(X)
64# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000065#endif
66
adamd2e8464a2006-09-06 21:39:40 +000067#if defined(_WIN32) || defined(WIN32)
68# include <io.h>
shane18e526c2008-12-10 22:30:24 +000069#define isatty(h) _isatty(h)
70#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000071#else
drh4328c8b2003-04-26 02:50:11 +000072/* Make sure isatty() has a prototype.
73*/
drhb2acc3b2011-10-13 16:36:29 +000074extern int isatty(int);
adamd2e8464a2006-09-06 21:39:40 +000075#endif
drh4328c8b2003-04-26 02:50:11 +000076
chw65d3c132007-11-12 21:09:10 +000077#if defined(_WIN32_WCE)
78/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
79 * thus we always assume that we have a console. That can be
80 * overridden with the -batch command line option.
81 */
82#define isatty(x) 1
83#endif
84
drhc6e41722011-04-11 15:36:26 +000085/* True if the timer is enabled */
86static int enableTimer = 0;
87
drhf0693c82011-10-11 20:41:54 +000088/* ctype macros that work with signed characters */
89#define IsSpace(X) isspace((unsigned char)X)
90#define IsDigit(X) isdigit((unsigned char)X)
91#define ToLower(X) (char)tolower((unsigned char)X)
92
chw97185482008-11-17 08:05:31 +000093#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000094#include <sys/time.h>
95#include <sys/resource.h>
96
drhda108222009-02-25 19:07:24 +000097/* Saved resource information for the beginning of an operation */
98static struct rusage sBegin;
99
drhda108222009-02-25 19:07:24 +0000100/*
101** Begin timing an operation
102*/
103static void beginTimer(void){
104 if( enableTimer ){
105 getrusage(RUSAGE_SELF, &sBegin);
106 }
107}
108
109/* Return the difference of two time_structs in seconds */
110static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
111 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
112 (double)(pEnd->tv_sec - pStart->tv_sec);
113}
114
115/*
116** Print the timing results.
117*/
118static void endTimer(void){
119 if( enableTimer ){
120 struct rusage sEnd;
121 getrusage(RUSAGE_SELF, &sEnd);
122 printf("CPU Time: user %f sys %f\n",
123 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
124 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
125 }
126}
shaneb320ccd2009-10-21 03:42:58 +0000127
drhda108222009-02-25 19:07:24 +0000128#define BEGIN_TIMER beginTimer()
129#define END_TIMER endTimer()
130#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000131
132#elif (defined(_WIN32) || defined(WIN32))
133
134#include <windows.h>
135
136/* Saved resource information for the beginning of an operation */
137static HANDLE hProcess;
138static FILETIME ftKernelBegin;
139static FILETIME ftUserBegin;
140typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
141static GETPROCTIMES getProcessTimesAddr = NULL;
142
shaneb320ccd2009-10-21 03:42:58 +0000143/*
144** Check to see if we have timer support. Return 1 if necessary
145** support found (or found previously).
146*/
147static int hasTimer(void){
148 if( getProcessTimesAddr ){
149 return 1;
150 } else {
151 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
152 ** See if the version we are running on has it, and if it does, save off
153 ** a pointer to it and the current process handle.
154 */
155 hProcess = GetCurrentProcess();
156 if( hProcess ){
157 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
158 if( NULL != hinstLib ){
159 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
160 if( NULL != getProcessTimesAddr ){
161 return 1;
162 }
163 FreeLibrary(hinstLib);
164 }
165 }
166 }
167 return 0;
168}
169
170/*
171** Begin timing an operation
172*/
173static void beginTimer(void){
174 if( enableTimer && getProcessTimesAddr ){
175 FILETIME ftCreation, ftExit;
176 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
177 }
178}
179
180/* Return the difference of two FILETIME structs in seconds */
181static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
182 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
183 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
184 return (double) ((i64End - i64Start) / 10000000.0);
185}
186
187/*
188** Print the timing results.
189*/
190static void endTimer(void){
191 if( enableTimer && getProcessTimesAddr){
192 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
193 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
194 printf("CPU Time: user %f sys %f\n",
195 timeDiff(&ftUserBegin, &ftUserEnd),
196 timeDiff(&ftKernelBegin, &ftKernelEnd));
197 }
198}
199
200#define BEGIN_TIMER beginTimer()
201#define END_TIMER endTimer()
202#define HAS_TIMER hasTimer()
203
drhda108222009-02-25 19:07:24 +0000204#else
205#define BEGIN_TIMER
206#define END_TIMER
207#define HAS_TIMER 0
208#endif
209
shanec0688ea2009-03-05 03:48:06 +0000210/*
211** Used to prevent warnings about unused parameters
212*/
213#define UNUSED_PARAMETER(x) (void)(x)
214
drhe91d16b2008-12-08 18:27:31 +0000215/*
drhc49f44e2006-10-26 18:15:42 +0000216** If the following flag is set, then command execution stops
217** at an error if we are not interactive.
218*/
219static int bail_on_error = 0;
220
221/*
drhc28490c2006-10-26 14:25:58 +0000222** Threat stdin as an interactive input if the following variable
223** is true. Otherwise, assume stdin is connected to a file or pipe.
224*/
225static int stdin_is_interactive = 1;
226
227/*
drh4c504392000-10-16 22:06:40 +0000228** The following is the open SQLite database. We make a pointer
229** to this database a static variable so that it can be accessed
230** by the SIGINT handler to interrupt database processing.
231*/
danielk197792f9a1b2004-06-19 09:08:16 +0000232static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000233
234/*
drh67505e72002-04-19 12:34:06 +0000235** True if an interrupt (Control-C) has been received.
236*/
drh43617e92006-03-06 20:55:46 +0000237static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000238
239/*
persicom7e2dfdd2002-04-18 02:46:52 +0000240** This is the name of our program. It is set in main(), used
241** in a number of other places, mostly for error messages.
242*/
243static char *Argv0;
244
245/*
246** Prompt strings. Initialized in main. Settable with
247** .prompt main continue
248*/
249static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
250static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
251
drhb0603412007-02-28 04:47:26 +0000252/*
253** Write I/O traces to the following stream.
254*/
rsebe0a9092007-07-30 18:24:38 +0000255#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000256static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000257#endif
drhb0603412007-02-28 04:47:26 +0000258
259/*
260** This routine works like printf in that its first argument is a
261** format string and subsequent arguments are values to be substituted
262** in place of % fields. The result of formatting this string
263** is written to iotrace.
264*/
rsebe0a9092007-07-30 18:24:38 +0000265#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000266static void iotracePrintf(const char *zFormat, ...){
267 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000268 char *z;
drhb0603412007-02-28 04:47:26 +0000269 if( iotrace==0 ) return;
270 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000271 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000272 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000273 fprintf(iotrace, "%s", z);
274 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000275}
rsebe0a9092007-07-30 18:24:38 +0000276#endif
drhb0603412007-02-28 04:47:26 +0000277
drh44c2eb12003-04-30 11:38:26 +0000278
persicom7e2dfdd2002-04-18 02:46:52 +0000279/*
drh83965662003-04-17 02:54:13 +0000280** Determines if a string is a number of not.
281*/
danielk19772e588c72005-12-09 14:25:08 +0000282static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000283 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000284 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000285 return 0;
286 }
287 z++;
288 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000289 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000290 if( *z=='.' ){
291 z++;
drhf0693c82011-10-11 20:41:54 +0000292 if( !IsDigit(*z) ) return 0;
293 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000294 if( realnum ) *realnum = 1;
295 }
296 if( *z=='e' || *z=='E' ){
297 z++;
298 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000299 if( !IsDigit(*z) ) return 0;
300 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000301 if( realnum ) *realnum = 1;
302 }
303 return *z==0;
304}
drh83965662003-04-17 02:54:13 +0000305
306/*
danielk1977bc6ada42004-06-30 08:20:16 +0000307** A global char* and an SQL function to access its current value
308** from within an SQL statement. This program used to use the
309** sqlite_exec_printf() API to substitue a string into an SQL statement.
310** The correct way to do this with sqlite3 is to use the bind API, but
311** since the shell is built around the callback paradigm it would be a lot
312** of work. Instead just use this hack, which is quite harmless.
313*/
314static const char *zShellStatic = 0;
315static void shellstaticFunc(
316 sqlite3_context *context,
317 int argc,
318 sqlite3_value **argv
319){
320 assert( 0==argc );
321 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000322 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000323 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000324 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
325}
326
327
328/*
drhfeac5f82004-08-01 00:10:45 +0000329** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000330** the text in memory obtained from malloc() and returns a pointer
331** to the text. NULL is returned at end of file, or if malloc()
332** fails.
333**
334** The interface is like "readline" but no command-line editing
335** is done.
336*/
drh18f52e02012-01-16 16:56:31 +0000337static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
drh8e7e7a22000-05-30 18:45:23 +0000338 char *zLine;
339 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000340 int n;
drh18f52e02012-01-16 16:56:31 +0000341 int inQuote = 0;
drh8e7e7a22000-05-30 18:45:23 +0000342
343 if( zPrompt && *zPrompt ){
344 printf("%s",zPrompt);
345 fflush(stdout);
346 }
347 nLine = 100;
348 zLine = malloc( nLine );
349 if( zLine==0 ) return 0;
350 n = 0;
drhb07028f2011-10-14 21:49:18 +0000351 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000352 if( n+100>nLine ){
353 nLine = nLine*2 + 100;
354 zLine = realloc(zLine, nLine);
355 if( zLine==0 ) return 0;
356 }
drhdaffd0e2001-04-11 14:28:42 +0000357 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000358 if( n==0 ){
359 free(zLine);
360 return 0;
361 }
362 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000363 break;
364 }
drh18f52e02012-01-16 16:56:31 +0000365 while( zLine[n] ){
366 if( zLine[n]=='"' ) inQuote = !inQuote;
367 n++;
368 }
369 if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
drh8e7e7a22000-05-30 18:45:23 +0000370 n--;
shaneh13b36022009-12-17 21:07:15 +0000371 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000372 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000373 break;
drh8e7e7a22000-05-30 18:45:23 +0000374 }
375 }
376 zLine = realloc( zLine, n+1 );
377 return zLine;
378}
379
380/*
drhc28490c2006-10-26 14:25:58 +0000381** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000382**
383** zPrior is a string of prior text retrieved. If not the empty
384** string, then issue a continuation prompt.
385*/
drhdaffd0e2001-04-11 14:28:42 +0000386static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000387 char *zPrompt;
388 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000389 if( in!=0 ){
drh18f52e02012-01-16 16:56:31 +0000390 return local_getline(0, in, 0);
drh8e7e7a22000-05-30 18:45:23 +0000391 }
392 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000393 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000394 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000395 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000396 }
397 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000398#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000399 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000400#endif
drh8e7e7a22000-05-30 18:45:23 +0000401 return zResult;
402}
403
persicom7e2dfdd2002-04-18 02:46:52 +0000404struct previous_mode_data {
405 int valid; /* Is there legit data in here? */
406 int mode;
407 int showHeader;
408 int colWidth[100];
409};
drh45e29d82006-11-20 16:21:10 +0000410
drh8e7e7a22000-05-30 18:45:23 +0000411/*
drh75897232000-05-29 14:26:00 +0000412** An pointer to an instance of this structure is passed from
413** the main program to the callback. This is used to communicate
414** state and mode information.
415*/
416struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000417 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000418 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000419 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000420 int cnt; /* Number of records displayed so far */
421 FILE *out; /* Write results here */
drh2f464a02011-10-13 00:41:49 +0000422 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000423 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000424 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000425 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000426 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000427 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000428 int colWidth[100]; /* Requested width of each column when in column mode*/
429 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000430 char nullvalue[20]; /* The text to print when a NULL comes back from
431 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000432 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000433 /* Holds the mode information just before
434 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000435 char outfile[FILENAME_MAX]; /* Filename for *out */
436 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000437 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000438 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000439 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000440};
441
442/*
443** These are the allowed modes.
444*/
drh967e8b72000-06-21 13:59:10 +0000445#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000446#define MODE_Column 1 /* One record per line in neat columns */
447#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000448#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
449#define MODE_Html 4 /* Generate an XHTML table */
450#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000451#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000452#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000453#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000454
drh66ce4d02008-02-15 17:38:06 +0000455static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000456 "line",
457 "column",
458 "list",
459 "semi",
460 "html",
drhfeac5f82004-08-01 00:10:45 +0000461 "insert",
462 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000463 "csv",
drh66ce4d02008-02-15 17:38:06 +0000464 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000465};
drh75897232000-05-29 14:26:00 +0000466
467/*
468** Number of elements in an array
469*/
drh902b9ee2008-12-05 17:17:07 +0000470#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000471
472/*
drhea678832008-12-10 19:26:22 +0000473** Compute a string length that is limited to what can be stored in
474** lower 30 bits of a 32-bit signed integer.
475*/
drh4f21c4a2008-12-10 22:15:00 +0000476static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000477 const char *z2 = z;
478 while( *z2 ){ z2++; }
479 return 0x3fffffff & (int)(z2 - z);
480}
481
482/*
drh127f9d72010-02-23 01:47:00 +0000483** A callback for the sqlite3_log() interface.
484*/
485static void shellLog(void *pArg, int iErrCode, const char *zMsg){
486 struct callback_data *p = (struct callback_data*)pArg;
487 if( p->pLog==0 ) return;
488 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
489 fflush(p->pLog);
490}
491
492/*
shane626a6e42009-10-22 17:30:15 +0000493** Output the given string as a hex-encoded blob (eg. X'1234' )
494*/
495static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
496 int i;
497 char *zBlob = (char *)pBlob;
498 fprintf(out,"X'");
499 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
500 fprintf(out,"'");
501}
502
503/*
drh28bd4bc2000-06-15 15:57:22 +0000504** Output the given string as a quoted string using SQL quoting conventions.
505*/
506static void output_quoted_string(FILE *out, const char *z){
507 int i;
508 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000509 for(i=0; z[i]; i++){
510 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000511 }
512 if( nSingle==0 ){
513 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000514 }else{
515 fprintf(out,"'");
516 while( *z ){
517 for(i=0; z[i] && z[i]!='\''; i++){}
518 if( i==0 ){
519 fprintf(out,"''");
520 z++;
521 }else if( z[i]=='\'' ){
522 fprintf(out,"%.*s''",i,z);
523 z += i+1;
524 }else{
drhcd7d2732002-02-26 23:24:26 +0000525 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000526 break;
527 }
528 }
drhcd7d2732002-02-26 23:24:26 +0000529 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000530 }
531}
532
533/*
drhfeac5f82004-08-01 00:10:45 +0000534** Output the given string as a quoted according to C or TCL quoting rules.
535*/
536static void output_c_string(FILE *out, const char *z){
537 unsigned int c;
538 fputc('"', out);
539 while( (c = *(z++))!=0 ){
540 if( c=='\\' ){
541 fputc(c, out);
542 fputc(c, out);
543 }else if( c=='\t' ){
544 fputc('\\', out);
545 fputc('t', out);
546 }else if( c=='\n' ){
547 fputc('\\', out);
548 fputc('n', out);
549 }else if( c=='\r' ){
550 fputc('\\', out);
551 fputc('r', out);
552 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000553 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000554 }else{
555 fputc(c, out);
556 }
557 }
558 fputc('"', out);
559}
560
561/*
drhc08a4f12000-06-15 16:49:48 +0000562** Output the given string with characters that are special to
563** HTML escaped.
564*/
565static void output_html_string(FILE *out, const char *z){
566 int i;
567 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000568 for(i=0; z[i]
569 && z[i]!='<'
570 && z[i]!='&'
571 && z[i]!='>'
572 && z[i]!='\"'
573 && z[i]!='\'';
574 i++){}
drhc08a4f12000-06-15 16:49:48 +0000575 if( i>0 ){
576 fprintf(out,"%.*s",i,z);
577 }
578 if( z[i]=='<' ){
579 fprintf(out,"&lt;");
580 }else if( z[i]=='&' ){
581 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000582 }else if( z[i]=='>' ){
583 fprintf(out,"&gt;");
584 }else if( z[i]=='\"' ){
585 fprintf(out,"&quot;");
586 }else if( z[i]=='\'' ){
587 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000588 }else{
589 break;
590 }
591 z += i + 1;
592 }
593}
594
595/*
drhc49f44e2006-10-26 18:15:42 +0000596** If a field contains any character identified by a 1 in the following
597** array, then the string must be quoted for CSV.
598*/
599static const char needCsvQuote[] = {
600 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
601 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
602 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
603 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
607 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
608 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
609 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
610 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
611 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
612 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
613 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
614 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
615 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
616};
617
618/*
drh8e64d1c2004-10-07 00:32:39 +0000619** Output a single term of CSV. Actually, p->separator is used for
620** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000621** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000622*/
623static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000624 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000625 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000626 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000627 }else{
drhc49f44e2006-10-26 18:15:42 +0000628 int i;
drh4f21c4a2008-12-10 22:15:00 +0000629 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000630 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000631 if( needCsvQuote[((unsigned char*)z)[i]]
632 || (z[i]==p->separator[0] &&
633 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000634 i = 0;
635 break;
636 }
637 }
638 if( i==0 ){
639 putc('"', out);
640 for(i=0; z[i]; i++){
641 if( z[i]=='"' ) putc('"', out);
642 putc(z[i], out);
643 }
644 putc('"', out);
645 }else{
646 fprintf(out, "%s", z);
647 }
drh8e64d1c2004-10-07 00:32:39 +0000648 }
649 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000650 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000651 }
652}
653
danielk19774af00c62005-01-23 23:43:21 +0000654#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000655/*
drh4c504392000-10-16 22:06:40 +0000656** This routine runs when the user presses Ctrl-C
657*/
658static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000659 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000660 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000661 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000662}
danielk19774af00c62005-01-23 23:43:21 +0000663#endif
drh4c504392000-10-16 22:06:40 +0000664
665/*
shane626a6e42009-10-22 17:30:15 +0000666** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000667** invokes for each row of a query result.
668*/
shane626a6e42009-10-22 17:30:15 +0000669static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000670 int i;
671 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000672
drh75897232000-05-29 14:26:00 +0000673 switch( p->mode ){
674 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000675 int w = 5;
drh6a535342001-10-19 16:44:56 +0000676 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000677 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000678 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000679 if( len>w ) w = len;
680 }
drh75897232000-05-29 14:26:00 +0000681 if( p->cnt++>0 ) fprintf(p->out,"\n");
682 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000683 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000684 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000685 }
686 break;
687 }
danielk19770d78bae2008-01-03 07:09:48 +0000688 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000689 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000690 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000691 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000692 int w, n;
693 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000694 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000695 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000696 w = 0;
drh75897232000-05-29 14:26:00 +0000697 }
drha0c66f52000-07-29 13:20:21 +0000698 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000699 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000700 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000701 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000702 if( w<n ) w = n;
703 }
704 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000705 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000706 }
707 if( p->showHeader ){
708 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
709 }
710 }
711 if( p->showHeader ){
712 for(i=0; i<nArg; i++){
713 int w;
714 if( i<ArraySize(p->actualWidth) ){
715 w = p->actualWidth[i];
716 }else{
717 w = 10;
718 }
719 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
720 "----------------------------------------------------------",
721 i==nArg-1 ? "\n": " ");
722 }
drh75897232000-05-29 14:26:00 +0000723 }
724 }
drh6a535342001-10-19 16:44:56 +0000725 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000726 for(i=0; i<nArg; i++){
727 int w;
drha0c66f52000-07-29 13:20:21 +0000728 if( i<ArraySize(p->actualWidth) ){
729 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000730 }else{
731 w = 10;
732 }
drhea678832008-12-10 19:26:22 +0000733 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000734 strlen30(azArg[i])>w ){
735 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000736 }
drhc61053b2000-06-04 12:58:36 +0000737 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000738 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000739 }
740 break;
741 }
drhe3710332000-09-29 13:30:53 +0000742 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000743 case MODE_List: {
744 if( p->cnt++==0 && p->showHeader ){
745 for(i=0; i<nArg; i++){
746 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
747 }
748 }
drh6a535342001-10-19 16:44:56 +0000749 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000750 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000751 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000752 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000753 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000754 if( i<nArg-1 ){
755 fprintf(p->out, "%s", p->separator);
756 }else if( p->mode==MODE_Semi ){
757 fprintf(p->out, ";\n");
758 }else{
759 fprintf(p->out, "\n");
760 }
drh75897232000-05-29 14:26:00 +0000761 }
762 break;
763 }
drh1e5d0e92000-05-31 23:33:17 +0000764 case MODE_Html: {
765 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000766 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000767 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000768 fprintf(p->out,"<TH>");
769 output_html_string(p->out, azCol[i]);
770 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000771 }
mihailim57c591a2008-06-23 21:26:05 +0000772 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000773 }
drh6a535342001-10-19 16:44:56 +0000774 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000775 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000776 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000777 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000778 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000779 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000780 }
mihailim57c591a2008-06-23 21:26:05 +0000781 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000782 break;
783 }
drhfeac5f82004-08-01 00:10:45 +0000784 case MODE_Tcl: {
785 if( p->cnt++==0 && p->showHeader ){
786 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000787 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000788 fprintf(p->out, "%s", p->separator);
789 }
790 fprintf(p->out,"\n");
791 }
792 if( azArg==0 ) break;
793 for(i=0; i<nArg; i++){
794 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
795 fprintf(p->out, "%s", p->separator);
796 }
797 fprintf(p->out,"\n");
798 break;
799 }
drh8e64d1c2004-10-07 00:32:39 +0000800 case MODE_Csv: {
801 if( p->cnt++==0 && p->showHeader ){
802 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000803 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000804 }
805 fprintf(p->out,"\n");
806 }
807 if( azArg==0 ) break;
808 for(i=0; i<nArg; i++){
809 output_csv(p, azArg[i], i<nArg-1);
810 }
811 fprintf(p->out,"\n");
812 break;
813 }
drh28bd4bc2000-06-15 15:57:22 +0000814 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000815 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000816 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000817 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000818 for(i=0; i<nArg; i++){
819 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000820 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000821 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000822 }else if( aiType && aiType[i]==SQLITE_TEXT ){
823 if( zSep[0] ) fprintf(p->out,"%s",zSep);
824 output_quoted_string(p->out, azArg[i]);
825 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
826 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000827 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
828 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
829 int nBlob = sqlite3_column_bytes(p->pStmt, i);
830 if( zSep[0] ) fprintf(p->out,"%s",zSep);
831 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000832 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000833 fprintf(p->out,"%s%s",zSep, azArg[i]);
834 }else{
835 if( zSep[0] ) fprintf(p->out,"%s",zSep);
836 output_quoted_string(p->out, azArg[i]);
837 }
838 }
839 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000840 break;
drh28bd4bc2000-06-15 15:57:22 +0000841 }
persicom1d0b8722002-04-18 02:53:04 +0000842 }
drh75897232000-05-29 14:26:00 +0000843 return 0;
844}
845
846/*
shane626a6e42009-10-22 17:30:15 +0000847** This is the callback routine that the SQLite library
848** invokes for each row of a query result.
849*/
850static int callback(void *pArg, int nArg, char **azArg, char **azCol){
851 /* since we don't have type info, call the shell_callback with a NULL value */
852 return shell_callback(pArg, nArg, azArg, azCol, NULL);
853}
854
855/*
drh33048c02001-10-01 14:29:22 +0000856** Set the destination table field of the callback_data structure to
857** the name of the table given. Escape any quote characters in the
858** table name.
859*/
860static void set_table_name(struct callback_data *p, const char *zName){
861 int i, n;
862 int needQuote;
863 char *z;
864
865 if( p->zDestTable ){
866 free(p->zDestTable);
867 p->zDestTable = 0;
868 }
869 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000870 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000871 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000872 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000873 needQuote = 1;
874 if( zName[i]=='\'' ) n++;
875 }
876 }
877 if( needQuote ) n += 2;
878 z = p->zDestTable = malloc( n+1 );
879 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000880 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000881 exit(1);
882 }
883 n = 0;
884 if( needQuote ) z[n++] = '\'';
885 for(i=0; zName[i]; i++){
886 z[n++] = zName[i];
887 if( zName[i]=='\'' ) z[n++] = '\'';
888 }
889 if( needQuote ) z[n++] = '\'';
890 z[n] = 0;
891}
892
danielk19772a02e332004-06-05 08:04:36 +0000893/* zIn is either a pointer to a NULL-terminated string in memory obtained
894** from malloc(), or a NULL pointer. The string pointed to by zAppend is
895** added to zIn, and the result returned in memory obtained from malloc().
896** zIn, if it was not NULL, is freed.
897**
898** If the third argument, quote, is not '\0', then it is used as a
899** quote character for zAppend.
900*/
drhc28490c2006-10-26 14:25:58 +0000901static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000902 int len;
903 int i;
drh4f21c4a2008-12-10 22:15:00 +0000904 int nAppend = strlen30(zAppend);
905 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000906
907 len = nAppend+nIn+1;
908 if( quote ){
909 len += 2;
910 for(i=0; i<nAppend; i++){
911 if( zAppend[i]==quote ) len++;
912 }
913 }
914
915 zIn = (char *)realloc(zIn, len);
916 if( !zIn ){
917 return 0;
918 }
919
920 if( quote ){
921 char *zCsr = &zIn[nIn];
922 *zCsr++ = quote;
923 for(i=0; i<nAppend; i++){
924 *zCsr++ = zAppend[i];
925 if( zAppend[i]==quote ) *zCsr++ = quote;
926 }
927 *zCsr++ = quote;
928 *zCsr++ = '\0';
929 assert( (zCsr-zIn)==len );
930 }else{
931 memcpy(&zIn[nIn], zAppend, nAppend);
932 zIn[len-1] = '\0';
933 }
934
935 return zIn;
936}
937
drhdd3d4592004-08-30 01:54:05 +0000938
939/*
drhb21a8e42012-01-28 21:08:51 +0000940** Execute a query statement that will generate SQL output. Print
941** the result columns, comma-separated, on a line and then add a
942** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000943**
drhb21a8e42012-01-28 21:08:51 +0000944** If the number of columns is 1 and that column contains text "--"
945** then write the semicolon on a separate line. That way, if a
946** "--" comment occurs at the end of the statement, the comment
947** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000948*/
drh157e29a2009-05-21 15:15:00 +0000949static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000950 struct callback_data *p, /* Query context */
951 const char *zSelect, /* SELECT statement to extract content */
952 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000953){
drhdd3d4592004-08-30 01:54:05 +0000954 sqlite3_stmt *pSelect;
955 int rc;
drhb21a8e42012-01-28 21:08:51 +0000956 int nResult;
957 int i;
958 const char *z;
drh2f464a02011-10-13 00:41:49 +0000959 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000960 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000961 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
962 p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000963 return rc;
964 }
965 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000966 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000967 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000968 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000969 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000970 zFirstRow = 0;
971 }
drhb21a8e42012-01-28 21:08:51 +0000972 z = (const char*)sqlite3_column_text(pSelect, 0);
973 fprintf(p->out, "%s", z);
974 for(i=1; i<nResult; i++){
975 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
976 }
977 if( z==0 ) z = "";
978 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
979 if( z[0] ){
980 fprintf(p->out, "\n;\n");
981 }else{
982 fprintf(p->out, ";\n");
983 }
drhdd3d4592004-08-30 01:54:05 +0000984 rc = sqlite3_step(pSelect);
985 }
drh2f464a02011-10-13 00:41:49 +0000986 rc = sqlite3_finalize(pSelect);
987 if( rc!=SQLITE_OK ){
988 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
989 p->nErr++;
990 }
991 return rc;
drhdd3d4592004-08-30 01:54:05 +0000992}
993
shane626a6e42009-10-22 17:30:15 +0000994/*
995** Allocate space and save off current error string.
996*/
997static char *save_err_msg(
998 sqlite3 *db /* Database to query */
999){
1000 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1001 char *zErrMsg = sqlite3_malloc(nErrMsg);
1002 if( zErrMsg ){
1003 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1004 }
1005 return zErrMsg;
1006}
1007
1008/*
shaneh642d8b82010-07-28 16:05:34 +00001009** Display memory stats.
1010*/
1011static int display_stats(
1012 sqlite3 *db, /* Database to query */
1013 struct callback_data *pArg, /* Pointer to struct callback_data */
1014 int bReset /* True to reset the stats */
1015){
1016 int iCur;
1017 int iHiwtr;
1018
1019 if( pArg && pArg->out ){
1020
1021 iHiwtr = iCur = -1;
1022 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001023 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001024 iHiwtr = iCur = -1;
1025 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001026 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001027/*
1028** Not currently used by the CLI.
1029** iHiwtr = iCur = -1;
1030** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1031** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1032*/
1033 iHiwtr = iCur = -1;
1034 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1035 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1036/*
1037** Not currently used by the CLI.
1038** iHiwtr = iCur = -1;
1039** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1040** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1041*/
1042 iHiwtr = iCur = -1;
1043 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1044 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1045 iHiwtr = iCur = -1;
1046 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1047 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1048 iHiwtr = iCur = -1;
1049 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1050 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1051 iHiwtr = iCur = -1;
1052 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1053 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1054#ifdef YYTRACKMAXSTACKDEPTH
1055 iHiwtr = iCur = -1;
1056 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1057 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1058#endif
1059 }
1060
1061 if( pArg && pArg->out && db ){
1062 iHiwtr = iCur = -1;
1063 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1064 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001065 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1066 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1067 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1068 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1069 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1070 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001071 iHiwtr = iCur = -1;
1072 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001073 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1074 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1075 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1076 iHiwtr = iCur = -1;
1077 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1078 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001079 iHiwtr = iCur = -1;
1080 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1081 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1082 iHiwtr = iCur = -1;
1083 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1084 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1085 }
1086
1087 if( pArg && pArg->out && db && pArg->pStmt ){
1088 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1089 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1090 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1091 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1092 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1093 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1094 }
1095
1096 return 0;
1097}
1098
1099/*
shane626a6e42009-10-22 17:30:15 +00001100** Execute a statement or set of statements. Print
1101** any result rows/columns depending on the current mode
1102** set via the supplied callback.
1103**
1104** This is very similar to SQLite's built-in sqlite3_exec()
1105** function except it takes a slightly different callback
1106** and callback data argument.
1107*/
1108static int shell_exec(
1109 sqlite3 *db, /* An open database */
1110 const char *zSql, /* SQL to be evaluated */
1111 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1112 /* (not the same as sqlite3_exec) */
1113 struct callback_data *pArg, /* Pointer to struct callback_data */
1114 char **pzErrMsg /* Error msg written here */
1115){
dan4564ced2010-01-05 04:59:56 +00001116 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1117 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001118 int rc2;
dan4564ced2010-01-05 04:59:56 +00001119 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001120
1121 if( pzErrMsg ){
1122 *pzErrMsg = NULL;
1123 }
1124
shaneb9fc17d2009-10-22 21:23:35 +00001125 while( zSql[0] && (SQLITE_OK == rc) ){
1126 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1127 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001128 if( pzErrMsg ){
1129 *pzErrMsg = save_err_msg(db);
1130 }
1131 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001132 if( !pStmt ){
1133 /* this happens for a comment or white-space */
1134 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001135 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001136 continue;
1137 }
shane626a6e42009-10-22 17:30:15 +00001138
shaneh642d8b82010-07-28 16:05:34 +00001139 /* save off the prepared statment handle and reset row count */
1140 if( pArg ){
1141 pArg->pStmt = pStmt;
1142 pArg->cnt = 0;
1143 }
1144
shanehb7977c52010-01-18 18:17:10 +00001145 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001146 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001147 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001148 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001149 }
shanehb7977c52010-01-18 18:17:10 +00001150
drh7e02e5e2011-12-06 19:44:51 +00001151 /* Output TESTCTRL_EXPLAIN text of requested */
1152 if( pArg && pArg->mode==MODE_Explain ){
1153 const char *zExplain = 0;
1154 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1155 if( zExplain && zExplain[0] ){
1156 fprintf(pArg->out, "%s", zExplain);
1157 }
1158 }
1159
shaneb9fc17d2009-10-22 21:23:35 +00001160 /* perform the first step. this will tell us if we
1161 ** have a result set or not and how wide it is.
1162 */
1163 rc = sqlite3_step(pStmt);
1164 /* if we have a result set... */
1165 if( SQLITE_ROW == rc ){
1166 /* if we have a callback... */
1167 if( xCallback ){
1168 /* allocate space for col name ptr, value ptr, and type */
1169 int nCol = sqlite3_column_count(pStmt);
1170 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1171 if( !pData ){
1172 rc = SQLITE_NOMEM;
1173 }else{
1174 char **azCols = (char **)pData; /* Names of result columns */
1175 char **azVals = &azCols[nCol]; /* Results */
1176 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1177 int i;
1178 assert(sizeof(int) <= sizeof(char *));
1179 /* save off ptrs to column names */
1180 for(i=0; i<nCol; i++){
1181 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1182 }
shaneb9fc17d2009-10-22 21:23:35 +00001183 do{
1184 /* extract the data and data types */
1185 for(i=0; i<nCol; i++){
1186 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1187 aiTypes[i] = sqlite3_column_type(pStmt, i);
1188 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1189 rc = SQLITE_NOMEM;
1190 break; /* from for */
1191 }
1192 } /* end for */
1193
1194 /* if data and types extracted successfully... */
1195 if( SQLITE_ROW == rc ){
1196 /* call the supplied callback with the result row data */
1197 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1198 rc = SQLITE_ABORT;
1199 }else{
1200 rc = sqlite3_step(pStmt);
1201 }
1202 }
1203 } while( SQLITE_ROW == rc );
1204 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001205 }
1206 }else{
1207 do{
1208 rc = sqlite3_step(pStmt);
1209 } while( rc == SQLITE_ROW );
1210 }
1211 }
1212
shaneh642d8b82010-07-28 16:05:34 +00001213 /* print usage stats if stats on */
1214 if( pArg && pArg->statsOn ){
1215 display_stats(db, pArg, 0);
1216 }
1217
dan4564ced2010-01-05 04:59:56 +00001218 /* Finalize the statement just executed. If this fails, save a
1219 ** copy of the error message. Otherwise, set zSql to point to the
1220 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001221 rc2 = sqlite3_finalize(pStmt);
1222 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001223 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001224 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001225 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001226 }else if( pzErrMsg ){
1227 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001228 }
shaneh642d8b82010-07-28 16:05:34 +00001229
1230 /* clear saved stmt handle */
1231 if( pArg ){
1232 pArg->pStmt = NULL;
1233 }
shane626a6e42009-10-22 17:30:15 +00001234 }
shaneb9fc17d2009-10-22 21:23:35 +00001235 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001236
1237 return rc;
1238}
1239
drhdd3d4592004-08-30 01:54:05 +00001240
drh33048c02001-10-01 14:29:22 +00001241/*
drh4c653a02000-06-07 01:27:47 +00001242** This is a different callback routine used for dumping the database.
1243** Each row received by this callback consists of a table name,
1244** the table type ("index" or "table") and SQL to create the table.
1245** This routine should print text sufficient to recreate the table.
1246*/
1247static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001248 int rc;
1249 const char *zTable;
1250 const char *zType;
1251 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001252 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001253 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001254
drh902b9ee2008-12-05 17:17:07 +00001255 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001256 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001257 zTable = azArg[0];
1258 zType = azArg[1];
1259 zSql = azArg[2];
1260
drh00b950d2005-09-11 02:03:03 +00001261 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001262 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001263 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1264 fprintf(p->out, "ANALYZE sqlite_master;\n");
1265 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1266 return 0;
drh45e29d82006-11-20 16:21:10 +00001267 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1268 char *zIns;
1269 if( !p->writableSchema ){
1270 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1271 p->writableSchema = 1;
1272 }
1273 zIns = sqlite3_mprintf(
1274 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1275 "VALUES('table','%q','%q',0,'%q');",
1276 zTable, zTable, zSql);
1277 fprintf(p->out, "%s\n", zIns);
1278 sqlite3_free(zIns);
1279 return 0;
drh00b950d2005-09-11 02:03:03 +00001280 }else{
1281 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001282 }
danielk19772a02e332004-06-05 08:04:36 +00001283
1284 if( strcmp(zType, "table")==0 ){
1285 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001286 char *zSelect = 0;
1287 char *zTableInfo = 0;
1288 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001289 int nRow = 0;
drhb21a8e42012-01-28 21:08:51 +00001290 int kk;
danielk19772a02e332004-06-05 08:04:36 +00001291
1292 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1293 zTableInfo = appendText(zTableInfo, zTable, '"');
1294 zTableInfo = appendText(zTableInfo, ");", 0);
1295
1296 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001297 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001298 if( rc!=SQLITE_OK || !pTableInfo ){
1299 return 1;
1300 }
1301
1302 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhb21a8e42012-01-28 21:08:51 +00001303 if( !isalpha(zTable[0]) ){
1304 kk = 0;
1305 }else{
1306 for(kk=1; isalnum(zTable[kk]); kk++){}
1307 }
1308 zTmp = appendText(zTmp, zTable, zTable[kk] ? '"' : 0);
danielk19772a02e332004-06-05 08:04:36 +00001309 if( zTmp ){
1310 zSelect = appendText(zSelect, zTmp, '\'');
1311 }
1312 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1313 rc = sqlite3_step(pTableInfo);
1314 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001315 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001316 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001317 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001318 rc = sqlite3_step(pTableInfo);
1319 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001320 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001321 }else{
1322 zSelect = appendText(zSelect, ") ", 0);
1323 }
drh157e29a2009-05-21 15:15:00 +00001324 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001325 }
1326 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001327 if( rc!=SQLITE_OK || nRow==0 ){
1328 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001329 return 1;
1330 }
1331 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1332 zSelect = appendText(zSelect, zTable, '"');
1333
drh2f464a02011-10-13 00:41:49 +00001334 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001335 if( rc==SQLITE_CORRUPT ){
1336 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001337 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001338 }
danielk19772a02e332004-06-05 08:04:36 +00001339 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001340 }
drh4c653a02000-06-07 01:27:47 +00001341 return 0;
1342}
1343
1344/*
drh45e29d82006-11-20 16:21:10 +00001345** Run zQuery. Use dump_callback() as the callback routine so that
1346** the contents of the query are output as SQL statements.
1347**
drhdd3d4592004-08-30 01:54:05 +00001348** If we get a SQLITE_CORRUPT error, rerun the query after appending
1349** "ORDER BY rowid DESC" to the end.
1350*/
1351static int run_schema_dump_query(
1352 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001353 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001354){
1355 int rc;
drh2f464a02011-10-13 00:41:49 +00001356 char *zErr = 0;
1357 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001358 if( rc==SQLITE_CORRUPT ){
1359 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001360 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001361 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1362 if( zErr ){
1363 fprintf(p->out, "/****** %s ******/\n", zErr);
1364 sqlite3_free(zErr);
1365 zErr = 0;
1366 }
drhdd3d4592004-08-30 01:54:05 +00001367 zQ2 = malloc( len+100 );
1368 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001369 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001370 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1371 if( rc ){
1372 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1373 }else{
1374 rc = SQLITE_CORRUPT;
1375 }
1376 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001377 free(zQ2);
1378 }
1379 return rc;
1380}
1381
1382/*
drh75897232000-05-29 14:26:00 +00001383** Text of a help message
1384*/
persicom1d0b8722002-04-18 02:53:04 +00001385static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001386 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001387 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001388 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001389 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001390 " If TABLE specified, only dump tables matching\n"
1391 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001392 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001393 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001394 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1395 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001396 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001397 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001398 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001399 ".indices ?TABLE? Show names of all indices\n"
1400 " If TABLE specified, only show indices for tables\n"
1401 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001402#ifdef SQLITE_ENABLE_IOTRACE
1403 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1404#endif
drh70df4fe2006-06-13 15:12:21 +00001405#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001406 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001407#endif
drh127f9d72010-02-23 01:47:00 +00001408 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001409 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001410 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001411 " column Left-aligned columns. (See .width)\n"
1412 " html HTML <table> code\n"
1413 " insert SQL insert statements for TABLE\n"
1414 " line One value per line\n"
1415 " list Values delimited by .separator string\n"
1416 " tabs Tab-separated values\n"
1417 " tcl TCL list elements\n"
1418 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001419 ".output FILENAME Send output to FILENAME\n"
1420 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001421 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001422 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001423 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001424 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001425 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001426 " If TABLE specified, only show tables matching\n"
1427 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001428 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001429 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001430 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001431 ".tables ?TABLE? List names of tables\n"
1432 " If TABLE specified, only list tables matching\n"
1433 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001434 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhde60fc22011-12-14 17:53:36 +00001435 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001436 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001437;
1438
shaneb320ccd2009-10-21 03:42:58 +00001439static char zTimerHelp[] =
1440 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1441;
1442
drhdaffd0e2001-04-11 14:28:42 +00001443/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001444static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001445
drh75897232000-05-29 14:26:00 +00001446/*
drh44c2eb12003-04-30 11:38:26 +00001447** Make sure the database is open. If it is not, then open it. If
1448** the database fails to open, print an error message and exit.
1449*/
1450static void open_db(struct callback_data *p){
1451 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001452 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001453 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001454 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1455 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1456 shellstaticFunc, 0, 0);
1457 }
1458 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001459 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001460 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001461 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001462 }
drhc2e87a32006-06-27 15:16:14 +00001463#ifndef SQLITE_OMIT_LOAD_EXTENSION
1464 sqlite3_enable_load_extension(p->db, 1);
1465#endif
drh44c2eb12003-04-30 11:38:26 +00001466 }
1467}
1468
1469/*
drhfeac5f82004-08-01 00:10:45 +00001470** Do C-language style dequoting.
1471**
1472** \t -> tab
1473** \n -> newline
1474** \r -> carriage return
1475** \NNN -> ascii character NNN in octal
1476** \\ -> backslash
1477*/
1478static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001479 int i, j;
1480 char c;
drhfeac5f82004-08-01 00:10:45 +00001481 for(i=j=0; (c = z[i])!=0; i++, j++){
1482 if( c=='\\' ){
1483 c = z[++i];
1484 if( c=='n' ){
1485 c = '\n';
1486 }else if( c=='t' ){
1487 c = '\t';
1488 }else if( c=='r' ){
1489 c = '\r';
1490 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001491 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001492 if( z[i+1]>='0' && z[i+1]<='7' ){
1493 i++;
1494 c = (c<<3) + z[i] - '0';
1495 if( z[i+1]>='0' && z[i+1]<='7' ){
1496 i++;
1497 c = (c<<3) + z[i] - '0';
1498 }
1499 }
1500 }
1501 }
1502 z[j] = c;
1503 }
1504 z[j] = 0;
1505}
1506
1507/*
drhc28490c2006-10-26 14:25:58 +00001508** Interpret zArg as a boolean value. Return either 0 or 1.
1509*/
1510static int booleanValue(char *zArg){
1511 int val = atoi(zArg);
1512 int j;
1513 for(j=0; zArg[j]; j++){
drhf0693c82011-10-11 20:41:54 +00001514 zArg[j] = ToLower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001515 }
1516 if( strcmp(zArg,"on")==0 ){
1517 val = 1;
1518 }else if( strcmp(zArg,"yes")==0 ){
1519 val = 1;
1520 }
1521 return val;
1522}
1523
1524/*
drh75897232000-05-29 14:26:00 +00001525** If an input line begins with "." then invoke this routine to
1526** process that line.
drh67505e72002-04-19 12:34:06 +00001527**
drh47ad6842006-11-08 12:25:42 +00001528** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001529*/
drh44c2eb12003-04-30 11:38:26 +00001530static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001531 int i = 1;
1532 int nArg = 0;
1533 int n, c;
drh67505e72002-04-19 12:34:06 +00001534 int rc = 0;
drh75897232000-05-29 14:26:00 +00001535 char *azArg[50];
1536
1537 /* Parse the input line into tokens.
1538 */
1539 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001540 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001541 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001542 if( zLine[i]=='\'' || zLine[i]=='"' ){
1543 int delim = zLine[i++];
1544 azArg[nArg++] = &zLine[i];
1545 while( zLine[i] && zLine[i]!=delim ){ i++; }
1546 if( zLine[i]==delim ){
1547 zLine[i++] = 0;
1548 }
drhfeac5f82004-08-01 00:10:45 +00001549 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001550 }else{
1551 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001552 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001553 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001554 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001555 }
1556 }
1557
1558 /* Process the input line.
1559 */
shane9bd1b442009-10-23 01:27:39 +00001560 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001561 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001562 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001563 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001564 const char *zDestFile;
1565 const char *zDb;
1566 sqlite3 *pDest;
1567 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001568 if( nArg==2 ){
1569 zDestFile = azArg[1];
1570 zDb = "main";
1571 }else{
1572 zDestFile = azArg[2];
1573 zDb = azArg[1];
1574 }
1575 rc = sqlite3_open(zDestFile, &pDest);
1576 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001577 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001578 sqlite3_close(pDest);
1579 return 1;
1580 }
drhdc2c4912009-02-04 22:46:47 +00001581 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001582 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1583 if( pBackup==0 ){
1584 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1585 sqlite3_close(pDest);
1586 return 1;
1587 }
1588 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1589 sqlite3_backup_finish(pBackup);
1590 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001591 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001592 }else{
1593 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001594 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001595 }
1596 sqlite3_close(pDest);
1597 }else
1598
shanehe2aa9d72009-11-06 17:20:17 +00001599 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001600 bail_on_error = booleanValue(azArg[1]);
1601 }else
1602
shanehe2aa9d72009-11-06 17:20:17 +00001603 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001604 struct callback_data data;
1605 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001606 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001607 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001608 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001609 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001610 data.colWidth[0] = 3;
1611 data.colWidth[1] = 15;
1612 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001613 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001614 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001615 if( zErrMsg ){
1616 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001617 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001618 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001619 }
1620 }else
1621
shanehe2aa9d72009-11-06 17:20:17 +00001622 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001623 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001624 /* When playing back a "dump", the content might appear in an order
1625 ** which causes immediate foreign key constraints to be violated.
1626 ** So disable foreign-key constraint enforcement to prevent problems. */
1627 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001628 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001629 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001630 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001631 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001632 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001633 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001634 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001635 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001636 );
1637 run_schema_dump_query(p,
1638 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001639 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001640 );
drh2f464a02011-10-13 00:41:49 +00001641 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001642 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001643 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001644 );
drh4c653a02000-06-07 01:27:47 +00001645 }else{
1646 int i;
drhdd3d4592004-08-30 01:54:05 +00001647 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001648 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001649 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001650 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001651 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001652 " AND sql NOT NULL");
1653 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001654 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001655 "WHERE sql NOT NULL"
1656 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001657 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001658 );
danielk1977bc6ada42004-06-30 08:20:16 +00001659 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001660 }
1661 }
drh45e29d82006-11-20 16:21:10 +00001662 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001663 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001664 p->writableSchema = 0;
1665 }
drh56197952011-10-13 16:30:13 +00001666 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1667 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001668 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001669 }else
drh75897232000-05-29 14:26:00 +00001670
shanehe2aa9d72009-11-06 17:20:17 +00001671 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001672 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001673 }else
1674
shanehe2aa9d72009-11-06 17:20:17 +00001675 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001676 rc = 2;
drh75897232000-05-29 14:26:00 +00001677 }else
1678
shanehe2aa9d72009-11-06 17:20:17 +00001679 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001680 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001681 if(val == 1) {
1682 if(!p->explainPrev.valid) {
1683 p->explainPrev.valid = 1;
1684 p->explainPrev.mode = p->mode;
1685 p->explainPrev.showHeader = p->showHeader;
1686 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1687 }
1688 /* We could put this code under the !p->explainValid
1689 ** condition so that it does not execute if we are already in
1690 ** explain mode. However, always executing it allows us an easy
1691 ** was to reset to explain mode in case the user previously
1692 ** did an .explain followed by a .width, .mode or .header
1693 ** command.
1694 */
danielk19770d78bae2008-01-03 07:09:48 +00001695 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001696 p->showHeader = 1;
1697 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001698 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001699 p->colWidth[1] = 13; /* opcode */
1700 p->colWidth[2] = 4; /* P1 */
1701 p->colWidth[3] = 4; /* P2 */
1702 p->colWidth[4] = 4; /* P3 */
1703 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001704 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001705 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001706 }else if (p->explainPrev.valid) {
1707 p->explainPrev.valid = 0;
1708 p->mode = p->explainPrev.mode;
1709 p->showHeader = p->explainPrev.showHeader;
1710 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1711 }
drh75897232000-05-29 14:26:00 +00001712 }else
1713
drhc28490c2006-10-26 14:25:58 +00001714 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001715 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001716 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001717 }else
1718
1719 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001720 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001721 if( HAS_TIMER ){
1722 fprintf(stderr,"%s",zTimerHelp);
1723 }
drh75897232000-05-29 14:26:00 +00001724 }else
1725
shanehe2aa9d72009-11-06 17:20:17 +00001726 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001727 char *zTable = azArg[2]; /* Insert data into this table */
1728 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001729 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001730 int nCol; /* Number of columns in the table */
1731 int nByte; /* Number of bytes in an SQL string */
1732 int i, j; /* Loop counters */
1733 int nSep; /* Number of bytes in p->separator[] */
1734 char *zSql; /* An SQL statement */
1735 char *zLine; /* A single line of input from the file */
1736 char **azCol; /* zLine[] broken up into columns */
1737 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001738 FILE *in; /* The input file */
1739 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001740
drha543c822006-06-08 16:10:14 +00001741 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001742 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001743 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001744 fprintf(stderr, "Error: non-null separator required for import\n");
1745 return 1;
drhfeac5f82004-08-01 00:10:45 +00001746 }
drh7b075e32011-09-28 01:10:00 +00001747 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00001748 if( zSql==0 ){
1749 fprintf(stderr, "Error: out of memory\n");
1750 return 1;
1751 }
drh4f21c4a2008-12-10 22:15:00 +00001752 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001753 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001754 sqlite3_free(zSql);
1755 if( rc ){
shane916f9612009-10-23 00:37:15 +00001756 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001757 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001758 return 1;
drhfeac5f82004-08-01 00:10:45 +00001759 }
shane916f9612009-10-23 00:37:15 +00001760 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001761 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001762 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001763 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001764 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001765 if( zSql==0 ){
1766 fprintf(stderr, "Error: out of memory\n");
1767 return 1;
1768 }
drh7b075e32011-09-28 01:10:00 +00001769 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001770 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001771 for(i=1; i<nCol; i++){
1772 zSql[j++] = ',';
1773 zSql[j++] = '?';
1774 }
1775 zSql[j++] = ')';
1776 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001777 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001778 free(zSql);
1779 if( rc ){
1780 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001781 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001782 return 1;
drhfeac5f82004-08-01 00:10:45 +00001783 }
1784 in = fopen(zFile, "rb");
1785 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001786 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001787 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001788 return 1;
drhfeac5f82004-08-01 00:10:45 +00001789 }
1790 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001791 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001792 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001793 fclose(in);
shane916f9612009-10-23 00:37:15 +00001794 sqlite3_finalize(pStmt);
1795 return 1;
drh43617e92006-03-06 20:55:46 +00001796 }
drhfeac5f82004-08-01 00:10:45 +00001797 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1798 zCommit = "COMMIT";
drh18f52e02012-01-16 16:56:31 +00001799 while( (zLine = local_getline(0, in, 1))!=0 ){
1800 char *z, c;
1801 int inQuote = 0;
drhb860bc92004-08-04 15:16:55 +00001802 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001803 azCol[0] = zLine;
drh18f52e02012-01-16 16:56:31 +00001804 for(i=0, z=zLine; (c = *z)!=0; z++){
1805 if( c=='"' ) inQuote = !inQuote;
1806 if( c=='\n' ) lineno++;
1807 if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001808 *z = 0;
1809 i++;
drhb860bc92004-08-04 15:16:55 +00001810 if( i<nCol ){
1811 azCol[i] = &z[nSep];
1812 z += nSep-1;
1813 }
drhfeac5f82004-08-01 00:10:45 +00001814 }
shane916f9612009-10-23 00:37:15 +00001815 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001816 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001817 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001818 fprintf(stderr,
1819 "Error: %s line %d: expected %d columns of data but found %d\n",
1820 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001821 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001822 free(zLine);
shane916f9612009-10-23 00:37:15 +00001823 rc = 1;
1824 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001825 }
drhfeac5f82004-08-01 00:10:45 +00001826 for(i=0; i<nCol; i++){
drh18f52e02012-01-16 16:56:31 +00001827 if( azCol[i][0]=='"' ){
1828 int k;
1829 for(z=azCol[i], j=1, k=0; z[j]; j++){
1830 if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1831 z[k++] = z[j];
1832 }
1833 z[k] = 0;
1834 }
drhfeac5f82004-08-01 00:10:45 +00001835 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1836 }
1837 sqlite3_step(pStmt);
1838 rc = sqlite3_reset(pStmt);
1839 free(zLine);
1840 if( rc!=SQLITE_OK ){
1841 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1842 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001843 rc = 1;
shane916f9612009-10-23 00:37:15 +00001844 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001845 }
shane916f9612009-10-23 00:37:15 +00001846 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001847 free(azCol);
1848 fclose(in);
1849 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001850 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001851 }else
1852
shanehe2aa9d72009-11-06 17:20:17 +00001853 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001854 struct callback_data data;
1855 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001856 open_db(p);
drh75897232000-05-29 14:26:00 +00001857 memcpy(&data, p, sizeof(data));
1858 data.showHeader = 0;
1859 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001860 if( nArg==1 ){
1861 rc = sqlite3_exec(p->db,
1862 "SELECT name FROM sqlite_master "
1863 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1864 "UNION ALL "
1865 "SELECT name FROM sqlite_temp_master "
1866 "WHERE type='index' "
1867 "ORDER BY 1",
1868 callback, &data, &zErrMsg
1869 );
1870 }else{
1871 zShellStatic = azArg[1];
1872 rc = sqlite3_exec(p->db,
1873 "SELECT name FROM sqlite_master "
1874 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1875 "UNION ALL "
1876 "SELECT name FROM sqlite_temp_master "
1877 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1878 "ORDER BY 1",
1879 callback, &data, &zErrMsg
1880 );
1881 zShellStatic = 0;
1882 }
drh75897232000-05-29 14:26:00 +00001883 if( zErrMsg ){
1884 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001885 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001886 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001887 }else if( rc != SQLITE_OK ){
1888 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1889 rc = 1;
drh75897232000-05-29 14:26:00 +00001890 }
1891 }else
1892
drhae5e4452007-05-03 17:18:36 +00001893#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001894 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001895 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001896 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1897 iotrace = 0;
1898 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001899 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001900 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001901 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001902 iotrace = stdout;
1903 }else{
1904 iotrace = fopen(azArg[1], "w");
1905 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001906 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001907 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001908 rc = 1;
drhb0603412007-02-28 04:47:26 +00001909 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001910 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001911 }
1912 }
1913 }else
drhae5e4452007-05-03 17:18:36 +00001914#endif
drhb0603412007-02-28 04:47:26 +00001915
drh70df4fe2006-06-13 15:12:21 +00001916#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001917 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1918 const char *zFile, *zProc;
1919 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001920 zFile = azArg[1];
1921 zProc = nArg>=3 ? azArg[2] : 0;
1922 open_db(p);
1923 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1924 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001925 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001926 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001927 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001928 }
1929 }else
drh70df4fe2006-06-13 15:12:21 +00001930#endif
drh1e397f82006-06-08 15:28:43 +00001931
drhc8ba2122011-03-23 11:16:22 +00001932 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00001933 const char *zFile = azArg[1];
1934 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1935 fclose(p->pLog);
1936 p->pLog = 0;
1937 }
1938 if( strcmp(zFile,"stdout")==0 ){
1939 p->pLog = stdout;
1940 }else if( strcmp(zFile, "stderr")==0 ){
1941 p->pLog = stderr;
1942 }else if( strcmp(zFile, "off")==0 ){
1943 p->pLog = 0;
1944 }else{
1945 p->pLog = fopen(zFile, "w");
1946 if( p->pLog==0 ){
1947 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1948 }
1949 }
1950 }else
1951
shanehe2aa9d72009-11-06 17:20:17 +00001952 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001953 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001954 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001955 ||
shanehe2aa9d72009-11-06 17:20:17 +00001956 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001957 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001958 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001959 ||
shanehe2aa9d72009-11-06 17:20:17 +00001960 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001961 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001962 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001963 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001964 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001965 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001966 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001967 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001968 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001969 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001970 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001971 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001972 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001973 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001974 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001975 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001976 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001977 }else {
shane9bd1b442009-10-23 01:27:39 +00001978 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001979 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001980 rc = 1;
drh75897232000-05-29 14:26:00 +00001981 }
1982 }else
1983
shanehe2aa9d72009-11-06 17:20:17 +00001984 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1985 int n2 = strlen30(azArg[1]);
1986 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1987 p->mode = MODE_Insert;
1988 set_table_name(p, azArg[2]);
1989 }else {
1990 fprintf(stderr, "Error: invalid arguments: "
1991 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1992 rc = 1;
1993 }
1994 }else
1995
persicom7e2dfdd2002-04-18 02:46:52 +00001996 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001997 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1998 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001999 }else
2000
drh75897232000-05-29 14:26:00 +00002001 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
2002 if( p->out!=stdout ){
2003 fclose(p->out);
2004 }
2005 if( strcmp(azArg[1],"stdout")==0 ){
2006 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00002007 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00002008 }else{
drha1f9b5e2004-02-14 16:31:02 +00002009 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00002010 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00002011 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00002012 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002013 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002014 } else {
drh5bb3eb92007-05-04 13:15:55 +00002015 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002016 }
2017 }
2018 }else
2019
drhdd45df82002-04-18 12:39:03 +00002020 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002021 if( nArg >= 2) {
2022 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2023 }
2024 if( nArg >= 3) {
2025 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2026 }
2027 }else
2028
shanehe2aa9d72009-11-06 17:20:17 +00002029 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002030 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002031 }else
2032
drh9ff849f2009-02-04 20:55:57 +00002033 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002034 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002035 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002036 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2037 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002038 }else{
shane9bd1b442009-10-23 01:27:39 +00002039 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002040 fclose(alt);
2041 }
2042 }else
2043
shanehe2aa9d72009-11-06 17:20:17 +00002044 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002045 const char *zSrcFile;
2046 const char *zDb;
2047 sqlite3 *pSrc;
2048 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002049 int nTimeout = 0;
2050
drh9ff849f2009-02-04 20:55:57 +00002051 if( nArg==2 ){
2052 zSrcFile = azArg[1];
2053 zDb = "main";
2054 }else{
2055 zSrcFile = azArg[2];
2056 zDb = azArg[1];
2057 }
2058 rc = sqlite3_open(zSrcFile, &pSrc);
2059 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002060 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002061 sqlite3_close(pSrc);
2062 return 1;
2063 }
drhdc2c4912009-02-04 22:46:47 +00002064 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002065 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2066 if( pBackup==0 ){
2067 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2068 sqlite3_close(pSrc);
2069 return 1;
2070 }
drhdc2c4912009-02-04 22:46:47 +00002071 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2072 || rc==SQLITE_BUSY ){
2073 if( rc==SQLITE_BUSY ){
2074 if( nTimeout++ >= 3 ) break;
2075 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002076 }
2077 }
2078 sqlite3_backup_finish(pBackup);
2079 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002080 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002081 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002082 fprintf(stderr, "Error: source database is busy\n");
2083 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002084 }else{
2085 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002086 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002087 }
2088 sqlite3_close(pSrc);
2089 }else
2090
shanehe2aa9d72009-11-06 17:20:17 +00002091 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002092 struct callback_data data;
2093 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002094 open_db(p);
drh75897232000-05-29 14:26:00 +00002095 memcpy(&data, p, sizeof(data));
2096 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002097 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002098 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002099 int i;
drhf0693c82011-10-11 20:41:54 +00002100 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002101 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002102 char *new_argv[2], *new_colv[2];
2103 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2104 " type text,\n"
2105 " name text,\n"
2106 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002107 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002108 " sql text\n"
2109 ")";
2110 new_argv[1] = 0;
2111 new_colv[0] = "sql";
2112 new_colv[1] = 0;
2113 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002114 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002115 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002116 char *new_argv[2], *new_colv[2];
2117 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2118 " type text,\n"
2119 " name text,\n"
2120 " tbl_name text,\n"
2121 " rootpage integer,\n"
2122 " sql text\n"
2123 ")";
2124 new_argv[1] = 0;
2125 new_colv[0] = "sql";
2126 new_colv[1] = 0;
2127 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002128 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002129 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002130 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002131 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002132 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002133 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2134 " FROM sqlite_master UNION ALL"
2135 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002136 "WHERE lower(tbl_name) LIKE shellstatic()"
2137 " AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002138 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002139 callback, &data, &zErrMsg);
2140 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002141 }
drh75897232000-05-29 14:26:00 +00002142 }else{
shane9bd1b442009-10-23 01:27:39 +00002143 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002144 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002145 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2146 " FROM sqlite_master UNION ALL"
2147 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002148 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002149 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002150 callback, &data, &zErrMsg
2151 );
drh75897232000-05-29 14:26:00 +00002152 }
drh75897232000-05-29 14:26:00 +00002153 if( zErrMsg ){
2154 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002155 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002156 rc = 1;
2157 }else if( rc != SQLITE_OK ){
2158 fprintf(stderr,"Error: querying schema information\n");
2159 rc = 1;
2160 }else{
2161 rc = 0;
drh75897232000-05-29 14:26:00 +00002162 }
2163 }else
2164
2165 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002166 sqlite3_snprintf(sizeof(p->separator), p->separator,
2167 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002168 }else
2169
shanehe2aa9d72009-11-06 17:20:17 +00002170 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002171 int i;
2172 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002173 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002174 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002175 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002176 fprintf(p->out,"%9.9s: ", "nullvalue");
2177 output_c_string(p->out, p->nullvalue);
2178 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002179 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002180 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002181 fprintf(p->out,"%9.9s: ", "separator");
2182 output_c_string(p->out, p->separator);
2183 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002184 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002185 fprintf(p->out,"%9.9s: ","width");
2186 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002187 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002188 }
drhfeac5f82004-08-01 00:10:45 +00002189 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002190 }else
2191
shaneh642d8b82010-07-28 16:05:34 +00002192 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2193 p->statsOn = booleanValue(azArg[1]);
2194 }else
2195
shanehe2aa9d72009-11-06 17:20:17 +00002196 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002197 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002198 int nRow;
drhe3710332000-09-29 13:30:53 +00002199 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002200 open_db(p);
drha50da102000-08-08 20:19:09 +00002201 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002202 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002203 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002204 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002205 "UNION ALL "
2206 "SELECT name FROM sqlite_temp_master "
2207 "WHERE type IN ('table','view') "
2208 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002209 &azResult, &nRow, 0, &zErrMsg
2210 );
drha50da102000-08-08 20:19:09 +00002211 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002212 zShellStatic = azArg[1];
2213 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002214 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002215 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002216 "UNION ALL "
2217 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002218 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002219 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002220 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002221 );
danielk1977bc6ada42004-06-30 08:20:16 +00002222 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002223 }
drh75897232000-05-29 14:26:00 +00002224 if( zErrMsg ){
2225 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002226 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002227 rc = 1;
2228 }else if( rc != SQLITE_OK ){
2229 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2230 rc = 1;
2231 }else{
drhe3710332000-09-29 13:30:53 +00002232 int len, maxlen = 0;
2233 int i, j;
2234 int nPrintCol, nPrintRow;
2235 for(i=1; i<=nRow; i++){
2236 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002237 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002238 if( len>maxlen ) maxlen = len;
2239 }
2240 nPrintCol = 80/(maxlen+2);
2241 if( nPrintCol<1 ) nPrintCol = 1;
2242 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2243 for(i=0; i<nPrintRow; i++){
2244 for(j=i+1; j<=nRow; j+=nPrintRow){
2245 char *zSp = j<=nPrintRow ? "" : " ";
2246 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2247 }
2248 printf("\n");
2249 }
2250 }
danielk19776f8a5032004-05-10 10:34:51 +00002251 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002252 }else
2253
shaneh96887e12011-02-10 21:08:58 +00002254 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002255 static const struct {
2256 const char *zCtrlName; /* Name of a test-control option */
2257 int ctrlCode; /* Integer code for that option */
2258 } aCtrl[] = {
2259 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2260 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2261 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2262 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2263 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2264 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2265 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2266 { "assert", SQLITE_TESTCTRL_ASSERT },
2267 { "always", SQLITE_TESTCTRL_ALWAYS },
2268 { "reserve", SQLITE_TESTCTRL_RESERVE },
2269 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2270 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002271 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2272 };
shaneh96887e12011-02-10 21:08:58 +00002273 int testctrl = -1;
2274 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002275 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002276 open_db(p);
2277
drhd416fe72011-03-17 16:45:50 +00002278 /* convert testctrl text option to value. allow any unique prefix
2279 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002280 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002281 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002282 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2283 if( testctrl<0 ){
2284 testctrl = aCtrl[i].ctrlCode;
2285 }else{
drhb07028f2011-10-14 21:49:18 +00002286 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002287 testctrl = -1;
2288 break;
2289 }
2290 }
2291 }
2292 if( testctrl<0 ) testctrl = atoi(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002293 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2294 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2295 }else{
2296 switch(testctrl){
2297
2298 /* sqlite3_test_control(int, db, int) */
2299 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2300 case SQLITE_TESTCTRL_RESERVE:
2301 if( nArg==3 ){
2302 int opt = (int)strtol(azArg[2], 0, 0);
2303 rc = sqlite3_test_control(testctrl, p->db, opt);
2304 printf("%d (0x%08x)\n", rc, rc);
2305 } else {
drhd416fe72011-03-17 16:45:50 +00002306 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2307 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002308 }
2309 break;
2310
2311 /* sqlite3_test_control(int) */
2312 case SQLITE_TESTCTRL_PRNG_SAVE:
2313 case SQLITE_TESTCTRL_PRNG_RESTORE:
2314 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002315 if( nArg==2 ){
2316 rc = sqlite3_test_control(testctrl);
2317 printf("%d (0x%08x)\n", rc, rc);
2318 } else {
2319 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2320 }
2321 break;
2322
2323 /* sqlite3_test_control(int, uint) */
2324 case SQLITE_TESTCTRL_PENDING_BYTE:
2325 if( nArg==3 ){
2326 unsigned int opt = (unsigned int)atoi(azArg[2]);
2327 rc = sqlite3_test_control(testctrl, opt);
2328 printf("%d (0x%08x)\n", rc, rc);
2329 } else {
drhd416fe72011-03-17 16:45:50 +00002330 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2331 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002332 }
2333 break;
2334
2335 /* sqlite3_test_control(int, int) */
2336 case SQLITE_TESTCTRL_ASSERT:
2337 case SQLITE_TESTCTRL_ALWAYS:
2338 if( nArg==3 ){
2339 int opt = atoi(azArg[2]);
2340 rc = sqlite3_test_control(testctrl, opt);
2341 printf("%d (0x%08x)\n", rc, rc);
2342 } else {
drhd416fe72011-03-17 16:45:50 +00002343 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2344 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002345 }
2346 break;
2347
2348 /* sqlite3_test_control(int, char *) */
2349#ifdef SQLITE_N_KEYWORD
2350 case SQLITE_TESTCTRL_ISKEYWORD:
2351 if( nArg==3 ){
2352 const char *opt = azArg[2];
2353 rc = sqlite3_test_control(testctrl, opt);
2354 printf("%d (0x%08x)\n", rc, rc);
2355 } else {
drhd416fe72011-03-17 16:45:50 +00002356 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2357 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002358 }
2359 break;
2360#endif
2361
2362 case SQLITE_TESTCTRL_BITVEC_TEST:
2363 case SQLITE_TESTCTRL_FAULT_INSTALL:
2364 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2365 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2366 default:
drhd416fe72011-03-17 16:45:50 +00002367 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2368 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002369 break;
2370 }
2371 }
2372 }else
2373
shanehe2aa9d72009-11-06 17:20:17 +00002374 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002375 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002376 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002377 }else
2378
drhd416fe72011-03-17 16:45:50 +00002379 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2380 && nArg==2
2381 ){
drh3b1a9882007-11-02 12:53:03 +00002382 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002383 }else
2384
drh9fd301b2011-06-03 13:28:22 +00002385 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh743e0032011-12-12 16:51:50 +00002386 printf("SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002387 sqlite3_libversion(), sqlite3_sourceid());
2388 }else
2389
drhde60fc22011-12-14 17:53:36 +00002390 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2391 const char *zDbName = nArg==2 ? azArg[1] : "main";
2392 char *zVfsName = 0;
2393 if( p->db ){
2394 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2395 if( zVfsName ){
2396 printf("%s\n", zVfsName);
2397 sqlite3_free(zVfsName);
2398 }
2399 }
2400 }else
2401
shanehe2aa9d72009-11-06 17:20:17 +00002402 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002403 int j;
drh43617e92006-03-06 20:55:46 +00002404 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002405 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2406 p->colWidth[j-1] = atoi(azArg[j]);
2407 }
2408 }else
2409
2410 {
shane9bd1b442009-10-23 01:27:39 +00002411 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002412 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002413 rc = 1;
drh75897232000-05-29 14:26:00 +00002414 }
drh67505e72002-04-19 12:34:06 +00002415
2416 return rc;
drh75897232000-05-29 14:26:00 +00002417}
2418
drh67505e72002-04-19 12:34:06 +00002419/*
drh91a66392007-09-07 01:12:32 +00002420** Return TRUE if a semicolon occurs anywhere in the first N characters
2421** of string z[].
drh324ccef2003-02-05 14:06:20 +00002422*/
drh91a66392007-09-07 01:12:32 +00002423static int _contains_semicolon(const char *z, int N){
2424 int i;
2425 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2426 return 0;
drh324ccef2003-02-05 14:06:20 +00002427}
2428
2429/*
drh70c7a4b2003-04-26 03:03:06 +00002430** Test to see if a line consists entirely of whitespace.
2431*/
2432static int _all_whitespace(const char *z){
2433 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002434 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002435 if( *z=='/' && z[1]=='*' ){
2436 z += 2;
2437 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2438 if( *z==0 ) return 0;
2439 z++;
2440 continue;
2441 }
2442 if( *z=='-' && z[1]=='-' ){
2443 z += 2;
2444 while( *z && *z!='\n' ){ z++; }
2445 if( *z==0 ) return 1;
2446 continue;
2447 }
2448 return 0;
2449 }
2450 return 1;
2451}
2452
2453/*
drha9b17162003-04-29 18:01:28 +00002454** Return TRUE if the line typed in is an SQL command terminator other
2455** than a semi-colon. The SQL Server style "go" command is understood
2456** as is the Oracle "/".
2457*/
2458static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002459 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002460 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2461 return 1; /* Oracle */
2462 }
drhf0693c82011-10-11 20:41:54 +00002463 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002464 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002465 return 1; /* SQL Server */
2466 }
2467 return 0;
2468}
2469
2470/*
drh233a5312008-12-18 22:25:13 +00002471** Return true if zSql is a complete SQL statement. Return false if it
2472** ends in the middle of a string literal or C-style comment.
2473*/
2474static int _is_complete(char *zSql, int nSql){
2475 int rc;
2476 if( zSql==0 ) return 1;
2477 zSql[nSql] = ';';
2478 zSql[nSql+1] = 0;
2479 rc = sqlite3_complete(zSql);
2480 zSql[nSql] = 0;
2481 return rc;
2482}
2483
2484/*
drh67505e72002-04-19 12:34:06 +00002485** Read input from *in and process it. If *in==0 then input
2486** is interactive - the user is typing it it. Otherwise, input
2487** is coming from a file or device. A prompt is issued and history
2488** is saved only if input is interactive. An interrupt signal will
2489** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002490**
2491** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002492*/
drhc28490c2006-10-26 14:25:58 +00002493static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002494 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002495 char *zSql = 0;
2496 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002497 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002498 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002499 int rc;
2500 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002501 int lineno = 0;
2502 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002503
2504 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2505 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002506 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002507 zLine = one_input_line(zSql, in);
2508 if( zLine==0 ){
2509 break; /* We have reached EOF */
2510 }
drh67505e72002-04-19 12:34:06 +00002511 if( seenInterrupt ){
2512 if( in!=0 ) break;
2513 seenInterrupt = 0;
2514 }
drhc28490c2006-10-26 14:25:58 +00002515 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002516 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002517 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002518 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002519 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002520 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002521 break;
2522 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002523 errCnt++;
2524 }
drhdaffd0e2001-04-11 14:28:42 +00002525 continue;
2526 }
drh233a5312008-12-18 22:25:13 +00002527 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002528 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002529 }
drh91a66392007-09-07 01:12:32 +00002530 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002531 if( zSql==0 ){
2532 int i;
drhf0693c82011-10-11 20:41:54 +00002533 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002534 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002535 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002536 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002537 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002538 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002539 exit(1);
2540 }
drh5bb3eb92007-05-04 13:15:55 +00002541 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002542 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002543 }
2544 }else{
drh4f21c4a2008-12-10 22:15:00 +00002545 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002546 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002547 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002548 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002549 exit(1);
2550 }
drh5bb3eb92007-05-04 13:15:55 +00002551 zSql[nSql++] = '\n';
2552 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002553 nSql += len;
2554 }
drh91a66392007-09-07 01:12:32 +00002555 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2556 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002557 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002558 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002559 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002560 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002561 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002562 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002563 char zPrefix[100];
2564 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002565 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002566 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002567 }else{
shane9bd1b442009-10-23 01:27:39 +00002568 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002569 }
drh7f953e22002-07-13 17:33:45 +00002570 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002571 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002572 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002573 zErrMsg = 0;
2574 }else{
shaned2bed1c2009-10-21 03:56:54 +00002575 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002576 }
drhc49f44e2006-10-26 18:15:42 +00002577 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002578 }
2579 free(zSql);
2580 zSql = 0;
2581 nSql = 0;
2582 }
2583 }
2584 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002585 if( !_all_whitespace(zSql) ){
2586 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2587 }
drhdaffd0e2001-04-11 14:28:42 +00002588 free(zSql);
2589 }
danielk19772ac27622007-07-03 05:31:16 +00002590 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002591 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002592}
2593
drh67505e72002-04-19 12:34:06 +00002594/*
2595** Return a pathname which is the user's home directory. A
2596** 0 return indicates an error of some kind. Space to hold the
2597** resulting string is obtained from malloc(). The calling
2598** function should free the result.
2599*/
2600static char *find_home_dir(void){
2601 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002602
chw97185482008-11-17 08:05:31 +00002603#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002604 struct passwd *pwent;
2605 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002606 if( (pwent=getpwuid(uid)) != NULL) {
2607 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002608 }
2609#endif
2610
chw65d3c132007-11-12 21:09:10 +00002611#if defined(_WIN32_WCE)
2612 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2613 */
2614 home_dir = strdup("/");
2615#else
2616
drh164a1b62006-08-19 11:15:20 +00002617#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2618 if (!home_dir) {
2619 home_dir = getenv("USERPROFILE");
2620 }
2621#endif
2622
drh67505e72002-04-19 12:34:06 +00002623 if (!home_dir) {
2624 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002625 }
2626
drhcdb36b72006-06-12 12:57:45 +00002627#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002628 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002629 char *zDrive, *zPath;
2630 int n;
2631 zDrive = getenv("HOMEDRIVE");
2632 zPath = getenv("HOMEPATH");
2633 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002634 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002635 home_dir = malloc( n );
2636 if( home_dir==0 ) return 0;
2637 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2638 return home_dir;
2639 }
2640 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002641 }
2642#endif
2643
chw65d3c132007-11-12 21:09:10 +00002644#endif /* !_WIN32_WCE */
2645
drh67505e72002-04-19 12:34:06 +00002646 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002647 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002648 char *z = malloc( n );
2649 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002650 home_dir = z;
2651 }
drhe98d4fa2002-04-21 19:06:22 +00002652
drh67505e72002-04-19 12:34:06 +00002653 return home_dir;
2654}
2655
2656/*
2657** Read input from the file given by sqliterc_override. Or if that
2658** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002659**
2660** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002661*/
shane9bd1b442009-10-23 01:27:39 +00002662static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002663 struct callback_data *p, /* Configuration data */
2664 const char *sqliterc_override /* Name of config file. NULL to use default */
2665){
persicom7e2dfdd2002-04-18 02:46:52 +00002666 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002667 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002668 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002669 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002670 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002671 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002672
2673 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002674 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002675 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002676#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002677 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002678#endif
shane9bd1b442009-10-23 01:27:39 +00002679 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002680 }
drh4f21c4a2008-12-10 22:15:00 +00002681 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002682 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002683 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002684 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2685 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002686 }
drha959ac42007-06-20 13:10:00 +00002687 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002688 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002689 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002690 }
drha1f9b5e2004-02-14 16:31:02 +00002691 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002692 if( in ){
drhc28490c2006-10-26 14:25:58 +00002693 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002694 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002695 }
shane9bd1b442009-10-23 01:27:39 +00002696 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002697 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002698 }
drh43617e92006-03-06 20:55:46 +00002699 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002700 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002701}
2702
drh67505e72002-04-19 12:34:06 +00002703/*
drhe1e38c42003-05-04 18:30:59 +00002704** Show available command line options
2705*/
2706static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00002707 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00002708 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002709 " -column set output mode to 'column'\n"
drhcc3b4f82012-02-07 14:13:50 +00002710 " -cmd command run \"command\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00002711 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00002712 " -echo print commands before execution\n"
2713 " -init filename read/process named file\n"
2714 " -[no]header turn headers on or off\n"
2715 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002716 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00002717 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002718 " -line set output mode to 'line'\n"
2719 " -list set output mode to 'list'\n"
drhcc3b4f82012-02-07 14:13:50 +00002720#ifdef SQLITE_ENABLE_MULTIPLEX
2721 " -multiplex enable the multiplexor VFS\n"
2722#endif
2723 " -nullvalue 'text' set text string for NULL values\n"
drhe1e38c42003-05-04 18:30:59 +00002724 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002725 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002726 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002727 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00002728#ifdef SQLITE_ENABLE_VFSTRACE
2729 " -vfstrace enable tracing of all VFS calls\n"
2730#endif
drhe1e38c42003-05-04 18:30:59 +00002731;
2732static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002733 fprintf(stderr,
2734 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2735 "FILENAME is the name of an SQLite database. A new database is created\n"
2736 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002737 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002738 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002739 }else{
2740 fprintf(stderr, "Use the -help option for additional information\n");
2741 }
2742 exit(1);
2743}
2744
2745/*
drh67505e72002-04-19 12:34:06 +00002746** Initialize the state information in data
2747*/
drh0850b532006-01-31 19:31:43 +00002748static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002749 memset(data, 0, sizeof(*data));
2750 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002751 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002752 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00002753 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00002754 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002755 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2756 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002757 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002758}
2759
drh75897232000-05-29 14:26:00 +00002760int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002761 char *zErrMsg = 0;
2762 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002763 const char *zInitFile = 0;
2764 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002765 int i;
drhc28490c2006-10-26 14:25:58 +00002766 int rc = 0;
drh75897232000-05-29 14:26:00 +00002767
drh52784bd2011-05-18 17:15:06 +00002768 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
2769 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
2770 sqlite3_sourceid(), SQLITE_SOURCE_ID);
2771 exit(1);
2772 }
drhdaffd0e2001-04-11 14:28:42 +00002773 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002774 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002775 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002776
drh44c2eb12003-04-30 11:38:26 +00002777 /* Make sure we have a valid signal handler early, before anything
2778 ** else is done.
2779 */
drh4c504392000-10-16 22:06:40 +00002780#ifdef SIGINT
2781 signal(SIGINT, interrupt_handler);
2782#endif
drh44c2eb12003-04-30 11:38:26 +00002783
drh22fbcb82004-02-01 01:22:50 +00002784 /* Do an initial pass through the command-line argument to locate
2785 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002786 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002787 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002788 */
drh22fbcb82004-02-01 01:22:50 +00002789 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002790 char *z;
drh44c2eb12003-04-30 11:38:26 +00002791 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002792 z = argv[i];
drhcc3b4f82012-02-07 14:13:50 +00002793 if( z[1]=='-' ) z++;
2794 if( strcmp(z,"-separator")==0
2795 || strcmp(z,"-nullvalue")==0
2796 || strcmp(z,"-cmd")==0
2797 ){
drh44c2eb12003-04-30 11:38:26 +00002798 i++;
drhcc3b4f82012-02-07 14:13:50 +00002799 }else if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002800 i++;
2801 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002802 /* Need to check for batch mode here to so we can avoid printing
2803 ** informational messages (like from process_sqliterc) before
2804 ** we do the actual processing of arguments later in a second pass.
2805 */
drhcc3b4f82012-02-07 14:13:50 +00002806 }else if( strcmp(z,"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002807 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00002808 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00002809#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00002810 int j, c;
2811 const char *zSize;
2812 sqlite3_int64 szHeap;
2813
2814 zSize = argv[++i];
2815 szHeap = atoi(zSize);
2816 for(j=0; (c = zSize[j])!=0; j++){
2817 if( c=='M' ){ szHeap *= 1000000; break; }
2818 if( c=='K' ){ szHeap *= 1000; break; }
2819 if( c=='G' ){ szHeap *= 1000000000; break; }
2820 }
2821 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00002822 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2823#endif
drh97ae8ff2011-03-16 16:56:29 +00002824#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00002825 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00002826 extern int vfstrace_register(
2827 const char *zTraceName,
2828 const char *zOldVfsName,
2829 int (*xOut)(const char*,void*),
2830 void *pOutArg,
2831 int makeDefault
2832 );
drh2b625e22011-03-16 17:05:28 +00002833 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00002834#endif
drh6f25e892011-07-08 17:02:57 +00002835#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00002836 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00002837 extern int sqlite3_multiple_initialize(const char*,int);
2838 sqlite3_multiplex_initialize(0, 1);
2839#endif
drhcc3b4f82012-02-07 14:13:50 +00002840 }else if( strcmp(z,"-vfs")==0 ){
drh77ec9ba2011-03-15 18:35:44 +00002841 sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
drha7e61d82011-03-12 17:02:57 +00002842 if( pVfs ){
2843 sqlite3_vfs_register(pVfs, 1);
2844 }else{
2845 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
2846 exit(1);
2847 }
drh44c2eb12003-04-30 11:38:26 +00002848 }
2849 }
drh22fbcb82004-02-01 01:22:50 +00002850 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002851#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002852 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2853#else
drh22fbcb82004-02-01 01:22:50 +00002854 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002855#endif
drh22fbcb82004-02-01 01:22:50 +00002856 }else{
danielk197703aded42004-11-22 05:26:27 +00002857#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002858 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002859#else
2860 data.zDbFilename = 0;
2861#endif
drh22fbcb82004-02-01 01:22:50 +00002862 }
2863 if( i<argc ){
2864 zFirstCmd = argv[i++];
2865 }
shaneh5fc25012009-11-11 04:17:07 +00002866 if( i<argc ){
2867 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2868 fprintf(stderr,"Use -help for a list of options.\n");
2869 return 1;
2870 }
drh44c2eb12003-04-30 11:38:26 +00002871 data.out = stdout;
2872
drh01b41712005-08-29 23:06:23 +00002873#ifdef SQLITE_OMIT_MEMORYDB
2874 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002875 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2876 return 1;
drh01b41712005-08-29 23:06:23 +00002877 }
2878#endif
2879
drh44c2eb12003-04-30 11:38:26 +00002880 /* Go ahead and open the database file if it already exists. If the
2881 ** file does not exist, delay opening it. This prevents empty database
2882 ** files from being created if a user mistypes the database name argument
2883 ** to the sqlite command-line tool.
2884 */
drhc8d74412004-08-31 23:41:26 +00002885 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002886 open_db(&data);
2887 }
2888
drh22fbcb82004-02-01 01:22:50 +00002889 /* Process the initialization file if there is one. If no -init option
2890 ** is given on the command line, look for a file named ~/.sqliterc and
2891 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002892 */
shane86f5bdb2009-10-24 02:00:07 +00002893 rc = process_sqliterc(&data,zInitFile);
2894 if( rc>0 ){
2895 return rc;
2896 }
drh44c2eb12003-04-30 11:38:26 +00002897
drh22fbcb82004-02-01 01:22:50 +00002898 /* Make a second pass through the command-line argument and set
2899 ** options. This second pass is delayed until after the initialization
2900 ** file is processed so that the command-line arguments will override
2901 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002902 */
drh22fbcb82004-02-01 01:22:50 +00002903 for(i=1; i<argc && argv[i][0]=='-'; i++){
2904 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002905 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002906 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002907 i++;
2908 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002909 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002910 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002911 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002912 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002913 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002914 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002915 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002916 }else if( strcmp(z,"-csv")==0 ){
2917 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002918 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002919 }else if( strcmp(z,"-separator")==0 ){
2920 i++;
shaneh5fc25012009-11-11 04:17:07 +00002921 if(i>=argc){
drhcc3b4f82012-02-07 14:13:50 +00002922 fprintf(stderr,"%s: Error: missing argument for option: %s\n",
2923 Argv0, z);
shaneh5fc25012009-11-11 04:17:07 +00002924 fprintf(stderr,"Use -help for a list of options.\n");
2925 return 1;
2926 }
drh5bb3eb92007-05-04 13:15:55 +00002927 sqlite3_snprintf(sizeof(data.separator), data.separator,
2928 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002929 }else if( strcmp(z,"-nullvalue")==0 ){
2930 i++;
shaneh5fc25012009-11-11 04:17:07 +00002931 if(i>=argc){
drhcc3b4f82012-02-07 14:13:50 +00002932 fprintf(stderr,"%s: Error: missing argument for option: %s\n",
2933 Argv0, z);
shaneh5fc25012009-11-11 04:17:07 +00002934 fprintf(stderr,"Use -help for a list of options.\n");
2935 return 1;
2936 }
drh5bb3eb92007-05-04 13:15:55 +00002937 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2938 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002939 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002940 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002941 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002942 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002943 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002944 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00002945 }else if( strcmp(z,"-stats")==0 ){
2946 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002947 }else if( strcmp(z,"-bail")==0 ){
2948 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002949 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00002950 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00002951 return 0;
drhc28490c2006-10-26 14:25:58 +00002952 }else if( strcmp(z,"-interactive")==0 ){
2953 stdin_is_interactive = 1;
2954 }else if( strcmp(z,"-batch")==0 ){
2955 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002956 }else if( strcmp(z,"-heap")==0 ){
2957 i++;
drha7e61d82011-03-12 17:02:57 +00002958 }else if( strcmp(z,"-vfs")==0 ){
2959 i++;
drh6f25e892011-07-08 17:02:57 +00002960#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00002961 }else if( strcmp(z,"-vfstrace")==0 ){
2962 i++;
drh6f25e892011-07-08 17:02:57 +00002963#endif
2964#ifdef SQLITE_ENABLE_MULTIPLEX
2965 }else if( strcmp(z,"-multiplex")==0 ){
2966 i++;
2967#endif
drhcc3b4f82012-02-07 14:13:50 +00002968 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002969 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00002970 }else if( strcmp(z,"-cmd")==0 ){
2971 if( i==argc-1 ) break;
2972 i++;
2973 z = argv[i];
2974 if( z[0]=='.' ){
2975 rc = do_meta_command(z, &data);
2976 if( rc && bail_on_error ) return rc;
2977 }else{
2978 open_db(&data);
2979 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
2980 if( zErrMsg!=0 ){
2981 fprintf(stderr,"Error: %s\n", zErrMsg);
2982 if( bail_on_error ) return rc!=0 ? rc : 1;
2983 }else if( rc!=0 ){
2984 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
2985 if( bail_on_error ) return rc;
2986 }
2987 }
drh1e5d0e92000-05-31 23:33:17 +00002988 }else{
shane86f5bdb2009-10-24 02:00:07 +00002989 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002990 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002991 return 1;
2992 }
2993 }
drh44c2eb12003-04-30 11:38:26 +00002994
drh22fbcb82004-02-01 01:22:50 +00002995 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002996 /* Run just the command that follows the database name
2997 */
drh22fbcb82004-02-01 01:22:50 +00002998 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00002999 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003000 }else{
drh44c2eb12003-04-30 11:38:26 +00003001 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003002 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003003 if( zErrMsg!=0 ){
3004 fprintf(stderr,"Error: %s\n", zErrMsg);
3005 return rc!=0 ? rc : 1;
3006 }else if( rc!=0 ){
3007 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3008 return rc;
drh6ff13852001-11-25 13:18:23 +00003009 }
drh75897232000-05-29 14:26:00 +00003010 }
3011 }else{
drh44c2eb12003-04-30 11:38:26 +00003012 /* Run commands received from standard input
3013 */
drhc28490c2006-10-26 14:25:58 +00003014 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003015 char *zHome;
3016 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003017 int nHistory;
drh75897232000-05-29 14:26:00 +00003018 printf(
drh743e0032011-12-12 16:51:50 +00003019 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003020 "Enter \".help\" for instructions\n"
3021 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003022 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003023 );
drh67505e72002-04-19 12:34:06 +00003024 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003025 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003026 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003027 if( (zHistory = malloc(nHistory))!=0 ){
3028 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3029 }
drh67505e72002-04-19 12:34:06 +00003030 }
danielk19774af00c62005-01-23 23:43:21 +00003031#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003032 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003033#endif
drhc28490c2006-10-26 14:25:58 +00003034 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003035 if( zHistory ){
3036 stifle_history(100);
3037 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003038 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003039 }
adamd0a3daa32006-07-28 20:16:14 +00003040 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00003041 }else{
drhc28490c2006-10-26 14:25:58 +00003042 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003043 }
3044 }
drh33048c02001-10-01 14:29:22 +00003045 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003046 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003047 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003048 }
drhc28490c2006-10-26 14:25:58 +00003049 return rc;
drh75897232000-05-29 14:26:00 +00003050}