blob: 91f234fb3105fd3c4a21e17f507e15879052fb77 [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)
drh18f52e02012-01-16 16:56:31 +000056# define readline(p) local_getline(p,stdin,0)
persicom1d0b8722002-04-18 02:53:04 +000057# define add_history(X)
drh67505e72002-04-19 12:34:06 +000058# define read_history(X)
59# define write_history(X)
60# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000061#endif
62
adamd2e8464a2006-09-06 21:39:40 +000063#if defined(_WIN32) || defined(WIN32)
64# include <io.h>
shane18e526c2008-12-10 22:30:24 +000065#define isatty(h) _isatty(h)
66#define access(f,m) _access((f),(m))
drh67ceaa62012-08-27 21:19:03 +000067#undef popen
drhe1da8fa2012-03-30 00:05:57 +000068#define popen(a,b) _popen((a),(b))
drh67ceaa62012-08-27 21:19:03 +000069#undef pclose
drhe1da8fa2012-03-30 00:05:57 +000070#define pclose(x) _pclose(x)
adamd2e8464a2006-09-06 21:39:40 +000071#else
drh4328c8b2003-04-26 02:50:11 +000072/* Make sure isatty() has a prototype.
73*/
drhb2acc3b2011-10-13 16:36:29 +000074extern int isatty(int);
adamd2e8464a2006-09-06 21:39:40 +000075#endif
drh4328c8b2003-04-26 02:50:11 +000076
chw65d3c132007-11-12 21:09:10 +000077#if defined(_WIN32_WCE)
78/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
79 * thus we always assume that we have a console. That can be
80 * overridden with the -batch command line option.
81 */
82#define isatty(x) 1
83#endif
84
drhc6e41722011-04-11 15:36:26 +000085/* True if the timer is enabled */
86static int enableTimer = 0;
87
drhf0693c82011-10-11 20:41:54 +000088/* ctype macros that work with signed characters */
89#define IsSpace(X) isspace((unsigned char)X)
90#define IsDigit(X) isdigit((unsigned char)X)
91#define ToLower(X) (char)tolower((unsigned char)X)
92
drhd5d0f642013-02-20 00:54:21 +000093#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
94 && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +000095#include <sys/time.h>
96#include <sys/resource.h>
97
drhda108222009-02-25 19:07:24 +000098/* Saved resource information for the beginning of an operation */
99static struct rusage sBegin;
100
drhda108222009-02-25 19:07:24 +0000101/*
102** Begin timing an operation
103*/
104static void beginTimer(void){
105 if( enableTimer ){
106 getrusage(RUSAGE_SELF, &sBegin);
107 }
108}
109
110/* Return the difference of two time_structs in seconds */
111static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
112 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
113 (double)(pEnd->tv_sec - pStart->tv_sec);
114}
115
116/*
117** Print the timing results.
118*/
119static void endTimer(void){
120 if( enableTimer ){
121 struct rusage sEnd;
122 getrusage(RUSAGE_SELF, &sEnd);
123 printf("CPU Time: user %f sys %f\n",
124 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
125 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
126 }
127}
shaneb320ccd2009-10-21 03:42:58 +0000128
drhda108222009-02-25 19:07:24 +0000129#define BEGIN_TIMER beginTimer()
130#define END_TIMER endTimer()
131#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000132
133#elif (defined(_WIN32) || defined(WIN32))
134
135#include <windows.h>
136
137/* Saved resource information for the beginning of an operation */
138static HANDLE hProcess;
139static FILETIME ftKernelBegin;
140static FILETIME ftUserBegin;
141typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
142static GETPROCTIMES getProcessTimesAddr = NULL;
143
shaneb320ccd2009-10-21 03:42:58 +0000144/*
145** Check to see if we have timer support. Return 1 if necessary
146** support found (or found previously).
147*/
148static int hasTimer(void){
149 if( getProcessTimesAddr ){
150 return 1;
151 } else {
152 /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
153 ** See if the version we are running on has it, and if it does, save off
154 ** a pointer to it and the current process handle.
155 */
156 hProcess = GetCurrentProcess();
157 if( hProcess ){
158 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
159 if( NULL != hinstLib ){
160 getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
161 if( NULL != getProcessTimesAddr ){
162 return 1;
163 }
164 FreeLibrary(hinstLib);
165 }
166 }
167 }
168 return 0;
169}
170
171/*
172** Begin timing an operation
173*/
174static void beginTimer(void){
175 if( enableTimer && getProcessTimesAddr ){
176 FILETIME ftCreation, ftExit;
177 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
178 }
179}
180
181/* Return the difference of two FILETIME structs in seconds */
182static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
183 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
184 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
185 return (double) ((i64End - i64Start) / 10000000.0);
186}
187
188/*
189** Print the timing results.
190*/
191static void endTimer(void){
192 if( enableTimer && getProcessTimesAddr){
193 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
194 getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
195 printf("CPU Time: user %f sys %f\n",
196 timeDiff(&ftUserBegin, &ftUserEnd),
197 timeDiff(&ftKernelBegin, &ftKernelEnd));
198 }
199}
200
201#define BEGIN_TIMER beginTimer()
202#define END_TIMER endTimer()
203#define HAS_TIMER hasTimer()
204
drhda108222009-02-25 19:07:24 +0000205#else
206#define BEGIN_TIMER
207#define END_TIMER
208#define HAS_TIMER 0
209#endif
210
shanec0688ea2009-03-05 03:48:06 +0000211/*
212** Used to prevent warnings about unused parameters
213*/
214#define UNUSED_PARAMETER(x) (void)(x)
215
drhe91d16b2008-12-08 18:27:31 +0000216/*
drhc49f44e2006-10-26 18:15:42 +0000217** If the following flag is set, then command execution stops
218** at an error if we are not interactive.
219*/
220static int bail_on_error = 0;
221
222/*
drhc28490c2006-10-26 14:25:58 +0000223** Threat stdin as an interactive input if the following variable
224** is true. Otherwise, assume stdin is connected to a file or pipe.
225*/
226static int stdin_is_interactive = 1;
227
228/*
drh4c504392000-10-16 22:06:40 +0000229** The following is the open SQLite database. We make a pointer
230** to this database a static variable so that it can be accessed
231** by the SIGINT handler to interrupt database processing.
232*/
danielk197792f9a1b2004-06-19 09:08:16 +0000233static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000234
235/*
drh67505e72002-04-19 12:34:06 +0000236** True if an interrupt (Control-C) has been received.
237*/
drh43617e92006-03-06 20:55:46 +0000238static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000239
240/*
persicom7e2dfdd2002-04-18 02:46:52 +0000241** This is the name of our program. It is set in main(), used
242** in a number of other places, mostly for error messages.
243*/
244static char *Argv0;
245
246/*
247** Prompt strings. Initialized in main. Settable with
248** .prompt main continue
249*/
250static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
251static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
252
drhb0603412007-02-28 04:47:26 +0000253/*
254** Write I/O traces to the following stream.
255*/
rsebe0a9092007-07-30 18:24:38 +0000256#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000257static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000258#endif
drhb0603412007-02-28 04:47:26 +0000259
260/*
261** This routine works like printf in that its first argument is a
262** format string and subsequent arguments are values to be substituted
263** in place of % fields. The result of formatting this string
264** is written to iotrace.
265*/
rsebe0a9092007-07-30 18:24:38 +0000266#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000267static void iotracePrintf(const char *zFormat, ...){
268 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000269 char *z;
drhb0603412007-02-28 04:47:26 +0000270 if( iotrace==0 ) return;
271 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000272 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000273 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000274 fprintf(iotrace, "%s", z);
275 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000276}
rsebe0a9092007-07-30 18:24:38 +0000277#endif
drhb0603412007-02-28 04:47:26 +0000278
drh44c2eb12003-04-30 11:38:26 +0000279
persicom7e2dfdd2002-04-18 02:46:52 +0000280/*
drh83965662003-04-17 02:54:13 +0000281** Determines if a string is a number of not.
282*/
danielk19772e588c72005-12-09 14:25:08 +0000283static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000284 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000285 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000286 return 0;
287 }
288 z++;
289 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000290 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000291 if( *z=='.' ){
292 z++;
drhf0693c82011-10-11 20:41:54 +0000293 if( !IsDigit(*z) ) return 0;
294 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000295 if( realnum ) *realnum = 1;
296 }
297 if( *z=='e' || *z=='E' ){
298 z++;
299 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000300 if( !IsDigit(*z) ) return 0;
301 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000302 if( realnum ) *realnum = 1;
303 }
304 return *z==0;
305}
drh83965662003-04-17 02:54:13 +0000306
307/*
danielk1977bc6ada42004-06-30 08:20:16 +0000308** A global char* and an SQL function to access its current value
309** from within an SQL statement. This program used to use the
310** sqlite_exec_printf() API to substitue a string into an SQL statement.
311** The correct way to do this with sqlite3 is to use the bind API, but
312** since the shell is built around the callback paradigm it would be a lot
313** of work. Instead just use this hack, which is quite harmless.
314*/
315static const char *zShellStatic = 0;
316static void shellstaticFunc(
317 sqlite3_context *context,
318 int argc,
319 sqlite3_value **argv
320){
321 assert( 0==argc );
322 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000323 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000324 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000325 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
326}
327
328
329/*
drhfeac5f82004-08-01 00:10:45 +0000330** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000331** the text in memory obtained from malloc() and returns a pointer
332** to the text. NULL is returned at end of file, or if malloc()
333** fails.
334**
335** The interface is like "readline" but no command-line editing
336** is done.
337*/
drh18f52e02012-01-16 16:56:31 +0000338static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
drh8e7e7a22000-05-30 18:45:23 +0000339 char *zLine;
340 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000341 int n;
drh18f52e02012-01-16 16:56:31 +0000342 int inQuote = 0;
drh8e7e7a22000-05-30 18:45:23 +0000343
344 if( zPrompt && *zPrompt ){
345 printf("%s",zPrompt);
346 fflush(stdout);
347 }
348 nLine = 100;
349 zLine = malloc( nLine );
350 if( zLine==0 ) return 0;
351 n = 0;
drhb07028f2011-10-14 21:49:18 +0000352 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000353 if( n+100>nLine ){
354 nLine = nLine*2 + 100;
355 zLine = realloc(zLine, nLine);
356 if( zLine==0 ) return 0;
357 }
drhdaffd0e2001-04-11 14:28:42 +0000358 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000359 if( n==0 ){
360 free(zLine);
361 return 0;
362 }
363 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000364 break;
365 }
drh18f52e02012-01-16 16:56:31 +0000366 while( zLine[n] ){
367 if( zLine[n]=='"' ) inQuote = !inQuote;
368 n++;
369 }
370 if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
drh8e7e7a22000-05-30 18:45:23 +0000371 n--;
shaneh13b36022009-12-17 21:07:15 +0000372 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000373 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000374 break;
drh8e7e7a22000-05-30 18:45:23 +0000375 }
376 }
377 zLine = realloc( zLine, n+1 );
378 return zLine;
379}
380
381/*
drhc28490c2006-10-26 14:25:58 +0000382** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000383**
384** zPrior is a string of prior text retrieved. If not the empty
385** string, then issue a continuation prompt.
386*/
drhdaffd0e2001-04-11 14:28:42 +0000387static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000388 char *zPrompt;
389 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000390 if( in!=0 ){
drh18f52e02012-01-16 16:56:31 +0000391 return local_getline(0, in, 0);
drh8e7e7a22000-05-30 18:45:23 +0000392 }
393 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000394 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000395 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000396 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000397 }
398 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000399#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000400 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000401#endif
drh8e7e7a22000-05-30 18:45:23 +0000402 return zResult;
403}
404
persicom7e2dfdd2002-04-18 02:46:52 +0000405struct previous_mode_data {
406 int valid; /* Is there legit data in here? */
407 int mode;
408 int showHeader;
409 int colWidth[100];
410};
drh45e29d82006-11-20 16:21:10 +0000411
drh8e7e7a22000-05-30 18:45:23 +0000412/*
drh75897232000-05-29 14:26:00 +0000413** An pointer to an instance of this structure is passed from
414** the main program to the callback. This is used to communicate
415** state and mode information.
416*/
417struct callback_data {
shane626a6e42009-10-22 17:30:15 +0000418 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000419 int echoOn; /* True to echo input commands */
shaneh642d8b82010-07-28 16:05:34 +0000420 int statsOn; /* True to display memory stats before each finalize */
drh28bd4bc2000-06-15 15:57:22 +0000421 int cnt; /* Number of records displayed so far */
422 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000423 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000424 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000425 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000426 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000427 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000428 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000429 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000430 int colWidth[100]; /* Requested width of each column when in column mode*/
431 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000432 char nullvalue[20]; /* The text to print when a NULL comes back from
433 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000434 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000435 /* Holds the mode information just before
436 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000437 char outfile[FILENAME_MAX]; /* Filename for *out */
438 const char *zDbFilename; /* name of the database file */
drha7e61d82011-03-12 17:02:57 +0000439 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000440 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000441 FILE *pLog; /* Write log output here */
drh75897232000-05-29 14:26:00 +0000442};
443
444/*
445** These are the allowed modes.
446*/
drh967e8b72000-06-21 13:59:10 +0000447#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000448#define MODE_Column 1 /* One record per line in neat columns */
449#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000450#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
451#define MODE_Html 4 /* Generate an XHTML table */
452#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000453#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000454#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000455#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000456
drh66ce4d02008-02-15 17:38:06 +0000457static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000458 "line",
459 "column",
460 "list",
461 "semi",
462 "html",
drhfeac5f82004-08-01 00:10:45 +0000463 "insert",
464 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000465 "csv",
drh66ce4d02008-02-15 17:38:06 +0000466 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000467};
drh75897232000-05-29 14:26:00 +0000468
469/*
470** Number of elements in an array
471*/
drh902b9ee2008-12-05 17:17:07 +0000472#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000473
474/*
drhea678832008-12-10 19:26:22 +0000475** Compute a string length that is limited to what can be stored in
476** lower 30 bits of a 32-bit signed integer.
477*/
drh4f21c4a2008-12-10 22:15:00 +0000478static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000479 const char *z2 = z;
480 while( *z2 ){ z2++; }
481 return 0x3fffffff & (int)(z2 - z);
482}
483
484/*
drh127f9d72010-02-23 01:47:00 +0000485** A callback for the sqlite3_log() interface.
486*/
487static void shellLog(void *pArg, int iErrCode, const char *zMsg){
488 struct callback_data *p = (struct callback_data*)pArg;
489 if( p->pLog==0 ) return;
490 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
491 fflush(p->pLog);
492}
493
494/*
shane626a6e42009-10-22 17:30:15 +0000495** Output the given string as a hex-encoded blob (eg. X'1234' )
496*/
497static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
498 int i;
499 char *zBlob = (char *)pBlob;
500 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000501 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000502 fprintf(out,"'");
503}
504
505/*
drh28bd4bc2000-06-15 15:57:22 +0000506** Output the given string as a quoted string using SQL quoting conventions.
507*/
508static void output_quoted_string(FILE *out, const char *z){
509 int i;
510 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000511 for(i=0; z[i]; i++){
512 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000513 }
514 if( nSingle==0 ){
515 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000516 }else{
517 fprintf(out,"'");
518 while( *z ){
519 for(i=0; z[i] && z[i]!='\''; i++){}
520 if( i==0 ){
521 fprintf(out,"''");
522 z++;
523 }else if( z[i]=='\'' ){
524 fprintf(out,"%.*s''",i,z);
525 z += i+1;
526 }else{
drhcd7d2732002-02-26 23:24:26 +0000527 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000528 break;
529 }
530 }
drhcd7d2732002-02-26 23:24:26 +0000531 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000532 }
533}
534
535/*
drhfeac5f82004-08-01 00:10:45 +0000536** Output the given string as a quoted according to C or TCL quoting rules.
537*/
538static void output_c_string(FILE *out, const char *z){
539 unsigned int c;
540 fputc('"', out);
541 while( (c = *(z++))!=0 ){
542 if( c=='\\' ){
543 fputc(c, out);
544 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000545 }else if( c=='"' ){
546 fputc('\\', out);
547 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000548 }else if( c=='\t' ){
549 fputc('\\', out);
550 fputc('t', out);
551 }else if( c=='\n' ){
552 fputc('\\', out);
553 fputc('n', out);
554 }else if( c=='\r' ){
555 fputc('\\', out);
556 fputc('r', out);
557 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000558 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000559 }else{
560 fputc(c, out);
561 }
562 }
563 fputc('"', out);
564}
565
566/*
drhc08a4f12000-06-15 16:49:48 +0000567** Output the given string with characters that are special to
568** HTML escaped.
569*/
570static void output_html_string(FILE *out, const char *z){
571 int i;
572 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000573 for(i=0; z[i]
574 && z[i]!='<'
575 && z[i]!='&'
576 && z[i]!='>'
577 && z[i]!='\"'
578 && z[i]!='\'';
579 i++){}
drhc08a4f12000-06-15 16:49:48 +0000580 if( i>0 ){
581 fprintf(out,"%.*s",i,z);
582 }
583 if( z[i]=='<' ){
584 fprintf(out,"&lt;");
585 }else if( z[i]=='&' ){
586 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000587 }else if( z[i]=='>' ){
588 fprintf(out,"&gt;");
589 }else if( z[i]=='\"' ){
590 fprintf(out,"&quot;");
591 }else if( z[i]=='\'' ){
592 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000593 }else{
594 break;
595 }
596 z += i + 1;
597 }
598}
599
600/*
drhc49f44e2006-10-26 18:15:42 +0000601** If a field contains any character identified by a 1 in the following
602** array, then the string must be quoted for CSV.
603*/
604static const char needCsvQuote[] = {
605 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
606 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
607 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
608 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
609 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
610 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
611 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
612 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
613 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
614 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
615 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
616 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
617 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
618 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
619 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
620 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
621};
622
623/*
drh8e64d1c2004-10-07 00:32:39 +0000624** Output a single term of CSV. Actually, p->separator is used for
625** the separator, which may or may not be a comma. p->nullvalue is
drh18f52e02012-01-16 16:56:31 +0000626** the null value. Strings are quoted if necessary.
drh8e64d1c2004-10-07 00:32:39 +0000627*/
628static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000629 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000630 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000631 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000632 }else{
drhc49f44e2006-10-26 18:15:42 +0000633 int i;
drh4f21c4a2008-12-10 22:15:00 +0000634 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000635 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000636 if( needCsvQuote[((unsigned char*)z)[i]]
637 || (z[i]==p->separator[0] &&
638 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000639 i = 0;
640 break;
641 }
642 }
643 if( i==0 ){
644 putc('"', out);
645 for(i=0; z[i]; i++){
646 if( z[i]=='"' ) putc('"', out);
647 putc(z[i], out);
648 }
649 putc('"', out);
650 }else{
651 fprintf(out, "%s", z);
652 }
drh8e64d1c2004-10-07 00:32:39 +0000653 }
654 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000655 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000656 }
657}
658
danielk19774af00c62005-01-23 23:43:21 +0000659#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000660/*
drh4c504392000-10-16 22:06:40 +0000661** This routine runs when the user presses Ctrl-C
662*/
663static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000664 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000665 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000666 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000667}
danielk19774af00c62005-01-23 23:43:21 +0000668#endif
drh4c504392000-10-16 22:06:40 +0000669
670/*
shane626a6e42009-10-22 17:30:15 +0000671** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000672** invokes for each row of a query result.
673*/
shane626a6e42009-10-22 17:30:15 +0000674static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
drh75897232000-05-29 14:26:00 +0000675 int i;
676 struct callback_data *p = (struct callback_data*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000677
drh75897232000-05-29 14:26:00 +0000678 switch( p->mode ){
679 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000680 int w = 5;
drh6a535342001-10-19 16:44:56 +0000681 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000682 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000683 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000684 if( len>w ) w = len;
685 }
drh75897232000-05-29 14:26:00 +0000686 if( p->cnt++>0 ) fprintf(p->out,"\n");
687 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000688 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000689 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000690 }
691 break;
692 }
danielk19770d78bae2008-01-03 07:09:48 +0000693 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000694 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000695 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000696 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000697 int w, n;
698 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000699 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000700 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000701 w = 0;
drh75897232000-05-29 14:26:00 +0000702 }
drh078b1fd2012-09-21 13:40:02 +0000703 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000704 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000705 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000706 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000707 if( w<n ) w = n;
708 }
709 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000710 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000711 }
712 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000713 if( w<0 ){
714 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
715 }else{
716 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
717 }
drha0c66f52000-07-29 13:20:21 +0000718 }
719 }
720 if( p->showHeader ){
721 for(i=0; i<nArg; i++){
722 int w;
723 if( i<ArraySize(p->actualWidth) ){
724 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000725 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000726 }else{
727 w = 10;
728 }
729 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
730 "----------------------------------------------------------",
731 i==nArg-1 ? "\n": " ");
732 }
drh75897232000-05-29 14:26:00 +0000733 }
734 }
drh6a535342001-10-19 16:44:56 +0000735 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000736 for(i=0; i<nArg; i++){
737 int w;
drha0c66f52000-07-29 13:20:21 +0000738 if( i<ArraySize(p->actualWidth) ){
739 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000740 }else{
741 w = 10;
742 }
drhea678832008-12-10 19:26:22 +0000743 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000744 strlen30(azArg[i])>w ){
745 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000746 }
drh078b1fd2012-09-21 13:40:02 +0000747 if( w<0 ){
748 fprintf(p->out,"%*.*s%s",-w,-w,
749 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
750 }else{
751 fprintf(p->out,"%-*.*s%s",w,w,
752 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
753 }
drh75897232000-05-29 14:26:00 +0000754 }
755 break;
756 }
drhe3710332000-09-29 13:30:53 +0000757 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000758 case MODE_List: {
759 if( p->cnt++==0 && p->showHeader ){
760 for(i=0; i<nArg; i++){
761 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
762 }
763 }
drh6a535342001-10-19 16:44:56 +0000764 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000765 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000766 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000767 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000768 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000769 if( i<nArg-1 ){
770 fprintf(p->out, "%s", p->separator);
771 }else if( p->mode==MODE_Semi ){
772 fprintf(p->out, ";\n");
773 }else{
774 fprintf(p->out, "\n");
775 }
drh75897232000-05-29 14:26:00 +0000776 }
777 break;
778 }
drh1e5d0e92000-05-31 23:33:17 +0000779 case MODE_Html: {
780 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000781 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000782 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000783 fprintf(p->out,"<TH>");
784 output_html_string(p->out, azCol[i]);
785 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000786 }
mihailim57c591a2008-06-23 21:26:05 +0000787 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000788 }
drh6a535342001-10-19 16:44:56 +0000789 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000790 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000791 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000792 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000793 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000794 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000795 }
mihailim57c591a2008-06-23 21:26:05 +0000796 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000797 break;
798 }
drhfeac5f82004-08-01 00:10:45 +0000799 case MODE_Tcl: {
800 if( p->cnt++==0 && p->showHeader ){
801 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000802 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin585dcb22012-12-04 00:23:43 +0000803 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000804 }
805 fprintf(p->out,"\n");
806 }
807 if( azArg==0 ) break;
808 for(i=0; i<nArg; i++){
809 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mistachkin585dcb22012-12-04 00:23:43 +0000810 if(i<nArg-1) fprintf(p->out, "%s", p->separator);
drhfeac5f82004-08-01 00:10:45 +0000811 }
812 fprintf(p->out,"\n");
813 break;
814 }
drh8e64d1c2004-10-07 00:32:39 +0000815 case MODE_Csv: {
816 if( p->cnt++==0 && p->showHeader ){
817 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000818 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000819 }
820 fprintf(p->out,"\n");
821 }
822 if( azArg==0 ) break;
823 for(i=0; i<nArg; i++){
824 output_csv(p, azArg[i], i<nArg-1);
825 }
826 fprintf(p->out,"\n");
827 break;
828 }
drh28bd4bc2000-06-15 15:57:22 +0000829 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000830 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000831 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000832 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000833 for(i=0; i<nArg; i++){
834 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000835 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000836 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000837 }else if( aiType && aiType[i]==SQLITE_TEXT ){
838 if( zSep[0] ) fprintf(p->out,"%s",zSep);
839 output_quoted_string(p->out, azArg[i]);
840 }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
841 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000842 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
843 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
844 int nBlob = sqlite3_column_bytes(p->pStmt, i);
845 if( zSep[0] ) fprintf(p->out,"%s",zSep);
846 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000847 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000848 fprintf(p->out,"%s%s",zSep, azArg[i]);
849 }else{
850 if( zSep[0] ) fprintf(p->out,"%s",zSep);
851 output_quoted_string(p->out, azArg[i]);
852 }
853 }
854 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000855 break;
drh28bd4bc2000-06-15 15:57:22 +0000856 }
persicom1d0b8722002-04-18 02:53:04 +0000857 }
drh75897232000-05-29 14:26:00 +0000858 return 0;
859}
860
861/*
shane626a6e42009-10-22 17:30:15 +0000862** This is the callback routine that the SQLite library
863** invokes for each row of a query result.
864*/
865static int callback(void *pArg, int nArg, char **azArg, char **azCol){
866 /* since we don't have type info, call the shell_callback with a NULL value */
867 return shell_callback(pArg, nArg, azArg, azCol, NULL);
868}
869
870/*
drh33048c02001-10-01 14:29:22 +0000871** Set the destination table field of the callback_data structure to
872** the name of the table given. Escape any quote characters in the
873** table name.
874*/
875static void set_table_name(struct callback_data *p, const char *zName){
876 int i, n;
877 int needQuote;
878 char *z;
879
880 if( p->zDestTable ){
881 free(p->zDestTable);
882 p->zDestTable = 0;
883 }
884 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000885 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000886 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000887 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000888 needQuote = 1;
889 if( zName[i]=='\'' ) n++;
890 }
891 }
892 if( needQuote ) n += 2;
893 z = p->zDestTable = malloc( n+1 );
894 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +0000895 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +0000896 exit(1);
897 }
898 n = 0;
899 if( needQuote ) z[n++] = '\'';
900 for(i=0; zName[i]; i++){
901 z[n++] = zName[i];
902 if( zName[i]=='\'' ) z[n++] = '\'';
903 }
904 if( needQuote ) z[n++] = '\'';
905 z[n] = 0;
906}
907
danielk19772a02e332004-06-05 08:04:36 +0000908/* zIn is either a pointer to a NULL-terminated string in memory obtained
909** from malloc(), or a NULL pointer. The string pointed to by zAppend is
910** added to zIn, and the result returned in memory obtained from malloc().
911** zIn, if it was not NULL, is freed.
912**
913** If the third argument, quote, is not '\0', then it is used as a
914** quote character for zAppend.
915*/
drhc28490c2006-10-26 14:25:58 +0000916static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000917 int len;
918 int i;
drh4f21c4a2008-12-10 22:15:00 +0000919 int nAppend = strlen30(zAppend);
920 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000921
922 len = nAppend+nIn+1;
923 if( quote ){
924 len += 2;
925 for(i=0; i<nAppend; i++){
926 if( zAppend[i]==quote ) len++;
927 }
928 }
929
930 zIn = (char *)realloc(zIn, len);
931 if( !zIn ){
932 return 0;
933 }
934
935 if( quote ){
936 char *zCsr = &zIn[nIn];
937 *zCsr++ = quote;
938 for(i=0; i<nAppend; i++){
939 *zCsr++ = zAppend[i];
940 if( zAppend[i]==quote ) *zCsr++ = quote;
941 }
942 *zCsr++ = quote;
943 *zCsr++ = '\0';
944 assert( (zCsr-zIn)==len );
945 }else{
946 memcpy(&zIn[nIn], zAppend, nAppend);
947 zIn[len-1] = '\0';
948 }
949
950 return zIn;
951}
952
drhdd3d4592004-08-30 01:54:05 +0000953
954/*
drhb21a8e42012-01-28 21:08:51 +0000955** Execute a query statement that will generate SQL output. Print
956** the result columns, comma-separated, on a line and then add a
957** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +0000958**
drhb21a8e42012-01-28 21:08:51 +0000959** If the number of columns is 1 and that column contains text "--"
960** then write the semicolon on a separate line. That way, if a
961** "--" comment occurs at the end of the statement, the comment
962** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +0000963*/
drh157e29a2009-05-21 15:15:00 +0000964static int run_table_dump_query(
drh2f464a02011-10-13 00:41:49 +0000965 struct callback_data *p, /* Query context */
966 const char *zSelect, /* SELECT statement to extract content */
967 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +0000968){
drhdd3d4592004-08-30 01:54:05 +0000969 sqlite3_stmt *pSelect;
970 int rc;
drhb21a8e42012-01-28 21:08:51 +0000971 int nResult;
972 int i;
973 const char *z;
drh2f464a02011-10-13 00:41:49 +0000974 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +0000975 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +0000976 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
977 p->nErr++;
drhdd3d4592004-08-30 01:54:05 +0000978 return rc;
979 }
980 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +0000981 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +0000982 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +0000983 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +0000984 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +0000985 zFirstRow = 0;
986 }
drhb21a8e42012-01-28 21:08:51 +0000987 z = (const char*)sqlite3_column_text(pSelect, 0);
988 fprintf(p->out, "%s", z);
989 for(i=1; i<nResult; i++){
990 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
991 }
992 if( z==0 ) z = "";
993 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
994 if( z[0] ){
995 fprintf(p->out, "\n;\n");
996 }else{
997 fprintf(p->out, ";\n");
998 }
drhdd3d4592004-08-30 01:54:05 +0000999 rc = sqlite3_step(pSelect);
1000 }
drh2f464a02011-10-13 00:41:49 +00001001 rc = sqlite3_finalize(pSelect);
1002 if( rc!=SQLITE_OK ){
1003 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
1004 p->nErr++;
1005 }
1006 return rc;
drhdd3d4592004-08-30 01:54:05 +00001007}
1008
shane626a6e42009-10-22 17:30:15 +00001009/*
1010** Allocate space and save off current error string.
1011*/
1012static char *save_err_msg(
1013 sqlite3 *db /* Database to query */
1014){
1015 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1016 char *zErrMsg = sqlite3_malloc(nErrMsg);
1017 if( zErrMsg ){
1018 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1019 }
1020 return zErrMsg;
1021}
1022
1023/*
shaneh642d8b82010-07-28 16:05:34 +00001024** Display memory stats.
1025*/
1026static int display_stats(
1027 sqlite3 *db, /* Database to query */
1028 struct callback_data *pArg, /* Pointer to struct callback_data */
1029 int bReset /* True to reset the stats */
1030){
1031 int iCur;
1032 int iHiwtr;
1033
1034 if( pArg && pArg->out ){
1035
1036 iHiwtr = iCur = -1;
1037 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh29dfbe32010-07-28 17:01:24 +00001038 fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001039 iHiwtr = iCur = -1;
1040 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh2a58e9c2010-12-21 21:28:38 +00001041 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001042/*
1043** Not currently used by the CLI.
1044** iHiwtr = iCur = -1;
1045** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1046** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1047*/
1048 iHiwtr = iCur = -1;
1049 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1050 fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1051/*
1052** Not currently used by the CLI.
1053** iHiwtr = iCur = -1;
1054** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1055** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1056*/
1057 iHiwtr = iCur = -1;
1058 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1059 fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1060 iHiwtr = iCur = -1;
1061 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1062 fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1063 iHiwtr = iCur = -1;
1064 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1065 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1066 iHiwtr = iCur = -1;
1067 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1068 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1069#ifdef YYTRACKMAXSTACKDEPTH
1070 iHiwtr = iCur = -1;
1071 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1072 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1073#endif
1074 }
1075
1076 if( pArg && pArg->out && db ){
1077 iHiwtr = iCur = -1;
1078 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1079 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
drh2a58e9c2010-12-21 21:28:38 +00001080 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1081 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1082 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1083 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1084 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1085 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001086 iHiwtr = iCur = -1;
1087 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drhc78e6e42011-09-23 18:58:23 +00001088 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1089 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1090 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1091 iHiwtr = iCur = -1;
1092 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1093 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001094 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001095 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1096 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1097 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001098 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1099 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1100 iHiwtr = iCur = -1;
1101 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1102 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1103 }
1104
1105 if( pArg && pArg->out && db && pArg->pStmt ){
1106 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1107 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1108 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1109 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1110 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1111 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001112 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1113 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001114 }
1115
1116 return 0;
1117}
1118
1119/*
shane626a6e42009-10-22 17:30:15 +00001120** Execute a statement or set of statements. Print
1121** any result rows/columns depending on the current mode
1122** set via the supplied callback.
1123**
1124** This is very similar to SQLite's built-in sqlite3_exec()
1125** function except it takes a slightly different callback
1126** and callback data argument.
1127*/
1128static int shell_exec(
1129 sqlite3 *db, /* An open database */
1130 const char *zSql, /* SQL to be evaluated */
1131 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1132 /* (not the same as sqlite3_exec) */
1133 struct callback_data *pArg, /* Pointer to struct callback_data */
1134 char **pzErrMsg /* Error msg written here */
1135){
dan4564ced2010-01-05 04:59:56 +00001136 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1137 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001138 int rc2;
dan4564ced2010-01-05 04:59:56 +00001139 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001140
1141 if( pzErrMsg ){
1142 *pzErrMsg = NULL;
1143 }
1144
shaneb9fc17d2009-10-22 21:23:35 +00001145 while( zSql[0] && (SQLITE_OK == rc) ){
1146 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1147 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001148 if( pzErrMsg ){
1149 *pzErrMsg = save_err_msg(db);
1150 }
1151 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001152 if( !pStmt ){
1153 /* this happens for a comment or white-space */
1154 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001155 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001156 continue;
1157 }
shane626a6e42009-10-22 17:30:15 +00001158
shaneh642d8b82010-07-28 16:05:34 +00001159 /* save off the prepared statment handle and reset row count */
1160 if( pArg ){
1161 pArg->pStmt = pStmt;
1162 pArg->cnt = 0;
1163 }
1164
shanehb7977c52010-01-18 18:17:10 +00001165 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001166 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001167 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001168 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001169 }
shanehb7977c52010-01-18 18:17:10 +00001170
drh7e02e5e2011-12-06 19:44:51 +00001171 /* Output TESTCTRL_EXPLAIN text of requested */
1172 if( pArg && pArg->mode==MODE_Explain ){
1173 const char *zExplain = 0;
1174 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1175 if( zExplain && zExplain[0] ){
1176 fprintf(pArg->out, "%s", zExplain);
1177 }
1178 }
1179
shaneb9fc17d2009-10-22 21:23:35 +00001180 /* perform the first step. this will tell us if we
1181 ** have a result set or not and how wide it is.
1182 */
1183 rc = sqlite3_step(pStmt);
1184 /* if we have a result set... */
1185 if( SQLITE_ROW == rc ){
1186 /* if we have a callback... */
1187 if( xCallback ){
1188 /* allocate space for col name ptr, value ptr, and type */
1189 int nCol = sqlite3_column_count(pStmt);
1190 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1191 if( !pData ){
1192 rc = SQLITE_NOMEM;
1193 }else{
1194 char **azCols = (char **)pData; /* Names of result columns */
1195 char **azVals = &azCols[nCol]; /* Results */
1196 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1197 int i;
1198 assert(sizeof(int) <= sizeof(char *));
1199 /* save off ptrs to column names */
1200 for(i=0; i<nCol; i++){
1201 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1202 }
shaneb9fc17d2009-10-22 21:23:35 +00001203 do{
1204 /* extract the data and data types */
1205 for(i=0; i<nCol; i++){
1206 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1207 aiTypes[i] = sqlite3_column_type(pStmt, i);
1208 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1209 rc = SQLITE_NOMEM;
1210 break; /* from for */
1211 }
1212 } /* end for */
1213
1214 /* if data and types extracted successfully... */
1215 if( SQLITE_ROW == rc ){
1216 /* call the supplied callback with the result row data */
1217 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1218 rc = SQLITE_ABORT;
1219 }else{
1220 rc = sqlite3_step(pStmt);
1221 }
1222 }
1223 } while( SQLITE_ROW == rc );
1224 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001225 }
1226 }else{
1227 do{
1228 rc = sqlite3_step(pStmt);
1229 } while( rc == SQLITE_ROW );
1230 }
1231 }
1232
shaneh642d8b82010-07-28 16:05:34 +00001233 /* print usage stats if stats on */
1234 if( pArg && pArg->statsOn ){
1235 display_stats(db, pArg, 0);
1236 }
1237
dan4564ced2010-01-05 04:59:56 +00001238 /* Finalize the statement just executed. If this fails, save a
1239 ** copy of the error message. Otherwise, set zSql to point to the
1240 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001241 rc2 = sqlite3_finalize(pStmt);
1242 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001243 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001244 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001245 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001246 }else if( pzErrMsg ){
1247 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001248 }
shaneh642d8b82010-07-28 16:05:34 +00001249
1250 /* clear saved stmt handle */
1251 if( pArg ){
1252 pArg->pStmt = NULL;
1253 }
shane626a6e42009-10-22 17:30:15 +00001254 }
shaneb9fc17d2009-10-22 21:23:35 +00001255 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001256
1257 return rc;
1258}
1259
drhdd3d4592004-08-30 01:54:05 +00001260
drh33048c02001-10-01 14:29:22 +00001261/*
drh4c653a02000-06-07 01:27:47 +00001262** This is a different callback routine used for dumping the database.
1263** Each row received by this callback consists of a table name,
1264** the table type ("index" or "table") and SQL to create the table.
1265** This routine should print text sufficient to recreate the table.
1266*/
1267static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001268 int rc;
1269 const char *zTable;
1270 const char *zType;
1271 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001272 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001273 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001274
drh902b9ee2008-12-05 17:17:07 +00001275 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001276 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001277 zTable = azArg[0];
1278 zType = azArg[1];
1279 zSql = azArg[2];
1280
drh00b950d2005-09-11 02:03:03 +00001281 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001282 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001283 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1284 fprintf(p->out, "ANALYZE sqlite_master;\n");
1285 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1286 return 0;
drh45e29d82006-11-20 16:21:10 +00001287 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1288 char *zIns;
1289 if( !p->writableSchema ){
1290 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1291 p->writableSchema = 1;
1292 }
1293 zIns = sqlite3_mprintf(
1294 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1295 "VALUES('table','%q','%q',0,'%q');",
1296 zTable, zTable, zSql);
1297 fprintf(p->out, "%s\n", zIns);
1298 sqlite3_free(zIns);
1299 return 0;
drh00b950d2005-09-11 02:03:03 +00001300 }else{
1301 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001302 }
danielk19772a02e332004-06-05 08:04:36 +00001303
1304 if( strcmp(zType, "table")==0 ){
1305 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001306 char *zSelect = 0;
1307 char *zTableInfo = 0;
1308 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001309 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001310
1311 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1312 zTableInfo = appendText(zTableInfo, zTable, '"');
1313 zTableInfo = appendText(zTableInfo, ");", 0);
1314
1315 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001316 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001317 if( rc!=SQLITE_OK || !pTableInfo ){
1318 return 1;
1319 }
1320
1321 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001322 /* Always quote the table name, even if it appears to be pure ascii,
1323 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1324 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001325 if( zTmp ){
1326 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001327 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001328 }
1329 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1330 rc = sqlite3_step(pTableInfo);
1331 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001332 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001333 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001334 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001335 rc = sqlite3_step(pTableInfo);
1336 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001337 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001338 }else{
1339 zSelect = appendText(zSelect, ") ", 0);
1340 }
drh157e29a2009-05-21 15:15:00 +00001341 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001342 }
1343 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001344 if( rc!=SQLITE_OK || nRow==0 ){
1345 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001346 return 1;
1347 }
1348 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1349 zSelect = appendText(zSelect, zTable, '"');
1350
drh2f464a02011-10-13 00:41:49 +00001351 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001352 if( rc==SQLITE_CORRUPT ){
1353 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001354 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001355 }
drh85e72432012-04-11 11:38:53 +00001356 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001357 }
drh4c653a02000-06-07 01:27:47 +00001358 return 0;
1359}
1360
1361/*
drh45e29d82006-11-20 16:21:10 +00001362** Run zQuery. Use dump_callback() as the callback routine so that
1363** the contents of the query are output as SQL statements.
1364**
drhdd3d4592004-08-30 01:54:05 +00001365** If we get a SQLITE_CORRUPT error, rerun the query after appending
1366** "ORDER BY rowid DESC" to the end.
1367*/
1368static int run_schema_dump_query(
1369 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001370 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001371){
1372 int rc;
drh2f464a02011-10-13 00:41:49 +00001373 char *zErr = 0;
1374 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001375 if( rc==SQLITE_CORRUPT ){
1376 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001377 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001378 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1379 if( zErr ){
1380 fprintf(p->out, "/****** %s ******/\n", zErr);
1381 sqlite3_free(zErr);
1382 zErr = 0;
1383 }
drhdd3d4592004-08-30 01:54:05 +00001384 zQ2 = malloc( len+100 );
1385 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001386 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001387 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1388 if( rc ){
1389 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1390 }else{
1391 rc = SQLITE_CORRUPT;
1392 }
1393 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001394 free(zQ2);
1395 }
1396 return rc;
1397}
1398
1399/*
drh75897232000-05-29 14:26:00 +00001400** Text of a help message
1401*/
persicom1d0b8722002-04-18 02:53:04 +00001402static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001403 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001404 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001405 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001406 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001407 " If TABLE specified, only dump tables matching\n"
1408 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001409 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001410 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001411 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1412 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001413 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001414 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001415 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001416 ".indices ?TABLE? Show names of all indices\n"
1417 " If TABLE specified, only show indices for tables\n"
1418 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001419#ifdef SQLITE_ENABLE_IOTRACE
1420 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1421#endif
drh70df4fe2006-06-13 15:12:21 +00001422#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001423 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001424#endif
drh127f9d72010-02-23 01:47:00 +00001425 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001426 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001427 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001428 " column Left-aligned columns. (See .width)\n"
1429 " html HTML <table> code\n"
1430 " insert SQL insert statements for TABLE\n"
1431 " line One value per line\n"
1432 " list Values delimited by .separator string\n"
1433 " tabs Tab-separated values\n"
1434 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001435 ".nullvalue STRING Use STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001436 ".output FILENAME Send output to FILENAME\n"
1437 ".output stdout Send output to the screen\n"
drh078b1fd2012-09-21 13:40:02 +00001438 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001439 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001440 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001441 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001442 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001443 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001444 " If TABLE specified, only show tables matching\n"
1445 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001446 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001447 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001448 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001449 ".tables ?TABLE? List names of tables\n"
1450 " If TABLE specified, only list tables matching\n"
1451 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001452 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001453 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001454 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001455 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001456;
1457
shaneb320ccd2009-10-21 03:42:58 +00001458static char zTimerHelp[] =
1459 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1460;
1461
drhdaffd0e2001-04-11 14:28:42 +00001462/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001463static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001464
drh75897232000-05-29 14:26:00 +00001465/*
drh44c2eb12003-04-30 11:38:26 +00001466** Make sure the database is open. If it is not, then open it. If
1467** the database fails to open, print an error message and exit.
1468*/
1469static void open_db(struct callback_data *p){
1470 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001471 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001472 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001473 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001474 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1475 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1476 shellstaticFunc, 0, 0);
1477 }
1478 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001479 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001480 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001481 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001482 }
drhc2e87a32006-06-27 15:16:14 +00001483#ifndef SQLITE_OMIT_LOAD_EXTENSION
1484 sqlite3_enable_load_extension(p->db, 1);
1485#endif
drh44c2eb12003-04-30 11:38:26 +00001486 }
1487}
1488
1489/*
drhfeac5f82004-08-01 00:10:45 +00001490** Do C-language style dequoting.
1491**
1492** \t -> tab
1493** \n -> newline
1494** \r -> carriage return
1495** \NNN -> ascii character NNN in octal
1496** \\ -> backslash
1497*/
1498static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001499 int i, j;
1500 char c;
drhfeac5f82004-08-01 00:10:45 +00001501 for(i=j=0; (c = z[i])!=0; i++, j++){
1502 if( c=='\\' ){
1503 c = z[++i];
1504 if( c=='n' ){
1505 c = '\n';
1506 }else if( c=='t' ){
1507 c = '\t';
1508 }else if( c=='r' ){
1509 c = '\r';
1510 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001511 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001512 if( z[i+1]>='0' && z[i+1]<='7' ){
1513 i++;
1514 c = (c<<3) + z[i] - '0';
1515 if( z[i+1]>='0' && z[i+1]<='7' ){
1516 i++;
1517 c = (c<<3) + z[i] - '0';
1518 }
1519 }
1520 }
1521 }
1522 z[j] = c;
1523 }
1524 z[j] = 0;
1525}
1526
1527/*
drh348d19c2013-06-03 12:47:43 +00001528** Return the value of a hexadecimal digit. Return -1 if the input
1529** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001530*/
drh348d19c2013-06-03 12:47:43 +00001531static int hexDigitValue(char c){
1532 if( c>='0' && c<='9' ) return c - '0';
1533 if( c>='a' && c<='f' ) return c - 'a' + 10;
1534 if( c>='A' && c<='F' ) return c - 'A' + 10;
1535 return -1;
drhc28490c2006-10-26 14:25:58 +00001536}
1537
1538/*
drh7d9f3942013-04-03 01:26:54 +00001539** Interpret zArg as an integer value, possibly with suffixes.
1540*/
1541static sqlite3_int64 integerValue(const char *zArg){
1542 sqlite3_int64 v = 0;
1543 static const struct { char *zSuffix; int iMult; } aMult[] = {
1544 { "KiB", 1024 },
1545 { "MiB", 1024*1024 },
1546 { "GiB", 1024*1024*1024 },
1547 { "KB", 1000 },
1548 { "MB", 1000000 },
1549 { "GB", 1000000000 },
1550 { "K", 1000 },
1551 { "M", 1000000 },
1552 { "G", 1000000000 },
1553 };
1554 int i;
1555 int isNeg = 0;
1556 if( zArg[0]=='-' ){
1557 isNeg = 1;
1558 zArg++;
1559 }else if( zArg[0]=='+' ){
1560 zArg++;
1561 }
drh348d19c2013-06-03 12:47:43 +00001562 if( zArg[0]=='0' && zArg[1]=='x' ){
1563 int x;
1564 zArg += 2;
1565 while( (x = hexDigitValue(zArg[0]))>=0 ){
1566 v = (v<<4) + x;
1567 zArg++;
1568 }
1569 }else{
1570 while( IsDigit(zArg[0]) ){
1571 v = v*10 + zArg[0] - '0';
1572 zArg++;
1573 }
drh7d9f3942013-04-03 01:26:54 +00001574 }
drhc2bed0a2013-05-24 11:57:50 +00001575 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001576 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1577 v *= aMult[i].iMult;
1578 break;
1579 }
1580 }
1581 return isNeg? -v : v;
1582}
1583
1584/*
drh348d19c2013-06-03 12:47:43 +00001585** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1586** for TRUE and FALSE. Return the integer value if appropriate.
1587*/
1588static int booleanValue(char *zArg){
1589 int i;
1590 if( zArg[0]=='0' && zArg[1]=='x' ){
1591 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1592 }else{
1593 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1594 }
1595 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1596 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1597 return 1;
1598 }
1599 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1600 return 0;
1601 }
1602 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1603 zArg);
1604 return 0;
1605}
1606
1607/*
drh42f64e52012-04-04 16:56:23 +00001608** Close an output file, assuming it is not stderr or stdout
1609*/
1610static void output_file_close(FILE *f){
1611 if( f && f!=stdout && f!=stderr ) fclose(f);
1612}
1613
1614/*
1615** Try to open an output file. The names "stdout" and "stderr" are
1616** recognized and do the right thing. NULL is returned if the output
1617** filename is "off".
1618*/
1619static FILE *output_file_open(const char *zFile){
1620 FILE *f;
1621 if( strcmp(zFile,"stdout")==0 ){
1622 f = stdout;
1623 }else if( strcmp(zFile, "stderr")==0 ){
1624 f = stderr;
1625 }else if( strcmp(zFile, "off")==0 ){
1626 f = 0;
1627 }else{
1628 f = fopen(zFile, "wb");
1629 if( f==0 ){
1630 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1631 }
1632 }
1633 return f;
1634}
1635
1636/*
1637** A routine for handling output from sqlite3_trace().
1638*/
1639static void sql_trace_callback(void *pArg, const char *z){
1640 FILE *f = (FILE*)pArg;
1641 if( f ) fprintf(f, "%s\n", z);
1642}
1643
1644/*
drhd8621b92012-04-17 09:09:33 +00001645** A no-op routine that runs with the ".breakpoint" doc-command. This is
1646** a useful spot to set a debugger breakpoint.
1647*/
1648static void test_breakpoint(void){
1649 static int nCall = 0;
1650 nCall++;
1651}
1652
1653/*
drhdb95f682013-06-26 22:46:00 +00001654** An object used to read a CSV file
1655*/
1656typedef struct CSVReader CSVReader;
1657struct CSVReader {
1658 const char *zFile; /* Name of the input file */
1659 FILE *in; /* Read the CSV text from this input stream */
1660 char *z; /* Accumulated text for a field */
1661 int n; /* Number of bytes in z */
1662 int nAlloc; /* Space allocated for z[] */
1663 int nLine; /* Current line number */
1664 int cTerm; /* Character that terminated the most recent field */
1665 int cSeparator; /* The separator character. (Usually ",") */
1666};
1667
1668/* Append a single byte to z[] */
1669static void csv_append_char(CSVReader *p, int c){
1670 if( p->n+1>=p->nAlloc ){
1671 p->nAlloc += p->nAlloc + 100;
1672 p->z = sqlite3_realloc(p->z, p->nAlloc);
1673 if( p->z==0 ){
1674 fprintf(stderr, "out of memory\n");
1675 exit(1);
1676 }
1677 }
1678 p->z[p->n++] = (char)c;
1679}
1680
1681/* Read a single field of CSV text. Compatible with rfc4180 and extended
1682** with the option of having a separator other than ",".
1683**
1684** + Input comes from p->in.
1685** + Store results in p->z of length p->n. Space to hold p->z comes
1686** from sqlite3_malloc().
1687** + Use p->cSep as the separator. The default is ",".
1688** + Keep track of the line number in p->nLine.
1689** + Store the character that terminates the field in p->cTerm. Store
1690** EOF on end-of-file.
1691** + Report syntax errors on stderr
1692*/
1693static char *csv_read_one_field(CSVReader *p){
1694 int c, pc;
1695 int cSep = p->cSeparator;
1696 p->n = 0;
1697 c = fgetc(p->in);
1698 if( c==EOF || seenInterrupt ){
1699 p->cTerm = EOF;
1700 return 0;
1701 }
1702 if( c=='"' ){
1703 int startLine = p->nLine;
1704 int cQuote = c;
1705 pc = 0;
1706 while( 1 ){
1707 c = fgetc(p->in);
1708 if( c=='\n' ) p->nLine++;
1709 if( c==cQuote ){
1710 if( pc==cQuote ){
1711 pc = 0;
1712 continue;
1713 }
1714 }
1715 if( (c==cSep && pc==cQuote)
1716 || (c=='\n' && pc==cQuote)
1717 || (c=='\n' && pc=='\r' && p->n>2 && p->z[p->n-2]==cQuote)
1718 || (c==EOF && pc==cQuote)
1719 ){
1720 do{ p->n--; }while( p->z[p->n]!=cQuote );
1721 p->z[p->n] = 0;
1722 p->cTerm = c;
1723 break;
1724 }
1725 if( pc==cQuote && c!='\r' ){
1726 fprintf(stderr, "%s:%d: unescaped %c character\n",
1727 p->zFile, p->nLine, cQuote);
1728 }
1729 if( c==EOF ){
1730 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
1731 p->zFile, startLine, cQuote);
1732 p->z[p->n] = 0;
1733 p->cTerm = EOF;
1734 break;
1735 }
1736 csv_append_char(p, c);
1737 pc = c;
1738 }
1739 }else{
1740 csv_append_char(p, c);
1741 while( (c = fgetc(p->in))!=EOF && c!=cSep && c!='\n' ){
1742 csv_append_char(p, c);
1743 }
1744 if( c=='\n' ){
1745 p->nLine++;
1746 if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
1747 }
1748 p->z[p->n] = 0;
1749 p->cTerm = c;
1750 }
1751 return p->z;
1752}
1753
1754/*
drh75897232000-05-29 14:26:00 +00001755** If an input line begins with "." then invoke this routine to
1756** process that line.
drh67505e72002-04-19 12:34:06 +00001757**
drh47ad6842006-11-08 12:25:42 +00001758** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001759*/
drh44c2eb12003-04-30 11:38:26 +00001760static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001761 int i = 1;
1762 int nArg = 0;
1763 int n, c;
drh67505e72002-04-19 12:34:06 +00001764 int rc = 0;
drh75897232000-05-29 14:26:00 +00001765 char *azArg[50];
1766
1767 /* Parse the input line into tokens.
1768 */
1769 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001770 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001771 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001772 if( zLine[i]=='\'' || zLine[i]=='"' ){
1773 int delim = zLine[i++];
1774 azArg[nArg++] = &zLine[i];
1775 while( zLine[i] && zLine[i]!=delim ){ i++; }
1776 if( zLine[i]==delim ){
1777 zLine[i++] = 0;
1778 }
drhfeac5f82004-08-01 00:10:45 +00001779 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001780 }else{
1781 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001782 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001783 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001784 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001785 }
1786 }
1787
1788 /* Process the input line.
1789 */
shane9bd1b442009-10-23 01:27:39 +00001790 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001791 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001792 c = azArg[0][0];
drhbc46f022013-01-23 18:53:23 +00001793 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1794 const char *zDestFile = 0;
1795 const char *zDb = 0;
1796 const char *zKey = 0;
drh9ff849f2009-02-04 20:55:57 +00001797 sqlite3 *pDest;
1798 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00001799 int j;
1800 for(j=1; j<nArg; j++){
1801 const char *z = azArg[j];
1802 if( z[0]=='-' ){
1803 while( z[0]=='-' ) z++;
1804 if( strcmp(z,"key")==0 && j<nArg-1 ){
1805 zKey = azArg[++j];
1806 }else
1807 {
1808 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1809 return 1;
1810 }
1811 }else if( zDestFile==0 ){
1812 zDestFile = azArg[j];
1813 }else if( zDb==0 ){
1814 zDb = zDestFile;
1815 zDestFile = azArg[j];
1816 }else{
1817 fprintf(stderr, "too many arguments to .backup\n");
1818 return 1;
1819 }
drh9ff849f2009-02-04 20:55:57 +00001820 }
drhbc46f022013-01-23 18:53:23 +00001821 if( zDestFile==0 ){
1822 fprintf(stderr, "missing FILENAME argument on .backup\n");
1823 return 1;
1824 }
1825 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00001826 rc = sqlite3_open(zDestFile, &pDest);
1827 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001828 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001829 sqlite3_close(pDest);
1830 return 1;
1831 }
drhbc46f022013-01-23 18:53:23 +00001832#ifdef SQLITE_HAS_CODEC
1833 sqlite3_key(pDest, zKey, (int)strlen(zKey));
1834#else
1835 (void)zKey;
1836#endif
drhdc2c4912009-02-04 22:46:47 +00001837 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001838 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1839 if( pBackup==0 ){
1840 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1841 sqlite3_close(pDest);
1842 return 1;
1843 }
1844 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1845 sqlite3_backup_finish(pBackup);
1846 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001847 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001848 }else{
1849 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001850 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001851 }
1852 sqlite3_close(pDest);
1853 }else
1854
shanehe2aa9d72009-11-06 17:20:17 +00001855 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001856 bail_on_error = booleanValue(azArg[1]);
1857 }else
1858
drhd8621b92012-04-17 09:09:33 +00001859 /* The undocumented ".breakpoint" command causes a call to the no-op
1860 ** routine named test_breakpoint().
1861 */
1862 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1863 test_breakpoint();
1864 }else
1865
shanehe2aa9d72009-11-06 17:20:17 +00001866 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001867 struct callback_data data;
1868 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001869 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001870 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001871 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001872 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001873 data.colWidth[0] = 3;
1874 data.colWidth[1] = 15;
1875 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001876 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001877 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001878 if( zErrMsg ){
1879 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001880 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001881 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001882 }
1883 }else
1884
shanehe2aa9d72009-11-06 17:20:17 +00001885 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001886 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001887 /* When playing back a "dump", the content might appear in an order
1888 ** which causes immediate foreign key constraints to be violated.
1889 ** So disable foreign-key constraint enforcement to prevent problems. */
1890 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001891 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001892 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001893 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001894 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001895 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001896 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001897 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001898 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001899 );
1900 run_schema_dump_query(p,
1901 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001902 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001903 );
drh2f464a02011-10-13 00:41:49 +00001904 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001905 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001906 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001907 );
drh4c653a02000-06-07 01:27:47 +00001908 }else{
1909 int i;
drhdd3d4592004-08-30 01:54:05 +00001910 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001911 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001912 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001913 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001914 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001915 " AND sql NOT NULL");
1916 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001917 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001918 "WHERE sql NOT NULL"
1919 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001920 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001921 );
danielk1977bc6ada42004-06-30 08:20:16 +00001922 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001923 }
1924 }
drh45e29d82006-11-20 16:21:10 +00001925 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001926 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001927 p->writableSchema = 0;
1928 }
drh56197952011-10-13 16:30:13 +00001929 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1930 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001931 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001932 }else
drh75897232000-05-29 14:26:00 +00001933
shanehe2aa9d72009-11-06 17:20:17 +00001934 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001935 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001936 }else
1937
drhd3ac7d92013-01-25 18:33:43 +00001938 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00001939 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00001940 rc = 2;
drh75897232000-05-29 14:26:00 +00001941 }else
1942
shanehe2aa9d72009-11-06 17:20:17 +00001943 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001944 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001945 if(val == 1) {
1946 if(!p->explainPrev.valid) {
1947 p->explainPrev.valid = 1;
1948 p->explainPrev.mode = p->mode;
1949 p->explainPrev.showHeader = p->showHeader;
1950 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1951 }
1952 /* We could put this code under the !p->explainValid
1953 ** condition so that it does not execute if we are already in
1954 ** explain mode. However, always executing it allows us an easy
1955 ** was to reset to explain mode in case the user previously
1956 ** did an .explain followed by a .width, .mode or .header
1957 ** command.
1958 */
danielk19770d78bae2008-01-03 07:09:48 +00001959 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001960 p->showHeader = 1;
1961 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001962 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001963 p->colWidth[1] = 13; /* opcode */
1964 p->colWidth[2] = 4; /* P1 */
1965 p->colWidth[3] = 4; /* P2 */
1966 p->colWidth[4] = 4; /* P3 */
1967 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001968 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001969 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001970 }else if (p->explainPrev.valid) {
1971 p->explainPrev.valid = 0;
1972 p->mode = p->explainPrev.mode;
1973 p->showHeader = p->explainPrev.showHeader;
1974 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1975 }
drh75897232000-05-29 14:26:00 +00001976 }else
1977
drhc28490c2006-10-26 14:25:58 +00001978 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001979 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001980 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001981 }else
1982
1983 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001984 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001985 if( HAS_TIMER ){
1986 fprintf(stderr,"%s",zTimerHelp);
1987 }
drh75897232000-05-29 14:26:00 +00001988 }else
1989
shanehe2aa9d72009-11-06 17:20:17 +00001990 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001991 char *zTable = azArg[2]; /* Insert data into this table */
shane916f9612009-10-23 00:37:15 +00001992 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001993 int nCol; /* Number of columns in the table */
1994 int nByte; /* Number of bytes in an SQL string */
1995 int i, j; /* Loop counters */
1996 int nSep; /* Number of bytes in p->separator[] */
1997 char *zSql; /* An SQL statement */
drhdb95f682013-06-26 22:46:00 +00001998 CSVReader sCsv; /* Reader context */
drhfeac5f82004-08-01 00:10:45 +00001999
drhdb95f682013-06-26 22:46:00 +00002000 seenInterrupt = 0;
2001 memset(&sCsv, 0, sizeof(sCsv));
2002 sCsv.zFile = azArg[1];
2003 sCsv.nLine = 1;
drha543c822006-06-08 16:10:14 +00002004 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00002005 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00002006 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00002007 fprintf(stderr, "Error: non-null separator required for import\n");
2008 return 1;
drhfeac5f82004-08-01 00:10:45 +00002009 }
drhdb95f682013-06-26 22:46:00 +00002010 if( nSep>1 ){
2011 fprintf(stderr, "Error: multi-character separators not allowed"
2012 " for import\n");
2013 return 1;
2014 }
2015 sCsv.in = fopen(sCsv.zFile, "rb");
2016 if( sCsv.in==0 ){
2017 fprintf(stderr, "Error: cannot open \"%s\"\n", sCsv.zFile);
2018 return 1;
2019 }
2020 sCsv.cSeparator = p->separator[0];
drh7b075e32011-09-28 01:10:00 +00002021 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002022 if( zSql==0 ){
2023 fprintf(stderr, "Error: out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002024 fclose(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002025 return 1;
2026 }
drh4f21c4a2008-12-10 22:15:00 +00002027 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00002028 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002029 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2030 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2031 char cSep = '(';
2032 while( csv_read_one_field(&sCsv) ){
2033 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
2034 cSep = ',';
2035 if( sCsv.cTerm!=sCsv.cSeparator ) break;
2036 }
2037 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2038 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2039 sqlite3_free(zCreate);
2040 if( rc ){
2041 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2042 sqlite3_errmsg(db));
2043 sqlite3_free(sCsv.z);
2044 fclose(sCsv.in);
2045 return 1;
2046 }
2047 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
2048 }
drhfeac5f82004-08-01 00:10:45 +00002049 sqlite3_free(zSql);
2050 if( rc ){
shane916f9612009-10-23 00:37:15 +00002051 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002052 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
drhdb95f682013-06-26 22:46:00 +00002053 fclose(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002054 return 1;
drhfeac5f82004-08-01 00:10:45 +00002055 }
shane916f9612009-10-23 00:37:15 +00002056 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002057 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002058 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002059 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00002060 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00002061 if( zSql==0 ){
2062 fprintf(stderr, "Error: out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002063 fclose(sCsv.in);
shane916f9612009-10-23 00:37:15 +00002064 return 1;
2065 }
drhdb95f682013-06-26 22:46:00 +00002066 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00002067 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00002068 for(i=1; i<nCol; i++){
2069 zSql[j++] = ',';
2070 zSql[j++] = '?';
2071 }
2072 zSql[j++] = ')';
2073 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00002074 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002075 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00002076 if( rc ){
2077 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00002078 if (pStmt) sqlite3_finalize(pStmt);
drhdb95f682013-06-26 22:46:00 +00002079 fclose(sCsv.in);
drh47ad6842006-11-08 12:25:42 +00002080 return 1;
drhfeac5f82004-08-01 00:10:45 +00002081 }
drhdb95f682013-06-26 22:46:00 +00002082 do{
2083 int startLine = sCsv.nLine;
drhfeac5f82004-08-01 00:10:45 +00002084 for(i=0; i<nCol; i++){
drhdb95f682013-06-26 22:46:00 +00002085 char *z = csv_read_one_field(&sCsv);
2086 if( z==0 && i==0 ) break;
2087 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
2088 if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
2089 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2090 "filling the rest with NULL\n",
2091 sCsv.zFile, startLine, nCol, i+1);
2092 i++;
2093 while( i<nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00002094 }
drhfeac5f82004-08-01 00:10:45 +00002095 }
drhdb95f682013-06-26 22:46:00 +00002096 if( sCsv.cTerm==sCsv.cSeparator ){
2097 do{
2098 csv_read_one_field(&sCsv);
2099 i++;
2100 }while( sCsv.cTerm==sCsv.cSeparator );
2101 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2102 "extras ignored\n",
2103 sCsv.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00002104 }
drhdb95f682013-06-26 22:46:00 +00002105 if( i>=nCol ){
2106 sqlite3_step(pStmt);
2107 rc = sqlite3_reset(pStmt);
2108 if( rc!=SQLITE_OK ){
2109 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
2110 sqlite3_errmsg(db));
2111 }
2112 }
2113 }while( sCsv.cTerm!=EOF );
2114
2115 fclose(sCsv.in);
2116 sqlite3_free(sCsv.z);
drhfeac5f82004-08-01 00:10:45 +00002117 sqlite3_finalize(pStmt);
drhdb95f682013-06-26 22:46:00 +00002118 sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002119 }else
2120
shanehe2aa9d72009-11-06 17:20:17 +00002121 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002122 struct callback_data data;
2123 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002124 open_db(p);
drh75897232000-05-29 14:26:00 +00002125 memcpy(&data, p, sizeof(data));
2126 data.showHeader = 0;
2127 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002128 if( nArg==1 ){
2129 rc = sqlite3_exec(p->db,
2130 "SELECT name FROM sqlite_master "
2131 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2132 "UNION ALL "
2133 "SELECT name FROM sqlite_temp_master "
2134 "WHERE type='index' "
2135 "ORDER BY 1",
2136 callback, &data, &zErrMsg
2137 );
2138 }else{
2139 zShellStatic = azArg[1];
2140 rc = sqlite3_exec(p->db,
2141 "SELECT name FROM sqlite_master "
2142 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2143 "UNION ALL "
2144 "SELECT name FROM sqlite_temp_master "
2145 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2146 "ORDER BY 1",
2147 callback, &data, &zErrMsg
2148 );
2149 zShellStatic = 0;
2150 }
drh75897232000-05-29 14:26:00 +00002151 if( zErrMsg ){
2152 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002153 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002154 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002155 }else if( rc != SQLITE_OK ){
2156 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2157 rc = 1;
drh75897232000-05-29 14:26:00 +00002158 }
2159 }else
2160
drhae5e4452007-05-03 17:18:36 +00002161#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002162 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002163 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002164 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2165 iotrace = 0;
2166 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002167 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002168 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002169 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002170 iotrace = stdout;
2171 }else{
2172 iotrace = fopen(azArg[1], "w");
2173 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002174 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002175 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002176 rc = 1;
drhb0603412007-02-28 04:47:26 +00002177 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002178 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002179 }
2180 }
2181 }else
drhae5e4452007-05-03 17:18:36 +00002182#endif
drhb0603412007-02-28 04:47:26 +00002183
drh70df4fe2006-06-13 15:12:21 +00002184#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002185 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2186 const char *zFile, *zProc;
2187 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00002188 zFile = azArg[1];
2189 zProc = nArg>=3 ? azArg[2] : 0;
2190 open_db(p);
2191 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2192 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002193 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002194 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002195 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002196 }
2197 }else
drh70df4fe2006-06-13 15:12:21 +00002198#endif
drh1e397f82006-06-08 15:28:43 +00002199
drhc8ba2122011-03-23 11:16:22 +00002200 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00002201 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00002202 output_file_close(p->pLog);
2203 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00002204 }else
2205
shanehe2aa9d72009-11-06 17:20:17 +00002206 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00002207 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002208 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002209 ||
shanehe2aa9d72009-11-06 17:20:17 +00002210 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002211 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002212 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002213 ||
shanehe2aa9d72009-11-06 17:20:17 +00002214 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002215 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002216 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002217 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002218 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002219 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002220 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002221 p->mode = MODE_Tcl;
mistachkin585dcb22012-12-04 00:23:43 +00002222 sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
shanehe2aa9d72009-11-06 17:20:17 +00002223 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002224 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002225 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002226 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002227 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002228 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002229 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002230 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002231 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002232 }else {
shane9bd1b442009-10-23 01:27:39 +00002233 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002234 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002235 rc = 1;
drh75897232000-05-29 14:26:00 +00002236 }
2237 }else
2238
shanehe2aa9d72009-11-06 17:20:17 +00002239 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2240 int n2 = strlen30(azArg[1]);
2241 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2242 p->mode = MODE_Insert;
2243 set_table_name(p, azArg[2]);
2244 }else {
2245 fprintf(stderr, "Error: invalid arguments: "
2246 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2247 rc = 1;
2248 }
2249 }else
2250
persicom7e2dfdd2002-04-18 02:46:52 +00002251 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002252 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2253 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002254 }else
2255
drh75897232000-05-29 14:26:00 +00002256 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002257 if( p->outfile[0]=='|' ){
2258 pclose(p->out);
2259 }else{
2260 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002261 }
drh42f64e52012-04-04 16:56:23 +00002262 p->outfile[0] = 0;
2263 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002264 p->out = popen(&azArg[1][1], "w");
2265 if( p->out==0 ){
2266 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2267 p->out = stdout;
2268 rc = 1;
2269 }else{
2270 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2271 }
drh75897232000-05-29 14:26:00 +00002272 }else{
drh42f64e52012-04-04 16:56:23 +00002273 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002274 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002275 if( strcmp(azArg[1],"off")!=0 ){
2276 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2277 }
drh75897232000-05-29 14:26:00 +00002278 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002279 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002280 } else {
drh42f64e52012-04-04 16:56:23 +00002281 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002282 }
2283 }
2284 }else
2285
drh078b1fd2012-09-21 13:40:02 +00002286 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2287 int i;
2288 for(i=1; i<nArg; i++){
2289 if( i>1 ) fprintf(p->out, " ");
2290 fprintf(p->out, "%s", azArg[i]);
2291 }
2292 fprintf(p->out, "\n");
2293 }else
2294
drhdd45df82002-04-18 12:39:03 +00002295 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002296 if( nArg >= 2) {
2297 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2298 }
2299 if( nArg >= 3) {
2300 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2301 }
2302 }else
2303
shanehe2aa9d72009-11-06 17:20:17 +00002304 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002305 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002306 }else
2307
drh9ff849f2009-02-04 20:55:57 +00002308 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002309 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002310 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002311 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2312 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002313 }else{
shane9bd1b442009-10-23 01:27:39 +00002314 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002315 fclose(alt);
2316 }
2317 }else
2318
shanehe2aa9d72009-11-06 17:20:17 +00002319 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002320 const char *zSrcFile;
2321 const char *zDb;
2322 sqlite3 *pSrc;
2323 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002324 int nTimeout = 0;
2325
drh9ff849f2009-02-04 20:55:57 +00002326 if( nArg==2 ){
2327 zSrcFile = azArg[1];
2328 zDb = "main";
2329 }else{
2330 zSrcFile = azArg[2];
2331 zDb = azArg[1];
2332 }
2333 rc = sqlite3_open(zSrcFile, &pSrc);
2334 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002335 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002336 sqlite3_close(pSrc);
2337 return 1;
2338 }
drhdc2c4912009-02-04 22:46:47 +00002339 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002340 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2341 if( pBackup==0 ){
2342 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2343 sqlite3_close(pSrc);
2344 return 1;
2345 }
drhdc2c4912009-02-04 22:46:47 +00002346 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2347 || rc==SQLITE_BUSY ){
2348 if( rc==SQLITE_BUSY ){
2349 if( nTimeout++ >= 3 ) break;
2350 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002351 }
2352 }
2353 sqlite3_backup_finish(pBackup);
2354 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002355 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002356 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002357 fprintf(stderr, "Error: source database is busy\n");
2358 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002359 }else{
2360 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002361 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002362 }
2363 sqlite3_close(pSrc);
2364 }else
2365
shanehe2aa9d72009-11-06 17:20:17 +00002366 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002367 struct callback_data data;
2368 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002369 open_db(p);
drh75897232000-05-29 14:26:00 +00002370 memcpy(&data, p, sizeof(data));
2371 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002372 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002373 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002374 int i;
drhf0693c82011-10-11 20:41:54 +00002375 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002376 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002377 char *new_argv[2], *new_colv[2];
2378 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2379 " type text,\n"
2380 " name text,\n"
2381 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002382 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002383 " sql text\n"
2384 ")";
2385 new_argv[1] = 0;
2386 new_colv[0] = "sql";
2387 new_colv[1] = 0;
2388 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002389 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002390 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002391 char *new_argv[2], *new_colv[2];
2392 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2393 " type text,\n"
2394 " name text,\n"
2395 " tbl_name text,\n"
2396 " rootpage integer,\n"
2397 " sql text\n"
2398 ")";
2399 new_argv[1] = 0;
2400 new_colv[0] = "sql";
2401 new_colv[1] = 0;
2402 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002403 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002404 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002405 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002406 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002407 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002408 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002409 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002410 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002411 "WHERE lower(tbl_name) LIKE shellstatic()"
2412 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00002413 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00002414 callback, &data, &zErrMsg);
2415 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002416 }
drh75897232000-05-29 14:26:00 +00002417 }else{
shane9bd1b442009-10-23 01:27:39 +00002418 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002419 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002420 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002421 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002422 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002423 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drh1ba00292013-05-06 21:01:06 +00002424 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00002425 callback, &data, &zErrMsg
2426 );
drh75897232000-05-29 14:26:00 +00002427 }
drh75897232000-05-29 14:26:00 +00002428 if( zErrMsg ){
2429 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002430 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002431 rc = 1;
2432 }else if( rc != SQLITE_OK ){
2433 fprintf(stderr,"Error: querying schema information\n");
2434 rc = 1;
2435 }else{
2436 rc = 0;
drh75897232000-05-29 14:26:00 +00002437 }
2438 }else
2439
drh340f5822013-06-27 13:01:21 +00002440#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00002441 /* Undocumented commands for internal testing. Subject to change
2442 ** without notice. */
2443 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
2444 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
2445 int i, v;
2446 for(i=1; i<nArg; i++){
2447 v = booleanValue(azArg[i]);
2448 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
2449 }
2450 }
2451 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
2452 int i; sqlite3_int64 v;
2453 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00002454 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00002455 v = integerValue(azArg[i]);
drh340f5822013-06-27 13:01:21 +00002456 sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);
2457 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00002458 }
2459 }
2460 }else
drh340f5822013-06-27 13:01:21 +00002461#endif
drh348d19c2013-06-03 12:47:43 +00002462
drh75897232000-05-29 14:26:00 +00002463 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002464 sqlite3_snprintf(sizeof(p->separator), p->separator,
2465 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002466 }else
2467
shanehe2aa9d72009-11-06 17:20:17 +00002468 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002469 int i;
2470 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002471 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002472 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002473 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002474 fprintf(p->out,"%9.9s: ", "nullvalue");
2475 output_c_string(p->out, p->nullvalue);
2476 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002477 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002478 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002479 fprintf(p->out,"%9.9s: ", "separator");
2480 output_c_string(p->out, p->separator);
2481 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002482 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002483 fprintf(p->out,"%9.9s: ","width");
2484 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002485 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002486 }
drhfeac5f82004-08-01 00:10:45 +00002487 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002488 }else
2489
shaneh642d8b82010-07-28 16:05:34 +00002490 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2491 p->statsOn = booleanValue(azArg[1]);
2492 }else
2493
shanehe2aa9d72009-11-06 17:20:17 +00002494 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002495 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002496 char **azResult;
drh98781232012-04-23 12:38:05 +00002497 int nRow, nAlloc;
2498 char *zSql = 0;
2499 int ii;
drh44c2eb12003-04-30 11:38:26 +00002500 open_db(p);
drh98781232012-04-23 12:38:05 +00002501 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2502 if( rc ) return rc;
2503 zSql = sqlite3_mprintf(
2504 "SELECT name FROM sqlite_master"
2505 " WHERE type IN ('table','view')"
2506 " AND name NOT LIKE 'sqlite_%%'"
2507 " AND name LIKE ?1");
2508 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2509 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2510 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2511 if( strcmp(zDbName,"temp")==0 ){
2512 zSql = sqlite3_mprintf(
2513 "%z UNION ALL "
2514 "SELECT 'temp.' || name FROM sqlite_temp_master"
2515 " WHERE type IN ('table','view')"
2516 " AND name NOT LIKE 'sqlite_%%'"
2517 " AND name LIKE ?1", zSql);
2518 }else{
2519 zSql = sqlite3_mprintf(
2520 "%z UNION ALL "
2521 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2522 " WHERE type IN ('table','view')"
2523 " AND name NOT LIKE 'sqlite_%%'"
2524 " AND name LIKE ?1", zSql, zDbName, zDbName);
2525 }
drha50da102000-08-08 20:19:09 +00002526 }
drh98781232012-04-23 12:38:05 +00002527 sqlite3_finalize(pStmt);
2528 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2529 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2530 sqlite3_free(zSql);
2531 if( rc ) return rc;
2532 nRow = nAlloc = 0;
2533 azResult = 0;
2534 if( nArg>1 ){
2535 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002536 }else{
drh98781232012-04-23 12:38:05 +00002537 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2538 }
2539 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2540 if( nRow>=nAlloc ){
2541 char **azNew;
2542 int n = nAlloc*2 + 10;
2543 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2544 if( azNew==0 ){
2545 fprintf(stderr, "Error: out of memory\n");
2546 break;
2547 }
2548 nAlloc = n;
2549 azResult = azNew;
2550 }
2551 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2552 if( azResult[nRow] ) nRow++;
2553 }
2554 sqlite3_finalize(pStmt);
2555 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002556 int len, maxlen = 0;
2557 int i, j;
2558 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002559 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002560 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002561 if( len>maxlen ) maxlen = len;
2562 }
2563 nPrintCol = 80/(maxlen+2);
2564 if( nPrintCol<1 ) nPrintCol = 1;
2565 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2566 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002567 for(j=i; j<nRow; j+=nPrintRow){
2568 char *zSp = j<nPrintRow ? "" : " ";
drh151b7d52013-05-06 20:28:54 +00002569 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
drhe3710332000-09-29 13:30:53 +00002570 }
drh151b7d52013-05-06 20:28:54 +00002571 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00002572 }
2573 }
drh98781232012-04-23 12:38:05 +00002574 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2575 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002576 }else
2577
shaneh96887e12011-02-10 21:08:58 +00002578 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002579 static const struct {
2580 const char *zCtrlName; /* Name of a test-control option */
2581 int ctrlCode; /* Integer code for that option */
2582 } aCtrl[] = {
2583 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2584 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2585 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2586 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2587 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2588 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2589 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2590 { "assert", SQLITE_TESTCTRL_ASSERT },
2591 { "always", SQLITE_TESTCTRL_ALWAYS },
2592 { "reserve", SQLITE_TESTCTRL_RESERVE },
2593 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2594 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002595 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2596 };
shaneh96887e12011-02-10 21:08:58 +00002597 int testctrl = -1;
2598 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002599 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002600 open_db(p);
2601
drhd416fe72011-03-17 16:45:50 +00002602 /* convert testctrl text option to value. allow any unique prefix
2603 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002604 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002605 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002606 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2607 if( testctrl<0 ){
2608 testctrl = aCtrl[i].ctrlCode;
2609 }else{
drhb07028f2011-10-14 21:49:18 +00002610 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002611 testctrl = -1;
2612 break;
2613 }
2614 }
2615 }
drh348d19c2013-06-03 12:47:43 +00002616 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002617 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2618 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2619 }else{
2620 switch(testctrl){
2621
2622 /* sqlite3_test_control(int, db, int) */
2623 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2624 case SQLITE_TESTCTRL_RESERVE:
2625 if( nArg==3 ){
2626 int opt = (int)strtol(azArg[2], 0, 0);
2627 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00002628 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002629 } else {
drhd416fe72011-03-17 16:45:50 +00002630 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2631 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002632 }
2633 break;
2634
2635 /* sqlite3_test_control(int) */
2636 case SQLITE_TESTCTRL_PRNG_SAVE:
2637 case SQLITE_TESTCTRL_PRNG_RESTORE:
2638 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002639 if( nArg==2 ){
2640 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00002641 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002642 } else {
2643 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2644 }
2645 break;
2646
2647 /* sqlite3_test_control(int, uint) */
2648 case SQLITE_TESTCTRL_PENDING_BYTE:
2649 if( nArg==3 ){
drh7d9f3942013-04-03 01:26:54 +00002650 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002651 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002652 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002653 } else {
drhd416fe72011-03-17 16:45:50 +00002654 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2655 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002656 }
2657 break;
2658
2659 /* sqlite3_test_control(int, int) */
2660 case SQLITE_TESTCTRL_ASSERT:
2661 case SQLITE_TESTCTRL_ALWAYS:
2662 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00002663 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002664 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002665 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002666 } else {
drhd416fe72011-03-17 16:45:50 +00002667 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2668 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002669 }
2670 break;
2671
2672 /* sqlite3_test_control(int, char *) */
2673#ifdef SQLITE_N_KEYWORD
2674 case SQLITE_TESTCTRL_ISKEYWORD:
2675 if( nArg==3 ){
2676 const char *opt = azArg[2];
2677 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002678 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002679 } else {
drhd416fe72011-03-17 16:45:50 +00002680 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2681 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002682 }
2683 break;
2684#endif
2685
2686 case SQLITE_TESTCTRL_BITVEC_TEST:
2687 case SQLITE_TESTCTRL_FAULT_INSTALL:
2688 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2689 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2690 default:
drhd416fe72011-03-17 16:45:50 +00002691 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2692 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002693 break;
2694 }
2695 }
2696 }else
2697
shanehe2aa9d72009-11-06 17:20:17 +00002698 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002699 open_db(p);
drh348d19c2013-06-03 12:47:43 +00002700 sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002701 }else
2702
drhd416fe72011-03-17 16:45:50 +00002703 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2704 && nArg==2
2705 ){
drh3b1a9882007-11-02 12:53:03 +00002706 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002707 }else
2708
drh42f64e52012-04-04 16:56:23 +00002709 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh98781232012-04-23 12:38:05 +00002710 open_db(p);
drh42f64e52012-04-04 16:56:23 +00002711 output_file_close(p->traceOut);
2712 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00002713#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002714 if( p->traceOut==0 ){
2715 sqlite3_trace(p->db, 0, 0);
2716 }else{
2717 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2718 }
2719#endif
2720 }else
2721
drh9fd301b2011-06-03 13:28:22 +00002722 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00002723 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002724 sqlite3_libversion(), sqlite3_sourceid());
2725 }else
2726
drhde60fc22011-12-14 17:53:36 +00002727 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2728 const char *zDbName = nArg==2 ? azArg[1] : "main";
2729 char *zVfsName = 0;
2730 if( p->db ){
2731 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2732 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00002733 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00002734 sqlite3_free(zVfsName);
2735 }
2736 }
2737 }else
2738
drhcef4fc82012-09-21 22:50:45 +00002739#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2740 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
2741 extern int sqlite3WhereTrace;
drh7d9f3942013-04-03 01:26:54 +00002742 sqlite3WhereTrace = booleanValue(azArg[1]);
drhcef4fc82012-09-21 22:50:45 +00002743 }else
2744#endif
2745
shanehe2aa9d72009-11-06 17:20:17 +00002746 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002747 int j;
drh43617e92006-03-06 20:55:46 +00002748 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002749 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00002750 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00002751 }
2752 }else
2753
2754 {
shane9bd1b442009-10-23 01:27:39 +00002755 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002756 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002757 rc = 1;
drh75897232000-05-29 14:26:00 +00002758 }
drh67505e72002-04-19 12:34:06 +00002759
2760 return rc;
drh75897232000-05-29 14:26:00 +00002761}
2762
drh67505e72002-04-19 12:34:06 +00002763/*
drh91a66392007-09-07 01:12:32 +00002764** Return TRUE if a semicolon occurs anywhere in the first N characters
2765** of string z[].
drh324ccef2003-02-05 14:06:20 +00002766*/
drh91a66392007-09-07 01:12:32 +00002767static int _contains_semicolon(const char *z, int N){
2768 int i;
2769 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2770 return 0;
drh324ccef2003-02-05 14:06:20 +00002771}
2772
2773/*
drh70c7a4b2003-04-26 03:03:06 +00002774** Test to see if a line consists entirely of whitespace.
2775*/
2776static int _all_whitespace(const char *z){
2777 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002778 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002779 if( *z=='/' && z[1]=='*' ){
2780 z += 2;
2781 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2782 if( *z==0 ) return 0;
2783 z++;
2784 continue;
2785 }
2786 if( *z=='-' && z[1]=='-' ){
2787 z += 2;
2788 while( *z && *z!='\n' ){ z++; }
2789 if( *z==0 ) return 1;
2790 continue;
2791 }
2792 return 0;
2793 }
2794 return 1;
2795}
2796
2797/*
drha9b17162003-04-29 18:01:28 +00002798** Return TRUE if the line typed in is an SQL command terminator other
2799** than a semi-colon. The SQL Server style "go" command is understood
2800** as is the Oracle "/".
2801*/
2802static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002803 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002804 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2805 return 1; /* Oracle */
2806 }
drhf0693c82011-10-11 20:41:54 +00002807 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002808 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002809 return 1; /* SQL Server */
2810 }
2811 return 0;
2812}
2813
2814/*
drh233a5312008-12-18 22:25:13 +00002815** Return true if zSql is a complete SQL statement. Return false if it
2816** ends in the middle of a string literal or C-style comment.
2817*/
2818static int _is_complete(char *zSql, int nSql){
2819 int rc;
2820 if( zSql==0 ) return 1;
2821 zSql[nSql] = ';';
2822 zSql[nSql+1] = 0;
2823 rc = sqlite3_complete(zSql);
2824 zSql[nSql] = 0;
2825 return rc;
2826}
2827
2828/*
drh67505e72002-04-19 12:34:06 +00002829** Read input from *in and process it. If *in==0 then input
2830** is interactive - the user is typing it it. Otherwise, input
2831** is coming from a file or device. A prompt is issued and history
2832** is saved only if input is interactive. An interrupt signal will
2833** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002834**
2835** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002836*/
drhc28490c2006-10-26 14:25:58 +00002837static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002838 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002839 char *zSql = 0;
2840 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002841 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002842 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002843 int rc;
2844 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002845 int lineno = 0;
2846 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002847
2848 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2849 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002850 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002851 zLine = one_input_line(zSql, in);
2852 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002853 /* End of input */
2854 if( stdin_is_interactive ) printf("\n");
2855 break;
drhc49f44e2006-10-26 18:15:42 +00002856 }
drh67505e72002-04-19 12:34:06 +00002857 if( seenInterrupt ){
2858 if( in!=0 ) break;
2859 seenInterrupt = 0;
2860 }
drhc28490c2006-10-26 14:25:58 +00002861 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002862 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002863 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002864 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002865 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002866 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002867 break;
2868 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002869 errCnt++;
2870 }
drhdaffd0e2001-04-11 14:28:42 +00002871 continue;
2872 }
drh233a5312008-12-18 22:25:13 +00002873 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002874 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002875 }
drh91a66392007-09-07 01:12:32 +00002876 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002877 if( zSql==0 ){
2878 int i;
drhf0693c82011-10-11 20:41:54 +00002879 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002880 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002881 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002882 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002883 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002884 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002885 exit(1);
2886 }
drh5bb3eb92007-05-04 13:15:55 +00002887 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002888 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002889 }
2890 }else{
drh4f21c4a2008-12-10 22:15:00 +00002891 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002892 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002893 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002894 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002895 exit(1);
2896 }
drh5bb3eb92007-05-04 13:15:55 +00002897 zSql[nSql++] = '\n';
2898 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002899 nSql += len;
2900 }
drh91a66392007-09-07 01:12:32 +00002901 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2902 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002903 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002904 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002905 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002906 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002907 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002908 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002909 char zPrefix[100];
2910 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002911 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002912 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002913 }else{
shane9bd1b442009-10-23 01:27:39 +00002914 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002915 }
drh7f953e22002-07-13 17:33:45 +00002916 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002917 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002918 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002919 zErrMsg = 0;
2920 }else{
shaned2bed1c2009-10-21 03:56:54 +00002921 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002922 }
drhc49f44e2006-10-26 18:15:42 +00002923 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002924 }
2925 free(zSql);
2926 zSql = 0;
2927 nSql = 0;
drh7a411f42013-04-17 17:33:17 +00002928 }else if( zSql && _all_whitespace(zSql) ){
2929 free(zSql);
2930 zSql = 0;
2931 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00002932 }
2933 }
2934 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002935 if( !_all_whitespace(zSql) ){
2936 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2937 }
drhdaffd0e2001-04-11 14:28:42 +00002938 free(zSql);
2939 }
danielk19772ac27622007-07-03 05:31:16 +00002940 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00002941 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00002942}
2943
drh67505e72002-04-19 12:34:06 +00002944/*
2945** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002946** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002947*/
2948static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002949 static char *home_dir = NULL;
2950 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002951
drh83905c92012-06-21 13:00:37 +00002952#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00002953 {
2954 struct passwd *pwent;
2955 uid_t uid = getuid();
2956 if( (pwent=getpwuid(uid)) != NULL) {
2957 home_dir = pwent->pw_dir;
2958 }
drh67505e72002-04-19 12:34:06 +00002959 }
2960#endif
2961
chw65d3c132007-11-12 21:09:10 +00002962#if defined(_WIN32_WCE)
2963 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2964 */
drh85e72432012-04-11 11:38:53 +00002965 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00002966#else
2967
drh83905c92012-06-21 13:00:37 +00002968#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00002969 if (!home_dir) {
2970 home_dir = getenv("USERPROFILE");
2971 }
2972#endif
2973
drh67505e72002-04-19 12:34:06 +00002974 if (!home_dir) {
2975 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002976 }
2977
drh83905c92012-06-21 13:00:37 +00002978#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00002979 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002980 char *zDrive, *zPath;
2981 int n;
2982 zDrive = getenv("HOMEDRIVE");
2983 zPath = getenv("HOMEPATH");
2984 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002985 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002986 home_dir = malloc( n );
2987 if( home_dir==0 ) return 0;
2988 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2989 return home_dir;
2990 }
2991 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002992 }
2993#endif
2994
chw65d3c132007-11-12 21:09:10 +00002995#endif /* !_WIN32_WCE */
2996
drh67505e72002-04-19 12:34:06 +00002997 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002998 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002999 char *z = malloc( n );
3000 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00003001 home_dir = z;
3002 }
drhe98d4fa2002-04-21 19:06:22 +00003003
drh67505e72002-04-19 12:34:06 +00003004 return home_dir;
3005}
3006
3007/*
3008** Read input from the file given by sqliterc_override. Or if that
3009** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00003010**
3011** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00003012*/
shane9bd1b442009-10-23 01:27:39 +00003013static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00003014 struct callback_data *p, /* Configuration data */
3015 const char *sqliterc_override /* Name of config file. NULL to use default */
3016){
persicom7e2dfdd2002-04-18 02:46:52 +00003017 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00003018 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00003019 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003020 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00003021 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00003022
3023 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00003024 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00003025 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00003026#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00003027 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00003028#endif
shane9bd1b442009-10-23 01:27:39 +00003029 return 1;
drhe98d4fa2002-04-21 19:06:22 +00003030 }
drh2f3de322012-06-27 16:41:31 +00003031 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00003032 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
3033 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00003034 }
drha1f9b5e2004-02-14 16:31:02 +00003035 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00003036 if( in ){
drhc28490c2006-10-26 14:25:58 +00003037 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00003038 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00003039 }
shane9bd1b442009-10-23 01:27:39 +00003040 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00003041 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00003042 }
drh85e72432012-04-11 11:38:53 +00003043 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00003044 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00003045}
3046
drh67505e72002-04-19 12:34:06 +00003047/*
drhe1e38c42003-05-04 18:30:59 +00003048** Show available command line options
3049*/
3050static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00003051 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00003052 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003053 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00003054 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00003055 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00003056 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00003057 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00003058 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00003059#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3060 " -heap SIZE Size of heap for memsys3 or memsys5\n"
3061#endif
drhcc3b4f82012-02-07 14:13:50 +00003062 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00003063 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00003064 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00003065 " -line set output mode to 'line'\n"
3066 " -list set output mode to 'list'\n"
drh7d9f3942013-04-03 01:26:54 +00003067 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00003068#ifdef SQLITE_ENABLE_MULTIPLEX
3069 " -multiplex enable the multiplexor VFS\n"
3070#endif
drh98d312f2012-10-25 15:23:14 +00003071 " -nullvalue TEXT set text string for NULL values. Default ''\n"
3072 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00003073 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00003074 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00003075 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00003076#ifdef SQLITE_ENABLE_VFSTRACE
3077 " -vfstrace enable tracing of all VFS calls\n"
3078#endif
drhe1e38c42003-05-04 18:30:59 +00003079;
3080static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00003081 fprintf(stderr,
3082 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3083 "FILENAME is the name of an SQLite database. A new database is created\n"
3084 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00003085 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00003086 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00003087 }else{
3088 fprintf(stderr, "Use the -help option for additional information\n");
3089 }
3090 exit(1);
3091}
3092
3093/*
drh67505e72002-04-19 12:34:06 +00003094** Initialize the state information in data
3095*/
drh0850b532006-01-31 19:31:43 +00003096static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00003097 memset(data, 0, sizeof(*data));
3098 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00003099 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00003100 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00003101 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00003102 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00003103 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3104 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00003105 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00003106}
3107
drh98d312f2012-10-25 15:23:14 +00003108/*
3109** Get the argument to an --option. Throw an error and die if no argument
3110** is available.
3111*/
3112static char *cmdline_option_value(int argc, char **argv, int i){
3113 if( i==argc ){
3114 fprintf(stderr, "%s: Error: missing argument to %s\n",
3115 argv[0], argv[argc-1]);
3116 exit(1);
3117 }
3118 return argv[i];
3119}
3120
drh75897232000-05-29 14:26:00 +00003121int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003122 char *zErrMsg = 0;
3123 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00003124 const char *zInitFile = 0;
3125 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003126 int i;
drhc28490c2006-10-26 14:25:58 +00003127 int rc = 0;
drh75897232000-05-29 14:26:00 +00003128
drh52784bd2011-05-18 17:15:06 +00003129 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
3130 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
3131 sqlite3_sourceid(), SQLITE_SOURCE_ID);
3132 exit(1);
3133 }
drhdaffd0e2001-04-11 14:28:42 +00003134 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003135 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003136 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003137
drh44c2eb12003-04-30 11:38:26 +00003138 /* Make sure we have a valid signal handler early, before anything
3139 ** else is done.
3140 */
drh4c504392000-10-16 22:06:40 +00003141#ifdef SIGINT
3142 signal(SIGINT, interrupt_handler);
3143#endif
drh44c2eb12003-04-30 11:38:26 +00003144
drh22fbcb82004-02-01 01:22:50 +00003145 /* Do an initial pass through the command-line argument to locate
3146 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00003147 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00003148 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003149 */
drh98d312f2012-10-25 15:23:14 +00003150 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00003151 char *z;
drhc28490c2006-10-26 14:25:58 +00003152 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003153 if( z[0]!='-' ){
3154 if( data.zDbFilename==0 ){
3155 data.zDbFilename = z;
3156 continue;
3157 }
3158 if( zFirstCmd==0 ){
3159 zFirstCmd = z;
3160 continue;
3161 }
3162 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
3163 fprintf(stderr,"Use -help for a list of options.\n");
3164 return 1;
3165 }
drhcc3b4f82012-02-07 14:13:50 +00003166 if( z[1]=='-' ) z++;
3167 if( strcmp(z,"-separator")==0
3168 || strcmp(z,"-nullvalue")==0
3169 || strcmp(z,"-cmd")==0
3170 ){
drh98d312f2012-10-25 15:23:14 +00003171 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003172 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00003173 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003174 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00003175 /* Need to check for batch mode here to so we can avoid printing
3176 ** informational messages (like from process_sqliterc) before
3177 ** we do the actual processing of arguments later in a second pass.
3178 */
shanef69573d2009-10-24 02:06:14 +00003179 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00003180 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00003181#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00003182 int j, c;
3183 const char *zSize;
3184 sqlite3_int64 szHeap;
3185
drh98d312f2012-10-25 15:23:14 +00003186 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00003187 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00003188 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00003189 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3190#endif
drh97ae8ff2011-03-16 16:56:29 +00003191#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00003192 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00003193 extern int vfstrace_register(
3194 const char *zTraceName,
3195 const char *zOldVfsName,
3196 int (*xOut)(const char*,void*),
3197 void *pOutArg,
3198 int makeDefault
3199 );
drh2b625e22011-03-16 17:05:28 +00003200 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00003201#endif
drh6f25e892011-07-08 17:02:57 +00003202#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00003203 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00003204 extern int sqlite3_multiple_initialize(const char*,int);
3205 sqlite3_multiplex_initialize(0, 1);
3206#endif
drh7d9f3942013-04-03 01:26:54 +00003207 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00003208 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
3209 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00003210 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00003211 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00003212 if( pVfs ){
3213 sqlite3_vfs_register(pVfs, 1);
3214 }else{
3215 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3216 exit(1);
3217 }
drh44c2eb12003-04-30 11:38:26 +00003218 }
3219 }
drh98d312f2012-10-25 15:23:14 +00003220 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00003221#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003222 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003223#else
shane86f5bdb2009-10-24 02:00:07 +00003224 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3225 return 1;
drh01b41712005-08-29 23:06:23 +00003226#endif
drh98d312f2012-10-25 15:23:14 +00003227 }
3228 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00003229
drh44c2eb12003-04-30 11:38:26 +00003230 /* Go ahead and open the database file if it already exists. If the
3231 ** file does not exist, delay opening it. This prevents empty database
3232 ** files from being created if a user mistypes the database name argument
3233 ** to the sqlite command-line tool.
3234 */
drhc8d74412004-08-31 23:41:26 +00003235 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003236 open_db(&data);
3237 }
3238
drh22fbcb82004-02-01 01:22:50 +00003239 /* Process the initialization file if there is one. If no -init option
3240 ** is given on the command line, look for a file named ~/.sqliterc and
3241 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003242 */
shane86f5bdb2009-10-24 02:00:07 +00003243 rc = process_sqliterc(&data,zInitFile);
3244 if( rc>0 ){
3245 return rc;
3246 }
drh44c2eb12003-04-30 11:38:26 +00003247
drh22fbcb82004-02-01 01:22:50 +00003248 /* Make a second pass through the command-line argument and set
3249 ** options. This second pass is delayed until after the initialization
3250 ** file is processed so that the command-line arguments will override
3251 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003252 */
drh98d312f2012-10-25 15:23:14 +00003253 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00003254 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003255 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00003256 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003257 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003258 i++;
3259 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003260 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003261 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003262 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003263 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003264 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003265 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003266 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003267 }else if( strcmp(z,"-csv")==0 ){
3268 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003269 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003270 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003271 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00003272 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003273 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003274 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00003275 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003276 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003277 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003278 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003279 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003280 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003281 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003282 }else if( strcmp(z,"-stats")==0 ){
3283 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003284 }else if( strcmp(z,"-bail")==0 ){
3285 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003286 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003287 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003288 return 0;
drhc28490c2006-10-26 14:25:58 +00003289 }else if( strcmp(z,"-interactive")==0 ){
3290 stdin_is_interactive = 1;
3291 }else if( strcmp(z,"-batch")==0 ){
3292 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003293 }else if( strcmp(z,"-heap")==0 ){
3294 i++;
drh7d9f3942013-04-03 01:26:54 +00003295 }else if( strcmp(z,"-mmap")==0 ){
3296 i++;
drha7e61d82011-03-12 17:02:57 +00003297 }else if( strcmp(z,"-vfs")==0 ){
3298 i++;
drh6f25e892011-07-08 17:02:57 +00003299#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003300 }else if( strcmp(z,"-vfstrace")==0 ){
3301 i++;
drh6f25e892011-07-08 17:02:57 +00003302#endif
3303#ifdef SQLITE_ENABLE_MULTIPLEX
3304 }else if( strcmp(z,"-multiplex")==0 ){
3305 i++;
3306#endif
drhcc3b4f82012-02-07 14:13:50 +00003307 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003308 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003309 }else if( strcmp(z,"-cmd")==0 ){
3310 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00003311 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00003312 if( z[0]=='.' ){
3313 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00003314 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00003315 }else{
3316 open_db(&data);
3317 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3318 if( zErrMsg!=0 ){
3319 fprintf(stderr,"Error: %s\n", zErrMsg);
3320 if( bail_on_error ) return rc!=0 ? rc : 1;
3321 }else if( rc!=0 ){
3322 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3323 if( bail_on_error ) return rc;
3324 }
3325 }
drh1e5d0e92000-05-31 23:33:17 +00003326 }else{
shane86f5bdb2009-10-24 02:00:07 +00003327 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003328 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003329 return 1;
3330 }
3331 }
drh44c2eb12003-04-30 11:38:26 +00003332
drh22fbcb82004-02-01 01:22:50 +00003333 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003334 /* Run just the command that follows the database name
3335 */
drh22fbcb82004-02-01 01:22:50 +00003336 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003337 rc = do_meta_command(zFirstCmd, &data);
drh99b39082013-04-17 12:19:48 +00003338 if( rc==2 ) rc = 0;
drh6ff13852001-11-25 13:18:23 +00003339 }else{
drh44c2eb12003-04-30 11:38:26 +00003340 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003341 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003342 if( zErrMsg!=0 ){
3343 fprintf(stderr,"Error: %s\n", zErrMsg);
3344 return rc!=0 ? rc : 1;
3345 }else if( rc!=0 ){
3346 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3347 return rc;
drh6ff13852001-11-25 13:18:23 +00003348 }
drh75897232000-05-29 14:26:00 +00003349 }
3350 }else{
drh44c2eb12003-04-30 11:38:26 +00003351 /* Run commands received from standard input
3352 */
drhc28490c2006-10-26 14:25:58 +00003353 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003354 char *zHome;
3355 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003356 int nHistory;
drh75897232000-05-29 14:26:00 +00003357 printf(
drh743e0032011-12-12 16:51:50 +00003358 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003359 "Enter \".help\" for instructions\n"
3360 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003361 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003362 );
drh67505e72002-04-19 12:34:06 +00003363 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003364 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003365 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003366 if( (zHistory = malloc(nHistory))!=0 ){
3367 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3368 }
drh67505e72002-04-19 12:34:06 +00003369 }
danielk19774af00c62005-01-23 23:43:21 +00003370#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003371 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003372#endif
drhc28490c2006-10-26 14:25:58 +00003373 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003374 if( zHistory ){
3375 stifle_history(100);
3376 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003377 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003378 }
drhdaffd0e2001-04-11 14:28:42 +00003379 }else{
drhc28490c2006-10-26 14:25:58 +00003380 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003381 }
3382 }
drh33048c02001-10-01 14:29:22 +00003383 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003384 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003385 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003386 }
drhc28490c2006-10-26 14:25:58 +00003387 return rc;
drh75897232000-05-29 14:26:00 +00003388}