blob: 4287ef17d816709eb81e15987b6c3000d65672b8 [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))
drhe1da8fa2012-03-30 00:05:57 +000071#define popen(a,b) _popen((a),(b))
72#define pclose(x) _pclose(x)
adamd2e8464a2006-09-06 21:39:40 +000073#else
drh4328c8b2003-04-26 02:50:11 +000074/* Make sure isatty() has a prototype.
75*/
drhb2acc3b2011-10-13 16:36:29 +000076extern int isatty(int);
adamd2e8464a2006-09-06 21:39:40 +000077#endif
drh4328c8b2003-04-26 02:50:11 +000078
chw65d3c132007-11-12 21:09:10 +000079#if defined(_WIN32_WCE)
80/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
81 * thus we always assume that we have a console. That can be
82 * overridden with the -batch command line option.
83 */
84#define isatty(x) 1
85#endif
86
drhc6e41722011-04-11 15:36:26 +000087/* True if the timer is enabled */
88static int enableTimer = 0;
89
drhf0693c82011-10-11 20:41:54 +000090/* ctype macros that work with signed characters */
91#define IsSpace(X) isspace((unsigned char)X)
92#define IsDigit(X) isdigit((unsigned char)X)
93#define ToLower(X) (char)tolower((unsigned char)X)
94
chw97185482008-11-17 08:05:31 +000095#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000096#include <sys/time.h>
97#include <sys/resource.h>
98
drhda108222009-02-25 19:07:24 +000099/* Saved resource information for the beginning of an operation */
100static struct rusage sBegin;
101
drhda108222009-02-25 19:07:24 +0000102/*
103** Begin timing an operation
104*/
105static void beginTimer(void){
106 if( enableTimer ){
107 getrusage(RUSAGE_SELF, &sBegin);
108 }
109}
110
111/* Return the difference of two time_structs in seconds */
112static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
113 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
114 (double)(pEnd->tv_sec - pStart->tv_sec);
115}
116
117/*
118** Print the timing results.
119*/
120static void endTimer(void){
121 if( enableTimer ){
122 struct rusage sEnd;
123 getrusage(RUSAGE_SELF, &sEnd);
124 printf("CPU Time: user %f sys %f\n",
125 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
126 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
127 }
128}
shaneb320ccd2009-10-21 03:42:58 +0000129
drhda108222009-02-25 19:07:24 +0000130#define BEGIN_TIMER beginTimer()
131#define END_TIMER endTimer()
132#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000133
134#elif (defined(_WIN32) || defined(WIN32))
135
136#include <windows.h>
137
138/* Saved resource information for the beginning of an operation */
139static HANDLE hProcess;
140static FILETIME ftKernelBegin;
141static FILETIME ftUserBegin;
142typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
143static GETPROCTIMES getProcessTimesAddr = NULL;
144
shaneb320ccd2009-10-21 03:42:58 +0000145/*
146** Check to see if we have timer support. Return 1 if necessary
147** support found (or found previously).
148*/
149static int hasTimer(void){
150 if( getProcessTimesAddr ){
151 return 1;
152 } else {
153 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
154 ** See if the version we are running on has it, and if it does, save off
155 ** a pointer to it and the current process handle.
156 */
157 hProcess = GetCurrentProcess();
158 if( hProcess ){
159 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
160 if( NULL != hinstLib ){
161 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
162 if( NULL != getProcessTimesAddr ){
163 return 1;
164 }
165 FreeLibrary(hinstLib);
166 }
167 }
168 }
169 return 0;
170}
171
172/*
173** Begin timing an operation
174*/
175static void beginTimer(void){
176 if( enableTimer && getProcessTimesAddr ){
177 FILETIME ftCreation, ftExit;
178 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
179 }
180}
181
182/* Return the difference of two FILETIME structs in seconds */
183static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
184 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
185 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
186 return (double) ((i64End - i64Start) / 10000000.0);
187}
188
189/*
190** Print the timing results.
191*/
192static void endTimer(void){
193 if( enableTimer && getProcessTimesAddr){
194 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
195 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
196 printf("CPU Time: user %f sys %f\n",
197 timeDiff(&ftUserBegin, &ftUserEnd),
198 timeDiff(&ftKernelBegin, &ftKernelEnd));
199 }
200}
201
202#define BEGIN_TIMER beginTimer()
203#define END_TIMER endTimer()
204#define HAS_TIMER hasTimer()
205
drhda108222009-02-25 19:07:24 +0000206#else
207#define BEGIN_TIMER
208#define END_TIMER
209#define HAS_TIMER 0
210#endif
211
shanec0688ea2009-03-05 03:48:06 +0000212/*
213** Used to prevent warnings about unused parameters
214*/
215#define UNUSED_PARAMETER(x) (void)(x)
216
drhe91d16b2008-12-08 18:27:31 +0000217/*
drhc49f44e2006-10-26 18:15:42 +0000218** If the following flag is set, then command execution stops
219** at an error if we are not interactive.
220*/
221static int bail_on_error = 0;
222
223/*
drhc28490c2006-10-26 14:25:58 +0000224** Threat stdin as an interactive input if the following variable
225** is true. Otherwise, assume stdin is connected to a file or pipe.
226*/
227static int stdin_is_interactive = 1;
228
229/*
drh4c504392000-10-16 22:06:40 +0000230** The following is the open SQLite database. We make a pointer
231** to this database a static variable so that it can be accessed
232** by the SIGINT handler to interrupt database processing.
233*/
danielk197792f9a1b2004-06-19 09:08:16 +0000234static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000235
236/*
drh67505e72002-04-19 12:34:06 +0000237** True if an interrupt (Control-C) has been received.
238*/
drh43617e92006-03-06 20:55:46 +0000239static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000240
241/*
persicom7e2dfdd2002-04-18 02:46:52 +0000242** This is the name of our program. It is set in main(), used
243** in a number of other places, mostly for error messages.
244*/
245static char *Argv0;
246
247/*
248** Prompt strings. Initialized in main. Settable with
249** .prompt main continue
250*/
251static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
252static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
253
drhb0603412007-02-28 04:47:26 +0000254/*
255** Write I/O traces to the following stream.
256*/
rsebe0a9092007-07-30 18:24:38 +0000257#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000258static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000259#endif
drhb0603412007-02-28 04:47:26 +0000260
261/*
262** This routine works like printf in that its first argument is a
263** format string and subsequent arguments are values to be substituted
264** in place of % fields. The result of formatting this string
265** is written to iotrace.
266*/
rsebe0a9092007-07-30 18:24:38 +0000267#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000268static void iotracePrintf(const char *zFormat, ...){
269 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000270 char *z;
drhb0603412007-02-28 04:47:26 +0000271 if( iotrace==0 ) return;
272 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000273 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000274 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000275 fprintf(iotrace, "%s", z);
276 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000277}
rsebe0a9092007-07-30 18:24:38 +0000278#endif
drhb0603412007-02-28 04:47:26 +0000279
drh44c2eb12003-04-30 11:38:26 +0000280
persicom7e2dfdd2002-04-18 02:46:52 +0000281/*
drh83965662003-04-17 02:54:13 +0000282** Determines if a string is a number of not.
283*/
danielk19772e588c72005-12-09 14:25:08 +0000284static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000285 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000286 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000287 return 0;
288 }
289 z++;
290 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000291 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000292 if( *z=='.' ){
293 z++;
drhf0693c82011-10-11 20:41:54 +0000294 if( !IsDigit(*z) ) return 0;
295 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000296 if( realnum ) *realnum = 1;
297 }
298 if( *z=='e' || *z=='E' ){
299 z++;
300 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000301 if( !IsDigit(*z) ) return 0;
302 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000303 if( realnum ) *realnum = 1;
304 }
305 return *z==0;
306}
drh83965662003-04-17 02:54:13 +0000307
308/*
danielk1977bc6ada42004-06-30 08:20:16 +0000309** A global char* and an SQL function to access its current value
310** from within an SQL statement. This program used to use the
311** sqlite_exec_printf() API to substitue a string into an SQL statement.
312** The correct way to do this with sqlite3 is to use the bind API, but
313** since the shell is built around the callback paradigm it would be a lot
314** of work. Instead just use this hack, which is quite harmless.
315*/
316static const char *zShellStatic = 0;
317static void shellstaticFunc(
318 sqlite3_context *context,
319 int argc,
320 sqlite3_value **argv
321){
322 assert( 0==argc );
323 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000324 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000325 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000326 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
327}
328
329
330/*
drhfeac5f82004-08-01 00:10:45 +0000331** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000332** the text in memory obtained from malloc() and returns a pointer
333** to the text. NULL is returned at end of file, or if malloc()
334** fails.
335**
336** The interface is like "readline" but no command-line editing
337** is done.
338*/
drh18f52e02012-01-16 16:56:31 +0000339static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
drh8e7e7a22000-05-30 18:45:23 +0000340 char *zLine;
341 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000342 int n;
drh18f52e02012-01-16 16:56:31 +0000343 int inQuote = 0;
drh8e7e7a22000-05-30 18:45:23 +0000344
345 if( zPrompt && *zPrompt ){
346 printf("%s",zPrompt);
347 fflush(stdout);
348 }
349 nLine = 100;
350 zLine = malloc( nLine );
351 if( zLine==0 ) return 0;
352 n = 0;
drhb07028f2011-10-14 21:49:18 +0000353 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000354 if( n+100>nLine ){
355 nLine = nLine*2 + 100;
356 zLine = realloc(zLine, nLine);
357 if( zLine==0 ) return 0;
358 }
drhdaffd0e2001-04-11 14:28:42 +0000359 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000360 if( n==0 ){
361 free(zLine);
362 return 0;
363 }
364 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000365 break;
366 }
drh18f52e02012-01-16 16:56:31 +0000367 while( zLine[n] ){
368 if( zLine[n]=='"' ) inQuote = !inQuote;
369 n++;
370 }
371 if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
drh8e7e7a22000-05-30 18:45:23 +0000372 n--;
shaneh13b36022009-12-17 21:07:15 +0000373 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000374 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000375 break;
drh8e7e7a22000-05-30 18:45:23 +0000376 }
377 }
378 zLine = realloc( zLine, n+1 );
379 return zLine;
380}
381
382/*
drhc28490c2006-10-26 14:25:58 +0000383** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000384**
385** zPrior is a string of prior text retrieved. If not the empty
386** string, then issue a continuation prompt.
387*/
drhdaffd0e2001-04-11 14:28:42 +0000388static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000389 char *zPrompt;
390 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000391 if( in!=0 ){
drh18f52e02012-01-16 16:56:31 +0000392 return local_getline(0, in, 0);
drh8e7e7a22000-05-30 18:45:23 +0000393 }
394 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000395 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000396 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000397 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000398 }
399 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000400#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000401 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000402#endif
drh8e7e7a22000-05-30 18:45:23 +0000403 return zResult;
404}
405
persicom7e2dfdd2002-04-18 02:46:52 +0000406struct previous_mode_data {
407 int valid; /* Is there legit data in here? */
408 int mode;
409 int showHeader;
410 int colWidth[100];
411};
drh45e29d82006-11-20 16:21:10 +0000412
drh8e7e7a22000-05-30 18:45:23 +0000413/*
drh75897232000-05-29 14:26:00 +0000414** An pointer to an instance of this structure is passed from
415** the main program to the callback. This is used to communicate
416** state and mode information.
417*/
418struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000419 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000420 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000421 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000422 int cnt; /* Number of records displayed so far */
423 FILE *out; /* Write results here */
drh2f464a02011-10-13 00:41:49 +0000424 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000425 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000426 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000427 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000428 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000429 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000430 int colWidth[100]; /* Requested width of each column when in column mode*/
431 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000432 char nullvalue[20]; /* The text to print when a NULL comes back from
433 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000434 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000435 /* Holds the mode information just before
436 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000437 char outfile[FILENAME_MAX]; /* Filename for *out */
438 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000439 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000440 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000441 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000442};
443
444/*
445** These are the allowed modes.
446*/
drh967e8b72000-06-21 13:59:10 +0000447#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000448#define MODE_Column 1 /* One record per line in neat columns */
449#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000450#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
451#define MODE_Html 4 /* Generate an XHTML table */
452#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000453#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000454#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000455#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000456
drh66ce4d02008-02-15 17:38:06 +0000457static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000458 "line",
459 "column",
460 "list",
461 "semi",
462 "html",
drhfeac5f82004-08-01 00:10:45 +0000463 "insert",
464 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000465 "csv",
drh66ce4d02008-02-15 17:38:06 +0000466 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000467};
drh75897232000-05-29 14:26:00 +0000468
469/*
470** Number of elements in an array
471*/
drh902b9ee2008-12-05 17:17:07 +0000472#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000473
474/*
drhea678832008-12-10 19:26:22 +0000475** Compute a string length that is limited to what can be stored in
476** lower 30 bits of a 32-bit signed integer.
477*/
drh4f21c4a2008-12-10 22:15:00 +0000478static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000479 const char *z2 = z;
480 while( *z2 ){ z2++; }
481 return 0x3fffffff & (int)(z2 - z);
482}
483
484/*
drh127f9d72010-02-23 01:47:00 +0000485** A callback for the sqlite3_log() interface.
486*/
487static void shellLog(void *pArg, int iErrCode, const char *zMsg){
488 struct callback_data *p = (struct callback_data*)pArg;
489 if( p->pLog==0 ) return;
490 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
491 fflush(p->pLog);
492}
493
494/*
shane626a6e42009-10-22 17:30:15 +0000495** Output the given string as a hex-encoded blob (eg. X'1234' )
496*/
497static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
498 int i;
499 char *zBlob = (char *)pBlob;
500 fprintf(out,"X'");
501 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); }
502 fprintf(out,"'");
503}
504
505/*
drh28bd4bc2000-06-15 15:57:22 +0000506** Output the given string as a quoted string using SQL quoting conventions.
507*/
508static void output_quoted_string(FILE *out, const char *z){
509 int i;
510 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000511 for(i=0; z[i]; i++){
512 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000513 }
514 if( nSingle==0 ){
515 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000516 }else{
517 fprintf(out,"'");
518 while( *z ){
519 for(i=0; z[i] && z[i]!='\''; i++){}
520 if( i==0 ){
521 fprintf(out,"''");
522 z++;
523 }else if( z[i]=='\'' ){
524 fprintf(out,"%.*s''",i,z);
525 z += i+1;
526 }else{
drhcd7d2732002-02-26 23:24:26 +0000527 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000528 break;
529 }
530 }
drhcd7d2732002-02-26 23:24:26 +0000531 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000532 }
533}
534
535/*
drhfeac5f82004-08-01 00:10:45 +0000536** Output the given string as a quoted according to C or TCL quoting rules.
537*/
538static void output_c_string(FILE *out, const char *z){
539 unsigned int c;
540 fputc('"', out);
541 while( (c = *(z++))!=0 ){
542 if( c=='\\' ){
543 fputc(c, out);
544 fputc(c, out);
545 }else if( c=='\t' ){
546 fputc('\\', out);
547 fputc('t', out);
548 }else if( c=='\n' ){
549 fputc('\\', out);
550 fputc('n', out);
551 }else if( c=='\r' ){
552 fputc('\\', out);
553 fputc('r', out);
554 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000555 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000556 }else{
557 fputc(c, out);
558 }
559 }
560 fputc('"', out);
561}
562
563/*
drhc08a4f12000-06-15 16:49:48 +0000564** Output the given string with characters that are special to
565** HTML escaped.
566*/
567static void output_html_string(FILE *out, const char *z){
568 int i;
569 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000570 for(i=0; z[i]
571 && z[i]!='<'
572 && z[i]!='&'
573 && z[i]!='>'
574 && z[i]!='\"'
575 && z[i]!='\'';
576 i++){}
drhc08a4f12000-06-15 16:49:48 +0000577 if( i>0 ){
578 fprintf(out,"%.*s",i,z);
579 }
580 if( z[i]=='<' ){
581 fprintf(out,"&lt;");
582 }else if( z[i]=='&' ){
583 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000584 }else if( z[i]=='>' ){
585 fprintf(out,"&gt;");
586 }else if( z[i]=='\"' ){
587 fprintf(out,"&quot;");
588 }else if( z[i]=='\'' ){
589 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000590 }else{
591 break;
592 }
593 z += i + 1;
594 }
595}
596
597/*
drhc49f44e2006-10-26 18:15:42 +0000598** If a field contains any character identified by a 1 in the following
599** array, then the string must be quoted for CSV.
600*/
601static const char needCsvQuote[] = {
602 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
603 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
604 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
608 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
609 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
617 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
618};
619
620/*
drh8e64d1c2004-10-07 00:32:39 +0000621** Output a single term of CSV. Actually, p->separator is used for
622** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000623** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000624*/
625static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000626 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000627 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000628 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000629 }else{
drhc49f44e2006-10-26 18:15:42 +0000630 int i;
drh4f21c4a2008-12-10 22:15:00 +0000631 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000632 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000633 if( needCsvQuote[((unsigned char*)z)[i]]
634 || (z[i]==p->separator[0] &&
635 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000636 i = 0;
637 break;
638 }
639 }
640 if( i==0 ){
641 putc('"', out);
642 for(i=0; z[i]; i++){
643 if( z[i]=='"' ) putc('"', out);
644 putc(z[i], out);
645 }
646 putc('"', out);
647 }else{
648 fprintf(out, "%s", z);
649 }
drh8e64d1c2004-10-07 00:32:39 +0000650 }
651 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000652 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000653 }
654}
655
danielk19774af00c62005-01-23 23:43:21 +0000656#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000657/*
drh4c504392000-10-16 22:06:40 +0000658** This routine runs when the user presses Ctrl-C
659*/
660static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000661 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000662 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000663 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000664}
danielk19774af00c62005-01-23 23:43:21 +0000665#endif
drh4c504392000-10-16 22:06:40 +0000666
667/*
shane626a6e42009-10-22 17:30:15 +0000668** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000669** invokes for each row of a query result.
670*/
shane626a6e42009-10-22 17:30:15 +0000671static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000672 int i;
673 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000674
drh75897232000-05-29 14:26:00 +0000675 switch( p->mode ){
676 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000677 int w = 5;
drh6a535342001-10-19 16:44:56 +0000678 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000679 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000680 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000681 if( len>w ) w = len;
682 }
drh75897232000-05-29 14:26:00 +0000683 if( p->cnt++>0 ) fprintf(p->out,"\n");
684 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000685 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000686 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000687 }
688 break;
689 }
danielk19770d78bae2008-01-03 07:09:48 +0000690 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000691 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000692 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000693 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000694 int w, n;
695 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000696 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000697 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000698 w = 0;
drh75897232000-05-29 14:26:00 +0000699 }
drha0c66f52000-07-29 13:20:21 +0000700 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000701 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000702 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000703 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000704 if( w<n ) w = n;
705 }
706 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000707 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000708 }
709 if( p->showHeader ){
710 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
711 }
712 }
713 if( p->showHeader ){
714 for(i=0; i<nArg; i++){
715 int w;
716 if( i<ArraySize(p->actualWidth) ){
717 w = p->actualWidth[i];
718 }else{
719 w = 10;
720 }
721 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
722 "----------------------------------------------------------",
723 i==nArg-1 ? "\n": " ");
724 }
drh75897232000-05-29 14:26:00 +0000725 }
726 }
drh6a535342001-10-19 16:44:56 +0000727 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000728 for(i=0; i<nArg; i++){
729 int w;
drha0c66f52000-07-29 13:20:21 +0000730 if( i<ArraySize(p->actualWidth) ){
731 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000732 }else{
733 w = 10;
734 }
drhea678832008-12-10 19:26:22 +0000735 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000736 strlen30(azArg[i])>w ){
737 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000738 }
drhc61053b2000-06-04 12:58:36 +0000739 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000740 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000741 }
742 break;
743 }
drhe3710332000-09-29 13:30:53 +0000744 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000745 case MODE_List: {
746 if( p->cnt++==0 && p->showHeader ){
747 for(i=0; i<nArg; i++){
748 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
749 }
750 }
drh6a535342001-10-19 16:44:56 +0000751 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000752 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000753 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000754 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000755 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000756 if( i<nArg-1 ){
757 fprintf(p->out, "%s", p->separator);
758 }else if( p->mode==MODE_Semi ){
759 fprintf(p->out, ";\n");
760 }else{
761 fprintf(p->out, "\n");
762 }
drh75897232000-05-29 14:26:00 +0000763 }
764 break;
765 }
drh1e5d0e92000-05-31 23:33:17 +0000766 case MODE_Html: {
767 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000768 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000769 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000770 fprintf(p->out,"<TH>");
771 output_html_string(p->out, azCol[i]);
772 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000773 }
mihailim57c591a2008-06-23 21:26:05 +0000774 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000775 }
drh6a535342001-10-19 16:44:56 +0000776 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000777 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000778 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000779 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000780 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000781 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000782 }
mihailim57c591a2008-06-23 21:26:05 +0000783 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000784 break;
785 }
drhfeac5f82004-08-01 00:10:45 +0000786 case MODE_Tcl: {
787 if( p->cnt++==0 && p->showHeader ){
788 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000789 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000790 fprintf(p->out, "%s", p->separator);
791 }
792 fprintf(p->out,"\n");
793 }
794 if( azArg==0 ) break;
795 for(i=0; i<nArg; i++){
796 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
797 fprintf(p->out, "%s", p->separator);
798 }
799 fprintf(p->out,"\n");
800 break;
801 }
drh8e64d1c2004-10-07 00:32:39 +0000802 case MODE_Csv: {
803 if( p->cnt++==0 && p->showHeader ){
804 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000805 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000806 }
807 fprintf(p->out,"\n");
808 }
809 if( azArg==0 ) break;
810 for(i=0; i<nArg; i++){
811 output_csv(p, azArg[i], i<nArg-1);
812 }
813 fprintf(p->out,"\n");
814 break;
815 }
drh28bd4bc2000-06-15 15:57:22 +0000816 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000817 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000818 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000819 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000820 for(i=0; i<nArg; i++){
821 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000822 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000823 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000824 }else if( aiType && aiType[i]==SQLITE_TEXT ){
825 if( zSep[0] ) fprintf(p->out,"%s",zSep);
826 output_quoted_string(p->out, azArg[i]);
827 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
828 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000829 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
830 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
831 int nBlob = sqlite3_column_bytes(p->pStmt, i);
832 if( zSep[0] ) fprintf(p->out,"%s",zSep);
833 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000834 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000835 fprintf(p->out,"%s%s",zSep, azArg[i]);
836 }else{
837 if( zSep[0] ) fprintf(p->out,"%s",zSep);
838 output_quoted_string(p->out, azArg[i]);
839 }
840 }
841 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000842 break;
drh28bd4bc2000-06-15 15:57:22 +0000843 }
persicom1d0b8722002-04-18 02:53:04 +0000844 }
drh75897232000-05-29 14:26:00 +0000845 return 0;
846}
847
848/*
shane626a6e42009-10-22 17:30:15 +0000849** This is the callback routine that the SQLite library
850** invokes for each row of a query result.
851*/
852static int callback(void *pArg, int nArg, char **azArg, char **azCol){
853 /* since we don't have type info, call the shell_callback with a NULL value */
854 return shell_callback(pArg, nArg, azArg, azCol, NULL);
855}
856
857/*
drh33048c02001-10-01 14:29:22 +0000858** Set the destination table field of the callback_data structure to
859** the name of the table given. Escape any quote characters in the
860** table name.
861*/
862static void set_table_name(struct callback_data *p, const char *zName){
863 int i, n;
864 int needQuote;
865 char *z;
866
867 if( p->zDestTable ){
868 free(p->zDestTable);
869 p->zDestTable = 0;
870 }
871 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000872 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000873 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000874 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000875 needQuote = 1;
876 if( zName[i]=='\'' ) n++;
877 }
878 }
879 if( needQuote ) n += 2;
880 z = p->zDestTable = malloc( n+1 );
881 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000882 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000883 exit(1);
884 }
885 n = 0;
886 if( needQuote ) z[n++] = '\'';
887 for(i=0; zName[i]; i++){
888 z[n++] = zName[i];
889 if( zName[i]=='\'' ) z[n++] = '\'';
890 }
891 if( needQuote ) z[n++] = '\'';
892 z[n] = 0;
893}
894
danielk19772a02e332004-06-05 08:04:36 +0000895/* zIn is either a pointer to a NULL-terminated string in memory obtained
896** from malloc(), or a NULL pointer. The string pointed to by zAppend is
897** added to zIn, and the result returned in memory obtained from malloc().
898** zIn, if it was not NULL, is freed.
899**
900** If the third argument, quote, is not '\0', then it is used as a
901** quote character for zAppend.
902*/
drhc28490c2006-10-26 14:25:58 +0000903static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000904 int len;
905 int i;
drh4f21c4a2008-12-10 22:15:00 +0000906 int nAppend = strlen30(zAppend);
907 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000908
909 len = nAppend+nIn+1;
910 if( quote ){
911 len += 2;
912 for(i=0; i<nAppend; i++){
913 if( zAppend[i]==quote ) len++;
914 }
915 }
916
917 zIn = (char *)realloc(zIn, len);
918 if( !zIn ){
919 return 0;
920 }
921
922 if( quote ){
923 char *zCsr = &zIn[nIn];
924 *zCsr++ = quote;
925 for(i=0; i<nAppend; i++){
926 *zCsr++ = zAppend[i];
927 if( zAppend[i]==quote ) *zCsr++ = quote;
928 }
929 *zCsr++ = quote;
930 *zCsr++ = '\0';
931 assert( (zCsr-zIn)==len );
932 }else{
933 memcpy(&zIn[nIn], zAppend, nAppend);
934 zIn[len-1] = '\0';
935 }
936
937 return zIn;
938}
939
drhdd3d4592004-08-30 01:54:05 +0000940
941/*
drhb21a8e42012-01-28 21:08:51 +0000942** Execute a query statement that will generate SQL output. Print
943** the result columns, comma-separated, on a line and then add a
944** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000945**
drhb21a8e42012-01-28 21:08:51 +0000946** If the number of columns is 1 and that column contains text "--"
947** then write the semicolon on a separate line. That way, if a
948** "--" comment occurs at the end of the statement, the comment
949** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000950*/
drh157e29a2009-05-21 15:15:00 +0000951static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000952 struct callback_data *p, /* Query context */
953 const char *zSelect, /* SELECT statement to extract content */
954 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000955){
drhdd3d4592004-08-30 01:54:05 +0000956 sqlite3_stmt *pSelect;
957 int rc;
drhb21a8e42012-01-28 21:08:51 +0000958 int nResult;
959 int i;
960 const char *z;
drh2f464a02011-10-13 00:41:49 +0000961 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000962 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000963 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
964 p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000965 return rc;
966 }
967 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000968 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000969 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000970 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000971 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000972 zFirstRow = 0;
973 }
drhb21a8e42012-01-28 21:08:51 +0000974 z = (const char*)sqlite3_column_text(pSelect, 0);
975 fprintf(p->out, "%s", z);
976 for(i=1; i<nResult; i++){
977 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
978 }
979 if( z==0 ) z = "";
980 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
981 if( z[0] ){
982 fprintf(p->out, "\n;\n");
983 }else{
984 fprintf(p->out, ";\n");
985 }
drhdd3d4592004-08-30 01:54:05 +0000986 rc = sqlite3_step(pSelect);
987 }
drh2f464a02011-10-13 00:41:49 +0000988 rc = sqlite3_finalize(pSelect);
989 if( rc!=SQLITE_OK ){
990 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
991 p->nErr++;
992 }
993 return rc;
drhdd3d4592004-08-30 01:54:05 +0000994}
995
shane626a6e42009-10-22 17:30:15 +0000996/*
997** Allocate space and save off current error string.
998*/
999static char *save_err_msg(
1000 sqlite3 *db /* Database to query */
1001){
1002 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1003 char *zErrMsg = sqlite3_malloc(nErrMsg);
1004 if( zErrMsg ){
1005 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1006 }
1007 return zErrMsg;
1008}
1009
1010/*
shaneh642d8b82010-07-28 16:05:34 +00001011** Display memory stats.
1012*/
1013static int display_stats(
1014 sqlite3 *db, /* Database to query */
1015 struct callback_data *pArg, /* Pointer to struct callback_data */
1016 int bReset /* True to reset the stats */
1017){
1018 int iCur;
1019 int iHiwtr;
1020
1021 if( pArg && pArg->out ){
1022
1023 iHiwtr = iCur = -1;
1024 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001025 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001026 iHiwtr = iCur = -1;
1027 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001028 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001029/*
1030** Not currently used by the CLI.
1031** iHiwtr = iCur = -1;
1032** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1033** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1034*/
1035 iHiwtr = iCur = -1;
1036 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1037 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1038/*
1039** Not currently used by the CLI.
1040** iHiwtr = iCur = -1;
1041** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1042** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1043*/
1044 iHiwtr = iCur = -1;
1045 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1046 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1047 iHiwtr = iCur = -1;
1048 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1049 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1050 iHiwtr = iCur = -1;
1051 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1052 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1053 iHiwtr = iCur = -1;
1054 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1055 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1056#ifdef YYTRACKMAXSTACKDEPTH
1057 iHiwtr = iCur = -1;
1058 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1059 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1060#endif
1061 }
1062
1063 if( pArg && pArg->out && db ){
1064 iHiwtr = iCur = -1;
1065 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1066 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001067 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1068 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1069 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1070 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1071 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1072 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001073 iHiwtr = iCur = -1;
1074 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001075 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1076 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1077 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1078 iHiwtr = iCur = -1;
1079 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1080 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001081 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001082 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1083 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1084 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001085 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1086 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1087 iHiwtr = iCur = -1;
1088 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1089 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1090 }
1091
1092 if( pArg && pArg->out && db && pArg->pStmt ){
1093 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1094 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1095 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1096 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1097 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1098 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1099 }
1100
1101 return 0;
1102}
1103
1104/*
shane626a6e42009-10-22 17:30:15 +00001105** Execute a statement or set of statements. Print
1106** any result rows/columns depending on the current mode
1107** set via the supplied callback.
1108**
1109** This is very similar to SQLite's built-in sqlite3_exec()
1110** function except it takes a slightly different callback
1111** and callback data argument.
1112*/
1113static int shell_exec(
1114 sqlite3 *db, /* An open database */
1115 const char *zSql, /* SQL to be evaluated */
1116 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1117 /* (not the same as sqlite3_exec) */
1118 struct callback_data *pArg, /* Pointer to struct callback_data */
1119 char **pzErrMsg /* Error msg written here */
1120){
dan4564ced2010-01-05 04:59:56 +00001121 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1122 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001123 int rc2;
dan4564ced2010-01-05 04:59:56 +00001124 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001125
1126 if( pzErrMsg ){
1127 *pzErrMsg = NULL;
1128 }
1129
shaneb9fc17d2009-10-22 21:23:35 +00001130 while( zSql[0] && (SQLITE_OK == rc) ){
1131 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1132 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001133 if( pzErrMsg ){
1134 *pzErrMsg = save_err_msg(db);
1135 }
1136 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001137 if( !pStmt ){
1138 /* this happens for a comment or white-space */
1139 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001140 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001141 continue;
1142 }
shane626a6e42009-10-22 17:30:15 +00001143
shaneh642d8b82010-07-28 16:05:34 +00001144 /* save off the prepared statment handle and reset row count */
1145 if( pArg ){
1146 pArg->pStmt = pStmt;
1147 pArg->cnt = 0;
1148 }
1149
shanehb7977c52010-01-18 18:17:10 +00001150 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001151 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001152 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001153 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001154 }
shanehb7977c52010-01-18 18:17:10 +00001155
drh7e02e5e2011-12-06 19:44:51 +00001156 /* Output TESTCTRL_EXPLAIN text of requested */
1157 if( pArg && pArg->mode==MODE_Explain ){
1158 const char *zExplain = 0;
1159 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1160 if( zExplain && zExplain[0] ){
1161 fprintf(pArg->out, "%s", zExplain);
1162 }
1163 }
1164
shaneb9fc17d2009-10-22 21:23:35 +00001165 /* perform the first step. this will tell us if we
1166 ** have a result set or not and how wide it is.
1167 */
1168 rc = sqlite3_step(pStmt);
1169 /* if we have a result set... */
1170 if( SQLITE_ROW == rc ){
1171 /* if we have a callback... */
1172 if( xCallback ){
1173 /* allocate space for col name ptr, value ptr, and type */
1174 int nCol = sqlite3_column_count(pStmt);
1175 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1176 if( !pData ){
1177 rc = SQLITE_NOMEM;
1178 }else{
1179 char **azCols = (char **)pData; /* Names of result columns */
1180 char **azVals = &azCols[nCol]; /* Results */
1181 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1182 int i;
1183 assert(sizeof(int) <= sizeof(char *));
1184 /* save off ptrs to column names */
1185 for(i=0; i<nCol; i++){
1186 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1187 }
shaneb9fc17d2009-10-22 21:23:35 +00001188 do{
1189 /* extract the data and data types */
1190 for(i=0; i<nCol; i++){
1191 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1192 aiTypes[i] = sqlite3_column_type(pStmt, i);
1193 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1194 rc = SQLITE_NOMEM;
1195 break; /* from for */
1196 }
1197 } /* end for */
1198
1199 /* if data and types extracted successfully... */
1200 if( SQLITE_ROW == rc ){
1201 /* call the supplied callback with the result row data */
1202 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1203 rc = SQLITE_ABORT;
1204 }else{
1205 rc = sqlite3_step(pStmt);
1206 }
1207 }
1208 } while( SQLITE_ROW == rc );
1209 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001210 }
1211 }else{
1212 do{
1213 rc = sqlite3_step(pStmt);
1214 } while( rc == SQLITE_ROW );
1215 }
1216 }
1217
shaneh642d8b82010-07-28 16:05:34 +00001218 /* print usage stats if stats on */
1219 if( pArg && pArg->statsOn ){
1220 display_stats(db, pArg, 0);
1221 }
1222
dan4564ced2010-01-05 04:59:56 +00001223 /* Finalize the statement just executed. If this fails, save a
1224 ** copy of the error message. Otherwise, set zSql to point to the
1225 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001226 rc2 = sqlite3_finalize(pStmt);
1227 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001228 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001229 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001230 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001231 }else if( pzErrMsg ){
1232 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001233 }
shaneh642d8b82010-07-28 16:05:34 +00001234
1235 /* clear saved stmt handle */
1236 if( pArg ){
1237 pArg->pStmt = NULL;
1238 }
shane626a6e42009-10-22 17:30:15 +00001239 }
shaneb9fc17d2009-10-22 21:23:35 +00001240 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001241
1242 return rc;
1243}
1244
drhdd3d4592004-08-30 01:54:05 +00001245
drh33048c02001-10-01 14:29:22 +00001246/*
drh4c653a02000-06-07 01:27:47 +00001247** This is a different callback routine used for dumping the database.
1248** Each row received by this callback consists of a table name,
1249** the table type ("index" or "table") and SQL to create the table.
1250** This routine should print text sufficient to recreate the table.
1251*/
1252static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001253 int rc;
1254 const char *zTable;
1255 const char *zType;
1256 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001257 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001258 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001259
drh902b9ee2008-12-05 17:17:07 +00001260 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001261 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001262 zTable = azArg[0];
1263 zType = azArg[1];
1264 zSql = azArg[2];
1265
drh00b950d2005-09-11 02:03:03 +00001266 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001267 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001268 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1269 fprintf(p->out, "ANALYZE sqlite_master;\n");
1270 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1271 return 0;
drh45e29d82006-11-20 16:21:10 +00001272 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1273 char *zIns;
1274 if( !p->writableSchema ){
1275 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1276 p->writableSchema = 1;
1277 }
1278 zIns = sqlite3_mprintf(
1279 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1280 "VALUES('table','%q','%q',0,'%q');",
1281 zTable, zTable, zSql);
1282 fprintf(p->out, "%s\n", zIns);
1283 sqlite3_free(zIns);
1284 return 0;
drh00b950d2005-09-11 02:03:03 +00001285 }else{
1286 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001287 }
danielk19772a02e332004-06-05 08:04:36 +00001288
1289 if( strcmp(zType, "table")==0 ){
1290 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001291 char *zSelect = 0;
1292 char *zTableInfo = 0;
1293 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001294 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001295
1296 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1297 zTableInfo = appendText(zTableInfo, zTable, '"');
1298 zTableInfo = appendText(zTableInfo, ");", 0);
1299
1300 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001301 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001302 if( rc!=SQLITE_OK || !pTableInfo ){
1303 return 1;
1304 }
1305
1306 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001307 /* Always quote the table name, even if it appears to be pure ascii,
1308 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1309 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001310 if( zTmp ){
1311 zSelect = appendText(zSelect, zTmp, '\'');
1312 }
1313 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1314 rc = sqlite3_step(pTableInfo);
1315 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001316 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001317 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001318 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001319 rc = sqlite3_step(pTableInfo);
1320 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001321 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001322 }else{
1323 zSelect = appendText(zSelect, ") ", 0);
1324 }
drh157e29a2009-05-21 15:15:00 +00001325 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001326 }
1327 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001328 if( rc!=SQLITE_OK || nRow==0 ){
1329 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001330 return 1;
1331 }
1332 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1333 zSelect = appendText(zSelect, zTable, '"');
1334
drh2f464a02011-10-13 00:41:49 +00001335 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001336 if( rc==SQLITE_CORRUPT ){
1337 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001338 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001339 }
danielk19772a02e332004-06-05 08:04:36 +00001340 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001341 }
drh4c653a02000-06-07 01:27:47 +00001342 return 0;
1343}
1344
1345/*
drh45e29d82006-11-20 16:21:10 +00001346** Run zQuery. Use dump_callback() as the callback routine so that
1347** the contents of the query are output as SQL statements.
1348**
drhdd3d4592004-08-30 01:54:05 +00001349** If we get a SQLITE_CORRUPT error, rerun the query after appending
1350** "ORDER BY rowid DESC" to the end.
1351*/
1352static int run_schema_dump_query(
1353 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001354 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001355){
1356 int rc;
drh2f464a02011-10-13 00:41:49 +00001357 char *zErr = 0;
1358 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001359 if( rc==SQLITE_CORRUPT ){
1360 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001361 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001362 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1363 if( zErr ){
1364 fprintf(p->out, "/****** %s ******/\n", zErr);
1365 sqlite3_free(zErr);
1366 zErr = 0;
1367 }
drhdd3d4592004-08-30 01:54:05 +00001368 zQ2 = malloc( len+100 );
1369 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +00001370 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001371 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1372 if( rc ){
1373 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1374 }else{
1375 rc = SQLITE_CORRUPT;
1376 }
1377 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001378 free(zQ2);
1379 }
1380 return rc;
1381}
1382
1383/*
drh75897232000-05-29 14:26:00 +00001384** Text of a help message
1385*/
persicom1d0b8722002-04-18 02:53:04 +00001386static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001387 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001388 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001389 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001390 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001391 " If TABLE specified, only dump tables matching\n"
1392 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001393 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001394 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001395 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1396 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001397 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001398 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001399 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001400 ".indices ?TABLE? Show names of all indices\n"
1401 " If TABLE specified, only show indices for tables\n"
1402 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001403#ifdef SQLITE_ENABLE_IOTRACE
1404 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1405#endif
drh70df4fe2006-06-13 15:12:21 +00001406#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001407 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001408#endif
drh127f9d72010-02-23 01:47:00 +00001409 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001410 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001411 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001412 " column Left-aligned columns. (See .width)\n"
1413 " html HTML <table> code\n"
1414 " insert SQL insert statements for TABLE\n"
1415 " line One value per line\n"
1416 " list Values delimited by .separator string\n"
1417 " tabs Tab-separated values\n"
1418 " tcl TCL list elements\n"
1419 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001420 ".output FILENAME Send output to FILENAME\n"
1421 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001422 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001423 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001424 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001425 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001426 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001427 " If TABLE specified, only show tables matching\n"
1428 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001429 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001430 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001431 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001432 ".tables ?TABLE? List names of tables\n"
1433 " If TABLE specified, only list tables matching\n"
1434 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001435 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhde60fc22011-12-14 17:53:36 +00001436 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001437 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001438;
1439
shaneb320ccd2009-10-21 03:42:58 +00001440static char zTimerHelp[] =
1441 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1442;
1443
drhdaffd0e2001-04-11 14:28:42 +00001444/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001445static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001446
drh75897232000-05-29 14:26:00 +00001447/*
drh44c2eb12003-04-30 11:38:26 +00001448** Make sure the database is open. If it is not, then open it. If
1449** the database fails to open, print an error message and exit.
1450*/
1451static void open_db(struct callback_data *p){
1452 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +00001453 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001454 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001455 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1456 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1457 shellstaticFunc, 0, 0);
1458 }
1459 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001460 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001461 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001462 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001463 }
drhc2e87a32006-06-27 15:16:14 +00001464#ifndef SQLITE_OMIT_LOAD_EXTENSION
1465 sqlite3_enable_load_extension(p->db, 1);
1466#endif
drh44c2eb12003-04-30 11:38:26 +00001467 }
1468}
1469
1470/*
drhfeac5f82004-08-01 00:10:45 +00001471** Do C-language style dequoting.
1472**
1473** \t -> tab
1474** \n -> newline
1475** \r -> carriage return
1476** \NNN -> ascii character NNN in octal
1477** \\ -> backslash
1478*/
1479static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001480 int i, j;
1481 char c;
drhfeac5f82004-08-01 00:10:45 +00001482 for(i=j=0; (c = z[i])!=0; i++, j++){
1483 if( c=='\\' ){
1484 c = z[++i];
1485 if( c=='n' ){
1486 c = '\n';
1487 }else if( c=='t' ){
1488 c = '\t';
1489 }else if( c=='r' ){
1490 c = '\r';
1491 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001492 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001493 if( z[i+1]>='0' && z[i+1]<='7' ){
1494 i++;
1495 c = (c<<3) + z[i] - '0';
1496 if( z[i+1]>='0' && z[i+1]<='7' ){
1497 i++;
1498 c = (c<<3) + z[i] - '0';
1499 }
1500 }
1501 }
1502 }
1503 z[j] = c;
1504 }
1505 z[j] = 0;
1506}
1507
1508/*
drhc28490c2006-10-26 14:25:58 +00001509** Interpret zArg as a boolean value. Return either 0 or 1.
1510*/
1511static int booleanValue(char *zArg){
1512 int val = atoi(zArg);
1513 int j;
1514 for(j=0; zArg[j]; j++){
drhf0693c82011-10-11 20:41:54 +00001515 zArg[j] = ToLower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001516 }
1517 if( strcmp(zArg,"on")==0 ){
1518 val = 1;
1519 }else if( strcmp(zArg,"yes")==0 ){
1520 val = 1;
1521 }
1522 return val;
1523}
1524
1525/*
drh75897232000-05-29 14:26:00 +00001526** If an input line begins with "." then invoke this routine to
1527** process that line.
drh67505e72002-04-19 12:34:06 +00001528**
drh47ad6842006-11-08 12:25:42 +00001529** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001530*/
drh44c2eb12003-04-30 11:38:26 +00001531static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001532 int i = 1;
1533 int nArg = 0;
1534 int n, c;
drh67505e72002-04-19 12:34:06 +00001535 int rc = 0;
drh75897232000-05-29 14:26:00 +00001536 char *azArg[50];
1537
1538 /* Parse the input line into tokens.
1539 */
1540 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001541 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001542 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001543 if( zLine[i]=='\'' || zLine[i]=='"' ){
1544 int delim = zLine[i++];
1545 azArg[nArg++] = &zLine[i];
1546 while( zLine[i] && zLine[i]!=delim ){ i++; }
1547 if( zLine[i]==delim ){
1548 zLine[i++] = 0;
1549 }
drhfeac5f82004-08-01 00:10:45 +00001550 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001551 }else{
1552 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001553 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001554 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001555 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001556 }
1557 }
1558
1559 /* Process the input line.
1560 */
shane9bd1b442009-10-23 01:27:39 +00001561 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001562 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001563 c = azArg[0][0];
shanehe2aa9d72009-11-06 17:20:17 +00001564 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00001565 const char *zDestFile;
1566 const char *zDb;
1567 sqlite3 *pDest;
1568 sqlite3_backup *pBackup;
drh9ff849f2009-02-04 20:55:57 +00001569 if( nArg==2 ){
1570 zDestFile = azArg[1];
1571 zDb = "main";
1572 }else{
1573 zDestFile = azArg[2];
1574 zDb = azArg[1];
1575 }
1576 rc = sqlite3_open(zDestFile, &pDest);
1577 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001578 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001579 sqlite3_close(pDest);
1580 return 1;
1581 }
drhdc2c4912009-02-04 22:46:47 +00001582 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001583 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1584 if( pBackup==0 ){
1585 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1586 sqlite3_close(pDest);
1587 return 1;
1588 }
1589 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1590 sqlite3_backup_finish(pBackup);
1591 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001592 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001593 }else{
1594 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001595 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001596 }
1597 sqlite3_close(pDest);
1598 }else
1599
shanehe2aa9d72009-11-06 17:20:17 +00001600 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001601 bail_on_error = booleanValue(azArg[1]);
1602 }else
1603
shanehe2aa9d72009-11-06 17:20:17 +00001604 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001605 struct callback_data data;
1606 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001607 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001608 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001609 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001610 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001611 data.colWidth[0] = 3;
1612 data.colWidth[1] = 15;
1613 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001614 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001615 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001616 if( zErrMsg ){
1617 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001618 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001619 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001620 }
1621 }else
1622
shanehe2aa9d72009-11-06 17:20:17 +00001623 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001624 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001625 /* When playing back a "dump", the content might appear in an order
1626 ** which causes immediate foreign key constraints to be violated.
1627 ** So disable foreign-key constraint enforcement to prevent problems. */
1628 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001629 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001630 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001631 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001632 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001633 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001634 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001635 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001636 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001637 );
1638 run_schema_dump_query(p,
1639 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001640 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001641 );
drh2f464a02011-10-13 00:41:49 +00001642 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001643 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001644 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001645 );
drh4c653a02000-06-07 01:27:47 +00001646 }else{
1647 int i;
drhdd3d4592004-08-30 01:54:05 +00001648 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001649 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001650 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001651 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001652 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001653 " AND sql NOT NULL");
1654 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001655 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001656 "WHERE sql NOT NULL"
1657 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001658 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001659 );
danielk1977bc6ada42004-06-30 08:20:16 +00001660 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001661 }
1662 }
drh45e29d82006-11-20 16:21:10 +00001663 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001664 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001665 p->writableSchema = 0;
1666 }
drh56197952011-10-13 16:30:13 +00001667 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1668 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001669 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001670 }else
drh75897232000-05-29 14:26:00 +00001671
shanehe2aa9d72009-11-06 17:20:17 +00001672 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001673 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001674 }else
1675
shanehe2aa9d72009-11-06 17:20:17 +00001676 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00001677 rc = 2;
drh75897232000-05-29 14:26:00 +00001678 }else
1679
shanehe2aa9d72009-11-06 17:20:17 +00001680 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001681 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001682 if(val == 1) {
1683 if(!p->explainPrev.valid) {
1684 p->explainPrev.valid = 1;
1685 p->explainPrev.mode = p->mode;
1686 p->explainPrev.showHeader = p->showHeader;
1687 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1688 }
1689 /* We could put this code under the !p->explainValid
1690 ** condition so that it does not execute if we are already in
1691 ** explain mode. However, always executing it allows us an easy
1692 ** was to reset to explain mode in case the user previously
1693 ** did an .explain followed by a .width, .mode or .header
1694 ** command.
1695 */
danielk19770d78bae2008-01-03 07:09:48 +00001696 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001697 p->showHeader = 1;
1698 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001699 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001700 p->colWidth[1] = 13; /* opcode */
1701 p->colWidth[2] = 4; /* P1 */
1702 p->colWidth[3] = 4; /* P2 */
1703 p->colWidth[4] = 4; /* P3 */
1704 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001705 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001706 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001707 }else if (p->explainPrev.valid) {
1708 p->explainPrev.valid = 0;
1709 p->mode = p->explainPrev.mode;
1710 p->showHeader = p->explainPrev.showHeader;
1711 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1712 }
drh75897232000-05-29 14:26:00 +00001713 }else
1714
drhc28490c2006-10-26 14:25:58 +00001715 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001716 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001717 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001718 }else
1719
1720 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001721 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001722 if( HAS_TIMER ){
1723 fprintf(stderr,"%s",zTimerHelp);
1724 }
drh75897232000-05-29 14:26:00 +00001725 }else
1726
shanehe2aa9d72009-11-06 17:20:17 +00001727 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001728 char *zTable = azArg[2]; /* Insert data into this table */
1729 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001730 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001731 int nCol; /* Number of columns in the table */
1732 int nByte; /* Number of bytes in an SQL string */
1733 int i, j; /* Loop counters */
1734 int nSep; /* Number of bytes in p->separator[] */
1735 char *zSql; /* An SQL statement */
1736 char *zLine; /* A single line of input from the file */
1737 char **azCol; /* zLine[] broken up into columns */
1738 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001739 FILE *in; /* The input file */
1740 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001741
drha543c822006-06-08 16:10:14 +00001742 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001743 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001744 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001745 fprintf(stderr, "Error: non-null separator required for import\n");
1746 return 1;
drhfeac5f82004-08-01 00:10:45 +00001747 }
drh7b075e32011-09-28 01:10:00 +00001748 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00001749 if( zSql==0 ){
1750 fprintf(stderr, "Error: out of memory\n");
1751 return 1;
1752 }
drh4f21c4a2008-12-10 22:15:00 +00001753 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001754 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001755 sqlite3_free(zSql);
1756 if( rc ){
shane916f9612009-10-23 00:37:15 +00001757 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001758 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001759 return 1;
drhfeac5f82004-08-01 00:10:45 +00001760 }
shane916f9612009-10-23 00:37:15 +00001761 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001762 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001763 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001764 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001765 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001766 if( zSql==0 ){
1767 fprintf(stderr, "Error: out of memory\n");
1768 return 1;
1769 }
drh7b075e32011-09-28 01:10:00 +00001770 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001771 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001772 for(i=1; i<nCol; i++){
1773 zSql[j++] = ',';
1774 zSql[j++] = '?';
1775 }
1776 zSql[j++] = ')';
1777 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001778 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001779 free(zSql);
1780 if( rc ){
1781 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001782 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001783 return 1;
drhfeac5f82004-08-01 00:10:45 +00001784 }
1785 in = fopen(zFile, "rb");
1786 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001787 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001788 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001789 return 1;
drhfeac5f82004-08-01 00:10:45 +00001790 }
1791 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001792 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001793 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001794 fclose(in);
shane916f9612009-10-23 00:37:15 +00001795 sqlite3_finalize(pStmt);
1796 return 1;
drh43617e92006-03-06 20:55:46 +00001797 }
drhfeac5f82004-08-01 00:10:45 +00001798 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1799 zCommit = "COMMIT";
drh18f52e02012-01-16 16:56:31 +00001800 while( (zLine = local_getline(0, in, 1))!=0 ){
1801 char *z, c;
1802 int inQuote = 0;
drhb860bc92004-08-04 15:16:55 +00001803 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001804 azCol[0] = zLine;
drh18f52e02012-01-16 16:56:31 +00001805 for(i=0, z=zLine; (c = *z)!=0; z++){
1806 if( c=='"' ) inQuote = !inQuote;
1807 if( c=='\n' ) lineno++;
1808 if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001809 *z = 0;
1810 i++;
drhb860bc92004-08-04 15:16:55 +00001811 if( i<nCol ){
1812 azCol[i] = &z[nSep];
1813 z += nSep-1;
1814 }
drhfeac5f82004-08-01 00:10:45 +00001815 }
shane916f9612009-10-23 00:37:15 +00001816 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001817 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001818 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001819 fprintf(stderr,
1820 "Error: %s line %d: expected %d columns of data but found %d\n",
1821 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001822 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001823 free(zLine);
shane916f9612009-10-23 00:37:15 +00001824 rc = 1;
1825 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001826 }
drhfeac5f82004-08-01 00:10:45 +00001827 for(i=0; i<nCol; i++){
drh18f52e02012-01-16 16:56:31 +00001828 if( azCol[i][0]=='"' ){
1829 int k;
1830 for(z=azCol[i], j=1, k=0; z[j]; j++){
1831 if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1832 z[k++] = z[j];
1833 }
1834 z[k] = 0;
1835 }
drhfeac5f82004-08-01 00:10:45 +00001836 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1837 }
1838 sqlite3_step(pStmt);
1839 rc = sqlite3_reset(pStmt);
1840 free(zLine);
1841 if( rc!=SQLITE_OK ){
1842 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1843 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001844 rc = 1;
shane916f9612009-10-23 00:37:15 +00001845 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00001846 }
shane916f9612009-10-23 00:37:15 +00001847 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00001848 free(azCol);
1849 fclose(in);
1850 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001851 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001852 }else
1853
shanehe2aa9d72009-11-06 17:20:17 +00001854 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00001855 struct callback_data data;
1856 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001857 open_db(p);
drh75897232000-05-29 14:26:00 +00001858 memcpy(&data, p, sizeof(data));
1859 data.showHeader = 0;
1860 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00001861 if( nArg==1 ){
1862 rc = sqlite3_exec(p->db,
1863 "SELECT name FROM sqlite_master "
1864 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
1865 "UNION ALL "
1866 "SELECT name FROM sqlite_temp_master "
1867 "WHERE type='index' "
1868 "ORDER BY 1",
1869 callback, &data, &zErrMsg
1870 );
1871 }else{
1872 zShellStatic = azArg[1];
1873 rc = sqlite3_exec(p->db,
1874 "SELECT name FROM sqlite_master "
1875 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1876 "UNION ALL "
1877 "SELECT name FROM sqlite_temp_master "
1878 "WHERE type='index' AND tbl_name LIKE shellstatic() "
1879 "ORDER BY 1",
1880 callback, &data, &zErrMsg
1881 );
1882 zShellStatic = 0;
1883 }
drh75897232000-05-29 14:26:00 +00001884 if( zErrMsg ){
1885 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001886 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001887 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00001888 }else if( rc != SQLITE_OK ){
1889 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
1890 rc = 1;
drh75897232000-05-29 14:26:00 +00001891 }
1892 }else
1893
drhae5e4452007-05-03 17:18:36 +00001894#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001895 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001896 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001897 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1898 iotrace = 0;
1899 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001900 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001901 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001902 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001903 iotrace = stdout;
1904 }else{
1905 iotrace = fopen(azArg[1], "w");
1906 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00001907 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001908 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00001909 rc = 1;
drhb0603412007-02-28 04:47:26 +00001910 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001911 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001912 }
1913 }
1914 }else
drhae5e4452007-05-03 17:18:36 +00001915#endif
drhb0603412007-02-28 04:47:26 +00001916
drh70df4fe2006-06-13 15:12:21 +00001917#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001918 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1919 const char *zFile, *zProc;
1920 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00001921 zFile = azArg[1];
1922 zProc = nArg>=3 ? azArg[2] : 0;
1923 open_db(p);
1924 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1925 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001926 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00001927 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001928 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001929 }
1930 }else
drh70df4fe2006-06-13 15:12:21 +00001931#endif
drh1e397f82006-06-08 15:28:43 +00001932
drhc8ba2122011-03-23 11:16:22 +00001933 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00001934 const char *zFile = azArg[1];
1935 if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
1936 fclose(p->pLog);
1937 p->pLog = 0;
1938 }
1939 if( strcmp(zFile,"stdout")==0 ){
1940 p->pLog = stdout;
1941 }else if( strcmp(zFile, "stderr")==0 ){
1942 p->pLog = stderr;
1943 }else if( strcmp(zFile, "off")==0 ){
1944 p->pLog = 0;
1945 }else{
1946 p->pLog = fopen(zFile, "w");
1947 if( p->pLog==0 ){
1948 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1949 }
1950 }
1951 }else
1952
shanehe2aa9d72009-11-06 17:20:17 +00001953 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00001954 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00001955 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001956 ||
shanehe2aa9d72009-11-06 17:20:17 +00001957 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001958 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00001959 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00001960 ||
shanehe2aa9d72009-11-06 17:20:17 +00001961 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00001962 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00001963 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001964 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00001965 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001966 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00001967 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001968 p->mode = MODE_Tcl;
shanehe2aa9d72009-11-06 17:20:17 +00001969 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001970 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001971 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00001972 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001973 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001974 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00001975 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00001976 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00001977 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00001978 }else {
shane9bd1b442009-10-23 01:27:39 +00001979 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001980 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00001981 rc = 1;
drh75897232000-05-29 14:26:00 +00001982 }
1983 }else
1984
shanehe2aa9d72009-11-06 17:20:17 +00001985 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
1986 int n2 = strlen30(azArg[1]);
1987 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
1988 p->mode = MODE_Insert;
1989 set_table_name(p, azArg[2]);
1990 }else {
1991 fprintf(stderr, "Error: invalid arguments: "
1992 " \"%s\". Enter \".help\" for help\n", azArg[2]);
1993 rc = 1;
1994 }
1995 }else
1996
persicom7e2dfdd2002-04-18 02:46:52 +00001997 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001998 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1999 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002000 }else
2001
drh75897232000-05-29 14:26:00 +00002002 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
2003 if( p->out!=stdout ){
drhe1da8fa2012-03-30 00:05:57 +00002004 if( p->outfile[0]=='|' ){
2005 pclose(p->out);
2006 }else{
2007 fclose(p->out);
2008 }
drh75897232000-05-29 14:26:00 +00002009 }
2010 if( strcmp(azArg[1],"stdout")==0 ){
2011 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00002012 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drhe1da8fa2012-03-30 00:05:57 +00002013 }else if( azArg[1][0]=='|' ){
2014 p->out = popen(&azArg[1][1], "w");
2015 if( p->out==0 ){
2016 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2017 p->out = stdout;
2018 rc = 1;
2019 }else{
2020 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2021 }
drh75897232000-05-29 14:26:00 +00002022 }else{
drha1f9b5e2004-02-14 16:31:02 +00002023 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00002024 if( p->out==0 ){
shane9bd1b442009-10-23 01:27:39 +00002025 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
drh75897232000-05-29 14:26:00 +00002026 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002027 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002028 } else {
drh5bb3eb92007-05-04 13:15:55 +00002029 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002030 }
2031 }
2032 }else
2033
drhdd45df82002-04-18 12:39:03 +00002034 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002035 if( nArg >= 2) {
2036 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2037 }
2038 if( nArg >= 3) {
2039 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2040 }
2041 }else
2042
shanehe2aa9d72009-11-06 17:20:17 +00002043 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002044 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002045 }else
2046
drh9ff849f2009-02-04 20:55:57 +00002047 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002048 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002049 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002050 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2051 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002052 }else{
shane9bd1b442009-10-23 01:27:39 +00002053 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002054 fclose(alt);
2055 }
2056 }else
2057
shanehe2aa9d72009-11-06 17:20:17 +00002058 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002059 const char *zSrcFile;
2060 const char *zDb;
2061 sqlite3 *pSrc;
2062 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002063 int nTimeout = 0;
2064
drh9ff849f2009-02-04 20:55:57 +00002065 if( nArg==2 ){
2066 zSrcFile = azArg[1];
2067 zDb = "main";
2068 }else{
2069 zSrcFile = azArg[2];
2070 zDb = azArg[1];
2071 }
2072 rc = sqlite3_open(zSrcFile, &pSrc);
2073 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002074 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002075 sqlite3_close(pSrc);
2076 return 1;
2077 }
drhdc2c4912009-02-04 22:46:47 +00002078 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002079 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2080 if( pBackup==0 ){
2081 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2082 sqlite3_close(pSrc);
2083 return 1;
2084 }
drhdc2c4912009-02-04 22:46:47 +00002085 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2086 || rc==SQLITE_BUSY ){
2087 if( rc==SQLITE_BUSY ){
2088 if( nTimeout++ >= 3 ) break;
2089 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002090 }
2091 }
2092 sqlite3_backup_finish(pBackup);
2093 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002094 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002095 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002096 fprintf(stderr, "Error: source database is busy\n");
2097 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002098 }else{
2099 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002100 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002101 }
2102 sqlite3_close(pSrc);
2103 }else
2104
shanehe2aa9d72009-11-06 17:20:17 +00002105 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002106 struct callback_data data;
2107 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002108 open_db(p);
drh75897232000-05-29 14:26:00 +00002109 memcpy(&data, p, sizeof(data));
2110 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002111 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002112 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002113 int i;
drhf0693c82011-10-11 20:41:54 +00002114 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002115 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002116 char *new_argv[2], *new_colv[2];
2117 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2118 " type text,\n"
2119 " name text,\n"
2120 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002121 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002122 " 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;
drhc8d74412004-08-31 23:41:26 +00002129 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002130 char *new_argv[2], *new_colv[2];
2131 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2132 " type text,\n"
2133 " name text,\n"
2134 " tbl_name text,\n"
2135 " rootpage integer,\n"
2136 " sql text\n"
2137 ")";
2138 new_argv[1] = 0;
2139 new_colv[0] = "sql";
2140 new_colv[1] = 0;
2141 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002142 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002143 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002144 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002145 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002146 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002147 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2148 " FROM sqlite_master UNION ALL"
2149 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002150 "WHERE lower(tbl_name) LIKE shellstatic()"
2151 " AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00002152 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00002153 callback, &data, &zErrMsg);
2154 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002155 }
drh75897232000-05-29 14:26:00 +00002156 }else{
shane9bd1b442009-10-23 01:27:39 +00002157 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002158 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00002159 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
2160 " FROM sqlite_master UNION ALL"
2161 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002162 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00002163 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00002164 callback, &data, &zErrMsg
2165 );
drh75897232000-05-29 14:26:00 +00002166 }
drh75897232000-05-29 14:26:00 +00002167 if( zErrMsg ){
2168 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002169 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002170 rc = 1;
2171 }else if( rc != SQLITE_OK ){
2172 fprintf(stderr,"Error: querying schema information\n");
2173 rc = 1;
2174 }else{
2175 rc = 0;
drh75897232000-05-29 14:26:00 +00002176 }
2177 }else
2178
2179 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002180 sqlite3_snprintf(sizeof(p->separator), p->separator,
2181 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002182 }else
2183
shanehe2aa9d72009-11-06 17:20:17 +00002184 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002185 int i;
2186 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002187 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002188 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002189 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002190 fprintf(p->out,"%9.9s: ", "nullvalue");
2191 output_c_string(p->out, p->nullvalue);
2192 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002193 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002194 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002195 fprintf(p->out,"%9.9s: ", "separator");
2196 output_c_string(p->out, p->separator);
2197 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002198 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002199 fprintf(p->out,"%9.9s: ","width");
2200 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002201 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002202 }
drhfeac5f82004-08-01 00:10:45 +00002203 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002204 }else
2205
shaneh642d8b82010-07-28 16:05:34 +00002206 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2207 p->statsOn = booleanValue(azArg[1]);
2208 }else
2209
shanehe2aa9d72009-11-06 17:20:17 +00002210 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drhe3710332000-09-29 13:30:53 +00002211 char **azResult;
shane9bd1b442009-10-23 01:27:39 +00002212 int nRow;
drhe3710332000-09-29 13:30:53 +00002213 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00002214 open_db(p);
drha50da102000-08-08 20:19:09 +00002215 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00002216 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002217 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002218 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' "
drhe0bc4042002-06-25 01:09:11 +00002219 "UNION ALL "
2220 "SELECT name FROM sqlite_temp_master "
2221 "WHERE type IN ('table','view') "
2222 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00002223 &azResult, &nRow, 0, &zErrMsg
2224 );
drha50da102000-08-08 20:19:09 +00002225 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002226 zShellStatic = azArg[1];
2227 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00002228 "SELECT name FROM sqlite_master "
shane86f5bdb2009-10-24 02:00:07 +00002229 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002230 "UNION ALL "
2231 "SELECT name FROM sqlite_temp_master "
shane86f5bdb2009-10-24 02:00:07 +00002232 "WHERE type IN ('table','view') AND name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00002233 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00002234 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00002235 );
danielk1977bc6ada42004-06-30 08:20:16 +00002236 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00002237 }
drh75897232000-05-29 14:26:00 +00002238 if( zErrMsg ){
2239 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002240 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002241 rc = 1;
2242 }else if( rc != SQLITE_OK ){
2243 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2244 rc = 1;
2245 }else{
drhe3710332000-09-29 13:30:53 +00002246 int len, maxlen = 0;
2247 int i, j;
2248 int nPrintCol, nPrintRow;
2249 for(i=1; i<=nRow; i++){
2250 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00002251 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002252 if( len>maxlen ) maxlen = len;
2253 }
2254 nPrintCol = 80/(maxlen+2);
2255 if( nPrintCol<1 ) nPrintCol = 1;
2256 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2257 for(i=0; i<nPrintRow; i++){
2258 for(j=i+1; j<=nRow; j+=nPrintRow){
2259 char *zSp = j<=nPrintRow ? "" : " ";
2260 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
2261 }
2262 printf("\n");
2263 }
2264 }
danielk19776f8a5032004-05-10 10:34:51 +00002265 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00002266 }else
2267
shaneh96887e12011-02-10 21:08:58 +00002268 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002269 static const struct {
2270 const char *zCtrlName; /* Name of a test-control option */
2271 int ctrlCode; /* Integer code for that option */
2272 } aCtrl[] = {
2273 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2274 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2275 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2276 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2277 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2278 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2279 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2280 { "assert", SQLITE_TESTCTRL_ASSERT },
2281 { "always", SQLITE_TESTCTRL_ALWAYS },
2282 { "reserve", SQLITE_TESTCTRL_RESERVE },
2283 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2284 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002285 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2286 };
shaneh96887e12011-02-10 21:08:58 +00002287 int testctrl = -1;
2288 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002289 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002290 open_db(p);
2291
drhd416fe72011-03-17 16:45:50 +00002292 /* convert testctrl text option to value. allow any unique prefix
2293 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002294 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002295 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002296 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2297 if( testctrl<0 ){
2298 testctrl = aCtrl[i].ctrlCode;
2299 }else{
drhb07028f2011-10-14 21:49:18 +00002300 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002301 testctrl = -1;
2302 break;
2303 }
2304 }
2305 }
2306 if( testctrl<0 ) testctrl = atoi(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002307 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2308 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2309 }else{
2310 switch(testctrl){
2311
2312 /* sqlite3_test_control(int, db, int) */
2313 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2314 case SQLITE_TESTCTRL_RESERVE:
2315 if( nArg==3 ){
2316 int opt = (int)strtol(azArg[2], 0, 0);
2317 rc = sqlite3_test_control(testctrl, p->db, opt);
2318 printf("%d (0x%08x)\n", rc, rc);
2319 } else {
drhd416fe72011-03-17 16:45:50 +00002320 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2321 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002322 }
2323 break;
2324
2325 /* sqlite3_test_control(int) */
2326 case SQLITE_TESTCTRL_PRNG_SAVE:
2327 case SQLITE_TESTCTRL_PRNG_RESTORE:
2328 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002329 if( nArg==2 ){
2330 rc = sqlite3_test_control(testctrl);
2331 printf("%d (0x%08x)\n", rc, rc);
2332 } else {
2333 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2334 }
2335 break;
2336
2337 /* sqlite3_test_control(int, uint) */
2338 case SQLITE_TESTCTRL_PENDING_BYTE:
2339 if( nArg==3 ){
2340 unsigned int opt = (unsigned int)atoi(azArg[2]);
2341 rc = sqlite3_test_control(testctrl, opt);
2342 printf("%d (0x%08x)\n", rc, rc);
2343 } else {
drhd416fe72011-03-17 16:45:50 +00002344 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2345 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002346 }
2347 break;
2348
2349 /* sqlite3_test_control(int, int) */
2350 case SQLITE_TESTCTRL_ASSERT:
2351 case SQLITE_TESTCTRL_ALWAYS:
2352 if( nArg==3 ){
2353 int opt = atoi(azArg[2]);
2354 rc = sqlite3_test_control(testctrl, opt);
2355 printf("%d (0x%08x)\n", rc, rc);
2356 } else {
drhd416fe72011-03-17 16:45:50 +00002357 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2358 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002359 }
2360 break;
2361
2362 /* sqlite3_test_control(int, char *) */
2363#ifdef SQLITE_N_KEYWORD
2364 case SQLITE_TESTCTRL_ISKEYWORD:
2365 if( nArg==3 ){
2366 const char *opt = azArg[2];
2367 rc = sqlite3_test_control(testctrl, opt);
2368 printf("%d (0x%08x)\n", rc, rc);
2369 } else {
drhd416fe72011-03-17 16:45:50 +00002370 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2371 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002372 }
2373 break;
2374#endif
2375
2376 case SQLITE_TESTCTRL_BITVEC_TEST:
2377 case SQLITE_TESTCTRL_FAULT_INSTALL:
2378 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2379 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2380 default:
drhd416fe72011-03-17 16:45:50 +00002381 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2382 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002383 break;
2384 }
2385 }
2386 }else
2387
shanehe2aa9d72009-11-06 17:20:17 +00002388 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002389 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00002390 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002391 }else
2392
drhd416fe72011-03-17 16:45:50 +00002393 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2394 && nArg==2
2395 ){
drh3b1a9882007-11-02 12:53:03 +00002396 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002397 }else
2398
drh9fd301b2011-06-03 13:28:22 +00002399 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh743e0032011-12-12 16:51:50 +00002400 printf("SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002401 sqlite3_libversion(), sqlite3_sourceid());
2402 }else
2403
drhde60fc22011-12-14 17:53:36 +00002404 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2405 const char *zDbName = nArg==2 ? azArg[1] : "main";
2406 char *zVfsName = 0;
2407 if( p->db ){
2408 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2409 if( zVfsName ){
2410 printf("%s\n", zVfsName);
2411 sqlite3_free(zVfsName);
2412 }
2413 }
2414 }else
2415
shanehe2aa9d72009-11-06 17:20:17 +00002416 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002417 int j;
drh43617e92006-03-06 20:55:46 +00002418 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002419 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
2420 p->colWidth[j-1] = atoi(azArg[j]);
2421 }
2422 }else
2423
2424 {
shane9bd1b442009-10-23 01:27:39 +00002425 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002426 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002427 rc = 1;
drh75897232000-05-29 14:26:00 +00002428 }
drh67505e72002-04-19 12:34:06 +00002429
2430 return rc;
drh75897232000-05-29 14:26:00 +00002431}
2432
drh67505e72002-04-19 12:34:06 +00002433/*
drh91a66392007-09-07 01:12:32 +00002434** Return TRUE if a semicolon occurs anywhere in the first N characters
2435** of string z[].
drh324ccef2003-02-05 14:06:20 +00002436*/
drh91a66392007-09-07 01:12:32 +00002437static int _contains_semicolon(const char *z, int N){
2438 int i;
2439 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2440 return 0;
drh324ccef2003-02-05 14:06:20 +00002441}
2442
2443/*
drh70c7a4b2003-04-26 03:03:06 +00002444** Test to see if a line consists entirely of whitespace.
2445*/
2446static int _all_whitespace(const char *z){
2447 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002448 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002449 if( *z=='/' && z[1]=='*' ){
2450 z += 2;
2451 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2452 if( *z==0 ) return 0;
2453 z++;
2454 continue;
2455 }
2456 if( *z=='-' && z[1]=='-' ){
2457 z += 2;
2458 while( *z && *z!='\n' ){ z++; }
2459 if( *z==0 ) return 1;
2460 continue;
2461 }
2462 return 0;
2463 }
2464 return 1;
2465}
2466
2467/*
drha9b17162003-04-29 18:01:28 +00002468** Return TRUE if the line typed in is an SQL command terminator other
2469** than a semi-colon. The SQL Server style "go" command is understood
2470** as is the Oracle "/".
2471*/
2472static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002473 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002474 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2475 return 1; /* Oracle */
2476 }
drhf0693c82011-10-11 20:41:54 +00002477 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002478 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002479 return 1; /* SQL Server */
2480 }
2481 return 0;
2482}
2483
2484/*
drh233a5312008-12-18 22:25:13 +00002485** Return true if zSql is a complete SQL statement. Return false if it
2486** ends in the middle of a string literal or C-style comment.
2487*/
2488static int _is_complete(char *zSql, int nSql){
2489 int rc;
2490 if( zSql==0 ) return 1;
2491 zSql[nSql] = ';';
2492 zSql[nSql+1] = 0;
2493 rc = sqlite3_complete(zSql);
2494 zSql[nSql] = 0;
2495 return rc;
2496}
2497
2498/*
drh67505e72002-04-19 12:34:06 +00002499** Read input from *in and process it. If *in==0 then input
2500** is interactive - the user is typing it it. Otherwise, input
2501** is coming from a file or device. A prompt is issued and history
2502** is saved only if input is interactive. An interrupt signal will
2503** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002504**
2505** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002506*/
drhc28490c2006-10-26 14:25:58 +00002507static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002508 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002509 char *zSql = 0;
2510 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002511 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002512 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002513 int rc;
2514 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002515 int lineno = 0;
2516 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002517
2518 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2519 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002520 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002521 zLine = one_input_line(zSql, in);
2522 if( zLine==0 ){
2523 break; /* We have reached EOF */
2524 }
drh67505e72002-04-19 12:34:06 +00002525 if( seenInterrupt ){
2526 if( in!=0 ) break;
2527 seenInterrupt = 0;
2528 }
drhc28490c2006-10-26 14:25:58 +00002529 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002530 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002531 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002532 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002533 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002534 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002535 break;
2536 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002537 errCnt++;
2538 }
drhdaffd0e2001-04-11 14:28:42 +00002539 continue;
2540 }
drh233a5312008-12-18 22:25:13 +00002541 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002542 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002543 }
drh91a66392007-09-07 01:12:32 +00002544 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002545 if( zSql==0 ){
2546 int i;
drhf0693c82011-10-11 20:41:54 +00002547 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002548 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002549 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002550 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002551 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002552 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002553 exit(1);
2554 }
drh5bb3eb92007-05-04 13:15:55 +00002555 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002556 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002557 }
2558 }else{
drh4f21c4a2008-12-10 22:15:00 +00002559 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002560 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002561 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002562 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002563 exit(1);
2564 }
drh5bb3eb92007-05-04 13:15:55 +00002565 zSql[nSql++] = '\n';
2566 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002567 nSql += len;
2568 }
drh91a66392007-09-07 01:12:32 +00002569 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2570 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002571 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002572 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002573 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002574 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002575 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002576 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002577 char zPrefix[100];
2578 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002579 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002580 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002581 }else{
shane9bd1b442009-10-23 01:27:39 +00002582 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002583 }
drh7f953e22002-07-13 17:33:45 +00002584 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002585 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002586 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002587 zErrMsg = 0;
2588 }else{
shaned2bed1c2009-10-21 03:56:54 +00002589 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002590 }
drhc49f44e2006-10-26 18:15:42 +00002591 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002592 }
2593 free(zSql);
2594 zSql = 0;
2595 nSql = 0;
2596 }
2597 }
2598 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002599 if( !_all_whitespace(zSql) ){
2600 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2601 }
drhdaffd0e2001-04-11 14:28:42 +00002602 free(zSql);
2603 }
danielk19772ac27622007-07-03 05:31:16 +00002604 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002605 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00002606}
2607
drh67505e72002-04-19 12:34:06 +00002608/*
2609** Return a pathname which is the user's home directory. A
2610** 0 return indicates an error of some kind. Space to hold the
2611** resulting string is obtained from malloc(). The calling
2612** function should free the result.
2613*/
2614static char *find_home_dir(void){
2615 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00002616
chw97185482008-11-17 08:05:31 +00002617#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00002618 struct passwd *pwent;
2619 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00002620 if( (pwent=getpwuid(uid)) != NULL) {
2621 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00002622 }
2623#endif
2624
chw65d3c132007-11-12 21:09:10 +00002625#if defined(_WIN32_WCE)
2626 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2627 */
2628 home_dir = strdup("/");
2629#else
2630
drh164a1b62006-08-19 11:15:20 +00002631#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
2632 if (!home_dir) {
2633 home_dir = getenv("USERPROFILE");
2634 }
2635#endif
2636
drh67505e72002-04-19 12:34:06 +00002637 if (!home_dir) {
2638 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002639 }
2640
drhcdb36b72006-06-12 12:57:45 +00002641#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00002642 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002643 char *zDrive, *zPath;
2644 int n;
2645 zDrive = getenv("HOMEDRIVE");
2646 zPath = getenv("HOMEPATH");
2647 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002648 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002649 home_dir = malloc( n );
2650 if( home_dir==0 ) return 0;
2651 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2652 return home_dir;
2653 }
2654 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002655 }
2656#endif
2657
chw65d3c132007-11-12 21:09:10 +00002658#endif /* !_WIN32_WCE */
2659
drh67505e72002-04-19 12:34:06 +00002660 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002661 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002662 char *z = malloc( n );
2663 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002664 home_dir = z;
2665 }
drhe98d4fa2002-04-21 19:06:22 +00002666
drh67505e72002-04-19 12:34:06 +00002667 return home_dir;
2668}
2669
2670/*
2671** Read input from the file given by sqliterc_override. Or if that
2672** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002673**
2674** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002675*/
shane9bd1b442009-10-23 01:27:39 +00002676static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002677 struct callback_data *p, /* Configuration data */
2678 const char *sqliterc_override /* Name of config file. NULL to use default */
2679){
persicom7e2dfdd2002-04-18 02:46:52 +00002680 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002681 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002682 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002683 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00002684 int nBuf;
shane9bd1b442009-10-23 01:27:39 +00002685 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002686
2687 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002688 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002689 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002690#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002691 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002692#endif
shane9bd1b442009-10-23 01:27:39 +00002693 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002694 }
drh4f21c4a2008-12-10 22:15:00 +00002695 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00002696 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00002697 if( zBuf==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002698 fprintf(stderr,"%s: Error: out of memory\n",Argv0);
2699 return 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002700 }
drha959ac42007-06-20 13:10:00 +00002701 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00002702 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00002703 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002704 }
drha1f9b5e2004-02-14 16:31:02 +00002705 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002706 if( in ){
drhc28490c2006-10-26 14:25:58 +00002707 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002708 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002709 }
shane9bd1b442009-10-23 01:27:39 +00002710 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002711 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002712 }
drh43617e92006-03-06 20:55:46 +00002713 free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002714 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002715}
2716
drh67505e72002-04-19 12:34:06 +00002717/*
drhe1e38c42003-05-04 18:30:59 +00002718** Show available command line options
2719*/
2720static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00002721 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00002722 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002723 " -column set output mode to 'column'\n"
drhcc3b4f82012-02-07 14:13:50 +00002724 " -cmd command run \"command\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00002725 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00002726 " -echo print commands before execution\n"
2727 " -init filename read/process named file\n"
2728 " -[no]header turn headers on or off\n"
2729 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002730 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00002731 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002732 " -line set output mode to 'line'\n"
2733 " -list set output mode to 'list'\n"
drhcc3b4f82012-02-07 14:13:50 +00002734#ifdef SQLITE_ENABLE_MULTIPLEX
2735 " -multiplex enable the multiplexor VFS\n"
2736#endif
2737 " -nullvalue 'text' set text string for NULL values\n"
drhe1e38c42003-05-04 18:30:59 +00002738 " -separator 'x' set output field separator (|)\n"
shaneh642d8b82010-07-28 16:05:34 +00002739 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002740 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002741 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00002742#ifdef SQLITE_ENABLE_VFSTRACE
2743 " -vfstrace enable tracing of all VFS calls\n"
2744#endif
drhe1e38c42003-05-04 18:30:59 +00002745;
2746static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002747 fprintf(stderr,
2748 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2749 "FILENAME is the name of an SQLite database. A new database is created\n"
2750 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002751 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002752 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002753 }else{
2754 fprintf(stderr, "Use the -help option for additional information\n");
2755 }
2756 exit(1);
2757}
2758
2759/*
drh67505e72002-04-19 12:34:06 +00002760** Initialize the state information in data
2761*/
drh0850b532006-01-31 19:31:43 +00002762static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002763 memset(data, 0, sizeof(*data));
2764 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002765 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002766 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00002767 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00002768 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002769 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2770 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002771 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002772}
2773
drh75897232000-05-29 14:26:00 +00002774int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002775 char *zErrMsg = 0;
2776 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002777 const char *zInitFile = 0;
2778 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002779 int i;
drhc28490c2006-10-26 14:25:58 +00002780 int rc = 0;
drh75897232000-05-29 14:26:00 +00002781
drh52784bd2011-05-18 17:15:06 +00002782 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
2783 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
2784 sqlite3_sourceid(), SQLITE_SOURCE_ID);
2785 exit(1);
2786 }
drhdaffd0e2001-04-11 14:28:42 +00002787 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002788 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002789 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002790
drh44c2eb12003-04-30 11:38:26 +00002791 /* Make sure we have a valid signal handler early, before anything
2792 ** else is done.
2793 */
drh4c504392000-10-16 22:06:40 +00002794#ifdef SIGINT
2795 signal(SIGINT, interrupt_handler);
2796#endif
drh44c2eb12003-04-30 11:38:26 +00002797
drh22fbcb82004-02-01 01:22:50 +00002798 /* Do an initial pass through the command-line argument to locate
2799 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00002800 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00002801 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002802 */
drh22fbcb82004-02-01 01:22:50 +00002803 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002804 char *z;
drh44c2eb12003-04-30 11:38:26 +00002805 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002806 z = argv[i];
drhcc3b4f82012-02-07 14:13:50 +00002807 if( z[1]=='-' ) z++;
2808 if( strcmp(z,"-separator")==0
2809 || strcmp(z,"-nullvalue")==0
2810 || strcmp(z,"-cmd")==0
2811 ){
drh44c2eb12003-04-30 11:38:26 +00002812 i++;
drhcc3b4f82012-02-07 14:13:50 +00002813 }else if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002814 i++;
2815 zInitFile = argv[i];
shanef69573d2009-10-24 02:06:14 +00002816 /* Need to check for batch mode here to so we can avoid printing
2817 ** informational messages (like from process_sqliterc) before
2818 ** we do the actual processing of arguments later in a second pass.
2819 */
drhcc3b4f82012-02-07 14:13:50 +00002820 }else if( strcmp(z,"-batch")==0 ){
shanef69573d2009-10-24 02:06:14 +00002821 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00002822 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00002823#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00002824 int j, c;
2825 const char *zSize;
2826 sqlite3_int64 szHeap;
2827
2828 zSize = argv[++i];
2829 szHeap = atoi(zSize);
2830 for(j=0; (c = zSize[j])!=0; j++){
2831 if( c=='M' ){ szHeap *= 1000000; break; }
2832 if( c=='K' ){ szHeap *= 1000; break; }
2833 if( c=='G' ){ szHeap *= 1000000000; break; }
2834 }
2835 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00002836 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2837#endif
drh97ae8ff2011-03-16 16:56:29 +00002838#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00002839 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00002840 extern int vfstrace_register(
2841 const char *zTraceName,
2842 const char *zOldVfsName,
2843 int (*xOut)(const char*,void*),
2844 void *pOutArg,
2845 int makeDefault
2846 );
drh2b625e22011-03-16 17:05:28 +00002847 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00002848#endif
drh6f25e892011-07-08 17:02:57 +00002849#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00002850 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00002851 extern int sqlite3_multiple_initialize(const char*,int);
2852 sqlite3_multiplex_initialize(0, 1);
2853#endif
drhcc3b4f82012-02-07 14:13:50 +00002854 }else if( strcmp(z,"-vfs")==0 ){
drh77ec9ba2011-03-15 18:35:44 +00002855 sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
drha7e61d82011-03-12 17:02:57 +00002856 if( pVfs ){
2857 sqlite3_vfs_register(pVfs, 1);
2858 }else{
2859 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
2860 exit(1);
2861 }
drh44c2eb12003-04-30 11:38:26 +00002862 }
2863 }
drh22fbcb82004-02-01 01:22:50 +00002864 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002865#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002866 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2867#else
drh22fbcb82004-02-01 01:22:50 +00002868 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002869#endif
drh22fbcb82004-02-01 01:22:50 +00002870 }else{
danielk197703aded42004-11-22 05:26:27 +00002871#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002872 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002873#else
2874 data.zDbFilename = 0;
2875#endif
drh22fbcb82004-02-01 01:22:50 +00002876 }
2877 if( i<argc ){
2878 zFirstCmd = argv[i++];
2879 }
shaneh5fc25012009-11-11 04:17:07 +00002880 if( i<argc ){
2881 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
2882 fprintf(stderr,"Use -help for a list of options.\n");
2883 return 1;
2884 }
drh44c2eb12003-04-30 11:38:26 +00002885 data.out = stdout;
2886
drh01b41712005-08-29 23:06:23 +00002887#ifdef SQLITE_OMIT_MEMORYDB
2888 if( data.zDbFilename==0 ){
shane86f5bdb2009-10-24 02:00:07 +00002889 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
2890 return 1;
drh01b41712005-08-29 23:06:23 +00002891 }
2892#endif
2893
drh44c2eb12003-04-30 11:38:26 +00002894 /* Go ahead and open the database file if it already exists. If the
2895 ** file does not exist, delay opening it. This prevents empty database
2896 ** files from being created if a user mistypes the database name argument
2897 ** to the sqlite command-line tool.
2898 */
drhc8d74412004-08-31 23:41:26 +00002899 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002900 open_db(&data);
2901 }
2902
drh22fbcb82004-02-01 01:22:50 +00002903 /* Process the initialization file if there is one. If no -init option
2904 ** is given on the command line, look for a file named ~/.sqliterc and
2905 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002906 */
shane86f5bdb2009-10-24 02:00:07 +00002907 rc = process_sqliterc(&data,zInitFile);
2908 if( rc>0 ){
2909 return rc;
2910 }
drh44c2eb12003-04-30 11:38:26 +00002911
drh22fbcb82004-02-01 01:22:50 +00002912 /* Make a second pass through the command-line argument and set
2913 ** options. This second pass is delayed until after the initialization
2914 ** file is processed so that the command-line arguments will override
2915 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002916 */
drh22fbcb82004-02-01 01:22:50 +00002917 for(i=1; i<argc && argv[i][0]=='-'; i++){
2918 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002919 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002920 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002921 i++;
2922 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002923 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002924 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002925 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002926 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002927 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002928 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002929 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002930 }else if( strcmp(z,"-csv")==0 ){
2931 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002932 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002933 }else if( strcmp(z,"-separator")==0 ){
2934 i++;
shaneh5fc25012009-11-11 04:17:07 +00002935 if(i>=argc){
drhcc3b4f82012-02-07 14:13:50 +00002936 fprintf(stderr,"%s: Error: missing argument for option: %s\n",
2937 Argv0, z);
shaneh5fc25012009-11-11 04:17:07 +00002938 fprintf(stderr,"Use -help for a list of options.\n");
2939 return 1;
2940 }
drh5bb3eb92007-05-04 13:15:55 +00002941 sqlite3_snprintf(sizeof(data.separator), data.separator,
2942 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002943 }else if( strcmp(z,"-nullvalue")==0 ){
2944 i++;
shaneh5fc25012009-11-11 04:17:07 +00002945 if(i>=argc){
drhcc3b4f82012-02-07 14:13:50 +00002946 fprintf(stderr,"%s: Error: missing argument for option: %s\n",
2947 Argv0, z);
shaneh5fc25012009-11-11 04:17:07 +00002948 fprintf(stderr,"Use -help for a list of options.\n");
2949 return 1;
2950 }
drh5bb3eb92007-05-04 13:15:55 +00002951 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2952 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002953 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002954 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002955 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002956 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002957 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002958 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00002959 }else if( strcmp(z,"-stats")==0 ){
2960 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002961 }else if( strcmp(z,"-bail")==0 ){
2962 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002963 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00002964 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00002965 return 0;
drhc28490c2006-10-26 14:25:58 +00002966 }else if( strcmp(z,"-interactive")==0 ){
2967 stdin_is_interactive = 1;
2968 }else if( strcmp(z,"-batch")==0 ){
2969 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00002970 }else if( strcmp(z,"-heap")==0 ){
2971 i++;
drha7e61d82011-03-12 17:02:57 +00002972 }else if( strcmp(z,"-vfs")==0 ){
2973 i++;
drh6f25e892011-07-08 17:02:57 +00002974#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00002975 }else if( strcmp(z,"-vfstrace")==0 ){
2976 i++;
drh6f25e892011-07-08 17:02:57 +00002977#endif
2978#ifdef SQLITE_ENABLE_MULTIPLEX
2979 }else if( strcmp(z,"-multiplex")==0 ){
2980 i++;
2981#endif
drhcc3b4f82012-02-07 14:13:50 +00002982 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002983 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00002984 }else if( strcmp(z,"-cmd")==0 ){
2985 if( i==argc-1 ) break;
2986 i++;
2987 z = argv[i];
2988 if( z[0]=='.' ){
2989 rc = do_meta_command(z, &data);
2990 if( rc && bail_on_error ) return rc;
2991 }else{
2992 open_db(&data);
2993 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
2994 if( zErrMsg!=0 ){
2995 fprintf(stderr,"Error: %s\n", zErrMsg);
2996 if( bail_on_error ) return rc!=0 ? rc : 1;
2997 }else if( rc!=0 ){
2998 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
2999 if( bail_on_error ) return rc;
3000 }
3001 }
drh1e5d0e92000-05-31 23:33:17 +00003002 }else{
shane86f5bdb2009-10-24 02:00:07 +00003003 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003004 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003005 return 1;
3006 }
3007 }
drh44c2eb12003-04-30 11:38:26 +00003008
drh22fbcb82004-02-01 01:22:50 +00003009 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003010 /* Run just the command that follows the database name
3011 */
drh22fbcb82004-02-01 01:22:50 +00003012 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003013 rc = do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00003014 }else{
drh44c2eb12003-04-30 11:38:26 +00003015 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003016 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003017 if( zErrMsg!=0 ){
3018 fprintf(stderr,"Error: %s\n", zErrMsg);
3019 return rc!=0 ? rc : 1;
3020 }else if( rc!=0 ){
3021 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3022 return rc;
drh6ff13852001-11-25 13:18:23 +00003023 }
drh75897232000-05-29 14:26:00 +00003024 }
3025 }else{
drh44c2eb12003-04-30 11:38:26 +00003026 /* Run commands received from standard input
3027 */
drhc28490c2006-10-26 14:25:58 +00003028 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003029 char *zHome;
3030 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003031 int nHistory;
drh75897232000-05-29 14:26:00 +00003032 printf(
drh743e0032011-12-12 16:51:50 +00003033 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003034 "Enter \".help\" for instructions\n"
3035 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003036 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003037 );
drh67505e72002-04-19 12:34:06 +00003038 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003039 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003040 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003041 if( (zHistory = malloc(nHistory))!=0 ){
3042 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3043 }
drh67505e72002-04-19 12:34:06 +00003044 }
danielk19774af00c62005-01-23 23:43:21 +00003045#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003046 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003047#endif
drhc28490c2006-10-26 14:25:58 +00003048 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003049 if( zHistory ){
3050 stifle_history(100);
3051 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003052 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003053 }
adamd0a3daa32006-07-28 20:16:14 +00003054 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00003055 }else{
drhc28490c2006-10-26 14:25:58 +00003056 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003057 }
3058 }
drh33048c02001-10-01 14:29:22 +00003059 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003060 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003061 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003062 }
drhc28490c2006-10-26 14:25:58 +00003063 return rc;
drh75897232000-05-29 14:26:00 +00003064}