blob: 00e7b66233ea479fcb6de32e97489d84cbe1da1b [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**
shaned87897d2009-01-30 05:40:27 +000015** $Id: shell.c,v 1.199 2009/01/30 05:40:27 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 );
shaned87897d2009-01-30 05:40:27 +0000230 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000231 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000232 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
233}
234
235
236/*
drhfeac5f82004-08-01 00:10:45 +0000237** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000238** the text in memory obtained from malloc() and returns a pointer
239** to the text. NULL is returned at end of file, or if malloc()
240** fails.
241**
242** The interface is like "readline" but no command-line editing
243** is done.
244*/
drh9347b202003-07-18 01:30:59 +0000245static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000246 char *zLine;
247 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000248 int n;
249 int eol;
250
251 if( zPrompt && *zPrompt ){
252 printf("%s",zPrompt);
253 fflush(stdout);
254 }
255 nLine = 100;
256 zLine = malloc( nLine );
257 if( zLine==0 ) return 0;
258 n = 0;
259 eol = 0;
260 while( !eol ){
261 if( n+100>nLine ){
262 nLine = nLine*2 + 100;
263 zLine = realloc(zLine, nLine);
264 if( zLine==0 ) return 0;
265 }
drhdaffd0e2001-04-11 14:28:42 +0000266 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000267 if( n==0 ){
268 free(zLine);
269 return 0;
270 }
271 zLine[n] = 0;
272 eol = 1;
273 break;
274 }
275 while( zLine[n] ){ n++; }
276 if( n>0 && zLine[n-1]=='\n' ){
277 n--;
278 zLine[n] = 0;
279 eol = 1;
280 }
281 }
282 zLine = realloc( zLine, n+1 );
283 return zLine;
284}
285
286/*
drhc28490c2006-10-26 14:25:58 +0000287** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000288**
289** zPrior is a string of prior text retrieved. If not the empty
290** string, then issue a continuation prompt.
291*/
drhdaffd0e2001-04-11 14:28:42 +0000292static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000293 char *zPrompt;
294 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000295 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000296 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000297 }
298 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000299 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000300 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000301 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000302 }
303 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000304#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000305 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000306#endif
drh8e7e7a22000-05-30 18:45:23 +0000307 return zResult;
308}
309
persicom7e2dfdd2002-04-18 02:46:52 +0000310struct previous_mode_data {
311 int valid; /* Is there legit data in here? */
312 int mode;
313 int showHeader;
314 int colWidth[100];
315};
drh45e29d82006-11-20 16:21:10 +0000316
drh8e7e7a22000-05-30 18:45:23 +0000317/*
drh75897232000-05-29 14:26:00 +0000318** An pointer to an instance of this structure is passed from
319** the main program to the callback. This is used to communicate
320** state and mode information.
321*/
322struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000323 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000324 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000325 int cnt; /* Number of records displayed so far */
326 FILE *out; /* Write results here */
327 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000328 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000329 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000330 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000331 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000332 int colWidth[100]; /* Requested width of each column when in column mode*/
333 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000334 char nullvalue[20]; /* The text to print when a NULL comes back from
335 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000336 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000337 /* Holds the mode information just before
338 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000339 char outfile[FILENAME_MAX]; /* Filename for *out */
340 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000341};
342
343/*
344** These are the allowed modes.
345*/
drh967e8b72000-06-21 13:59:10 +0000346#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000347#define MODE_Column 1 /* One record per line in neat columns */
348#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000349#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
350#define MODE_Html 4 /* Generate an XHTML table */
351#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000352#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000353#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000354#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000355
drh66ce4d02008-02-15 17:38:06 +0000356static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000357 "line",
358 "column",
359 "list",
360 "semi",
361 "html",
drhfeac5f82004-08-01 00:10:45 +0000362 "insert",
363 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000364 "csv",
drh66ce4d02008-02-15 17:38:06 +0000365 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000366};
drh75897232000-05-29 14:26:00 +0000367
368/*
369** Number of elements in an array
370*/
drh902b9ee2008-12-05 17:17:07 +0000371#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000372
373/*
drhea678832008-12-10 19:26:22 +0000374** Compute a string length that is limited to what can be stored in
375** lower 30 bits of a 32-bit signed integer.
376*/
drh4f21c4a2008-12-10 22:15:00 +0000377static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000378 const char *z2 = z;
379 while( *z2 ){ z2++; }
380 return 0x3fffffff & (int)(z2 - z);
381}
382
383/*
drh28bd4bc2000-06-15 15:57:22 +0000384** Output the given string as a quoted string using SQL quoting conventions.
385*/
386static void output_quoted_string(FILE *out, const char *z){
387 int i;
388 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000389 for(i=0; z[i]; i++){
390 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000391 }
392 if( nSingle==0 ){
393 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000394 }else{
395 fprintf(out,"'");
396 while( *z ){
397 for(i=0; z[i] && z[i]!='\''; i++){}
398 if( i==0 ){
399 fprintf(out,"''");
400 z++;
401 }else if( z[i]=='\'' ){
402 fprintf(out,"%.*s''",i,z);
403 z += i+1;
404 }else{
drhcd7d2732002-02-26 23:24:26 +0000405 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000406 break;
407 }
408 }
drhcd7d2732002-02-26 23:24:26 +0000409 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000410 }
411}
412
413/*
drhfeac5f82004-08-01 00:10:45 +0000414** Output the given string as a quoted according to C or TCL quoting rules.
415*/
416static void output_c_string(FILE *out, const char *z){
417 unsigned int c;
418 fputc('"', out);
419 while( (c = *(z++))!=0 ){
420 if( c=='\\' ){
421 fputc(c, out);
422 fputc(c, out);
423 }else if( c=='\t' ){
424 fputc('\\', out);
425 fputc('t', out);
426 }else if( c=='\n' ){
427 fputc('\\', out);
428 fputc('n', out);
429 }else if( c=='\r' ){
430 fputc('\\', out);
431 fputc('r', out);
432 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000433 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000434 }else{
435 fputc(c, out);
436 }
437 }
438 fputc('"', out);
439}
440
441/*
drhc08a4f12000-06-15 16:49:48 +0000442** Output the given string with characters that are special to
443** HTML escaped.
444*/
445static void output_html_string(FILE *out, const char *z){
446 int i;
447 while( *z ){
448 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
449 if( i>0 ){
450 fprintf(out,"%.*s",i,z);
451 }
452 if( z[i]=='<' ){
453 fprintf(out,"&lt;");
454 }else if( z[i]=='&' ){
455 fprintf(out,"&amp;");
456 }else{
457 break;
458 }
459 z += i + 1;
460 }
461}
462
463/*
drhc49f44e2006-10-26 18:15:42 +0000464** If a field contains any character identified by a 1 in the following
465** array, then the string must be quoted for CSV.
466*/
467static const char needCsvQuote[] = {
468 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
469 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
470 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
475 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
484};
485
486/*
drh8e64d1c2004-10-07 00:32:39 +0000487** Output a single term of CSV. Actually, p->separator is used for
488** the separator, which may or may not be a comma. p->nullvalue is
489** the null value. Strings are quoted using ANSI-C rules. Numbers
490** appear outside of quotes.
491*/
492static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000493 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000494 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000495 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000496 }else{
drhc49f44e2006-10-26 18:15:42 +0000497 int i;
drh4f21c4a2008-12-10 22:15:00 +0000498 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000499 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000500 if( needCsvQuote[((unsigned char*)z)[i]]
501 || (z[i]==p->separator[0] &&
502 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000503 i = 0;
504 break;
505 }
506 }
507 if( i==0 ){
508 putc('"', out);
509 for(i=0; z[i]; i++){
510 if( z[i]=='"' ) putc('"', out);
511 putc(z[i], out);
512 }
513 putc('"', out);
514 }else{
515 fprintf(out, "%s", z);
516 }
drh8e64d1c2004-10-07 00:32:39 +0000517 }
518 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000519 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000520 }
521}
522
danielk19774af00c62005-01-23 23:43:21 +0000523#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000524/*
drh4c504392000-10-16 22:06:40 +0000525** This routine runs when the user presses Ctrl-C
526*/
527static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000528 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000529 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000530 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000531}
danielk19774af00c62005-01-23 23:43:21 +0000532#endif
drh4c504392000-10-16 22:06:40 +0000533
534/*
drh75897232000-05-29 14:26:00 +0000535** This is the callback routine that the SQLite library
536** invokes for each row of a query result.
537*/
538static int callback(void *pArg, int nArg, char **azArg, char **azCol){
539 int i;
540 struct callback_data *p = (struct callback_data*)pArg;
541 switch( p->mode ){
542 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000543 int w = 5;
drh6a535342001-10-19 16:44:56 +0000544 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000545 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000546 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000547 if( len>w ) w = len;
548 }
drh75897232000-05-29 14:26:00 +0000549 if( p->cnt++>0 ) fprintf(p->out,"\n");
550 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000551 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000552 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000553 }
554 break;
555 }
danielk19770d78bae2008-01-03 07:09:48 +0000556 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000557 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000558 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000559 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000560 int w, n;
561 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000562 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000563 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000564 w = 0;
drh75897232000-05-29 14:26:00 +0000565 }
drha0c66f52000-07-29 13:20:21 +0000566 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000567 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000568 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000569 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000570 if( w<n ) w = n;
571 }
572 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000573 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000574 }
575 if( p->showHeader ){
576 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
577 }
578 }
579 if( p->showHeader ){
580 for(i=0; i<nArg; i++){
581 int w;
582 if( i<ArraySize(p->actualWidth) ){
583 w = p->actualWidth[i];
584 }else{
585 w = 10;
586 }
587 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
588 "----------------------------------------------------------",
589 i==nArg-1 ? "\n": " ");
590 }
drh75897232000-05-29 14:26:00 +0000591 }
592 }
drh6a535342001-10-19 16:44:56 +0000593 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000594 for(i=0; i<nArg; i++){
595 int w;
drha0c66f52000-07-29 13:20:21 +0000596 if( i<ArraySize(p->actualWidth) ){
597 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000598 }else{
599 w = 10;
600 }
drhea678832008-12-10 19:26:22 +0000601 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000602 strlen30(azArg[i])>w ){
603 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000604 }
drhc61053b2000-06-04 12:58:36 +0000605 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000606 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000607 }
608 break;
609 }
drhe3710332000-09-29 13:30:53 +0000610 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000611 case MODE_List: {
612 if( p->cnt++==0 && p->showHeader ){
613 for(i=0; i<nArg; i++){
614 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
615 }
616 }
drh6a535342001-10-19 16:44:56 +0000617 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000618 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000619 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000620 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000621 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000622 if( i<nArg-1 ){
623 fprintf(p->out, "%s", p->separator);
624 }else if( p->mode==MODE_Semi ){
625 fprintf(p->out, ";\n");
626 }else{
627 fprintf(p->out, "\n");
628 }
drh75897232000-05-29 14:26:00 +0000629 }
630 break;
631 }
drh1e5d0e92000-05-31 23:33:17 +0000632 case MODE_Html: {
633 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000634 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000635 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000636 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
drh1e5d0e92000-05-31 23:33:17 +0000637 }
mihailim57c591a2008-06-23 21:26:05 +0000638 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000639 }
drh6a535342001-10-19 16:44:56 +0000640 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000641 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000642 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000643 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000644 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000645 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000646 }
mihailim57c591a2008-06-23 21:26:05 +0000647 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000648 break;
649 }
drhfeac5f82004-08-01 00:10:45 +0000650 case MODE_Tcl: {
651 if( p->cnt++==0 && p->showHeader ){
652 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000653 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000654 fprintf(p->out, "%s", p->separator);
655 }
656 fprintf(p->out,"\n");
657 }
658 if( azArg==0 ) break;
659 for(i=0; i<nArg; i++){
660 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
661 fprintf(p->out, "%s", p->separator);
662 }
663 fprintf(p->out,"\n");
664 break;
665 }
drh8e64d1c2004-10-07 00:32:39 +0000666 case MODE_Csv: {
667 if( p->cnt++==0 && p->showHeader ){
668 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000669 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000670 }
671 fprintf(p->out,"\n");
672 }
673 if( azArg==0 ) break;
674 for(i=0; i<nArg; i++){
675 output_csv(p, azArg[i], i<nArg-1);
676 }
677 fprintf(p->out,"\n");
678 break;
679 }
drh28bd4bc2000-06-15 15:57:22 +0000680 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000681 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000682 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000683 for(i=0; i<nArg; i++){
684 char *zSep = i>0 ? ",": "";
685 if( azArg[i]==0 ){
686 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000687 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000688 fprintf(p->out,"%s%s",zSep, azArg[i]);
689 }else{
690 if( zSep[0] ) fprintf(p->out,"%s",zSep);
691 output_quoted_string(p->out, azArg[i]);
692 }
693 }
694 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000695 break;
drh28bd4bc2000-06-15 15:57:22 +0000696 }
persicom1d0b8722002-04-18 02:53:04 +0000697 }
drh75897232000-05-29 14:26:00 +0000698 return 0;
699}
700
701/*
drh33048c02001-10-01 14:29:22 +0000702** Set the destination table field of the callback_data structure to
703** the name of the table given. Escape any quote characters in the
704** table name.
705*/
706static void set_table_name(struct callback_data *p, const char *zName){
707 int i, n;
708 int needQuote;
709 char *z;
710
711 if( p->zDestTable ){
712 free(p->zDestTable);
713 p->zDestTable = 0;
714 }
715 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000716 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000717 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000718 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000719 needQuote = 1;
720 if( zName[i]=='\'' ) n++;
721 }
722 }
723 if( needQuote ) n += 2;
724 z = p->zDestTable = malloc( n+1 );
725 if( z==0 ){
726 fprintf(stderr,"Out of memory!\n");
727 exit(1);
728 }
729 n = 0;
730 if( needQuote ) z[n++] = '\'';
731 for(i=0; zName[i]; i++){
732 z[n++] = zName[i];
733 if( zName[i]=='\'' ) z[n++] = '\'';
734 }
735 if( needQuote ) z[n++] = '\'';
736 z[n] = 0;
737}
738
danielk19772a02e332004-06-05 08:04:36 +0000739/* zIn is either a pointer to a NULL-terminated string in memory obtained
740** from malloc(), or a NULL pointer. The string pointed to by zAppend is
741** added to zIn, and the result returned in memory obtained from malloc().
742** zIn, if it was not NULL, is freed.
743**
744** If the third argument, quote, is not '\0', then it is used as a
745** quote character for zAppend.
746*/
drhc28490c2006-10-26 14:25:58 +0000747static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000748 int len;
749 int i;
drh4f21c4a2008-12-10 22:15:00 +0000750 int nAppend = strlen30(zAppend);
751 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000752
753 len = nAppend+nIn+1;
754 if( quote ){
755 len += 2;
756 for(i=0; i<nAppend; i++){
757 if( zAppend[i]==quote ) len++;
758 }
759 }
760
761 zIn = (char *)realloc(zIn, len);
762 if( !zIn ){
763 return 0;
764 }
765
766 if( quote ){
767 char *zCsr = &zIn[nIn];
768 *zCsr++ = quote;
769 for(i=0; i<nAppend; i++){
770 *zCsr++ = zAppend[i];
771 if( zAppend[i]==quote ) *zCsr++ = quote;
772 }
773 *zCsr++ = quote;
774 *zCsr++ = '\0';
775 assert( (zCsr-zIn)==len );
776 }else{
777 memcpy(&zIn[nIn], zAppend, nAppend);
778 zIn[len-1] = '\0';
779 }
780
781 return zIn;
782}
783
drhdd3d4592004-08-30 01:54:05 +0000784
785/*
786** Execute a query statement that has a single result column. Print
787** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000788**
789** This is used, for example, to show the schema of the database by
790** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000791*/
792static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
793 sqlite3_stmt *pSelect;
794 int rc;
795 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
796 if( rc!=SQLITE_OK || !pSelect ){
797 return rc;
798 }
799 rc = sqlite3_step(pSelect);
800 while( rc==SQLITE_ROW ){
801 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
802 rc = sqlite3_step(pSelect);
803 }
804 return sqlite3_finalize(pSelect);
805}
806
807
drh33048c02001-10-01 14:29:22 +0000808/*
drh4c653a02000-06-07 01:27:47 +0000809** This is a different callback routine used for dumping the database.
810** Each row received by this callback consists of a table name,
811** the table type ("index" or "table") and SQL to create the table.
812** This routine should print text sufficient to recreate the table.
813*/
814static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000815 int rc;
816 const char *zTable;
817 const char *zType;
818 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000819 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000820
drh902b9ee2008-12-05 17:17:07 +0000821 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +0000822 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000823 zTable = azArg[0];
824 zType = azArg[1];
825 zSql = azArg[2];
826
drh00b950d2005-09-11 02:03:03 +0000827 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000828 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000829 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
830 fprintf(p->out, "ANALYZE sqlite_master;\n");
831 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
832 return 0;
drh45e29d82006-11-20 16:21:10 +0000833 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
834 char *zIns;
835 if( !p->writableSchema ){
836 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
837 p->writableSchema = 1;
838 }
839 zIns = sqlite3_mprintf(
840 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
841 "VALUES('table','%q','%q',0,'%q');",
842 zTable, zTable, zSql);
843 fprintf(p->out, "%s\n", zIns);
844 sqlite3_free(zIns);
845 return 0;
drh00b950d2005-09-11 02:03:03 +0000846 }else{
847 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000848 }
danielk19772a02e332004-06-05 08:04:36 +0000849
850 if( strcmp(zType, "table")==0 ){
851 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000852 char *zSelect = 0;
853 char *zTableInfo = 0;
854 char *zTmp = 0;
855
856 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
857 zTableInfo = appendText(zTableInfo, zTable, '"');
858 zTableInfo = appendText(zTableInfo, ");", 0);
859
860 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
861 if( zTableInfo ) free(zTableInfo);
862 if( rc!=SQLITE_OK || !pTableInfo ){
863 return 1;
864 }
865
866 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
867 zTmp = appendText(zTmp, zTable, '"');
868 if( zTmp ){
869 zSelect = appendText(zSelect, zTmp, '\'');
870 }
871 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
872 rc = sqlite3_step(pTableInfo);
873 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000874 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000875 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000876 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000877 rc = sqlite3_step(pTableInfo);
878 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000879 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000880 }else{
881 zSelect = appendText(zSelect, ") ", 0);
882 }
883 }
884 rc = sqlite3_finalize(pTableInfo);
885 if( rc!=SQLITE_OK ){
886 if( zSelect ) free(zSelect);
887 return 1;
888 }
889 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
890 zSelect = appendText(zSelect, zTable, '"');
891
drhdd3d4592004-08-30 01:54:05 +0000892 rc = run_table_dump_query(p->out, p->db, zSelect);
893 if( rc==SQLITE_CORRUPT ){
894 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
895 rc = run_table_dump_query(p->out, p->db, zSelect);
896 }
danielk19772a02e332004-06-05 08:04:36 +0000897 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000898 }
drh4c653a02000-06-07 01:27:47 +0000899 return 0;
900}
901
902/*
drh45e29d82006-11-20 16:21:10 +0000903** Run zQuery. Use dump_callback() as the callback routine so that
904** the contents of the query are output as SQL statements.
905**
drhdd3d4592004-08-30 01:54:05 +0000906** If we get a SQLITE_CORRUPT error, rerun the query after appending
907** "ORDER BY rowid DESC" to the end.
908*/
909static int run_schema_dump_query(
910 struct callback_data *p,
911 const char *zQuery,
912 char **pzErrMsg
913){
914 int rc;
915 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
916 if( rc==SQLITE_CORRUPT ){
917 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +0000918 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +0000919 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
920 zQ2 = malloc( len+100 );
921 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000922 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000923 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
924 free(zQ2);
925 }
926 return rc;
927}
928
929/*
drh75897232000-05-29 14:26:00 +0000930** Text of a help message
931*/
persicom1d0b8722002-04-18 02:53:04 +0000932static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000933 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000934 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000935 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000936 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000937 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000938 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000939 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000940 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000941 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000942 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000943#ifdef SQLITE_ENABLE_IOTRACE
944 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
945#endif
drh70df4fe2006-06-13 15:12:21 +0000946#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000947 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000948#endif
danielk19776b77a362005-01-13 11:10:25 +0000949 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000950 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000951 " column Left-aligned columns. (See .width)\n"
952 " html HTML <table> code\n"
953 " insert SQL insert statements for TABLE\n"
954 " line One value per line\n"
955 " list Values delimited by .separator string\n"
956 " tabs Tab-separated values\n"
957 " tcl TCL list elements\n"
958 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000959 ".output FILENAME Send output to FILENAME\n"
960 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000961 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000962 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000963 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000964 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000965 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000966 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000967 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000968 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +0000969#if HAS_TIMER
970 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
971#endif
drh75897232000-05-29 14:26:00 +0000972 ".width NUM NUM ... Set column widths for \"column\" mode\n"
973;
974
drhdaffd0e2001-04-11 14:28:42 +0000975/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000976static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000977
drh75897232000-05-29 14:26:00 +0000978/*
drh44c2eb12003-04-30 11:38:26 +0000979** Make sure the database is open. If it is not, then open it. If
980** the database fails to open, print an error message and exit.
981*/
982static void open_db(struct callback_data *p){
983 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000984 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000985 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +0000986 if( db && sqlite3_errcode(db)==SQLITE_OK ){
987 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
988 shellstaticFunc, 0, 0);
989 }
990 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +0000991 fprintf(stderr,"Unable to open database \"%s\": %s\n",
992 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000993 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000994 }
drhc2e87a32006-06-27 15:16:14 +0000995#ifndef SQLITE_OMIT_LOAD_EXTENSION
996 sqlite3_enable_load_extension(p->db, 1);
997#endif
drh44c2eb12003-04-30 11:38:26 +0000998 }
999}
1000
1001/*
drhfeac5f82004-08-01 00:10:45 +00001002** Do C-language style dequoting.
1003**
1004** \t -> tab
1005** \n -> newline
1006** \r -> carriage return
1007** \NNN -> ascii character NNN in octal
1008** \\ -> backslash
1009*/
1010static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001011 int i, j;
1012 char c;
drhfeac5f82004-08-01 00:10:45 +00001013 for(i=j=0; (c = z[i])!=0; i++, j++){
1014 if( c=='\\' ){
1015 c = z[++i];
1016 if( c=='n' ){
1017 c = '\n';
1018 }else if( c=='t' ){
1019 c = '\t';
1020 }else if( c=='r' ){
1021 c = '\r';
1022 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001023 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001024 if( z[i+1]>='0' && z[i+1]<='7' ){
1025 i++;
1026 c = (c<<3) + z[i] - '0';
1027 if( z[i+1]>='0' && z[i+1]<='7' ){
1028 i++;
1029 c = (c<<3) + z[i] - '0';
1030 }
1031 }
1032 }
1033 }
1034 z[j] = c;
1035 }
1036 z[j] = 0;
1037}
1038
1039/*
drhc28490c2006-10-26 14:25:58 +00001040** Interpret zArg as a boolean value. Return either 0 or 1.
1041*/
1042static int booleanValue(char *zArg){
1043 int val = atoi(zArg);
1044 int j;
1045 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001046 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001047 }
1048 if( strcmp(zArg,"on")==0 ){
1049 val = 1;
1050 }else if( strcmp(zArg,"yes")==0 ){
1051 val = 1;
1052 }
1053 return val;
1054}
1055
1056/*
drh75897232000-05-29 14:26:00 +00001057** If an input line begins with "." then invoke this routine to
1058** process that line.
drh67505e72002-04-19 12:34:06 +00001059**
drh47ad6842006-11-08 12:25:42 +00001060** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001061*/
drh44c2eb12003-04-30 11:38:26 +00001062static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001063 int i = 1;
1064 int nArg = 0;
1065 int n, c;
drh67505e72002-04-19 12:34:06 +00001066 int rc = 0;
drh75897232000-05-29 14:26:00 +00001067 char *azArg[50];
1068
1069 /* Parse the input line into tokens.
1070 */
1071 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001072 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001073 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001074 if( zLine[i]=='\'' || zLine[i]=='"' ){
1075 int delim = zLine[i++];
1076 azArg[nArg++] = &zLine[i];
1077 while( zLine[i] && zLine[i]!=delim ){ i++; }
1078 if( zLine[i]==delim ){
1079 zLine[i++] = 0;
1080 }
drhfeac5f82004-08-01 00:10:45 +00001081 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001082 }else{
1083 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001084 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001085 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001086 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001087 }
1088 }
1089
1090 /* Process the input line.
1091 */
drh67505e72002-04-19 12:34:06 +00001092 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00001093 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001094 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001095 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1096 bail_on_error = booleanValue(azArg[1]);
1097 }else
1098
jplyon6a65bb32003-05-04 07:25:57 +00001099 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001100 struct callback_data data;
1101 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001102 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001103 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001104 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001105 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001106 data.colWidth[0] = 3;
1107 data.colWidth[1] = 15;
1108 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001109 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001110 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001111 if( zErrMsg ){
1112 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001113 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001114 }
1115 }else
1116
drh4c653a02000-06-07 01:27:47 +00001117 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1118 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001119 open_db(p);
drh33048c02001-10-01 14:29:22 +00001120 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001121 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001122 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001123 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001124 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001125 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001126 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001127 );
1128 run_table_dump_query(p->out, p->db,
1129 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001130 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001131 );
drh4c653a02000-06-07 01:27:47 +00001132 }else{
1133 int i;
drhdd3d4592004-08-30 01:54:05 +00001134 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001135 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001136 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001137 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001138 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001139 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001140 run_table_dump_query(p->out, p->db,
1141 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001142 "WHERE sql NOT NULL"
1143 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001144 " AND tbl_name LIKE shellstatic()"
1145 );
danielk1977bc6ada42004-06-30 08:20:16 +00001146 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001147 }
1148 }
drh45e29d82006-11-20 16:21:10 +00001149 if( p->writableSchema ){
1150 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1151 p->writableSchema = 0;
1152 }
drh93f41e52008-08-11 19:12:34 +00001153 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001154 if( zErrMsg ){
1155 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001156 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001157 }else{
1158 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001159 }
1160 }else
drh75897232000-05-29 14:26:00 +00001161
drhdaffd0e2001-04-11 14:28:42 +00001162 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001163 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001164 }else
1165
drh75897232000-05-29 14:26:00 +00001166 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001167 rc = 2;
drh75897232000-05-29 14:26:00 +00001168 }else
1169
drhdd45df82002-04-18 12:39:03 +00001170 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001171 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001172 if(val == 1) {
1173 if(!p->explainPrev.valid) {
1174 p->explainPrev.valid = 1;
1175 p->explainPrev.mode = p->mode;
1176 p->explainPrev.showHeader = p->showHeader;
1177 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1178 }
1179 /* We could put this code under the !p->explainValid
1180 ** condition so that it does not execute if we are already in
1181 ** explain mode. However, always executing it allows us an easy
1182 ** was to reset to explain mode in case the user previously
1183 ** did an .explain followed by a .width, .mode or .header
1184 ** command.
1185 */
danielk19770d78bae2008-01-03 07:09:48 +00001186 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001187 p->showHeader = 1;
1188 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001189 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001190 p->colWidth[1] = 13; /* opcode */
1191 p->colWidth[2] = 4; /* P1 */
1192 p->colWidth[3] = 4; /* P2 */
1193 p->colWidth[4] = 4; /* P3 */
1194 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001195 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001196 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001197 }else if (p->explainPrev.valid) {
1198 p->explainPrev.valid = 0;
1199 p->mode = p->explainPrev.mode;
1200 p->showHeader = p->explainPrev.showHeader;
1201 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1202 }
drh75897232000-05-29 14:26:00 +00001203 }else
1204
drhc28490c2006-10-26 14:25:58 +00001205 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001206 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001207 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001208 }else
1209
1210 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001211 fprintf(stderr,"%s",zHelp);
drh75897232000-05-29 14:26:00 +00001212 }else
1213
drhfeac5f82004-08-01 00:10:45 +00001214 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1215 char *zTable = azArg[2]; /* Insert data into this table */
1216 char *zFile = azArg[1]; /* The file from which to extract data */
1217 sqlite3_stmt *pStmt; /* A statement */
1218 int rc; /* Result code */
1219 int nCol; /* Number of columns in the table */
1220 int nByte; /* Number of bytes in an SQL string */
1221 int i, j; /* Loop counters */
1222 int nSep; /* Number of bytes in p->separator[] */
1223 char *zSql; /* An SQL statement */
1224 char *zLine; /* A single line of input from the file */
1225 char **azCol; /* zLine[] broken up into columns */
1226 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001227 FILE *in; /* The input file */
1228 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001229
drha543c822006-06-08 16:10:14 +00001230 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001231 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001232 if( nSep==0 ){
1233 fprintf(stderr, "non-null separator required for import\n");
1234 return 0;
1235 }
1236 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1237 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00001238 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001239 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001240 sqlite3_free(zSql);
1241 if( rc ){
1242 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1243 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001244 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001245 }else{
1246 nCol = sqlite3_column_count(pStmt);
1247 }
1248 sqlite3_finalize(pStmt);
1249 if( nCol==0 ) return 0;
1250 zSql = malloc( nByte + 20 + nCol*2 );
1251 if( zSql==0 ) return 0;
1252 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001253 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001254 for(i=1; i<nCol; i++){
1255 zSql[j++] = ',';
1256 zSql[j++] = '?';
1257 }
1258 zSql[j++] = ')';
1259 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001260 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001261 free(zSql);
1262 if( rc ){
1263 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1264 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001265 return 1;
drhfeac5f82004-08-01 00:10:45 +00001266 }
1267 in = fopen(zFile, "rb");
1268 if( in==0 ){
1269 fprintf(stderr, "cannot open file: %s\n", zFile);
1270 sqlite3_finalize(pStmt);
1271 return 0;
1272 }
1273 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001274 if( azCol==0 ){
1275 fclose(in);
1276 return 0;
1277 }
drhfeac5f82004-08-01 00:10:45 +00001278 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1279 zCommit = "COMMIT";
1280 while( (zLine = local_getline(0, in))!=0 ){
1281 char *z;
1282 i = 0;
drhb860bc92004-08-04 15:16:55 +00001283 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001284 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001285 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001286 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1287 *z = 0;
1288 i++;
drhb860bc92004-08-04 15:16:55 +00001289 if( i<nCol ){
1290 azCol[i] = &z[nSep];
1291 z += nSep-1;
1292 }
drhfeac5f82004-08-01 00:10:45 +00001293 }
1294 }
drh1cd7f832005-08-05 18:50:51 +00001295 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001296 if( i+1!=nCol ){
1297 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1298 zFile, lineno, nCol, i+1);
1299 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001300 free(zLine);
drhb860bc92004-08-04 15:16:55 +00001301 break;
1302 }
drhfeac5f82004-08-01 00:10:45 +00001303 for(i=0; i<nCol; i++){
1304 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1305 }
1306 sqlite3_step(pStmt);
1307 rc = sqlite3_reset(pStmt);
1308 free(zLine);
1309 if( rc!=SQLITE_OK ){
1310 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1311 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001312 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001313 break;
1314 }
1315 }
1316 free(azCol);
1317 fclose(in);
1318 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001319 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001320 }else
1321
drh75897232000-05-29 14:26:00 +00001322 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1323 struct callback_data data;
1324 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001325 open_db(p);
drh75897232000-05-29 14:26:00 +00001326 memcpy(&data, p, sizeof(data));
1327 data.showHeader = 0;
1328 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001329 zShellStatic = azArg[1];
1330 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001331 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001332 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001333 "UNION ALL "
1334 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001335 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001336 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001337 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001338 );
danielk1977bc6ada42004-06-30 08:20:16 +00001339 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001340 if( zErrMsg ){
1341 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001342 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001343 }
1344 }else
1345
drhae5e4452007-05-03 17:18:36 +00001346#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001347 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001348 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001349 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1350 iotrace = 0;
1351 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001352 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001353 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001354 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001355 iotrace = stdout;
1356 }else{
1357 iotrace = fopen(azArg[1], "w");
1358 if( iotrace==0 ){
1359 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001360 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001361 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001362 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001363 }
1364 }
1365 }else
drhae5e4452007-05-03 17:18:36 +00001366#endif
drhb0603412007-02-28 04:47:26 +00001367
drh70df4fe2006-06-13 15:12:21 +00001368#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001369 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1370 const char *zFile, *zProc;
1371 char *zErrMsg = 0;
1372 int rc;
1373 zFile = azArg[1];
1374 zProc = nArg>=3 ? azArg[2] : 0;
1375 open_db(p);
1376 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1377 if( rc!=SQLITE_OK ){
1378 fprintf(stderr, "%s\n", zErrMsg);
1379 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001380 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001381 }
1382 }else
drh70df4fe2006-06-13 15:12:21 +00001383#endif
drh1e397f82006-06-08 15:28:43 +00001384
drh28bd4bc2000-06-15 15:57:22 +00001385 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00001386 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001387 if( strncmp(azArg[1],"line",n2)==0
1388 ||
1389 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001390 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001391 }else if( strncmp(azArg[1],"column",n2)==0
1392 ||
1393 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001394 p->mode = MODE_Column;
1395 }else if( strncmp(azArg[1],"list",n2)==0 ){
1396 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001397 }else if( strncmp(azArg[1],"html",n2)==0 ){
1398 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001399 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1400 p->mode = MODE_Tcl;
1401 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001402 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001403 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001404 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1405 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001406 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001407 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1408 p->mode = MODE_Insert;
1409 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001410 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001411 }else{
drh33048c02001-10-01 14:29:22 +00001412 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001413 }
drhdaffd0e2001-04-11 14:28:42 +00001414 }else {
drhcf68ae92006-12-19 18:47:41 +00001415 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001416 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001417 }
1418 }else
1419
persicom7e2dfdd2002-04-18 02:46:52 +00001420 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001421 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1422 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001423 }else
1424
drh75897232000-05-29 14:26:00 +00001425 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1426 if( p->out!=stdout ){
1427 fclose(p->out);
1428 }
1429 if( strcmp(azArg[1],"stdout")==0 ){
1430 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001431 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001432 }else{
drha1f9b5e2004-02-14 16:31:02 +00001433 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001434 if( p->out==0 ){
1435 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1436 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001437 } else {
drh5bb3eb92007-05-04 13:15:55 +00001438 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001439 }
1440 }
1441 }else
1442
drhdd45df82002-04-18 12:39:03 +00001443 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001444 if( nArg >= 2) {
1445 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1446 }
1447 if( nArg >= 3) {
1448 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1449 }
1450 }else
1451
1452 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001453 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001454 }else
1455
drhdaffd0e2001-04-11 14:28:42 +00001456 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001457 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001458 if( alt==0 ){
1459 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1460 }else{
1461 process_input(p, alt);
1462 fclose(alt);
1463 }
1464 }else
1465
drh75897232000-05-29 14:26:00 +00001466 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1467 struct callback_data data;
1468 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001469 open_db(p);
drh75897232000-05-29 14:26:00 +00001470 memcpy(&data, p, sizeof(data));
1471 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001472 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001473 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001474 int i;
shane7d3846a2008-12-11 02:58:26 +00001475 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00001476 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001477 char *new_argv[2], *new_colv[2];
1478 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1479 " type text,\n"
1480 " name text,\n"
1481 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001482 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001483 " sql text\n"
1484 ")";
1485 new_argv[1] = 0;
1486 new_colv[0] = "sql";
1487 new_colv[1] = 0;
1488 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001489 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001490 char *new_argv[2], *new_colv[2];
1491 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1492 " type text,\n"
1493 " name text,\n"
1494 " tbl_name text,\n"
1495 " rootpage integer,\n"
1496 " sql text\n"
1497 ")";
1498 new_argv[1] = 0;
1499 new_colv[0] = "sql";
1500 new_colv[1] = 0;
1501 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001502 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001503 zShellStatic = azArg[1];
1504 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001505 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00001506 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
1507 " FROM sqlite_master UNION ALL"
1508 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001509 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001510 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001511 callback, &data, &zErrMsg);
1512 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001513 }
drh75897232000-05-29 14:26:00 +00001514 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001515 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001516 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00001517 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
1518 " FROM sqlite_master UNION ALL"
1519 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001520 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001521 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001522 callback, &data, &zErrMsg
1523 );
drh75897232000-05-29 14:26:00 +00001524 }
drh75897232000-05-29 14:26:00 +00001525 if( zErrMsg ){
1526 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001527 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001528 }
1529 }else
1530
1531 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001532 sqlite3_snprintf(sizeof(p->separator), p->separator,
1533 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001534 }else
1535
persicom7e2dfdd2002-04-18 02:46:52 +00001536 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1537 int i;
1538 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001539 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001540 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001541 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001542 fprintf(p->out,"%9.9s: ", "nullvalue");
1543 output_c_string(p->out, p->nullvalue);
1544 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001545 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00001546 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001547 fprintf(p->out,"%9.9s: ", "separator");
1548 output_c_string(p->out, p->separator);
1549 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001550 fprintf(p->out,"%9.9s: ","width");
1551 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001552 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001553 }
drhfeac5f82004-08-01 00:10:45 +00001554 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001555 }else
1556
drh2dfbbca2000-07-28 14:32:48 +00001557 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001558 char **azResult;
1559 int nRow, rc;
1560 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001561 open_db(p);
drha50da102000-08-08 20:19:09 +00001562 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001563 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001564 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001565 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001566 "UNION ALL "
1567 "SELECT name FROM sqlite_temp_master "
1568 "WHERE type IN ('table','view') "
1569 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001570 &azResult, &nRow, 0, &zErrMsg
1571 );
drha50da102000-08-08 20:19:09 +00001572 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001573 zShellStatic = azArg[1];
1574 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001575 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001576 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001577 "UNION ALL "
1578 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001579 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001580 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001581 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001582 );
danielk1977bc6ada42004-06-30 08:20:16 +00001583 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001584 }
drh75897232000-05-29 14:26:00 +00001585 if( zErrMsg ){
1586 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001587 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001588 }
drhe3710332000-09-29 13:30:53 +00001589 if( rc==SQLITE_OK ){
1590 int len, maxlen = 0;
1591 int i, j;
1592 int nPrintCol, nPrintRow;
1593 for(i=1; i<=nRow; i++){
1594 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00001595 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00001596 if( len>maxlen ) maxlen = len;
1597 }
1598 nPrintCol = 80/(maxlen+2);
1599 if( nPrintCol<1 ) nPrintCol = 1;
1600 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1601 for(i=0; i<nPrintRow; i++){
1602 for(j=i+1; j<=nRow; j+=nPrintRow){
1603 char *zSp = j<=nPrintRow ? "" : " ";
1604 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1605 }
1606 printf("\n");
1607 }
drh47ad6842006-11-08 12:25:42 +00001608 }else{
1609 rc = 1;
drhe3710332000-09-29 13:30:53 +00001610 }
danielk19776f8a5032004-05-10 10:34:51 +00001611 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001612 }else
1613
drh3b1a9882007-11-02 12:53:03 +00001614 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001615 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001616 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001617 }else
drh3b1a9882007-11-02 12:53:03 +00001618
1619#if HAS_TIMER
1620 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
1621 enableTimer = booleanValue(azArg[1]);
1622 }else
1623#endif
drh2dfbbca2000-07-28 14:32:48 +00001624
drh75897232000-05-29 14:26:00 +00001625 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1626 int j;
drh43617e92006-03-06 20:55:46 +00001627 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001628 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1629 p->colWidth[j-1] = atoi(azArg[j]);
1630 }
1631 }else
1632
drh3b1a9882007-11-02 12:53:03 +00001633
drh75897232000-05-29 14:26:00 +00001634 {
drh67505e72002-04-19 12:34:06 +00001635 fprintf(stderr, "unknown command or invalid arguments: "
1636 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001637 }
drh67505e72002-04-19 12:34:06 +00001638
1639 return rc;
drh75897232000-05-29 14:26:00 +00001640}
1641
drh67505e72002-04-19 12:34:06 +00001642/*
drh91a66392007-09-07 01:12:32 +00001643** Return TRUE if a semicolon occurs anywhere in the first N characters
1644** of string z[].
drh324ccef2003-02-05 14:06:20 +00001645*/
drh91a66392007-09-07 01:12:32 +00001646static int _contains_semicolon(const char *z, int N){
1647 int i;
1648 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
1649 return 0;
drh324ccef2003-02-05 14:06:20 +00001650}
1651
1652/*
drh70c7a4b2003-04-26 03:03:06 +00001653** Test to see if a line consists entirely of whitespace.
1654*/
1655static int _all_whitespace(const char *z){
1656 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001657 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001658 if( *z=='/' && z[1]=='*' ){
1659 z += 2;
1660 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1661 if( *z==0 ) return 0;
1662 z++;
1663 continue;
1664 }
1665 if( *z=='-' && z[1]=='-' ){
1666 z += 2;
1667 while( *z && *z!='\n' ){ z++; }
1668 if( *z==0 ) return 1;
1669 continue;
1670 }
1671 return 0;
1672 }
1673 return 1;
1674}
1675
1676/*
drha9b17162003-04-29 18:01:28 +00001677** Return TRUE if the line typed in is an SQL command terminator other
1678** than a semi-colon. The SQL Server style "go" command is understood
1679** as is the Oracle "/".
1680*/
1681static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001682 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00001683 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
1684 return 1; /* Oracle */
1685 }
drhc8d74412004-08-31 23:41:26 +00001686 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1687 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001688 return 1; /* SQL Server */
1689 }
1690 return 0;
1691}
1692
1693/*
drh233a5312008-12-18 22:25:13 +00001694** Return true if zSql is a complete SQL statement. Return false if it
1695** ends in the middle of a string literal or C-style comment.
1696*/
1697static int _is_complete(char *zSql, int nSql){
1698 int rc;
1699 if( zSql==0 ) return 1;
1700 zSql[nSql] = ';';
1701 zSql[nSql+1] = 0;
1702 rc = sqlite3_complete(zSql);
1703 zSql[nSql] = 0;
1704 return rc;
1705}
1706
1707/*
drh67505e72002-04-19 12:34:06 +00001708** Read input from *in and process it. If *in==0 then input
1709** is interactive - the user is typing it it. Otherwise, input
1710** is coming from a file or device. A prompt is issued and history
1711** is saved only if input is interactive. An interrupt signal will
1712** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001713**
1714** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001715*/
drhc28490c2006-10-26 14:25:58 +00001716static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001717 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001718 char *zSql = 0;
1719 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00001720 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00001721 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001722 int rc;
1723 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001724 int lineno = 0;
1725 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001726
1727 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1728 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001729 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001730 zLine = one_input_line(zSql, in);
1731 if( zLine==0 ){
1732 break; /* We have reached EOF */
1733 }
drh67505e72002-04-19 12:34:06 +00001734 if( seenInterrupt ){
1735 if( in!=0 ) break;
1736 seenInterrupt = 0;
1737 }
drhc28490c2006-10-26 14:25:58 +00001738 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001739 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001740 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001741 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001742 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001743 if( rc==2 ){
1744 break;
1745 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001746 errCnt++;
1747 }
drhdaffd0e2001-04-11 14:28:42 +00001748 continue;
1749 }
drh233a5312008-12-18 22:25:13 +00001750 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00001751 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001752 }
drh91a66392007-09-07 01:12:32 +00001753 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00001754 if( zSql==0 ){
1755 int i;
drh4c755c02004-08-08 20:22:17 +00001756 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001757 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001758 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00001759 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00001760 if( zSql==0 ){
1761 fprintf(stderr, "out of memory\n");
1762 exit(1);
1763 }
drh5bb3eb92007-05-04 13:15:55 +00001764 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001765 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001766 }
1767 }else{
drh4f21c4a2008-12-10 22:15:00 +00001768 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00001769 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00001770 if( zSql==0 ){
1771 fprintf(stderr,"%s: out of memory!\n", Argv0);
1772 exit(1);
1773 }
drh5bb3eb92007-05-04 13:15:55 +00001774 zSql[nSql++] = '\n';
1775 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001776 nSql += len;
1777 }
drh91a66392007-09-07 01:12:32 +00001778 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1779 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001780 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001781 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00001782 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00001783 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00001784 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00001785 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001786 char zPrefix[100];
1787 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001788 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1789 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001790 }else{
drh5bb3eb92007-05-04 13:15:55 +00001791 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001792 }
drh7f953e22002-07-13 17:33:45 +00001793 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001794 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001795 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001796 zErrMsg = 0;
1797 }else{
drhc28490c2006-10-26 14:25:58 +00001798 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001799 }
drhc49f44e2006-10-26 18:15:42 +00001800 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001801 }
1802 free(zSql);
1803 zSql = 0;
1804 nSql = 0;
1805 }
1806 }
1807 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00001808 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001809 free(zSql);
1810 }
danielk19772ac27622007-07-03 05:31:16 +00001811 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001812 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001813}
1814
drh67505e72002-04-19 12:34:06 +00001815/*
1816** Return a pathname which is the user's home directory. A
1817** 0 return indicates an error of some kind. Space to hold the
1818** resulting string is obtained from malloc(). The calling
1819** function should free the result.
1820*/
1821static char *find_home_dir(void){
1822 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001823
chw97185482008-11-17 08:05:31 +00001824#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00001825 struct passwd *pwent;
1826 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001827 if( (pwent=getpwuid(uid)) != NULL) {
1828 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001829 }
1830#endif
1831
chw65d3c132007-11-12 21:09:10 +00001832#if defined(_WIN32_WCE)
1833 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
1834 */
1835 home_dir = strdup("/");
1836#else
1837
drh164a1b62006-08-19 11:15:20 +00001838#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1839 if (!home_dir) {
1840 home_dir = getenv("USERPROFILE");
1841 }
1842#endif
1843
drh67505e72002-04-19 12:34:06 +00001844 if (!home_dir) {
1845 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001846 }
1847
drhcdb36b72006-06-12 12:57:45 +00001848#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001849 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001850 char *zDrive, *zPath;
1851 int n;
1852 zDrive = getenv("HOMEDRIVE");
1853 zPath = getenv("HOMEPATH");
1854 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00001855 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00001856 home_dir = malloc( n );
1857 if( home_dir==0 ) return 0;
1858 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1859 return home_dir;
1860 }
1861 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001862 }
1863#endif
1864
chw65d3c132007-11-12 21:09:10 +00001865#endif /* !_WIN32_WCE */
1866
drh67505e72002-04-19 12:34:06 +00001867 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00001868 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00001869 char *z = malloc( n );
1870 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001871 home_dir = z;
1872 }
drhe98d4fa2002-04-21 19:06:22 +00001873
drh67505e72002-04-19 12:34:06 +00001874 return home_dir;
1875}
1876
1877/*
1878** Read input from the file given by sqliterc_override. Or if that
1879** parameter is NULL, take input from ~/.sqliterc
1880*/
drh22fbcb82004-02-01 01:22:50 +00001881static void process_sqliterc(
1882 struct callback_data *p, /* Configuration data */
1883 const char *sqliterc_override /* Name of config file. NULL to use default */
1884){
persicom7e2dfdd2002-04-18 02:46:52 +00001885 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001886 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001887 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001888 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001889 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001890
1891 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001892 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001893 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00001894#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00001895 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00001896#endif
drhe98d4fa2002-04-21 19:06:22 +00001897 return;
1898 }
drh4f21c4a2008-12-10 22:15:00 +00001899 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00001900 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001901 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001902 fprintf(stderr,"%s: out of memory!\n", Argv0);
1903 exit(1);
1904 }
drha959ac42007-06-20 13:10:00 +00001905 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001906 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001907 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001908 }
drha1f9b5e2004-02-14 16:31:02 +00001909 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001910 if( in ){
drhc28490c2006-10-26 14:25:58 +00001911 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00001912 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00001913 }
persicom7e2dfdd2002-04-18 02:46:52 +00001914 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001915 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001916 }
drh43617e92006-03-06 20:55:46 +00001917 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001918 return;
1919}
1920
drh67505e72002-04-19 12:34:06 +00001921/*
drhe1e38c42003-05-04 18:30:59 +00001922** Show available command line options
1923*/
1924static const char zOptions[] =
1925 " -init filename read/process named file\n"
1926 " -echo print commands before execution\n"
1927 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001928 " -bail stop after hitting an error\n"
1929 " -interactive force interactive I/O\n"
1930 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001931 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001932 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001933 " -html set output mode to HTML\n"
1934 " -line set output mode to 'line'\n"
1935 " -list set output mode to 'list'\n"
1936 " -separator 'x' set output field separator (|)\n"
1937 " -nullvalue 'text' set text string for NULL values\n"
1938 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001939;
1940static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001941 fprintf(stderr,
1942 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1943 "FILENAME is the name of an SQLite database. A new database is created\n"
1944 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001945 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001946 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001947 }else{
1948 fprintf(stderr, "Use the -help option for additional information\n");
1949 }
1950 exit(1);
1951}
1952
1953/*
drh67505e72002-04-19 12:34:06 +00001954** Initialize the state information in data
1955*/
drh0850b532006-01-31 19:31:43 +00001956static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001957 memset(data, 0, sizeof(*data));
1958 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001959 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001960 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001961 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1962 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001963}
1964
drh75897232000-05-29 14:26:00 +00001965int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001966 char *zErrMsg = 0;
1967 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001968 const char *zInitFile = 0;
1969 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001970 int i;
drhc28490c2006-10-26 14:25:58 +00001971 int rc = 0;
drh75897232000-05-29 14:26:00 +00001972
drhdaffd0e2001-04-11 14:28:42 +00001973 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001974 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001975 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001976
drh44c2eb12003-04-30 11:38:26 +00001977 /* Make sure we have a valid signal handler early, before anything
1978 ** else is done.
1979 */
drh4c504392000-10-16 22:06:40 +00001980#ifdef SIGINT
1981 signal(SIGINT, interrupt_handler);
1982#endif
drh44c2eb12003-04-30 11:38:26 +00001983
drh22fbcb82004-02-01 01:22:50 +00001984 /* Do an initial pass through the command-line argument to locate
1985 ** the name of the database file, the name of the initialization file,
1986 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001987 */
drh22fbcb82004-02-01 01:22:50 +00001988 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001989 char *z;
drh44c2eb12003-04-30 11:38:26 +00001990 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001991 z = argv[i];
1992 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001993 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1994 i++;
drh22fbcb82004-02-01 01:22:50 +00001995 }else if( strcmp(argv[i],"-init")==0 ){
1996 i++;
1997 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001998 }
1999 }
drh22fbcb82004-02-01 01:22:50 +00002000 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002001#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002002 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2003#else
drh22fbcb82004-02-01 01:22:50 +00002004 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002005#endif
drh22fbcb82004-02-01 01:22:50 +00002006 }else{
danielk197703aded42004-11-22 05:26:27 +00002007#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002008 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002009#else
2010 data.zDbFilename = 0;
2011#endif
drh22fbcb82004-02-01 01:22:50 +00002012 }
2013 if( i<argc ){
2014 zFirstCmd = argv[i++];
2015 }
drh44c2eb12003-04-30 11:38:26 +00002016 data.out = stdout;
2017
drh01b41712005-08-29 23:06:23 +00002018#ifdef SQLITE_OMIT_MEMORYDB
2019 if( data.zDbFilename==0 ){
2020 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
2021 exit(1);
2022 }
2023#endif
2024
drh44c2eb12003-04-30 11:38:26 +00002025 /* Go ahead and open the database file if it already exists. If the
2026 ** file does not exist, delay opening it. This prevents empty database
2027 ** files from being created if a user mistypes the database name argument
2028 ** to the sqlite command-line tool.
2029 */
drhc8d74412004-08-31 23:41:26 +00002030 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002031 open_db(&data);
2032 }
2033
drh22fbcb82004-02-01 01:22:50 +00002034 /* Process the initialization file if there is one. If no -init option
2035 ** is given on the command line, look for a file named ~/.sqliterc and
2036 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002037 */
drh22fbcb82004-02-01 01:22:50 +00002038 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00002039
drh22fbcb82004-02-01 01:22:50 +00002040 /* Make a second pass through the command-line argument and set
2041 ** options. This second pass is delayed until after the initialization
2042 ** file is processed so that the command-line arguments will override
2043 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002044 */
drh22fbcb82004-02-01 01:22:50 +00002045 for(i=1; i<argc && argv[i][0]=='-'; i++){
2046 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002047 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002048 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002049 i++;
2050 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002051 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002052 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002053 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002054 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002055 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002056 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002057 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002058 }else if( strcmp(z,"-csv")==0 ){
2059 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002060 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002061 }else if( strcmp(z,"-separator")==0 ){
2062 i++;
drh5bb3eb92007-05-04 13:15:55 +00002063 sqlite3_snprintf(sizeof(data.separator), data.separator,
2064 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002065 }else if( strcmp(z,"-nullvalue")==0 ){
2066 i++;
drh5bb3eb92007-05-04 13:15:55 +00002067 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2068 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002069 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002070 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002071 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002072 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002073 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002074 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002075 }else if( strcmp(z,"-bail")==0 ){
2076 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002077 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002078 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002079 return 0;
drhc28490c2006-10-26 14:25:58 +00002080 }else if( strcmp(z,"-interactive")==0 ){
2081 stdin_is_interactive = 1;
2082 }else if( strcmp(z,"-batch")==0 ){
2083 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002084 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002085 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002086 }else{
drh22fbcb82004-02-01 01:22:50 +00002087 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002088 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002089 return 1;
2090 }
2091 }
drh44c2eb12003-04-30 11:38:26 +00002092
drh22fbcb82004-02-01 01:22:50 +00002093 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002094 /* Run just the command that follows the database name
2095 */
drh22fbcb82004-02-01 01:22:50 +00002096 if( zFirstCmd[0]=='.' ){
2097 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002098 exit(0);
2099 }else{
2100 int rc;
drh44c2eb12003-04-30 11:38:26 +00002101 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00002102 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00002103 if( rc!=0 && zErrMsg!=0 ){
2104 fprintf(stderr,"SQL error: %s\n", zErrMsg);
2105 exit(1);
2106 }
drh75897232000-05-29 14:26:00 +00002107 }
2108 }else{
drh44c2eb12003-04-30 11:38:26 +00002109 /* Run commands received from standard input
2110 */
drhc28490c2006-10-26 14:25:58 +00002111 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002112 char *zHome;
2113 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002114 int nHistory;
drh75897232000-05-29 14:26:00 +00002115 printf(
drhb217a572000-08-22 13:40:18 +00002116 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002117 "Enter \".help\" for instructions\n"
2118 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002119 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002120 );
drh67505e72002-04-19 12:34:06 +00002121 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002122 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002123 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002124 if( (zHistory = malloc(nHistory))!=0 ){
2125 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2126 }
drh67505e72002-04-19 12:34:06 +00002127 }
danielk19774af00c62005-01-23 23:43:21 +00002128#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002129 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002130#endif
drhc28490c2006-10-26 14:25:58 +00002131 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002132 if( zHistory ){
2133 stifle_history(100);
2134 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002135 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002136 }
adamd0a3daa32006-07-28 20:16:14 +00002137 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002138 }else{
drhc28490c2006-10-26 14:25:58 +00002139 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002140 }
2141 }
drh33048c02001-10-01 14:29:22 +00002142 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002143 if( db ){
2144 if( sqlite3_close(db)!=SQLITE_OK ){
2145 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2146 }
2147 }
drhc28490c2006-10-26 14:25:58 +00002148 return rc;
drh75897232000-05-29 14:26:00 +00002149}