blob: bb0e5a524f23fbd661010eb88054df9fca96b9c1 [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**
shane18e526c2008-12-10 22:30:24 +000015** $Id: shell.c,v 1.194 2008/12/10 22:30:25 shane Exp $
drh75897232000-05-29 14:26:00 +000016*/
shane18e526c2008-12-10 22:30:24 +000017#if defined(_WIN32) || defined(WIN32)
18/* This needs to come before any includes for MSVC compiler */
19#define _CRT_SECURE_NO_WARNINGS
20#endif
21
drh75897232000-05-29 14:26:00 +000022#include <stdlib.h>
23#include <string.h>
24#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000025#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000026#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000027#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000028#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000029
drh454ad582007-11-26 22:54:27 +000030#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000031# include <signal.h>
chw97185482008-11-17 08:05:31 +000032# if !defined(__RTP__) && !defined(_WRS_KERNEL)
33# include <pwd.h>
34# endif
drhdd45df82002-04-18 12:39:03 +000035# include <unistd.h>
36# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000037#endif
drh75897232000-05-29 14:26:00 +000038
drhcdb36b72006-06-12 12:57:45 +000039#ifdef __OS2__
40# include <unistd.h>
41#endif
42
drh16e59552000-07-31 11:57:37 +000043#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000044# include <readline/readline.h>
45# include <readline/history.h>
46#else
drh9347b202003-07-18 01:30:59 +000047# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000048# define add_history(X)
drh67505e72002-04-19 12:34:06 +000049# define read_history(X)
50# define write_history(X)
51# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000052#endif
53
adamd2e8464a2006-09-06 21:39:40 +000054#if defined(_WIN32) || defined(WIN32)
55# include <io.h>
shane18e526c2008-12-10 22:30:24 +000056#define isatty(h) _isatty(h)
57#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000058#else
drh4328c8b2003-04-26 02:50:11 +000059/* Make sure isatty() has a prototype.
60*/
61extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000062#endif
drh4328c8b2003-04-26 02:50:11 +000063
chw65d3c132007-11-12 21:09:10 +000064#if defined(_WIN32_WCE)
65/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
66 * thus we always assume that we have a console. That can be
67 * overridden with the -batch command line option.
68 */
69#define isatty(x) 1
70#endif
71
chw97185482008-11-17 08:05:31 +000072#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000073#include <sys/time.h>
74#include <sys/resource.h>
75
76/* Saved resource information for the beginning of an operation */
77static struct rusage sBegin;
78
79/* True if the timer is enabled */
80static int enableTimer = 0;
81
82/*
83** Begin timing an operation
84*/
85static void beginTimer(void){
86 if( enableTimer ){
87 getrusage(RUSAGE_SELF, &sBegin);
88 }
89}
90
drhf4608092008-07-11 17:23:24 +000091/* Return the difference of two time_structs in seconds */
92static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
93 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
94 (double)(pEnd->tv_sec - pStart->tv_sec);
drh3b1a9882007-11-02 12:53:03 +000095}
96
97/*
98** Print the timing results.
99*/
100static void endTimer(void){
101 if( enableTimer ){
102 struct rusage sEnd;
103 getrusage(RUSAGE_SELF, &sEnd);
104 printf("CPU Time: user %f sys %f\n",
drhf4608092008-07-11 17:23:24 +0000105 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
106 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
drh3b1a9882007-11-02 12:53:03 +0000107 }
108}
109#define BEGIN_TIMER beginTimer()
110#define END_TIMER endTimer()
111#define HAS_TIMER 1
112#else
113#define BEGIN_TIMER
114#define END_TIMER
115#define HAS_TIMER 0
116#endif
117
drhe91d16b2008-12-08 18:27:31 +0000118/*
119** Used to prevent warnings about unused parameters
120*/
121#define UNUSED_PARAMETER(x) (void)(x)
drh3b1a9882007-11-02 12:53:03 +0000122
drh75897232000-05-29 14:26:00 +0000123/*
drhc49f44e2006-10-26 18:15:42 +0000124** If the following flag is set, then command execution stops
125** at an error if we are not interactive.
126*/
127static int bail_on_error = 0;
128
129/*
drhc28490c2006-10-26 14:25:58 +0000130** Threat stdin as an interactive input if the following variable
131** is true. Otherwise, assume stdin is connected to a file or pipe.
132*/
133static int stdin_is_interactive = 1;
134
135/*
drh4c504392000-10-16 22:06:40 +0000136** The following is the open SQLite database. We make a pointer
137** to this database a static variable so that it can be accessed
138** by the SIGINT handler to interrupt database processing.
139*/
danielk197792f9a1b2004-06-19 09:08:16 +0000140static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000141
142/*
drh67505e72002-04-19 12:34:06 +0000143** True if an interrupt (Control-C) has been received.
144*/
drh43617e92006-03-06 20:55:46 +0000145static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000146
147/*
persicom7e2dfdd2002-04-18 02:46:52 +0000148** This is the name of our program. It is set in main(), used
149** in a number of other places, mostly for error messages.
150*/
151static char *Argv0;
152
153/*
154** Prompt strings. Initialized in main. Settable with
155** .prompt main continue
156*/
157static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
158static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
159
drhb0603412007-02-28 04:47:26 +0000160/*
161** Write I/O traces to the following stream.
162*/
rsebe0a9092007-07-30 18:24:38 +0000163#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000164static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000165#endif
drhb0603412007-02-28 04:47:26 +0000166
167/*
168** This routine works like printf in that its first argument is a
169** format string and subsequent arguments are values to be substituted
170** in place of % fields. The result of formatting this string
171** is written to iotrace.
172*/
rsebe0a9092007-07-30 18:24:38 +0000173#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000174static void iotracePrintf(const char *zFormat, ...){
175 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000176 char *z;
drhb0603412007-02-28 04:47:26 +0000177 if( iotrace==0 ) return;
178 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000179 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000180 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000181 fprintf(iotrace, "%s", z);
182 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000183}
rsebe0a9092007-07-30 18:24:38 +0000184#endif
drhb0603412007-02-28 04:47:26 +0000185
drh44c2eb12003-04-30 11:38:26 +0000186
persicom7e2dfdd2002-04-18 02:46:52 +0000187/*
drh83965662003-04-17 02:54:13 +0000188** Determines if a string is a number of not.
189*/
danielk19772e588c72005-12-09 14:25:08 +0000190static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000191 if( *z=='-' || *z=='+' ) z++;
192 if( !isdigit(*z) ){
193 return 0;
194 }
195 z++;
196 if( realnum ) *realnum = 0;
197 while( isdigit(*z) ){ z++; }
198 if( *z=='.' ){
199 z++;
200 if( !isdigit(*z) ) return 0;
201 while( isdigit(*z) ){ z++; }
202 if( realnum ) *realnum = 1;
203 }
204 if( *z=='e' || *z=='E' ){
205 z++;
206 if( *z=='+' || *z=='-' ) z++;
207 if( !isdigit(*z) ) return 0;
208 while( isdigit(*z) ){ z++; }
209 if( realnum ) *realnum = 1;
210 }
211 return *z==0;
212}
drh83965662003-04-17 02:54:13 +0000213
214/*
danielk1977bc6ada42004-06-30 08:20:16 +0000215** A global char* and an SQL function to access its current value
216** from within an SQL statement. This program used to use the
217** sqlite_exec_printf() API to substitue a string into an SQL statement.
218** The correct way to do this with sqlite3 is to use the bind API, but
219** since the shell is built around the callback paradigm it would be a lot
220** of work. Instead just use this hack, which is quite harmless.
221*/
222static const char *zShellStatic = 0;
223static void shellstaticFunc(
224 sqlite3_context *context,
225 int argc,
226 sqlite3_value **argv
227){
228 assert( 0==argc );
229 assert( zShellStatic );
drh902b9ee2008-12-05 17:17:07 +0000230 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000231 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
232}
233
234
235/*
drhfeac5f82004-08-01 00:10:45 +0000236** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000237** the text in memory obtained from malloc() and returns a pointer
238** to the text. NULL is returned at end of file, or if malloc()
239** fails.
240**
241** The interface is like "readline" but no command-line editing
242** is done.
243*/
drh9347b202003-07-18 01:30:59 +0000244static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000245 char *zLine;
246 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000247 int n;
248 int eol;
249
250 if( zPrompt && *zPrompt ){
251 printf("%s",zPrompt);
252 fflush(stdout);
253 }
254 nLine = 100;
255 zLine = malloc( nLine );
256 if( zLine==0 ) return 0;
257 n = 0;
258 eol = 0;
259 while( !eol ){
260 if( n+100>nLine ){
261 nLine = nLine*2 + 100;
262 zLine = realloc(zLine, nLine);
263 if( zLine==0 ) return 0;
264 }
drhdaffd0e2001-04-11 14:28:42 +0000265 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000266 if( n==0 ){
267 free(zLine);
268 return 0;
269 }
270 zLine[n] = 0;
271 eol = 1;
272 break;
273 }
274 while( zLine[n] ){ n++; }
275 if( n>0 && zLine[n-1]=='\n' ){
276 n--;
277 zLine[n] = 0;
278 eol = 1;
279 }
280 }
281 zLine = realloc( zLine, n+1 );
282 return zLine;
283}
284
285/*
drhc28490c2006-10-26 14:25:58 +0000286** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000287**
288** zPrior is a string of prior text retrieved. If not the empty
289** string, then issue a continuation prompt.
290*/
drhdaffd0e2001-04-11 14:28:42 +0000291static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000292 char *zPrompt;
293 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000294 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000295 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000296 }
297 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000298 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000299 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000300 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000301 }
302 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000303#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000304 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000305#endif
drh8e7e7a22000-05-30 18:45:23 +0000306 return zResult;
307}
308
persicom7e2dfdd2002-04-18 02:46:52 +0000309struct previous_mode_data {
310 int valid; /* Is there legit data in here? */
311 int mode;
312 int showHeader;
313 int colWidth[100];
314};
drh45e29d82006-11-20 16:21:10 +0000315
drh8e7e7a22000-05-30 18:45:23 +0000316/*
drh75897232000-05-29 14:26:00 +0000317** An pointer to an instance of this structure is passed from
318** the main program to the callback. This is used to communicate
319** state and mode information.
320*/
321struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000322 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000323 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000324 int cnt; /* Number of records displayed so far */
325 FILE *out; /* Write results here */
326 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000327 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000328 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000329 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000330 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000331 int colWidth[100]; /* Requested width of each column when in column mode*/
332 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000333 char nullvalue[20]; /* The text to print when a NULL comes back from
334 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000335 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000336 /* Holds the mode information just before
337 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000338 char outfile[FILENAME_MAX]; /* Filename for *out */
339 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000340};
341
342/*
343** These are the allowed modes.
344*/
drh967e8b72000-06-21 13:59:10 +0000345#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000346#define MODE_Column 1 /* One record per line in neat columns */
347#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000348#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
349#define MODE_Html 4 /* Generate an XHTML table */
350#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000351#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000352#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000353#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000354
drh66ce4d02008-02-15 17:38:06 +0000355static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000356 "line",
357 "column",
358 "list",
359 "semi",
360 "html",
drhfeac5f82004-08-01 00:10:45 +0000361 "insert",
362 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000363 "csv",
drh66ce4d02008-02-15 17:38:06 +0000364 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000365};
drh75897232000-05-29 14:26:00 +0000366
367/*
368** Number of elements in an array
369*/
drh902b9ee2008-12-05 17:17:07 +0000370#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000371
372/*
drhea678832008-12-10 19:26:22 +0000373** Compute a string length that is limited to what can be stored in
374** lower 30 bits of a 32-bit signed integer.
375*/
drh4f21c4a2008-12-10 22:15:00 +0000376static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000377 const char *z2 = z;
378 while( *z2 ){ z2++; }
379 return 0x3fffffff & (int)(z2 - z);
380}
381
382/*
drh28bd4bc2000-06-15 15:57:22 +0000383** Output the given string as a quoted string using SQL quoting conventions.
384*/
385static void output_quoted_string(FILE *out, const char *z){
386 int i;
387 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000388 for(i=0; z[i]; i++){
389 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000390 }
391 if( nSingle==0 ){
392 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000393 }else{
394 fprintf(out,"'");
395 while( *z ){
396 for(i=0; z[i] && z[i]!='\''; i++){}
397 if( i==0 ){
398 fprintf(out,"''");
399 z++;
400 }else if( z[i]=='\'' ){
401 fprintf(out,"%.*s''",i,z);
402 z += i+1;
403 }else{
drhcd7d2732002-02-26 23:24:26 +0000404 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000405 break;
406 }
407 }
drhcd7d2732002-02-26 23:24:26 +0000408 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000409 }
410}
411
412/*
drhfeac5f82004-08-01 00:10:45 +0000413** Output the given string as a quoted according to C or TCL quoting rules.
414*/
415static void output_c_string(FILE *out, const char *z){
416 unsigned int c;
417 fputc('"', out);
418 while( (c = *(z++))!=0 ){
419 if( c=='\\' ){
420 fputc(c, out);
421 fputc(c, out);
422 }else if( c=='\t' ){
423 fputc('\\', out);
424 fputc('t', out);
425 }else if( c=='\n' ){
426 fputc('\\', out);
427 fputc('n', out);
428 }else if( c=='\r' ){
429 fputc('\\', out);
430 fputc('r', out);
431 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000432 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000433 }else{
434 fputc(c, out);
435 }
436 }
437 fputc('"', out);
438}
439
440/*
drhc08a4f12000-06-15 16:49:48 +0000441** Output the given string with characters that are special to
442** HTML escaped.
443*/
444static void output_html_string(FILE *out, const char *z){
445 int i;
446 while( *z ){
447 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
448 if( i>0 ){
449 fprintf(out,"%.*s",i,z);
450 }
451 if( z[i]=='<' ){
452 fprintf(out,"&lt;");
453 }else if( z[i]=='&' ){
454 fprintf(out,"&amp;");
455 }else{
456 break;
457 }
458 z += i + 1;
459 }
460}
461
462/*
drhc49f44e2006-10-26 18:15:42 +0000463** If a field contains any character identified by a 1 in the following
464** array, then the string must be quoted for CSV.
465*/
466static const char needCsvQuote[] = {
467 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
468 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
469 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
470 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
471 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
472 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
473 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
474 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
475 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
476 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
477 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
478 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
479 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
480 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
481 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
482 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
483};
484
485/*
drh8e64d1c2004-10-07 00:32:39 +0000486** Output a single term of CSV. Actually, p->separator is used for
487** the separator, which may or may not be a comma. p->nullvalue is
488** the null value. Strings are quoted using ANSI-C rules. Numbers
489** appear outside of quotes.
490*/
491static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000492 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000493 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000494 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000495 }else{
drhc49f44e2006-10-26 18:15:42 +0000496 int i;
drh4f21c4a2008-12-10 22:15:00 +0000497 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000498 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000499 if( needCsvQuote[((unsigned char*)z)[i]]
500 || (z[i]==p->separator[0] &&
501 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000502 i = 0;
503 break;
504 }
505 }
506 if( i==0 ){
507 putc('"', out);
508 for(i=0; z[i]; i++){
509 if( z[i]=='"' ) putc('"', out);
510 putc(z[i], out);
511 }
512 putc('"', out);
513 }else{
514 fprintf(out, "%s", z);
515 }
drh8e64d1c2004-10-07 00:32:39 +0000516 }
517 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000518 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000519 }
520}
521
danielk19774af00c62005-01-23 23:43:21 +0000522#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000523/*
drh4c504392000-10-16 22:06:40 +0000524** This routine runs when the user presses Ctrl-C
525*/
526static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000527 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000528 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000529 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000530}
danielk19774af00c62005-01-23 23:43:21 +0000531#endif
drh4c504392000-10-16 22:06:40 +0000532
533/*
drh75897232000-05-29 14:26:00 +0000534** This is the callback routine that the SQLite library
535** invokes for each row of a query result.
536*/
537static int callback(void *pArg, int nArg, char **azArg, char **azCol){
538 int i;
539 struct callback_data *p = (struct callback_data*)pArg;
540 switch( p->mode ){
541 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000542 int w = 5;
drh6a535342001-10-19 16:44:56 +0000543 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000544 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000545 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000546 if( len>w ) w = len;
547 }
drh75897232000-05-29 14:26:00 +0000548 if( p->cnt++>0 ) fprintf(p->out,"\n");
549 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000550 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000551 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000552 }
553 break;
554 }
danielk19770d78bae2008-01-03 07:09:48 +0000555 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000556 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000557 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000558 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000559 int w, n;
560 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000561 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000562 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000563 w = 0;
drh75897232000-05-29 14:26:00 +0000564 }
drha0c66f52000-07-29 13:20:21 +0000565 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000566 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000567 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000568 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000569 if( w<n ) w = n;
570 }
571 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000572 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000573 }
574 if( p->showHeader ){
575 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
576 }
577 }
578 if( p->showHeader ){
579 for(i=0; i<nArg; i++){
580 int w;
581 if( i<ArraySize(p->actualWidth) ){
582 w = p->actualWidth[i];
583 }else{
584 w = 10;
585 }
586 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
587 "----------------------------------------------------------",
588 i==nArg-1 ? "\n": " ");
589 }
drh75897232000-05-29 14:26:00 +0000590 }
591 }
drh6a535342001-10-19 16:44:56 +0000592 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000593 for(i=0; i<nArg; i++){
594 int w;
drha0c66f52000-07-29 13:20:21 +0000595 if( i<ArraySize(p->actualWidth) ){
596 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000597 }else{
598 w = 10;
599 }
drhea678832008-12-10 19:26:22 +0000600 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000601 strlen30(azArg[i])>w ){
602 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000603 }
drhc61053b2000-06-04 12:58:36 +0000604 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000605 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000606 }
607 break;
608 }
drhe3710332000-09-29 13:30:53 +0000609 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000610 case MODE_List: {
611 if( p->cnt++==0 && p->showHeader ){
612 for(i=0; i<nArg; i++){
613 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
614 }
615 }
drh6a535342001-10-19 16:44:56 +0000616 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000617 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000618 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000619 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000620 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000621 if( i<nArg-1 ){
622 fprintf(p->out, "%s", p->separator);
623 }else if( p->mode==MODE_Semi ){
624 fprintf(p->out, ";\n");
625 }else{
626 fprintf(p->out, "\n");
627 }
drh75897232000-05-29 14:26:00 +0000628 }
629 break;
630 }
drh1e5d0e92000-05-31 23:33:17 +0000631 case MODE_Html: {
632 if( p->cnt++==0 && p->showHeader ){
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,"<TH>%s</TH>",azCol[i]);
drh1e5d0e92000-05-31 23:33:17 +0000636 }
mihailim57c591a2008-06-23 21:26:05 +0000637 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000638 }
drh6a535342001-10-19 16:44:56 +0000639 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000640 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000641 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000642 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000643 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000644 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000645 }
mihailim57c591a2008-06-23 21:26:05 +0000646 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000647 break;
648 }
drhfeac5f82004-08-01 00:10:45 +0000649 case MODE_Tcl: {
650 if( p->cnt++==0 && p->showHeader ){
651 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000652 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000653 fprintf(p->out, "%s", p->separator);
654 }
655 fprintf(p->out,"\n");
656 }
657 if( azArg==0 ) break;
658 for(i=0; i<nArg; i++){
659 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
660 fprintf(p->out, "%s", p->separator);
661 }
662 fprintf(p->out,"\n");
663 break;
664 }
drh8e64d1c2004-10-07 00:32:39 +0000665 case MODE_Csv: {
666 if( p->cnt++==0 && p->showHeader ){
667 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000668 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000669 }
670 fprintf(p->out,"\n");
671 }
672 if( azArg==0 ) break;
673 for(i=0; i<nArg; i++){
674 output_csv(p, azArg[i], i<nArg-1);
675 }
676 fprintf(p->out,"\n");
677 break;
678 }
drh28bd4bc2000-06-15 15:57:22 +0000679 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000680 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000681 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000682 for(i=0; i<nArg; i++){
683 char *zSep = i>0 ? ",": "";
684 if( azArg[i]==0 ){
685 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000686 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000687 fprintf(p->out,"%s%s",zSep, azArg[i]);
688 }else{
689 if( zSep[0] ) fprintf(p->out,"%s",zSep);
690 output_quoted_string(p->out, azArg[i]);
691 }
692 }
693 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000694 break;
drh28bd4bc2000-06-15 15:57:22 +0000695 }
persicom1d0b8722002-04-18 02:53:04 +0000696 }
drh75897232000-05-29 14:26:00 +0000697 return 0;
698}
699
700/*
drh33048c02001-10-01 14:29:22 +0000701** Set the destination table field of the callback_data structure to
702** the name of the table given. Escape any quote characters in the
703** table name.
704*/
705static void set_table_name(struct callback_data *p, const char *zName){
706 int i, n;
707 int needQuote;
708 char *z;
709
710 if( p->zDestTable ){
711 free(p->zDestTable);
712 p->zDestTable = 0;
713 }
714 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000715 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000716 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000717 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000718 needQuote = 1;
719 if( zName[i]=='\'' ) n++;
720 }
721 }
722 if( needQuote ) n += 2;
723 z = p->zDestTable = malloc( n+1 );
724 if( z==0 ){
725 fprintf(stderr,"Out of memory!\n");
726 exit(1);
727 }
728 n = 0;
729 if( needQuote ) z[n++] = '\'';
730 for(i=0; zName[i]; i++){
731 z[n++] = zName[i];
732 if( zName[i]=='\'' ) z[n++] = '\'';
733 }
734 if( needQuote ) z[n++] = '\'';
735 z[n] = 0;
736}
737
danielk19772a02e332004-06-05 08:04:36 +0000738/* zIn is either a pointer to a NULL-terminated string in memory obtained
739** from malloc(), or a NULL pointer. The string pointed to by zAppend is
740** added to zIn, and the result returned in memory obtained from malloc().
741** zIn, if it was not NULL, is freed.
742**
743** If the third argument, quote, is not '\0', then it is used as a
744** quote character for zAppend.
745*/
drhc28490c2006-10-26 14:25:58 +0000746static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000747 int len;
748 int i;
drh4f21c4a2008-12-10 22:15:00 +0000749 int nAppend = strlen30(zAppend);
750 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000751
752 len = nAppend+nIn+1;
753 if( quote ){
754 len += 2;
755 for(i=0; i<nAppend; i++){
756 if( zAppend[i]==quote ) len++;
757 }
758 }
759
760 zIn = (char *)realloc(zIn, len);
761 if( !zIn ){
762 return 0;
763 }
764
765 if( quote ){
766 char *zCsr = &zIn[nIn];
767 *zCsr++ = quote;
768 for(i=0; i<nAppend; i++){
769 *zCsr++ = zAppend[i];
770 if( zAppend[i]==quote ) *zCsr++ = quote;
771 }
772 *zCsr++ = quote;
773 *zCsr++ = '\0';
774 assert( (zCsr-zIn)==len );
775 }else{
776 memcpy(&zIn[nIn], zAppend, nAppend);
777 zIn[len-1] = '\0';
778 }
779
780 return zIn;
781}
782
drhdd3d4592004-08-30 01:54:05 +0000783
784/*
785** Execute a query statement that has a single result column. Print
786** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000787**
788** This is used, for example, to show the schema of the database by
789** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000790*/
791static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
792 sqlite3_stmt *pSelect;
793 int rc;
794 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
795 if( rc!=SQLITE_OK || !pSelect ){
796 return rc;
797 }
798 rc = sqlite3_step(pSelect);
799 while( rc==SQLITE_ROW ){
800 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
801 rc = sqlite3_step(pSelect);
802 }
803 return sqlite3_finalize(pSelect);
804}
805
806
drh33048c02001-10-01 14:29:22 +0000807/*
drh4c653a02000-06-07 01:27:47 +0000808** This is a different callback routine used for dumping the database.
809** Each row received by this callback consists of a table name,
810** the table type ("index" or "table") and SQL to create the table.
811** This routine should print text sufficient to recreate the table.
812*/
813static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000814 int rc;
815 const char *zTable;
816 const char *zType;
817 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000818 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000819
drh902b9ee2008-12-05 17:17:07 +0000820 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +0000821 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000822 zTable = azArg[0];
823 zType = azArg[1];
824 zSql = azArg[2];
825
drh00b950d2005-09-11 02:03:03 +0000826 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000827 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000828 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
829 fprintf(p->out, "ANALYZE sqlite_master;\n");
830 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
831 return 0;
drh45e29d82006-11-20 16:21:10 +0000832 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
833 char *zIns;
834 if( !p->writableSchema ){
835 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
836 p->writableSchema = 1;
837 }
838 zIns = sqlite3_mprintf(
839 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
840 "VALUES('table','%q','%q',0,'%q');",
841 zTable, zTable, zSql);
842 fprintf(p->out, "%s\n", zIns);
843 sqlite3_free(zIns);
844 return 0;
drh00b950d2005-09-11 02:03:03 +0000845 }else{
846 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000847 }
danielk19772a02e332004-06-05 08:04:36 +0000848
849 if( strcmp(zType, "table")==0 ){
850 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000851 char *zSelect = 0;
852 char *zTableInfo = 0;
853 char *zTmp = 0;
854
855 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
856 zTableInfo = appendText(zTableInfo, zTable, '"');
857 zTableInfo = appendText(zTableInfo, ");", 0);
858
859 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
860 if( zTableInfo ) free(zTableInfo);
861 if( rc!=SQLITE_OK || !pTableInfo ){
862 return 1;
863 }
864
865 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
866 zTmp = appendText(zTmp, zTable, '"');
867 if( zTmp ){
868 zSelect = appendText(zSelect, zTmp, '\'');
869 }
870 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
871 rc = sqlite3_step(pTableInfo);
872 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000873 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000874 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000875 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000876 rc = sqlite3_step(pTableInfo);
877 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000878 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000879 }else{
880 zSelect = appendText(zSelect, ") ", 0);
881 }
882 }
883 rc = sqlite3_finalize(pTableInfo);
884 if( rc!=SQLITE_OK ){
885 if( zSelect ) free(zSelect);
886 return 1;
887 }
888 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
889 zSelect = appendText(zSelect, zTable, '"');
890
drhdd3d4592004-08-30 01:54:05 +0000891 rc = run_table_dump_query(p->out, p->db, zSelect);
892 if( rc==SQLITE_CORRUPT ){
893 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
894 rc = run_table_dump_query(p->out, p->db, zSelect);
895 }
danielk19772a02e332004-06-05 08:04:36 +0000896 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000897 }
drh4c653a02000-06-07 01:27:47 +0000898 return 0;
899}
900
901/*
drh45e29d82006-11-20 16:21:10 +0000902** Run zQuery. Use dump_callback() as the callback routine so that
903** the contents of the query are output as SQL statements.
904**
drhdd3d4592004-08-30 01:54:05 +0000905** If we get a SQLITE_CORRUPT error, rerun the query after appending
906** "ORDER BY rowid DESC" to the end.
907*/
908static int run_schema_dump_query(
909 struct callback_data *p,
910 const char *zQuery,
911 char **pzErrMsg
912){
913 int rc;
914 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
915 if( rc==SQLITE_CORRUPT ){
916 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +0000917 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +0000918 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
919 zQ2 = malloc( len+100 );
920 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000921 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000922 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
923 free(zQ2);
924 }
925 return rc;
926}
927
928/*
drh75897232000-05-29 14:26:00 +0000929** Text of a help message
930*/
persicom1d0b8722002-04-18 02:53:04 +0000931static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000932 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000933 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000934 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000935 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000936 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000937 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000938 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000939 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000940 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000941 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000942#ifdef SQLITE_ENABLE_IOTRACE
943 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
944#endif
drh70df4fe2006-06-13 15:12:21 +0000945#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000946 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000947#endif
danielk19776b77a362005-01-13 11:10:25 +0000948 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000949 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000950 " column Left-aligned columns. (See .width)\n"
951 " html HTML <table> code\n"
952 " insert SQL insert statements for TABLE\n"
953 " line One value per line\n"
954 " list Values delimited by .separator string\n"
955 " tabs Tab-separated values\n"
956 " tcl TCL list elements\n"
957 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000958 ".output FILENAME Send output to FILENAME\n"
959 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000960 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000961 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000962 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000963 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000964 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000965 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000966 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000967 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +0000968#if HAS_TIMER
969 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
970#endif
drh75897232000-05-29 14:26:00 +0000971 ".width NUM NUM ... Set column widths for \"column\" mode\n"
972;
973
drhdaffd0e2001-04-11 14:28:42 +0000974/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000975static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000976
drh75897232000-05-29 14:26:00 +0000977/*
drh44c2eb12003-04-30 11:38:26 +0000978** Make sure the database is open. If it is not, then open it. If
979** the database fails to open, print an error message and exit.
980*/
981static void open_db(struct callback_data *p){
982 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000983 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000984 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +0000985 if( db && sqlite3_errcode(db)==SQLITE_OK ){
986 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
987 shellstaticFunc, 0, 0);
988 }
989 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +0000990 fprintf(stderr,"Unable to open database \"%s\": %s\n",
991 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000992 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000993 }
drhc2e87a32006-06-27 15:16:14 +0000994#ifndef SQLITE_OMIT_LOAD_EXTENSION
995 sqlite3_enable_load_extension(p->db, 1);
996#endif
drh44c2eb12003-04-30 11:38:26 +0000997 }
998}
999
1000/*
drhfeac5f82004-08-01 00:10:45 +00001001** Do C-language style dequoting.
1002**
1003** \t -> tab
1004** \n -> newline
1005** \r -> carriage return
1006** \NNN -> ascii character NNN in octal
1007** \\ -> backslash
1008*/
1009static void resolve_backslashes(char *z){
1010 int i, j, c;
1011 for(i=j=0; (c = z[i])!=0; i++, j++){
1012 if( c=='\\' ){
1013 c = z[++i];
1014 if( c=='n' ){
1015 c = '\n';
1016 }else if( c=='t' ){
1017 c = '\t';
1018 }else if( c=='r' ){
1019 c = '\r';
1020 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001021 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001022 if( z[i+1]>='0' && z[i+1]<='7' ){
1023 i++;
1024 c = (c<<3) + z[i] - '0';
1025 if( z[i+1]>='0' && z[i+1]<='7' ){
1026 i++;
1027 c = (c<<3) + z[i] - '0';
1028 }
1029 }
1030 }
1031 }
1032 z[j] = c;
1033 }
1034 z[j] = 0;
1035}
1036
1037/*
drhc28490c2006-10-26 14:25:58 +00001038** Interpret zArg as a boolean value. Return either 0 or 1.
1039*/
1040static int booleanValue(char *zArg){
1041 int val = atoi(zArg);
1042 int j;
1043 for(j=0; zArg[j]; j++){
1044 zArg[j] = tolower(zArg[j]);
1045 }
1046 if( strcmp(zArg,"on")==0 ){
1047 val = 1;
1048 }else if( strcmp(zArg,"yes")==0 ){
1049 val = 1;
1050 }
1051 return val;
1052}
1053
1054/*
drh75897232000-05-29 14:26:00 +00001055** If an input line begins with "." then invoke this routine to
1056** process that line.
drh67505e72002-04-19 12:34:06 +00001057**
drh47ad6842006-11-08 12:25:42 +00001058** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001059*/
drh44c2eb12003-04-30 11:38:26 +00001060static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001061 int i = 1;
1062 int nArg = 0;
1063 int n, c;
drh67505e72002-04-19 12:34:06 +00001064 int rc = 0;
drh75897232000-05-29 14:26:00 +00001065 char *azArg[50];
1066
1067 /* Parse the input line into tokens.
1068 */
1069 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001070 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001071 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001072 if( zLine[i]=='\'' || zLine[i]=='"' ){
1073 int delim = zLine[i++];
1074 azArg[nArg++] = &zLine[i];
1075 while( zLine[i] && zLine[i]!=delim ){ i++; }
1076 if( zLine[i]==delim ){
1077 zLine[i++] = 0;
1078 }
drhfeac5f82004-08-01 00:10:45 +00001079 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001080 }else{
1081 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001082 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001083 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001084 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001085 }
1086 }
1087
1088 /* Process the input line.
1089 */
drh67505e72002-04-19 12:34:06 +00001090 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00001091 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001092 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001093 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1094 bail_on_error = booleanValue(azArg[1]);
1095 }else
1096
jplyon6a65bb32003-05-04 07:25:57 +00001097 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001098 struct callback_data data;
1099 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001100 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001101 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001102 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001103 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001104 data.colWidth[0] = 3;
1105 data.colWidth[1] = 15;
1106 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001107 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001108 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001109 if( zErrMsg ){
1110 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001111 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001112 }
1113 }else
1114
drh4c653a02000-06-07 01:27:47 +00001115 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1116 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001117 open_db(p);
drh33048c02001-10-01 14:29:22 +00001118 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001119 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001120 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001121 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001122 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001123 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001124 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001125 );
1126 run_table_dump_query(p->out, p->db,
1127 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001128 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001129 );
drh4c653a02000-06-07 01:27:47 +00001130 }else{
1131 int i;
drhdd3d4592004-08-30 01:54:05 +00001132 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001133 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001134 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001135 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001136 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001137 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001138 run_table_dump_query(p->out, p->db,
1139 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001140 "WHERE sql NOT NULL"
1141 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001142 " AND tbl_name LIKE shellstatic()"
1143 );
danielk1977bc6ada42004-06-30 08:20:16 +00001144 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001145 }
1146 }
drh45e29d82006-11-20 16:21:10 +00001147 if( p->writableSchema ){
1148 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1149 p->writableSchema = 0;
1150 }
drh93f41e52008-08-11 19:12:34 +00001151 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001152 if( zErrMsg ){
1153 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001154 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001155 }else{
1156 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001157 }
1158 }else
drh75897232000-05-29 14:26:00 +00001159
drhdaffd0e2001-04-11 14:28:42 +00001160 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001161 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001162 }else
1163
drh75897232000-05-29 14:26:00 +00001164 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001165 rc = 2;
drh75897232000-05-29 14:26:00 +00001166 }else
1167
drhdd45df82002-04-18 12:39:03 +00001168 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001169 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001170 if(val == 1) {
1171 if(!p->explainPrev.valid) {
1172 p->explainPrev.valid = 1;
1173 p->explainPrev.mode = p->mode;
1174 p->explainPrev.showHeader = p->showHeader;
1175 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1176 }
1177 /* We could put this code under the !p->explainValid
1178 ** condition so that it does not execute if we are already in
1179 ** explain mode. However, always executing it allows us an easy
1180 ** was to reset to explain mode in case the user previously
1181 ** did an .explain followed by a .width, .mode or .header
1182 ** command.
1183 */
danielk19770d78bae2008-01-03 07:09:48 +00001184 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001185 p->showHeader = 1;
1186 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001187 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001188 p->colWidth[1] = 13; /* opcode */
1189 p->colWidth[2] = 4; /* P1 */
1190 p->colWidth[3] = 4; /* P2 */
1191 p->colWidth[4] = 4; /* P3 */
1192 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001193 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001194 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001195 }else if (p->explainPrev.valid) {
1196 p->explainPrev.valid = 0;
1197 p->mode = p->explainPrev.mode;
1198 p->showHeader = p->explainPrev.showHeader;
1199 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1200 }
drh75897232000-05-29 14:26:00 +00001201 }else
1202
drhc28490c2006-10-26 14:25:58 +00001203 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001204 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001205 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001206 }else
1207
1208 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1209 fprintf(stderr,zHelp);
1210 }else
1211
drhfeac5f82004-08-01 00:10:45 +00001212 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1213 char *zTable = azArg[2]; /* Insert data into this table */
1214 char *zFile = azArg[1]; /* The file from which to extract data */
1215 sqlite3_stmt *pStmt; /* A statement */
1216 int rc; /* Result code */
1217 int nCol; /* Number of columns in the table */
1218 int nByte; /* Number of bytes in an SQL string */
1219 int i, j; /* Loop counters */
1220 int nSep; /* Number of bytes in p->separator[] */
1221 char *zSql; /* An SQL statement */
1222 char *zLine; /* A single line of input from the file */
1223 char **azCol; /* zLine[] broken up into columns */
1224 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001225 FILE *in; /* The input file */
1226 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001227
drha543c822006-06-08 16:10:14 +00001228 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001229 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001230 if( nSep==0 ){
1231 fprintf(stderr, "non-null separator required for import\n");
1232 return 0;
1233 }
1234 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1235 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00001236 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001237 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001238 sqlite3_free(zSql);
1239 if( rc ){
1240 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1241 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001242 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001243 }else{
1244 nCol = sqlite3_column_count(pStmt);
1245 }
1246 sqlite3_finalize(pStmt);
1247 if( nCol==0 ) return 0;
1248 zSql = malloc( nByte + 20 + nCol*2 );
1249 if( zSql==0 ) return 0;
1250 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001251 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001252 for(i=1; i<nCol; i++){
1253 zSql[j++] = ',';
1254 zSql[j++] = '?';
1255 }
1256 zSql[j++] = ')';
1257 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001258 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001259 free(zSql);
1260 if( rc ){
1261 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1262 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001263 return 1;
drhfeac5f82004-08-01 00:10:45 +00001264 }
1265 in = fopen(zFile, "rb");
1266 if( in==0 ){
1267 fprintf(stderr, "cannot open file: %s\n", zFile);
1268 sqlite3_finalize(pStmt);
1269 return 0;
1270 }
1271 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001272 if( azCol==0 ){
1273 fclose(in);
1274 return 0;
1275 }
drhfeac5f82004-08-01 00:10:45 +00001276 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1277 zCommit = "COMMIT";
1278 while( (zLine = local_getline(0, in))!=0 ){
1279 char *z;
1280 i = 0;
drhb860bc92004-08-04 15:16:55 +00001281 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001282 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001283 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001284 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1285 *z = 0;
1286 i++;
drhb860bc92004-08-04 15:16:55 +00001287 if( i<nCol ){
1288 azCol[i] = &z[nSep];
1289 z += nSep-1;
1290 }
drhfeac5f82004-08-01 00:10:45 +00001291 }
1292 }
drh1cd7f832005-08-05 18:50:51 +00001293 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001294 if( i+1!=nCol ){
1295 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1296 zFile, lineno, nCol, i+1);
1297 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001298 free(zLine);
drhb860bc92004-08-04 15:16:55 +00001299 break;
1300 }
drhfeac5f82004-08-01 00:10:45 +00001301 for(i=0; i<nCol; i++){
1302 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1303 }
1304 sqlite3_step(pStmt);
1305 rc = sqlite3_reset(pStmt);
1306 free(zLine);
1307 if( rc!=SQLITE_OK ){
1308 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1309 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001310 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001311 break;
1312 }
1313 }
1314 free(azCol);
1315 fclose(in);
1316 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001317 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001318 }else
1319
drh75897232000-05-29 14:26:00 +00001320 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1321 struct callback_data data;
1322 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001323 open_db(p);
drh75897232000-05-29 14:26:00 +00001324 memcpy(&data, p, sizeof(data));
1325 data.showHeader = 0;
1326 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001327 zShellStatic = azArg[1];
1328 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001329 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001330 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001331 "UNION ALL "
1332 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001333 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001334 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001335 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001336 );
danielk1977bc6ada42004-06-30 08:20:16 +00001337 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001338 if( zErrMsg ){
1339 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001340 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001341 }
1342 }else
1343
drhae5e4452007-05-03 17:18:36 +00001344#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001345 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001346 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001347 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1348 iotrace = 0;
1349 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001350 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001351 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001352 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001353 iotrace = stdout;
1354 }else{
1355 iotrace = fopen(azArg[1], "w");
1356 if( iotrace==0 ){
1357 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001358 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001359 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001360 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001361 }
1362 }
1363 }else
drhae5e4452007-05-03 17:18:36 +00001364#endif
drhb0603412007-02-28 04:47:26 +00001365
drh70df4fe2006-06-13 15:12:21 +00001366#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001367 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1368 const char *zFile, *zProc;
1369 char *zErrMsg = 0;
1370 int rc;
1371 zFile = azArg[1];
1372 zProc = nArg>=3 ? azArg[2] : 0;
1373 open_db(p);
1374 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1375 if( rc!=SQLITE_OK ){
1376 fprintf(stderr, "%s\n", zErrMsg);
1377 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001378 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001379 }
1380 }else
drh70df4fe2006-06-13 15:12:21 +00001381#endif
drh1e397f82006-06-08 15:28:43 +00001382
drh28bd4bc2000-06-15 15:57:22 +00001383 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00001384 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001385 if( strncmp(azArg[1],"line",n2)==0
1386 ||
1387 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001388 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001389 }else if( strncmp(azArg[1],"column",n2)==0
1390 ||
1391 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001392 p->mode = MODE_Column;
1393 }else if( strncmp(azArg[1],"list",n2)==0 ){
1394 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001395 }else if( strncmp(azArg[1],"html",n2)==0 ){
1396 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001397 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1398 p->mode = MODE_Tcl;
1399 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001400 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001401 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001402 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1403 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001404 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001405 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1406 p->mode = MODE_Insert;
1407 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001408 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001409 }else{
drh33048c02001-10-01 14:29:22 +00001410 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001411 }
drhdaffd0e2001-04-11 14:28:42 +00001412 }else {
drhcf68ae92006-12-19 18:47:41 +00001413 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001414 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001415 }
1416 }else
1417
persicom7e2dfdd2002-04-18 02:46:52 +00001418 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001419 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1420 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001421 }else
1422
drh75897232000-05-29 14:26:00 +00001423 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1424 if( p->out!=stdout ){
1425 fclose(p->out);
1426 }
1427 if( strcmp(azArg[1],"stdout")==0 ){
1428 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001429 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001430 }else{
drha1f9b5e2004-02-14 16:31:02 +00001431 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001432 if( p->out==0 ){
1433 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1434 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001435 } else {
drh5bb3eb92007-05-04 13:15:55 +00001436 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001437 }
1438 }
1439 }else
1440
drhdd45df82002-04-18 12:39:03 +00001441 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001442 if( nArg >= 2) {
1443 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1444 }
1445 if( nArg >= 3) {
1446 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1447 }
1448 }else
1449
1450 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001451 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001452 }else
1453
drhdaffd0e2001-04-11 14:28:42 +00001454 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001455 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001456 if( alt==0 ){
1457 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1458 }else{
1459 process_input(p, alt);
1460 fclose(alt);
1461 }
1462 }else
1463
drh75897232000-05-29 14:26:00 +00001464 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1465 struct callback_data data;
1466 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001467 open_db(p);
drh75897232000-05-29 14:26:00 +00001468 memcpy(&data, p, sizeof(data));
1469 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001470 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001471 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001472 int i;
1473 for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
1474 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001475 char *new_argv[2], *new_colv[2];
1476 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1477 " type text,\n"
1478 " name text,\n"
1479 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001480 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001481 " sql text\n"
1482 ")";
1483 new_argv[1] = 0;
1484 new_colv[0] = "sql";
1485 new_colv[1] = 0;
1486 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001487 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001488 char *new_argv[2], *new_colv[2];
1489 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1490 " type text,\n"
1491 " name text,\n"
1492 " tbl_name text,\n"
1493 " rootpage integer,\n"
1494 " sql text\n"
1495 ")";
1496 new_argv[1] = 0;
1497 new_colv[0] = "sql";
1498 new_colv[1] = 0;
1499 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001500 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001501 zShellStatic = azArg[1];
1502 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001503 "SELECT sql FROM "
1504 " (SELECT * FROM sqlite_master UNION ALL"
1505 " SELECT * FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001506 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001507 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001508 callback, &data, &zErrMsg);
1509 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001510 }
drh75897232000-05-29 14:26:00 +00001511 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001512 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001513 "SELECT sql FROM "
1514 " (SELECT * FROM sqlite_master UNION ALL"
1515 " SELECT * FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001516 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001517 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001518 callback, &data, &zErrMsg
1519 );
drh75897232000-05-29 14:26:00 +00001520 }
drh75897232000-05-29 14:26:00 +00001521 if( zErrMsg ){
1522 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001523 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001524 }
1525 }else
1526
1527 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001528 sqlite3_snprintf(sizeof(p->separator), p->separator,
1529 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001530 }else
1531
persicom7e2dfdd2002-04-18 02:46:52 +00001532 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1533 int i;
1534 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001535 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001536 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001537 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001538 fprintf(p->out,"%9.9s: ", "nullvalue");
1539 output_c_string(p->out, p->nullvalue);
1540 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001541 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00001542 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001543 fprintf(p->out,"%9.9s: ", "separator");
1544 output_c_string(p->out, p->separator);
1545 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001546 fprintf(p->out,"%9.9s: ","width");
1547 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001548 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001549 }
drhfeac5f82004-08-01 00:10:45 +00001550 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001551 }else
1552
drh2dfbbca2000-07-28 14:32:48 +00001553 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001554 char **azResult;
1555 int nRow, rc;
1556 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001557 open_db(p);
drha50da102000-08-08 20:19:09 +00001558 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001559 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001560 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001561 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001562 "UNION ALL "
1563 "SELECT name FROM sqlite_temp_master "
1564 "WHERE type IN ('table','view') "
1565 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001566 &azResult, &nRow, 0, &zErrMsg
1567 );
drha50da102000-08-08 20:19:09 +00001568 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001569 zShellStatic = azArg[1];
1570 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001571 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001572 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001573 "UNION ALL "
1574 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001575 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001576 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001577 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001578 );
danielk1977bc6ada42004-06-30 08:20:16 +00001579 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001580 }
drh75897232000-05-29 14:26:00 +00001581 if( zErrMsg ){
1582 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001583 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001584 }
drhe3710332000-09-29 13:30:53 +00001585 if( rc==SQLITE_OK ){
1586 int len, maxlen = 0;
1587 int i, j;
1588 int nPrintCol, nPrintRow;
1589 for(i=1; i<=nRow; i++){
1590 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00001591 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00001592 if( len>maxlen ) maxlen = len;
1593 }
1594 nPrintCol = 80/(maxlen+2);
1595 if( nPrintCol<1 ) nPrintCol = 1;
1596 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1597 for(i=0; i<nPrintRow; i++){
1598 for(j=i+1; j<=nRow; j+=nPrintRow){
1599 char *zSp = j<=nPrintRow ? "" : " ";
1600 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1601 }
1602 printf("\n");
1603 }
drh47ad6842006-11-08 12:25:42 +00001604 }else{
1605 rc = 1;
drhe3710332000-09-29 13:30:53 +00001606 }
danielk19776f8a5032004-05-10 10:34:51 +00001607 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001608 }else
1609
drh3b1a9882007-11-02 12:53:03 +00001610 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001611 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001612 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001613 }else
drh3b1a9882007-11-02 12:53:03 +00001614
1615#if HAS_TIMER
1616 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
1617 enableTimer = booleanValue(azArg[1]);
1618 }else
1619#endif
drh2dfbbca2000-07-28 14:32:48 +00001620
drh75897232000-05-29 14:26:00 +00001621 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1622 int j;
drh43617e92006-03-06 20:55:46 +00001623 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001624 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1625 p->colWidth[j-1] = atoi(azArg[j]);
1626 }
1627 }else
1628
drh3b1a9882007-11-02 12:53:03 +00001629
drh75897232000-05-29 14:26:00 +00001630 {
drh67505e72002-04-19 12:34:06 +00001631 fprintf(stderr, "unknown command or invalid arguments: "
1632 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001633 }
drh67505e72002-04-19 12:34:06 +00001634
1635 return rc;
drh75897232000-05-29 14:26:00 +00001636}
1637
drh67505e72002-04-19 12:34:06 +00001638/*
drh91a66392007-09-07 01:12:32 +00001639** Return TRUE if a semicolon occurs anywhere in the first N characters
1640** of string z[].
drh324ccef2003-02-05 14:06:20 +00001641*/
drh91a66392007-09-07 01:12:32 +00001642static int _contains_semicolon(const char *z, int N){
1643 int i;
1644 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
1645 return 0;
drh324ccef2003-02-05 14:06:20 +00001646}
1647
1648/*
drh70c7a4b2003-04-26 03:03:06 +00001649** Test to see if a line consists entirely of whitespace.
1650*/
1651static int _all_whitespace(const char *z){
1652 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001653 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001654 if( *z=='/' && z[1]=='*' ){
1655 z += 2;
1656 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1657 if( *z==0 ) return 0;
1658 z++;
1659 continue;
1660 }
1661 if( *z=='-' && z[1]=='-' ){
1662 z += 2;
1663 while( *z && *z!='\n' ){ z++; }
1664 if( *z==0 ) return 1;
1665 continue;
1666 }
1667 return 0;
1668 }
1669 return 1;
1670}
1671
1672/*
drha9b17162003-04-29 18:01:28 +00001673** Return TRUE if the line typed in is an SQL command terminator other
1674** than a semi-colon. The SQL Server style "go" command is understood
1675** as is the Oracle "/".
1676*/
1677static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001678 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drha9b17162003-04-29 18:01:28 +00001679 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
drhc8d74412004-08-31 23:41:26 +00001680 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1681 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001682 return 1; /* SQL Server */
1683 }
1684 return 0;
1685}
1686
1687/*
drh67505e72002-04-19 12:34:06 +00001688** Read input from *in and process it. If *in==0 then input
1689** is interactive - the user is typing it it. Otherwise, input
1690** is coming from a file or device. A prompt is issued and history
1691** is saved only if input is interactive. An interrupt signal will
1692** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001693**
1694** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001695*/
drhc28490c2006-10-26 14:25:58 +00001696static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001697 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001698 char *zSql = 0;
1699 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00001700 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00001701 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001702 int rc;
1703 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001704 int lineno = 0;
1705 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001706
1707 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1708 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001709 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001710 zLine = one_input_line(zSql, in);
1711 if( zLine==0 ){
1712 break; /* We have reached EOF */
1713 }
drh67505e72002-04-19 12:34:06 +00001714 if( seenInterrupt ){
1715 if( in!=0 ) break;
1716 seenInterrupt = 0;
1717 }
drhc28490c2006-10-26 14:25:58 +00001718 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001719 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001720 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001721 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001722 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001723 if( rc==2 ){
1724 break;
1725 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001726 errCnt++;
1727 }
drhdaffd0e2001-04-11 14:28:42 +00001728 continue;
1729 }
drhc717b382008-11-11 00:30:11 +00001730 if( _is_command_terminator(zLine) && sqlite3_complete(zSql) ){
drh5bb3eb92007-05-04 13:15:55 +00001731 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001732 }
drh91a66392007-09-07 01:12:32 +00001733 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00001734 if( zSql==0 ){
1735 int i;
drh4c755c02004-08-08 20:22:17 +00001736 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001737 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001738 nSql = strlen30(zLine);
drhdaffd0e2001-04-11 14:28:42 +00001739 zSql = malloc( nSql+1 );
drhc1f44942006-05-10 14:39:13 +00001740 if( zSql==0 ){
1741 fprintf(stderr, "out of memory\n");
1742 exit(1);
1743 }
drh5bb3eb92007-05-04 13:15:55 +00001744 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001745 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001746 }
1747 }else{
drh4f21c4a2008-12-10 22:15:00 +00001748 int len = strlen30(zLine);
drhdaffd0e2001-04-11 14:28:42 +00001749 zSql = realloc( zSql, nSql + len + 2 );
1750 if( zSql==0 ){
1751 fprintf(stderr,"%s: out of memory!\n", Argv0);
1752 exit(1);
1753 }
drh5bb3eb92007-05-04 13:15:55 +00001754 zSql[nSql++] = '\n';
1755 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001756 nSql += len;
1757 }
drh91a66392007-09-07 01:12:32 +00001758 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1759 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001760 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001761 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00001762 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00001763 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00001764 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00001765 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001766 char zPrefix[100];
1767 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001768 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1769 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001770 }else{
drh5bb3eb92007-05-04 13:15:55 +00001771 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001772 }
drh7f953e22002-07-13 17:33:45 +00001773 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001774 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001775 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001776 zErrMsg = 0;
1777 }else{
drhc28490c2006-10-26 14:25:58 +00001778 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001779 }
drhc49f44e2006-10-26 18:15:42 +00001780 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001781 }
1782 free(zSql);
1783 zSql = 0;
1784 nSql = 0;
1785 }
1786 }
1787 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00001788 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001789 free(zSql);
1790 }
danielk19772ac27622007-07-03 05:31:16 +00001791 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001792 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001793}
1794
drh67505e72002-04-19 12:34:06 +00001795/*
1796** Return a pathname which is the user's home directory. A
1797** 0 return indicates an error of some kind. Space to hold the
1798** resulting string is obtained from malloc(). The calling
1799** function should free the result.
1800*/
1801static char *find_home_dir(void){
1802 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001803
chw97185482008-11-17 08:05:31 +00001804#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00001805 struct passwd *pwent;
1806 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001807 if( (pwent=getpwuid(uid)) != NULL) {
1808 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001809 }
1810#endif
1811
chw65d3c132007-11-12 21:09:10 +00001812#if defined(_WIN32_WCE)
1813 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
1814 */
1815 home_dir = strdup("/");
1816#else
1817
drh164a1b62006-08-19 11:15:20 +00001818#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1819 if (!home_dir) {
1820 home_dir = getenv("USERPROFILE");
1821 }
1822#endif
1823
drh67505e72002-04-19 12:34:06 +00001824 if (!home_dir) {
1825 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001826 }
1827
drhcdb36b72006-06-12 12:57:45 +00001828#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001829 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001830 char *zDrive, *zPath;
1831 int n;
1832 zDrive = getenv("HOMEDRIVE");
1833 zPath = getenv("HOMEPATH");
1834 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00001835 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00001836 home_dir = malloc( n );
1837 if( home_dir==0 ) return 0;
1838 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1839 return home_dir;
1840 }
1841 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001842 }
1843#endif
1844
chw65d3c132007-11-12 21:09:10 +00001845#endif /* !_WIN32_WCE */
1846
drh67505e72002-04-19 12:34:06 +00001847 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00001848 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00001849 char *z = malloc( n );
1850 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001851 home_dir = z;
1852 }
drhe98d4fa2002-04-21 19:06:22 +00001853
drh67505e72002-04-19 12:34:06 +00001854 return home_dir;
1855}
1856
1857/*
1858** Read input from the file given by sqliterc_override. Or if that
1859** parameter is NULL, take input from ~/.sqliterc
1860*/
drh22fbcb82004-02-01 01:22:50 +00001861static void process_sqliterc(
1862 struct callback_data *p, /* Configuration data */
1863 const char *sqliterc_override /* Name of config file. NULL to use default */
1864){
persicom7e2dfdd2002-04-18 02:46:52 +00001865 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001866 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001867 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001868 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001869 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001870
1871 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001872 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001873 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00001874#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00001875 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00001876#endif
drhe98d4fa2002-04-21 19:06:22 +00001877 return;
1878 }
drh4f21c4a2008-12-10 22:15:00 +00001879 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00001880 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001881 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001882 fprintf(stderr,"%s: out of memory!\n", Argv0);
1883 exit(1);
1884 }
drha959ac42007-06-20 13:10:00 +00001885 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001886 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001887 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001888 }
drha1f9b5e2004-02-14 16:31:02 +00001889 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001890 if( in ){
drhc28490c2006-10-26 14:25:58 +00001891 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00001892 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00001893 }
persicom7e2dfdd2002-04-18 02:46:52 +00001894 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001895 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001896 }
drh43617e92006-03-06 20:55:46 +00001897 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001898 return;
1899}
1900
drh67505e72002-04-19 12:34:06 +00001901/*
drhe1e38c42003-05-04 18:30:59 +00001902** Show available command line options
1903*/
1904static const char zOptions[] =
1905 " -init filename read/process named file\n"
1906 " -echo print commands before execution\n"
1907 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001908 " -bail stop after hitting an error\n"
1909 " -interactive force interactive I/O\n"
1910 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001911 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001912 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001913 " -html set output mode to HTML\n"
1914 " -line set output mode to 'line'\n"
1915 " -list set output mode to 'list'\n"
1916 " -separator 'x' set output field separator (|)\n"
1917 " -nullvalue 'text' set text string for NULL values\n"
1918 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001919;
1920static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001921 fprintf(stderr,
1922 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1923 "FILENAME is the name of an SQLite database. A new database is created\n"
1924 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001925 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001926 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001927 }else{
1928 fprintf(stderr, "Use the -help option for additional information\n");
1929 }
1930 exit(1);
1931}
1932
1933/*
drh67505e72002-04-19 12:34:06 +00001934** Initialize the state information in data
1935*/
drh0850b532006-01-31 19:31:43 +00001936static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001937 memset(data, 0, sizeof(*data));
1938 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001939 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001940 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001941 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1942 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001943}
1944
drh75897232000-05-29 14:26:00 +00001945int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001946 char *zErrMsg = 0;
1947 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001948 const char *zInitFile = 0;
1949 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001950 int i;
drhc28490c2006-10-26 14:25:58 +00001951 int rc = 0;
drh75897232000-05-29 14:26:00 +00001952
drhdaffd0e2001-04-11 14:28:42 +00001953 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001954 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001955 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001956
drh44c2eb12003-04-30 11:38:26 +00001957 /* Make sure we have a valid signal handler early, before anything
1958 ** else is done.
1959 */
drh4c504392000-10-16 22:06:40 +00001960#ifdef SIGINT
1961 signal(SIGINT, interrupt_handler);
1962#endif
drh44c2eb12003-04-30 11:38:26 +00001963
drh22fbcb82004-02-01 01:22:50 +00001964 /* Do an initial pass through the command-line argument to locate
1965 ** the name of the database file, the name of the initialization file,
1966 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001967 */
drh22fbcb82004-02-01 01:22:50 +00001968 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001969 char *z;
drh44c2eb12003-04-30 11:38:26 +00001970 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001971 z = argv[i];
1972 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001973 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1974 i++;
drh22fbcb82004-02-01 01:22:50 +00001975 }else if( strcmp(argv[i],"-init")==0 ){
1976 i++;
1977 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001978 }
1979 }
drh22fbcb82004-02-01 01:22:50 +00001980 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00001981#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00001982 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
1983#else
drh22fbcb82004-02-01 01:22:50 +00001984 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00001985#endif
drh22fbcb82004-02-01 01:22:50 +00001986 }else{
danielk197703aded42004-11-22 05:26:27 +00001987#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00001988 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00001989#else
1990 data.zDbFilename = 0;
1991#endif
drh22fbcb82004-02-01 01:22:50 +00001992 }
1993 if( i<argc ){
1994 zFirstCmd = argv[i++];
1995 }
drh44c2eb12003-04-30 11:38:26 +00001996 data.out = stdout;
1997
drh01b41712005-08-29 23:06:23 +00001998#ifdef SQLITE_OMIT_MEMORYDB
1999 if( data.zDbFilename==0 ){
2000 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
2001 exit(1);
2002 }
2003#endif
2004
drh44c2eb12003-04-30 11:38:26 +00002005 /* Go ahead and open the database file if it already exists. If the
2006 ** file does not exist, delay opening it. This prevents empty database
2007 ** files from being created if a user mistypes the database name argument
2008 ** to the sqlite command-line tool.
2009 */
drhc8d74412004-08-31 23:41:26 +00002010 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002011 open_db(&data);
2012 }
2013
drh22fbcb82004-02-01 01:22:50 +00002014 /* Process the initialization file if there is one. If no -init option
2015 ** is given on the command line, look for a file named ~/.sqliterc and
2016 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002017 */
drh22fbcb82004-02-01 01:22:50 +00002018 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00002019
drh22fbcb82004-02-01 01:22:50 +00002020 /* Make a second pass through the command-line argument and set
2021 ** options. This second pass is delayed until after the initialization
2022 ** file is processed so that the command-line arguments will override
2023 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002024 */
drh22fbcb82004-02-01 01:22:50 +00002025 for(i=1; i<argc && argv[i][0]=='-'; i++){
2026 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002027 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002028 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002029 i++;
2030 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002031 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002032 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002033 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002034 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002035 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002036 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002037 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002038 }else if( strcmp(z,"-csv")==0 ){
2039 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002040 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002041 }else if( strcmp(z,"-separator")==0 ){
2042 i++;
drh5bb3eb92007-05-04 13:15:55 +00002043 sqlite3_snprintf(sizeof(data.separator), data.separator,
2044 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002045 }else if( strcmp(z,"-nullvalue")==0 ){
2046 i++;
drh5bb3eb92007-05-04 13:15:55 +00002047 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2048 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002049 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002050 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002051 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002052 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002053 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002054 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002055 }else if( strcmp(z,"-bail")==0 ){
2056 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002057 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002058 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002059 return 0;
drhc28490c2006-10-26 14:25:58 +00002060 }else if( strcmp(z,"-interactive")==0 ){
2061 stdin_is_interactive = 1;
2062 }else if( strcmp(z,"-batch")==0 ){
2063 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002064 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002065 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002066 }else{
drh22fbcb82004-02-01 01:22:50 +00002067 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002068 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002069 return 1;
2070 }
2071 }
drh44c2eb12003-04-30 11:38:26 +00002072
drh22fbcb82004-02-01 01:22:50 +00002073 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002074 /* Run just the command that follows the database name
2075 */
drh22fbcb82004-02-01 01:22:50 +00002076 if( zFirstCmd[0]=='.' ){
2077 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002078 exit(0);
2079 }else{
2080 int rc;
drh44c2eb12003-04-30 11:38:26 +00002081 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00002082 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00002083 if( rc!=0 && zErrMsg!=0 ){
2084 fprintf(stderr,"SQL error: %s\n", zErrMsg);
2085 exit(1);
2086 }
drh75897232000-05-29 14:26:00 +00002087 }
2088 }else{
drh44c2eb12003-04-30 11:38:26 +00002089 /* Run commands received from standard input
2090 */
drhc28490c2006-10-26 14:25:58 +00002091 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002092 char *zHome;
2093 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002094 int nHistory;
drh75897232000-05-29 14:26:00 +00002095 printf(
drhb217a572000-08-22 13:40:18 +00002096 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002097 "Enter \".help\" for instructions\n"
2098 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002099 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002100 );
drh67505e72002-04-19 12:34:06 +00002101 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002102 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002103 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002104 if( (zHistory = malloc(nHistory))!=0 ){
2105 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2106 }
drh67505e72002-04-19 12:34:06 +00002107 }
danielk19774af00c62005-01-23 23:43:21 +00002108#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002109 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002110#endif
drhc28490c2006-10-26 14:25:58 +00002111 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002112 if( zHistory ){
2113 stifle_history(100);
2114 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002115 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002116 }
adamd0a3daa32006-07-28 20:16:14 +00002117 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002118 }else{
drhc28490c2006-10-26 14:25:58 +00002119 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002120 }
2121 }
drh33048c02001-10-01 14:29:22 +00002122 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002123 if( db ){
2124 if( sqlite3_close(db)!=SQLITE_OK ){
2125 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2126 }
2127 }
drhc28490c2006-10-26 14:25:58 +00002128 return rc;
drh75897232000-05-29 14:26:00 +00002129}