blob: 26c38c59ea4532977c6b8ad80c527d88ec1c8981 [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 */
drh05782482013-10-24 15:20:20 +0000439 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000440 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000441 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000442 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000443};
444
445/*
446** These are the allowed modes.
447*/
drh967e8b72000-06-21 13:59:10 +0000448#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000449#define MODE_Column 1 /* One record per line in neat columns */
450#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000451#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
452#define MODE_Html 4 /* Generate an XHTML table */
453#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000454#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000455#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000456#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000457
drh66ce4d02008-02-15 17:38:06 +0000458static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000459 "line",
460 "column",
461 "list",
462 "semi",
463 "html",
drhfeac5f82004-08-01 00:10:45 +0000464 "insert",
465 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000466 "csv",
drh66ce4d02008-02-15 17:38:06 +0000467 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000468};
drh75897232000-05-29 14:26:00 +0000469
470/*
471** Number of elements in an array
472*/
drh902b9ee2008-12-05 17:17:07 +0000473#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000474
475/*
drhea678832008-12-10 19:26:22 +0000476** Compute a string length that is limited to what can be stored in
477** lower 30 bits of a 32-bit signed integer.
478*/
drh4f21c4a2008-12-10 22:15:00 +0000479static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000480 const char *z2 = z;
481 while( *z2 ){ z2++; }
482 return 0x3fffffff & (int)(z2 - z);
483}
484
485/*
drh127f9d72010-02-23 01:47:00 +0000486** A callback for the sqlite3_log() interface.
487*/
488static void shellLog(void *pArg, int iErrCode, const char *zMsg){
489 struct callback_data *p = (struct callback_data*)pArg;
490 if( p->pLog==0 ) return;
491 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
492 fflush(p->pLog);
493}
494
495/*
shane626a6e42009-10-22 17:30:15 +0000496** Output the given string as a hex-encoded blob (eg. X'1234' )
497*/
498static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
499 int i;
500 char *zBlob = (char *)pBlob;
501 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000502 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000503 fprintf(out,"'");
504}
505
506/*
drh28bd4bc2000-06-15 15:57:22 +0000507** Output the given string as a quoted string using SQL quoting conventions.
508*/
509static void output_quoted_string(FILE *out, const char *z){
510 int i;
511 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000512 for(i=0; z[i]; i++){
513 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000514 }
515 if( nSingle==0 ){
516 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000517 }else{
518 fprintf(out,"'");
519 while( *z ){
520 for(i=0; z[i] && z[i]!='\''; i++){}
521 if( i==0 ){
522 fprintf(out,"''");
523 z++;
524 }else if( z[i]=='\'' ){
525 fprintf(out,"%.*s''",i,z);
526 z += i+1;
527 }else{
drhcd7d2732002-02-26 23:24:26 +0000528 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000529 break;
530 }
531 }
drhcd7d2732002-02-26 23:24:26 +0000532 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000533 }
534}
535
536/*
drhfeac5f82004-08-01 00:10:45 +0000537** Output the given string as a quoted according to C or TCL quoting rules.
538*/
539static void output_c_string(FILE *out, const char *z){
540 unsigned int c;
541 fputc('"', out);
542 while( (c = *(z++))!=0 ){
543 if( c=='\\' ){
544 fputc(c, out);
545 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000546 }else if( c=='"' ){
547 fputc('\\', out);
548 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000549 }else if( c=='\t' ){
550 fputc('\\', out);
551 fputc('t', out);
552 }else if( c=='\n' ){
553 fputc('\\', out);
554 fputc('n', out);
555 }else if( c=='\r' ){
556 fputc('\\', out);
557 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000558 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000559 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000560 }else{
561 fputc(c, out);
562 }
563 }
564 fputc('"', out);
565}
566
567/*
drhc08a4f12000-06-15 16:49:48 +0000568** Output the given string with characters that are special to
569** HTML escaped.
570*/
571static void output_html_string(FILE *out, const char *z){
572 int i;
573 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000574 for(i=0; z[i]
575 && z[i]!='<'
576 && z[i]!='&'
577 && z[i]!='>'
578 && z[i]!='\"'
579 && z[i]!='\'';
580 i++){}
drhc08a4f12000-06-15 16:49:48 +0000581 if( i>0 ){
582 fprintf(out,"%.*s",i,z);
583 }
584 if( z[i]=='<' ){
585 fprintf(out,"&lt;");
586 }else if( z[i]=='&' ){
587 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000588 }else if( z[i]=='>' ){
589 fprintf(out,"&gt;");
590 }else if( z[i]=='\"' ){
591 fprintf(out,"&quot;");
592 }else if( z[i]=='\'' ){
593 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000594 }else{
595 break;
596 }
597 z += i + 1;
598 }
599}
600
601/*
drhc49f44e2006-10-26 18:15:42 +0000602** If a field contains any character identified by a 1 in the following
603** array, then the string must be quoted for CSV.
604*/
605static const char needCsvQuote[] = {
606 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
607 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
608 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
613 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
622};
623
624/*
drh8e64d1c2004-10-07 00:32:39 +0000625** Output a single term of CSV. Actually, p->separator is used for
626** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000627** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000628*/
629static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000630 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000631 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000632 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000633 }else{
drhc49f44e2006-10-26 18:15:42 +0000634 int i;
drh4f21c4a2008-12-10 22:15:00 +0000635 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000636 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000637 if( needCsvQuote[((unsigned char*)z)[i]]
638 || (z[i]==p->separator[0] &&
639 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000640 i = 0;
641 break;
642 }
643 }
644 if( i==0 ){
645 putc('"', out);
646 for(i=0; z[i]; i++){
647 if( z[i]=='"' ) putc('"', out);
648 putc(z[i], out);
649 }
650 putc('"', out);
651 }else{
652 fprintf(out, "%s", z);
653 }
drh8e64d1c2004-10-07 00:32:39 +0000654 }
655 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000656 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000657 }
658}
659
danielk19774af00c62005-01-23 23:43:21 +0000660#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000661/*
drh4c504392000-10-16 22:06:40 +0000662** This routine runs when the user presses Ctrl-C
663*/
664static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000665 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000666 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000667 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000668}
danielk19774af00c62005-01-23 23:43:21 +0000669#endif
drh4c504392000-10-16 22:06:40 +0000670
671/*
shane626a6e42009-10-22 17:30:15 +0000672** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000673** invokes for each row of a query result.
674*/
shane626a6e42009-10-22 17:30:15 +0000675static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000676 int i;
677 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000678
drh75897232000-05-29 14:26:00 +0000679 switch( p->mode ){
680 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000681 int w = 5;
drh6a535342001-10-19 16:44:56 +0000682 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000683 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000684 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000685 if( len>w ) w = len;
686 }
drh75897232000-05-29 14:26:00 +0000687 if( p->cnt++>0 ) fprintf(p->out,"\n");
688 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000689 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000690 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000691 }
692 break;
693 }
danielk19770d78bae2008-01-03 07:09:48 +0000694 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000695 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000696 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000697 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000698 int w, n;
699 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000700 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000701 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000702 w = 0;
drh75897232000-05-29 14:26:00 +0000703 }
drh078b1fd2012-09-21 13:40:02 +0000704 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000705 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000706 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000707 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000708 if( w<n ) w = n;
709 }
710 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000711 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000712 }
713 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000714 if( w<0 ){
715 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
716 }else{
717 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
718 }
drha0c66f52000-07-29 13:20:21 +0000719 }
720 }
721 if( p->showHeader ){
722 for(i=0; i<nArg; i++){
723 int w;
724 if( i<ArraySize(p->actualWidth) ){
725 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000726 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000727 }else{
728 w = 10;
729 }
730 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
731 "----------------------------------------------------------",
732 i==nArg-1 ? "\n": " ");
733 }
drh75897232000-05-29 14:26:00 +0000734 }
735 }
drh6a535342001-10-19 16:44:56 +0000736 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000737 for(i=0; i<nArg; i++){
738 int w;
drha0c66f52000-07-29 13:20:21 +0000739 if( i<ArraySize(p->actualWidth) ){
740 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000741 }else{
742 w = 10;
743 }
drhea678832008-12-10 19:26:22 +0000744 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000745 strlen30(azArg[i])>w ){
746 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000747 }
drh078b1fd2012-09-21 13:40:02 +0000748 if( w<0 ){
749 fprintf(p->out,"%*.*s%s",-w,-w,
750 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
751 }else{
752 fprintf(p->out,"%-*.*s%s",w,w,
753 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
754 }
drh75897232000-05-29 14:26:00 +0000755 }
756 break;
757 }
drhe3710332000-09-29 13:30:53 +0000758 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000759 case MODE_List: {
760 if( p->cnt++==0 && p->showHeader ){
761 for(i=0; i<nArg; i++){
762 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
763 }
764 }
drh6a535342001-10-19 16:44:56 +0000765 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000766 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000767 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000768 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000769 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000770 if( i<nArg-1 ){
771 fprintf(p->out, "%s", p->separator);
772 }else if( p->mode==MODE_Semi ){
773 fprintf(p->out, ";\n");
774 }else{
775 fprintf(p->out, "\n");
776 }
drh75897232000-05-29 14:26:00 +0000777 }
778 break;
779 }
drh1e5d0e92000-05-31 23:33:17 +0000780 case MODE_Html: {
781 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000782 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000783 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000784 fprintf(p->out,"<TH>");
785 output_html_string(p->out, azCol[i]);
786 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000787 }
mihailim57c591a2008-06-23 21:26:05 +0000788 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000789 }
drh6a535342001-10-19 16:44:56 +0000790 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000791 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000792 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000793 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000794 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000795 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000796 }
mihailim57c591a2008-06-23 21:26:05 +0000797 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000798 break;
799 }
drhfeac5f82004-08-01 00:10:45 +0000800 case MODE_Tcl: {
801 if( p->cnt++==0 && p->showHeader ){
802 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000803 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin585dcb22012-12-04 00:23:43 +0000804 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000805 }
806 fprintf(p->out,"\n");
807 }
808 if( azArg==0 ) break;
809 for(i=0; i<nArg; i++){
810 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mistachkin585dcb22012-12-04 00:23:43 +0000811 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000812 }
813 fprintf(p->out,"\n");
814 break;
815 }
drh8e64d1c2004-10-07 00:32:39 +0000816 case MODE_Csv: {
817 if( p->cnt++==0 && p->showHeader ){
818 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000819 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000820 }
821 fprintf(p->out,"\n");
822 }
823 if( azArg==0 ) break;
824 for(i=0; i<nArg; i++){
825 output_csv(p, azArg[i], i<nArg-1);
826 }
827 fprintf(p->out,"\n");
828 break;
829 }
drh28bd4bc2000-06-15 15:57:22 +0000830 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000831 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000832 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000833 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000834 for(i=0; i<nArg; i++){
835 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000836 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000837 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000838 }else if( aiType && aiType[i]==SQLITE_TEXT ){
839 if( zSep[0] ) fprintf(p->out,"%s",zSep);
840 output_quoted_string(p->out, azArg[i]);
841 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
842 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000843 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
844 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
845 int nBlob = sqlite3_column_bytes(p->pStmt, i);
846 if( zSep[0] ) fprintf(p->out,"%s",zSep);
847 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000848 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000849 fprintf(p->out,"%s%s",zSep, azArg[i]);
850 }else{
851 if( zSep[0] ) fprintf(p->out,"%s",zSep);
852 output_quoted_string(p->out, azArg[i]);
853 }
854 }
855 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000856 break;
drh28bd4bc2000-06-15 15:57:22 +0000857 }
persicom1d0b8722002-04-18 02:53:04 +0000858 }
drh75897232000-05-29 14:26:00 +0000859 return 0;
860}
861
862/*
shane626a6e42009-10-22 17:30:15 +0000863** This is the callback routine that the SQLite library
864** invokes for each row of a query result.
865*/
866static int callback(void *pArg, int nArg, char **azArg, char **azCol){
867 /* since we don't have type info, call the shell_callback with a NULL value */
868 return shell_callback(pArg, nArg, azArg, azCol, NULL);
869}
870
871/*
drh33048c02001-10-01 14:29:22 +0000872** Set the destination table field of the callback_data structure to
873** the name of the table given. Escape any quote characters in the
874** table name.
875*/
876static void set_table_name(struct callback_data *p, const char *zName){
877 int i, n;
878 int needQuote;
879 char *z;
880
881 if( p->zDestTable ){
882 free(p->zDestTable);
883 p->zDestTable = 0;
884 }
885 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000886 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000887 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000888 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000889 needQuote = 1;
890 if( zName[i]=='\'' ) n++;
891 }
892 }
893 if( needQuote ) n += 2;
894 z = p->zDestTable = malloc( n+1 );
895 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000896 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000897 exit(1);
898 }
899 n = 0;
900 if( needQuote ) z[n++] = '\'';
901 for(i=0; zName[i]; i++){
902 z[n++] = zName[i];
903 if( zName[i]=='\'' ) z[n++] = '\'';
904 }
905 if( needQuote ) z[n++] = '\'';
906 z[n] = 0;
907}
908
danielk19772a02e332004-06-05 08:04:36 +0000909/* zIn is either a pointer to a NULL-terminated string in memory obtained
910** from malloc(), or a NULL pointer. The string pointed to by zAppend is
911** added to zIn, and the result returned in memory obtained from malloc().
912** zIn, if it was not NULL, is freed.
913**
914** If the third argument, quote, is not '\0', then it is used as a
915** quote character for zAppend.
916*/
drhc28490c2006-10-26 14:25:58 +0000917static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000918 int len;
919 int i;
drh4f21c4a2008-12-10 22:15:00 +0000920 int nAppend = strlen30(zAppend);
921 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000922
923 len = nAppend+nIn+1;
924 if( quote ){
925 len += 2;
926 for(i=0; i<nAppend; i++){
927 if( zAppend[i]==quote ) len++;
928 }
929 }
930
931 zIn = (char *)realloc(zIn, len);
932 if( !zIn ){
933 return 0;
934 }
935
936 if( quote ){
937 char *zCsr = &zIn[nIn];
938 *zCsr++ = quote;
939 for(i=0; i<nAppend; i++){
940 *zCsr++ = zAppend[i];
941 if( zAppend[i]==quote ) *zCsr++ = quote;
942 }
943 *zCsr++ = quote;
944 *zCsr++ = '\0';
945 assert( (zCsr-zIn)==len );
946 }else{
947 memcpy(&zIn[nIn], zAppend, nAppend);
948 zIn[len-1] = '\0';
949 }
950
951 return zIn;
952}
953
drhdd3d4592004-08-30 01:54:05 +0000954
955/*
drhb21a8e42012-01-28 21:08:51 +0000956** Execute a query statement that will generate SQL output. Print
957** the result columns, comma-separated, on a line and then add a
958** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000959**
drhb21a8e42012-01-28 21:08:51 +0000960** If the number of columns is 1 and that column contains text "--"
961** then write the semicolon on a separate line. That way, if a
962** "--" comment occurs at the end of the statement, the comment
963** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000964*/
drh157e29a2009-05-21 15:15:00 +0000965static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000966 struct callback_data *p, /* Query context */
967 const char *zSelect, /* SELECT statement to extract content */
968 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000969){
drhdd3d4592004-08-30 01:54:05 +0000970 sqlite3_stmt *pSelect;
971 int rc;
drhb21a8e42012-01-28 21:08:51 +0000972 int nResult;
973 int i;
974 const char *z;
drh2f464a02011-10-13 00:41:49 +0000975 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000976 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000977 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +0000978 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000979 return rc;
980 }
981 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000982 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000983 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000984 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000985 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000986 zFirstRow = 0;
987 }
drhb21a8e42012-01-28 21:08:51 +0000988 z = (const char*)sqlite3_column_text(pSelect, 0);
989 fprintf(p->out, "%s", z);
990 for(i=1; i<nResult; i++){
991 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
992 }
993 if( z==0 ) z = "";
994 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
995 if( z[0] ){
996 fprintf(p->out, "\n;\n");
997 }else{
998 fprintf(p->out, ";\n");
999 }
drhdd3d4592004-08-30 01:54:05 +00001000 rc = sqlite3_step(pSelect);
1001 }
drh2f464a02011-10-13 00:41:49 +00001002 rc = sqlite3_finalize(pSelect);
1003 if( rc!=SQLITE_OK ){
1004 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001005 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001006 }
1007 return rc;
drhdd3d4592004-08-30 01:54:05 +00001008}
1009
shane626a6e42009-10-22 17:30:15 +00001010/*
1011** Allocate space and save off current error string.
1012*/
1013static char *save_err_msg(
1014 sqlite3 *db /* Database to query */
1015){
1016 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1017 char *zErrMsg = sqlite3_malloc(nErrMsg);
1018 if( zErrMsg ){
1019 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1020 }
1021 return zErrMsg;
1022}
1023
1024/*
shaneh642d8b82010-07-28 16:05:34 +00001025** Display memory stats.
1026*/
1027static int display_stats(
1028 sqlite3 *db, /* Database to query */
1029 struct callback_data *pArg, /* Pointer to struct callback_data */
1030 int bReset /* True to reset the stats */
1031){
1032 int iCur;
1033 int iHiwtr;
1034
1035 if( pArg && pArg->out ){
1036
1037 iHiwtr = iCur = -1;
1038 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001039 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001040 iHiwtr = iCur = -1;
1041 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001042 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001043/*
1044** Not currently used by the CLI.
1045** iHiwtr = iCur = -1;
1046** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1047** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1048*/
1049 iHiwtr = iCur = -1;
1050 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1051 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1052/*
1053** Not currently used by the CLI.
1054** iHiwtr = iCur = -1;
1055** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1056** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1057*/
1058 iHiwtr = iCur = -1;
1059 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1060 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1061 iHiwtr = iCur = -1;
1062 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1063 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1064 iHiwtr = iCur = -1;
1065 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1066 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1067 iHiwtr = iCur = -1;
1068 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1069 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1070#ifdef YYTRACKMAXSTACKDEPTH
1071 iHiwtr = iCur = -1;
1072 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1073 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1074#endif
1075 }
1076
1077 if( pArg && pArg->out && db ){
1078 iHiwtr = iCur = -1;
1079 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1080 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001081 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1082 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1083 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1084 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1085 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1086 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001087 iHiwtr = iCur = -1;
1088 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001089 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1090 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1091 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1092 iHiwtr = iCur = -1;
1093 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1094 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001095 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001096 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1097 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1098 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001099 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1100 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1101 iHiwtr = iCur = -1;
1102 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1103 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1104 }
1105
1106 if( pArg && pArg->out && db && pArg->pStmt ){
1107 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1108 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1109 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1110 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1111 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1112 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001113 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1114 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001115 }
1116
1117 return 0;
1118}
1119
1120/*
shane626a6e42009-10-22 17:30:15 +00001121** Execute a statement or set of statements. Print
1122** any result rows/columns depending on the current mode
1123** set via the supplied callback.
1124**
1125** This is very similar to SQLite's built-in sqlite3_exec()
1126** function except it takes a slightly different callback
1127** and callback data argument.
1128*/
1129static int shell_exec(
1130 sqlite3 *db, /* An open database */
1131 const char *zSql, /* SQL to be evaluated */
1132 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1133 /* (not the same as sqlite3_exec) */
1134 struct callback_data *pArg, /* Pointer to struct callback_data */
1135 char **pzErrMsg /* Error msg written here */
1136){
dan4564ced2010-01-05 04:59:56 +00001137 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1138 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001139 int rc2;
dan4564ced2010-01-05 04:59:56 +00001140 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001141
1142 if( pzErrMsg ){
1143 *pzErrMsg = NULL;
1144 }
1145
shaneb9fc17d2009-10-22 21:23:35 +00001146 while( zSql[0] && (SQLITE_OK == rc) ){
1147 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1148 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001149 if( pzErrMsg ){
1150 *pzErrMsg = save_err_msg(db);
1151 }
1152 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001153 if( !pStmt ){
1154 /* this happens for a comment or white-space */
1155 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001156 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001157 continue;
1158 }
shane626a6e42009-10-22 17:30:15 +00001159
shaneh642d8b82010-07-28 16:05:34 +00001160 /* save off the prepared statment handle and reset row count */
1161 if( pArg ){
1162 pArg->pStmt = pStmt;
1163 pArg->cnt = 0;
1164 }
1165
shanehb7977c52010-01-18 18:17:10 +00001166 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001167 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001168 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001169 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001170 }
shanehb7977c52010-01-18 18:17:10 +00001171
drh7e02e5e2011-12-06 19:44:51 +00001172 /* Output TESTCTRL_EXPLAIN text of requested */
1173 if( pArg && pArg->mode==MODE_Explain ){
1174 const char *zExplain = 0;
1175 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1176 if( zExplain && zExplain[0] ){
1177 fprintf(pArg->out, "%s", zExplain);
1178 }
1179 }
1180
shaneb9fc17d2009-10-22 21:23:35 +00001181 /* perform the first step. this will tell us if we
1182 ** have a result set or not and how wide it is.
1183 */
1184 rc = sqlite3_step(pStmt);
1185 /* if we have a result set... */
1186 if( SQLITE_ROW == rc ){
1187 /* if we have a callback... */
1188 if( xCallback ){
1189 /* allocate space for col name ptr, value ptr, and type */
1190 int nCol = sqlite3_column_count(pStmt);
1191 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1192 if( !pData ){
1193 rc = SQLITE_NOMEM;
1194 }else{
1195 char **azCols = (char **)pData; /* Names of result columns */
1196 char **azVals = &azCols[nCol]; /* Results */
1197 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001198 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001199 assert(sizeof(int) <= sizeof(char *));
1200 /* save off ptrs to column names */
1201 for(i=0; i<nCol; i++){
1202 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1203 }
shaneb9fc17d2009-10-22 21:23:35 +00001204 do{
1205 /* extract the data and data types */
1206 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001207 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001208 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001209 azVals[i] = "";
1210 }else{
1211 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1212 }
shaneb9fc17d2009-10-22 21:23:35 +00001213 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1214 rc = SQLITE_NOMEM;
1215 break; /* from for */
1216 }
1217 } /* end for */
1218
1219 /* if data and types extracted successfully... */
1220 if( SQLITE_ROW == rc ){
1221 /* call the supplied callback with the result row data */
1222 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1223 rc = SQLITE_ABORT;
1224 }else{
1225 rc = sqlite3_step(pStmt);
1226 }
1227 }
1228 } while( SQLITE_ROW == rc );
1229 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001230 }
1231 }else{
1232 do{
1233 rc = sqlite3_step(pStmt);
1234 } while( rc == SQLITE_ROW );
1235 }
1236 }
1237
shaneh642d8b82010-07-28 16:05:34 +00001238 /* print usage stats if stats on */
1239 if( pArg && pArg->statsOn ){
1240 display_stats(db, pArg, 0);
1241 }
1242
dan4564ced2010-01-05 04:59:56 +00001243 /* Finalize the statement just executed. If this fails, save a
1244 ** copy of the error message. Otherwise, set zSql to point to the
1245 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001246 rc2 = sqlite3_finalize(pStmt);
1247 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001248 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001249 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001250 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001251 }else if( pzErrMsg ){
1252 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001253 }
shaneh642d8b82010-07-28 16:05:34 +00001254
1255 /* clear saved stmt handle */
1256 if( pArg ){
1257 pArg->pStmt = NULL;
1258 }
shane626a6e42009-10-22 17:30:15 +00001259 }
shaneb9fc17d2009-10-22 21:23:35 +00001260 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001261
1262 return rc;
1263}
1264
drhdd3d4592004-08-30 01:54:05 +00001265
drh33048c02001-10-01 14:29:22 +00001266/*
drh4c653a02000-06-07 01:27:47 +00001267** This is a different callback routine used for dumping the database.
1268** Each row received by this callback consists of a table name,
1269** the table type ("index" or "table") and SQL to create the table.
1270** This routine should print text sufficient to recreate the table.
1271*/
1272static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001273 int rc;
1274 const char *zTable;
1275 const char *zType;
1276 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001277 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001278 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001279
drh902b9ee2008-12-05 17:17:07 +00001280 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001281 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001282 zTable = azArg[0];
1283 zType = azArg[1];
1284 zSql = azArg[2];
1285
drh00b950d2005-09-11 02:03:03 +00001286 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001287 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001288 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001289 fprintf(p->out, "ANALYZE sqlite_master;\n");
1290 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1291 return 0;
drh45e29d82006-11-20 16:21:10 +00001292 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1293 char *zIns;
1294 if( !p->writableSchema ){
1295 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1296 p->writableSchema = 1;
1297 }
1298 zIns = sqlite3_mprintf(
1299 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1300 "VALUES('table','%q','%q',0,'%q');",
1301 zTable, zTable, zSql);
1302 fprintf(p->out, "%s\n", zIns);
1303 sqlite3_free(zIns);
1304 return 0;
drh00b950d2005-09-11 02:03:03 +00001305 }else{
1306 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001307 }
danielk19772a02e332004-06-05 08:04:36 +00001308
1309 if( strcmp(zType, "table")==0 ){
1310 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001311 char *zSelect = 0;
1312 char *zTableInfo = 0;
1313 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001314 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001315
1316 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1317 zTableInfo = appendText(zTableInfo, zTable, '"');
1318 zTableInfo = appendText(zTableInfo, ");", 0);
1319
1320 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001321 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001322 if( rc!=SQLITE_OK || !pTableInfo ){
1323 return 1;
1324 }
1325
1326 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001327 /* Always quote the table name, even if it appears to be pure ascii,
1328 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1329 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001330 if( zTmp ){
1331 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001332 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001333 }
1334 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1335 rc = sqlite3_step(pTableInfo);
1336 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001337 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001338 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001339 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001340 rc = sqlite3_step(pTableInfo);
1341 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001342 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001343 }else{
1344 zSelect = appendText(zSelect, ") ", 0);
1345 }
drh157e29a2009-05-21 15:15:00 +00001346 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001347 }
1348 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001349 if( rc!=SQLITE_OK || nRow==0 ){
1350 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001351 return 1;
1352 }
1353 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1354 zSelect = appendText(zSelect, zTable, '"');
1355
drh2f464a02011-10-13 00:41:49 +00001356 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001357 if( rc==SQLITE_CORRUPT ){
1358 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001359 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001360 }
drh85e72432012-04-11 11:38:53 +00001361 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001362 }
drh4c653a02000-06-07 01:27:47 +00001363 return 0;
1364}
1365
1366/*
drh45e29d82006-11-20 16:21:10 +00001367** Run zQuery. Use dump_callback() as the callback routine so that
1368** the contents of the query are output as SQL statements.
1369**
drhdd3d4592004-08-30 01:54:05 +00001370** If we get a SQLITE_CORRUPT error, rerun the query after appending
1371** "ORDER BY rowid DESC" to the end.
1372*/
1373static int run_schema_dump_query(
1374 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001375 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001376){
1377 int rc;
drh2f464a02011-10-13 00:41:49 +00001378 char *zErr = 0;
1379 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001380 if( rc==SQLITE_CORRUPT ){
1381 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001382 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001383 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1384 if( zErr ){
1385 fprintf(p->out, "/****** %s ******/\n", zErr);
1386 sqlite3_free(zErr);
1387 zErr = 0;
1388 }
drhdd3d4592004-08-30 01:54:05 +00001389 zQ2 = malloc( len+100 );
1390 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001391 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001392 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1393 if( rc ){
1394 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1395 }else{
1396 rc = SQLITE_CORRUPT;
1397 }
1398 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001399 free(zQ2);
1400 }
1401 return rc;
1402}
1403
1404/*
drh75897232000-05-29 14:26:00 +00001405** Text of a help message
1406*/
persicom1d0b8722002-04-18 02:53:04 +00001407static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001408 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001409 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001410 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001411 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001412 " If TABLE specified, only dump tables matching\n"
1413 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001414 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001415 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001416 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1417 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001418 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001419 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001420 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001421 ".indices ?TABLE? Show names of all indices\n"
1422 " If TABLE specified, only show indices for tables\n"
1423 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001424#ifdef SQLITE_ENABLE_IOTRACE
1425 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1426#endif
drh70df4fe2006-06-13 15:12:21 +00001427#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001428 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001429#endif
drh127f9d72010-02-23 01:47:00 +00001430 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001431 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001432 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001433 " column Left-aligned columns. (See .width)\n"
1434 " html HTML <table> code\n"
1435 " insert SQL insert statements for TABLE\n"
1436 " line One value per line\n"
1437 " list Values delimited by .separator string\n"
1438 " tabs Tab-separated values\n"
1439 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001440 ".nullvalue STRING Use STRING in place of NULL values\n"
drh05782482013-10-24 15:20:20 +00001441 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drh75897232000-05-29 14:26:00 +00001442 ".output FILENAME Send output to FILENAME\n"
1443 ".output stdout Send output to the screen\n"
drh078b1fd2012-09-21 13:40:02 +00001444 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001445 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001446 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001447 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001448 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001449 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001450 " If TABLE specified, only show tables matching\n"
1451 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001452 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001453 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001454 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001455 ".tables ?TABLE? List names of tables\n"
1456 " If TABLE specified, only list tables matching\n"
1457 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001458 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001459 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001460 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001461 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001462;
1463
shaneb320ccd2009-10-21 03:42:58 +00001464static char zTimerHelp[] =
1465 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1466;
1467
drhdaffd0e2001-04-11 14:28:42 +00001468/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001469static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001470
drh75897232000-05-29 14:26:00 +00001471/*
drh44c2eb12003-04-30 11:38:26 +00001472** Make sure the database is open. If it is not, then open it. If
1473** the database fails to open, print an error message and exit.
1474*/
drh05782482013-10-24 15:20:20 +00001475static void open_db(struct callback_data *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001476 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001477 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001478 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001479 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001480 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1481 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1482 shellstaticFunc, 0, 0);
1483 }
1484 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001485 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001486 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001487 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001488 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001489 }
drhc2e87a32006-06-27 15:16:14 +00001490#ifndef SQLITE_OMIT_LOAD_EXTENSION
1491 sqlite3_enable_load_extension(p->db, 1);
1492#endif
drh44c2eb12003-04-30 11:38:26 +00001493 }
1494}
1495
1496/*
drhfeac5f82004-08-01 00:10:45 +00001497** Do C-language style dequoting.
1498**
1499** \t -> tab
1500** \n -> newline
1501** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001502** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001503** \NNN -> ascii character NNN in octal
1504** \\ -> backslash
1505*/
1506static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001507 int i, j;
1508 char c;
drhfeac5f82004-08-01 00:10:45 +00001509 for(i=j=0; (c = z[i])!=0; i++, j++){
1510 if( c=='\\' ){
1511 c = z[++i];
1512 if( c=='n' ){
1513 c = '\n';
1514 }else if( c=='t' ){
1515 c = '\t';
1516 }else if( c=='r' ){
1517 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001518 }else if( c=='\\' ){
1519 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001520 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001521 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001522 if( z[i+1]>='0' && z[i+1]<='7' ){
1523 i++;
1524 c = (c<<3) + z[i] - '0';
1525 if( z[i+1]>='0' && z[i+1]<='7' ){
1526 i++;
1527 c = (c<<3) + z[i] - '0';
1528 }
1529 }
1530 }
1531 }
1532 z[j] = c;
1533 }
1534 z[j] = 0;
1535}
1536
1537/*
drh348d19c2013-06-03 12:47:43 +00001538** Return the value of a hexadecimal digit. Return -1 if the input
1539** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001540*/
drh348d19c2013-06-03 12:47:43 +00001541static int hexDigitValue(char c){
1542 if( c>='0' && c<='9' ) return c - '0';
1543 if( c>='a' && c<='f' ) return c - 'a' + 10;
1544 if( c>='A' && c<='F' ) return c - 'A' + 10;
1545 return -1;
drhc28490c2006-10-26 14:25:58 +00001546}
1547
1548/*
drh7d9f3942013-04-03 01:26:54 +00001549** Interpret zArg as an integer value, possibly with suffixes.
1550*/
1551static sqlite3_int64 integerValue(const char *zArg){
1552 sqlite3_int64 v = 0;
1553 static const struct { char *zSuffix; int iMult; } aMult[] = {
1554 { "KiB", 1024 },
1555 { "MiB", 1024*1024 },
1556 { "GiB", 1024*1024*1024 },
1557 { "KB", 1000 },
1558 { "MB", 1000000 },
1559 { "GB", 1000000000 },
1560 { "K", 1000 },
1561 { "M", 1000000 },
1562 { "G", 1000000000 },
1563 };
1564 int i;
1565 int isNeg = 0;
1566 if( zArg[0]=='-' ){
1567 isNeg = 1;
1568 zArg++;
1569 }else if( zArg[0]=='+' ){
1570 zArg++;
1571 }
drh348d19c2013-06-03 12:47:43 +00001572 if( zArg[0]=='0' && zArg[1]=='x' ){
1573 int x;
1574 zArg += 2;
1575 while( (x = hexDigitValue(zArg[0]))>=0 ){
1576 v = (v<<4) + x;
1577 zArg++;
1578 }
1579 }else{
1580 while( IsDigit(zArg[0]) ){
1581 v = v*10 + zArg[0] - '0';
1582 zArg++;
1583 }
drh7d9f3942013-04-03 01:26:54 +00001584 }
drhc2bed0a2013-05-24 11:57:50 +00001585 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001586 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1587 v *= aMult[i].iMult;
1588 break;
1589 }
1590 }
1591 return isNeg? -v : v;
1592}
1593
1594/*
drh348d19c2013-06-03 12:47:43 +00001595** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1596** for TRUE and FALSE. Return the integer value if appropriate.
1597*/
1598static int booleanValue(char *zArg){
1599 int i;
1600 if( zArg[0]=='0' && zArg[1]=='x' ){
1601 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1602 }else{
1603 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1604 }
1605 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1606 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1607 return 1;
1608 }
1609 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1610 return 0;
1611 }
1612 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1613 zArg);
1614 return 0;
1615}
1616
1617/*
drh42f64e52012-04-04 16:56:23 +00001618** Close an output file, assuming it is not stderr or stdout
1619*/
1620static void output_file_close(FILE *f){
1621 if( f && f!=stdout && f!=stderr ) fclose(f);
1622}
1623
1624/*
1625** Try to open an output file. The names "stdout" and "stderr" are
1626** recognized and do the right thing. NULL is returned if the output
1627** filename is "off".
1628*/
1629static FILE *output_file_open(const char *zFile){
1630 FILE *f;
1631 if( strcmp(zFile,"stdout")==0 ){
1632 f = stdout;
1633 }else if( strcmp(zFile, "stderr")==0 ){
1634 f = stderr;
1635 }else if( strcmp(zFile, "off")==0 ){
1636 f = 0;
1637 }else{
1638 f = fopen(zFile, "wb");
1639 if( f==0 ){
1640 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1641 }
1642 }
1643 return f;
1644}
1645
1646/*
1647** A routine for handling output from sqlite3_trace().
1648*/
1649static void sql_trace_callback(void *pArg, const char *z){
1650 FILE *f = (FILE*)pArg;
1651 if( f ) fprintf(f, "%s\n", z);
1652}
1653
1654/*
drhd8621b92012-04-17 09:09:33 +00001655** A no-op routine that runs with the ".breakpoint" doc-command. This is
1656** a useful spot to set a debugger breakpoint.
1657*/
1658static void test_breakpoint(void){
1659 static int nCall = 0;
1660 nCall++;
1661}
1662
1663/*
drhdb95f682013-06-26 22:46:00 +00001664** An object used to read a CSV file
1665*/
1666typedef struct CSVReader CSVReader;
1667struct CSVReader {
1668 const char *zFile; /* Name of the input file */
1669 FILE *in; /* Read the CSV text from this input stream */
1670 char *z; /* Accumulated text for a field */
1671 int n; /* Number of bytes in z */
1672 int nAlloc; /* Space allocated for z[] */
1673 int nLine; /* Current line number */
1674 int cTerm; /* Character that terminated the most recent field */
1675 int cSeparator; /* The separator character. (Usually ",") */
1676};
1677
1678/* Append a single byte to z[] */
1679static void csv_append_char(CSVReader *p, int c){
1680 if( p->n+1>=p->nAlloc ){
1681 p->nAlloc += p->nAlloc + 100;
1682 p->z = sqlite3_realloc(p->z, p->nAlloc);
1683 if( p->z==0 ){
1684 fprintf(stderr, "out of memory\n");
1685 exit(1);
1686 }
1687 }
1688 p->z[p->n++] = (char)c;
1689}
1690
1691/* Read a single field of CSV text. Compatible with rfc4180 and extended
1692** with the option of having a separator other than ",".
1693**
1694** + Input comes from p->in.
1695** + Store results in p->z of length p->n. Space to hold p->z comes
1696** from sqlite3_malloc().
1697** + Use p->cSep as the separator. The default is ",".
1698** + Keep track of the line number in p->nLine.
1699** + Store the character that terminates the field in p->cTerm. Store
1700** EOF on end-of-file.
1701** + Report syntax errors on stderr
1702*/
1703static char *csv_read_one_field(CSVReader *p){
1704 int c, pc;
1705 int cSep = p->cSeparator;
1706 p->n = 0;
1707 c = fgetc(p->in);
1708 if( c==EOF || seenInterrupt ){
1709 p->cTerm = EOF;
1710 return 0;
1711 }
1712 if( c=='"' ){
1713 int startLine = p->nLine;
1714 int cQuote = c;
1715 pc = 0;
1716 while( 1 ){
1717 c = fgetc(p->in);
1718 if( c=='\n' ) p->nLine++;
1719 if( c==cQuote ){
1720 if( pc==cQuote ){
1721 pc = 0;
1722 continue;
1723 }
1724 }
1725 if( (c==cSep && pc==cQuote)
1726 || (c=='\n' && pc==cQuote)
drh868ccf22013-08-28 13:33:40 +00001727 || (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote)
drhdb95f682013-06-26 22:46:00 +00001728 || (c==EOF && pc==cQuote)
1729 ){
1730 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00001731 p->cTerm = c;
1732 break;
1733 }
1734 if( pc==cQuote && c!='\r' ){
1735 fprintf(stderr, "%s:%d: unescaped %c character\n",
1736 p->zFile, p->nLine, cQuote);
1737 }
1738 if( c==EOF ){
1739 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
1740 p->zFile, startLine, cQuote);
drhdb95f682013-06-26 22:46:00 +00001741 p->cTerm = EOF;
1742 break;
1743 }
1744 csv_append_char(p, c);
1745 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00001746 }
drhdb95f682013-06-26 22:46:00 +00001747 }else{
drhd0a64dc2013-06-30 20:24:26 +00001748 while( c!=EOF && c!=cSep && c!='\n' ){
drhdb95f682013-06-26 22:46:00 +00001749 csv_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00001750 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00001751 }
1752 if( c=='\n' ){
1753 p->nLine++;
1754 if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
1755 }
drhdb95f682013-06-26 22:46:00 +00001756 p->cTerm = c;
1757 }
drh8dd675e2013-07-12 21:09:24 +00001758 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00001759 return p->z;
1760}
1761
1762/*
drh75897232000-05-29 14:26:00 +00001763** If an input line begins with "." then invoke this routine to
1764** process that line.
drh67505e72002-04-19 12:34:06 +00001765**
drh47ad6842006-11-08 12:25:42 +00001766** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001767*/
drh44c2eb12003-04-30 11:38:26 +00001768static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001769 int i = 1;
1770 int nArg = 0;
1771 int n, c;
drh67505e72002-04-19 12:34:06 +00001772 int rc = 0;
drh75897232000-05-29 14:26:00 +00001773 char *azArg[50];
1774
1775 /* Parse the input line into tokens.
1776 */
1777 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001778 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001779 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001780 if( zLine[i]=='\'' || zLine[i]=='"' ){
1781 int delim = zLine[i++];
1782 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00001783 while( zLine[i] && zLine[i]!=delim ){
1784 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
1785 i++;
1786 }
drh75897232000-05-29 14:26:00 +00001787 if( zLine[i]==delim ){
1788 zLine[i++] = 0;
1789 }
drhfeac5f82004-08-01 00:10:45 +00001790 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001791 }else{
1792 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001793 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001794 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001795 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001796 }
1797 }
1798
1799 /* Process the input line.
1800 */
shane9bd1b442009-10-23 01:27:39 +00001801 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001802 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001803 c = azArg[0][0];
drhbc46f022013-01-23 18:53:23 +00001804 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1805 const char *zDestFile = 0;
1806 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00001807 sqlite3 *pDest;
1808 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00001809 int j;
1810 for(j=1; j<nArg; j++){
1811 const char *z = azArg[j];
1812 if( z[0]=='-' ){
1813 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00001814 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00001815 {
1816 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1817 return 1;
1818 }
1819 }else if( zDestFile==0 ){
1820 zDestFile = azArg[j];
1821 }else if( zDb==0 ){
1822 zDb = zDestFile;
1823 zDestFile = azArg[j];
1824 }else{
1825 fprintf(stderr, "too many arguments to .backup\n");
1826 return 1;
1827 }
drh9ff849f2009-02-04 20:55:57 +00001828 }
drhbc46f022013-01-23 18:53:23 +00001829 if( zDestFile==0 ){
1830 fprintf(stderr, "missing FILENAME argument on .backup\n");
1831 return 1;
1832 }
1833 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00001834 rc = sqlite3_open(zDestFile, &pDest);
1835 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001836 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001837 sqlite3_close(pDest);
1838 return 1;
1839 }
drh05782482013-10-24 15:20:20 +00001840 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00001841 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1842 if( pBackup==0 ){
1843 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1844 sqlite3_close(pDest);
1845 return 1;
1846 }
1847 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1848 sqlite3_backup_finish(pBackup);
1849 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001850 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001851 }else{
1852 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001853 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001854 }
1855 sqlite3_close(pDest);
1856 }else
1857
shanehe2aa9d72009-11-06 17:20:17 +00001858 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001859 bail_on_error = booleanValue(azArg[1]);
1860 }else
1861
drhd8621b92012-04-17 09:09:33 +00001862 /* The undocumented ".breakpoint" command causes a call to the no-op
1863 ** routine named test_breakpoint().
1864 */
1865 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1866 test_breakpoint();
1867 }else
1868
shanehe2aa9d72009-11-06 17:20:17 +00001869 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001870 struct callback_data data;
1871 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00001872 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00001873 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001874 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001875 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001876 data.colWidth[0] = 3;
1877 data.colWidth[1] = 15;
1878 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001879 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001880 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001881 if( zErrMsg ){
1882 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001883 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001884 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001885 }
1886 }else
1887
shanehe2aa9d72009-11-06 17:20:17 +00001888 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh05782482013-10-24 15:20:20 +00001889 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00001890 /* When playing back a "dump", the content might appear in an order
1891 ** which causes immediate foreign key constraints to be violated.
1892 ** So disable foreign-key constraint enforcement to prevent problems. */
1893 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001894 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001895 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001896 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001897 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001898 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001899 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001900 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001901 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001902 );
1903 run_schema_dump_query(p,
1904 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001905 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001906 );
drh2f464a02011-10-13 00:41:49 +00001907 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001908 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001909 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001910 );
drh4c653a02000-06-07 01:27:47 +00001911 }else{
1912 int i;
drhdd3d4592004-08-30 01:54:05 +00001913 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001914 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001915 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001916 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001917 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001918 " AND sql NOT NULL");
1919 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001920 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001921 "WHERE sql NOT NULL"
1922 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001923 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001924 );
danielk1977bc6ada42004-06-30 08:20:16 +00001925 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001926 }
1927 }
drh45e29d82006-11-20 16:21:10 +00001928 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001929 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001930 p->writableSchema = 0;
1931 }
drh56197952011-10-13 16:30:13 +00001932 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1933 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001934 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001935 }else
drh75897232000-05-29 14:26:00 +00001936
shanehe2aa9d72009-11-06 17:20:17 +00001937 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001938 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001939 }else
1940
drhd3ac7d92013-01-25 18:33:43 +00001941 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00001942 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00001943 rc = 2;
drh75897232000-05-29 14:26:00 +00001944 }else
1945
shanehe2aa9d72009-11-06 17:20:17 +00001946 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001947 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001948 if(val == 1) {
1949 if(!p->explainPrev.valid) {
1950 p->explainPrev.valid = 1;
1951 p->explainPrev.mode = p->mode;
1952 p->explainPrev.showHeader = p->showHeader;
1953 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1954 }
1955 /* We could put this code under the !p->explainValid
1956 ** condition so that it does not execute if we are already in
1957 ** explain mode. However, always executing it allows us an easy
1958 ** was to reset to explain mode in case the user previously
1959 ** did an .explain followed by a .width, .mode or .header
1960 ** command.
1961 */
danielk19770d78bae2008-01-03 07:09:48 +00001962 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001963 p->showHeader = 1;
1964 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001965 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001966 p->colWidth[1] = 13; /* opcode */
1967 p->colWidth[2] = 4; /* P1 */
1968 p->colWidth[3] = 4; /* P2 */
1969 p->colWidth[4] = 4; /* P3 */
1970 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001971 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001972 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001973 }else if (p->explainPrev.valid) {
1974 p->explainPrev.valid = 0;
1975 p->mode = p->explainPrev.mode;
1976 p->showHeader = p->explainPrev.showHeader;
1977 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1978 }
drh75897232000-05-29 14:26:00 +00001979 }else
1980
drhc28490c2006-10-26 14:25:58 +00001981 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001982 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001983 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001984 }else
1985
1986 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001987 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001988 if( HAS_TIMER ){
1989 fprintf(stderr,"%s",zTimerHelp);
1990 }
drh75897232000-05-29 14:26:00 +00001991 }else
1992
shanehe2aa9d72009-11-06 17:20:17 +00001993 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001994 char *zTable = azArg[2]; /* Insert data into this table */
drh5bde8162013-06-27 14:07:53 +00001995 char *zFile = azArg[1]; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00001996 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001997 int nCol; /* Number of columns in the table */
1998 int nByte; /* Number of bytes in an SQL string */
1999 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002000 int needCommit; /* True to COMMIT or ROLLBACK at end */
drhfeac5f82004-08-01 00:10:45 +00002001 int nSep; /* Number of bytes in p->separator[] */
2002 char *zSql; /* An SQL statement */
drhdb95f682013-06-26 22:46:00 +00002003 CSVReader sCsv; /* Reader context */
drh5bde8162013-06-27 14:07:53 +00002004 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002005
drhdb95f682013-06-26 22:46:00 +00002006 seenInterrupt = 0;
2007 memset(&sCsv, 0, sizeof(sCsv));
drh05782482013-10-24 15:20:20 +00002008 open_db(p, 0);
drh4f21c4a2008-12-10 22:15:00 +00002009 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002010 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00002011 fprintf(stderr, "Error: non-null separator required for import\n");
2012 return 1;
drhfeac5f82004-08-01 00:10:45 +00002013 }
drhdb95f682013-06-26 22:46:00 +00002014 if( nSep>1 ){
2015 fprintf(stderr, "Error: multi-character separators not allowed"
2016 " for import\n");
2017 return 1;
2018 }
drh5bde8162013-06-27 14:07:53 +00002019 sCsv.zFile = zFile;
2020 sCsv.nLine = 1;
2021 if( sCsv.zFile[0]=='|' ){
2022 sCsv.in = popen(sCsv.zFile+1, "r");
2023 sCsv.zFile = "<pipe>";
2024 xCloser = pclose;
2025 }else{
2026 sCsv.in = fopen(sCsv.zFile, "rb");
2027 xCloser = fclose;
2028 }
drhdb95f682013-06-26 22:46:00 +00002029 if( sCsv.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002030 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002031 return 1;
2032 }
2033 sCsv.cSeparator = p->separator[0];
drh7b075e32011-09-28 01:10:00 +00002034 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002035 if( zSql==0 ){
2036 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002037 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002038 return 1;
2039 }
drh4f21c4a2008-12-10 22:15:00 +00002040 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002041 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002042 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2043 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2044 char cSep = '(';
2045 while( csv_read_one_field(&sCsv) ){
2046 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
2047 cSep = ',';
2048 if( sCsv.cTerm!=sCsv.cSeparator ) break;
2049 }
drh5bde8162013-06-27 14:07:53 +00002050 if( cSep=='(' ){
2051 sqlite3_free(zCreate);
2052 sqlite3_free(sCsv.z);
2053 xCloser(sCsv.in);
2054 fprintf(stderr,"%s: empty file\n", sCsv.zFile);
2055 return 1;
2056 }
drhdb95f682013-06-26 22:46:00 +00002057 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2058 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2059 sqlite3_free(zCreate);
2060 if( rc ){
2061 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2062 sqlite3_errmsg(db));
2063 sqlite3_free(sCsv.z);
drh5bde8162013-06-27 14:07:53 +00002064 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002065 return 1;
2066 }
2067 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
2068 }
drhfeac5f82004-08-01 00:10:45 +00002069 sqlite3_free(zSql);
2070 if( rc ){
shane916f9612009-10-23 00:37:15 +00002071 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002072 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
drh5bde8162013-06-27 14:07:53 +00002073 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002074 return 1;
drhfeac5f82004-08-01 00:10:45 +00002075 }
shane916f9612009-10-23 00:37:15 +00002076 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002077 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002078 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002079 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002080 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002081 if( zSql==0 ){
2082 fprintf(stderr, "Error: out of memory\n");
drh5bde8162013-06-27 14:07:53 +00002083 xCloser(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002084 return 1;
2085 }
drhdb95f682013-06-26 22:46:00 +00002086 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002087 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002088 for(i=1; i<nCol; i++){
2089 zSql[j++] = ',';
2090 zSql[j++] = '?';
2091 }
2092 zSql[j++] = ')';
2093 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002094 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002095 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002096 if( rc ){
2097 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002098 if (pStmt) sqlite3_finalize(pStmt);
drh5bde8162013-06-27 14:07:53 +00002099 xCloser(sCsv.in);
drh47ad6842006-11-08 12:25:42 +00002100 return 1;
drhfeac5f82004-08-01 00:10:45 +00002101 }
drh2d463112013-08-06 14:36:36 +00002102 needCommit = sqlite3_get_autocommit(db);
2103 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00002104 do{
2105 int startLine = sCsv.nLine;
drhfeac5f82004-08-01 00:10:45 +00002106 for(i=0; i<nCol; i++){
drhdb95f682013-06-26 22:46:00 +00002107 char *z = csv_read_one_field(&sCsv);
2108 if( z==0 && i==0 ) break;
2109 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
2110 if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
2111 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2112 "filling the rest with NULL\n",
2113 sCsv.zFile, startLine, nCol, i+1);
2114 i++;
2115 while( i<nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002116 }
drhfeac5f82004-08-01 00:10:45 +00002117 }
drhdb95f682013-06-26 22:46:00 +00002118 if( sCsv.cTerm==sCsv.cSeparator ){
2119 do{
2120 csv_read_one_field(&sCsv);
2121 i++;
2122 }while( sCsv.cTerm==sCsv.cSeparator );
2123 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2124 "extras ignored\n",
2125 sCsv.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002126 }
drhdb95f682013-06-26 22:46:00 +00002127 if( i>=nCol ){
2128 sqlite3_step(pStmt);
2129 rc = sqlite3_reset(pStmt);
2130 if( rc!=SQLITE_OK ){
2131 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
2132 sqlite3_errmsg(db));
2133 }
2134 }
2135 }while( sCsv.cTerm!=EOF );
2136
drh5bde8162013-06-27 14:07:53 +00002137 xCloser(sCsv.in);
drhdb95f682013-06-26 22:46:00 +00002138 sqlite3_free(sCsv.z);
drhfeac5f82004-08-01 00:10:45 +00002139 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00002140 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002141 }else
2142
shanehe2aa9d72009-11-06 17:20:17 +00002143 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002144 struct callback_data data;
2145 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002146 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00002147 memcpy(&data, p, sizeof(data));
2148 data.showHeader = 0;
2149 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002150 if( nArg==1 ){
2151 rc = sqlite3_exec(p->db,
2152 "SELECT name FROM sqlite_master "
2153 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2154 "UNION ALL "
2155 "SELECT name FROM sqlite_temp_master "
2156 "WHERE type='index' "
2157 "ORDER BY 1",
2158 callback, &data, &zErrMsg
2159 );
2160 }else{
2161 zShellStatic = azArg[1];
2162 rc = sqlite3_exec(p->db,
2163 "SELECT name FROM sqlite_master "
2164 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2165 "UNION ALL "
2166 "SELECT name FROM sqlite_temp_master "
2167 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2168 "ORDER BY 1",
2169 callback, &data, &zErrMsg
2170 );
2171 zShellStatic = 0;
2172 }
drh75897232000-05-29 14:26:00 +00002173 if( zErrMsg ){
2174 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002175 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002176 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002177 }else if( rc != SQLITE_OK ){
2178 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2179 rc = 1;
drh75897232000-05-29 14:26:00 +00002180 }
2181 }else
2182
drhae5e4452007-05-03 17:18:36 +00002183#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002184 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002185 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002186 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2187 iotrace = 0;
2188 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002189 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002190 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002191 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002192 iotrace = stdout;
2193 }else{
2194 iotrace = fopen(azArg[1], "w");
2195 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002196 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002197 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002198 rc = 1;
drhb0603412007-02-28 04:47:26 +00002199 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002200 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002201 }
2202 }
2203 }else
drhae5e4452007-05-03 17:18:36 +00002204#endif
drhb0603412007-02-28 04:47:26 +00002205
drh70df4fe2006-06-13 15:12:21 +00002206#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002207 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2208 const char *zFile, *zProc;
2209 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00002210 zFile = azArg[1];
2211 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00002212 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00002213 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2214 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002215 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002216 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002217 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002218 }
2219 }else
drh70df4fe2006-06-13 15:12:21 +00002220#endif
drh1e397f82006-06-08 15:28:43 +00002221
drhc8ba2122011-03-23 11:16:22 +00002222 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00002223 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00002224 output_file_close(p->pLog);
2225 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00002226 }else
2227
shanehe2aa9d72009-11-06 17:20:17 +00002228 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00002229 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002230 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002231 ||
shanehe2aa9d72009-11-06 17:20:17 +00002232 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002233 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002234 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002235 ||
shanehe2aa9d72009-11-06 17:20:17 +00002236 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002237 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002238 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002239 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002240 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002241 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002242 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002243 p->mode = MODE_Tcl;
mistachkin585dcb22012-12-04 00:23:43 +00002244 sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
shanehe2aa9d72009-11-06 17:20:17 +00002245 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002246 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002247 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002248 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002249 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002250 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002251 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002252 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002253 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002254 }else {
shane9bd1b442009-10-23 01:27:39 +00002255 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002256 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002257 rc = 1;
drh75897232000-05-29 14:26:00 +00002258 }
2259 }else
2260
shanehe2aa9d72009-11-06 17:20:17 +00002261 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2262 int n2 = strlen30(azArg[1]);
2263 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2264 p->mode = MODE_Insert;
2265 set_table_name(p, azArg[2]);
2266 }else {
2267 fprintf(stderr, "Error: invalid arguments: "
2268 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2269 rc = 1;
2270 }
2271 }else
2272
persicom7e2dfdd2002-04-18 02:46:52 +00002273 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002274 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2275 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002276 }else
2277
drh05782482013-10-24 15:20:20 +00002278 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
2279 sqlite3 *savedDb = p->db;
2280 const char *zSavedFilename = p->zDbFilename;
2281 char *zNewFilename = 0;
2282 p->db = 0;
2283 if( nArg>=2 ){
2284 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
2285 }
2286 open_db(p, 1);
2287 if( p->db!=0 ){
2288 sqlite3_close(savedDb);
2289 sqlite3_free(p->zFreeOnClose);
2290 p->zFreeOnClose = zNewFilename;
2291 }else{
2292 sqlite3_free(zNewFilename);
2293 p->db = savedDb;
2294 p->zDbFilename = zSavedFilename;
2295 }
2296 }else
2297
drh75897232000-05-29 14:26:00 +00002298 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002299 if( p->outfile[0]=='|' ){
2300 pclose(p->out);
2301 }else{
2302 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002303 }
drh42f64e52012-04-04 16:56:23 +00002304 p->outfile[0] = 0;
2305 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002306 p->out = popen(&azArg[1][1], "w");
2307 if( p->out==0 ){
2308 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2309 p->out = stdout;
2310 rc = 1;
2311 }else{
2312 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2313 }
drh75897232000-05-29 14:26:00 +00002314 }else{
drh42f64e52012-04-04 16:56:23 +00002315 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002316 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002317 if( strcmp(azArg[1],"off")!=0 ){
2318 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2319 }
drh75897232000-05-29 14:26:00 +00002320 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002321 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002322 } else {
drh42f64e52012-04-04 16:56:23 +00002323 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002324 }
2325 }
2326 }else
2327
drh078b1fd2012-09-21 13:40:02 +00002328 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2329 int i;
2330 for(i=1; i<nArg; i++){
2331 if( i>1 ) fprintf(p->out, " ");
2332 fprintf(p->out, "%s", azArg[i]);
2333 }
2334 fprintf(p->out, "\n");
2335 }else
2336
drhdd45df82002-04-18 12:39:03 +00002337 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002338 if( nArg >= 2) {
2339 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2340 }
2341 if( nArg >= 3) {
2342 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2343 }
2344 }else
2345
shanehe2aa9d72009-11-06 17:20:17 +00002346 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002347 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002348 }else
2349
drh9ff849f2009-02-04 20:55:57 +00002350 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002351 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002352 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002353 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2354 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002355 }else{
shane9bd1b442009-10-23 01:27:39 +00002356 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002357 fclose(alt);
2358 }
2359 }else
2360
shanehe2aa9d72009-11-06 17:20:17 +00002361 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002362 const char *zSrcFile;
2363 const char *zDb;
2364 sqlite3 *pSrc;
2365 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002366 int nTimeout = 0;
2367
drh9ff849f2009-02-04 20:55:57 +00002368 if( nArg==2 ){
2369 zSrcFile = azArg[1];
2370 zDb = "main";
2371 }else{
2372 zSrcFile = azArg[2];
2373 zDb = azArg[1];
2374 }
2375 rc = sqlite3_open(zSrcFile, &pSrc);
2376 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002377 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002378 sqlite3_close(pSrc);
2379 return 1;
2380 }
drh05782482013-10-24 15:20:20 +00002381 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002382 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2383 if( pBackup==0 ){
2384 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2385 sqlite3_close(pSrc);
2386 return 1;
2387 }
drhdc2c4912009-02-04 22:46:47 +00002388 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2389 || rc==SQLITE_BUSY ){
2390 if( rc==SQLITE_BUSY ){
2391 if( nTimeout++ >= 3 ) break;
2392 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002393 }
2394 }
2395 sqlite3_backup_finish(pBackup);
2396 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002397 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002398 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002399 fprintf(stderr, "Error: source database is busy\n");
2400 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002401 }else{
2402 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002403 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002404 }
2405 sqlite3_close(pSrc);
2406 }else
2407
shanehe2aa9d72009-11-06 17:20:17 +00002408 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002409 struct callback_data data;
2410 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002411 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00002412 memcpy(&data, p, sizeof(data));
2413 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002414 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002415 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002416 int i;
drhf0693c82011-10-11 20:41:54 +00002417 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002418 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002419 char *new_argv[2], *new_colv[2];
2420 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2421 " type text,\n"
2422 " name text,\n"
2423 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002424 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002425 " sql text\n"
2426 ")";
2427 new_argv[1] = 0;
2428 new_colv[0] = "sql";
2429 new_colv[1] = 0;
2430 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002431 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002432 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002433 char *new_argv[2], *new_colv[2];
2434 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2435 " type text,\n"
2436 " name text,\n"
2437 " tbl_name text,\n"
2438 " rootpage integer,\n"
2439 " sql text\n"
2440 ")";
2441 new_argv[1] = 0;
2442 new_colv[0] = "sql";
2443 new_colv[1] = 0;
2444 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002445 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002446 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002447 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002448 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002449 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002450 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002451 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002452 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002453 "WHERE lower(tbl_name) LIKE shellstatic()"
2454 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00002455 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00002456 callback, &data, &zErrMsg);
2457 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002458 }
drh75897232000-05-29 14:26:00 +00002459 }else{
shane9bd1b442009-10-23 01:27:39 +00002460 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002461 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002462 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002463 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002464 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002465 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drh1ba00292013-05-06 21:01:06 +00002466 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00002467 callback, &data, &zErrMsg
2468 );
drh75897232000-05-29 14:26:00 +00002469 }
drh75897232000-05-29 14:26:00 +00002470 if( zErrMsg ){
2471 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002472 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002473 rc = 1;
2474 }else if( rc != SQLITE_OK ){
2475 fprintf(stderr,"Error: querying schema information\n");
2476 rc = 1;
2477 }else{
2478 rc = 0;
drh75897232000-05-29 14:26:00 +00002479 }
2480 }else
2481
drh340f5822013-06-27 13:01:21 +00002482#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00002483 /* Undocumented commands for internal testing. Subject to change
2484 ** without notice. */
2485 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
2486 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
2487 int i, v;
2488 for(i=1; i<nArg; i++){
2489 v = booleanValue(azArg[i]);
2490 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
2491 }
2492 }
2493 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
2494 int i; sqlite3_int64 v;
2495 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00002496 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00002497 v = integerValue(azArg[i]);
drh340f5822013-06-27 13:01:21 +00002498 sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);
2499 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00002500 }
2501 }
2502 }else
drh340f5822013-06-27 13:01:21 +00002503#endif
drh348d19c2013-06-03 12:47:43 +00002504
drh75897232000-05-29 14:26:00 +00002505 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002506 sqlite3_snprintf(sizeof(p->separator), p->separator,
2507 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002508 }else
2509
shanehe2aa9d72009-11-06 17:20:17 +00002510 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002511 int i;
2512 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002513 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002514 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002515 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002516 fprintf(p->out,"%9.9s: ", "nullvalue");
2517 output_c_string(p->out, p->nullvalue);
2518 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002519 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002520 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002521 fprintf(p->out,"%9.9s: ", "separator");
2522 output_c_string(p->out, p->separator);
2523 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002524 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002525 fprintf(p->out,"%9.9s: ","width");
2526 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002527 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002528 }
drhfeac5f82004-08-01 00:10:45 +00002529 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002530 }else
2531
shaneh642d8b82010-07-28 16:05:34 +00002532 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2533 p->statsOn = booleanValue(azArg[1]);
2534 }else
2535
shanehe2aa9d72009-11-06 17:20:17 +00002536 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002537 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002538 char **azResult;
drh98781232012-04-23 12:38:05 +00002539 int nRow, nAlloc;
2540 char *zSql = 0;
2541 int ii;
drh05782482013-10-24 15:20:20 +00002542 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00002543 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2544 if( rc ) return rc;
2545 zSql = sqlite3_mprintf(
2546 "SELECT name FROM sqlite_master"
2547 " WHERE type IN ('table','view')"
2548 " AND name NOT LIKE 'sqlite_%%'"
2549 " AND name LIKE ?1");
2550 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2551 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2552 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2553 if( strcmp(zDbName,"temp")==0 ){
2554 zSql = sqlite3_mprintf(
2555 "%z UNION ALL "
2556 "SELECT 'temp.' || name FROM sqlite_temp_master"
2557 " WHERE type IN ('table','view')"
2558 " AND name NOT LIKE 'sqlite_%%'"
2559 " AND name LIKE ?1", zSql);
2560 }else{
2561 zSql = sqlite3_mprintf(
2562 "%z UNION ALL "
2563 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2564 " WHERE type IN ('table','view')"
2565 " AND name NOT LIKE 'sqlite_%%'"
2566 " AND name LIKE ?1", zSql, zDbName, zDbName);
2567 }
drha50da102000-08-08 20:19:09 +00002568 }
drh98781232012-04-23 12:38:05 +00002569 sqlite3_finalize(pStmt);
2570 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2571 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2572 sqlite3_free(zSql);
2573 if( rc ) return rc;
2574 nRow = nAlloc = 0;
2575 azResult = 0;
2576 if( nArg>1 ){
2577 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002578 }else{
drh98781232012-04-23 12:38:05 +00002579 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2580 }
2581 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2582 if( nRow>=nAlloc ){
2583 char **azNew;
2584 int n = nAlloc*2 + 10;
2585 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2586 if( azNew==0 ){
2587 fprintf(stderr, "Error: out of memory\n");
2588 break;
2589 }
2590 nAlloc = n;
2591 azResult = azNew;
2592 }
2593 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2594 if( azResult[nRow] ) nRow++;
2595 }
2596 sqlite3_finalize(pStmt);
2597 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002598 int len, maxlen = 0;
2599 int i, j;
2600 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002601 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002602 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002603 if( len>maxlen ) maxlen = len;
2604 }
2605 nPrintCol = 80/(maxlen+2);
2606 if( nPrintCol<1 ) nPrintCol = 1;
2607 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2608 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002609 for(j=i; j<nRow; j+=nPrintRow){
2610 char *zSp = j<nPrintRow ? "" : " ";
drh151b7d52013-05-06 20:28:54 +00002611 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
drhe3710332000-09-29 13:30:53 +00002612 }
drh151b7d52013-05-06 20:28:54 +00002613 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00002614 }
2615 }
drh98781232012-04-23 12:38:05 +00002616 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2617 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002618 }else
2619
shaneh96887e12011-02-10 21:08:58 +00002620 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002621 static const struct {
2622 const char *zCtrlName; /* Name of a test-control option */
2623 int ctrlCode; /* Integer code for that option */
2624 } aCtrl[] = {
2625 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2626 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2627 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2628 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2629 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2630 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2631 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2632 { "assert", SQLITE_TESTCTRL_ASSERT },
2633 { "always", SQLITE_TESTCTRL_ALWAYS },
2634 { "reserve", SQLITE_TESTCTRL_RESERVE },
2635 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2636 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002637 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2638 };
shaneh96887e12011-02-10 21:08:58 +00002639 int testctrl = -1;
2640 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002641 int i, n;
drh05782482013-10-24 15:20:20 +00002642 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00002643
drhd416fe72011-03-17 16:45:50 +00002644 /* convert testctrl text option to value. allow any unique prefix
2645 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002646 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002647 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002648 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2649 if( testctrl<0 ){
2650 testctrl = aCtrl[i].ctrlCode;
2651 }else{
drhb07028f2011-10-14 21:49:18 +00002652 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002653 testctrl = -1;
2654 break;
2655 }
2656 }
2657 }
drh348d19c2013-06-03 12:47:43 +00002658 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002659 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2660 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2661 }else{
2662 switch(testctrl){
2663
2664 /* sqlite3_test_control(int, db, int) */
2665 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2666 case SQLITE_TESTCTRL_RESERVE:
2667 if( nArg==3 ){
2668 int opt = (int)strtol(azArg[2], 0, 0);
2669 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00002670 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002671 } else {
drhd416fe72011-03-17 16:45:50 +00002672 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2673 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002674 }
2675 break;
2676
2677 /* sqlite3_test_control(int) */
2678 case SQLITE_TESTCTRL_PRNG_SAVE:
2679 case SQLITE_TESTCTRL_PRNG_RESTORE:
2680 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002681 if( nArg==2 ){
2682 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00002683 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002684 } else {
2685 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2686 }
2687 break;
2688
2689 /* sqlite3_test_control(int, uint) */
2690 case SQLITE_TESTCTRL_PENDING_BYTE:
2691 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00002692 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002693 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002694 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002695 } else {
drhd416fe72011-03-17 16:45:50 +00002696 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2697 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002698 }
2699 break;
2700
2701 /* sqlite3_test_control(int, int) */
2702 case SQLITE_TESTCTRL_ASSERT:
2703 case SQLITE_TESTCTRL_ALWAYS:
2704 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00002705 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002706 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002707 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002708 } else {
drhd416fe72011-03-17 16:45:50 +00002709 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2710 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002711 }
2712 break;
2713
2714 /* sqlite3_test_control(int, char *) */
2715#ifdef SQLITE_N_KEYWORD
2716 case SQLITE_TESTCTRL_ISKEYWORD:
2717 if( nArg==3 ){
2718 const char *opt = azArg[2];
2719 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002720 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002721 } else {
drhd416fe72011-03-17 16:45:50 +00002722 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2723 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002724 }
2725 break;
2726#endif
2727
2728 case SQLITE_TESTCTRL_BITVEC_TEST:
2729 case SQLITE_TESTCTRL_FAULT_INSTALL:
2730 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2731 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2732 default:
drhd416fe72011-03-17 16:45:50 +00002733 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2734 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002735 break;
2736 }
2737 }
2738 }else
2739
shanehe2aa9d72009-11-06 17:20:17 +00002740 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh05782482013-10-24 15:20:20 +00002741 open_db(p, 0);
drh348d19c2013-06-03 12:47:43 +00002742 sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002743 }else
2744
drhd416fe72011-03-17 16:45:50 +00002745 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2746 && nArg==2
2747 ){
drh3b1a9882007-11-02 12:53:03 +00002748 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002749 }else
2750
drh42f64e52012-04-04 16:56:23 +00002751 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh05782482013-10-24 15:20:20 +00002752 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00002753 output_file_close(p->traceOut);
2754 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00002755#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002756 if( p->traceOut==0 ){
2757 sqlite3_trace(p->db, 0, 0);
2758 }else{
2759 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2760 }
2761#endif
2762 }else
2763
drh9fd301b2011-06-03 13:28:22 +00002764 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00002765 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002766 sqlite3_libversion(), sqlite3_sourceid());
2767 }else
2768
drhde60fc22011-12-14 17:53:36 +00002769 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2770 const char *zDbName = nArg==2 ? azArg[1] : "main";
2771 char *zVfsName = 0;
2772 if( p->db ){
2773 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2774 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00002775 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00002776 sqlite3_free(zVfsName);
2777 }
2778 }
2779 }else
2780
drhcef4fc82012-09-21 22:50:45 +00002781#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2782 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
2783 extern int sqlite3WhereTrace;
drh7d9f3942013-04-03 01:26:54 +00002784 sqlite3WhereTrace = booleanValue(azArg[1]);
drhcef4fc82012-09-21 22:50:45 +00002785 }else
2786#endif
2787
shanehe2aa9d72009-11-06 17:20:17 +00002788 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002789 int j;
drh43617e92006-03-06 20:55:46 +00002790 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002791 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00002792 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00002793 }
2794 }else
2795
2796 {
shane9bd1b442009-10-23 01:27:39 +00002797 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002798 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002799 rc = 1;
drh75897232000-05-29 14:26:00 +00002800 }
drh67505e72002-04-19 12:34:06 +00002801
2802 return rc;
drh75897232000-05-29 14:26:00 +00002803}
2804
drh67505e72002-04-19 12:34:06 +00002805/*
drh91a66392007-09-07 01:12:32 +00002806** Return TRUE if a semicolon occurs anywhere in the first N characters
2807** of string z[].
drh324ccef2003-02-05 14:06:20 +00002808*/
drh9f099fd2013-08-06 14:01:46 +00002809static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00002810 int i;
2811 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2812 return 0;
drh324ccef2003-02-05 14:06:20 +00002813}
2814
2815/*
drh70c7a4b2003-04-26 03:03:06 +00002816** Test to see if a line consists entirely of whitespace.
2817*/
2818static int _all_whitespace(const char *z){
2819 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002820 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002821 if( *z=='/' && z[1]=='*' ){
2822 z += 2;
2823 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2824 if( *z==0 ) return 0;
2825 z++;
2826 continue;
2827 }
2828 if( *z=='-' && z[1]=='-' ){
2829 z += 2;
2830 while( *z && *z!='\n' ){ z++; }
2831 if( *z==0 ) return 1;
2832 continue;
2833 }
2834 return 0;
2835 }
2836 return 1;
2837}
2838
2839/*
drha9b17162003-04-29 18:01:28 +00002840** Return TRUE if the line typed in is an SQL command terminator other
2841** than a semi-colon. The SQL Server style "go" command is understood
2842** as is the Oracle "/".
2843*/
drh9f099fd2013-08-06 14:01:46 +00002844static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002845 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002846 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2847 return 1; /* Oracle */
2848 }
drhf0693c82011-10-11 20:41:54 +00002849 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002850 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002851 return 1; /* SQL Server */
2852 }
2853 return 0;
2854}
2855
2856/*
drh233a5312008-12-18 22:25:13 +00002857** Return true if zSql is a complete SQL statement. Return false if it
2858** ends in the middle of a string literal or C-style comment.
2859*/
drh9f099fd2013-08-06 14:01:46 +00002860static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00002861 int rc;
2862 if( zSql==0 ) return 1;
2863 zSql[nSql] = ';';
2864 zSql[nSql+1] = 0;
2865 rc = sqlite3_complete(zSql);
2866 zSql[nSql] = 0;
2867 return rc;
2868}
2869
2870/*
drh67505e72002-04-19 12:34:06 +00002871** Read input from *in and process it. If *in==0 then input
2872** is interactive - the user is typing it it. Otherwise, input
2873** is coming from a file or device. A prompt is issued and history
2874** is saved only if input is interactive. An interrupt signal will
2875** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002876**
2877** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002878*/
drhc28490c2006-10-26 14:25:58 +00002879static int process_input(struct callback_data *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00002880 char *zLine = 0; /* A single input line */
2881 char *zSql = 0; /* Accumulated SQL text */
2882 int nLine; /* Length of current line */
2883 int nSql = 0; /* Bytes of zSql[] used */
2884 int nAlloc = 0; /* Allocated zSql[] space */
2885 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
2886 char *zErrMsg; /* Error message returned */
2887 int rc; /* Error code */
2888 int errCnt = 0; /* Number of errors seen */
2889 int lineno = 0; /* Current line number */
2890 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00002891
2892 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2893 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00002894 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00002895 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002896 /* End of input */
2897 if( stdin_is_interactive ) printf("\n");
2898 break;
drhc49f44e2006-10-26 18:15:42 +00002899 }
drh67505e72002-04-19 12:34:06 +00002900 if( seenInterrupt ){
2901 if( in!=0 ) break;
2902 seenInterrupt = 0;
2903 }
drhc28490c2006-10-26 14:25:58 +00002904 lineno++;
drh9f099fd2013-08-06 14:01:46 +00002905 if( nSql==0 && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002906 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002907 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002908 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002909 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002910 break;
2911 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002912 errCnt++;
2913 }
drhdaffd0e2001-04-11 14:28:42 +00002914 continue;
2915 }
drh9f099fd2013-08-06 14:01:46 +00002916 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002917 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002918 }
drh9f099fd2013-08-06 14:01:46 +00002919 nLine = strlen30(zLine);
2920 if( nSql+nLine+2>=nAlloc ){
2921 nAlloc = nSql+nLine+100;
2922 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00002923 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00002924 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002925 exit(1);
2926 }
drhdaffd0e2001-04-11 14:28:42 +00002927 }
drh9f099fd2013-08-06 14:01:46 +00002928 nSqlPrior = nSql;
2929 if( nSql==0 ){
2930 int i;
2931 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00002932 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00002933 memcpy(zSql, zLine+i, nLine+1-i);
2934 startline = lineno;
2935 nSql = nLine-i;
2936 }else{
2937 zSql[nSql++] = '\n';
2938 memcpy(zSql+nSql, zLine, nLine+1);
2939 nSql += nLine;
2940 }
2941 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00002942 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002943 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00002944 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00002945 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002946 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002947 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002948 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002949 char zPrefix[100];
2950 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002951 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002952 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002953 }else{
shane9bd1b442009-10-23 01:27:39 +00002954 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002955 }
drh7f953e22002-07-13 17:33:45 +00002956 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002957 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002958 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002959 zErrMsg = 0;
2960 }else{
shaned2bed1c2009-10-21 03:56:54 +00002961 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002962 }
drhc49f44e2006-10-26 18:15:42 +00002963 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002964 }
drhdaffd0e2001-04-11 14:28:42 +00002965 nSql = 0;
drh9f099fd2013-08-06 14:01:46 +00002966 }else if( nSql && _all_whitespace(zSql) ){
drh7a411f42013-04-17 17:33:17 +00002967 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00002968 }
2969 }
drh9f099fd2013-08-06 14:01:46 +00002970 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00002971 if( !_all_whitespace(zSql) ){
2972 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2973 }
drhdaffd0e2001-04-11 14:28:42 +00002974 free(zSql);
2975 }
danielk19772ac27622007-07-03 05:31:16 +00002976 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00002977 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00002978}
2979
drh67505e72002-04-19 12:34:06 +00002980/*
2981** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002982** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002983*/
2984static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002985 static char *home_dir = NULL;
2986 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002987
drh83905c92012-06-21 13:00:37 +00002988#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00002989 {
2990 struct passwd *pwent;
2991 uid_t uid = getuid();
2992 if( (pwent=getpwuid(uid)) != NULL) {
2993 home_dir = pwent->pw_dir;
2994 }
drh67505e72002-04-19 12:34:06 +00002995 }
2996#endif
2997
chw65d3c132007-11-12 21:09:10 +00002998#if defined(_WIN32_WCE)
2999 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
3000 */
drh85e72432012-04-11 11:38:53 +00003001 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00003002#else
3003
drh83905c92012-06-21 13:00:37 +00003004#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00003005 if (!home_dir) {
3006 home_dir = getenv("USERPROFILE");
3007 }
3008#endif
3009
drh67505e72002-04-19 12:34:06 +00003010 if (!home_dir) {
3011 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00003012 }
3013
drh83905c92012-06-21 13:00:37 +00003014#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00003015 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00003016 char *zDrive, *zPath;
3017 int n;
3018 zDrive = getenv("HOMEDRIVE");
3019 zPath = getenv("HOMEPATH");
3020 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00003021 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00003022 home_dir = malloc( n );
3023 if( home_dir==0 ) return 0;
3024 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3025 return home_dir;
3026 }
3027 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00003028 }
3029#endif
3030
chw65d3c132007-11-12 21:09:10 +00003031#endif /* !_WIN32_WCE */
3032
drh67505e72002-04-19 12:34:06 +00003033 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00003034 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00003035 char *z = malloc( n );
3036 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00003037 home_dir = z;
3038 }
drhe98d4fa2002-04-21 19:06:22 +00003039
drh67505e72002-04-19 12:34:06 +00003040 return home_dir;
3041}
3042
3043/*
3044** Read input from the file given by sqliterc_override. Or if that
3045** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00003046**
3047** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00003048*/
shane9bd1b442009-10-23 01:27:39 +00003049static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00003050 struct callback_data *p, /* Configuration data */
3051 const char *sqliterc_override /* Name of config file. NULL to use default */
3052){
persicom7e2dfdd2002-04-18 02:46:52 +00003053 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00003054 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00003055 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003056 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00003057 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003058
3059 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00003060 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00003061 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00003062#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00003063 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00003064#endif
shane9bd1b442009-10-23 01:27:39 +00003065 return 1;
drhe98d4fa2002-04-21 19:06:22 +00003066 }
drh2f3de322012-06-27 16:41:31 +00003067 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00003068 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
3069 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003070 }
drha1f9b5e2004-02-14 16:31:02 +00003071 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00003072 if( in ){
drhc28490c2006-10-26 14:25:58 +00003073 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00003074 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00003075 }
shane9bd1b442009-10-23 01:27:39 +00003076 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00003077 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00003078 }
drh85e72432012-04-11 11:38:53 +00003079 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00003080 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00003081}
3082
drh67505e72002-04-19 12:34:06 +00003083/*
drhe1e38c42003-05-04 18:30:59 +00003084** Show available command line options
3085*/
3086static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00003087 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00003088 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003089 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00003090 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00003091 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00003092 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00003093 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00003094 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00003095#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3096 " -heap SIZE Size of heap for memsys3 or memsys5\n"
3097#endif
drhcc3b4f82012-02-07 14:13:50 +00003098 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00003099 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00003100 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003101 " -line set output mode to 'line'\n"
3102 " -list set output mode to 'list'\n"
drh7d9f3942013-04-03 01:26:54 +00003103 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00003104#ifdef SQLITE_ENABLE_MULTIPLEX
3105 " -multiplex enable the multiplexor VFS\n"
3106#endif
drh98d312f2012-10-25 15:23:14 +00003107 " -nullvalue TEXT set text string for NULL values. Default ''\n"
3108 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00003109 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00003110 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00003111 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00003112#ifdef SQLITE_ENABLE_VFSTRACE
3113 " -vfstrace enable tracing of all VFS calls\n"
3114#endif
drhe1e38c42003-05-04 18:30:59 +00003115;
3116static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00003117 fprintf(stderr,
3118 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3119 "FILENAME is the name of an SQLite database. A new database is created\n"
3120 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00003121 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00003122 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00003123 }else{
3124 fprintf(stderr, "Use the -help option for additional information\n");
3125 }
3126 exit(1);
3127}
3128
3129/*
drh67505e72002-04-19 12:34:06 +00003130** Initialize the state information in data
3131*/
drh0850b532006-01-31 19:31:43 +00003132static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00003133 memset(data, 0, sizeof(*data));
3134 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00003135 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00003136 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00003137 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00003138 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00003139 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3140 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00003141 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00003142}
3143
drh98d312f2012-10-25 15:23:14 +00003144/*
3145** Get the argument to an --option. Throw an error and die if no argument
3146** is available.
3147*/
3148static char *cmdline_option_value(int argc, char **argv, int i){
3149 if( i==argc ){
3150 fprintf(stderr, "%s: Error: missing argument to %s\n",
3151 argv[0], argv[argc-1]);
3152 exit(1);
3153 }
3154 return argv[i];
3155}
3156
drh75897232000-05-29 14:26:00 +00003157int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003158 char *zErrMsg = 0;
3159 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00003160 const char *zInitFile = 0;
3161 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003162 int i;
drhc28490c2006-10-26 14:25:58 +00003163 int rc = 0;
drh75897232000-05-29 14:26:00 +00003164
drh52784bd2011-05-18 17:15:06 +00003165 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
3166 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
3167 sqlite3_sourceid(), SQLITE_SOURCE_ID);
3168 exit(1);
3169 }
drhdaffd0e2001-04-11 14:28:42 +00003170 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003171 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003172 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003173
drh44c2eb12003-04-30 11:38:26 +00003174 /* Make sure we have a valid signal handler early, before anything
3175 ** else is done.
3176 */
drh4c504392000-10-16 22:06:40 +00003177#ifdef SIGINT
3178 signal(SIGINT, interrupt_handler);
3179#endif
drh44c2eb12003-04-30 11:38:26 +00003180
drh22fbcb82004-02-01 01:22:50 +00003181 /* Do an initial pass through the command-line argument to locate
3182 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00003183 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00003184 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003185 */
drh98d312f2012-10-25 15:23:14 +00003186 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00003187 char *z;
drhc28490c2006-10-26 14:25:58 +00003188 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003189 if( z[0]!='-' ){
3190 if( data.zDbFilename==0 ){
3191 data.zDbFilename = z;
3192 continue;
3193 }
3194 if( zFirstCmd==0 ){
3195 zFirstCmd = z;
3196 continue;
3197 }
3198 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
3199 fprintf(stderr,"Use -help for a list of options.\n");
3200 return 1;
3201 }
drhcc3b4f82012-02-07 14:13:50 +00003202 if( z[1]=='-' ) z++;
3203 if( strcmp(z,"-separator")==0
3204 || strcmp(z,"-nullvalue")==0
3205 || strcmp(z,"-cmd")==0
3206 ){
drh98d312f2012-10-25 15:23:14 +00003207 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003208 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00003209 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003210 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00003211 /* Need to check for batch mode here to so we can avoid printing
3212 ** informational messages (like from process_sqliterc) before
3213 ** we do the actual processing of arguments later in a second pass.
3214 */
shanef69573d2009-10-24 02:06:14 +00003215 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00003216 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00003217#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00003218 const char *zSize;
3219 sqlite3_int64 szHeap;
3220
drh98d312f2012-10-25 15:23:14 +00003221 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00003222 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00003223 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00003224 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3225#endif
drh97ae8ff2011-03-16 16:56:29 +00003226#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00003227 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00003228 extern int vfstrace_register(
3229 const char *zTraceName,
3230 const char *zOldVfsName,
3231 int (*xOut)(const char*,void*),
3232 void *pOutArg,
3233 int makeDefault
3234 );
drh2b625e22011-03-16 17:05:28 +00003235 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00003236#endif
drh6f25e892011-07-08 17:02:57 +00003237#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00003238 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00003239 extern int sqlite3_multiple_initialize(const char*,int);
3240 sqlite3_multiplex_initialize(0, 1);
3241#endif
drh7d9f3942013-04-03 01:26:54 +00003242 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00003243 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
3244 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00003245 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00003246 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00003247 if( pVfs ){
3248 sqlite3_vfs_register(pVfs, 1);
3249 }else{
3250 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3251 exit(1);
3252 }
drh44c2eb12003-04-30 11:38:26 +00003253 }
3254 }
drh98d312f2012-10-25 15:23:14 +00003255 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00003256#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003257 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003258#else
shane86f5bdb2009-10-24 02:00:07 +00003259 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3260 return 1;
drh01b41712005-08-29 23:06:23 +00003261#endif
drh98d312f2012-10-25 15:23:14 +00003262 }
3263 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00003264
drh44c2eb12003-04-30 11:38:26 +00003265 /* Go ahead and open the database file if it already exists. If the
3266 ** file does not exist, delay opening it. This prevents empty database
3267 ** files from being created if a user mistypes the database name argument
3268 ** to the sqlite command-line tool.
3269 */
drhc8d74412004-08-31 23:41:26 +00003270 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00003271 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00003272 }
3273
drh22fbcb82004-02-01 01:22:50 +00003274 /* Process the initialization file if there is one. If no -init option
3275 ** is given on the command line, look for a file named ~/.sqliterc and
3276 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003277 */
shane86f5bdb2009-10-24 02:00:07 +00003278 rc = process_sqliterc(&data,zInitFile);
3279 if( rc>0 ){
3280 return rc;
3281 }
drh44c2eb12003-04-30 11:38:26 +00003282
drh22fbcb82004-02-01 01:22:50 +00003283 /* Make a second pass through the command-line argument and set
3284 ** options. This second pass is delayed until after the initialization
3285 ** file is processed so that the command-line arguments will override
3286 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003287 */
drh98d312f2012-10-25 15:23:14 +00003288 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00003289 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003290 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00003291 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003292 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003293 i++;
3294 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003295 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003296 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003297 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003298 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003299 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003300 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003301 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003302 }else if( strcmp(z,"-csv")==0 ){
3303 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003304 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003305 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003306 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00003307 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003308 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003309 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00003310 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003311 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003312 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003313 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003314 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003315 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003316 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003317 }else if( strcmp(z,"-stats")==0 ){
3318 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003319 }else if( strcmp(z,"-bail")==0 ){
3320 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003321 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003322 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003323 return 0;
drhc28490c2006-10-26 14:25:58 +00003324 }else if( strcmp(z,"-interactive")==0 ){
3325 stdin_is_interactive = 1;
3326 }else if( strcmp(z,"-batch")==0 ){
3327 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003328 }else if( strcmp(z,"-heap")==0 ){
3329 i++;
drh7d9f3942013-04-03 01:26:54 +00003330 }else if( strcmp(z,"-mmap")==0 ){
3331 i++;
drha7e61d82011-03-12 17:02:57 +00003332 }else if( strcmp(z,"-vfs")==0 ){
3333 i++;
drh6f25e892011-07-08 17:02:57 +00003334#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003335 }else if( strcmp(z,"-vfstrace")==0 ){
3336 i++;
drh6f25e892011-07-08 17:02:57 +00003337#endif
3338#ifdef SQLITE_ENABLE_MULTIPLEX
3339 }else if( strcmp(z,"-multiplex")==0 ){
3340 i++;
3341#endif
drhcc3b4f82012-02-07 14:13:50 +00003342 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003343 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003344 }else if( strcmp(z,"-cmd")==0 ){
3345 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00003346 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00003347 if( z[0]=='.' ){
3348 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00003349 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00003350 }else{
drh05782482013-10-24 15:20:20 +00003351 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00003352 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3353 if( zErrMsg!=0 ){
3354 fprintf(stderr,"Error: %s\n", zErrMsg);
3355 if( bail_on_error ) return rc!=0 ? rc : 1;
3356 }else if( rc!=0 ){
3357 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3358 if( bail_on_error ) return rc;
3359 }
3360 }
drh1e5d0e92000-05-31 23:33:17 +00003361 }else{
shane86f5bdb2009-10-24 02:00:07 +00003362 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003363 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003364 return 1;
3365 }
3366 }
drh44c2eb12003-04-30 11:38:26 +00003367
drh22fbcb82004-02-01 01:22:50 +00003368 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003369 /* Run just the command that follows the database name
3370 */
drh22fbcb82004-02-01 01:22:50 +00003371 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003372 rc = do_meta_command(zFirstCmd, &data);
drh99b39082013-04-17 12:19:48 +00003373 if( rc==2 ) rc = 0;
drh6ff13852001-11-25 13:18:23 +00003374 }else{
drh05782482013-10-24 15:20:20 +00003375 open_db(&data, 0);
shane626a6e42009-10-22 17:30:15 +00003376 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003377 if( zErrMsg!=0 ){
3378 fprintf(stderr,"Error: %s\n", zErrMsg);
3379 return rc!=0 ? rc : 1;
3380 }else if( rc!=0 ){
3381 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3382 return rc;
drh6ff13852001-11-25 13:18:23 +00003383 }
drh75897232000-05-29 14:26:00 +00003384 }
3385 }else{
drh44c2eb12003-04-30 11:38:26 +00003386 /* Run commands received from standard input
3387 */
drhc28490c2006-10-26 14:25:58 +00003388 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003389 char *zHome;
3390 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003391 int nHistory;
drh75897232000-05-29 14:26:00 +00003392 printf(
drh743e0032011-12-12 16:51:50 +00003393 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003394 "Enter \".help\" for instructions\n"
3395 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003396 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003397 );
drh67505e72002-04-19 12:34:06 +00003398 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003399 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003400 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003401 if( (zHistory = malloc(nHistory))!=0 ){
3402 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3403 }
drh67505e72002-04-19 12:34:06 +00003404 }
danielk19774af00c62005-01-23 23:43:21 +00003405#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003406 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003407#endif
drhc28490c2006-10-26 14:25:58 +00003408 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003409 if( zHistory ){
3410 stifle_history(100);
3411 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003412 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003413 }
drhdaffd0e2001-04-11 14:28:42 +00003414 }else{
drhc28490c2006-10-26 14:25:58 +00003415 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003416 }
3417 }
drh33048c02001-10-01 14:29:22 +00003418 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003419 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003420 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003421 }
drh05782482013-10-24 15:20:20 +00003422 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00003423 return rc;
drh75897232000-05-29 14:26:00 +00003424}