blob: 3434dd437d4d9ad0367db468a6739c23535a3790 [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.
14**
drhea678832008-12-10 19:26:22 +000015** $Id: shell.c,v 1.192 2008/12/10 19:26:24 drh Exp $
drh75897232000-05-29 14:26:00 +000016*/
17#include <stdlib.h>
18#include <string.h>
19#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000020#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000021#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000022#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000023#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000024
drh454ad582007-11-26 22:54:27 +000025#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000026# include <signal.h>
chw97185482008-11-17 08:05:31 +000027# if !defined(__RTP__) && !defined(_WRS_KERNEL)
28# include <pwd.h>
29# endif
drhdd45df82002-04-18 12:39:03 +000030# include <unistd.h>
31# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000032#endif
drh75897232000-05-29 14:26:00 +000033
drhcdb36b72006-06-12 12:57:45 +000034#ifdef __OS2__
35# include <unistd.h>
36#endif
37
drh16e59552000-07-31 11:57:37 +000038#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000039# include <readline/readline.h>
40# include <readline/history.h>
41#else
drh9347b202003-07-18 01:30:59 +000042# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000043# define add_history(X)
drh67505e72002-04-19 12:34:06 +000044# define read_history(X)
45# define write_history(X)
46# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000047#endif
48
adamd2e8464a2006-09-06 21:39:40 +000049#if defined(_WIN32) || defined(WIN32)
50# include <io.h>
51#else
drh4328c8b2003-04-26 02:50:11 +000052/* Make sure isatty() has a prototype.
53*/
54extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000055#endif
drh4328c8b2003-04-26 02:50:11 +000056
chw65d3c132007-11-12 21:09:10 +000057#if defined(_WIN32_WCE)
58/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
59 * thus we always assume that we have a console. That can be
60 * overridden with the -batch command line option.
61 */
62#define isatty(x) 1
63#endif
64
chw97185482008-11-17 08:05:31 +000065#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000066#include <sys/time.h>
67#include <sys/resource.h>
68
69/* Saved resource information for the beginning of an operation */
70static struct rusage sBegin;
71
72/* True if the timer is enabled */
73static int enableTimer = 0;
74
75/*
76** Begin timing an operation
77*/
78static void beginTimer(void){
79 if( enableTimer ){
80 getrusage(RUSAGE_SELF, &sBegin);
81 }
82}
83
drhf4608092008-07-11 17:23:24 +000084/* Return the difference of two time_structs in seconds */
85static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
86 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
87 (double)(pEnd->tv_sec - pStart->tv_sec);
drh3b1a9882007-11-02 12:53:03 +000088}
89
90/*
91** Print the timing results.
92*/
93static void endTimer(void){
94 if( enableTimer ){
95 struct rusage sEnd;
96 getrusage(RUSAGE_SELF, &sEnd);
97 printf("CPU Time: user %f sys %f\n",
drhf4608092008-07-11 17:23:24 +000098 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
99 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
drh3b1a9882007-11-02 12:53:03 +0000100 }
101}
102#define BEGIN_TIMER beginTimer()
103#define END_TIMER endTimer()
104#define HAS_TIMER 1
105#else
106#define BEGIN_TIMER
107#define END_TIMER
108#define HAS_TIMER 0
109#endif
110
drhe91d16b2008-12-08 18:27:31 +0000111/*
112** Used to prevent warnings about unused parameters
113*/
114#define UNUSED_PARAMETER(x) (void)(x)
drh3b1a9882007-11-02 12:53:03 +0000115
drh75897232000-05-29 14:26:00 +0000116/*
drhc49f44e2006-10-26 18:15:42 +0000117** If the following flag is set, then command execution stops
118** at an error if we are not interactive.
119*/
120static int bail_on_error = 0;
121
122/*
drhc28490c2006-10-26 14:25:58 +0000123** Threat stdin as an interactive input if the following variable
124** is true. Otherwise, assume stdin is connected to a file or pipe.
125*/
126static int stdin_is_interactive = 1;
127
128/*
drh4c504392000-10-16 22:06:40 +0000129** The following is the open SQLite database. We make a pointer
130** to this database a static variable so that it can be accessed
131** by the SIGINT handler to interrupt database processing.
132*/
danielk197792f9a1b2004-06-19 09:08:16 +0000133static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000134
135/*
drh67505e72002-04-19 12:34:06 +0000136** True if an interrupt (Control-C) has been received.
137*/
drh43617e92006-03-06 20:55:46 +0000138static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000139
140/*
persicom7e2dfdd2002-04-18 02:46:52 +0000141** This is the name of our program. It is set in main(), used
142** in a number of other places, mostly for error messages.
143*/
144static char *Argv0;
145
146/*
147** Prompt strings. Initialized in main. Settable with
148** .prompt main continue
149*/
150static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
151static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
152
drhb0603412007-02-28 04:47:26 +0000153/*
154** Write I/O traces to the following stream.
155*/
rsebe0a9092007-07-30 18:24:38 +0000156#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000157static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000158#endif
drhb0603412007-02-28 04:47:26 +0000159
160/*
161** This routine works like printf in that its first argument is a
162** format string and subsequent arguments are values to be substituted
163** in place of % fields. The result of formatting this string
164** is written to iotrace.
165*/
rsebe0a9092007-07-30 18:24:38 +0000166#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000167static void iotracePrintf(const char *zFormat, ...){
168 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000169 char *z;
drhb0603412007-02-28 04:47:26 +0000170 if( iotrace==0 ) return;
171 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000172 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000173 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000174 fprintf(iotrace, "%s", z);
175 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000176}
rsebe0a9092007-07-30 18:24:38 +0000177#endif
drhb0603412007-02-28 04:47:26 +0000178
drh44c2eb12003-04-30 11:38:26 +0000179
persicom7e2dfdd2002-04-18 02:46:52 +0000180/*
drh83965662003-04-17 02:54:13 +0000181** Determines if a string is a number of not.
182*/
danielk19772e588c72005-12-09 14:25:08 +0000183static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000184 if( *z=='-' || *z=='+' ) z++;
185 if( !isdigit(*z) ){
186 return 0;
187 }
188 z++;
189 if( realnum ) *realnum = 0;
190 while( isdigit(*z) ){ z++; }
191 if( *z=='.' ){
192 z++;
193 if( !isdigit(*z) ) return 0;
194 while( isdigit(*z) ){ z++; }
195 if( realnum ) *realnum = 1;
196 }
197 if( *z=='e' || *z=='E' ){
198 z++;
199 if( *z=='+' || *z=='-' ) z++;
200 if( !isdigit(*z) ) return 0;
201 while( isdigit(*z) ){ z++; }
202 if( realnum ) *realnum = 1;
203 }
204 return *z==0;
205}
drh83965662003-04-17 02:54:13 +0000206
207/*
danielk1977bc6ada42004-06-30 08:20:16 +0000208** A global char* and an SQL function to access its current value
209** from within an SQL statement. This program used to use the
210** sqlite_exec_printf() API to substitue a string into an SQL statement.
211** The correct way to do this with sqlite3 is to use the bind API, but
212** since the shell is built around the callback paradigm it would be a lot
213** of work. Instead just use this hack, which is quite harmless.
214*/
215static const char *zShellStatic = 0;
216static void shellstaticFunc(
217 sqlite3_context *context,
218 int argc,
219 sqlite3_value **argv
220){
221 assert( 0==argc );
222 assert( zShellStatic );
drh902b9ee2008-12-05 17:17:07 +0000223 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000224 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
225}
226
227
228/*
drhfeac5f82004-08-01 00:10:45 +0000229** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000230** the text in memory obtained from malloc() and returns a pointer
231** to the text. NULL is returned at end of file, or if malloc()
232** fails.
233**
234** The interface is like "readline" but no command-line editing
235** is done.
236*/
drh9347b202003-07-18 01:30:59 +0000237static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000238 char *zLine;
239 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000240 int n;
241 int eol;
242
243 if( zPrompt && *zPrompt ){
244 printf("%s",zPrompt);
245 fflush(stdout);
246 }
247 nLine = 100;
248 zLine = malloc( nLine );
249 if( zLine==0 ) return 0;
250 n = 0;
251 eol = 0;
252 while( !eol ){
253 if( n+100>nLine ){
254 nLine = nLine*2 + 100;
255 zLine = realloc(zLine, nLine);
256 if( zLine==0 ) return 0;
257 }
drhdaffd0e2001-04-11 14:28:42 +0000258 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000259 if( n==0 ){
260 free(zLine);
261 return 0;
262 }
263 zLine[n] = 0;
264 eol = 1;
265 break;
266 }
267 while( zLine[n] ){ n++; }
268 if( n>0 && zLine[n-1]=='\n' ){
269 n--;
270 zLine[n] = 0;
271 eol = 1;
272 }
273 }
274 zLine = realloc( zLine, n+1 );
275 return zLine;
276}
277
278/*
drhc28490c2006-10-26 14:25:58 +0000279** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000280**
281** zPrior is a string of prior text retrieved. If not the empty
282** string, then issue a continuation prompt.
283*/
drhdaffd0e2001-04-11 14:28:42 +0000284static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000285 char *zPrompt;
286 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000287 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000288 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000289 }
290 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000291 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000292 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000293 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000294 }
295 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000296#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000297 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000298#endif
drh8e7e7a22000-05-30 18:45:23 +0000299 return zResult;
300}
301
persicom7e2dfdd2002-04-18 02:46:52 +0000302struct previous_mode_data {
303 int valid; /* Is there legit data in here? */
304 int mode;
305 int showHeader;
306 int colWidth[100];
307};
drh45e29d82006-11-20 16:21:10 +0000308
drh8e7e7a22000-05-30 18:45:23 +0000309/*
drh75897232000-05-29 14:26:00 +0000310** An pointer to an instance of this structure is passed from
311** the main program to the callback. This is used to communicate
312** state and mode information.
313*/
314struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000315 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000316 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000317 int cnt; /* Number of records displayed so far */
318 FILE *out; /* Write results here */
319 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000320 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000321 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000322 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000323 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000324 int colWidth[100]; /* Requested width of each column when in column mode*/
325 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000326 char nullvalue[20]; /* The text to print when a NULL comes back from
327 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000328 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000329 /* Holds the mode information just before
330 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000331 char outfile[FILENAME_MAX]; /* Filename for *out */
332 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000333};
334
335/*
336** These are the allowed modes.
337*/
drh967e8b72000-06-21 13:59:10 +0000338#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000339#define MODE_Column 1 /* One record per line in neat columns */
340#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000341#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
342#define MODE_Html 4 /* Generate an XHTML table */
343#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000344#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000345#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000346#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000347
drh66ce4d02008-02-15 17:38:06 +0000348static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000349 "line",
350 "column",
351 "list",
352 "semi",
353 "html",
drhfeac5f82004-08-01 00:10:45 +0000354 "insert",
355 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000356 "csv",
drh66ce4d02008-02-15 17:38:06 +0000357 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000358};
drh75897232000-05-29 14:26:00 +0000359
360/*
361** Number of elements in an array
362*/
drh902b9ee2008-12-05 17:17:07 +0000363#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000364
365/*
drhea678832008-12-10 19:26:22 +0000366** Compute a string length that is limited to what can be stored in
367** lower 30 bits of a 32-bit signed integer.
368*/
369int sqlite3Strlen30(const char *z){
370 const char *z2 = z;
371 while( *z2 ){ z2++; }
372 return 0x3fffffff & (int)(z2 - z);
373}
374
375/*
drh28bd4bc2000-06-15 15:57:22 +0000376** Output the given string as a quoted string using SQL quoting conventions.
377*/
378static void output_quoted_string(FILE *out, const char *z){
379 int i;
380 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000381 for(i=0; z[i]; i++){
382 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000383 }
384 if( nSingle==0 ){
385 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000386 }else{
387 fprintf(out,"'");
388 while( *z ){
389 for(i=0; z[i] && z[i]!='\''; i++){}
390 if( i==0 ){
391 fprintf(out,"''");
392 z++;
393 }else if( z[i]=='\'' ){
394 fprintf(out,"%.*s''",i,z);
395 z += i+1;
396 }else{
drhcd7d2732002-02-26 23:24:26 +0000397 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000398 break;
399 }
400 }
drhcd7d2732002-02-26 23:24:26 +0000401 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000402 }
403}
404
405/*
drhfeac5f82004-08-01 00:10:45 +0000406** Output the given string as a quoted according to C or TCL quoting rules.
407*/
408static void output_c_string(FILE *out, const char *z){
409 unsigned int c;
410 fputc('"', out);
411 while( (c = *(z++))!=0 ){
412 if( c=='\\' ){
413 fputc(c, out);
414 fputc(c, out);
415 }else if( c=='\t' ){
416 fputc('\\', out);
417 fputc('t', out);
418 }else if( c=='\n' ){
419 fputc('\\', out);
420 fputc('n', out);
421 }else if( c=='\r' ){
422 fputc('\\', out);
423 fputc('r', out);
424 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000425 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000426 }else{
427 fputc(c, out);
428 }
429 }
430 fputc('"', out);
431}
432
433/*
drhc08a4f12000-06-15 16:49:48 +0000434** Output the given string with characters that are special to
435** HTML escaped.
436*/
437static void output_html_string(FILE *out, const char *z){
438 int i;
439 while( *z ){
440 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
441 if( i>0 ){
442 fprintf(out,"%.*s",i,z);
443 }
444 if( z[i]=='<' ){
445 fprintf(out,"&lt;");
446 }else if( z[i]=='&' ){
447 fprintf(out,"&amp;");
448 }else{
449 break;
450 }
451 z += i + 1;
452 }
453}
454
455/*
drhc49f44e2006-10-26 18:15:42 +0000456** If a field contains any character identified by a 1 in the following
457** array, then the string must be quoted for CSV.
458*/
459static const char needCsvQuote[] = {
460 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
461 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
462 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
463 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
464 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
465 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
466 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
467 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
468 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
469 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
470 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
471 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
472 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
473 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
474 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
475 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
476};
477
478/*
drh8e64d1c2004-10-07 00:32:39 +0000479** Output a single term of CSV. Actually, p->separator is used for
480** the separator, which may or may not be a comma. p->nullvalue is
481** the null value. Strings are quoted using ANSI-C rules. Numbers
482** appear outside of quotes.
483*/
484static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000485 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000486 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000487 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000488 }else{
drhc49f44e2006-10-26 18:15:42 +0000489 int i;
drhea678832008-12-10 19:26:22 +0000490 int nSep = sqlite3Strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000491 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000492 if( needCsvQuote[((unsigned char*)z)[i]]
493 || (z[i]==p->separator[0] &&
494 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000495 i = 0;
496 break;
497 }
498 }
499 if( i==0 ){
500 putc('"', out);
501 for(i=0; z[i]; i++){
502 if( z[i]=='"' ) putc('"', out);
503 putc(z[i], out);
504 }
505 putc('"', out);
506 }else{
507 fprintf(out, "%s", z);
508 }
drh8e64d1c2004-10-07 00:32:39 +0000509 }
510 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000511 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000512 }
513}
514
danielk19774af00c62005-01-23 23:43:21 +0000515#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000516/*
drh4c504392000-10-16 22:06:40 +0000517** This routine runs when the user presses Ctrl-C
518*/
519static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000520 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000521 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000522 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000523}
danielk19774af00c62005-01-23 23:43:21 +0000524#endif
drh4c504392000-10-16 22:06:40 +0000525
526/*
drh75897232000-05-29 14:26:00 +0000527** This is the callback routine that the SQLite library
528** invokes for each row of a query result.
529*/
530static int callback(void *pArg, int nArg, char **azArg, char **azCol){
531 int i;
532 struct callback_data *p = (struct callback_data*)pArg;
533 switch( p->mode ){
534 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000535 int w = 5;
drh6a535342001-10-19 16:44:56 +0000536 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000537 for(i=0; i<nArg; i++){
drhea678832008-12-10 19:26:22 +0000538 int len = sqlite3Strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000539 if( len>w ) w = len;
540 }
drh75897232000-05-29 14:26:00 +0000541 if( p->cnt++>0 ) fprintf(p->out,"\n");
542 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000543 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000544 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000545 }
546 break;
547 }
danielk19770d78bae2008-01-03 07:09:48 +0000548 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000549 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000550 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000551 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000552 int w, n;
553 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000554 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000555 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000556 w = 0;
drh75897232000-05-29 14:26:00 +0000557 }
drha0c66f52000-07-29 13:20:21 +0000558 if( w<=0 ){
drhea678832008-12-10 19:26:22 +0000559 w = sqlite3Strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000560 if( w<10 ) w = 10;
drhea678832008-12-10 19:26:22 +0000561 n = sqlite3Strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000562 if( w<n ) w = n;
563 }
564 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000565 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000566 }
567 if( p->showHeader ){
568 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
569 }
570 }
571 if( p->showHeader ){
572 for(i=0; i<nArg; i++){
573 int w;
574 if( i<ArraySize(p->actualWidth) ){
575 w = p->actualWidth[i];
576 }else{
577 w = 10;
578 }
579 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
580 "----------------------------------------------------------",
581 i==nArg-1 ? "\n": " ");
582 }
drh75897232000-05-29 14:26:00 +0000583 }
584 }
drh6a535342001-10-19 16:44:56 +0000585 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000586 for(i=0; i<nArg; i++){
587 int w;
drha0c66f52000-07-29 13:20:21 +0000588 if( i<ArraySize(p->actualWidth) ){
589 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000590 }else{
591 w = 10;
592 }
drhea678832008-12-10 19:26:22 +0000593 if( p->mode==MODE_Explain && azArg[i] &&
594 sqlite3Strlen30(azArg[i])>w ){
595 w = sqlite3Strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000596 }
drhc61053b2000-06-04 12:58:36 +0000597 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000598 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000599 }
600 break;
601 }
drhe3710332000-09-29 13:30:53 +0000602 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000603 case MODE_List: {
604 if( p->cnt++==0 && p->showHeader ){
605 for(i=0; i<nArg; i++){
606 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
607 }
608 }
drh6a535342001-10-19 16:44:56 +0000609 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000610 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000611 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000612 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000613 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000614 if( i<nArg-1 ){
615 fprintf(p->out, "%s", p->separator);
616 }else if( p->mode==MODE_Semi ){
617 fprintf(p->out, ";\n");
618 }else{
619 fprintf(p->out, "\n");
620 }
drh75897232000-05-29 14:26:00 +0000621 }
622 break;
623 }
drh1e5d0e92000-05-31 23:33:17 +0000624 case MODE_Html: {
625 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000626 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000627 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000628 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
drh1e5d0e92000-05-31 23:33:17 +0000629 }
mihailim57c591a2008-06-23 21:26:05 +0000630 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000631 }
drh6a535342001-10-19 16:44:56 +0000632 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000633 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000634 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000635 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000636 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000637 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000638 }
mihailim57c591a2008-06-23 21:26:05 +0000639 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000640 break;
641 }
drhfeac5f82004-08-01 00:10:45 +0000642 case MODE_Tcl: {
643 if( p->cnt++==0 && p->showHeader ){
644 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000645 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000646 fprintf(p->out, "%s", p->separator);
647 }
648 fprintf(p->out,"\n");
649 }
650 if( azArg==0 ) break;
651 for(i=0; i<nArg; i++){
652 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
653 fprintf(p->out, "%s", p->separator);
654 }
655 fprintf(p->out,"\n");
656 break;
657 }
drh8e64d1c2004-10-07 00:32:39 +0000658 case MODE_Csv: {
659 if( p->cnt++==0 && p->showHeader ){
660 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000661 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000662 }
663 fprintf(p->out,"\n");
664 }
665 if( azArg==0 ) break;
666 for(i=0; i<nArg; i++){
667 output_csv(p, azArg[i], i<nArg-1);
668 }
669 fprintf(p->out,"\n");
670 break;
671 }
drh28bd4bc2000-06-15 15:57:22 +0000672 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000673 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000674 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000675 for(i=0; i<nArg; i++){
676 char *zSep = i>0 ? ",": "";
677 if( azArg[i]==0 ){
678 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000679 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000680 fprintf(p->out,"%s%s",zSep, azArg[i]);
681 }else{
682 if( zSep[0] ) fprintf(p->out,"%s",zSep);
683 output_quoted_string(p->out, azArg[i]);
684 }
685 }
686 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000687 break;
drh28bd4bc2000-06-15 15:57:22 +0000688 }
persicom1d0b8722002-04-18 02:53:04 +0000689 }
drh75897232000-05-29 14:26:00 +0000690 return 0;
691}
692
693/*
drh33048c02001-10-01 14:29:22 +0000694** Set the destination table field of the callback_data structure to
695** the name of the table given. Escape any quote characters in the
696** table name.
697*/
698static void set_table_name(struct callback_data *p, const char *zName){
699 int i, n;
700 int needQuote;
701 char *z;
702
703 if( p->zDestTable ){
704 free(p->zDestTable);
705 p->zDestTable = 0;
706 }
707 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000708 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000709 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000710 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000711 needQuote = 1;
712 if( zName[i]=='\'' ) n++;
713 }
714 }
715 if( needQuote ) n += 2;
716 z = p->zDestTable = malloc( n+1 );
717 if( z==0 ){
718 fprintf(stderr,"Out of memory!\n");
719 exit(1);
720 }
721 n = 0;
722 if( needQuote ) z[n++] = '\'';
723 for(i=0; zName[i]; i++){
724 z[n++] = zName[i];
725 if( zName[i]=='\'' ) z[n++] = '\'';
726 }
727 if( needQuote ) z[n++] = '\'';
728 z[n] = 0;
729}
730
danielk19772a02e332004-06-05 08:04:36 +0000731/* zIn is either a pointer to a NULL-terminated string in memory obtained
732** from malloc(), or a NULL pointer. The string pointed to by zAppend is
733** added to zIn, and the result returned in memory obtained from malloc().
734** zIn, if it was not NULL, is freed.
735**
736** If the third argument, quote, is not '\0', then it is used as a
737** quote character for zAppend.
738*/
drhc28490c2006-10-26 14:25:58 +0000739static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000740 int len;
741 int i;
drhea678832008-12-10 19:26:22 +0000742 int nAppend = sqlite3Strlen30(zAppend);
743 int nIn = (zIn?sqlite3Strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000744
745 len = nAppend+nIn+1;
746 if( quote ){
747 len += 2;
748 for(i=0; i<nAppend; i++){
749 if( zAppend[i]==quote ) len++;
750 }
751 }
752
753 zIn = (char *)realloc(zIn, len);
754 if( !zIn ){
755 return 0;
756 }
757
758 if( quote ){
759 char *zCsr = &zIn[nIn];
760 *zCsr++ = quote;
761 for(i=0; i<nAppend; i++){
762 *zCsr++ = zAppend[i];
763 if( zAppend[i]==quote ) *zCsr++ = quote;
764 }
765 *zCsr++ = quote;
766 *zCsr++ = '\0';
767 assert( (zCsr-zIn)==len );
768 }else{
769 memcpy(&zIn[nIn], zAppend, nAppend);
770 zIn[len-1] = '\0';
771 }
772
773 return zIn;
774}
775
drhdd3d4592004-08-30 01:54:05 +0000776
777/*
778** Execute a query statement that has a single result column. Print
779** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000780**
781** This is used, for example, to show the schema of the database by
782** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000783*/
784static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
785 sqlite3_stmt *pSelect;
786 int rc;
787 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
788 if( rc!=SQLITE_OK || !pSelect ){
789 return rc;
790 }
791 rc = sqlite3_step(pSelect);
792 while( rc==SQLITE_ROW ){
793 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
794 rc = sqlite3_step(pSelect);
795 }
796 return sqlite3_finalize(pSelect);
797}
798
799
drh33048c02001-10-01 14:29:22 +0000800/*
drh4c653a02000-06-07 01:27:47 +0000801** This is a different callback routine used for dumping the database.
802** Each row received by this callback consists of a table name,
803** the table type ("index" or "table") and SQL to create the table.
804** This routine should print text sufficient to recreate the table.
805*/
806static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000807 int rc;
808 const char *zTable;
809 const char *zType;
810 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000811 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000812
drh902b9ee2008-12-05 17:17:07 +0000813 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +0000814 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000815 zTable = azArg[0];
816 zType = azArg[1];
817 zSql = azArg[2];
818
drh00b950d2005-09-11 02:03:03 +0000819 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000820 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000821 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
822 fprintf(p->out, "ANALYZE sqlite_master;\n");
823 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
824 return 0;
drh45e29d82006-11-20 16:21:10 +0000825 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
826 char *zIns;
827 if( !p->writableSchema ){
828 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
829 p->writableSchema = 1;
830 }
831 zIns = sqlite3_mprintf(
832 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
833 "VALUES('table','%q','%q',0,'%q');",
834 zTable, zTable, zSql);
835 fprintf(p->out, "%s\n", zIns);
836 sqlite3_free(zIns);
837 return 0;
drh00b950d2005-09-11 02:03:03 +0000838 }else{
839 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000840 }
danielk19772a02e332004-06-05 08:04:36 +0000841
842 if( strcmp(zType, "table")==0 ){
843 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000844 char *zSelect = 0;
845 char *zTableInfo = 0;
846 char *zTmp = 0;
847
848 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
849 zTableInfo = appendText(zTableInfo, zTable, '"');
850 zTableInfo = appendText(zTableInfo, ");", 0);
851
852 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
853 if( zTableInfo ) free(zTableInfo);
854 if( rc!=SQLITE_OK || !pTableInfo ){
855 return 1;
856 }
857
858 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
859 zTmp = appendText(zTmp, zTable, '"');
860 if( zTmp ){
861 zSelect = appendText(zSelect, zTmp, '\'');
862 }
863 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
864 rc = sqlite3_step(pTableInfo);
865 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000866 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000867 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000868 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000869 rc = sqlite3_step(pTableInfo);
870 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000871 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000872 }else{
873 zSelect = appendText(zSelect, ") ", 0);
874 }
875 }
876 rc = sqlite3_finalize(pTableInfo);
877 if( rc!=SQLITE_OK ){
878 if( zSelect ) free(zSelect);
879 return 1;
880 }
881 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
882 zSelect = appendText(zSelect, zTable, '"');
883
drhdd3d4592004-08-30 01:54:05 +0000884 rc = run_table_dump_query(p->out, p->db, zSelect);
885 if( rc==SQLITE_CORRUPT ){
886 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
887 rc = run_table_dump_query(p->out, p->db, zSelect);
888 }
danielk19772a02e332004-06-05 08:04:36 +0000889 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000890 }
drh4c653a02000-06-07 01:27:47 +0000891 return 0;
892}
893
894/*
drh45e29d82006-11-20 16:21:10 +0000895** Run zQuery. Use dump_callback() as the callback routine so that
896** the contents of the query are output as SQL statements.
897**
drhdd3d4592004-08-30 01:54:05 +0000898** If we get a SQLITE_CORRUPT error, rerun the query after appending
899** "ORDER BY rowid DESC" to the end.
900*/
901static int run_schema_dump_query(
902 struct callback_data *p,
903 const char *zQuery,
904 char **pzErrMsg
905){
906 int rc;
907 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
908 if( rc==SQLITE_CORRUPT ){
909 char *zQ2;
drhea678832008-12-10 19:26:22 +0000910 int len = sqlite3Strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +0000911 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
912 zQ2 = malloc( len+100 );
913 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000914 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000915 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
916 free(zQ2);
917 }
918 return rc;
919}
920
921/*
drh75897232000-05-29 14:26:00 +0000922** Text of a help message
923*/
persicom1d0b8722002-04-18 02:53:04 +0000924static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000925 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000926 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000927 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000928 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000929 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000930 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000931 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000932 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000933 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000934 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000935#ifdef SQLITE_ENABLE_IOTRACE
936 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
937#endif
drh70df4fe2006-06-13 15:12:21 +0000938#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000939 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000940#endif
danielk19776b77a362005-01-13 11:10:25 +0000941 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000942 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000943 " column Left-aligned columns. (See .width)\n"
944 " html HTML <table> code\n"
945 " insert SQL insert statements for TABLE\n"
946 " line One value per line\n"
947 " list Values delimited by .separator string\n"
948 " tabs Tab-separated values\n"
949 " tcl TCL list elements\n"
950 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000951 ".output FILENAME Send output to FILENAME\n"
952 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000953 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000954 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000955 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000956 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000957 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000958 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000959 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000960 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +0000961#if HAS_TIMER
962 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
963#endif
drh75897232000-05-29 14:26:00 +0000964 ".width NUM NUM ... Set column widths for \"column\" mode\n"
965;
966
drhdaffd0e2001-04-11 14:28:42 +0000967/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000968static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000969
drh75897232000-05-29 14:26:00 +0000970/*
drh44c2eb12003-04-30 11:38:26 +0000971** Make sure the database is open. If it is not, then open it. If
972** the database fails to open, print an error message and exit.
973*/
974static void open_db(struct callback_data *p){
975 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000976 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000977 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +0000978 if( db && sqlite3_errcode(db)==SQLITE_OK ){
979 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
980 shellstaticFunc, 0, 0);
981 }
982 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +0000983 fprintf(stderr,"Unable to open database \"%s\": %s\n",
984 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000985 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000986 }
drhc2e87a32006-06-27 15:16:14 +0000987#ifndef SQLITE_OMIT_LOAD_EXTENSION
988 sqlite3_enable_load_extension(p->db, 1);
989#endif
drh44c2eb12003-04-30 11:38:26 +0000990 }
991}
992
993/*
drhfeac5f82004-08-01 00:10:45 +0000994** Do C-language style dequoting.
995**
996** \t -> tab
997** \n -> newline
998** \r -> carriage return
999** \NNN -> ascii character NNN in octal
1000** \\ -> backslash
1001*/
1002static void resolve_backslashes(char *z){
1003 int i, j, c;
1004 for(i=j=0; (c = z[i])!=0; i++, j++){
1005 if( c=='\\' ){
1006 c = z[++i];
1007 if( c=='n' ){
1008 c = '\n';
1009 }else if( c=='t' ){
1010 c = '\t';
1011 }else if( c=='r' ){
1012 c = '\r';
1013 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001014 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001015 if( z[i+1]>='0' && z[i+1]<='7' ){
1016 i++;
1017 c = (c<<3) + z[i] - '0';
1018 if( z[i+1]>='0' && z[i+1]<='7' ){
1019 i++;
1020 c = (c<<3) + z[i] - '0';
1021 }
1022 }
1023 }
1024 }
1025 z[j] = c;
1026 }
1027 z[j] = 0;
1028}
1029
1030/*
drhc28490c2006-10-26 14:25:58 +00001031** Interpret zArg as a boolean value. Return either 0 or 1.
1032*/
1033static int booleanValue(char *zArg){
1034 int val = atoi(zArg);
1035 int j;
1036 for(j=0; zArg[j]; j++){
1037 zArg[j] = tolower(zArg[j]);
1038 }
1039 if( strcmp(zArg,"on")==0 ){
1040 val = 1;
1041 }else if( strcmp(zArg,"yes")==0 ){
1042 val = 1;
1043 }
1044 return val;
1045}
1046
1047/*
drh75897232000-05-29 14:26:00 +00001048** If an input line begins with "." then invoke this routine to
1049** process that line.
drh67505e72002-04-19 12:34:06 +00001050**
drh47ad6842006-11-08 12:25:42 +00001051** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001052*/
drh44c2eb12003-04-30 11:38:26 +00001053static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001054 int i = 1;
1055 int nArg = 0;
1056 int n, c;
drh67505e72002-04-19 12:34:06 +00001057 int rc = 0;
drh75897232000-05-29 14:26:00 +00001058 char *azArg[50];
1059
1060 /* Parse the input line into tokens.
1061 */
1062 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001063 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001064 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001065 if( zLine[i]=='\'' || zLine[i]=='"' ){
1066 int delim = zLine[i++];
1067 azArg[nArg++] = &zLine[i];
1068 while( zLine[i] && zLine[i]!=delim ){ i++; }
1069 if( zLine[i]==delim ){
1070 zLine[i++] = 0;
1071 }
drhfeac5f82004-08-01 00:10:45 +00001072 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001073 }else{
1074 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001075 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001076 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001077 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001078 }
1079 }
1080
1081 /* Process the input line.
1082 */
drh67505e72002-04-19 12:34:06 +00001083 if( nArg==0 ) return rc;
drhea678832008-12-10 19:26:22 +00001084 n = sqlite3Strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001085 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001086 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1087 bail_on_error = booleanValue(azArg[1]);
1088 }else
1089
jplyon6a65bb32003-05-04 07:25:57 +00001090 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001091 struct callback_data data;
1092 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001093 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001094 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001095 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001096 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001097 data.colWidth[0] = 3;
1098 data.colWidth[1] = 15;
1099 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001100 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001101 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001102 if( zErrMsg ){
1103 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001104 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001105 }
1106 }else
1107
drh4c653a02000-06-07 01:27:47 +00001108 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1109 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001110 open_db(p);
drh33048c02001-10-01 14:29:22 +00001111 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001112 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001113 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001114 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001115 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001116 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001117 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001118 );
1119 run_table_dump_query(p->out, p->db,
1120 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001121 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001122 );
drh4c653a02000-06-07 01:27:47 +00001123 }else{
1124 int i;
drhdd3d4592004-08-30 01:54:05 +00001125 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001126 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001127 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001128 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001129 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001130 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001131 run_table_dump_query(p->out, p->db,
1132 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001133 "WHERE sql NOT NULL"
1134 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001135 " AND tbl_name LIKE shellstatic()"
1136 );
danielk1977bc6ada42004-06-30 08:20:16 +00001137 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001138 }
1139 }
drh45e29d82006-11-20 16:21:10 +00001140 if( p->writableSchema ){
1141 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1142 p->writableSchema = 0;
1143 }
drh93f41e52008-08-11 19:12:34 +00001144 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001145 if( zErrMsg ){
1146 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001147 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001148 }else{
1149 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001150 }
1151 }else
drh75897232000-05-29 14:26:00 +00001152
drhdaffd0e2001-04-11 14:28:42 +00001153 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001154 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001155 }else
1156
drh75897232000-05-29 14:26:00 +00001157 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001158 rc = 2;
drh75897232000-05-29 14:26:00 +00001159 }else
1160
drhdd45df82002-04-18 12:39:03 +00001161 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001162 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001163 if(val == 1) {
1164 if(!p->explainPrev.valid) {
1165 p->explainPrev.valid = 1;
1166 p->explainPrev.mode = p->mode;
1167 p->explainPrev.showHeader = p->showHeader;
1168 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1169 }
1170 /* We could put this code under the !p->explainValid
1171 ** condition so that it does not execute if we are already in
1172 ** explain mode. However, always executing it allows us an easy
1173 ** was to reset to explain mode in case the user previously
1174 ** did an .explain followed by a .width, .mode or .header
1175 ** command.
1176 */
danielk19770d78bae2008-01-03 07:09:48 +00001177 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001178 p->showHeader = 1;
1179 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001180 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001181 p->colWidth[1] = 13; /* opcode */
1182 p->colWidth[2] = 4; /* P1 */
1183 p->colWidth[3] = 4; /* P2 */
1184 p->colWidth[4] = 4; /* P3 */
1185 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001186 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001187 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001188 }else if (p->explainPrev.valid) {
1189 p->explainPrev.valid = 0;
1190 p->mode = p->explainPrev.mode;
1191 p->showHeader = p->explainPrev.showHeader;
1192 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1193 }
drh75897232000-05-29 14:26:00 +00001194 }else
1195
drhc28490c2006-10-26 14:25:58 +00001196 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001197 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001198 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001199 }else
1200
1201 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1202 fprintf(stderr,zHelp);
1203 }else
1204
drhfeac5f82004-08-01 00:10:45 +00001205 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1206 char *zTable = azArg[2]; /* Insert data into this table */
1207 char *zFile = azArg[1]; /* The file from which to extract data */
1208 sqlite3_stmt *pStmt; /* A statement */
1209 int rc; /* Result code */
1210 int nCol; /* Number of columns in the table */
1211 int nByte; /* Number of bytes in an SQL string */
1212 int i, j; /* Loop counters */
1213 int nSep; /* Number of bytes in p->separator[] */
1214 char *zSql; /* An SQL statement */
1215 char *zLine; /* A single line of input from the file */
1216 char **azCol; /* zLine[] broken up into columns */
1217 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001218 FILE *in; /* The input file */
1219 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001220
drha543c822006-06-08 16:10:14 +00001221 open_db(p);
drhea678832008-12-10 19:26:22 +00001222 nSep = sqlite3Strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001223 if( nSep==0 ){
1224 fprintf(stderr, "non-null separator required for import\n");
1225 return 0;
1226 }
1227 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1228 if( zSql==0 ) return 0;
drhea678832008-12-10 19:26:22 +00001229 nByte = sqlite3Strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001230 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001231 sqlite3_free(zSql);
1232 if( rc ){
1233 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1234 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001235 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001236 }else{
1237 nCol = sqlite3_column_count(pStmt);
1238 }
1239 sqlite3_finalize(pStmt);
1240 if( nCol==0 ) return 0;
1241 zSql = malloc( nByte + 20 + nCol*2 );
1242 if( zSql==0 ) return 0;
1243 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drhea678832008-12-10 19:26:22 +00001244 j = sqlite3Strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001245 for(i=1; i<nCol; i++){
1246 zSql[j++] = ',';
1247 zSql[j++] = '?';
1248 }
1249 zSql[j++] = ')';
1250 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001251 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001252 free(zSql);
1253 if( rc ){
1254 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1255 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001256 return 1;
drhfeac5f82004-08-01 00:10:45 +00001257 }
1258 in = fopen(zFile, "rb");
1259 if( in==0 ){
1260 fprintf(stderr, "cannot open file: %s\n", zFile);
1261 sqlite3_finalize(pStmt);
1262 return 0;
1263 }
1264 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001265 if( azCol==0 ){
1266 fclose(in);
1267 return 0;
1268 }
drhfeac5f82004-08-01 00:10:45 +00001269 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1270 zCommit = "COMMIT";
1271 while( (zLine = local_getline(0, in))!=0 ){
1272 char *z;
1273 i = 0;
drhb860bc92004-08-04 15:16:55 +00001274 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001275 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001276 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001277 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1278 *z = 0;
1279 i++;
drhb860bc92004-08-04 15:16:55 +00001280 if( i<nCol ){
1281 azCol[i] = &z[nSep];
1282 z += nSep-1;
1283 }
drhfeac5f82004-08-01 00:10:45 +00001284 }
1285 }
drh1cd7f832005-08-05 18:50:51 +00001286 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001287 if( i+1!=nCol ){
1288 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1289 zFile, lineno, nCol, i+1);
1290 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001291 free(zLine);
drhb860bc92004-08-04 15:16:55 +00001292 break;
1293 }
drhfeac5f82004-08-01 00:10:45 +00001294 for(i=0; i<nCol; i++){
1295 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1296 }
1297 sqlite3_step(pStmt);
1298 rc = sqlite3_reset(pStmt);
1299 free(zLine);
1300 if( rc!=SQLITE_OK ){
1301 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1302 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001303 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001304 break;
1305 }
1306 }
1307 free(azCol);
1308 fclose(in);
1309 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001310 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001311 }else
1312
drh75897232000-05-29 14:26:00 +00001313 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1314 struct callback_data data;
1315 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001316 open_db(p);
drh75897232000-05-29 14:26:00 +00001317 memcpy(&data, p, sizeof(data));
1318 data.showHeader = 0;
1319 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001320 zShellStatic = azArg[1];
1321 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001322 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001323 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001324 "UNION ALL "
1325 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001326 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001327 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001328 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001329 );
danielk1977bc6ada42004-06-30 08:20:16 +00001330 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001331 if( zErrMsg ){
1332 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001333 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001334 }
1335 }else
1336
drhae5e4452007-05-03 17:18:36 +00001337#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001338 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001339 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001340 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1341 iotrace = 0;
1342 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001343 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001344 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001345 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001346 iotrace = stdout;
1347 }else{
1348 iotrace = fopen(azArg[1], "w");
1349 if( iotrace==0 ){
1350 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001351 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001352 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001353 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001354 }
1355 }
1356 }else
drhae5e4452007-05-03 17:18:36 +00001357#endif
drhb0603412007-02-28 04:47:26 +00001358
drh70df4fe2006-06-13 15:12:21 +00001359#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001360 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1361 const char *zFile, *zProc;
1362 char *zErrMsg = 0;
1363 int rc;
1364 zFile = azArg[1];
1365 zProc = nArg>=3 ? azArg[2] : 0;
1366 open_db(p);
1367 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1368 if( rc!=SQLITE_OK ){
1369 fprintf(stderr, "%s\n", zErrMsg);
1370 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001371 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001372 }
1373 }else
drh70df4fe2006-06-13 15:12:21 +00001374#endif
drh1e397f82006-06-08 15:28:43 +00001375
drh28bd4bc2000-06-15 15:57:22 +00001376 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drhea678832008-12-10 19:26:22 +00001377 int n2 = sqlite3Strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001378 if( strncmp(azArg[1],"line",n2)==0
1379 ||
1380 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001381 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001382 }else if( strncmp(azArg[1],"column",n2)==0
1383 ||
1384 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001385 p->mode = MODE_Column;
1386 }else if( strncmp(azArg[1],"list",n2)==0 ){
1387 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001388 }else if( strncmp(azArg[1],"html",n2)==0 ){
1389 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001390 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1391 p->mode = MODE_Tcl;
1392 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001393 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001394 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001395 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1396 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001397 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001398 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1399 p->mode = MODE_Insert;
1400 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001401 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001402 }else{
drh33048c02001-10-01 14:29:22 +00001403 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001404 }
drhdaffd0e2001-04-11 14:28:42 +00001405 }else {
drhcf68ae92006-12-19 18:47:41 +00001406 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001407 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001408 }
1409 }else
1410
persicom7e2dfdd2002-04-18 02:46:52 +00001411 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001412 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1413 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001414 }else
1415
drh75897232000-05-29 14:26:00 +00001416 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1417 if( p->out!=stdout ){
1418 fclose(p->out);
1419 }
1420 if( strcmp(azArg[1],"stdout")==0 ){
1421 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001422 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001423 }else{
drha1f9b5e2004-02-14 16:31:02 +00001424 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001425 if( p->out==0 ){
1426 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1427 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001428 } else {
drh5bb3eb92007-05-04 13:15:55 +00001429 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001430 }
1431 }
1432 }else
1433
drhdd45df82002-04-18 12:39:03 +00001434 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001435 if( nArg >= 2) {
1436 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1437 }
1438 if( nArg >= 3) {
1439 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1440 }
1441 }else
1442
1443 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001444 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001445 }else
1446
drhdaffd0e2001-04-11 14:28:42 +00001447 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001448 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001449 if( alt==0 ){
1450 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1451 }else{
1452 process_input(p, alt);
1453 fclose(alt);
1454 }
1455 }else
1456
drh75897232000-05-29 14:26:00 +00001457 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1458 struct callback_data data;
1459 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001460 open_db(p);
drh75897232000-05-29 14:26:00 +00001461 memcpy(&data, p, sizeof(data));
1462 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001463 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001464 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001465 int i;
1466 for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
1467 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001468 char *new_argv[2], *new_colv[2];
1469 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1470 " type text,\n"
1471 " name text,\n"
1472 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001473 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001474 " sql text\n"
1475 ")";
1476 new_argv[1] = 0;
1477 new_colv[0] = "sql";
1478 new_colv[1] = 0;
1479 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001480 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001481 char *new_argv[2], *new_colv[2];
1482 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1483 " type text,\n"
1484 " name text,\n"
1485 " tbl_name text,\n"
1486 " rootpage integer,\n"
1487 " sql text\n"
1488 ")";
1489 new_argv[1] = 0;
1490 new_colv[0] = "sql";
1491 new_colv[1] = 0;
1492 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001493 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001494 zShellStatic = azArg[1];
1495 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001496 "SELECT sql FROM "
1497 " (SELECT * FROM sqlite_master UNION ALL"
1498 " SELECT * FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001499 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001500 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001501 callback, &data, &zErrMsg);
1502 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001503 }
drh75897232000-05-29 14:26:00 +00001504 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001505 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001506 "SELECT sql FROM "
1507 " (SELECT * FROM sqlite_master UNION ALL"
1508 " SELECT * FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001509 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001510 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001511 callback, &data, &zErrMsg
1512 );
drh75897232000-05-29 14:26:00 +00001513 }
drh75897232000-05-29 14:26:00 +00001514 if( zErrMsg ){
1515 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001516 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001517 }
1518 }else
1519
1520 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001521 sqlite3_snprintf(sizeof(p->separator), p->separator,
1522 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001523 }else
1524
persicom7e2dfdd2002-04-18 02:46:52 +00001525 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1526 int i;
1527 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001528 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001529 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001530 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001531 fprintf(p->out,"%9.9s: ", "nullvalue");
1532 output_c_string(p->out, p->nullvalue);
1533 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001534 fprintf(p->out,"%9.9s: %s\n","output",
drhea678832008-12-10 19:26:22 +00001535 sqlite3Strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001536 fprintf(p->out,"%9.9s: ", "separator");
1537 output_c_string(p->out, p->separator);
1538 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001539 fprintf(p->out,"%9.9s: ","width");
1540 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001541 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001542 }
drhfeac5f82004-08-01 00:10:45 +00001543 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001544 }else
1545
drh2dfbbca2000-07-28 14:32:48 +00001546 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001547 char **azResult;
1548 int nRow, rc;
1549 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001550 open_db(p);
drha50da102000-08-08 20:19:09 +00001551 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001552 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001553 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001554 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001555 "UNION ALL "
1556 "SELECT name FROM sqlite_temp_master "
1557 "WHERE type IN ('table','view') "
1558 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001559 &azResult, &nRow, 0, &zErrMsg
1560 );
drha50da102000-08-08 20:19:09 +00001561 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001562 zShellStatic = azArg[1];
1563 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001564 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001565 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001566 "UNION ALL "
1567 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001568 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001569 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001570 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001571 );
danielk1977bc6ada42004-06-30 08:20:16 +00001572 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001573 }
drh75897232000-05-29 14:26:00 +00001574 if( zErrMsg ){
1575 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001576 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001577 }
drhe3710332000-09-29 13:30:53 +00001578 if( rc==SQLITE_OK ){
1579 int len, maxlen = 0;
1580 int i, j;
1581 int nPrintCol, nPrintRow;
1582 for(i=1; i<=nRow; i++){
1583 if( azResult[i]==0 ) continue;
drhea678832008-12-10 19:26:22 +00001584 len = sqlite3Strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00001585 if( len>maxlen ) maxlen = len;
1586 }
1587 nPrintCol = 80/(maxlen+2);
1588 if( nPrintCol<1 ) nPrintCol = 1;
1589 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1590 for(i=0; i<nPrintRow; i++){
1591 for(j=i+1; j<=nRow; j+=nPrintRow){
1592 char *zSp = j<=nPrintRow ? "" : " ";
1593 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1594 }
1595 printf("\n");
1596 }
drh47ad6842006-11-08 12:25:42 +00001597 }else{
1598 rc = 1;
drhe3710332000-09-29 13:30:53 +00001599 }
danielk19776f8a5032004-05-10 10:34:51 +00001600 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001601 }else
1602
drh3b1a9882007-11-02 12:53:03 +00001603 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001604 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001605 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001606 }else
drh3b1a9882007-11-02 12:53:03 +00001607
1608#if HAS_TIMER
1609 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
1610 enableTimer = booleanValue(azArg[1]);
1611 }else
1612#endif
drh2dfbbca2000-07-28 14:32:48 +00001613
drh75897232000-05-29 14:26:00 +00001614 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1615 int j;
drh43617e92006-03-06 20:55:46 +00001616 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001617 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1618 p->colWidth[j-1] = atoi(azArg[j]);
1619 }
1620 }else
1621
drh3b1a9882007-11-02 12:53:03 +00001622
drh75897232000-05-29 14:26:00 +00001623 {
drh67505e72002-04-19 12:34:06 +00001624 fprintf(stderr, "unknown command or invalid arguments: "
1625 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001626 }
drh67505e72002-04-19 12:34:06 +00001627
1628 return rc;
drh75897232000-05-29 14:26:00 +00001629}
1630
drh67505e72002-04-19 12:34:06 +00001631/*
drh91a66392007-09-07 01:12:32 +00001632** Return TRUE if a semicolon occurs anywhere in the first N characters
1633** of string z[].
drh324ccef2003-02-05 14:06:20 +00001634*/
drh91a66392007-09-07 01:12:32 +00001635static int _contains_semicolon(const char *z, int N){
1636 int i;
1637 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
1638 return 0;
drh324ccef2003-02-05 14:06:20 +00001639}
1640
1641/*
drh70c7a4b2003-04-26 03:03:06 +00001642** Test to see if a line consists entirely of whitespace.
1643*/
1644static int _all_whitespace(const char *z){
1645 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001646 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001647 if( *z=='/' && z[1]=='*' ){
1648 z += 2;
1649 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1650 if( *z==0 ) return 0;
1651 z++;
1652 continue;
1653 }
1654 if( *z=='-' && z[1]=='-' ){
1655 z += 2;
1656 while( *z && *z!='\n' ){ z++; }
1657 if( *z==0 ) return 1;
1658 continue;
1659 }
1660 return 0;
1661 }
1662 return 1;
1663}
1664
1665/*
drha9b17162003-04-29 18:01:28 +00001666** Return TRUE if the line typed in is an SQL command terminator other
1667** than a semi-colon. The SQL Server style "go" command is understood
1668** as is the Oracle "/".
1669*/
1670static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001671 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drha9b17162003-04-29 18:01:28 +00001672 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
drhc8d74412004-08-31 23:41:26 +00001673 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1674 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001675 return 1; /* SQL Server */
1676 }
1677 return 0;
1678}
1679
1680/*
drh67505e72002-04-19 12:34:06 +00001681** Read input from *in and process it. If *in==0 then input
1682** is interactive - the user is typing it it. Otherwise, input
1683** is coming from a file or device. A prompt is issued and history
1684** is saved only if input is interactive. An interrupt signal will
1685** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001686**
1687** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001688*/
drhc28490c2006-10-26 14:25:58 +00001689static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001690 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001691 char *zSql = 0;
1692 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00001693 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00001694 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001695 int rc;
1696 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001697 int lineno = 0;
1698 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001699
1700 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1701 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001702 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001703 zLine = one_input_line(zSql, in);
1704 if( zLine==0 ){
1705 break; /* We have reached EOF */
1706 }
drh67505e72002-04-19 12:34:06 +00001707 if( seenInterrupt ){
1708 if( in!=0 ) break;
1709 seenInterrupt = 0;
1710 }
drhc28490c2006-10-26 14:25:58 +00001711 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001712 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001713 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001714 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001715 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001716 if( rc==2 ){
1717 break;
1718 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001719 errCnt++;
1720 }
drhdaffd0e2001-04-11 14:28:42 +00001721 continue;
1722 }
drhc717b382008-11-11 00:30:11 +00001723 if( _is_command_terminator(zLine) && sqlite3_complete(zSql) ){
drh5bb3eb92007-05-04 13:15:55 +00001724 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001725 }
drh91a66392007-09-07 01:12:32 +00001726 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00001727 if( zSql==0 ){
1728 int i;
drh4c755c02004-08-08 20:22:17 +00001729 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001730 if( zLine[i]!=0 ){
drhea678832008-12-10 19:26:22 +00001731 nSql = sqlite3Strlen30(zLine);
drhdaffd0e2001-04-11 14:28:42 +00001732 zSql = malloc( nSql+1 );
drhc1f44942006-05-10 14:39:13 +00001733 if( zSql==0 ){
1734 fprintf(stderr, "out of memory\n");
1735 exit(1);
1736 }
drh5bb3eb92007-05-04 13:15:55 +00001737 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001738 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001739 }
1740 }else{
drhea678832008-12-10 19:26:22 +00001741 int len = sqlite3Strlen30(zLine);
drhdaffd0e2001-04-11 14:28:42 +00001742 zSql = realloc( zSql, nSql + len + 2 );
1743 if( zSql==0 ){
1744 fprintf(stderr,"%s: out of memory!\n", Argv0);
1745 exit(1);
1746 }
drh5bb3eb92007-05-04 13:15:55 +00001747 zSql[nSql++] = '\n';
1748 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001749 nSql += len;
1750 }
drh91a66392007-09-07 01:12:32 +00001751 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1752 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001753 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001754 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00001755 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00001756 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00001757 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00001758 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001759 char zPrefix[100];
1760 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001761 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1762 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001763 }else{
drh5bb3eb92007-05-04 13:15:55 +00001764 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001765 }
drh7f953e22002-07-13 17:33:45 +00001766 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001767 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001768 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001769 zErrMsg = 0;
1770 }else{
drhc28490c2006-10-26 14:25:58 +00001771 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001772 }
drhc49f44e2006-10-26 18:15:42 +00001773 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001774 }
1775 free(zSql);
1776 zSql = 0;
1777 nSql = 0;
1778 }
1779 }
1780 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00001781 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001782 free(zSql);
1783 }
danielk19772ac27622007-07-03 05:31:16 +00001784 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001785 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001786}
1787
drh67505e72002-04-19 12:34:06 +00001788/*
1789** Return a pathname which is the user's home directory. A
1790** 0 return indicates an error of some kind. Space to hold the
1791** resulting string is obtained from malloc(). The calling
1792** function should free the result.
1793*/
1794static char *find_home_dir(void){
1795 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001796
chw97185482008-11-17 08:05:31 +00001797#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00001798 struct passwd *pwent;
1799 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001800 if( (pwent=getpwuid(uid)) != NULL) {
1801 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001802 }
1803#endif
1804
chw65d3c132007-11-12 21:09:10 +00001805#if defined(_WIN32_WCE)
1806 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
1807 */
1808 home_dir = strdup("/");
1809#else
1810
drh164a1b62006-08-19 11:15:20 +00001811#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1812 if (!home_dir) {
1813 home_dir = getenv("USERPROFILE");
1814 }
1815#endif
1816
drh67505e72002-04-19 12:34:06 +00001817 if (!home_dir) {
1818 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001819 }
1820
drhcdb36b72006-06-12 12:57:45 +00001821#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001822 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001823 char *zDrive, *zPath;
1824 int n;
1825 zDrive = getenv("HOMEDRIVE");
1826 zPath = getenv("HOMEPATH");
1827 if( zDrive && zPath ){
drhea678832008-12-10 19:26:22 +00001828 n = sqlite3Strlen30(zDrive) + sqlite3Strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00001829 home_dir = malloc( n );
1830 if( home_dir==0 ) return 0;
1831 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1832 return home_dir;
1833 }
1834 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001835 }
1836#endif
1837
chw65d3c132007-11-12 21:09:10 +00001838#endif /* !_WIN32_WCE */
1839
drh67505e72002-04-19 12:34:06 +00001840 if( home_dir ){
drhea678832008-12-10 19:26:22 +00001841 int n = sqlite3Strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00001842 char *z = malloc( n );
1843 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001844 home_dir = z;
1845 }
drhe98d4fa2002-04-21 19:06:22 +00001846
drh67505e72002-04-19 12:34:06 +00001847 return home_dir;
1848}
1849
1850/*
1851** Read input from the file given by sqliterc_override. Or if that
1852** parameter is NULL, take input from ~/.sqliterc
1853*/
drh22fbcb82004-02-01 01:22:50 +00001854static void process_sqliterc(
1855 struct callback_data *p, /* Configuration data */
1856 const char *sqliterc_override /* Name of config file. NULL to use default */
1857){
persicom7e2dfdd2002-04-18 02:46:52 +00001858 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001859 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001860 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001861 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001862 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001863
1864 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001865 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001866 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00001867#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00001868 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00001869#endif
drhe98d4fa2002-04-21 19:06:22 +00001870 return;
1871 }
drhea678832008-12-10 19:26:22 +00001872 nBuf = sqlite3Strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00001873 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001874 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001875 fprintf(stderr,"%s: out of memory!\n", Argv0);
1876 exit(1);
1877 }
drha959ac42007-06-20 13:10:00 +00001878 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001879 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001880 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001881 }
drha1f9b5e2004-02-14 16:31:02 +00001882 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001883 if( in ){
drhc28490c2006-10-26 14:25:58 +00001884 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00001885 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00001886 }
persicom7e2dfdd2002-04-18 02:46:52 +00001887 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001888 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001889 }
drh43617e92006-03-06 20:55:46 +00001890 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001891 return;
1892}
1893
drh67505e72002-04-19 12:34:06 +00001894/*
drhe1e38c42003-05-04 18:30:59 +00001895** Show available command line options
1896*/
1897static const char zOptions[] =
1898 " -init filename read/process named file\n"
1899 " -echo print commands before execution\n"
1900 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001901 " -bail stop after hitting an error\n"
1902 " -interactive force interactive I/O\n"
1903 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001904 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001905 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001906 " -html set output mode to HTML\n"
1907 " -line set output mode to 'line'\n"
1908 " -list set output mode to 'list'\n"
1909 " -separator 'x' set output field separator (|)\n"
1910 " -nullvalue 'text' set text string for NULL values\n"
1911 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001912;
1913static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001914 fprintf(stderr,
1915 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1916 "FILENAME is the name of an SQLite database. A new database is created\n"
1917 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001918 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001919 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001920 }else{
1921 fprintf(stderr, "Use the -help option for additional information\n");
1922 }
1923 exit(1);
1924}
1925
1926/*
drh67505e72002-04-19 12:34:06 +00001927** Initialize the state information in data
1928*/
drh0850b532006-01-31 19:31:43 +00001929static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001930 memset(data, 0, sizeof(*data));
1931 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001932 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001933 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001934 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1935 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001936}
1937
drh75897232000-05-29 14:26:00 +00001938int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001939 char *zErrMsg = 0;
1940 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001941 const char *zInitFile = 0;
1942 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001943 int i;
drhc28490c2006-10-26 14:25:58 +00001944 int rc = 0;
drh75897232000-05-29 14:26:00 +00001945
drhdaffd0e2001-04-11 14:28:42 +00001946 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001947 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001948 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001949
drh44c2eb12003-04-30 11:38:26 +00001950 /* Make sure we have a valid signal handler early, before anything
1951 ** else is done.
1952 */
drh4c504392000-10-16 22:06:40 +00001953#ifdef SIGINT
1954 signal(SIGINT, interrupt_handler);
1955#endif
drh44c2eb12003-04-30 11:38:26 +00001956
drh22fbcb82004-02-01 01:22:50 +00001957 /* Do an initial pass through the command-line argument to locate
1958 ** the name of the database file, the name of the initialization file,
1959 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001960 */
drh22fbcb82004-02-01 01:22:50 +00001961 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001962 char *z;
drh44c2eb12003-04-30 11:38:26 +00001963 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001964 z = argv[i];
1965 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001966 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1967 i++;
drh22fbcb82004-02-01 01:22:50 +00001968 }else if( strcmp(argv[i],"-init")==0 ){
1969 i++;
1970 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001971 }
1972 }
drh22fbcb82004-02-01 01:22:50 +00001973 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00001974#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00001975 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
1976#else
drh22fbcb82004-02-01 01:22:50 +00001977 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00001978#endif
drh22fbcb82004-02-01 01:22:50 +00001979 }else{
danielk197703aded42004-11-22 05:26:27 +00001980#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00001981 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00001982#else
1983 data.zDbFilename = 0;
1984#endif
drh22fbcb82004-02-01 01:22:50 +00001985 }
1986 if( i<argc ){
1987 zFirstCmd = argv[i++];
1988 }
drh44c2eb12003-04-30 11:38:26 +00001989 data.out = stdout;
1990
drh01b41712005-08-29 23:06:23 +00001991#ifdef SQLITE_OMIT_MEMORYDB
1992 if( data.zDbFilename==0 ){
1993 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
1994 exit(1);
1995 }
1996#endif
1997
drh44c2eb12003-04-30 11:38:26 +00001998 /* Go ahead and open the database file if it already exists. If the
1999 ** file does not exist, delay opening it. This prevents empty database
2000 ** files from being created if a user mistypes the database name argument
2001 ** to the sqlite command-line tool.
2002 */
drhc8d74412004-08-31 23:41:26 +00002003 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002004 open_db(&data);
2005 }
2006
drh22fbcb82004-02-01 01:22:50 +00002007 /* Process the initialization file if there is one. If no -init option
2008 ** is given on the command line, look for a file named ~/.sqliterc and
2009 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002010 */
drh22fbcb82004-02-01 01:22:50 +00002011 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00002012
drh22fbcb82004-02-01 01:22:50 +00002013 /* Make a second pass through the command-line argument and set
2014 ** options. This second pass is delayed until after the initialization
2015 ** file is processed so that the command-line arguments will override
2016 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002017 */
drh22fbcb82004-02-01 01:22:50 +00002018 for(i=1; i<argc && argv[i][0]=='-'; i++){
2019 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002020 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002021 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002022 i++;
2023 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002024 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002025 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002026 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002027 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002028 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002029 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002030 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002031 }else if( strcmp(z,"-csv")==0 ){
2032 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002033 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002034 }else if( strcmp(z,"-separator")==0 ){
2035 i++;
drh5bb3eb92007-05-04 13:15:55 +00002036 sqlite3_snprintf(sizeof(data.separator), data.separator,
2037 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002038 }else if( strcmp(z,"-nullvalue")==0 ){
2039 i++;
drh5bb3eb92007-05-04 13:15:55 +00002040 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2041 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002042 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002043 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002044 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002045 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002046 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002047 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002048 }else if( strcmp(z,"-bail")==0 ){
2049 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002050 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002051 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002052 return 0;
drhc28490c2006-10-26 14:25:58 +00002053 }else if( strcmp(z,"-interactive")==0 ){
2054 stdin_is_interactive = 1;
2055 }else if( strcmp(z,"-batch")==0 ){
2056 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002057 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002058 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002059 }else{
drh22fbcb82004-02-01 01:22:50 +00002060 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002061 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002062 return 1;
2063 }
2064 }
drh44c2eb12003-04-30 11:38:26 +00002065
drh22fbcb82004-02-01 01:22:50 +00002066 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002067 /* Run just the command that follows the database name
2068 */
drh22fbcb82004-02-01 01:22:50 +00002069 if( zFirstCmd[0]=='.' ){
2070 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002071 exit(0);
2072 }else{
2073 int rc;
drh44c2eb12003-04-30 11:38:26 +00002074 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00002075 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00002076 if( rc!=0 && zErrMsg!=0 ){
2077 fprintf(stderr,"SQL error: %s\n", zErrMsg);
2078 exit(1);
2079 }
drh75897232000-05-29 14:26:00 +00002080 }
2081 }else{
drh44c2eb12003-04-30 11:38:26 +00002082 /* Run commands received from standard input
2083 */
drhc28490c2006-10-26 14:25:58 +00002084 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002085 char *zHome;
2086 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002087 int nHistory;
drh75897232000-05-29 14:26:00 +00002088 printf(
drhb217a572000-08-22 13:40:18 +00002089 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002090 "Enter \".help\" for instructions\n"
2091 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002092 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002093 );
drh67505e72002-04-19 12:34:06 +00002094 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002095 if( zHome ){
2096 nHistory = sqlite3Strlen30(zHome) + 20;
2097 if( (zHistory = malloc(nHistory))!=0 ){
2098 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2099 }
drh67505e72002-04-19 12:34:06 +00002100 }
danielk19774af00c62005-01-23 23:43:21 +00002101#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002102 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002103#endif
drhc28490c2006-10-26 14:25:58 +00002104 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002105 if( zHistory ){
2106 stifle_history(100);
2107 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002108 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002109 }
adamd0a3daa32006-07-28 20:16:14 +00002110 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002111 }else{
drhc28490c2006-10-26 14:25:58 +00002112 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002113 }
2114 }
drh33048c02001-10-01 14:29:22 +00002115 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002116 if( db ){
2117 if( sqlite3_close(db)!=SQLITE_OK ){
2118 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2119 }
2120 }
drhc28490c2006-10-26 14:25:58 +00002121 return rc;
drh75897232000-05-29 14:26:00 +00002122}