blob: 9f0e3530bc151c620e4747b1641338083bee26f3 [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
drh83905c92012-06-21 13:00:37 +000039#if !defined(_WIN32) && !defined(WIN32)
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
drh81d7fd12010-12-08 00:02:26 +000048#ifdef HAVE_EDITLINE
49# include <editline/editline.h>
50#endif
drh16e59552000-07-31 11:57:37 +000051#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000052# include <readline/readline.h>
53# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000054#endif
55#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
persicom1d0b8722002-04-18 02:53:04 +000056# define add_history(X)
drh67505e72002-04-19 12:34:06 +000057# define read_history(X)
58# define write_history(X)
59# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000060#endif
61
adamd2e8464a2006-09-06 21:39:40 +000062#if defined(_WIN32) || defined(WIN32)
63# include <io.h>
shane18e526c2008-12-10 22:30:24 +000064#define isatty(h) _isatty(h)
65#define access(f,m) _access((f),(m))
drh67ceaa62012-08-27 21:19:03 +000066#undef popen
drh53371f92013-07-25 17:07:03 +000067#define popen _popen
drh67ceaa62012-08-27 21:19:03 +000068#undef pclose
drh12cd6cf2013-06-29 15:40:22 +000069#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +000070#else
drh4328c8b2003-04-26 02:50:11 +000071/* Make sure isatty() has a prototype.
72*/
drhb2acc3b2011-10-13 16:36:29 +000073extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +000074
drh53371f92013-07-25 17:07:03 +000075/* popen and pclose are not C89 functions and so are sometimes omitted from
76** the <stdio.h> header */
mistachkinf6418892013-08-28 01:54:12 +000077extern FILE *popen(const char*,const char*);
78extern int pclose(FILE*);
79#endif
drh53371f92013-07-25 17:07:03 +000080
chw65d3c132007-11-12 21:09:10 +000081#if defined(_WIN32_WCE)
82/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
83 * thus we always assume that we have a console. That can be
84 * overridden with the -batch command line option.
85 */
86#define isatty(x) 1
87#endif
88
drhc6e41722011-04-11 15:36:26 +000089/* True if the timer is enabled */
90static int enableTimer = 0;
91
drhf0693c82011-10-11 20:41:54 +000092/* ctype macros that work with signed characters */
93#define IsSpace(X) isspace((unsigned char)X)
94#define IsDigit(X) isdigit((unsigned char)X)
95#define ToLower(X) (char)tolower((unsigned char)X)
96
drhd5d0f642013-02-20 00:54:21 +000097#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
98 && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +000099#include <sys/time.h>
100#include <sys/resource.h>
101
drhda108222009-02-25 19:07:24 +0000102/* Saved resource information for the beginning of an operation */
103static struct rusage sBegin;
104
drhda108222009-02-25 19:07:24 +0000105/*
106** Begin timing an operation
107*/
108static void beginTimer(void){
109 if( enableTimer ){
110 getrusage(RUSAGE_SELF, &sBegin);
111 }
112}
113
114/* Return the difference of two time_structs in seconds */
115static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
116 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
117 (double)(pEnd->tv_sec - pStart->tv_sec);
118}
119
120/*
121** Print the timing results.
122*/
123static void endTimer(void){
124 if( enableTimer ){
125 struct rusage sEnd;
126 getrusage(RUSAGE_SELF, &sEnd);
127 printf("CPU Time: user %f sys %f\n",
128 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
129 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
130 }
131}
shaneb320ccd2009-10-21 03:42:58 +0000132
drhda108222009-02-25 19:07:24 +0000133#define BEGIN_TIMER beginTimer()
134#define END_TIMER endTimer()
135#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000136
137#elif (defined(_WIN32) || defined(WIN32))
138
139#include <windows.h>
140
141/* Saved resource information for the beginning of an operation */
142static HANDLE hProcess;
143static FILETIME ftKernelBegin;
144static FILETIME ftUserBegin;
145typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
146static GETPROCTIMES getProcessTimesAddr = NULL;
147
shaneb320ccd2009-10-21 03:42:58 +0000148/*
149** Check to see if we have timer support. Return 1 if necessary
150** support found (or found previously).
151*/
152static int hasTimer(void){
153 if( getProcessTimesAddr ){
154 return 1;
155 } else {
156 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
157 ** See if the version we are running on has it, and if it does, save off
158 ** a pointer to it and the current process handle.
159 */
160 hProcess = GetCurrentProcess();
161 if( hProcess ){
162 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
163 if( NULL != hinstLib ){
164 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
165 if( NULL != getProcessTimesAddr ){
166 return 1;
167 }
168 FreeLibrary(hinstLib);
169 }
170 }
171 }
172 return 0;
173}
174
175/*
176** Begin timing an operation
177*/
178static void beginTimer(void){
179 if( enableTimer && getProcessTimesAddr ){
180 FILETIME ftCreation, ftExit;
181 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
182 }
183}
184
185/* Return the difference of two FILETIME structs in seconds */
186static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
187 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
188 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
189 return (double) ((i64End - i64Start) / 10000000.0);
190}
191
192/*
193** Print the timing results.
194*/
195static void endTimer(void){
196 if( enableTimer && getProcessTimesAddr){
197 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
198 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
199 printf("CPU Time: user %f sys %f\n",
200 timeDiff(&ftUserBegin, &ftUserEnd),
201 timeDiff(&ftKernelBegin, &ftKernelEnd));
202 }
203}
204
205#define BEGIN_TIMER beginTimer()
206#define END_TIMER endTimer()
207#define HAS_TIMER hasTimer()
208
drhda108222009-02-25 19:07:24 +0000209#else
210#define BEGIN_TIMER
211#define END_TIMER
212#define HAS_TIMER 0
213#endif
214
shanec0688ea2009-03-05 03:48:06 +0000215/*
216** Used to prevent warnings about unused parameters
217*/
218#define UNUSED_PARAMETER(x) (void)(x)
219
drhe91d16b2008-12-08 18:27:31 +0000220/*
drhc49f44e2006-10-26 18:15:42 +0000221** If the following flag is set, then command execution stops
222** at an error if we are not interactive.
223*/
224static int bail_on_error = 0;
225
226/*
drhc28490c2006-10-26 14:25:58 +0000227** Threat stdin as an interactive input if the following variable
228** is true. Otherwise, assume stdin is connected to a file or pipe.
229*/
230static int stdin_is_interactive = 1;
231
232/*
drh4c504392000-10-16 22:06:40 +0000233** The following is the open SQLite database. We make a pointer
234** to this database a static variable so that it can be accessed
235** by the SIGINT handler to interrupt database processing.
236*/
danielk197792f9a1b2004-06-19 09:08:16 +0000237static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000238
239/*
drh67505e72002-04-19 12:34:06 +0000240** True if an interrupt (Control-C) has been received.
241*/
drh43617e92006-03-06 20:55:46 +0000242static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000243
244/*
persicom7e2dfdd2002-04-18 02:46:52 +0000245** This is the name of our program. It is set in main(), used
246** in a number of other places, mostly for error messages.
247*/
248static char *Argv0;
249
250/*
251** Prompt strings. Initialized in main. Settable with
252** .prompt main continue
253*/
254static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
255static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
256
drhb0603412007-02-28 04:47:26 +0000257/*
258** Write I/O traces to the following stream.
259*/
rsebe0a9092007-07-30 18:24:38 +0000260#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000261static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000262#endif
drhb0603412007-02-28 04:47:26 +0000263
264/*
265** This routine works like printf in that its first argument is a
266** format string and subsequent arguments are values to be substituted
267** in place of % fields. The result of formatting this string
268** is written to iotrace.
269*/
rsebe0a9092007-07-30 18:24:38 +0000270#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000271static void iotracePrintf(const char *zFormat, ...){
272 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000273 char *z;
drhb0603412007-02-28 04:47:26 +0000274 if( iotrace==0 ) return;
275 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000276 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000277 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000278 fprintf(iotrace, "%s", z);
279 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000280}
rsebe0a9092007-07-30 18:24:38 +0000281#endif
drhb0603412007-02-28 04:47:26 +0000282
drh44c2eb12003-04-30 11:38:26 +0000283
persicom7e2dfdd2002-04-18 02:46:52 +0000284/*
drh83965662003-04-17 02:54:13 +0000285** Determines if a string is a number of not.
286*/
danielk19772e588c72005-12-09 14:25:08 +0000287static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000288 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000289 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000290 return 0;
291 }
292 z++;
293 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000294 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000295 if( *z=='.' ){
296 z++;
drhf0693c82011-10-11 20:41:54 +0000297 if( !IsDigit(*z) ) return 0;
298 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000299 if( realnum ) *realnum = 1;
300 }
301 if( *z=='e' || *z=='E' ){
302 z++;
303 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000304 if( !IsDigit(*z) ) return 0;
305 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000306 if( realnum ) *realnum = 1;
307 }
308 return *z==0;
309}
drh83965662003-04-17 02:54:13 +0000310
311/*
danielk1977bc6ada42004-06-30 08:20:16 +0000312** A global char* and an SQL function to access its current value
313** from within an SQL statement. This program used to use the
314** sqlite_exec_printf() API to substitue a string into an SQL statement.
315** The correct way to do this with sqlite3 is to use the bind API, but
316** since the shell is built around the callback paradigm it would be a lot
317** of work. Instead just use this hack, which is quite harmless.
318*/
319static const char *zShellStatic = 0;
320static void shellstaticFunc(
321 sqlite3_context *context,
322 int argc,
323 sqlite3_value **argv
324){
325 assert( 0==argc );
326 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000327 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000328 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000329 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
330}
331
332
333/*
drhfeac5f82004-08-01 00:10:45 +0000334** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000335** the text in memory obtained from malloc() and returns a pointer
336** to the text. NULL is returned at end of file, or if malloc()
337** fails.
338**
drh9f099fd2013-08-06 14:01:46 +0000339** If zLine is not NULL then it is a malloced buffer returned from
340** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000341*/
drh9f099fd2013-08-06 14:01:46 +0000342static char *local_getline(char *zLine, FILE *in){
343 int nLine = zLine==0 ? 0 : 100;
344 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000345
drhb07028f2011-10-14 21:49:18 +0000346 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000347 if( n+100>nLine ){
348 nLine = nLine*2 + 100;
349 zLine = realloc(zLine, nLine);
350 if( zLine==0 ) return 0;
351 }
drhdaffd0e2001-04-11 14:28:42 +0000352 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000353 if( n==0 ){
354 free(zLine);
355 return 0;
356 }
357 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000358 break;
359 }
drh9f099fd2013-08-06 14:01:46 +0000360 while( zLine[n] ) n++;
361 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000362 n--;
shaneh13b36022009-12-17 21:07:15 +0000363 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000364 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000365 break;
drh8e7e7a22000-05-30 18:45:23 +0000366 }
367 }
drh8e7e7a22000-05-30 18:45:23 +0000368 return zLine;
369}
370
371/*
drhc28490c2006-10-26 14:25:58 +0000372** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000373**
drh9f099fd2013-08-06 14:01:46 +0000374** If in==0 then read from standard input and prompt before each line.
375** If isContinuation is true, then a continuation prompt is appropriate.
376** If isContinuation is zero, then the main prompt should be used.
377**
378** If zPrior is not NULL then it is a buffer from a prior call to this
379** routine that can be reused.
380**
381** The result is stored in space obtained from malloc() and must either
382** be freed by the caller or else passed back into this routine via the
383** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000384*/
drh9f099fd2013-08-06 14:01:46 +0000385static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000386 char *zPrompt;
387 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000388 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000389 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000390 }else{
drh9f099fd2013-08-06 14:01:46 +0000391 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danielk19774af00c62005-01-23 23:43:21 +0000392#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh9f099fd2013-08-06 14:01:46 +0000393 free(zPrior);
394 zResult = readline(zPrompt);
395 if( zResult && *zResult ) add_history(zResult);
396#else
397 printf("%s", zPrompt);
398 fflush(stdout);
399 zResult = local_getline(zPrior, stdin);
danielk19774af00c62005-01-23 23:43:21 +0000400#endif
drh9f099fd2013-08-06 14:01:46 +0000401 }
drh8e7e7a22000-05-30 18:45:23 +0000402 return zResult;
403}
404
persicom7e2dfdd2002-04-18 02:46:52 +0000405struct previous_mode_data {
406 int valid; /* Is there legit data in here? */
407 int mode;
408 int showHeader;
409 int colWidth[100];
410};
drh45e29d82006-11-20 16:21:10 +0000411
drh8e7e7a22000-05-30 18:45:23 +0000412/*
drh75897232000-05-29 14:26:00 +0000413** An pointer to an instance of this structure is passed from
414** the main program to the callback. This is used to communicate
415** state and mode information.
416*/
417struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000418 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000419 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000420 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000421 int cnt; /* Number of records displayed so far */
422 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000423 FILE *traceOut; /* Output for sqlite3_trace() */
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'");
drhb202d702012-04-24 12:12:57 +0000501 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000502 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);
mistachkin585dcb22012-12-04 00:23:43 +0000545 }else if( c=='"' ){
546 fputc('\\', out);
547 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000548 }else if( c=='\t' ){
549 fputc('\\', out);
550 fputc('t', out);
551 }else if( c=='\n' ){
552 fputc('\\', out);
553 fputc('n', out);
554 }else if( c=='\r' ){
555 fputc('\\', out);
556 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000557 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000558 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000559 }else{
560 fputc(c, out);
561 }
562 }
563 fputc('"', out);
564}
565
566/*
drhc08a4f12000-06-15 16:49:48 +0000567** Output the given string with characters that are special to
568** HTML escaped.
569*/
570static void output_html_string(FILE *out, const char *z){
571 int i;
572 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000573 for(i=0; z[i]
574 && z[i]!='<'
575 && z[i]!='&'
576 && z[i]!='>'
577 && z[i]!='\"'
578 && z[i]!='\'';
579 i++){}
drhc08a4f12000-06-15 16:49:48 +0000580 if( i>0 ){
581 fprintf(out,"%.*s",i,z);
582 }
583 if( z[i]=='<' ){
584 fprintf(out,"&lt;");
585 }else if( z[i]=='&' ){
586 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000587 }else if( z[i]=='>' ){
588 fprintf(out,"&gt;");
589 }else if( z[i]=='\"' ){
590 fprintf(out,"&quot;");
591 }else if( z[i]=='\'' ){
592 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000593 }else{
594 break;
595 }
596 z += i + 1;
597 }
598}
599
600/*
drhc49f44e2006-10-26 18:15:42 +0000601** If a field contains any character identified by a 1 in the following
602** array, then the string must be quoted for CSV.
603*/
604static const char needCsvQuote[] = {
605 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
606 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
607 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
610 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
611 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
612 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
619 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
620 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
621};
622
623/*
drh8e64d1c2004-10-07 00:32:39 +0000624** Output a single term of CSV. Actually, p->separator is used for
625** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000626** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000627*/
628static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000629 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000630 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000631 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000632 }else{
drhc49f44e2006-10-26 18:15:42 +0000633 int i;
drh4f21c4a2008-12-10 22:15:00 +0000634 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000635 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000636 if( needCsvQuote[((unsigned char*)z)[i]]
637 || (z[i]==p->separator[0] &&
638 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000639 i = 0;
640 break;
641 }
642 }
643 if( i==0 ){
644 putc('"', out);
645 for(i=0; z[i]; i++){
646 if( z[i]=='"' ) putc('"', out);
647 putc(z[i], out);
648 }
649 putc('"', out);
650 }else{
651 fprintf(out, "%s", z);
652 }
drh8e64d1c2004-10-07 00:32:39 +0000653 }
654 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000655 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000656 }
657}
658
danielk19774af00c62005-01-23 23:43:21 +0000659#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000660/*
drh4c504392000-10-16 22:06:40 +0000661** This routine runs when the user presses Ctrl-C
662*/
663static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000664 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000665 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000666 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000667}
danielk19774af00c62005-01-23 23:43:21 +0000668#endif
drh4c504392000-10-16 22:06:40 +0000669
670/*
shane626a6e42009-10-22 17:30:15 +0000671** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000672** invokes for each row of a query result.
673*/
shane626a6e42009-10-22 17:30:15 +0000674static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000675 int i;
676 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000677
drh75897232000-05-29 14:26:00 +0000678 switch( p->mode ){
679 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000680 int w = 5;
drh6a535342001-10-19 16:44:56 +0000681 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000682 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000683 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000684 if( len>w ) w = len;
685 }
drh75897232000-05-29 14:26:00 +0000686 if( p->cnt++>0 ) fprintf(p->out,"\n");
687 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000688 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000689 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000690 }
691 break;
692 }
danielk19770d78bae2008-01-03 07:09:48 +0000693 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000694 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000695 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000696 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000697 int w, n;
698 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000699 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000700 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000701 w = 0;
drh75897232000-05-29 14:26:00 +0000702 }
drh078b1fd2012-09-21 13:40:02 +0000703 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000704 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000705 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000706 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000707 if( w<n ) w = n;
708 }
709 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000710 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000711 }
712 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000713 if( w<0 ){
714 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
715 }else{
716 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
717 }
drha0c66f52000-07-29 13:20:21 +0000718 }
719 }
720 if( p->showHeader ){
721 for(i=0; i<nArg; i++){
722 int w;
723 if( i<ArraySize(p->actualWidth) ){
724 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000725 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000726 }else{
727 w = 10;
728 }
729 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
730 "----------------------------------------------------------",
731 i==nArg-1 ? "\n": " ");
732 }
drh75897232000-05-29 14:26:00 +0000733 }
734 }
drh6a535342001-10-19 16:44:56 +0000735 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000736 for(i=0; i<nArg; i++){
737 int w;
drha0c66f52000-07-29 13:20:21 +0000738 if( i<ArraySize(p->actualWidth) ){
739 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000740 }else{
741 w = 10;
742 }
drhea678832008-12-10 19:26:22 +0000743 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000744 strlen30(azArg[i])>w ){
745 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000746 }
drh078b1fd2012-09-21 13:40:02 +0000747 if( w<0 ){
748 fprintf(p->out,"%*.*s%s",-w,-w,
749 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
750 }else{
751 fprintf(p->out,"%-*.*s%s",w,w,
752 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
753 }
drh75897232000-05-29 14:26:00 +0000754 }
755 break;
756 }
drhe3710332000-09-29 13:30:53 +0000757 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000758 case MODE_List: {
759 if( p->cnt++==0 && p->showHeader ){
760 for(i=0; i<nArg; i++){
761 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
762 }
763 }
drh6a535342001-10-19 16:44:56 +0000764 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000765 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000766 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000767 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000768 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000769 if( i<nArg-1 ){
770 fprintf(p->out, "%s", p->separator);
771 }else if( p->mode==MODE_Semi ){
772 fprintf(p->out, ";\n");
773 }else{
774 fprintf(p->out, "\n");
775 }
drh75897232000-05-29 14:26:00 +0000776 }
777 break;
778 }
drh1e5d0e92000-05-31 23:33:17 +0000779 case MODE_Html: {
780 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000781 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000782 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000783 fprintf(p->out,"<TH>");
784 output_html_string(p->out, azCol[i]);
785 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000786 }
mihailim57c591a2008-06-23 21:26:05 +0000787 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000788 }
drh6a535342001-10-19 16:44:56 +0000789 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000790 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000791 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000792 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000793 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000794 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000795 }
mihailim57c591a2008-06-23 21:26:05 +0000796 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000797 break;
798 }
drhfeac5f82004-08-01 00:10:45 +0000799 case MODE_Tcl: {
800 if( p->cnt++==0 && p->showHeader ){
801 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000802 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin585dcb22012-12-04 00:23:43 +0000803 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000804 }
805 fprintf(p->out,"\n");
806 }
807 if( azArg==0 ) break;
808 for(i=0; i<nArg; i++){
809 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mistachkin585dcb22012-12-04 00:23:43 +0000810 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000811 }
812 fprintf(p->out,"\n");
813 break;
814 }
drh8e64d1c2004-10-07 00:32:39 +0000815 case MODE_Csv: {
816 if( p->cnt++==0 && p->showHeader ){
817 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000818 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000819 }
820 fprintf(p->out,"\n");
821 }
822 if( azArg==0 ) break;
823 for(i=0; i<nArg; i++){
824 output_csv(p, azArg[i], i<nArg-1);
825 }
826 fprintf(p->out,"\n");
827 break;
828 }
drh28bd4bc2000-06-15 15:57:22 +0000829 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000830 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000831 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000832 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000833 for(i=0; i<nArg; i++){
834 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000835 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000836 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000837 }else if( aiType && aiType[i]==SQLITE_TEXT ){
838 if( zSep[0] ) fprintf(p->out,"%s",zSep);
839 output_quoted_string(p->out, azArg[i]);
840 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
841 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000842 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
843 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
844 int nBlob = sqlite3_column_bytes(p->pStmt, i);
845 if( zSep[0] ) fprintf(p->out,"%s",zSep);
846 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000847 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000848 fprintf(p->out,"%s%s",zSep, azArg[i]);
849 }else{
850 if( zSep[0] ) fprintf(p->out,"%s",zSep);
851 output_quoted_string(p->out, azArg[i]);
852 }
853 }
854 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000855 break;
drh28bd4bc2000-06-15 15:57:22 +0000856 }
persicom1d0b8722002-04-18 02:53:04 +0000857 }
drh75897232000-05-29 14:26:00 +0000858 return 0;
859}
860
861/*
shane626a6e42009-10-22 17:30:15 +0000862** This is the callback routine that the SQLite library
863** invokes for each row of a query result.
864*/
865static int callback(void *pArg, int nArg, char **azArg, char **azCol){
866 /* since we don't have type info, call the shell_callback with a NULL value */
867 return shell_callback(pArg, nArg, azArg, azCol, NULL);
868}
869
870/*
drh33048c02001-10-01 14:29:22 +0000871** Set the destination table field of the callback_data structure to
872** the name of the table given. Escape any quote characters in the
873** table name.
874*/
875static void set_table_name(struct callback_data *p, const char *zName){
876 int i, n;
877 int needQuote;
878 char *z;
879
880 if( p->zDestTable ){
881 free(p->zDestTable);
882 p->zDestTable = 0;
883 }
884 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000885 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000886 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000887 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000888 needQuote = 1;
889 if( zName[i]=='\'' ) n++;
890 }
891 }
892 if( needQuote ) n += 2;
893 z = p->zDestTable = malloc( n+1 );
894 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000895 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000896 exit(1);
897 }
898 n = 0;
899 if( needQuote ) z[n++] = '\'';
900 for(i=0; zName[i]; i++){
901 z[n++] = zName[i];
902 if( zName[i]=='\'' ) z[n++] = '\'';
903 }
904 if( needQuote ) z[n++] = '\'';
905 z[n] = 0;
906}
907
danielk19772a02e332004-06-05 08:04:36 +0000908/* zIn is either a pointer to a NULL-terminated string in memory obtained
909** from malloc(), or a NULL pointer. The string pointed to by zAppend is
910** added to zIn, and the result returned in memory obtained from malloc().
911** zIn, if it was not NULL, is freed.
912**
913** If the third argument, quote, is not '\0', then it is used as a
914** quote character for zAppend.
915*/
drhc28490c2006-10-26 14:25:58 +0000916static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000917 int len;
918 int i;
drh4f21c4a2008-12-10 22:15:00 +0000919 int nAppend = strlen30(zAppend);
920 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000921
922 len = nAppend+nIn+1;
923 if( quote ){
924 len += 2;
925 for(i=0; i<nAppend; i++){
926 if( zAppend[i]==quote ) len++;
927 }
928 }
929
930 zIn = (char *)realloc(zIn, len);
931 if( !zIn ){
932 return 0;
933 }
934
935 if( quote ){
936 char *zCsr = &zIn[nIn];
937 *zCsr++ = quote;
938 for(i=0; i<nAppend; i++){
939 *zCsr++ = zAppend[i];
940 if( zAppend[i]==quote ) *zCsr++ = quote;
941 }
942 *zCsr++ = quote;
943 *zCsr++ = '\0';
944 assert( (zCsr-zIn)==len );
945 }else{
946 memcpy(&zIn[nIn], zAppend, nAppend);
947 zIn[len-1] = '\0';
948 }
949
950 return zIn;
951}
952
drhdd3d4592004-08-30 01:54:05 +0000953
954/*
drhb21a8e42012-01-28 21:08:51 +0000955** Execute a query statement that will generate SQL output. Print
956** the result columns, comma-separated, on a line and then add a
957** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000958**
drhb21a8e42012-01-28 21:08:51 +0000959** If the number of columns is 1 and that column contains text "--"
960** then write the semicolon on a separate line. That way, if a
961** "--" comment occurs at the end of the statement, the comment
962** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000963*/
drh157e29a2009-05-21 15:15:00 +0000964static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000965 struct callback_data *p, /* Query context */
966 const char *zSelect, /* SELECT statement to extract content */
967 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000968){
drhdd3d4592004-08-30 01:54:05 +0000969 sqlite3_stmt *pSelect;
970 int rc;
drhb21a8e42012-01-28 21:08:51 +0000971 int nResult;
972 int i;
973 const char *z;
drh2f464a02011-10-13 00:41:49 +0000974 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000975 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000976 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +0000977 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000978 return rc;
979 }
980 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000981 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000982 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000983 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000984 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000985 zFirstRow = 0;
986 }
drhb21a8e42012-01-28 21:08:51 +0000987 z = (const char*)sqlite3_column_text(pSelect, 0);
988 fprintf(p->out, "%s", z);
989 for(i=1; i<nResult; i++){
990 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
991 }
992 if( z==0 ) z = "";
993 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
994 if( z[0] ){
995 fprintf(p->out, "\n;\n");
996 }else{
997 fprintf(p->out, ";\n");
998 }
drhdd3d4592004-08-30 01:54:05 +0000999 rc = sqlite3_step(pSelect);
1000 }
drh2f464a02011-10-13 00:41:49 +00001001 rc = sqlite3_finalize(pSelect);
1002 if( rc!=SQLITE_OK ){
1003 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001004 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001005 }
1006 return rc;
drhdd3d4592004-08-30 01:54:05 +00001007}
1008
shane626a6e42009-10-22 17:30:15 +00001009/*
1010** Allocate space and save off current error string.
1011*/
1012static char *save_err_msg(
1013 sqlite3 *db /* Database to query */
1014){
1015 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1016 char *zErrMsg = sqlite3_malloc(nErrMsg);
1017 if( zErrMsg ){
1018 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1019 }
1020 return zErrMsg;
1021}
1022
1023/*
shaneh642d8b82010-07-28 16:05:34 +00001024** Display memory stats.
1025*/
1026static int display_stats(
1027 sqlite3 *db, /* Database to query */
1028 struct callback_data *pArg, /* Pointer to struct callback_data */
1029 int bReset /* True to reset the stats */
1030){
1031 int iCur;
1032 int iHiwtr;
1033
1034 if( pArg && pArg->out ){
1035
1036 iHiwtr = iCur = -1;
1037 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001038 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001039 iHiwtr = iCur = -1;
1040 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001041 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001042/*
1043** Not currently used by the CLI.
1044** iHiwtr = iCur = -1;
1045** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1046** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1047*/
1048 iHiwtr = iCur = -1;
1049 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1050 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1051/*
1052** Not currently used by the CLI.
1053** iHiwtr = iCur = -1;
1054** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1055** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1056*/
1057 iHiwtr = iCur = -1;
1058 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1059 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1060 iHiwtr = iCur = -1;
1061 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1062 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1063 iHiwtr = iCur = -1;
1064 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1065 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1066 iHiwtr = iCur = -1;
1067 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1068 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1069#ifdef YYTRACKMAXSTACKDEPTH
1070 iHiwtr = iCur = -1;
1071 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1072 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1073#endif
1074 }
1075
1076 if( pArg && pArg->out && db ){
1077 iHiwtr = iCur = -1;
1078 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1079 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001080 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1081 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1082 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1083 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1084 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1085 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001086 iHiwtr = iCur = -1;
1087 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001088 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1089 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1090 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1091 iHiwtr = iCur = -1;
1092 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1093 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001094 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001095 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1096 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1097 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001098 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1099 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1100 iHiwtr = iCur = -1;
1101 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1102 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1103 }
1104
1105 if( pArg && pArg->out && db && pArg->pStmt ){
1106 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1107 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1108 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1109 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1110 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1111 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001112 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1113 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001114 }
1115
1116 return 0;
1117}
1118
1119/*
shane626a6e42009-10-22 17:30:15 +00001120** Execute a statement or set of statements. Print
1121** any result rows/columns depending on the current mode
1122** set via the supplied callback.
1123**
1124** This is very similar to SQLite's built-in sqlite3_exec()
1125** function except it takes a slightly different callback
1126** and callback data argument.
1127*/
1128static int shell_exec(
1129 sqlite3 *db, /* An open database */
1130 const char *zSql, /* SQL to be evaluated */
1131 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1132 /* (not the same as sqlite3_exec) */
1133 struct callback_data *pArg, /* Pointer to struct callback_data */
1134 char **pzErrMsg /* Error msg written here */
1135){
dan4564ced2010-01-05 04:59:56 +00001136 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1137 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001138 int rc2;
dan4564ced2010-01-05 04:59:56 +00001139 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001140
1141 if( pzErrMsg ){
1142 *pzErrMsg = NULL;
1143 }
1144
shaneb9fc17d2009-10-22 21:23:35 +00001145 while( zSql[0] && (SQLITE_OK == rc) ){
1146 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1147 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001148 if( pzErrMsg ){
1149 *pzErrMsg = save_err_msg(db);
1150 }
1151 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001152 if( !pStmt ){
1153 /* this happens for a comment or white-space */
1154 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001155 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001156 continue;
1157 }
shane626a6e42009-10-22 17:30:15 +00001158
shaneh642d8b82010-07-28 16:05:34 +00001159 /* save off the prepared statment handle and reset row count */
1160 if( pArg ){
1161 pArg->pStmt = pStmt;
1162 pArg->cnt = 0;
1163 }
1164
shanehb7977c52010-01-18 18:17:10 +00001165 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001166 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001167 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001168 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001169 }
shanehb7977c52010-01-18 18:17:10 +00001170
drh7e02e5e2011-12-06 19:44:51 +00001171 /* Output TESTCTRL_EXPLAIN text of requested */
1172 if( pArg && pArg->mode==MODE_Explain ){
1173 const char *zExplain = 0;
1174 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1175 if( zExplain && zExplain[0] ){
1176 fprintf(pArg->out, "%s", zExplain);
1177 }
1178 }
1179
shaneb9fc17d2009-10-22 21:23:35 +00001180 /* perform the first step. this will tell us if we
1181 ** have a result set or not and how wide it is.
1182 */
1183 rc = sqlite3_step(pStmt);
1184 /* if we have a result set... */
1185 if( SQLITE_ROW == rc ){
1186 /* if we have a callback... */
1187 if( xCallback ){
1188 /* allocate space for col name ptr, value ptr, and type */
1189 int nCol = sqlite3_column_count(pStmt);
1190 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1191 if( !pData ){
1192 rc = SQLITE_NOMEM;
1193 }else{
1194 char **azCols = (char **)pData; /* Names of result columns */
1195 char **azVals = &azCols[nCol]; /* Results */
1196 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001197 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001198 assert(sizeof(int) <= sizeof(char *));
1199 /* save off ptrs to column names */
1200 for(i=0; i<nCol; i++){
1201 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1202 }
shaneb9fc17d2009-10-22 21:23:35 +00001203 do{
1204 /* extract the data and data types */
1205 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001206 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1207 if( x==SQLITE_BLOB && pArg->mode==MODE_Insert ){
1208 azVals[i] = "";
1209 }else{
1210 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1211 }
shaneb9fc17d2009-10-22 21:23:35 +00001212 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1213 rc = SQLITE_NOMEM;
1214 break; /* from for */
1215 }
1216 } /* end for */
1217
1218 /* if data and types extracted successfully... */
1219 if( SQLITE_ROW == rc ){
1220 /* call the supplied callback with the result row data */
1221 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1222 rc = SQLITE_ABORT;
1223 }else{
1224 rc = sqlite3_step(pStmt);
1225 }
1226 }
1227 } while( SQLITE_ROW == rc );
1228 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001229 }
1230 }else{
1231 do{
1232 rc = sqlite3_step(pStmt);
1233 } while( rc == SQLITE_ROW );
1234 }
1235 }
1236
shaneh642d8b82010-07-28 16:05:34 +00001237 /* print usage stats if stats on */
1238 if( pArg && pArg->statsOn ){
1239 display_stats(db, pArg, 0);
1240 }
1241
dan4564ced2010-01-05 04:59:56 +00001242 /* Finalize the statement just executed. If this fails, save a
1243 ** copy of the error message. Otherwise, set zSql to point to the
1244 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001245 rc2 = sqlite3_finalize(pStmt);
1246 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001247 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001248 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001249 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001250 }else if( pzErrMsg ){
1251 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001252 }
shaneh642d8b82010-07-28 16:05:34 +00001253
1254 /* clear saved stmt handle */
1255 if( pArg ){
1256 pArg->pStmt = NULL;
1257 }
shane626a6e42009-10-22 17:30:15 +00001258 }
shaneb9fc17d2009-10-22 21:23:35 +00001259 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001260
1261 return rc;
1262}
1263
drhdd3d4592004-08-30 01:54:05 +00001264
drh33048c02001-10-01 14:29:22 +00001265/*
drh4c653a02000-06-07 01:27:47 +00001266** This is a different callback routine used for dumping the database.
1267** Each row received by this callback consists of a table name,
1268** the table type ("index" or "table") and SQL to create the table.
1269** This routine should print text sufficient to recreate the table.
1270*/
1271static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001272 int rc;
1273 const char *zTable;
1274 const char *zType;
1275 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001276 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001277 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001278
drh902b9ee2008-12-05 17:17:07 +00001279 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001280 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001281 zTable = azArg[0];
1282 zType = azArg[1];
1283 zSql = azArg[2];
1284
drh00b950d2005-09-11 02:03:03 +00001285 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001286 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001287 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001288 fprintf(p->out, "ANALYZE sqlite_master;\n");
1289 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1290 return 0;
drh45e29d82006-11-20 16:21:10 +00001291 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1292 char *zIns;
1293 if( !p->writableSchema ){
1294 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1295 p->writableSchema = 1;
1296 }
1297 zIns = sqlite3_mprintf(
1298 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1299 "VALUES('table','%q','%q',0,'%q');",
1300 zTable, zTable, zSql);
1301 fprintf(p->out, "%s\n", zIns);
1302 sqlite3_free(zIns);
1303 return 0;
drh00b950d2005-09-11 02:03:03 +00001304 }else{
1305 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001306 }
danielk19772a02e332004-06-05 08:04:36 +00001307
1308 if( strcmp(zType, "table")==0 ){
1309 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001310 char *zSelect = 0;
1311 char *zTableInfo = 0;
1312 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001313 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001314
1315 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1316 zTableInfo = appendText(zTableInfo, zTable, '"');
1317 zTableInfo = appendText(zTableInfo, ");", 0);
1318
1319 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001320 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001321 if( rc!=SQLITE_OK || !pTableInfo ){
1322 return 1;
1323 }
1324
1325 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001326 /* Always quote the table name, even if it appears to be pure ascii,
1327 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1328 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001329 if( zTmp ){
1330 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001331 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001332 }
1333 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1334 rc = sqlite3_step(pTableInfo);
1335 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001336 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001337 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001338 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001339 rc = sqlite3_step(pTableInfo);
1340 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001341 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001342 }else{
1343 zSelect = appendText(zSelect, ") ", 0);
1344 }
drh157e29a2009-05-21 15:15:00 +00001345 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001346 }
1347 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001348 if( rc!=SQLITE_OK || nRow==0 ){
1349 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001350 return 1;
1351 }
1352 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1353 zSelect = appendText(zSelect, zTable, '"');
1354
drh2f464a02011-10-13 00:41:49 +00001355 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001356 if( rc==SQLITE_CORRUPT ){
1357 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001358 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001359 }
drh85e72432012-04-11 11:38:53 +00001360 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001361 }
drh4c653a02000-06-07 01:27:47 +00001362 return 0;
1363}
1364
1365/*
drh45e29d82006-11-20 16:21:10 +00001366** Run zQuery. Use dump_callback() as the callback routine so that
1367** the contents of the query are output as SQL statements.
1368**
drhdd3d4592004-08-30 01:54:05 +00001369** If we get a SQLITE_CORRUPT error, rerun the query after appending
1370** "ORDER BY rowid DESC" to the end.
1371*/
1372static int run_schema_dump_query(
1373 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001374 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001375){
1376 int rc;
drh2f464a02011-10-13 00:41:49 +00001377 char *zErr = 0;
1378 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001379 if( rc==SQLITE_CORRUPT ){
1380 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001381 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001382 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1383 if( zErr ){
1384 fprintf(p->out, "/****** %s ******/\n", zErr);
1385 sqlite3_free(zErr);
1386 zErr = 0;
1387 }
drhdd3d4592004-08-30 01:54:05 +00001388 zQ2 = malloc( len+100 );
1389 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001390 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001391 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1392 if( rc ){
1393 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1394 }else{
1395 rc = SQLITE_CORRUPT;
1396 }
1397 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001398 free(zQ2);
1399 }
1400 return rc;
1401}
1402
1403/*
drh75897232000-05-29 14:26:00 +00001404** Text of a help message
1405*/
persicom1d0b8722002-04-18 02:53:04 +00001406static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001407 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001408 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001409 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001410 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001411 " If TABLE specified, only dump tables matching\n"
1412 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001413 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001414 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001415 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1416 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001417 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001418 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001419 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001420 ".indices ?TABLE? Show names of all indices\n"
1421 " If TABLE specified, only show indices for tables\n"
1422 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001423#ifdef SQLITE_ENABLE_IOTRACE
1424 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1425#endif
drh70df4fe2006-06-13 15:12:21 +00001426#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001427 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001428#endif
drh127f9d72010-02-23 01:47:00 +00001429 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001430 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001431 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001432 " column Left-aligned columns. (See .width)\n"
1433 " html HTML <table> code\n"
1434 " insert SQL insert statements for TABLE\n"
1435 " line One value per line\n"
1436 " list Values delimited by .separator string\n"
1437 " tabs Tab-separated values\n"
1438 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001439 ".nullvalue STRING Use STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001440 ".output FILENAME Send output to FILENAME\n"
1441 ".output stdout Send output to the screen\n"
drh078b1fd2012-09-21 13:40:02 +00001442 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001443 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001444 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001445 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001446 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001447 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001448 " If TABLE specified, only show tables matching\n"
1449 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001450 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001451 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001452 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001453 ".tables ?TABLE? List names of tables\n"
1454 " If TABLE specified, only list tables matching\n"
1455 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001456 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001457 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001458 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001459 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001460;
1461
shaneb320ccd2009-10-21 03:42:58 +00001462static char zTimerHelp[] =
1463 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1464;
1465
drhdaffd0e2001-04-11 14:28:42 +00001466/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001467static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001468
drh75897232000-05-29 14:26:00 +00001469/*
drh44c2eb12003-04-30 11:38:26 +00001470** Make sure the database is open. If it is not, then open it. If
1471** the database fails to open, print an error message and exit.
1472*/
1473static void open_db(struct callback_data *p){
1474 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001475 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001476 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001477 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001478 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1479 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1480 shellstaticFunc, 0, 0);
1481 }
1482 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001483 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001484 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001485 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001486 }
drhc2e87a32006-06-27 15:16:14 +00001487#ifndef SQLITE_OMIT_LOAD_EXTENSION
1488 sqlite3_enable_load_extension(p->db, 1);
1489#endif
drh44c2eb12003-04-30 11:38:26 +00001490 }
1491}
1492
1493/*
drhfeac5f82004-08-01 00:10:45 +00001494** Do C-language style dequoting.
1495**
1496** \t -> tab
1497** \n -> newline
1498** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001499** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001500** \NNN -> ascii character NNN in octal
1501** \\ -> backslash
1502*/
1503static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001504 int i, j;
1505 char c;
drhfeac5f82004-08-01 00:10:45 +00001506 for(i=j=0; (c = z[i])!=0; i++, j++){
1507 if( c=='\\' ){
1508 c = z[++i];
1509 if( c=='n' ){
1510 c = '\n';
1511 }else if( c=='t' ){
1512 c = '\t';
1513 }else if( c=='r' ){
1514 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001515 }else if( c=='\\' ){
1516 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001517 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001518 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001519 if( z[i+1]>='0' && z[i+1]<='7' ){
1520 i++;
1521 c = (c<<3) + z[i] - '0';
1522 if( z[i+1]>='0' && z[i+1]<='7' ){
1523 i++;
1524 c = (c<<3) + z[i] - '0';
1525 }
1526 }
1527 }
1528 }
1529 z[j] = c;
1530 }
1531 z[j] = 0;
1532}
1533
1534/*
drh348d19c2013-06-03 12:47:43 +00001535** Return the value of a hexadecimal digit. Return -1 if the input
1536** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001537*/
drh348d19c2013-06-03 12:47:43 +00001538static int hexDigitValue(char c){
1539 if( c>='0' && c<='9' ) return c - '0';
1540 if( c>='a' && c<='f' ) return c - 'a' + 10;
1541 if( c>='A' && c<='F' ) return c - 'A' + 10;
1542 return -1;
drhc28490c2006-10-26 14:25:58 +00001543}
1544
1545/*
drh7d9f3942013-04-03 01:26:54 +00001546** Interpret zArg as an integer value, possibly with suffixes.
1547*/
1548static sqlite3_int64 integerValue(const char *zArg){
1549 sqlite3_int64 v = 0;
1550 static const struct { char *zSuffix; int iMult; } aMult[] = {
1551 { "KiB", 1024 },
1552 { "MiB", 1024*1024 },
1553 { "GiB", 1024*1024*1024 },
1554 { "KB", 1000 },
1555 { "MB", 1000000 },
1556 { "GB", 1000000000 },
1557 { "K", 1000 },
1558 { "M", 1000000 },
1559 { "G", 1000000000 },
1560 };
1561 int i;
1562 int isNeg = 0;
1563 if( zArg[0]=='-' ){
1564 isNeg = 1;
1565 zArg++;
1566 }else if( zArg[0]=='+' ){
1567 zArg++;
1568 }
drh348d19c2013-06-03 12:47:43 +00001569 if( zArg[0]=='0' && zArg[1]=='x' ){
1570 int x;
1571 zArg += 2;
1572 while( (x = hexDigitValue(zArg[0]))>=0 ){
1573 v = (v<<4) + x;
1574 zArg++;
1575 }
1576 }else{
1577 while( IsDigit(zArg[0]) ){
1578 v = v*10 + zArg[0] - '0';
1579 zArg++;
1580 }
drh7d9f3942013-04-03 01:26:54 +00001581 }
drhc2bed0a2013-05-24 11:57:50 +00001582 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001583 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1584 v *= aMult[i].iMult;
1585 break;
1586 }
1587 }
1588 return isNeg? -v : v;
1589}
1590
1591/*
drh348d19c2013-06-03 12:47:43 +00001592** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1593** for TRUE and FALSE. Return the integer value if appropriate.
1594*/
1595static int booleanValue(char *zArg){
1596 int i;
1597 if( zArg[0]=='0' && zArg[1]=='x' ){
1598 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1599 }else{
1600 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1601 }
1602 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1603 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1604 return 1;
1605 }
1606 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1607 return 0;
1608 }
1609 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1610 zArg);
1611 return 0;
1612}
1613
1614/*
drh42f64e52012-04-04 16:56:23 +00001615** Close an output file, assuming it is not stderr or stdout
1616*/
1617static void output_file_close(FILE *f){
1618 if( f && f!=stdout && f!=stderr ) fclose(f);
1619}
1620
1621/*
1622** Try to open an output file. The names "stdout" and "stderr" are
1623** recognized and do the right thing. NULL is returned if the output
1624** filename is "off".
1625*/
1626static FILE *output_file_open(const char *zFile){
1627 FILE *f;
1628 if( strcmp(zFile,"stdout")==0 ){
1629 f = stdout;
1630 }else if( strcmp(zFile, "stderr")==0 ){
1631 f = stderr;
1632 }else if( strcmp(zFile, "off")==0 ){
1633 f = 0;
1634 }else{
1635 f = fopen(zFile, "wb");
1636 if( f==0 ){
1637 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1638 }
1639 }
1640 return f;
1641}
1642
1643/*
1644** A routine for handling output from sqlite3_trace().
1645*/
1646static void sql_trace_callback(void *pArg, const char *z){
1647 FILE *f = (FILE*)pArg;
1648 if( f ) fprintf(f, "%s\n", z);
1649}
1650
1651/*
drhd8621b92012-04-17 09:09:33 +00001652** A no-op routine that runs with the ".breakpoint" doc-command. This is
1653** a useful spot to set a debugger breakpoint.
1654*/
1655static void test_breakpoint(void){
1656 static int nCall = 0;
1657 nCall++;
1658}
1659
1660/*
drhdb95f682013-06-26 22:46:00 +00001661** An object used to read a CSV file
1662*/
1663typedef struct CSVReader CSVReader;
1664struct CSVReader {
1665 const char *zFile; /* Name of the input file */
1666 FILE *in; /* Read the CSV text from this input stream */
1667 char *z; /* Accumulated text for a field */
1668 int n; /* Number of bytes in z */
1669 int nAlloc; /* Space allocated for z[] */
1670 int nLine; /* Current line number */
1671 int cTerm; /* Character that terminated the most recent field */
1672 int cSeparator; /* The separator character. (Usually ",") */
1673};
1674
1675/* Append a single byte to z[] */
1676static void csv_append_char(CSVReader *p, int c){
1677 if( p->n+1>=p->nAlloc ){
1678 p->nAlloc += p->nAlloc + 100;
1679 p->z = sqlite3_realloc(p->z, p->nAlloc);
1680 if( p->z==0 ){
1681 fprintf(stderr, "out of memory\n");
1682 exit(1);
1683 }
1684 }
1685 p->z[p->n++] = (char)c;
1686}
1687
1688/* Read a single field of CSV text. Compatible with rfc4180 and extended
1689** with the option of having a separator other than ",".
1690**
1691** + Input comes from p->in.
1692** + Store results in p->z of length p->n. Space to hold p->z comes
1693** from sqlite3_malloc().
1694** + Use p->cSep as the separator. The default is ",".
1695** + Keep track of the line number in p->nLine.
1696** + Store the character that terminates the field in p->cTerm. Store
1697** EOF on end-of-file.
1698** + Report syntax errors on stderr
1699*/
1700static char *csv_read_one_field(CSVReader *p){
1701 int c, pc;
1702 int cSep = p->cSeparator;
1703 p->n = 0;
1704 c = fgetc(p->in);
1705 if( c==EOF || seenInterrupt ){
1706 p->cTerm = EOF;
1707 return 0;
1708 }
1709 if( c=='"' ){
1710 int startLine = p->nLine;
1711 int cQuote = c;
1712 pc = 0;
1713 while( 1 ){
1714 c = fgetc(p->in);
1715 if( c=='\n' ) p->nLine++;
1716 if( c==cQuote ){
1717 if( pc==cQuote ){
1718 pc = 0;
1719 continue;
1720 }
1721 }
1722 if( (c==cSep && pc==cQuote)
1723 || (c=='\n' && pc==cQuote)
drh868ccf22013-08-28 13:33:40 +00001724 || (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote)
drhdb95f682013-06-26 22:46:00 +00001725 || (c==EOF && pc==cQuote)
1726 ){
1727 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00001728 p->cTerm = c;
1729 break;
1730 }
1731 if( pc==cQuote && c!='\r' ){
1732 fprintf(stderr, "%s:%d: unescaped %c character\n",
1733 p->zFile, p->nLine, cQuote);
1734 }
1735 if( c==EOF ){
1736 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
1737 p->zFile, startLine, cQuote);
drhdb95f682013-06-26 22:46:00 +00001738 p->cTerm = EOF;
1739 break;
1740 }
1741 csv_append_char(p, c);
1742 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00001743 }
drhdb95f682013-06-26 22:46:00 +00001744 }else{
drhd0a64dc2013-06-30 20:24:26 +00001745 while( c!=EOF && c!=cSep && c!='\n' ){
drhdb95f682013-06-26 22:46:00 +00001746 csv_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00001747 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00001748 }
1749 if( c=='\n' ){
1750 p->nLine++;
1751 if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
1752 }
drhdb95f682013-06-26 22:46:00 +00001753 p->cTerm = c;
1754 }
drh8dd675e2013-07-12 21:09:24 +00001755 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00001756 return p->z;
1757}
1758
1759/*
drh75897232000-05-29 14:26:00 +00001760** If an input line begins with "." then invoke this routine to
1761** process that line.
drh67505e72002-04-19 12:34:06 +00001762**
drh47ad6842006-11-08 12:25:42 +00001763** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001764*/
drh44c2eb12003-04-30 11:38:26 +00001765static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001766 int i = 1;
1767 int nArg = 0;
1768 int n, c;
drh67505e72002-04-19 12:34:06 +00001769 int rc = 0;
drh75897232000-05-29 14:26:00 +00001770 char *azArg[50];
1771
1772 /* Parse the input line into tokens.
1773 */
1774 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001775 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001776 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001777 if( zLine[i]=='\'' || zLine[i]=='"' ){
1778 int delim = zLine[i++];
1779 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00001780 while( zLine[i] && zLine[i]!=delim ){
1781 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
1782 i++;
1783 }
drh75897232000-05-29 14:26:00 +00001784 if( zLine[i]==delim ){
1785 zLine[i++] = 0;
1786 }
drhfeac5f82004-08-01 00:10:45 +00001787 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001788 }else{
1789 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001790 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001791 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001792 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001793 }
1794 }
1795
1796 /* Process the input line.
1797 */
shane9bd1b442009-10-23 01:27:39 +00001798 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001799 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001800 c = azArg[0][0];
drhbc46f022013-01-23 18:53:23 +00001801 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1802 const char *zDestFile = 0;
1803 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00001804 sqlite3 *pDest;
1805 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00001806 int j;
1807 for(j=1; j<nArg; j++){
1808 const char *z = azArg[j];
1809 if( z[0]=='-' ){
1810 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00001811 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00001812 {
1813 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1814 return 1;
1815 }
1816 }else if( zDestFile==0 ){
1817 zDestFile = azArg[j];
1818 }else if( zDb==0 ){
1819 zDb = zDestFile;
1820 zDestFile = azArg[j];
1821 }else{
1822 fprintf(stderr, "too many arguments to .backup\n");
1823 return 1;
1824 }
drh9ff849f2009-02-04 20:55:57 +00001825 }
drhbc46f022013-01-23 18:53:23 +00001826 if( zDestFile==0 ){
1827 fprintf(stderr, "missing FILENAME argument on .backup\n");
1828 return 1;
1829 }
1830 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00001831 rc = sqlite3_open(zDestFile, &pDest);
1832 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001833 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001834 sqlite3_close(pDest);
1835 return 1;
1836 }
drhdc2c4912009-02-04 22:46:47 +00001837 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001838 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1839 if( pBackup==0 ){
1840 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1841 sqlite3_close(pDest);
1842 return 1;
1843 }
1844 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1845 sqlite3_backup_finish(pBackup);
1846 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001847 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001848 }else{
1849 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001850 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001851 }
1852 sqlite3_close(pDest);
1853 }else
1854
shanehe2aa9d72009-11-06 17:20:17 +00001855 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001856 bail_on_error = booleanValue(azArg[1]);
1857 }else
1858
drhd8621b92012-04-17 09:09:33 +00001859 /* The undocumented ".breakpoint" command causes a call to the no-op
1860 ** routine named test_breakpoint().
1861 */
1862 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1863 test_breakpoint();
1864 }else
1865
shanehe2aa9d72009-11-06 17:20:17 +00001866 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001867 struct callback_data data;
1868 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001869 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001870 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001871 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001872 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001873 data.colWidth[0] = 3;
1874 data.colWidth[1] = 15;
1875 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001876 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001877 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001878 if( zErrMsg ){
1879 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001880 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001881 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001882 }
1883 }else
1884
shanehe2aa9d72009-11-06 17:20:17 +00001885 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001886 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001887 /* When playing back a "dump", the content might appear in an order
1888 ** which causes immediate foreign key constraints to be violated.
1889 ** So disable foreign-key constraint enforcement to prevent problems. */
1890 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001891 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001892 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001893 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001894 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001895 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001896 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001897 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001898 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001899 );
1900 run_schema_dump_query(p,
1901 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001902 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001903 );
drh2f464a02011-10-13 00:41:49 +00001904 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001905 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001906 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001907 );
drh4c653a02000-06-07 01:27:47 +00001908 }else{
1909 int i;
drhdd3d4592004-08-30 01:54:05 +00001910 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001911 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001912 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001913 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001914 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001915 " AND sql NOT NULL");
1916 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001917 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001918 "WHERE sql NOT NULL"
1919 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001920 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001921 );
danielk1977bc6ada42004-06-30 08:20:16 +00001922 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001923 }
1924 }
drh45e29d82006-11-20 16:21:10 +00001925 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001926 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001927 p->writableSchema = 0;
1928 }
drh56197952011-10-13 16:30:13 +00001929 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1930 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001931 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001932 }else
drh75897232000-05-29 14:26:00 +00001933
shanehe2aa9d72009-11-06 17:20:17 +00001934 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001935 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001936 }else
1937
drhd3ac7d92013-01-25 18:33:43 +00001938 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00001939 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00001940 rc = 2;
drh75897232000-05-29 14:26:00 +00001941 }else
1942
shanehe2aa9d72009-11-06 17:20:17 +00001943 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001944 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001945 if(val == 1) {
1946 if(!p->explainPrev.valid) {
1947 p->explainPrev.valid = 1;
1948 p->explainPrev.mode = p->mode;
1949 p->explainPrev.showHeader = p->showHeader;
1950 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1951 }
1952 /* We could put this code under the !p->explainValid
1953 ** condition so that it does not execute if we are already in
1954 ** explain mode. However, always executing it allows us an easy
1955 ** was to reset to explain mode in case the user previously
1956 ** did an .explain followed by a .width, .mode or .header
1957 ** command.
1958 */
danielk19770d78bae2008-01-03 07:09:48 +00001959 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001960 p->showHeader = 1;
1961 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001962 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001963 p->colWidth[1] = 13; /* opcode */
1964 p->colWidth[2] = 4; /* P1 */
1965 p->colWidth[3] = 4; /* P2 */
1966 p->colWidth[4] = 4; /* P3 */
1967 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001968 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001969 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001970 }else if (p->explainPrev.valid) {
1971 p->explainPrev.valid = 0;
1972 p->mode = p->explainPrev.mode;
1973 p->showHeader = p->explainPrev.showHeader;
1974 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1975 }
drh75897232000-05-29 14:26:00 +00001976 }else
1977
drhc28490c2006-10-26 14:25:58 +00001978 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001979 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001980 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001981 }else
1982
1983 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001984 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001985 if( HAS_TIMER ){
1986 fprintf(stderr,"%s",zTimerHelp);
1987 }
drh75897232000-05-29 14:26:00 +00001988 }else
1989
shanehe2aa9d72009-11-06 17:20:17 +00001990 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001991 char *zTable = azArg[2]; /* Insert data into this table */
drh5bde8162013-06-27 14:07:53 +00001992 char *zFile = azArg[1]; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00001993 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001994 int nCol; /* Number of columns in the table */
1995 int nByte; /* Number of bytes in an SQL string */
1996 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00001997 int needCommit; /* True to COMMIT or ROLLBACK at end */
drhfeac5f82004-08-01 00:10:45 +00001998 int nSep; /* Number of bytes in p->separator[] */
1999 char *zSql; /* An SQL statement */
drhdb95f682013-06-26 22:46:00 +00002000 CSVReader sCsv; /* Reader context */
drh5bde8162013-06-27 14:07:53 +00002001 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002002
drhdb95f682013-06-26 22:46:00 +00002003 seenInterrupt = 0;
2004 memset(&sCsv, 0, sizeof(sCsv));
drha543c822006-06-08 16:10:14 +00002005 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002006 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002007 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00002008 fprintf(stderr, "Error: non-null separator required for import\n");
2009 return 1;
drhfeac5f82004-08-01 00:10:45 +00002010 }
drhdb95f682013-06-26 22:46:00 +00002011 if( nSep>1 ){
2012 fprintf(stderr, "Error: multi-character separators not allowed"
2013 " for import\n");
2014 return 1;
2015 }
drh5bde8162013-06-27 14:07:53 +00002016 sCsv.zFile = zFile;
2017 sCsv.nLine = 1;
2018 if( sCsv.zFile[0]=='|' ){
2019 sCsv.in = popen(sCsv.zFile+1, "r");
2020 sCsv.zFile = "<pipe>";
2021 xCloser = pclose;
2022 }else{
2023 sCsv.in = fopen(sCsv.zFile, "rb");
2024 xCloser = fclose;
2025 }
drhdb95f682013-06-26 22:46:00 +00002026 if( sCsv.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002027 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002028 return 1;
2029 }
2030 sCsv.cSeparator = p->separator[0];
drh7b075e32011-09-28 01:10:00 +00002031 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002032 if( zSql==0 ){
2033 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002034 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002035 return 1;
2036 }
drh4f21c4a2008-12-10 22:15:00 +00002037 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002038 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002039 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2040 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2041 char cSep = '(';
2042 while( csv_read_one_field(&sCsv) ){
2043 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
2044 cSep = ',';
2045 if( sCsv.cTerm!=sCsv.cSeparator ) break;
2046 }
drh5bde8162013-06-27 14:07:53 +00002047 if( cSep=='(' ){
2048 sqlite3_free(zCreate);
2049 sqlite3_free(sCsv.z);
2050 xCloser(sCsv.in);
2051 fprintf(stderr,"%s: empty file\n", sCsv.zFile);
2052 return 1;
2053 }
drhdb95f682013-06-26 22:46:00 +00002054 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2055 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2056 sqlite3_free(zCreate);
2057 if( rc ){
2058 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2059 sqlite3_errmsg(db));
2060 sqlite3_free(sCsv.z);
drh5bde8162013-06-27 14:07:53 +00002061 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002062 return 1;
2063 }
2064 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
2065 }
drhfeac5f82004-08-01 00:10:45 +00002066 sqlite3_free(zSql);
2067 if( rc ){
shane916f9612009-10-23 00:37:15 +00002068 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002069 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
drh5bde8162013-06-27 14:07:53 +00002070 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002071 return 1;
drhfeac5f82004-08-01 00:10:45 +00002072 }
shane916f9612009-10-23 00:37:15 +00002073 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002074 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002075 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002076 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002077 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002078 if( zSql==0 ){
2079 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002080 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002081 return 1;
2082 }
drhdb95f682013-06-26 22:46:00 +00002083 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002084 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002085 for(i=1; i<nCol; i++){
2086 zSql[j++] = ',';
2087 zSql[j++] = '?';
2088 }
2089 zSql[j++] = ')';
2090 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002091 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002092 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002093 if( rc ){
2094 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002095 if (pStmt) sqlite3_finalize(pStmt);
drh5bde8162013-06-27 14:07:53 +00002096 xCloser(sCsv.in);
drh47ad6842006-11-08 12:25:42 +00002097 return 1;
drhfeac5f82004-08-01 00:10:45 +00002098 }
drh2d463112013-08-06 14:36:36 +00002099 needCommit = sqlite3_get_autocommit(db);
2100 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00002101 do{
2102 int startLine = sCsv.nLine;
drhfeac5f82004-08-01 00:10:45 +00002103 for(i=0; i<nCol; i++){
drhdb95f682013-06-26 22:46:00 +00002104 char *z = csv_read_one_field(&sCsv);
2105 if( z==0 && i==0 ) break;
2106 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
2107 if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
2108 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2109 "filling the rest with NULL\n",
2110 sCsv.zFile, startLine, nCol, i+1);
2111 i++;
2112 while( i<nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002113 }
drhfeac5f82004-08-01 00:10:45 +00002114 }
drhdb95f682013-06-26 22:46:00 +00002115 if( sCsv.cTerm==sCsv.cSeparator ){
2116 do{
2117 csv_read_one_field(&sCsv);
2118 i++;
2119 }while( sCsv.cTerm==sCsv.cSeparator );
2120 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2121 "extras ignored\n",
2122 sCsv.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002123 }
drhdb95f682013-06-26 22:46:00 +00002124 if( i>=nCol ){
2125 sqlite3_step(pStmt);
2126 rc = sqlite3_reset(pStmt);
2127 if( rc!=SQLITE_OK ){
2128 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
2129 sqlite3_errmsg(db));
2130 }
2131 }
2132 }while( sCsv.cTerm!=EOF );
2133
drh5bde8162013-06-27 14:07:53 +00002134 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002135 sqlite3_free(sCsv.z);
drhfeac5f82004-08-01 00:10:45 +00002136 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00002137 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002138 }else
2139
shanehe2aa9d72009-11-06 17:20:17 +00002140 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002141 struct callback_data data;
2142 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002143 open_db(p);
drh75897232000-05-29 14:26:00 +00002144 memcpy(&data, p, sizeof(data));
2145 data.showHeader = 0;
2146 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002147 if( nArg==1 ){
2148 rc = sqlite3_exec(p->db,
2149 "SELECT name FROM sqlite_master "
2150 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2151 "UNION ALL "
2152 "SELECT name FROM sqlite_temp_master "
2153 "WHERE type='index' "
2154 "ORDER BY 1",
2155 callback, &data, &zErrMsg
2156 );
2157 }else{
2158 zShellStatic = azArg[1];
2159 rc = sqlite3_exec(p->db,
2160 "SELECT name FROM sqlite_master "
2161 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2162 "UNION ALL "
2163 "SELECT name FROM sqlite_temp_master "
2164 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2165 "ORDER BY 1",
2166 callback, &data, &zErrMsg
2167 );
2168 zShellStatic = 0;
2169 }
drh75897232000-05-29 14:26:00 +00002170 if( zErrMsg ){
2171 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002172 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002173 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002174 }else if( rc != SQLITE_OK ){
2175 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2176 rc = 1;
drh75897232000-05-29 14:26:00 +00002177 }
2178 }else
2179
drhae5e4452007-05-03 17:18:36 +00002180#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002181 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002182 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002183 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2184 iotrace = 0;
2185 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002186 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002187 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002188 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002189 iotrace = stdout;
2190 }else{
2191 iotrace = fopen(azArg[1], "w");
2192 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002193 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002194 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002195 rc = 1;
drhb0603412007-02-28 04:47:26 +00002196 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002197 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002198 }
2199 }
2200 }else
drhae5e4452007-05-03 17:18:36 +00002201#endif
drhb0603412007-02-28 04:47:26 +00002202
drh70df4fe2006-06-13 15:12:21 +00002203#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002204 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2205 const char *zFile, *zProc;
2206 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00002207 zFile = azArg[1];
2208 zProc = nArg>=3 ? azArg[2] : 0;
2209 open_db(p);
2210 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2211 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002212 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002213 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002214 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002215 }
2216 }else
drh70df4fe2006-06-13 15:12:21 +00002217#endif
drh1e397f82006-06-08 15:28:43 +00002218
drhc8ba2122011-03-23 11:16:22 +00002219 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00002220 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00002221 output_file_close(p->pLog);
2222 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00002223 }else
2224
shanehe2aa9d72009-11-06 17:20:17 +00002225 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00002226 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002227 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002228 ||
shanehe2aa9d72009-11-06 17:20:17 +00002229 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002230 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002231 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002232 ||
shanehe2aa9d72009-11-06 17:20:17 +00002233 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002234 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002235 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002236 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002237 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002238 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002239 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002240 p->mode = MODE_Tcl;
mistachkin585dcb22012-12-04 00:23:43 +00002241 sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
shanehe2aa9d72009-11-06 17:20:17 +00002242 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002243 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002244 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002245 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002246 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002247 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002248 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002249 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002250 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002251 }else {
shane9bd1b442009-10-23 01:27:39 +00002252 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002253 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002254 rc = 1;
drh75897232000-05-29 14:26:00 +00002255 }
2256 }else
2257
shanehe2aa9d72009-11-06 17:20:17 +00002258 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2259 int n2 = strlen30(azArg[1]);
2260 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2261 p->mode = MODE_Insert;
2262 set_table_name(p, azArg[2]);
2263 }else {
2264 fprintf(stderr, "Error: invalid arguments: "
2265 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2266 rc = 1;
2267 }
2268 }else
2269
persicom7e2dfdd2002-04-18 02:46:52 +00002270 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002271 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2272 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002273 }else
2274
drh75897232000-05-29 14:26:00 +00002275 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002276 if( p->outfile[0]=='|' ){
2277 pclose(p->out);
2278 }else{
2279 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002280 }
drh42f64e52012-04-04 16:56:23 +00002281 p->outfile[0] = 0;
2282 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002283 p->out = popen(&azArg[1][1], "w");
2284 if( p->out==0 ){
2285 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2286 p->out = stdout;
2287 rc = 1;
2288 }else{
2289 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2290 }
drh75897232000-05-29 14:26:00 +00002291 }else{
drh42f64e52012-04-04 16:56:23 +00002292 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002293 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002294 if( strcmp(azArg[1],"off")!=0 ){
2295 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2296 }
drh75897232000-05-29 14:26:00 +00002297 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002298 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002299 } else {
drh42f64e52012-04-04 16:56:23 +00002300 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002301 }
2302 }
2303 }else
2304
drh078b1fd2012-09-21 13:40:02 +00002305 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2306 int i;
2307 for(i=1; i<nArg; i++){
2308 if( i>1 ) fprintf(p->out, " ");
2309 fprintf(p->out, "%s", azArg[i]);
2310 }
2311 fprintf(p->out, "\n");
2312 }else
2313
drhdd45df82002-04-18 12:39:03 +00002314 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002315 if( nArg >= 2) {
2316 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2317 }
2318 if( nArg >= 3) {
2319 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2320 }
2321 }else
2322
shanehe2aa9d72009-11-06 17:20:17 +00002323 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002324 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002325 }else
2326
drh9ff849f2009-02-04 20:55:57 +00002327 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002328 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002329 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002330 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2331 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002332 }else{
shane9bd1b442009-10-23 01:27:39 +00002333 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002334 fclose(alt);
2335 }
2336 }else
2337
shanehe2aa9d72009-11-06 17:20:17 +00002338 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002339 const char *zSrcFile;
2340 const char *zDb;
2341 sqlite3 *pSrc;
2342 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002343 int nTimeout = 0;
2344
drh9ff849f2009-02-04 20:55:57 +00002345 if( nArg==2 ){
2346 zSrcFile = azArg[1];
2347 zDb = "main";
2348 }else{
2349 zSrcFile = azArg[2];
2350 zDb = azArg[1];
2351 }
2352 rc = sqlite3_open(zSrcFile, &pSrc);
2353 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002354 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002355 sqlite3_close(pSrc);
2356 return 1;
2357 }
drhdc2c4912009-02-04 22:46:47 +00002358 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002359 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2360 if( pBackup==0 ){
2361 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2362 sqlite3_close(pSrc);
2363 return 1;
2364 }
drhdc2c4912009-02-04 22:46:47 +00002365 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2366 || rc==SQLITE_BUSY ){
2367 if( rc==SQLITE_BUSY ){
2368 if( nTimeout++ >= 3 ) break;
2369 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002370 }
2371 }
2372 sqlite3_backup_finish(pBackup);
2373 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002374 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002375 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002376 fprintf(stderr, "Error: source database is busy\n");
2377 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002378 }else{
2379 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002380 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002381 }
2382 sqlite3_close(pSrc);
2383 }else
2384
shanehe2aa9d72009-11-06 17:20:17 +00002385 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002386 struct callback_data data;
2387 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002388 open_db(p);
drh75897232000-05-29 14:26:00 +00002389 memcpy(&data, p, sizeof(data));
2390 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002391 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002392 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002393 int i;
drhf0693c82011-10-11 20:41:54 +00002394 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002395 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002396 char *new_argv[2], *new_colv[2];
2397 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2398 " type text,\n"
2399 " name text,\n"
2400 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002401 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002402 " sql text\n"
2403 ")";
2404 new_argv[1] = 0;
2405 new_colv[0] = "sql";
2406 new_colv[1] = 0;
2407 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002408 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002409 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002410 char *new_argv[2], *new_colv[2];
2411 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2412 " type text,\n"
2413 " name text,\n"
2414 " tbl_name text,\n"
2415 " rootpage integer,\n"
2416 " sql text\n"
2417 ")";
2418 new_argv[1] = 0;
2419 new_colv[0] = "sql";
2420 new_colv[1] = 0;
2421 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002422 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002423 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002424 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002425 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002426 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002427 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002428 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002429 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002430 "WHERE lower(tbl_name) LIKE shellstatic()"
2431 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00002432 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00002433 callback, &data, &zErrMsg);
2434 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002435 }
drh75897232000-05-29 14:26:00 +00002436 }else{
shane9bd1b442009-10-23 01:27:39 +00002437 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002438 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002439 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002440 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002441 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002442 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drh1ba00292013-05-06 21:01:06 +00002443 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00002444 callback, &data, &zErrMsg
2445 );
drh75897232000-05-29 14:26:00 +00002446 }
drh75897232000-05-29 14:26:00 +00002447 if( zErrMsg ){
2448 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002449 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002450 rc = 1;
2451 }else if( rc != SQLITE_OK ){
2452 fprintf(stderr,"Error: querying schema information\n");
2453 rc = 1;
2454 }else{
2455 rc = 0;
drh75897232000-05-29 14:26:00 +00002456 }
2457 }else
2458
drh340f5822013-06-27 13:01:21 +00002459#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00002460 /* Undocumented commands for internal testing. Subject to change
2461 ** without notice. */
2462 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
2463 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
2464 int i, v;
2465 for(i=1; i<nArg; i++){
2466 v = booleanValue(azArg[i]);
2467 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
2468 }
2469 }
2470 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
2471 int i; sqlite3_int64 v;
2472 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00002473 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00002474 v = integerValue(azArg[i]);
drh340f5822013-06-27 13:01:21 +00002475 sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);
2476 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00002477 }
2478 }
2479 }else
drh340f5822013-06-27 13:01:21 +00002480#endif
drh348d19c2013-06-03 12:47:43 +00002481
drh75897232000-05-29 14:26:00 +00002482 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002483 sqlite3_snprintf(sizeof(p->separator), p->separator,
2484 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002485 }else
2486
shanehe2aa9d72009-11-06 17:20:17 +00002487 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002488 int i;
2489 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002490 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002491 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002492 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002493 fprintf(p->out,"%9.9s: ", "nullvalue");
2494 output_c_string(p->out, p->nullvalue);
2495 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002496 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002497 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002498 fprintf(p->out,"%9.9s: ", "separator");
2499 output_c_string(p->out, p->separator);
2500 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002501 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002502 fprintf(p->out,"%9.9s: ","width");
2503 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002504 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002505 }
drhfeac5f82004-08-01 00:10:45 +00002506 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002507 }else
2508
shaneh642d8b82010-07-28 16:05:34 +00002509 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2510 p->statsOn = booleanValue(azArg[1]);
2511 }else
2512
shanehe2aa9d72009-11-06 17:20:17 +00002513 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002514 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002515 char **azResult;
drh98781232012-04-23 12:38:05 +00002516 int nRow, nAlloc;
2517 char *zSql = 0;
2518 int ii;
drh44c2eb12003-04-30 11:38:26 +00002519 open_db(p);
drh98781232012-04-23 12:38:05 +00002520 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2521 if( rc ) return rc;
2522 zSql = sqlite3_mprintf(
2523 "SELECT name FROM sqlite_master"
2524 " WHERE type IN ('table','view')"
2525 " AND name NOT LIKE 'sqlite_%%'"
2526 " AND name LIKE ?1");
2527 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2528 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2529 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2530 if( strcmp(zDbName,"temp")==0 ){
2531 zSql = sqlite3_mprintf(
2532 "%z UNION ALL "
2533 "SELECT 'temp.' || name FROM sqlite_temp_master"
2534 " WHERE type IN ('table','view')"
2535 " AND name NOT LIKE 'sqlite_%%'"
2536 " AND name LIKE ?1", zSql);
2537 }else{
2538 zSql = sqlite3_mprintf(
2539 "%z UNION ALL "
2540 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2541 " WHERE type IN ('table','view')"
2542 " AND name NOT LIKE 'sqlite_%%'"
2543 " AND name LIKE ?1", zSql, zDbName, zDbName);
2544 }
drha50da102000-08-08 20:19:09 +00002545 }
drh98781232012-04-23 12:38:05 +00002546 sqlite3_finalize(pStmt);
2547 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2548 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2549 sqlite3_free(zSql);
2550 if( rc ) return rc;
2551 nRow = nAlloc = 0;
2552 azResult = 0;
2553 if( nArg>1 ){
2554 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002555 }else{
drh98781232012-04-23 12:38:05 +00002556 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2557 }
2558 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2559 if( nRow>=nAlloc ){
2560 char **azNew;
2561 int n = nAlloc*2 + 10;
2562 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2563 if( azNew==0 ){
2564 fprintf(stderr, "Error: out of memory\n");
2565 break;
2566 }
2567 nAlloc = n;
2568 azResult = azNew;
2569 }
2570 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2571 if( azResult[nRow] ) nRow++;
2572 }
2573 sqlite3_finalize(pStmt);
2574 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002575 int len, maxlen = 0;
2576 int i, j;
2577 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002578 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002579 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002580 if( len>maxlen ) maxlen = len;
2581 }
2582 nPrintCol = 80/(maxlen+2);
2583 if( nPrintCol<1 ) nPrintCol = 1;
2584 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2585 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002586 for(j=i; j<nRow; j+=nPrintRow){
2587 char *zSp = j<nPrintRow ? "" : " ";
drh151b7d52013-05-06 20:28:54 +00002588 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
drhe3710332000-09-29 13:30:53 +00002589 }
drh151b7d52013-05-06 20:28:54 +00002590 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00002591 }
2592 }
drh98781232012-04-23 12:38:05 +00002593 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2594 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002595 }else
2596
shaneh96887e12011-02-10 21:08:58 +00002597 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002598 static const struct {
2599 const char *zCtrlName; /* Name of a test-control option */
2600 int ctrlCode; /* Integer code for that option */
2601 } aCtrl[] = {
2602 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2603 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2604 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2605 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2606 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2607 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2608 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2609 { "assert", SQLITE_TESTCTRL_ASSERT },
2610 { "always", SQLITE_TESTCTRL_ALWAYS },
2611 { "reserve", SQLITE_TESTCTRL_RESERVE },
2612 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2613 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002614 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2615 };
shaneh96887e12011-02-10 21:08:58 +00002616 int testctrl = -1;
2617 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002618 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002619 open_db(p);
2620
drhd416fe72011-03-17 16:45:50 +00002621 /* convert testctrl text option to value. allow any unique prefix
2622 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002623 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002624 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002625 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2626 if( testctrl<0 ){
2627 testctrl = aCtrl[i].ctrlCode;
2628 }else{
drhb07028f2011-10-14 21:49:18 +00002629 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002630 testctrl = -1;
2631 break;
2632 }
2633 }
2634 }
drh348d19c2013-06-03 12:47:43 +00002635 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002636 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2637 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2638 }else{
2639 switch(testctrl){
2640
2641 /* sqlite3_test_control(int, db, int) */
2642 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2643 case SQLITE_TESTCTRL_RESERVE:
2644 if( nArg==3 ){
2645 int opt = (int)strtol(azArg[2], 0, 0);
2646 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00002647 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002648 } else {
drhd416fe72011-03-17 16:45:50 +00002649 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2650 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002651 }
2652 break;
2653
2654 /* sqlite3_test_control(int) */
2655 case SQLITE_TESTCTRL_PRNG_SAVE:
2656 case SQLITE_TESTCTRL_PRNG_RESTORE:
2657 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002658 if( nArg==2 ){
2659 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00002660 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002661 } else {
2662 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2663 }
2664 break;
2665
2666 /* sqlite3_test_control(int, uint) */
2667 case SQLITE_TESTCTRL_PENDING_BYTE:
2668 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00002669 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002670 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002671 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002672 } else {
drhd416fe72011-03-17 16:45:50 +00002673 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2674 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002675 }
2676 break;
2677
2678 /* sqlite3_test_control(int, int) */
2679 case SQLITE_TESTCTRL_ASSERT:
2680 case SQLITE_TESTCTRL_ALWAYS:
2681 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00002682 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002683 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002684 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002685 } else {
drhd416fe72011-03-17 16:45:50 +00002686 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2687 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002688 }
2689 break;
2690
2691 /* sqlite3_test_control(int, char *) */
2692#ifdef SQLITE_N_KEYWORD
2693 case SQLITE_TESTCTRL_ISKEYWORD:
2694 if( nArg==3 ){
2695 const char *opt = azArg[2];
2696 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002697 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002698 } else {
drhd416fe72011-03-17 16:45:50 +00002699 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2700 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002701 }
2702 break;
2703#endif
2704
2705 case SQLITE_TESTCTRL_BITVEC_TEST:
2706 case SQLITE_TESTCTRL_FAULT_INSTALL:
2707 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2708 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2709 default:
drhd416fe72011-03-17 16:45:50 +00002710 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2711 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002712 break;
2713 }
2714 }
2715 }else
2716
shanehe2aa9d72009-11-06 17:20:17 +00002717 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002718 open_db(p);
drh348d19c2013-06-03 12:47:43 +00002719 sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002720 }else
2721
drhd416fe72011-03-17 16:45:50 +00002722 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2723 && nArg==2
2724 ){
drh3b1a9882007-11-02 12:53:03 +00002725 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002726 }else
2727
drh42f64e52012-04-04 16:56:23 +00002728 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh98781232012-04-23 12:38:05 +00002729 open_db(p);
drh42f64e52012-04-04 16:56:23 +00002730 output_file_close(p->traceOut);
2731 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00002732#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002733 if( p->traceOut==0 ){
2734 sqlite3_trace(p->db, 0, 0);
2735 }else{
2736 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2737 }
2738#endif
2739 }else
2740
drh9fd301b2011-06-03 13:28:22 +00002741 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00002742 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002743 sqlite3_libversion(), sqlite3_sourceid());
2744 }else
2745
drhde60fc22011-12-14 17:53:36 +00002746 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2747 const char *zDbName = nArg==2 ? azArg[1] : "main";
2748 char *zVfsName = 0;
2749 if( p->db ){
2750 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2751 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00002752 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00002753 sqlite3_free(zVfsName);
2754 }
2755 }
2756 }else
2757
drhcef4fc82012-09-21 22:50:45 +00002758#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2759 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
2760 extern int sqlite3WhereTrace;
drh7d9f3942013-04-03 01:26:54 +00002761 sqlite3WhereTrace = booleanValue(azArg[1]);
drhcef4fc82012-09-21 22:50:45 +00002762 }else
2763#endif
2764
shanehe2aa9d72009-11-06 17:20:17 +00002765 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002766 int j;
drh43617e92006-03-06 20:55:46 +00002767 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002768 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00002769 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00002770 }
2771 }else
2772
2773 {
shane9bd1b442009-10-23 01:27:39 +00002774 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002775 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002776 rc = 1;
drh75897232000-05-29 14:26:00 +00002777 }
drh67505e72002-04-19 12:34:06 +00002778
2779 return rc;
drh75897232000-05-29 14:26:00 +00002780}
2781
drh67505e72002-04-19 12:34:06 +00002782/*
drh91a66392007-09-07 01:12:32 +00002783** Return TRUE if a semicolon occurs anywhere in the first N characters
2784** of string z[].
drh324ccef2003-02-05 14:06:20 +00002785*/
drh9f099fd2013-08-06 14:01:46 +00002786static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00002787 int i;
2788 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2789 return 0;
drh324ccef2003-02-05 14:06:20 +00002790}
2791
2792/*
drh70c7a4b2003-04-26 03:03:06 +00002793** Test to see if a line consists entirely of whitespace.
2794*/
2795static int _all_whitespace(const char *z){
2796 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002797 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002798 if( *z=='/' && z[1]=='*' ){
2799 z += 2;
2800 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2801 if( *z==0 ) return 0;
2802 z++;
2803 continue;
2804 }
2805 if( *z=='-' && z[1]=='-' ){
2806 z += 2;
2807 while( *z && *z!='\n' ){ z++; }
2808 if( *z==0 ) return 1;
2809 continue;
2810 }
2811 return 0;
2812 }
2813 return 1;
2814}
2815
2816/*
drha9b17162003-04-29 18:01:28 +00002817** Return TRUE if the line typed in is an SQL command terminator other
2818** than a semi-colon. The SQL Server style "go" command is understood
2819** as is the Oracle "/".
2820*/
drh9f099fd2013-08-06 14:01:46 +00002821static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002822 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002823 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2824 return 1; /* Oracle */
2825 }
drhf0693c82011-10-11 20:41:54 +00002826 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002827 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002828 return 1; /* SQL Server */
2829 }
2830 return 0;
2831}
2832
2833/*
drh233a5312008-12-18 22:25:13 +00002834** Return true if zSql is a complete SQL statement. Return false if it
2835** ends in the middle of a string literal or C-style comment.
2836*/
drh9f099fd2013-08-06 14:01:46 +00002837static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00002838 int rc;
2839 if( zSql==0 ) return 1;
2840 zSql[nSql] = ';';
2841 zSql[nSql+1] = 0;
2842 rc = sqlite3_complete(zSql);
2843 zSql[nSql] = 0;
2844 return rc;
2845}
2846
2847/*
drh67505e72002-04-19 12:34:06 +00002848** Read input from *in and process it. If *in==0 then input
2849** is interactive - the user is typing it it. Otherwise, input
2850** is coming from a file or device. A prompt is issued and history
2851** is saved only if input is interactive. An interrupt signal will
2852** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002853**
2854** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002855*/
drhc28490c2006-10-26 14:25:58 +00002856static int process_input(struct callback_data *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00002857 char *zLine = 0; /* A single input line */
2858 char *zSql = 0; /* Accumulated SQL text */
2859 int nLine; /* Length of current line */
2860 int nSql = 0; /* Bytes of zSql[] used */
2861 int nAlloc = 0; /* Allocated zSql[] space */
2862 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
2863 char *zErrMsg; /* Error message returned */
2864 int rc; /* Error code */
2865 int errCnt = 0; /* Number of errors seen */
2866 int lineno = 0; /* Current line number */
2867 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00002868
2869 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2870 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00002871 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00002872 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002873 /* End of input */
2874 if( stdin_is_interactive ) printf("\n");
2875 break;
drhc49f44e2006-10-26 18:15:42 +00002876 }
drh67505e72002-04-19 12:34:06 +00002877 if( seenInterrupt ){
2878 if( in!=0 ) break;
2879 seenInterrupt = 0;
2880 }
drhc28490c2006-10-26 14:25:58 +00002881 lineno++;
drh9f099fd2013-08-06 14:01:46 +00002882 if( nSql==0 && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002883 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002884 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002885 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002886 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002887 break;
2888 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002889 errCnt++;
2890 }
drhdaffd0e2001-04-11 14:28:42 +00002891 continue;
2892 }
drh9f099fd2013-08-06 14:01:46 +00002893 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002894 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002895 }
drh9f099fd2013-08-06 14:01:46 +00002896 nLine = strlen30(zLine);
2897 if( nSql+nLine+2>=nAlloc ){
2898 nAlloc = nSql+nLine+100;
2899 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00002900 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00002901 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002902 exit(1);
2903 }
drhdaffd0e2001-04-11 14:28:42 +00002904 }
drh9f099fd2013-08-06 14:01:46 +00002905 nSqlPrior = nSql;
2906 if( nSql==0 ){
2907 int i;
2908 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00002909 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00002910 memcpy(zSql, zLine+i, nLine+1-i);
2911 startline = lineno;
2912 nSql = nLine-i;
2913 }else{
2914 zSql[nSql++] = '\n';
2915 memcpy(zSql+nSql, zLine, nLine+1);
2916 nSql += nLine;
2917 }
2918 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00002919 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002920 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002921 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002922 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002923 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002924 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002925 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002926 char zPrefix[100];
2927 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002928 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002929 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002930 }else{
shane9bd1b442009-10-23 01:27:39 +00002931 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002932 }
drh7f953e22002-07-13 17:33:45 +00002933 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002934 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002935 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002936 zErrMsg = 0;
2937 }else{
shaned2bed1c2009-10-21 03:56:54 +00002938 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002939 }
drhc49f44e2006-10-26 18:15:42 +00002940 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002941 }
drhdaffd0e2001-04-11 14:28:42 +00002942 nSql = 0;
drh9f099fd2013-08-06 14:01:46 +00002943 }else if( nSql && _all_whitespace(zSql) ){
drh7a411f42013-04-17 17:33:17 +00002944 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00002945 }
2946 }
drh9f099fd2013-08-06 14:01:46 +00002947 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00002948 if( !_all_whitespace(zSql) ){
2949 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2950 }
drhdaffd0e2001-04-11 14:28:42 +00002951 free(zSql);
2952 }
danielk19772ac27622007-07-03 05:31:16 +00002953 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00002954 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00002955}
2956
drh67505e72002-04-19 12:34:06 +00002957/*
2958** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002959** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002960*/
2961static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002962 static char *home_dir = NULL;
2963 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002964
drh83905c92012-06-21 13:00:37 +00002965#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00002966 {
2967 struct passwd *pwent;
2968 uid_t uid = getuid();
2969 if( (pwent=getpwuid(uid)) != NULL) {
2970 home_dir = pwent->pw_dir;
2971 }
drh67505e72002-04-19 12:34:06 +00002972 }
2973#endif
2974
chw65d3c132007-11-12 21:09:10 +00002975#if defined(_WIN32_WCE)
2976 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2977 */
drh85e72432012-04-11 11:38:53 +00002978 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00002979#else
2980
drh83905c92012-06-21 13:00:37 +00002981#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00002982 if (!home_dir) {
2983 home_dir = getenv("USERPROFILE");
2984 }
2985#endif
2986
drh67505e72002-04-19 12:34:06 +00002987 if (!home_dir) {
2988 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002989 }
2990
drh83905c92012-06-21 13:00:37 +00002991#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00002992 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002993 char *zDrive, *zPath;
2994 int n;
2995 zDrive = getenv("HOMEDRIVE");
2996 zPath = getenv("HOMEPATH");
2997 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002998 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002999 home_dir = malloc( n );
3000 if( home_dir==0 ) return 0;
3001 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3002 return home_dir;
3003 }
3004 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00003005 }
3006#endif
3007
chw65d3c132007-11-12 21:09:10 +00003008#endif /* !_WIN32_WCE */
3009
drh67505e72002-04-19 12:34:06 +00003010 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00003011 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00003012 char *z = malloc( n );
3013 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00003014 home_dir = z;
3015 }
drhe98d4fa2002-04-21 19:06:22 +00003016
drh67505e72002-04-19 12:34:06 +00003017 return home_dir;
3018}
3019
3020/*
3021** Read input from the file given by sqliterc_override. Or if that
3022** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00003023**
3024** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00003025*/
shane9bd1b442009-10-23 01:27:39 +00003026static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00003027 struct callback_data *p, /* Configuration data */
3028 const char *sqliterc_override /* Name of config file. NULL to use default */
3029){
persicom7e2dfdd2002-04-18 02:46:52 +00003030 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00003031 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00003032 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003033 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00003034 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003035
3036 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00003037 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00003038 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00003039#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00003040 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00003041#endif
shane9bd1b442009-10-23 01:27:39 +00003042 return 1;
drhe98d4fa2002-04-21 19:06:22 +00003043 }
drh2f3de322012-06-27 16:41:31 +00003044 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00003045 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
3046 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003047 }
drha1f9b5e2004-02-14 16:31:02 +00003048 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00003049 if( in ){
drhc28490c2006-10-26 14:25:58 +00003050 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00003051 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00003052 }
shane9bd1b442009-10-23 01:27:39 +00003053 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00003054 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00003055 }
drh85e72432012-04-11 11:38:53 +00003056 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00003057 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00003058}
3059
drh67505e72002-04-19 12:34:06 +00003060/*
drhe1e38c42003-05-04 18:30:59 +00003061** Show available command line options
3062*/
3063static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00003064 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00003065 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003066 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00003067 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00003068 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00003069 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00003070 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00003071 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00003072#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3073 " -heap SIZE Size of heap for memsys3 or memsys5\n"
3074#endif
drhcc3b4f82012-02-07 14:13:50 +00003075 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00003076 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00003077 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003078 " -line set output mode to 'line'\n"
3079 " -list set output mode to 'list'\n"
drh7d9f3942013-04-03 01:26:54 +00003080 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00003081#ifdef SQLITE_ENABLE_MULTIPLEX
3082 " -multiplex enable the multiplexor VFS\n"
3083#endif
drh98d312f2012-10-25 15:23:14 +00003084 " -nullvalue TEXT set text string for NULL values. Default ''\n"
3085 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00003086 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00003087 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00003088 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00003089#ifdef SQLITE_ENABLE_VFSTRACE
3090 " -vfstrace enable tracing of all VFS calls\n"
3091#endif
drhe1e38c42003-05-04 18:30:59 +00003092;
3093static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00003094 fprintf(stderr,
3095 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3096 "FILENAME is the name of an SQLite database. A new database is created\n"
3097 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00003098 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00003099 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00003100 }else{
3101 fprintf(stderr, "Use the -help option for additional information\n");
3102 }
3103 exit(1);
3104}
3105
3106/*
drh67505e72002-04-19 12:34:06 +00003107** Initialize the state information in data
3108*/
drh0850b532006-01-31 19:31:43 +00003109static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00003110 memset(data, 0, sizeof(*data));
3111 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00003112 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00003113 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00003114 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00003115 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00003116 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3117 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00003118 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00003119}
3120
drh98d312f2012-10-25 15:23:14 +00003121/*
3122** Get the argument to an --option. Throw an error and die if no argument
3123** is available.
3124*/
3125static char *cmdline_option_value(int argc, char **argv, int i){
3126 if( i==argc ){
3127 fprintf(stderr, "%s: Error: missing argument to %s\n",
3128 argv[0], argv[argc-1]);
3129 exit(1);
3130 }
3131 return argv[i];
3132}
3133
drh75897232000-05-29 14:26:00 +00003134int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003135 char *zErrMsg = 0;
3136 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00003137 const char *zInitFile = 0;
3138 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003139 int i;
drhc28490c2006-10-26 14:25:58 +00003140 int rc = 0;
drh75897232000-05-29 14:26:00 +00003141
drh52784bd2011-05-18 17:15:06 +00003142 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
3143 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
3144 sqlite3_sourceid(), SQLITE_SOURCE_ID);
3145 exit(1);
3146 }
drhdaffd0e2001-04-11 14:28:42 +00003147 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003148 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003149 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003150
drh44c2eb12003-04-30 11:38:26 +00003151 /* Make sure we have a valid signal handler early, before anything
3152 ** else is done.
3153 */
drh4c504392000-10-16 22:06:40 +00003154#ifdef SIGINT
3155 signal(SIGINT, interrupt_handler);
3156#endif
drh44c2eb12003-04-30 11:38:26 +00003157
drh22fbcb82004-02-01 01:22:50 +00003158 /* Do an initial pass through the command-line argument to locate
3159 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00003160 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00003161 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003162 */
drh98d312f2012-10-25 15:23:14 +00003163 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00003164 char *z;
drhc28490c2006-10-26 14:25:58 +00003165 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003166 if( z[0]!='-' ){
3167 if( data.zDbFilename==0 ){
3168 data.zDbFilename = z;
3169 continue;
3170 }
3171 if( zFirstCmd==0 ){
3172 zFirstCmd = z;
3173 continue;
3174 }
3175 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
3176 fprintf(stderr,"Use -help for a list of options.\n");
3177 return 1;
3178 }
drhcc3b4f82012-02-07 14:13:50 +00003179 if( z[1]=='-' ) z++;
3180 if( strcmp(z,"-separator")==0
3181 || strcmp(z,"-nullvalue")==0
3182 || strcmp(z,"-cmd")==0
3183 ){
drh98d312f2012-10-25 15:23:14 +00003184 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003185 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00003186 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003187 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00003188 /* Need to check for batch mode here to so we can avoid printing
3189 ** informational messages (like from process_sqliterc) before
3190 ** we do the actual processing of arguments later in a second pass.
3191 */
shanef69573d2009-10-24 02:06:14 +00003192 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00003193 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00003194#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00003195 const char *zSize;
3196 sqlite3_int64 szHeap;
3197
drh98d312f2012-10-25 15:23:14 +00003198 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00003199 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00003200 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00003201 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3202#endif
drh97ae8ff2011-03-16 16:56:29 +00003203#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00003204 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00003205 extern int vfstrace_register(
3206 const char *zTraceName,
3207 const char *zOldVfsName,
3208 int (*xOut)(const char*,void*),
3209 void *pOutArg,
3210 int makeDefault
3211 );
drh2b625e22011-03-16 17:05:28 +00003212 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00003213#endif
drh6f25e892011-07-08 17:02:57 +00003214#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00003215 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00003216 extern int sqlite3_multiple_initialize(const char*,int);
3217 sqlite3_multiplex_initialize(0, 1);
3218#endif
drh7d9f3942013-04-03 01:26:54 +00003219 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00003220 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
3221 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00003222 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00003223 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00003224 if( pVfs ){
3225 sqlite3_vfs_register(pVfs, 1);
3226 }else{
3227 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3228 exit(1);
3229 }
drh44c2eb12003-04-30 11:38:26 +00003230 }
3231 }
drh98d312f2012-10-25 15:23:14 +00003232 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00003233#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003234 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003235#else
shane86f5bdb2009-10-24 02:00:07 +00003236 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3237 return 1;
drh01b41712005-08-29 23:06:23 +00003238#endif
drh98d312f2012-10-25 15:23:14 +00003239 }
3240 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00003241
drh44c2eb12003-04-30 11:38:26 +00003242 /* Go ahead and open the database file if it already exists. If the
3243 ** file does not exist, delay opening it. This prevents empty database
3244 ** files from being created if a user mistypes the database name argument
3245 ** to the sqlite command-line tool.
3246 */
drhc8d74412004-08-31 23:41:26 +00003247 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003248 open_db(&data);
3249 }
3250
drh22fbcb82004-02-01 01:22:50 +00003251 /* Process the initialization file if there is one. If no -init option
3252 ** is given on the command line, look for a file named ~/.sqliterc and
3253 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003254 */
shane86f5bdb2009-10-24 02:00:07 +00003255 rc = process_sqliterc(&data,zInitFile);
3256 if( rc>0 ){
3257 return rc;
3258 }
drh44c2eb12003-04-30 11:38:26 +00003259
drh22fbcb82004-02-01 01:22:50 +00003260 /* Make a second pass through the command-line argument and set
3261 ** options. This second pass is delayed until after the initialization
3262 ** file is processed so that the command-line arguments will override
3263 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003264 */
drh98d312f2012-10-25 15:23:14 +00003265 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00003266 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003267 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00003268 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003269 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003270 i++;
3271 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003272 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003273 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003274 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003275 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003276 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003277 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003278 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003279 }else if( strcmp(z,"-csv")==0 ){
3280 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003281 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003282 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003283 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00003284 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003285 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003286 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00003287 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003288 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003289 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003290 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003291 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003292 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003293 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003294 }else if( strcmp(z,"-stats")==0 ){
3295 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003296 }else if( strcmp(z,"-bail")==0 ){
3297 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003298 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003299 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003300 return 0;
drhc28490c2006-10-26 14:25:58 +00003301 }else if( strcmp(z,"-interactive")==0 ){
3302 stdin_is_interactive = 1;
3303 }else if( strcmp(z,"-batch")==0 ){
3304 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003305 }else if( strcmp(z,"-heap")==0 ){
3306 i++;
drh7d9f3942013-04-03 01:26:54 +00003307 }else if( strcmp(z,"-mmap")==0 ){
3308 i++;
drha7e61d82011-03-12 17:02:57 +00003309 }else if( strcmp(z,"-vfs")==0 ){
3310 i++;
drh6f25e892011-07-08 17:02:57 +00003311#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003312 }else if( strcmp(z,"-vfstrace")==0 ){
3313 i++;
drh6f25e892011-07-08 17:02:57 +00003314#endif
3315#ifdef SQLITE_ENABLE_MULTIPLEX
3316 }else if( strcmp(z,"-multiplex")==0 ){
3317 i++;
3318#endif
drhcc3b4f82012-02-07 14:13:50 +00003319 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003320 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003321 }else if( strcmp(z,"-cmd")==0 ){
3322 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00003323 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00003324 if( z[0]=='.' ){
3325 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00003326 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00003327 }else{
3328 open_db(&data);
3329 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3330 if( zErrMsg!=0 ){
3331 fprintf(stderr,"Error: %s\n", zErrMsg);
3332 if( bail_on_error ) return rc!=0 ? rc : 1;
3333 }else if( rc!=0 ){
3334 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3335 if( bail_on_error ) return rc;
3336 }
3337 }
drh1e5d0e92000-05-31 23:33:17 +00003338 }else{
shane86f5bdb2009-10-24 02:00:07 +00003339 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003340 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003341 return 1;
3342 }
3343 }
drh44c2eb12003-04-30 11:38:26 +00003344
drh22fbcb82004-02-01 01:22:50 +00003345 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003346 /* Run just the command that follows the database name
3347 */
drh22fbcb82004-02-01 01:22:50 +00003348 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003349 rc = do_meta_command(zFirstCmd, &data);
drh99b39082013-04-17 12:19:48 +00003350 if( rc==2 ) rc = 0;
drh6ff13852001-11-25 13:18:23 +00003351 }else{
drh44c2eb12003-04-30 11:38:26 +00003352 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003353 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003354 if( zErrMsg!=0 ){
3355 fprintf(stderr,"Error: %s\n", zErrMsg);
3356 return rc!=0 ? rc : 1;
3357 }else if( rc!=0 ){
3358 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3359 return rc;
drh6ff13852001-11-25 13:18:23 +00003360 }
drh75897232000-05-29 14:26:00 +00003361 }
3362 }else{
drh44c2eb12003-04-30 11:38:26 +00003363 /* Run commands received from standard input
3364 */
drhc28490c2006-10-26 14:25:58 +00003365 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003366 char *zHome;
3367 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003368 int nHistory;
drh75897232000-05-29 14:26:00 +00003369 printf(
drh743e0032011-12-12 16:51:50 +00003370 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003371 "Enter \".help\" for instructions\n"
3372 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003373 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003374 );
drh67505e72002-04-19 12:34:06 +00003375 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003376 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003377 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003378 if( (zHistory = malloc(nHistory))!=0 ){
3379 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3380 }
drh67505e72002-04-19 12:34:06 +00003381 }
danielk19774af00c62005-01-23 23:43:21 +00003382#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003383 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003384#endif
drhc28490c2006-10-26 14:25:58 +00003385 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003386 if( zHistory ){
3387 stifle_history(100);
3388 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003389 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003390 }
drhdaffd0e2001-04-11 14:28:42 +00003391 }else{
drhc28490c2006-10-26 14:25:58 +00003392 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003393 }
3394 }
drh33048c02001-10-01 14:29:22 +00003395 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003396 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003397 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003398 }
drhc28490c2006-10-26 14:25:58 +00003399 return rc;
drh75897232000-05-29 14:26:00 +00003400}