blob: 9f2f46bd18bf2c5f4e00ca93fc63e8a0a415e6c7 [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);
1112 }
1113
1114 return 0;
1115}
1116
1117/*
shane626a6e42009-10-22 17:30:15 +00001118** Execute a statement or set of statements. Print
1119** any result rows/columns depending on the current mode
1120** set via the supplied callback.
1121**
1122** This is very similar to SQLite's built-in sqlite3_exec()
1123** function except it takes a slightly different callback
1124** and callback data argument.
1125*/
1126static int shell_exec(
1127 sqlite3 *db, /* An open database */
1128 const char *zSql, /* SQL to be evaluated */
1129 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1130 /* (not the same as sqlite3_exec) */
1131 struct callback_data *pArg, /* Pointer to struct callback_data */
1132 char **pzErrMsg /* Error msg written here */
1133){
dan4564ced2010-01-05 04:59:56 +00001134 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1135 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001136 int rc2;
dan4564ced2010-01-05 04:59:56 +00001137 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001138
1139 if( pzErrMsg ){
1140 *pzErrMsg = NULL;
1141 }
1142
shaneb9fc17d2009-10-22 21:23:35 +00001143 while( zSql[0] && (SQLITE_OK == rc) ){
1144 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1145 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001146 if( pzErrMsg ){
1147 *pzErrMsg = save_err_msg(db);
1148 }
1149 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001150 if( !pStmt ){
1151 /* this happens for a comment or white-space */
1152 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001153 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001154 continue;
1155 }
shane626a6e42009-10-22 17:30:15 +00001156
shaneh642d8b82010-07-28 16:05:34 +00001157 /* save off the prepared statment handle and reset row count */
1158 if( pArg ){
1159 pArg->pStmt = pStmt;
1160 pArg->cnt = 0;
1161 }
1162
shanehb7977c52010-01-18 18:17:10 +00001163 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001164 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001165 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001166 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001167 }
shanehb7977c52010-01-18 18:17:10 +00001168
drh7e02e5e2011-12-06 19:44:51 +00001169 /* Output TESTCTRL_EXPLAIN text of requested */
1170 if( pArg && pArg->mode==MODE_Explain ){
1171 const char *zExplain = 0;
1172 sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1173 if( zExplain && zExplain[0] ){
1174 fprintf(pArg->out, "%s", zExplain);
1175 }
1176 }
1177
shaneb9fc17d2009-10-22 21:23:35 +00001178 /* perform the first step. this will tell us if we
1179 ** have a result set or not and how wide it is.
1180 */
1181 rc = sqlite3_step(pStmt);
1182 /* if we have a result set... */
1183 if( SQLITE_ROW == rc ){
1184 /* if we have a callback... */
1185 if( xCallback ){
1186 /* allocate space for col name ptr, value ptr, and type */
1187 int nCol = sqlite3_column_count(pStmt);
1188 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1189 if( !pData ){
1190 rc = SQLITE_NOMEM;
1191 }else{
1192 char **azCols = (char **)pData; /* Names of result columns */
1193 char **azVals = &azCols[nCol]; /* Results */
1194 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1195 int i;
1196 assert(sizeof(int) <= sizeof(char *));
1197 /* save off ptrs to column names */
1198 for(i=0; i<nCol; i++){
1199 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1200 }
shaneb9fc17d2009-10-22 21:23:35 +00001201 do{
1202 /* extract the data and data types */
1203 for(i=0; i<nCol; i++){
1204 azVals[i] = (char *)sqlite3_column_text(pStmt, i);
1205 aiTypes[i] = sqlite3_column_type(pStmt, i);
1206 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1207 rc = SQLITE_NOMEM;
1208 break; /* from for */
1209 }
1210 } /* end for */
1211
1212 /* if data and types extracted successfully... */
1213 if( SQLITE_ROW == rc ){
1214 /* call the supplied callback with the result row data */
1215 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1216 rc = SQLITE_ABORT;
1217 }else{
1218 rc = sqlite3_step(pStmt);
1219 }
1220 }
1221 } while( SQLITE_ROW == rc );
1222 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001223 }
1224 }else{
1225 do{
1226 rc = sqlite3_step(pStmt);
1227 } while( rc == SQLITE_ROW );
1228 }
1229 }
1230
shaneh642d8b82010-07-28 16:05:34 +00001231 /* print usage stats if stats on */
1232 if( pArg && pArg->statsOn ){
1233 display_stats(db, pArg, 0);
1234 }
1235
dan4564ced2010-01-05 04:59:56 +00001236 /* Finalize the statement just executed. If this fails, save a
1237 ** copy of the error message. Otherwise, set zSql to point to the
1238 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001239 rc2 = sqlite3_finalize(pStmt);
1240 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001241 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001242 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001243 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001244 }else if( pzErrMsg ){
1245 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001246 }
shaneh642d8b82010-07-28 16:05:34 +00001247
1248 /* clear saved stmt handle */
1249 if( pArg ){
1250 pArg->pStmt = NULL;
1251 }
shane626a6e42009-10-22 17:30:15 +00001252 }
shaneb9fc17d2009-10-22 21:23:35 +00001253 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001254
1255 return rc;
1256}
1257
drhdd3d4592004-08-30 01:54:05 +00001258
drh33048c02001-10-01 14:29:22 +00001259/*
drh4c653a02000-06-07 01:27:47 +00001260** This is a different callback routine used for dumping the database.
1261** Each row received by this callback consists of a table name,
1262** the table type ("index" or "table") and SQL to create the table.
1263** This routine should print text sufficient to recreate the table.
1264*/
1265static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001266 int rc;
1267 const char *zTable;
1268 const char *zType;
1269 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001270 const char *zPrepStmt = 0;
drhdaffd0e2001-04-11 14:28:42 +00001271 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001272
drh902b9ee2008-12-05 17:17:07 +00001273 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001274 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001275 zTable = azArg[0];
1276 zType = azArg[1];
1277 zSql = azArg[2];
1278
drh00b950d2005-09-11 02:03:03 +00001279 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001280 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh00b950d2005-09-11 02:03:03 +00001281 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
1282 fprintf(p->out, "ANALYZE sqlite_master;\n");
1283 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1284 return 0;
drh45e29d82006-11-20 16:21:10 +00001285 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1286 char *zIns;
1287 if( !p->writableSchema ){
1288 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1289 p->writableSchema = 1;
1290 }
1291 zIns = sqlite3_mprintf(
1292 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1293 "VALUES('table','%q','%q',0,'%q');",
1294 zTable, zTable, zSql);
1295 fprintf(p->out, "%s\n", zIns);
1296 sqlite3_free(zIns);
1297 return 0;
drh00b950d2005-09-11 02:03:03 +00001298 }else{
1299 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001300 }
danielk19772a02e332004-06-05 08:04:36 +00001301
1302 if( strcmp(zType, "table")==0 ){
1303 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001304 char *zSelect = 0;
1305 char *zTableInfo = 0;
1306 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001307 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001308
1309 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1310 zTableInfo = appendText(zTableInfo, zTable, '"');
1311 zTableInfo = appendText(zTableInfo, ");", 0);
1312
1313 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001314 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001315 if( rc!=SQLITE_OK || !pTableInfo ){
1316 return 1;
1317 }
1318
1319 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001320 /* Always quote the table name, even if it appears to be pure ascii,
1321 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1322 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001323 if( zTmp ){
1324 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001325 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001326 }
1327 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1328 rc = sqlite3_step(pTableInfo);
1329 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001330 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001331 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001332 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001333 rc = sqlite3_step(pTableInfo);
1334 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001335 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001336 }else{
1337 zSelect = appendText(zSelect, ") ", 0);
1338 }
drh157e29a2009-05-21 15:15:00 +00001339 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001340 }
1341 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001342 if( rc!=SQLITE_OK || nRow==0 ){
1343 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001344 return 1;
1345 }
1346 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1347 zSelect = appendText(zSelect, zTable, '"');
1348
drh2f464a02011-10-13 00:41:49 +00001349 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001350 if( rc==SQLITE_CORRUPT ){
1351 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001352 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001353 }
drh85e72432012-04-11 11:38:53 +00001354 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001355 }
drh4c653a02000-06-07 01:27:47 +00001356 return 0;
1357}
1358
1359/*
drh45e29d82006-11-20 16:21:10 +00001360** Run zQuery. Use dump_callback() as the callback routine so that
1361** the contents of the query are output as SQL statements.
1362**
drhdd3d4592004-08-30 01:54:05 +00001363** If we get a SQLITE_CORRUPT error, rerun the query after appending
1364** "ORDER BY rowid DESC" to the end.
1365*/
1366static int run_schema_dump_query(
1367 struct callback_data *p,
drh2f464a02011-10-13 00:41:49 +00001368 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001369){
1370 int rc;
drh2f464a02011-10-13 00:41:49 +00001371 char *zErr = 0;
1372 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001373 if( rc==SQLITE_CORRUPT ){
1374 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001375 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001376 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1377 if( zErr ){
1378 fprintf(p->out, "/****** %s ******/\n", zErr);
1379 sqlite3_free(zErr);
1380 zErr = 0;
1381 }
drhdd3d4592004-08-30 01:54:05 +00001382 zQ2 = malloc( len+100 );
1383 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001384 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001385 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1386 if( rc ){
1387 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1388 }else{
1389 rc = SQLITE_CORRUPT;
1390 }
1391 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001392 free(zQ2);
1393 }
1394 return rc;
1395}
1396
1397/*
drh75897232000-05-29 14:26:00 +00001398** Text of a help message
1399*/
persicom1d0b8722002-04-18 02:53:04 +00001400static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001401 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +00001402 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +00001403 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +00001404 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001405 " If TABLE specified, only dump tables matching\n"
1406 " LIKE pattern TABLE.\n"
drhdaffd0e2001-04-11 14:28:42 +00001407 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +00001408 ".exit Exit this program\n"
shanehe2aa9d72009-11-06 17:20:17 +00001409 ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n"
1410 " With no args, it turns EXPLAIN on.\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001411 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001412 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001413 ".import FILE TABLE Import data from FILE into TABLE\n"
shane86f5bdb2009-10-24 02:00:07 +00001414 ".indices ?TABLE? Show names of all indices\n"
1415 " If TABLE specified, only show indices for tables\n"
1416 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001417#ifdef SQLITE_ENABLE_IOTRACE
1418 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1419#endif
drh70df4fe2006-06-13 15:12:21 +00001420#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001421 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001422#endif
drh127f9d72010-02-23 01:47:00 +00001423 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001424 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +00001425 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001426 " column Left-aligned columns. (See .width)\n"
1427 " html HTML <table> code\n"
1428 " insert SQL insert statements for TABLE\n"
1429 " line One value per line\n"
1430 " list Values delimited by .separator string\n"
1431 " tabs Tab-separated values\n"
1432 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001433 ".nullvalue STRING Use STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +00001434 ".output FILENAME Send output to FILENAME\n"
1435 ".output stdout Send output to the screen\n"
drh078b1fd2012-09-21 13:40:02 +00001436 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001437 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001438 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001439 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001440 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +00001441 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001442 " If TABLE specified, only show tables matching\n"
1443 " LIKE pattern TABLE.\n"
drhb860bc92004-08-04 15:16:55 +00001444 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +00001445 ".show Show the current values for various settings\n"
shaneh642d8b82010-07-28 16:05:34 +00001446 ".stats ON|OFF Turn stats on or off\n"
shane86f5bdb2009-10-24 02:00:07 +00001447 ".tables ?TABLE? List names of tables\n"
1448 " If TABLE specified, only list tables matching\n"
1449 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001450 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh42f64e52012-04-04 16:56:23 +00001451 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001452 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001453 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh75897232000-05-29 14:26:00 +00001454;
1455
shaneb320ccd2009-10-21 03:42:58 +00001456static char zTimerHelp[] =
1457 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
1458;
1459
drhdaffd0e2001-04-11 14:28:42 +00001460/* Forward reference */
drhc28490c2006-10-26 14:25:58 +00001461static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +00001462
drh75897232000-05-29 14:26:00 +00001463/*
drh44c2eb12003-04-30 11:38:26 +00001464** Make sure the database is open. If it is not, then open it. If
1465** the database fails to open, print an error message and exit.
1466*/
1467static void open_db(struct callback_data *p){
1468 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001469 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001470 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001471 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001472 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1473 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1474 shellstaticFunc, 0, 0);
1475 }
1476 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001477 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001478 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +00001479 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001480 }
drhc2e87a32006-06-27 15:16:14 +00001481#ifndef SQLITE_OMIT_LOAD_EXTENSION
1482 sqlite3_enable_load_extension(p->db, 1);
1483#endif
drh44c2eb12003-04-30 11:38:26 +00001484 }
1485}
1486
1487/*
drhfeac5f82004-08-01 00:10:45 +00001488** Do C-language style dequoting.
1489**
1490** \t -> tab
1491** \n -> newline
1492** \r -> carriage return
1493** \NNN -> ascii character NNN in octal
1494** \\ -> backslash
1495*/
1496static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001497 int i, j;
1498 char c;
drhfeac5f82004-08-01 00:10:45 +00001499 for(i=j=0; (c = z[i])!=0; i++, j++){
1500 if( c=='\\' ){
1501 c = z[++i];
1502 if( c=='n' ){
1503 c = '\n';
1504 }else if( c=='t' ){
1505 c = '\t';
1506 }else if( c=='r' ){
1507 c = '\r';
1508 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001509 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001510 if( z[i+1]>='0' && z[i+1]<='7' ){
1511 i++;
1512 c = (c<<3) + z[i] - '0';
1513 if( z[i+1]>='0' && z[i+1]<='7' ){
1514 i++;
1515 c = (c<<3) + z[i] - '0';
1516 }
1517 }
1518 }
1519 }
1520 z[j] = c;
1521 }
1522 z[j] = 0;
1523}
1524
1525/*
drh348d19c2013-06-03 12:47:43 +00001526** Return the value of a hexadecimal digit. Return -1 if the input
1527** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001528*/
drh348d19c2013-06-03 12:47:43 +00001529static int hexDigitValue(char c){
1530 if( c>='0' && c<='9' ) return c - '0';
1531 if( c>='a' && c<='f' ) return c - 'a' + 10;
1532 if( c>='A' && c<='F' ) return c - 'A' + 10;
1533 return -1;
drhc28490c2006-10-26 14:25:58 +00001534}
1535
1536/*
drh7d9f3942013-04-03 01:26:54 +00001537** Interpret zArg as an integer value, possibly with suffixes.
1538*/
1539static sqlite3_int64 integerValue(const char *zArg){
1540 sqlite3_int64 v = 0;
1541 static const struct { char *zSuffix; int iMult; } aMult[] = {
1542 { "KiB", 1024 },
1543 { "MiB", 1024*1024 },
1544 { "GiB", 1024*1024*1024 },
1545 { "KB", 1000 },
1546 { "MB", 1000000 },
1547 { "GB", 1000000000 },
1548 { "K", 1000 },
1549 { "M", 1000000 },
1550 { "G", 1000000000 },
1551 };
1552 int i;
1553 int isNeg = 0;
1554 if( zArg[0]=='-' ){
1555 isNeg = 1;
1556 zArg++;
1557 }else if( zArg[0]=='+' ){
1558 zArg++;
1559 }
drh348d19c2013-06-03 12:47:43 +00001560 if( zArg[0]=='0' && zArg[1]=='x' ){
1561 int x;
1562 zArg += 2;
1563 while( (x = hexDigitValue(zArg[0]))>=0 ){
1564 v = (v<<4) + x;
1565 zArg++;
1566 }
1567 }else{
1568 while( IsDigit(zArg[0]) ){
1569 v = v*10 + zArg[0] - '0';
1570 zArg++;
1571 }
drh7d9f3942013-04-03 01:26:54 +00001572 }
drhc2bed0a2013-05-24 11:57:50 +00001573 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00001574 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1575 v *= aMult[i].iMult;
1576 break;
1577 }
1578 }
1579 return isNeg? -v : v;
1580}
1581
1582/*
drh348d19c2013-06-03 12:47:43 +00001583** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1584** for TRUE and FALSE. Return the integer value if appropriate.
1585*/
1586static int booleanValue(char *zArg){
1587 int i;
1588 if( zArg[0]=='0' && zArg[1]=='x' ){
1589 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1590 }else{
1591 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1592 }
1593 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1594 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1595 return 1;
1596 }
1597 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1598 return 0;
1599 }
1600 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1601 zArg);
1602 return 0;
1603}
1604
1605/*
drh42f64e52012-04-04 16:56:23 +00001606** Close an output file, assuming it is not stderr or stdout
1607*/
1608static void output_file_close(FILE *f){
1609 if( f && f!=stdout && f!=stderr ) fclose(f);
1610}
1611
1612/*
1613** Try to open an output file. The names "stdout" and "stderr" are
1614** recognized and do the right thing. NULL is returned if the output
1615** filename is "off".
1616*/
1617static FILE *output_file_open(const char *zFile){
1618 FILE *f;
1619 if( strcmp(zFile,"stdout")==0 ){
1620 f = stdout;
1621 }else if( strcmp(zFile, "stderr")==0 ){
1622 f = stderr;
1623 }else if( strcmp(zFile, "off")==0 ){
1624 f = 0;
1625 }else{
1626 f = fopen(zFile, "wb");
1627 if( f==0 ){
1628 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1629 }
1630 }
1631 return f;
1632}
1633
1634/*
1635** A routine for handling output from sqlite3_trace().
1636*/
1637static void sql_trace_callback(void *pArg, const char *z){
1638 FILE *f = (FILE*)pArg;
1639 if( f ) fprintf(f, "%s\n", z);
1640}
1641
1642/*
drhd8621b92012-04-17 09:09:33 +00001643** A no-op routine that runs with the ".breakpoint" doc-command. This is
1644** a useful spot to set a debugger breakpoint.
1645*/
1646static void test_breakpoint(void){
1647 static int nCall = 0;
1648 nCall++;
1649}
1650
1651/*
drh75897232000-05-29 14:26:00 +00001652** If an input line begins with "." then invoke this routine to
1653** process that line.
drh67505e72002-04-19 12:34:06 +00001654**
drh47ad6842006-11-08 12:25:42 +00001655** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001656*/
drh44c2eb12003-04-30 11:38:26 +00001657static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001658 int i = 1;
1659 int nArg = 0;
1660 int n, c;
drh67505e72002-04-19 12:34:06 +00001661 int rc = 0;
drh75897232000-05-29 14:26:00 +00001662 char *azArg[50];
1663
1664 /* Parse the input line into tokens.
1665 */
1666 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00001667 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001668 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001669 if( zLine[i]=='\'' || zLine[i]=='"' ){
1670 int delim = zLine[i++];
1671 azArg[nArg++] = &zLine[i];
1672 while( zLine[i] && zLine[i]!=delim ){ i++; }
1673 if( zLine[i]==delim ){
1674 zLine[i++] = 0;
1675 }
drhfeac5f82004-08-01 00:10:45 +00001676 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001677 }else{
1678 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00001679 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001680 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001681 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001682 }
1683 }
1684
1685 /* Process the input line.
1686 */
shane9bd1b442009-10-23 01:27:39 +00001687 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00001688 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001689 c = azArg[0][0];
drhbc46f022013-01-23 18:53:23 +00001690 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1691 const char *zDestFile = 0;
1692 const char *zDb = 0;
1693 const char *zKey = 0;
drh9ff849f2009-02-04 20:55:57 +00001694 sqlite3 *pDest;
1695 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00001696 int j;
1697 for(j=1; j<nArg; j++){
1698 const char *z = azArg[j];
1699 if( z[0]=='-' ){
1700 while( z[0]=='-' ) z++;
1701 if( strcmp(z,"key")==0 && j<nArg-1 ){
1702 zKey = azArg[++j];
1703 }else
1704 {
1705 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1706 return 1;
1707 }
1708 }else if( zDestFile==0 ){
1709 zDestFile = azArg[j];
1710 }else if( zDb==0 ){
1711 zDb = zDestFile;
1712 zDestFile = azArg[j];
1713 }else{
1714 fprintf(stderr, "too many arguments to .backup\n");
1715 return 1;
1716 }
drh9ff849f2009-02-04 20:55:57 +00001717 }
drhbc46f022013-01-23 18:53:23 +00001718 if( zDestFile==0 ){
1719 fprintf(stderr, "missing FILENAME argument on .backup\n");
1720 return 1;
1721 }
1722 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00001723 rc = sqlite3_open(zDestFile, &pDest);
1724 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00001725 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00001726 sqlite3_close(pDest);
1727 return 1;
1728 }
drhbc46f022013-01-23 18:53:23 +00001729#ifdef SQLITE_HAS_CODEC
1730 sqlite3_key(pDest, zKey, (int)strlen(zKey));
1731#else
1732 (void)zKey;
1733#endif
drhdc2c4912009-02-04 22:46:47 +00001734 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00001735 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1736 if( pBackup==0 ){
1737 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1738 sqlite3_close(pDest);
1739 return 1;
1740 }
1741 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1742 sqlite3_backup_finish(pBackup);
1743 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00001744 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00001745 }else{
1746 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00001747 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00001748 }
1749 sqlite3_close(pDest);
1750 }else
1751
shanehe2aa9d72009-11-06 17:20:17 +00001752 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
drhc49f44e2006-10-26 18:15:42 +00001753 bail_on_error = booleanValue(azArg[1]);
1754 }else
1755
drhd8621b92012-04-17 09:09:33 +00001756 /* The undocumented ".breakpoint" command causes a call to the no-op
1757 ** routine named test_breakpoint().
1758 */
1759 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
1760 test_breakpoint();
1761 }else
1762
shanehe2aa9d72009-11-06 17:20:17 +00001763 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
jplyon672a1ed2003-05-11 20:07:05 +00001764 struct callback_data data;
1765 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001766 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001767 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001768 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001769 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001770 data.colWidth[0] = 3;
1771 data.colWidth[1] = 15;
1772 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001773 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001774 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001775 if( zErrMsg ){
1776 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001777 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00001778 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00001779 }
1780 }else
1781
shanehe2aa9d72009-11-06 17:20:17 +00001782 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
drh44c2eb12003-04-30 11:38:26 +00001783 open_db(p);
drhf1dfc4f2009-09-23 15:51:35 +00001784 /* When playing back a "dump", the content might appear in an order
1785 ** which causes immediate foreign key constraints to be violated.
1786 ** So disable foreign-key constraint enforcement to prevent problems. */
1787 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00001788 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001789 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00001790 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001791 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00001792 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001793 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001794 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001795 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00001796 );
1797 run_schema_dump_query(p,
1798 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00001799 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00001800 );
drh2f464a02011-10-13 00:41:49 +00001801 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001802 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00001803 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00001804 );
drh4c653a02000-06-07 01:27:47 +00001805 }else{
1806 int i;
drhdd3d4592004-08-30 01:54:05 +00001807 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001808 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001809 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001810 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001811 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00001812 " AND sql NOT NULL");
1813 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00001814 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001815 "WHERE sql NOT NULL"
1816 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00001817 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00001818 );
danielk1977bc6ada42004-06-30 08:20:16 +00001819 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001820 }
1821 }
drh45e29d82006-11-20 16:21:10 +00001822 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00001823 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00001824 p->writableSchema = 0;
1825 }
drh56197952011-10-13 16:30:13 +00001826 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1827 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00001828 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001829 }else
drh75897232000-05-29 14:26:00 +00001830
shanehe2aa9d72009-11-06 17:20:17 +00001831 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001832 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001833 }else
1834
drhd3ac7d92013-01-25 18:33:43 +00001835 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00001836 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00001837 rc = 2;
drh75897232000-05-29 14:26:00 +00001838 }else
1839
shanehe2aa9d72009-11-06 17:20:17 +00001840 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001841 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001842 if(val == 1) {
1843 if(!p->explainPrev.valid) {
1844 p->explainPrev.valid = 1;
1845 p->explainPrev.mode = p->mode;
1846 p->explainPrev.showHeader = p->showHeader;
1847 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1848 }
1849 /* We could put this code under the !p->explainValid
1850 ** condition so that it does not execute if we are already in
1851 ** explain mode. However, always executing it allows us an easy
1852 ** was to reset to explain mode in case the user previously
1853 ** did an .explain followed by a .width, .mode or .header
1854 ** command.
1855 */
danielk19770d78bae2008-01-03 07:09:48 +00001856 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001857 p->showHeader = 1;
1858 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001859 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001860 p->colWidth[1] = 13; /* opcode */
1861 p->colWidth[2] = 4; /* P1 */
1862 p->colWidth[3] = 4; /* P2 */
1863 p->colWidth[4] = 4; /* P3 */
1864 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001865 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001866 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001867 }else if (p->explainPrev.valid) {
1868 p->explainPrev.valid = 0;
1869 p->mode = p->explainPrev.mode;
1870 p->showHeader = p->explainPrev.showHeader;
1871 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1872 }
drh75897232000-05-29 14:26:00 +00001873 }else
1874
drhc28490c2006-10-26 14:25:58 +00001875 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
shanehe2aa9d72009-11-06 17:20:17 +00001876 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
drhc28490c2006-10-26 14:25:58 +00001877 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001878 }else
1879
1880 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001881 fprintf(stderr,"%s",zHelp);
shaneb320ccd2009-10-21 03:42:58 +00001882 if( HAS_TIMER ){
1883 fprintf(stderr,"%s",zTimerHelp);
1884 }
drh75897232000-05-29 14:26:00 +00001885 }else
1886
shanehe2aa9d72009-11-06 17:20:17 +00001887 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
drhfeac5f82004-08-01 00:10:45 +00001888 char *zTable = azArg[2]; /* Insert data into this table */
1889 char *zFile = azArg[1]; /* The file from which to extract data */
shane916f9612009-10-23 00:37:15 +00001890 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00001891 int nCol; /* Number of columns in the table */
1892 int nByte; /* Number of bytes in an SQL string */
1893 int i, j; /* Loop counters */
1894 int nSep; /* Number of bytes in p->separator[] */
1895 char *zSql; /* An SQL statement */
1896 char *zLine; /* A single line of input from the file */
1897 char **azCol; /* zLine[] broken up into columns */
1898 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001899 FILE *in; /* The input file */
1900 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001901
drha543c822006-06-08 16:10:14 +00001902 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001903 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001904 if( nSep==0 ){
shane916f9612009-10-23 00:37:15 +00001905 fprintf(stderr, "Error: non-null separator required for import\n");
1906 return 1;
drhfeac5f82004-08-01 00:10:45 +00001907 }
drh7b075e32011-09-28 01:10:00 +00001908 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00001909 if( zSql==0 ){
1910 fprintf(stderr, "Error: out of memory\n");
1911 return 1;
1912 }
drh4f21c4a2008-12-10 22:15:00 +00001913 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001914 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001915 sqlite3_free(zSql);
1916 if( rc ){
shane916f9612009-10-23 00:37:15 +00001917 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001918 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001919 return 1;
drhfeac5f82004-08-01 00:10:45 +00001920 }
shane916f9612009-10-23 00:37:15 +00001921 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00001922 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001923 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00001924 if( nCol==0 ) return 0; /* no columns, no error */
drhfeac5f82004-08-01 00:10:45 +00001925 zSql = malloc( nByte + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00001926 if( zSql==0 ){
1927 fprintf(stderr, "Error: out of memory\n");
1928 return 1;
1929 }
drh7b075e32011-09-28 01:10:00 +00001930 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001931 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001932 for(i=1; i<nCol; i++){
1933 zSql[j++] = ',';
1934 zSql[j++] = '?';
1935 }
1936 zSql[j++] = ')';
1937 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001938 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001939 free(zSql);
1940 if( rc ){
1941 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00001942 if (pStmt) sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001943 return 1;
drhfeac5f82004-08-01 00:10:45 +00001944 }
1945 in = fopen(zFile, "rb");
1946 if( in==0 ){
shane9bd1b442009-10-23 01:27:39 +00001947 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhfeac5f82004-08-01 00:10:45 +00001948 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00001949 return 1;
drhfeac5f82004-08-01 00:10:45 +00001950 }
1951 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001952 if( azCol==0 ){
shane916f9612009-10-23 00:37:15 +00001953 fprintf(stderr, "Error: out of memory\n");
drh43617e92006-03-06 20:55:46 +00001954 fclose(in);
shane916f9612009-10-23 00:37:15 +00001955 sqlite3_finalize(pStmt);
1956 return 1;
drh43617e92006-03-06 20:55:46 +00001957 }
drhfeac5f82004-08-01 00:10:45 +00001958 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1959 zCommit = "COMMIT";
drh18f52e02012-01-16 16:56:31 +00001960 while( (zLine = local_getline(0, in, 1))!=0 ){
1961 char *z, c;
1962 int inQuote = 0;
drhb860bc92004-08-04 15:16:55 +00001963 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001964 azCol[0] = zLine;
drh18f52e02012-01-16 16:56:31 +00001965 for(i=0, z=zLine; (c = *z)!=0; z++){
1966 if( c=='"' ) inQuote = !inQuote;
1967 if( c=='\n' ) lineno++;
1968 if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
drhfeac5f82004-08-01 00:10:45 +00001969 *z = 0;
1970 i++;
drhb860bc92004-08-04 15:16:55 +00001971 if( i<nCol ){
1972 azCol[i] = &z[nSep];
1973 z += nSep-1;
1974 }
drhfeac5f82004-08-01 00:10:45 +00001975 }
shane916f9612009-10-23 00:37:15 +00001976 } /* end for */
drh1cd7f832005-08-05 18:50:51 +00001977 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001978 if( i+1!=nCol ){
shane916f9612009-10-23 00:37:15 +00001979 fprintf(stderr,
1980 "Error: %s line %d: expected %d columns of data but found %d\n",
1981 zFile, lineno, nCol, i+1);
drhb860bc92004-08-04 15:16:55 +00001982 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001983 free(zLine);
shane916f9612009-10-23 00:37:15 +00001984 rc = 1;
1985 break; /* from while */
drhb860bc92004-08-04 15:16:55 +00001986 }
drhfeac5f82004-08-01 00:10:45 +00001987 for(i=0; i<nCol; i++){
drh18f52e02012-01-16 16:56:31 +00001988 if( azCol[i][0]=='"' ){
1989 int k;
1990 for(z=azCol[i], j=1, k=0; z[j]; j++){
1991 if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
1992 z[k++] = z[j];
1993 }
1994 z[k] = 0;
1995 }
drhfeac5f82004-08-01 00:10:45 +00001996 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1997 }
1998 sqlite3_step(pStmt);
1999 rc = sqlite3_reset(pStmt);
2000 free(zLine);
2001 if( rc!=SQLITE_OK ){
2002 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
2003 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00002004 rc = 1;
shane916f9612009-10-23 00:37:15 +00002005 break; /* from while */
drhfeac5f82004-08-01 00:10:45 +00002006 }
shane916f9612009-10-23 00:37:15 +00002007 } /* end while */
drhfeac5f82004-08-01 00:10:45 +00002008 free(azCol);
2009 fclose(in);
2010 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00002011 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00002012 }else
2013
shanehe2aa9d72009-11-06 17:20:17 +00002014 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002015 struct callback_data data;
2016 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002017 open_db(p);
drh75897232000-05-29 14:26:00 +00002018 memcpy(&data, p, sizeof(data));
2019 data.showHeader = 0;
2020 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00002021 if( nArg==1 ){
2022 rc = sqlite3_exec(p->db,
2023 "SELECT name FROM sqlite_master "
2024 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2025 "UNION ALL "
2026 "SELECT name FROM sqlite_temp_master "
2027 "WHERE type='index' "
2028 "ORDER BY 1",
2029 callback, &data, &zErrMsg
2030 );
2031 }else{
2032 zShellStatic = azArg[1];
2033 rc = sqlite3_exec(p->db,
2034 "SELECT name FROM sqlite_master "
2035 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2036 "UNION ALL "
2037 "SELECT name FROM sqlite_temp_master "
2038 "WHERE type='index' AND tbl_name LIKE shellstatic() "
2039 "ORDER BY 1",
2040 callback, &data, &zErrMsg
2041 );
2042 zShellStatic = 0;
2043 }
drh75897232000-05-29 14:26:00 +00002044 if( zErrMsg ){
2045 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002046 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002047 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00002048 }else if( rc != SQLITE_OK ){
2049 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2050 rc = 1;
drh75897232000-05-29 14:26:00 +00002051 }
2052 }else
2053
drhae5e4452007-05-03 17:18:36 +00002054#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00002055 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002056 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00002057 if( iotrace && iotrace!=stdout ) fclose(iotrace);
2058 iotrace = 0;
2059 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00002060 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00002061 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00002062 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002063 iotrace = stdout;
2064 }else{
2065 iotrace = fopen(azArg[1], "w");
2066 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00002067 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00002068 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00002069 rc = 1;
drhb0603412007-02-28 04:47:26 +00002070 }else{
mlcreech3a00f902008-03-04 17:45:01 +00002071 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00002072 }
2073 }
2074 }else
drhae5e4452007-05-03 17:18:36 +00002075#endif
drhb0603412007-02-28 04:47:26 +00002076
drh70df4fe2006-06-13 15:12:21 +00002077#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002078 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
2079 const char *zFile, *zProc;
2080 char *zErrMsg = 0;
drh1e397f82006-06-08 15:28:43 +00002081 zFile = azArg[1];
2082 zProc = nArg>=3 ? azArg[2] : 0;
2083 open_db(p);
2084 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2085 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002086 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00002087 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00002088 rc = 1;
drh1e397f82006-06-08 15:28:43 +00002089 }
2090 }else
drh70df4fe2006-06-13 15:12:21 +00002091#endif
drh1e397f82006-06-08 15:28:43 +00002092
drhc8ba2122011-03-23 11:16:22 +00002093 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
drh127f9d72010-02-23 01:47:00 +00002094 const char *zFile = azArg[1];
drh42f64e52012-04-04 16:56:23 +00002095 output_file_close(p->pLog);
2096 p->pLog = output_file_open(zFile);
drh127f9d72010-02-23 01:47:00 +00002097 }else
2098
shanehe2aa9d72009-11-06 17:20:17 +00002099 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
drh4f21c4a2008-12-10 22:15:00 +00002100 int n2 = strlen30(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002101 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002102 ||
shanehe2aa9d72009-11-06 17:20:17 +00002103 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002104 p->mode = MODE_Line;
shanehe2aa9d72009-11-06 17:20:17 +00002105 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
persicom7e2dfdd2002-04-18 02:46:52 +00002106 ||
shanehe2aa9d72009-11-06 17:20:17 +00002107 (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
drh75897232000-05-29 14:26:00 +00002108 p->mode = MODE_Column;
shanehe2aa9d72009-11-06 17:20:17 +00002109 }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00002110 p->mode = MODE_List;
shanehe2aa9d72009-11-06 17:20:17 +00002111 }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002112 p->mode = MODE_Html;
shanehe2aa9d72009-11-06 17:20:17 +00002113 }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002114 p->mode = MODE_Tcl;
mistachkin585dcb22012-12-04 00:23:43 +00002115 sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
shanehe2aa9d72009-11-06 17:20:17 +00002116 }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00002117 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002118 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
shanehe2aa9d72009-11-06 17:20:17 +00002119 }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00002120 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002121 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
shanehe2aa9d72009-11-06 17:20:17 +00002122 }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00002123 p->mode = MODE_Insert;
shanehe2aa9d72009-11-06 17:20:17 +00002124 set_table_name(p, "table");
drhdaffd0e2001-04-11 14:28:42 +00002125 }else {
shane9bd1b442009-10-23 01:27:39 +00002126 fprintf(stderr,"Error: mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00002127 "column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00002128 rc = 1;
drh75897232000-05-29 14:26:00 +00002129 }
2130 }else
2131
shanehe2aa9d72009-11-06 17:20:17 +00002132 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
2133 int n2 = strlen30(azArg[1]);
2134 if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
2135 p->mode = MODE_Insert;
2136 set_table_name(p, azArg[2]);
2137 }else {
2138 fprintf(stderr, "Error: invalid arguments: "
2139 " \"%s\". Enter \".help\" for help\n", azArg[2]);
2140 rc = 1;
2141 }
2142 }else
2143
persicom7e2dfdd2002-04-18 02:46:52 +00002144 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00002145 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
2146 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002147 }else
2148
drh75897232000-05-29 14:26:00 +00002149 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
drh42f64e52012-04-04 16:56:23 +00002150 if( p->outfile[0]=='|' ){
2151 pclose(p->out);
2152 }else{
2153 output_file_close(p->out);
drh75897232000-05-29 14:26:00 +00002154 }
drh42f64e52012-04-04 16:56:23 +00002155 p->outfile[0] = 0;
2156 if( azArg[1][0]=='|' ){
drhe1da8fa2012-03-30 00:05:57 +00002157 p->out = popen(&azArg[1][1], "w");
2158 if( p->out==0 ){
2159 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
2160 p->out = stdout;
2161 rc = 1;
2162 }else{
2163 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
2164 }
drh75897232000-05-29 14:26:00 +00002165 }else{
drh42f64e52012-04-04 16:56:23 +00002166 p->out = output_file_open(azArg[1]);
drh75897232000-05-29 14:26:00 +00002167 if( p->out==0 ){
drh42f64e52012-04-04 16:56:23 +00002168 if( strcmp(azArg[1],"off")!=0 ){
2169 fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
2170 }
drh75897232000-05-29 14:26:00 +00002171 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00002172 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002173 } else {
drh42f64e52012-04-04 16:56:23 +00002174 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00002175 }
2176 }
2177 }else
2178
drh078b1fd2012-09-21 13:40:02 +00002179 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2180 int i;
2181 for(i=1; i<nArg; i++){
2182 if( i>1 ) fprintf(p->out, " ");
2183 fprintf(p->out, "%s", azArg[i]);
2184 }
2185 fprintf(p->out, "\n");
2186 }else
2187
drhdd45df82002-04-18 12:39:03 +00002188 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00002189 if( nArg >= 2) {
2190 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2191 }
2192 if( nArg >= 3) {
2193 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2194 }
2195 }else
2196
shanehe2aa9d72009-11-06 17:20:17 +00002197 if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
drh47ad6842006-11-08 12:25:42 +00002198 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00002199 }else
2200
drh9ff849f2009-02-04 20:55:57 +00002201 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00002202 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00002203 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00002204 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2205 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00002206 }else{
shane9bd1b442009-10-23 01:27:39 +00002207 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00002208 fclose(alt);
2209 }
2210 }else
2211
shanehe2aa9d72009-11-06 17:20:17 +00002212 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
drh9ff849f2009-02-04 20:55:57 +00002213 const char *zSrcFile;
2214 const char *zDb;
2215 sqlite3 *pSrc;
2216 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00002217 int nTimeout = 0;
2218
drh9ff849f2009-02-04 20:55:57 +00002219 if( nArg==2 ){
2220 zSrcFile = azArg[1];
2221 zDb = "main";
2222 }else{
2223 zSrcFile = azArg[2];
2224 zDb = azArg[1];
2225 }
2226 rc = sqlite3_open(zSrcFile, &pSrc);
2227 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002228 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00002229 sqlite3_close(pSrc);
2230 return 1;
2231 }
drhdc2c4912009-02-04 22:46:47 +00002232 open_db(p);
drh9ff849f2009-02-04 20:55:57 +00002233 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2234 if( pBackup==0 ){
2235 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2236 sqlite3_close(pSrc);
2237 return 1;
2238 }
drhdc2c4912009-02-04 22:46:47 +00002239 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2240 || rc==SQLITE_BUSY ){
2241 if( rc==SQLITE_BUSY ){
2242 if( nTimeout++ >= 3 ) break;
2243 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00002244 }
2245 }
2246 sqlite3_backup_finish(pBackup);
2247 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002248 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00002249 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00002250 fprintf(stderr, "Error: source database is busy\n");
2251 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002252 }else{
2253 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00002254 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002255 }
2256 sqlite3_close(pSrc);
2257 }else
2258
shanehe2aa9d72009-11-06 17:20:17 +00002259 if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
drh75897232000-05-29 14:26:00 +00002260 struct callback_data data;
2261 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00002262 open_db(p);
drh75897232000-05-29 14:26:00 +00002263 memcpy(&data, p, sizeof(data));
2264 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00002265 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00002266 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00002267 int i;
drhf0693c82011-10-11 20:41:54 +00002268 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00002269 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00002270 char *new_argv[2], *new_colv[2];
2271 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2272 " type text,\n"
2273 " name text,\n"
2274 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00002275 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00002276 " sql text\n"
2277 ")";
2278 new_argv[1] = 0;
2279 new_colv[0] = "sql";
2280 new_colv[1] = 0;
2281 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002282 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00002283 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00002284 char *new_argv[2], *new_colv[2];
2285 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
2286 " type text,\n"
2287 " name text,\n"
2288 " tbl_name text,\n"
2289 " rootpage integer,\n"
2290 " sql text\n"
2291 ")";
2292 new_argv[1] = 0;
2293 new_colv[0] = "sql";
2294 new_colv[1] = 0;
2295 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00002296 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00002297 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00002298 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00002299 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002300 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002301 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002302 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002303 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00002304 "WHERE lower(tbl_name) LIKE shellstatic()"
2305 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00002306 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00002307 callback, &data, &zErrMsg);
2308 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00002309 }
drh75897232000-05-29 14:26:00 +00002310 }else{
shane9bd1b442009-10-23 01:27:39 +00002311 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00002312 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00002313 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00002314 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00002315 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00002316 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drh1ba00292013-05-06 21:01:06 +00002317 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00002318 callback, &data, &zErrMsg
2319 );
drh75897232000-05-29 14:26:00 +00002320 }
drh75897232000-05-29 14:26:00 +00002321 if( zErrMsg ){
2322 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002323 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002324 rc = 1;
2325 }else if( rc != SQLITE_OK ){
2326 fprintf(stderr,"Error: querying schema information\n");
2327 rc = 1;
2328 }else{
2329 rc = 0;
drh75897232000-05-29 14:26:00 +00002330 }
2331 }else
2332
drh348d19c2013-06-03 12:47:43 +00002333 /* Undocumented commands for internal testing. Subject to change
2334 ** without notice. */
2335 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
2336 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
2337 int i, v;
2338 for(i=1; i<nArg; i++){
2339 v = booleanValue(azArg[i]);
2340 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
2341 }
2342 }
2343 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
2344 int i; sqlite3_int64 v;
2345 for(i=1; i<nArg; i++){
2346 v = integerValue(azArg[i]);
2347 fprintf(p->out, "%s: %lld 0x%llx\n", azArg[i], v, v);
2348 }
2349 }
2350 }else
2351
drh75897232000-05-29 14:26:00 +00002352 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00002353 sqlite3_snprintf(sizeof(p->separator), p->separator,
2354 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00002355 }else
2356
shanehe2aa9d72009-11-06 17:20:17 +00002357 if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
persicom7e2dfdd2002-04-18 02:46:52 +00002358 int i;
2359 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00002360 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00002361 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002362 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00002363 fprintf(p->out,"%9.9s: ", "nullvalue");
2364 output_c_string(p->out, p->nullvalue);
2365 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00002366 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00002367 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00002368 fprintf(p->out,"%9.9s: ", "separator");
2369 output_c_string(p->out, p->separator);
2370 fprintf(p->out, "\n");
shaneh642d8b82010-07-28 16:05:34 +00002371 fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00002372 fprintf(p->out,"%9.9s: ","width");
2373 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00002374 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00002375 }
drhfeac5f82004-08-01 00:10:45 +00002376 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00002377 }else
2378
shaneh642d8b82010-07-28 16:05:34 +00002379 if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
2380 p->statsOn = booleanValue(azArg[1]);
2381 }else
2382
shanehe2aa9d72009-11-06 17:20:17 +00002383 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
drh98781232012-04-23 12:38:05 +00002384 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00002385 char **azResult;
drh98781232012-04-23 12:38:05 +00002386 int nRow, nAlloc;
2387 char *zSql = 0;
2388 int ii;
drh44c2eb12003-04-30 11:38:26 +00002389 open_db(p);
drh98781232012-04-23 12:38:05 +00002390 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
2391 if( rc ) return rc;
2392 zSql = sqlite3_mprintf(
2393 "SELECT name FROM sqlite_master"
2394 " WHERE type IN ('table','view')"
2395 " AND name NOT LIKE 'sqlite_%%'"
2396 " AND name LIKE ?1");
2397 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2398 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
2399 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
2400 if( strcmp(zDbName,"temp")==0 ){
2401 zSql = sqlite3_mprintf(
2402 "%z UNION ALL "
2403 "SELECT 'temp.' || name FROM sqlite_temp_master"
2404 " WHERE type IN ('table','view')"
2405 " AND name NOT LIKE 'sqlite_%%'"
2406 " AND name LIKE ?1", zSql);
2407 }else{
2408 zSql = sqlite3_mprintf(
2409 "%z UNION ALL "
2410 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
2411 " WHERE type IN ('table','view')"
2412 " AND name NOT LIKE 'sqlite_%%'"
2413 " AND name LIKE ?1", zSql, zDbName, zDbName);
2414 }
drha50da102000-08-08 20:19:09 +00002415 }
drh98781232012-04-23 12:38:05 +00002416 sqlite3_finalize(pStmt);
2417 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
2418 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2419 sqlite3_free(zSql);
2420 if( rc ) return rc;
2421 nRow = nAlloc = 0;
2422 azResult = 0;
2423 if( nArg>1 ){
2424 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00002425 }else{
drh98781232012-04-23 12:38:05 +00002426 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
2427 }
2428 while( sqlite3_step(pStmt)==SQLITE_ROW ){
2429 if( nRow>=nAlloc ){
2430 char **azNew;
2431 int n = nAlloc*2 + 10;
2432 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
2433 if( azNew==0 ){
2434 fprintf(stderr, "Error: out of memory\n");
2435 break;
2436 }
2437 nAlloc = n;
2438 azResult = azNew;
2439 }
2440 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
2441 if( azResult[nRow] ) nRow++;
2442 }
2443 sqlite3_finalize(pStmt);
2444 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00002445 int len, maxlen = 0;
2446 int i, j;
2447 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00002448 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00002449 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00002450 if( len>maxlen ) maxlen = len;
2451 }
2452 nPrintCol = 80/(maxlen+2);
2453 if( nPrintCol<1 ) nPrintCol = 1;
2454 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
2455 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00002456 for(j=i; j<nRow; j+=nPrintRow){
2457 char *zSp = j<nPrintRow ? "" : " ";
drh151b7d52013-05-06 20:28:54 +00002458 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
drhe3710332000-09-29 13:30:53 +00002459 }
drh151b7d52013-05-06 20:28:54 +00002460 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00002461 }
2462 }
drh98781232012-04-23 12:38:05 +00002463 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
2464 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00002465 }else
2466
shaneh96887e12011-02-10 21:08:58 +00002467 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00002468 static const struct {
2469 const char *zCtrlName; /* Name of a test-control option */
2470 int ctrlCode; /* Integer code for that option */
2471 } aCtrl[] = {
2472 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
2473 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
2474 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
2475 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
2476 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
2477 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
2478 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
2479 { "assert", SQLITE_TESTCTRL_ASSERT },
2480 { "always", SQLITE_TESTCTRL_ALWAYS },
2481 { "reserve", SQLITE_TESTCTRL_RESERVE },
2482 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
2483 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00002484 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
2485 };
shaneh96887e12011-02-10 21:08:58 +00002486 int testctrl = -1;
2487 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00002488 int i, n;
shaneh96887e12011-02-10 21:08:58 +00002489 open_db(p);
2490
drhd416fe72011-03-17 16:45:50 +00002491 /* convert testctrl text option to value. allow any unique prefix
2492 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00002493 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00002494 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00002495 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2496 if( testctrl<0 ){
2497 testctrl = aCtrl[i].ctrlCode;
2498 }else{
drhb07028f2011-10-14 21:49:18 +00002499 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00002500 testctrl = -1;
2501 break;
2502 }
2503 }
2504 }
drh348d19c2013-06-03 12:47:43 +00002505 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002506 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
2507 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
2508 }else{
2509 switch(testctrl){
2510
2511 /* sqlite3_test_control(int, db, int) */
2512 case SQLITE_TESTCTRL_OPTIMIZATIONS:
2513 case SQLITE_TESTCTRL_RESERVE:
2514 if( nArg==3 ){
2515 int opt = (int)strtol(azArg[2], 0, 0);
2516 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00002517 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002518 } else {
drhd416fe72011-03-17 16:45:50 +00002519 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2520 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002521 }
2522 break;
2523
2524 /* sqlite3_test_control(int) */
2525 case SQLITE_TESTCTRL_PRNG_SAVE:
2526 case SQLITE_TESTCTRL_PRNG_RESTORE:
2527 case SQLITE_TESTCTRL_PRNG_RESET:
shaneh96887e12011-02-10 21:08:58 +00002528 if( nArg==2 ){
2529 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00002530 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002531 } else {
2532 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
2533 }
2534 break;
2535
2536 /* sqlite3_test_control(int, uint) */
2537 case SQLITE_TESTCTRL_PENDING_BYTE:
2538 if( nArg==3 ){
drh7d9f3942013-04-03 01:26:54 +00002539 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002540 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002541 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002542 } else {
drhd416fe72011-03-17 16:45:50 +00002543 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2544 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002545 }
2546 break;
2547
2548 /* sqlite3_test_control(int, int) */
2549 case SQLITE_TESTCTRL_ASSERT:
2550 case SQLITE_TESTCTRL_ALWAYS:
2551 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00002552 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00002553 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002554 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002555 } else {
drhd416fe72011-03-17 16:45:50 +00002556 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
2557 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002558 }
2559 break;
2560
2561 /* sqlite3_test_control(int, char *) */
2562#ifdef SQLITE_N_KEYWORD
2563 case SQLITE_TESTCTRL_ISKEYWORD:
2564 if( nArg==3 ){
2565 const char *opt = azArg[2];
2566 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00002567 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00002568 } else {
drhd416fe72011-03-17 16:45:50 +00002569 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
2570 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002571 }
2572 break;
2573#endif
2574
2575 case SQLITE_TESTCTRL_BITVEC_TEST:
2576 case SQLITE_TESTCTRL_FAULT_INSTALL:
2577 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
2578 case SQLITE_TESTCTRL_SCRATCHMALLOC:
2579 default:
drhd416fe72011-03-17 16:45:50 +00002580 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
2581 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00002582 break;
2583 }
2584 }
2585 }else
2586
shanehe2aa9d72009-11-06 17:20:17 +00002587 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
drh44c2eb12003-04-30 11:38:26 +00002588 open_db(p);
drh348d19c2013-06-03 12:47:43 +00002589 sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));
shanehe2aa9d72009-11-06 17:20:17 +00002590 }else
2591
drhd416fe72011-03-17 16:45:50 +00002592 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
2593 && nArg==2
2594 ){
drh3b1a9882007-11-02 12:53:03 +00002595 enableTimer = booleanValue(azArg[1]);
shanehe2aa9d72009-11-06 17:20:17 +00002596 }else
2597
drh42f64e52012-04-04 16:56:23 +00002598 if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
drh98781232012-04-23 12:38:05 +00002599 open_db(p);
drh42f64e52012-04-04 16:56:23 +00002600 output_file_close(p->traceOut);
2601 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00002602#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002603 if( p->traceOut==0 ){
2604 sqlite3_trace(p->db, 0, 0);
2605 }else{
2606 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
2607 }
2608#endif
2609 }else
2610
drh9fd301b2011-06-03 13:28:22 +00002611 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00002612 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00002613 sqlite3_libversion(), sqlite3_sourceid());
2614 }else
2615
drhde60fc22011-12-14 17:53:36 +00002616 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
2617 const char *zDbName = nArg==2 ? azArg[1] : "main";
2618 char *zVfsName = 0;
2619 if( p->db ){
2620 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
2621 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00002622 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00002623 sqlite3_free(zVfsName);
2624 }
2625 }
2626 }else
2627
drhcef4fc82012-09-21 22:50:45 +00002628#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2629 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
2630 extern int sqlite3WhereTrace;
drh7d9f3942013-04-03 01:26:54 +00002631 sqlite3WhereTrace = booleanValue(azArg[1]);
drhcef4fc82012-09-21 22:50:45 +00002632 }else
2633#endif
2634
shanehe2aa9d72009-11-06 17:20:17 +00002635 if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
drh75897232000-05-29 14:26:00 +00002636 int j;
drh43617e92006-03-06 20:55:46 +00002637 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00002638 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00002639 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00002640 }
2641 }else
2642
2643 {
shane9bd1b442009-10-23 01:27:39 +00002644 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00002645 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00002646 rc = 1;
drh75897232000-05-29 14:26:00 +00002647 }
drh67505e72002-04-19 12:34:06 +00002648
2649 return rc;
drh75897232000-05-29 14:26:00 +00002650}
2651
drh67505e72002-04-19 12:34:06 +00002652/*
drh91a66392007-09-07 01:12:32 +00002653** Return TRUE if a semicolon occurs anywhere in the first N characters
2654** of string z[].
drh324ccef2003-02-05 14:06:20 +00002655*/
drh91a66392007-09-07 01:12:32 +00002656static int _contains_semicolon(const char *z, int N){
2657 int i;
2658 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
2659 return 0;
drh324ccef2003-02-05 14:06:20 +00002660}
2661
2662/*
drh70c7a4b2003-04-26 03:03:06 +00002663** Test to see if a line consists entirely of whitespace.
2664*/
2665static int _all_whitespace(const char *z){
2666 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00002667 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00002668 if( *z=='/' && z[1]=='*' ){
2669 z += 2;
2670 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2671 if( *z==0 ) return 0;
2672 z++;
2673 continue;
2674 }
2675 if( *z=='-' && z[1]=='-' ){
2676 z += 2;
2677 while( *z && *z!='\n' ){ z++; }
2678 if( *z==0 ) return 1;
2679 continue;
2680 }
2681 return 0;
2682 }
2683 return 1;
2684}
2685
2686/*
drha9b17162003-04-29 18:01:28 +00002687** Return TRUE if the line typed in is an SQL command terminator other
2688** than a semi-colon. The SQL Server style "go" command is understood
2689** as is the Oracle "/".
2690*/
2691static int _is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00002692 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00002693 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2694 return 1; /* Oracle */
2695 }
drhf0693c82011-10-11 20:41:54 +00002696 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00002697 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00002698 return 1; /* SQL Server */
2699 }
2700 return 0;
2701}
2702
2703/*
drh233a5312008-12-18 22:25:13 +00002704** Return true if zSql is a complete SQL statement. Return false if it
2705** ends in the middle of a string literal or C-style comment.
2706*/
2707static int _is_complete(char *zSql, int nSql){
2708 int rc;
2709 if( zSql==0 ) return 1;
2710 zSql[nSql] = ';';
2711 zSql[nSql+1] = 0;
2712 rc = sqlite3_complete(zSql);
2713 zSql[nSql] = 0;
2714 return rc;
2715}
2716
2717/*
drh67505e72002-04-19 12:34:06 +00002718** Read input from *in and process it. If *in==0 then input
2719** is interactive - the user is typing it it. Otherwise, input
2720** is coming from a file or device. A prompt is issued and history
2721** is saved only if input is interactive. An interrupt signal will
2722** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00002723**
2724** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00002725*/
drhc28490c2006-10-26 14:25:58 +00002726static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00002727 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00002728 char *zSql = 0;
2729 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00002730 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00002731 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00002732 int rc;
2733 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00002734 int lineno = 0;
2735 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00002736
2737 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
2738 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00002739 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00002740 zLine = one_input_line(zSql, in);
2741 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00002742 /* End of input */
2743 if( stdin_is_interactive ) printf("\n");
2744 break;
drhc49f44e2006-10-26 18:15:42 +00002745 }
drh67505e72002-04-19 12:34:06 +00002746 if( seenInterrupt ){
2747 if( in!=0 ) break;
2748 seenInterrupt = 0;
2749 }
drhc28490c2006-10-26 14:25:58 +00002750 lineno++;
drhf817b6b2003-06-16 00:16:41 +00002751 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00002752 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00002753 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00002754 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00002755 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00002756 break;
2757 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00002758 errCnt++;
2759 }
drhdaffd0e2001-04-11 14:28:42 +00002760 continue;
2761 }
drh233a5312008-12-18 22:25:13 +00002762 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00002763 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00002764 }
drh91a66392007-09-07 01:12:32 +00002765 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00002766 if( zSql==0 ){
2767 int i;
drhf0693c82011-10-11 20:41:54 +00002768 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00002769 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00002770 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002771 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00002772 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002773 fprintf(stderr, "Error: out of memory\n");
drhc1f44942006-05-10 14:39:13 +00002774 exit(1);
2775 }
drh5bb3eb92007-05-04 13:15:55 +00002776 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00002777 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00002778 }
2779 }else{
drh4f21c4a2008-12-10 22:15:00 +00002780 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00002781 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00002782 if( zSql==0 ){
shane9bd1b442009-10-23 01:27:39 +00002783 fprintf(stderr,"Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00002784 exit(1);
2785 }
drh5bb3eb92007-05-04 13:15:55 +00002786 zSql[nSql++] = '\n';
2787 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00002788 nSql += len;
2789 }
drh91a66392007-09-07 01:12:32 +00002790 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
2791 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00002792 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00002793 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00002794 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00002795 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00002796 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00002797 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00002798 char zPrefix[100];
2799 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00002800 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00002801 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00002802 }else{
shane9bd1b442009-10-23 01:27:39 +00002803 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00002804 }
drh7f953e22002-07-13 17:33:45 +00002805 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00002806 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002807 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00002808 zErrMsg = 0;
2809 }else{
shaned2bed1c2009-10-21 03:56:54 +00002810 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00002811 }
drhc49f44e2006-10-26 18:15:42 +00002812 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00002813 }
2814 free(zSql);
2815 zSql = 0;
2816 nSql = 0;
drh7a411f42013-04-17 17:33:17 +00002817 }else if( zSql && _all_whitespace(zSql) ){
2818 free(zSql);
2819 zSql = 0;
2820 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00002821 }
2822 }
2823 if( zSql ){
drhd416fe72011-03-17 16:45:50 +00002824 if( !_all_whitespace(zSql) ){
2825 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
2826 }
drhdaffd0e2001-04-11 14:28:42 +00002827 free(zSql);
2828 }
danielk19772ac27622007-07-03 05:31:16 +00002829 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00002830 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00002831}
2832
drh67505e72002-04-19 12:34:06 +00002833/*
2834** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00002835** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00002836*/
2837static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00002838 static char *home_dir = NULL;
2839 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00002840
drh83905c92012-06-21 13:00:37 +00002841#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00002842 {
2843 struct passwd *pwent;
2844 uid_t uid = getuid();
2845 if( (pwent=getpwuid(uid)) != NULL) {
2846 home_dir = pwent->pw_dir;
2847 }
drh67505e72002-04-19 12:34:06 +00002848 }
2849#endif
2850
chw65d3c132007-11-12 21:09:10 +00002851#if defined(_WIN32_WCE)
2852 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
2853 */
drh85e72432012-04-11 11:38:53 +00002854 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00002855#else
2856
drh83905c92012-06-21 13:00:37 +00002857#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00002858 if (!home_dir) {
2859 home_dir = getenv("USERPROFILE");
2860 }
2861#endif
2862
drh67505e72002-04-19 12:34:06 +00002863 if (!home_dir) {
2864 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00002865 }
2866
drh83905c92012-06-21 13:00:37 +00002867#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00002868 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00002869 char *zDrive, *zPath;
2870 int n;
2871 zDrive = getenv("HOMEDRIVE");
2872 zPath = getenv("HOMEPATH");
2873 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00002874 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00002875 home_dir = malloc( n );
2876 if( home_dir==0 ) return 0;
2877 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
2878 return home_dir;
2879 }
2880 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00002881 }
2882#endif
2883
chw65d3c132007-11-12 21:09:10 +00002884#endif /* !_WIN32_WCE */
2885
drh67505e72002-04-19 12:34:06 +00002886 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00002887 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00002888 char *z = malloc( n );
2889 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00002890 home_dir = z;
2891 }
drhe98d4fa2002-04-21 19:06:22 +00002892
drh67505e72002-04-19 12:34:06 +00002893 return home_dir;
2894}
2895
2896/*
2897** Read input from the file given by sqliterc_override. Or if that
2898** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00002899**
2900** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00002901*/
shane9bd1b442009-10-23 01:27:39 +00002902static int process_sqliterc(
drh22fbcb82004-02-01 01:22:50 +00002903 struct callback_data *p, /* Configuration data */
2904 const char *sqliterc_override /* Name of config file. NULL to use default */
2905){
persicom7e2dfdd2002-04-18 02:46:52 +00002906 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00002907 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00002908 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002909 FILE *in = NULL;
shane9bd1b442009-10-23 01:27:39 +00002910 int rc = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00002911
2912 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00002913 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00002914 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00002915#if !defined(__RTP__) && !defined(_WRS_KERNEL)
shane86f5bdb2009-10-24 02:00:07 +00002916 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
chw97185482008-11-17 08:05:31 +00002917#endif
shane9bd1b442009-10-23 01:27:39 +00002918 return 1;
drhe98d4fa2002-04-21 19:06:22 +00002919 }
drh2f3de322012-06-27 16:41:31 +00002920 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00002921 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
2922 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00002923 }
drha1f9b5e2004-02-14 16:31:02 +00002924 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00002925 if( in ){
drhc28490c2006-10-26 14:25:58 +00002926 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00002927 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00002928 }
shane9bd1b442009-10-23 01:27:39 +00002929 rc = process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00002930 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00002931 }
drh85e72432012-04-11 11:38:53 +00002932 sqlite3_free(zBuf);
shane9bd1b442009-10-23 01:27:39 +00002933 return rc;
persicom7e2dfdd2002-04-18 02:46:52 +00002934}
2935
drh67505e72002-04-19 12:34:06 +00002936/*
drhe1e38c42003-05-04 18:30:59 +00002937** Show available command line options
2938*/
2939static const char zOptions[] =
drhc49f44e2006-10-26 18:15:42 +00002940 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00002941 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002942 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00002943 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00002944 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00002945 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00002946 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00002947 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00002948#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2949 " -heap SIZE Size of heap for memsys3 or memsys5\n"
2950#endif
drhcc3b4f82012-02-07 14:13:50 +00002951 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00002952 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00002953 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002954 " -line set output mode to 'line'\n"
2955 " -list set output mode to 'list'\n"
drh7d9f3942013-04-03 01:26:54 +00002956 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00002957#ifdef SQLITE_ENABLE_MULTIPLEX
2958 " -multiplex enable the multiplexor VFS\n"
2959#endif
drh98d312f2012-10-25 15:23:14 +00002960 " -nullvalue TEXT set text string for NULL values. Default ''\n"
2961 " -separator SEP set output field separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00002962 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00002963 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00002964 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00002965#ifdef SQLITE_ENABLE_VFSTRACE
2966 " -vfstrace enable tracing of all VFS calls\n"
2967#endif
drhe1e38c42003-05-04 18:30:59 +00002968;
2969static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002970 fprintf(stderr,
2971 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2972 "FILENAME is the name of an SQLite database. A new database is created\n"
2973 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002974 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002975 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002976 }else{
2977 fprintf(stderr, "Use the -help option for additional information\n");
2978 }
2979 exit(1);
2980}
2981
2982/*
drh67505e72002-04-19 12:34:06 +00002983** Initialize the state information in data
2984*/
drh0850b532006-01-31 19:31:43 +00002985static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002986 memset(data, 0, sizeof(*data));
2987 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002988 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002989 data->showHeader = 0;
drh52784bd2011-05-18 17:15:06 +00002990 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00002991 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh5bb3eb92007-05-04 13:15:55 +00002992 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2993 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
dan0f831772010-03-03 07:23:12 +00002994 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
persicom7e2dfdd2002-04-18 02:46:52 +00002995}
2996
drh98d312f2012-10-25 15:23:14 +00002997/*
2998** Get the argument to an --option. Throw an error and die if no argument
2999** is available.
3000*/
3001static char *cmdline_option_value(int argc, char **argv, int i){
3002 if( i==argc ){
3003 fprintf(stderr, "%s: Error: missing argument to %s\n",
3004 argv[0], argv[argc-1]);
3005 exit(1);
3006 }
3007 return argv[i];
3008}
3009
drh75897232000-05-29 14:26:00 +00003010int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00003011 char *zErrMsg = 0;
3012 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00003013 const char *zInitFile = 0;
3014 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00003015 int i;
drhc28490c2006-10-26 14:25:58 +00003016 int rc = 0;
drh75897232000-05-29 14:26:00 +00003017
drh52784bd2011-05-18 17:15:06 +00003018 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
3019 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
3020 sqlite3_sourceid(), SQLITE_SOURCE_ID);
3021 exit(1);
3022 }
drhdaffd0e2001-04-11 14:28:42 +00003023 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00003024 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00003025 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00003026
drh44c2eb12003-04-30 11:38:26 +00003027 /* Make sure we have a valid signal handler early, before anything
3028 ** else is done.
3029 */
drh4c504392000-10-16 22:06:40 +00003030#ifdef SIGINT
3031 signal(SIGINT, interrupt_handler);
3032#endif
drh44c2eb12003-04-30 11:38:26 +00003033
drh22fbcb82004-02-01 01:22:50 +00003034 /* Do an initial pass through the command-line argument to locate
3035 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00003036 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00003037 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00003038 */
drh98d312f2012-10-25 15:23:14 +00003039 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00003040 char *z;
drhc28490c2006-10-26 14:25:58 +00003041 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003042 if( z[0]!='-' ){
3043 if( data.zDbFilename==0 ){
3044 data.zDbFilename = z;
3045 continue;
3046 }
3047 if( zFirstCmd==0 ){
3048 zFirstCmd = z;
3049 continue;
3050 }
3051 fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
3052 fprintf(stderr,"Use -help for a list of options.\n");
3053 return 1;
3054 }
drhcc3b4f82012-02-07 14:13:50 +00003055 if( z[1]=='-' ) z++;
3056 if( strcmp(z,"-separator")==0
3057 || strcmp(z,"-nullvalue")==0
3058 || strcmp(z,"-cmd")==0
3059 ){
drh98d312f2012-10-25 15:23:14 +00003060 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003061 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00003062 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00003063 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00003064 /* Need to check for batch mode here to so we can avoid printing
3065 ** informational messages (like from process_sqliterc) before
3066 ** we do the actual processing of arguments later in a second pass.
3067 */
shanef69573d2009-10-24 02:06:14 +00003068 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00003069 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00003070#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00003071 int j, c;
3072 const char *zSize;
3073 sqlite3_int64 szHeap;
3074
drh98d312f2012-10-25 15:23:14 +00003075 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00003076 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00003077 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00003078 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3079#endif
drh97ae8ff2011-03-16 16:56:29 +00003080#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00003081 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00003082 extern int vfstrace_register(
3083 const char *zTraceName,
3084 const char *zOldVfsName,
3085 int (*xOut)(const char*,void*),
3086 void *pOutArg,
3087 int makeDefault
3088 );
drh2b625e22011-03-16 17:05:28 +00003089 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00003090#endif
drh6f25e892011-07-08 17:02:57 +00003091#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00003092 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00003093 extern int sqlite3_multiple_initialize(const char*,int);
3094 sqlite3_multiplex_initialize(0, 1);
3095#endif
drh7d9f3942013-04-03 01:26:54 +00003096 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00003097 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
3098 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00003099 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00003100 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00003101 if( pVfs ){
3102 sqlite3_vfs_register(pVfs, 1);
3103 }else{
3104 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3105 exit(1);
3106 }
drh44c2eb12003-04-30 11:38:26 +00003107 }
3108 }
drh98d312f2012-10-25 15:23:14 +00003109 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00003110#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00003111 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00003112#else
shane86f5bdb2009-10-24 02:00:07 +00003113 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3114 return 1;
drh01b41712005-08-29 23:06:23 +00003115#endif
drh98d312f2012-10-25 15:23:14 +00003116 }
3117 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00003118
drh44c2eb12003-04-30 11:38:26 +00003119 /* Go ahead and open the database file if it already exists. If the
3120 ** file does not exist, delay opening it. This prevents empty database
3121 ** files from being created if a user mistypes the database name argument
3122 ** to the sqlite command-line tool.
3123 */
drhc8d74412004-08-31 23:41:26 +00003124 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00003125 open_db(&data);
3126 }
3127
drh22fbcb82004-02-01 01:22:50 +00003128 /* Process the initialization file if there is one. If no -init option
3129 ** is given on the command line, look for a file named ~/.sqliterc and
3130 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00003131 */
shane86f5bdb2009-10-24 02:00:07 +00003132 rc = process_sqliterc(&data,zInitFile);
3133 if( rc>0 ){
3134 return rc;
3135 }
drh44c2eb12003-04-30 11:38:26 +00003136
drh22fbcb82004-02-01 01:22:50 +00003137 /* Make a second pass through the command-line argument and set
3138 ** options. This second pass is delayed until after the initialization
3139 ** file is processed so that the command-line arguments will override
3140 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00003141 */
drh98d312f2012-10-25 15:23:14 +00003142 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00003143 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00003144 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00003145 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00003146 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00003147 i++;
3148 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003149 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00003150 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003151 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00003152 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003153 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00003154 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00003155 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00003156 }else if( strcmp(z,"-csv")==0 ){
3157 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00003158 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00003159 }else if( strcmp(z,"-separator")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003160 sqlite3_snprintf(sizeof(data.separator), data.separator,
drh98d312f2012-10-25 15:23:14 +00003161 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003162 }else if( strcmp(z,"-nullvalue")==0 ){
drh5bb3eb92007-05-04 13:15:55 +00003163 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
drh98d312f2012-10-25 15:23:14 +00003164 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00003165 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003166 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00003167 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003168 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00003169 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00003170 data.echoOn = 1;
shaneh642d8b82010-07-28 16:05:34 +00003171 }else if( strcmp(z,"-stats")==0 ){
3172 data.statsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00003173 }else if( strcmp(z,"-bail")==0 ){
3174 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00003175 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00003176 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00003177 return 0;
drhc28490c2006-10-26 14:25:58 +00003178 }else if( strcmp(z,"-interactive")==0 ){
3179 stdin_is_interactive = 1;
3180 }else if( strcmp(z,"-batch")==0 ){
3181 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00003182 }else if( strcmp(z,"-heap")==0 ){
3183 i++;
drh7d9f3942013-04-03 01:26:54 +00003184 }else if( strcmp(z,"-mmap")==0 ){
3185 i++;
drha7e61d82011-03-12 17:02:57 +00003186 }else if( strcmp(z,"-vfs")==0 ){
3187 i++;
drh6f25e892011-07-08 17:02:57 +00003188#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00003189 }else if( strcmp(z,"-vfstrace")==0 ){
3190 i++;
drh6f25e892011-07-08 17:02:57 +00003191#endif
3192#ifdef SQLITE_ENABLE_MULTIPLEX
3193 }else if( strcmp(z,"-multiplex")==0 ){
3194 i++;
3195#endif
drhcc3b4f82012-02-07 14:13:50 +00003196 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00003197 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00003198 }else if( strcmp(z,"-cmd")==0 ){
3199 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00003200 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00003201 if( z[0]=='.' ){
3202 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00003203 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00003204 }else{
3205 open_db(&data);
3206 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
3207 if( zErrMsg!=0 ){
3208 fprintf(stderr,"Error: %s\n", zErrMsg);
3209 if( bail_on_error ) return rc!=0 ? rc : 1;
3210 }else if( rc!=0 ){
3211 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
3212 if( bail_on_error ) return rc;
3213 }
3214 }
drh1e5d0e92000-05-31 23:33:17 +00003215 }else{
shane86f5bdb2009-10-24 02:00:07 +00003216 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00003217 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00003218 return 1;
3219 }
3220 }
drh44c2eb12003-04-30 11:38:26 +00003221
drh22fbcb82004-02-01 01:22:50 +00003222 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00003223 /* Run just the command that follows the database name
3224 */
drh22fbcb82004-02-01 01:22:50 +00003225 if( zFirstCmd[0]=='.' ){
shane916f9612009-10-23 00:37:15 +00003226 rc = do_meta_command(zFirstCmd, &data);
drh99b39082013-04-17 12:19:48 +00003227 if( rc==2 ) rc = 0;
drh6ff13852001-11-25 13:18:23 +00003228 }else{
drh44c2eb12003-04-30 11:38:26 +00003229 open_db(&data);
shane626a6e42009-10-22 17:30:15 +00003230 rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
shane86f5bdb2009-10-24 02:00:07 +00003231 if( zErrMsg!=0 ){
3232 fprintf(stderr,"Error: %s\n", zErrMsg);
3233 return rc!=0 ? rc : 1;
3234 }else if( rc!=0 ){
3235 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
3236 return rc;
drh6ff13852001-11-25 13:18:23 +00003237 }
drh75897232000-05-29 14:26:00 +00003238 }
3239 }else{
drh44c2eb12003-04-30 11:38:26 +00003240 /* Run commands received from standard input
3241 */
drhc28490c2006-10-26 14:25:58 +00003242 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00003243 char *zHome;
3244 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00003245 int nHistory;
drh75897232000-05-29 14:26:00 +00003246 printf(
drh743e0032011-12-12 16:51:50 +00003247 "SQLite version %s %.19s\n" /*extra-version-info*/
mihailim65df9db2008-06-28 11:29:22 +00003248 "Enter \".help\" for instructions\n"
3249 "Enter SQL statements terminated with a \";\"\n",
drh9fd301b2011-06-03 13:28:22 +00003250 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00003251 );
drh67505e72002-04-19 12:34:06 +00003252 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00003253 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00003254 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00003255 if( (zHistory = malloc(nHistory))!=0 ){
3256 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
3257 }
drh67505e72002-04-19 12:34:06 +00003258 }
danielk19774af00c62005-01-23 23:43:21 +00003259#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00003260 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00003261#endif
drhc28490c2006-10-26 14:25:58 +00003262 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00003263 if( zHistory ){
3264 stifle_history(100);
3265 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00003266 free(zHistory);
drh67505e72002-04-19 12:34:06 +00003267 }
drhdaffd0e2001-04-11 14:28:42 +00003268 }else{
drhc28490c2006-10-26 14:25:58 +00003269 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00003270 }
3271 }
drh33048c02001-10-01 14:29:22 +00003272 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00003273 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00003274 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00003275 }
drhc28490c2006-10-26 14:25:58 +00003276 return rc;
drh75897232000-05-29 14:26:00 +00003277}