blob: 9c1babcdb8ab893e7e82bebfdd08a1cd172f0214 [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**
drhc85375d2007-12-18 15:41:44 +000015** $Id: shell.c,v 1.171 2007/12/18 15:41:44 drh Exp $
drh75897232000-05-29 14:26:00 +000016*/
17#include <stdlib.h>
18#include <string.h>
19#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000020#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000021#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000022#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000023#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000024
drh454ad582007-11-26 22:54:27 +000025#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000026# include <signal.h>
drhdd45df82002-04-18 12:39:03 +000027# include <pwd.h>
28# include <unistd.h>
29# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000030#endif
drh75897232000-05-29 14:26:00 +000031
drhcdb36b72006-06-12 12:57:45 +000032#ifdef __OS2__
33# include <unistd.h>
34#endif
35
drh16e59552000-07-31 11:57:37 +000036#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000037# include <readline/readline.h>
38# include <readline/history.h>
39#else
drh9347b202003-07-18 01:30:59 +000040# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000041# define add_history(X)
drh67505e72002-04-19 12:34:06 +000042# define read_history(X)
43# define write_history(X)
44# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000045#endif
46
adamd2e8464a2006-09-06 21:39:40 +000047#if defined(_WIN32) || defined(WIN32)
48# include <io.h>
49#else
drh4328c8b2003-04-26 02:50:11 +000050/* Make sure isatty() has a prototype.
51*/
52extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000053#endif
drh4328c8b2003-04-26 02:50:11 +000054
chw65d3c132007-11-12 21:09:10 +000055#if defined(_WIN32_WCE)
56/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
57 * thus we always assume that we have a console. That can be
58 * overridden with the -batch command line option.
59 */
60#define isatty(x) 1
61#endif
62
drh3b1a9882007-11-02 12:53:03 +000063#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
64#include <sys/time.h>
65#include <sys/resource.h>
66
67/* Saved resource information for the beginning of an operation */
68static struct rusage sBegin;
69
70/* True if the timer is enabled */
71static int enableTimer = 0;
72
73/*
74** Begin timing an operation
75*/
76static void beginTimer(void){
77 if( enableTimer ){
78 getrusage(RUSAGE_SELF, &sBegin);
79 }
80}
81
82/* Return the difference of two time_structs in microseconds */
83static int timeDiff(struct timeval *pStart, struct timeval *pEnd){
84 return (pEnd->tv_usec - pStart->tv_usec) +
85 1000000*(pEnd->tv_sec - pStart->tv_sec);
86}
87
88/*
89** Print the timing results.
90*/
91static void endTimer(void){
92 if( enableTimer ){
93 struct rusage sEnd;
94 getrusage(RUSAGE_SELF, &sEnd);
95 printf("CPU Time: user %f sys %f\n",
96 0.000001*timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
97 0.000001*timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
98 }
99}
100#define BEGIN_TIMER beginTimer()
101#define END_TIMER endTimer()
102#define HAS_TIMER 1
103#else
104#define BEGIN_TIMER
105#define END_TIMER
106#define HAS_TIMER 0
107#endif
108
109
drh75897232000-05-29 14:26:00 +0000110/*
drhc49f44e2006-10-26 18:15:42 +0000111** If the following flag is set, then command execution stops
112** at an error if we are not interactive.
113*/
114static int bail_on_error = 0;
115
116/*
drhc28490c2006-10-26 14:25:58 +0000117** Threat stdin as an interactive input if the following variable
118** is true. Otherwise, assume stdin is connected to a file or pipe.
119*/
120static int stdin_is_interactive = 1;
121
122/*
drh4c504392000-10-16 22:06:40 +0000123** The following is the open SQLite database. We make a pointer
124** to this database a static variable so that it can be accessed
125** by the SIGINT handler to interrupt database processing.
126*/
danielk197792f9a1b2004-06-19 09:08:16 +0000127static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000128
129/*
drh67505e72002-04-19 12:34:06 +0000130** True if an interrupt (Control-C) has been received.
131*/
drh43617e92006-03-06 20:55:46 +0000132static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000133
134/*
persicom7e2dfdd2002-04-18 02:46:52 +0000135** This is the name of our program. It is set in main(), used
136** in a number of other places, mostly for error messages.
137*/
138static char *Argv0;
139
140/*
141** Prompt strings. Initialized in main. Settable with
142** .prompt main continue
143*/
144static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
145static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
146
drhb0603412007-02-28 04:47:26 +0000147/*
148** Write I/O traces to the following stream.
149*/
rsebe0a9092007-07-30 18:24:38 +0000150#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000151static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000152#endif
drhb0603412007-02-28 04:47:26 +0000153
154/*
155** This routine works like printf in that its first argument is a
156** format string and subsequent arguments are values to be substituted
157** in place of % fields. The result of formatting this string
158** is written to iotrace.
159*/
rsebe0a9092007-07-30 18:24:38 +0000160#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000161static void iotracePrintf(const char *zFormat, ...){
162 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000163 char *z;
drhb0603412007-02-28 04:47:26 +0000164 if( iotrace==0 ) return;
165 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000166 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000167 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000168 fprintf(iotrace, "%s", z);
169 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000170}
rsebe0a9092007-07-30 18:24:38 +0000171#endif
drhb0603412007-02-28 04:47:26 +0000172
drh44c2eb12003-04-30 11:38:26 +0000173
persicom7e2dfdd2002-04-18 02:46:52 +0000174/*
drh83965662003-04-17 02:54:13 +0000175** Determines if a string is a number of not.
176*/
danielk19772e588c72005-12-09 14:25:08 +0000177static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000178 if( *z=='-' || *z=='+' ) z++;
179 if( !isdigit(*z) ){
180 return 0;
181 }
182 z++;
183 if( realnum ) *realnum = 0;
184 while( isdigit(*z) ){ z++; }
185 if( *z=='.' ){
186 z++;
187 if( !isdigit(*z) ) return 0;
188 while( isdigit(*z) ){ z++; }
189 if( realnum ) *realnum = 1;
190 }
191 if( *z=='e' || *z=='E' ){
192 z++;
193 if( *z=='+' || *z=='-' ) z++;
194 if( !isdigit(*z) ) return 0;
195 while( isdigit(*z) ){ z++; }
196 if( realnum ) *realnum = 1;
197 }
198 return *z==0;
199}
drh83965662003-04-17 02:54:13 +0000200
201/*
danielk1977bc6ada42004-06-30 08:20:16 +0000202** A global char* and an SQL function to access its current value
203** from within an SQL statement. This program used to use the
204** sqlite_exec_printf() API to substitue a string into an SQL statement.
205** The correct way to do this with sqlite3 is to use the bind API, but
206** since the shell is built around the callback paradigm it would be a lot
207** of work. Instead just use this hack, which is quite harmless.
208*/
209static const char *zShellStatic = 0;
210static void shellstaticFunc(
211 sqlite3_context *context,
212 int argc,
213 sqlite3_value **argv
214){
215 assert( 0==argc );
216 assert( zShellStatic );
217 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
218}
219
220
221/*
drhfeac5f82004-08-01 00:10:45 +0000222** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000223** the text in memory obtained from malloc() and returns a pointer
224** to the text. NULL is returned at end of file, or if malloc()
225** fails.
226**
227** The interface is like "readline" but no command-line editing
228** is done.
229*/
drh9347b202003-07-18 01:30:59 +0000230static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000231 char *zLine;
232 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000233 int n;
234 int eol;
235
236 if( zPrompt && *zPrompt ){
237 printf("%s",zPrompt);
238 fflush(stdout);
239 }
240 nLine = 100;
241 zLine = malloc( nLine );
242 if( zLine==0 ) return 0;
243 n = 0;
244 eol = 0;
245 while( !eol ){
246 if( n+100>nLine ){
247 nLine = nLine*2 + 100;
248 zLine = realloc(zLine, nLine);
249 if( zLine==0 ) return 0;
250 }
drhdaffd0e2001-04-11 14:28:42 +0000251 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000252 if( n==0 ){
253 free(zLine);
254 return 0;
255 }
256 zLine[n] = 0;
257 eol = 1;
258 break;
259 }
260 while( zLine[n] ){ n++; }
261 if( n>0 && zLine[n-1]=='\n' ){
262 n--;
263 zLine[n] = 0;
264 eol = 1;
265 }
266 }
267 zLine = realloc( zLine, n+1 );
268 return zLine;
269}
270
271/*
drhc28490c2006-10-26 14:25:58 +0000272** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000273**
274** zPrior is a string of prior text retrieved. If not the empty
275** string, then issue a continuation prompt.
276*/
drhdaffd0e2001-04-11 14:28:42 +0000277static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000278 char *zPrompt;
279 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000280 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000281 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000282 }
283 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000284 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000285 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000286 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000287 }
288 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000289#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000290 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000291#endif
drh8e7e7a22000-05-30 18:45:23 +0000292 return zResult;
293}
294
persicom7e2dfdd2002-04-18 02:46:52 +0000295struct previous_mode_data {
296 int valid; /* Is there legit data in here? */
297 int mode;
298 int showHeader;
299 int colWidth[100];
300};
drh45e29d82006-11-20 16:21:10 +0000301
drh8e7e7a22000-05-30 18:45:23 +0000302/*
drh75897232000-05-29 14:26:00 +0000303** An pointer to an instance of this structure is passed from
304** the main program to the callback. This is used to communicate
305** state and mode information.
306*/
307struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000308 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000309 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000310 int cnt; /* Number of records displayed so far */
311 FILE *out; /* Write results here */
312 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000313 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000314 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000315 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000316 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000317 int colWidth[100]; /* Requested width of each column when in column mode*/
318 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000319 char nullvalue[20]; /* The text to print when a NULL comes back from
320 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000321 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000322 /* Holds the mode information just before
323 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000324 char outfile[FILENAME_MAX]; /* Filename for *out */
325 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000326};
327
328/*
329** These are the allowed modes.
330*/
drh967e8b72000-06-21 13:59:10 +0000331#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000332#define MODE_Column 1 /* One record per line in neat columns */
333#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000334#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
335#define MODE_Html 4 /* Generate an XHTML table */
336#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000337#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000338#define MODE_Csv 7 /* Quote strings, numbers are plain */
339#define MODE_NUM_OF 8 /* The number of modes (not a mode itself) */
persicom7e2dfdd2002-04-18 02:46:52 +0000340
drh0850b532006-01-31 19:31:43 +0000341static const char *modeDescr[MODE_NUM_OF] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000342 "line",
343 "column",
344 "list",
345 "semi",
346 "html",
drhfeac5f82004-08-01 00:10:45 +0000347 "insert",
348 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000349 "csv",
persicom7e2dfdd2002-04-18 02:46:52 +0000350};
drh75897232000-05-29 14:26:00 +0000351
352/*
353** Number of elements in an array
354*/
355#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
356
357/*
drh28bd4bc2000-06-15 15:57:22 +0000358** Output the given string as a quoted string using SQL quoting conventions.
359*/
360static void output_quoted_string(FILE *out, const char *z){
361 int i;
362 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000363 for(i=0; z[i]; i++){
364 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000365 }
366 if( nSingle==0 ){
367 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000368 }else{
369 fprintf(out,"'");
370 while( *z ){
371 for(i=0; z[i] && z[i]!='\''; i++){}
372 if( i==0 ){
373 fprintf(out,"''");
374 z++;
375 }else if( z[i]=='\'' ){
376 fprintf(out,"%.*s''",i,z);
377 z += i+1;
378 }else{
drhcd7d2732002-02-26 23:24:26 +0000379 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000380 break;
381 }
382 }
drhcd7d2732002-02-26 23:24:26 +0000383 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000384 }
385}
386
387/*
drhfeac5f82004-08-01 00:10:45 +0000388** Output the given string as a quoted according to C or TCL quoting rules.
389*/
390static void output_c_string(FILE *out, const char *z){
391 unsigned int c;
392 fputc('"', out);
393 while( (c = *(z++))!=0 ){
394 if( c=='\\' ){
395 fputc(c, out);
396 fputc(c, out);
397 }else if( c=='\t' ){
398 fputc('\\', out);
399 fputc('t', out);
400 }else if( c=='\n' ){
401 fputc('\\', out);
402 fputc('n', out);
403 }else if( c=='\r' ){
404 fputc('\\', out);
405 fputc('r', out);
406 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000407 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000408 }else{
409 fputc(c, out);
410 }
411 }
412 fputc('"', out);
413}
414
415/*
drhc08a4f12000-06-15 16:49:48 +0000416** Output the given string with characters that are special to
417** HTML escaped.
418*/
419static void output_html_string(FILE *out, const char *z){
420 int i;
421 while( *z ){
422 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
423 if( i>0 ){
424 fprintf(out,"%.*s",i,z);
425 }
426 if( z[i]=='<' ){
427 fprintf(out,"&lt;");
428 }else if( z[i]=='&' ){
429 fprintf(out,"&amp;");
430 }else{
431 break;
432 }
433 z += i + 1;
434 }
435}
436
437/*
drhc49f44e2006-10-26 18:15:42 +0000438** If a field contains any character identified by a 1 in the following
439** array, then the string must be quoted for CSV.
440*/
441static const char needCsvQuote[] = {
442 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
443 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
444 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
445 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
446 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
447 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
448 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
449 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
450 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
451 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
452 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
453 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
454 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
455 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
456 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
457 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
458};
459
460/*
drh8e64d1c2004-10-07 00:32:39 +0000461** Output a single term of CSV. Actually, p->separator is used for
462** the separator, which may or may not be a comma. p->nullvalue is
463** the null value. Strings are quoted using ANSI-C rules. Numbers
464** appear outside of quotes.
465*/
466static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000467 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000468 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000469 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000470 }else{
drhc49f44e2006-10-26 18:15:42 +0000471 int i;
drhc85375d2007-12-18 15:41:44 +0000472 int nSep = strlen(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000473 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000474 if( needCsvQuote[((unsigned char*)z)[i]]
475 || (z[i]==p->separator[0] &&
476 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000477 i = 0;
478 break;
479 }
480 }
481 if( i==0 ){
482 putc('"', out);
483 for(i=0; z[i]; i++){
484 if( z[i]=='"' ) putc('"', out);
485 putc(z[i], out);
486 }
487 putc('"', out);
488 }else{
489 fprintf(out, "%s", z);
490 }
drh8e64d1c2004-10-07 00:32:39 +0000491 }
492 if( bSep ){
493 fprintf(p->out, p->separator);
494 }
495}
496
danielk19774af00c62005-01-23 23:43:21 +0000497#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000498/*
drh4c504392000-10-16 22:06:40 +0000499** This routine runs when the user presses Ctrl-C
500*/
501static void interrupt_handler(int NotUsed){
drh67505e72002-04-19 12:34:06 +0000502 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000503 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000504}
danielk19774af00c62005-01-23 23:43:21 +0000505#endif
drh4c504392000-10-16 22:06:40 +0000506
507/*
drh75897232000-05-29 14:26:00 +0000508** This is the callback routine that the SQLite library
509** invokes for each row of a query result.
510*/
511static int callback(void *pArg, int nArg, char **azArg, char **azCol){
512 int i;
513 struct callback_data *p = (struct callback_data*)pArg;
514 switch( p->mode ){
515 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000516 int w = 5;
drh6a535342001-10-19 16:44:56 +0000517 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000518 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000519 int len = strlen(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000520 if( len>w ) w = len;
521 }
drh75897232000-05-29 14:26:00 +0000522 if( p->cnt++>0 ) fprintf(p->out,"\n");
523 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000524 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000525 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000526 }
527 break;
528 }
529 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000530 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000531 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000532 int w, n;
533 if( i<ArraySize(p->colWidth) ){
drh75897232000-05-29 14:26:00 +0000534 w = p->colWidth[i];
535 }else{
drha0c66f52000-07-29 13:20:21 +0000536 w = 0;
drh75897232000-05-29 14:26:00 +0000537 }
drha0c66f52000-07-29 13:20:21 +0000538 if( w<=0 ){
drhff6e9112000-08-28 16:21:58 +0000539 w = strlen(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000540 if( w<10 ) w = 10;
persicom7e2dfdd2002-04-18 02:46:52 +0000541 n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000542 if( w<n ) w = n;
543 }
544 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000545 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000546 }
547 if( p->showHeader ){
548 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
549 }
550 }
551 if( p->showHeader ){
552 for(i=0; i<nArg; i++){
553 int w;
554 if( i<ArraySize(p->actualWidth) ){
555 w = p->actualWidth[i];
556 }else{
557 w = 10;
558 }
559 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
560 "----------------------------------------------------------",
561 i==nArg-1 ? "\n": " ");
562 }
drh75897232000-05-29 14:26:00 +0000563 }
564 }
drh6a535342001-10-19 16:44:56 +0000565 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000566 for(i=0; i<nArg; i++){
567 int w;
drha0c66f52000-07-29 13:20:21 +0000568 if( i<ArraySize(p->actualWidth) ){
569 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000570 }else{
571 w = 10;
572 }
drhc61053b2000-06-04 12:58:36 +0000573 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000574 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000575 }
576 break;
577 }
drhe3710332000-09-29 13:30:53 +0000578 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000579 case MODE_List: {
580 if( p->cnt++==0 && p->showHeader ){
581 for(i=0; i<nArg; i++){
582 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
583 }
584 }
drh6a535342001-10-19 16:44:56 +0000585 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000586 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000587 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000588 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000589 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000590 if( i<nArg-1 ){
591 fprintf(p->out, "%s", p->separator);
592 }else if( p->mode==MODE_Semi ){
593 fprintf(p->out, ";\n");
594 }else{
595 fprintf(p->out, "\n");
596 }
drh75897232000-05-29 14:26:00 +0000597 }
598 break;
599 }
drh1e5d0e92000-05-31 23:33:17 +0000600 case MODE_Html: {
601 if( p->cnt++==0 && p->showHeader ){
602 fprintf(p->out,"<TR>");
603 for(i=0; i<nArg; i++){
604 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
605 }
606 fprintf(p->out,"</TR>\n");
607 }
drh6a535342001-10-19 16:44:56 +0000608 if( azArg==0 ) break;
drh28bd4bc2000-06-15 15:57:22 +0000609 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000610 for(i=0; i<nArg; i++){
drhc08a4f12000-06-15 16:49:48 +0000611 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000612 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
drhc08a4f12000-06-15 16:49:48 +0000613 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000614 }
drh7d686b22002-11-11 13:56:47 +0000615 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000616 break;
617 }
drhfeac5f82004-08-01 00:10:45 +0000618 case MODE_Tcl: {
619 if( p->cnt++==0 && p->showHeader ){
620 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000621 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000622 fprintf(p->out, "%s", p->separator);
623 }
624 fprintf(p->out,"\n");
625 }
626 if( azArg==0 ) break;
627 for(i=0; i<nArg; i++){
628 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
629 fprintf(p->out, "%s", p->separator);
630 }
631 fprintf(p->out,"\n");
632 break;
633 }
drh8e64d1c2004-10-07 00:32:39 +0000634 case MODE_Csv: {
635 if( p->cnt++==0 && p->showHeader ){
636 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000637 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000638 }
639 fprintf(p->out,"\n");
640 }
641 if( azArg==0 ) break;
642 for(i=0; i<nArg; i++){
643 output_csv(p, azArg[i], i<nArg-1);
644 }
645 fprintf(p->out,"\n");
646 break;
647 }
drh28bd4bc2000-06-15 15:57:22 +0000648 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000649 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000650 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000651 for(i=0; i<nArg; i++){
652 char *zSep = i>0 ? ",": "";
653 if( azArg[i]==0 ){
654 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000655 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000656 fprintf(p->out,"%s%s",zSep, azArg[i]);
657 }else{
658 if( zSep[0] ) fprintf(p->out,"%s",zSep);
659 output_quoted_string(p->out, azArg[i]);
660 }
661 }
662 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000663 break;
drh28bd4bc2000-06-15 15:57:22 +0000664 }
persicom1d0b8722002-04-18 02:53:04 +0000665 }
drh75897232000-05-29 14:26:00 +0000666 return 0;
667}
668
669/*
drh33048c02001-10-01 14:29:22 +0000670** Set the destination table field of the callback_data structure to
671** the name of the table given. Escape any quote characters in the
672** table name.
673*/
674static void set_table_name(struct callback_data *p, const char *zName){
675 int i, n;
676 int needQuote;
677 char *z;
678
679 if( p->zDestTable ){
680 free(p->zDestTable);
681 p->zDestTable = 0;
682 }
683 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000684 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000685 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000686 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000687 needQuote = 1;
688 if( zName[i]=='\'' ) n++;
689 }
690 }
691 if( needQuote ) n += 2;
692 z = p->zDestTable = malloc( n+1 );
693 if( z==0 ){
694 fprintf(stderr,"Out of memory!\n");
695 exit(1);
696 }
697 n = 0;
698 if( needQuote ) z[n++] = '\'';
699 for(i=0; zName[i]; i++){
700 z[n++] = zName[i];
701 if( zName[i]=='\'' ) z[n++] = '\'';
702 }
703 if( needQuote ) z[n++] = '\'';
704 z[n] = 0;
705}
706
danielk19772a02e332004-06-05 08:04:36 +0000707/* zIn is either a pointer to a NULL-terminated string in memory obtained
708** from malloc(), or a NULL pointer. The string pointed to by zAppend is
709** added to zIn, and the result returned in memory obtained from malloc().
710** zIn, if it was not NULL, is freed.
711**
712** If the third argument, quote, is not '\0', then it is used as a
713** quote character for zAppend.
714*/
drhc28490c2006-10-26 14:25:58 +0000715static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000716 int len;
717 int i;
718 int nAppend = strlen(zAppend);
719 int nIn = (zIn?strlen(zIn):0);
720
721 len = nAppend+nIn+1;
722 if( quote ){
723 len += 2;
724 for(i=0; i<nAppend; i++){
725 if( zAppend[i]==quote ) len++;
726 }
727 }
728
729 zIn = (char *)realloc(zIn, len);
730 if( !zIn ){
731 return 0;
732 }
733
734 if( quote ){
735 char *zCsr = &zIn[nIn];
736 *zCsr++ = quote;
737 for(i=0; i<nAppend; i++){
738 *zCsr++ = zAppend[i];
739 if( zAppend[i]==quote ) *zCsr++ = quote;
740 }
741 *zCsr++ = quote;
742 *zCsr++ = '\0';
743 assert( (zCsr-zIn)==len );
744 }else{
745 memcpy(&zIn[nIn], zAppend, nAppend);
746 zIn[len-1] = '\0';
747 }
748
749 return zIn;
750}
751
drhdd3d4592004-08-30 01:54:05 +0000752
753/*
754** Execute a query statement that has a single result column. Print
755** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000756**
757** This is used, for example, to show the schema of the database by
758** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000759*/
760static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
761 sqlite3_stmt *pSelect;
762 int rc;
763 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
764 if( rc!=SQLITE_OK || !pSelect ){
765 return rc;
766 }
767 rc = sqlite3_step(pSelect);
768 while( rc==SQLITE_ROW ){
769 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
770 rc = sqlite3_step(pSelect);
771 }
772 return sqlite3_finalize(pSelect);
773}
774
775
drh33048c02001-10-01 14:29:22 +0000776/*
drh4c653a02000-06-07 01:27:47 +0000777** This is a different callback routine used for dumping the database.
778** Each row received by this callback consists of a table name,
779** the table type ("index" or "table") and SQL to create the table.
780** This routine should print text sufficient to recreate the table.
781*/
782static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000783 int rc;
784 const char *zTable;
785 const char *zType;
786 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000787 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000788
drh4c653a02000-06-07 01:27:47 +0000789 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000790 zTable = azArg[0];
791 zType = azArg[1];
792 zSql = azArg[2];
793
drh00b950d2005-09-11 02:03:03 +0000794 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000795 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000796 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
797 fprintf(p->out, "ANALYZE sqlite_master;\n");
798 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
799 return 0;
drh45e29d82006-11-20 16:21:10 +0000800 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
801 char *zIns;
802 if( !p->writableSchema ){
803 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
804 p->writableSchema = 1;
805 }
806 zIns = sqlite3_mprintf(
807 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
808 "VALUES('table','%q','%q',0,'%q');",
809 zTable, zTable, zSql);
810 fprintf(p->out, "%s\n", zIns);
811 sqlite3_free(zIns);
812 return 0;
drh00b950d2005-09-11 02:03:03 +0000813 }else{
814 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000815 }
danielk19772a02e332004-06-05 08:04:36 +0000816
817 if( strcmp(zType, "table")==0 ){
818 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000819 char *zSelect = 0;
820 char *zTableInfo = 0;
821 char *zTmp = 0;
822
823 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
824 zTableInfo = appendText(zTableInfo, zTable, '"');
825 zTableInfo = appendText(zTableInfo, ");", 0);
826
827 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
828 if( zTableInfo ) free(zTableInfo);
829 if( rc!=SQLITE_OK || !pTableInfo ){
830 return 1;
831 }
832
833 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
834 zTmp = appendText(zTmp, zTable, '"');
835 if( zTmp ){
836 zSelect = appendText(zSelect, zTmp, '\'');
837 }
838 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
839 rc = sqlite3_step(pTableInfo);
840 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000841 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000842 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000843 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000844 rc = sqlite3_step(pTableInfo);
845 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000846 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000847 }else{
848 zSelect = appendText(zSelect, ") ", 0);
849 }
850 }
851 rc = sqlite3_finalize(pTableInfo);
852 if( rc!=SQLITE_OK ){
853 if( zSelect ) free(zSelect);
854 return 1;
855 }
856 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
857 zSelect = appendText(zSelect, zTable, '"');
858
drhdd3d4592004-08-30 01:54:05 +0000859 rc = run_table_dump_query(p->out, p->db, zSelect);
860 if( rc==SQLITE_CORRUPT ){
861 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
862 rc = run_table_dump_query(p->out, p->db, zSelect);
863 }
danielk19772a02e332004-06-05 08:04:36 +0000864 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000865 }
drh4c653a02000-06-07 01:27:47 +0000866 return 0;
867}
868
869/*
drh45e29d82006-11-20 16:21:10 +0000870** Run zQuery. Use dump_callback() as the callback routine so that
871** the contents of the query are output as SQL statements.
872**
drhdd3d4592004-08-30 01:54:05 +0000873** If we get a SQLITE_CORRUPT error, rerun the query after appending
874** "ORDER BY rowid DESC" to the end.
875*/
876static int run_schema_dump_query(
877 struct callback_data *p,
878 const char *zQuery,
879 char **pzErrMsg
880){
881 int rc;
882 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
883 if( rc==SQLITE_CORRUPT ){
884 char *zQ2;
885 int len = strlen(zQuery);
886 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
887 zQ2 = malloc( len+100 );
888 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000889 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000890 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
891 free(zQ2);
892 }
893 return rc;
894}
895
896/*
drh75897232000-05-29 14:26:00 +0000897** Text of a help message
898*/
persicom1d0b8722002-04-18 02:53:04 +0000899static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000900 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000901 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000902 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000903 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000904 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000905 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000906 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000907 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000908 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000909 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000910#ifdef SQLITE_ENABLE_IOTRACE
911 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
912#endif
drh70df4fe2006-06-13 15:12:21 +0000913#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000914 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000915#endif
danielk19776b77a362005-01-13 11:10:25 +0000916 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000917 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000918 " column Left-aligned columns. (See .width)\n"
919 " html HTML <table> code\n"
920 " insert SQL insert statements for TABLE\n"
921 " line One value per line\n"
922 " list Values delimited by .separator string\n"
923 " tabs Tab-separated values\n"
924 " tcl TCL list elements\n"
925 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000926 ".output FILENAME Send output to FILENAME\n"
927 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000928 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000929 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000930 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000931 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000932 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000933 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000934 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000935 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +0000936#if HAS_TIMER
937 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
938#endif
drh75897232000-05-29 14:26:00 +0000939 ".width NUM NUM ... Set column widths for \"column\" mode\n"
940;
941
drhdaffd0e2001-04-11 14:28:42 +0000942/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000943static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000944
drh75897232000-05-29 14:26:00 +0000945/*
drh44c2eb12003-04-30 11:38:26 +0000946** Make sure the database is open. If it is not, then open it. If
947** the database fails to open, print an error message and exit.
948*/
949static void open_db(struct callback_data *p){
950 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000951 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000952 db = p->db;
danielk1977bc6ada42004-06-30 08:20:16 +0000953 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
954 shellstaticFunc, 0, 0);
danielk197780290862004-05-22 09:21:21 +0000955 if( SQLITE_OK!=sqlite3_errcode(db) ){
956 fprintf(stderr,"Unable to open database \"%s\": %s\n",
957 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000958 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000959 }
drhc2e87a32006-06-27 15:16:14 +0000960#ifndef SQLITE_OMIT_LOAD_EXTENSION
961 sqlite3_enable_load_extension(p->db, 1);
962#endif
drh44c2eb12003-04-30 11:38:26 +0000963 }
964}
965
966/*
drhfeac5f82004-08-01 00:10:45 +0000967** Do C-language style dequoting.
968**
969** \t -> tab
970** \n -> newline
971** \r -> carriage return
972** \NNN -> ascii character NNN in octal
973** \\ -> backslash
974*/
975static void resolve_backslashes(char *z){
976 int i, j, c;
977 for(i=j=0; (c = z[i])!=0; i++, j++){
978 if( c=='\\' ){
979 c = z[++i];
980 if( c=='n' ){
981 c = '\n';
982 }else if( c=='t' ){
983 c = '\t';
984 }else if( c=='r' ){
985 c = '\r';
986 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +0000987 c -= '0';
drhfeac5f82004-08-01 00:10:45 +0000988 if( z[i+1]>='0' && z[i+1]<='7' ){
989 i++;
990 c = (c<<3) + z[i] - '0';
991 if( z[i+1]>='0' && z[i+1]<='7' ){
992 i++;
993 c = (c<<3) + z[i] - '0';
994 }
995 }
996 }
997 }
998 z[j] = c;
999 }
1000 z[j] = 0;
1001}
1002
1003/*
drhc28490c2006-10-26 14:25:58 +00001004** Interpret zArg as a boolean value. Return either 0 or 1.
1005*/
1006static int booleanValue(char *zArg){
1007 int val = atoi(zArg);
1008 int j;
1009 for(j=0; zArg[j]; j++){
1010 zArg[j] = tolower(zArg[j]);
1011 }
1012 if( strcmp(zArg,"on")==0 ){
1013 val = 1;
1014 }else if( strcmp(zArg,"yes")==0 ){
1015 val = 1;
1016 }
1017 return val;
1018}
1019
1020/*
drh75897232000-05-29 14:26:00 +00001021** If an input line begins with "." then invoke this routine to
1022** process that line.
drh67505e72002-04-19 12:34:06 +00001023**
drh47ad6842006-11-08 12:25:42 +00001024** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001025*/
drh44c2eb12003-04-30 11:38:26 +00001026static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001027 int i = 1;
1028 int nArg = 0;
1029 int n, c;
drh67505e72002-04-19 12:34:06 +00001030 int rc = 0;
drh75897232000-05-29 14:26:00 +00001031 char *azArg[50];
1032
1033 /* Parse the input line into tokens.
1034 */
1035 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001036 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001037 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001038 if( zLine[i]=='\'' || zLine[i]=='"' ){
1039 int delim = zLine[i++];
1040 azArg[nArg++] = &zLine[i];
1041 while( zLine[i] && zLine[i]!=delim ){ i++; }
1042 if( zLine[i]==delim ){
1043 zLine[i++] = 0;
1044 }
drhfeac5f82004-08-01 00:10:45 +00001045 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001046 }else{
1047 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001048 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001049 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001050 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001051 }
1052 }
1053
1054 /* Process the input line.
1055 */
drh67505e72002-04-19 12:34:06 +00001056 if( nArg==0 ) return rc;
drh75897232000-05-29 14:26:00 +00001057 n = strlen(azArg[0]);
1058 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001059 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1060 bail_on_error = booleanValue(azArg[1]);
1061 }else
1062
jplyon6a65bb32003-05-04 07:25:57 +00001063 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001064 struct callback_data data;
1065 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001066 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001067 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001068 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001069 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001070 data.colWidth[0] = 3;
1071 data.colWidth[1] = 15;
1072 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001073 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001074 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001075 if( zErrMsg ){
1076 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001077 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001078 }
1079 }else
1080
drh4c653a02000-06-07 01:27:47 +00001081 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1082 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001083 open_db(p);
drh33048c02001-10-01 14:29:22 +00001084 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001085 p->writableSchema = 0;
drh4c653a02000-06-07 01:27:47 +00001086 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001087 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001088 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001089 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001090 );
1091 run_table_dump_query(p->out, p->db,
1092 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001093 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001094 );
drh4c653a02000-06-07 01:27:47 +00001095 }else{
1096 int i;
drhdd3d4592004-08-30 01:54:05 +00001097 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001098 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001099 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001100 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001101 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001102 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001103 run_table_dump_query(p->out, p->db,
1104 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001105 "WHERE sql NOT NULL"
1106 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001107 " AND tbl_name LIKE shellstatic()"
1108 );
danielk1977bc6ada42004-06-30 08:20:16 +00001109 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001110 }
1111 }
drh45e29d82006-11-20 16:21:10 +00001112 if( p->writableSchema ){
1113 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1114 p->writableSchema = 0;
1115 }
drh4c653a02000-06-07 01:27:47 +00001116 if( zErrMsg ){
1117 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001118 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001119 }else{
1120 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001121 }
1122 }else
drh75897232000-05-29 14:26:00 +00001123
drhdaffd0e2001-04-11 14:28:42 +00001124 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001125 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001126 }else
1127
drh75897232000-05-29 14:26:00 +00001128 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001129 rc = 2;
drh75897232000-05-29 14:26:00 +00001130 }else
1131
drhdd45df82002-04-18 12:39:03 +00001132 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001133 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001134 if(val == 1) {
1135 if(!p->explainPrev.valid) {
1136 p->explainPrev.valid = 1;
1137 p->explainPrev.mode = p->mode;
1138 p->explainPrev.showHeader = p->showHeader;
1139 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1140 }
1141 /* We could put this code under the !p->explainValid
1142 ** condition so that it does not execute if we are already in
1143 ** explain mode. However, always executing it allows us an easy
1144 ** was to reset to explain mode in case the user previously
1145 ** did an .explain followed by a .width, .mode or .header
1146 ** command.
1147 */
1148 p->mode = MODE_Column;
1149 p->showHeader = 1;
1150 memset(p->colWidth,0,ArraySize(p->colWidth));
1151 p->colWidth[0] = 4;
drhe69cc5b2005-08-27 01:50:53 +00001152 p->colWidth[1] = 14;
persicom7e2dfdd2002-04-18 02:46:52 +00001153 p->colWidth[2] = 10;
1154 p->colWidth[3] = 10;
drhe69cc5b2005-08-27 01:50:53 +00001155 p->colWidth[4] = 33;
persicom7e2dfdd2002-04-18 02:46:52 +00001156 }else if (p->explainPrev.valid) {
1157 p->explainPrev.valid = 0;
1158 p->mode = p->explainPrev.mode;
1159 p->showHeader = p->explainPrev.showHeader;
1160 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1161 }
drh75897232000-05-29 14:26:00 +00001162 }else
1163
drhc28490c2006-10-26 14:25:58 +00001164 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001165 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001166 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001167 }else
1168
1169 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1170 fprintf(stderr,zHelp);
1171 }else
1172
drhfeac5f82004-08-01 00:10:45 +00001173 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1174 char *zTable = azArg[2]; /* Insert data into this table */
1175 char *zFile = azArg[1]; /* The file from which to extract data */
1176 sqlite3_stmt *pStmt; /* A statement */
1177 int rc; /* Result code */
1178 int nCol; /* Number of columns in the table */
1179 int nByte; /* Number of bytes in an SQL string */
1180 int i, j; /* Loop counters */
1181 int nSep; /* Number of bytes in p->separator[] */
1182 char *zSql; /* An SQL statement */
1183 char *zLine; /* A single line of input from the file */
1184 char **azCol; /* zLine[] broken up into columns */
1185 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001186 FILE *in; /* The input file */
1187 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001188
drha543c822006-06-08 16:10:14 +00001189 open_db(p);
drhfeac5f82004-08-01 00:10:45 +00001190 nSep = strlen(p->separator);
1191 if( nSep==0 ){
1192 fprintf(stderr, "non-null separator required for import\n");
1193 return 0;
1194 }
1195 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1196 if( zSql==0 ) return 0;
1197 nByte = strlen(zSql);
drh5e6078b2006-01-31 19:07:22 +00001198 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001199 sqlite3_free(zSql);
1200 if( rc ){
1201 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1202 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001203 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001204 }else{
1205 nCol = sqlite3_column_count(pStmt);
1206 }
1207 sqlite3_finalize(pStmt);
1208 if( nCol==0 ) return 0;
1209 zSql = malloc( nByte + 20 + nCol*2 );
1210 if( zSql==0 ) return 0;
1211 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
1212 j = strlen(zSql);
1213 for(i=1; i<nCol; i++){
1214 zSql[j++] = ',';
1215 zSql[j++] = '?';
1216 }
1217 zSql[j++] = ')';
1218 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001219 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001220 free(zSql);
1221 if( rc ){
1222 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1223 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001224 return 1;
drhfeac5f82004-08-01 00:10:45 +00001225 }
1226 in = fopen(zFile, "rb");
1227 if( in==0 ){
1228 fprintf(stderr, "cannot open file: %s\n", zFile);
1229 sqlite3_finalize(pStmt);
1230 return 0;
1231 }
1232 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001233 if( azCol==0 ){
1234 fclose(in);
1235 return 0;
1236 }
drhfeac5f82004-08-01 00:10:45 +00001237 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1238 zCommit = "COMMIT";
1239 while( (zLine = local_getline(0, in))!=0 ){
1240 char *z;
1241 i = 0;
drhb860bc92004-08-04 15:16:55 +00001242 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001243 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001244 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001245 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1246 *z = 0;
1247 i++;
drhb860bc92004-08-04 15:16:55 +00001248 if( i<nCol ){
1249 azCol[i] = &z[nSep];
1250 z += nSep-1;
1251 }
drhfeac5f82004-08-01 00:10:45 +00001252 }
1253 }
drh1cd7f832005-08-05 18:50:51 +00001254 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001255 if( i+1!=nCol ){
1256 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1257 zFile, lineno, nCol, i+1);
1258 zCommit = "ROLLBACK";
1259 break;
1260 }
drhfeac5f82004-08-01 00:10:45 +00001261 for(i=0; i<nCol; i++){
1262 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1263 }
1264 sqlite3_step(pStmt);
1265 rc = sqlite3_reset(pStmt);
1266 free(zLine);
1267 if( rc!=SQLITE_OK ){
1268 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1269 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001270 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001271 break;
1272 }
1273 }
1274 free(azCol);
1275 fclose(in);
1276 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001277 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001278 }else
1279
drh75897232000-05-29 14:26:00 +00001280 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1281 struct callback_data data;
1282 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001283 open_db(p);
drh75897232000-05-29 14:26:00 +00001284 memcpy(&data, p, sizeof(data));
1285 data.showHeader = 0;
1286 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001287 zShellStatic = azArg[1];
1288 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001289 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001290 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001291 "UNION ALL "
1292 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001293 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001294 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001295 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001296 );
danielk1977bc6ada42004-06-30 08:20:16 +00001297 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001298 if( zErrMsg ){
1299 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001300 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001301 }
1302 }else
1303
drhae5e4452007-05-03 17:18:36 +00001304#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001305 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
1306 extern void (*sqlite3_io_trace)(const char*, ...);
1307 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1308 iotrace = 0;
1309 if( nArg<2 ){
1310 sqlite3_io_trace = 0;
1311 }else if( strcmp(azArg[1], "-")==0 ){
1312 sqlite3_io_trace = iotracePrintf;
1313 iotrace = stdout;
1314 }else{
1315 iotrace = fopen(azArg[1], "w");
1316 if( iotrace==0 ){
1317 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
1318 sqlite3_io_trace = 0;
1319 }else{
1320 sqlite3_io_trace = iotracePrintf;
1321 }
1322 }
1323 }else
drhae5e4452007-05-03 17:18:36 +00001324#endif
drhb0603412007-02-28 04:47:26 +00001325
drh70df4fe2006-06-13 15:12:21 +00001326#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001327 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1328 const char *zFile, *zProc;
1329 char *zErrMsg = 0;
1330 int rc;
1331 zFile = azArg[1];
1332 zProc = nArg>=3 ? azArg[2] : 0;
1333 open_db(p);
1334 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1335 if( rc!=SQLITE_OK ){
1336 fprintf(stderr, "%s\n", zErrMsg);
1337 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001338 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001339 }
1340 }else
drh70df4fe2006-06-13 15:12:21 +00001341#endif
drh1e397f82006-06-08 15:28:43 +00001342
drh28bd4bc2000-06-15 15:57:22 +00001343 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh75897232000-05-29 14:26:00 +00001344 int n2 = strlen(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001345 if( strncmp(azArg[1],"line",n2)==0
1346 ||
1347 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001348 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001349 }else if( strncmp(azArg[1],"column",n2)==0
1350 ||
1351 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001352 p->mode = MODE_Column;
1353 }else if( strncmp(azArg[1],"list",n2)==0 ){
1354 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001355 }else if( strncmp(azArg[1],"html",n2)==0 ){
1356 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001357 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1358 p->mode = MODE_Tcl;
1359 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001360 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001361 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001362 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1363 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001364 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001365 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1366 p->mode = MODE_Insert;
1367 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001368 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001369 }else{
drh33048c02001-10-01 14:29:22 +00001370 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001371 }
drhdaffd0e2001-04-11 14:28:42 +00001372 }else {
drhcf68ae92006-12-19 18:47:41 +00001373 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001374 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001375 }
1376 }else
1377
persicom7e2dfdd2002-04-18 02:46:52 +00001378 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001379 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1380 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001381 }else
1382
drh75897232000-05-29 14:26:00 +00001383 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1384 if( p->out!=stdout ){
1385 fclose(p->out);
1386 }
1387 if( strcmp(azArg[1],"stdout")==0 ){
1388 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001389 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001390 }else{
drha1f9b5e2004-02-14 16:31:02 +00001391 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001392 if( p->out==0 ){
1393 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1394 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001395 } else {
drh5bb3eb92007-05-04 13:15:55 +00001396 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001397 }
1398 }
1399 }else
1400
drhdd45df82002-04-18 12:39:03 +00001401 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001402 if( nArg >= 2) {
1403 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1404 }
1405 if( nArg >= 3) {
1406 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1407 }
1408 }else
1409
1410 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001411 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001412 }else
1413
drhdaffd0e2001-04-11 14:28:42 +00001414 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001415 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001416 if( alt==0 ){
1417 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1418 }else{
1419 process_input(p, alt);
1420 fclose(alt);
1421 }
1422 }else
1423
drh75897232000-05-29 14:26:00 +00001424 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1425 struct callback_data data;
1426 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001427 open_db(p);
drh75897232000-05-29 14:26:00 +00001428 memcpy(&data, p, sizeof(data));
1429 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001430 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001431 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001432 int i;
1433 for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
1434 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001435 char *new_argv[2], *new_colv[2];
1436 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1437 " type text,\n"
1438 " name text,\n"
1439 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001440 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001441 " sql text\n"
1442 ")";
1443 new_argv[1] = 0;
1444 new_colv[0] = "sql";
1445 new_colv[1] = 0;
1446 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001447 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001448 char *new_argv[2], *new_colv[2];
1449 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1450 " type text,\n"
1451 " name text,\n"
1452 " tbl_name text,\n"
1453 " rootpage integer,\n"
1454 " sql text\n"
1455 ")";
1456 new_argv[1] = 0;
1457 new_colv[0] = "sql";
1458 new_colv[1] = 0;
1459 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001460 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001461 zShellStatic = azArg[1];
1462 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001463 "SELECT sql FROM "
1464 " (SELECT * FROM sqlite_master UNION ALL"
1465 " SELECT * FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001466 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001467 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001468 callback, &data, &zErrMsg);
1469 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001470 }
drh75897232000-05-29 14:26:00 +00001471 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001472 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001473 "SELECT sql FROM "
1474 " (SELECT * FROM sqlite_master UNION ALL"
1475 " SELECT * FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001476 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001477 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001478 callback, &data, &zErrMsg
1479 );
drh75897232000-05-29 14:26:00 +00001480 }
drh75897232000-05-29 14:26:00 +00001481 if( zErrMsg ){
1482 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001483 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001484 }
1485 }else
1486
1487 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001488 sqlite3_snprintf(sizeof(p->separator), p->separator,
1489 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001490 }else
1491
persicom7e2dfdd2002-04-18 02:46:52 +00001492 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1493 int i;
1494 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001495 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001496 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001497 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001498 fprintf(p->out,"%9.9s: ", "nullvalue");
1499 output_c_string(p->out, p->nullvalue);
1500 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001501 fprintf(p->out,"%9.9s: %s\n","output",
1502 strlen(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001503 fprintf(p->out,"%9.9s: ", "separator");
1504 output_c_string(p->out, p->separator);
1505 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001506 fprintf(p->out,"%9.9s: ","width");
1507 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001508 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001509 }
drhfeac5f82004-08-01 00:10:45 +00001510 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001511 }else
1512
drh2dfbbca2000-07-28 14:32:48 +00001513 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001514 char **azResult;
1515 int nRow, rc;
1516 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001517 open_db(p);
drha50da102000-08-08 20:19:09 +00001518 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001519 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001520 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001521 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001522 "UNION ALL "
1523 "SELECT name FROM sqlite_temp_master "
1524 "WHERE type IN ('table','view') "
1525 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001526 &azResult, &nRow, 0, &zErrMsg
1527 );
drha50da102000-08-08 20:19:09 +00001528 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001529 zShellStatic = azArg[1];
1530 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001531 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001532 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001533 "UNION ALL "
1534 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001535 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001536 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001537 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001538 );
danielk1977bc6ada42004-06-30 08:20:16 +00001539 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001540 }
drh75897232000-05-29 14:26:00 +00001541 if( zErrMsg ){
1542 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001543 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001544 }
drhe3710332000-09-29 13:30:53 +00001545 if( rc==SQLITE_OK ){
1546 int len, maxlen = 0;
1547 int i, j;
1548 int nPrintCol, nPrintRow;
1549 for(i=1; i<=nRow; i++){
1550 if( azResult[i]==0 ) continue;
1551 len = strlen(azResult[i]);
1552 if( len>maxlen ) maxlen = len;
1553 }
1554 nPrintCol = 80/(maxlen+2);
1555 if( nPrintCol<1 ) nPrintCol = 1;
1556 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1557 for(i=0; i<nPrintRow; i++){
1558 for(j=i+1; j<=nRow; j+=nPrintRow){
1559 char *zSp = j<=nPrintRow ? "" : " ";
1560 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1561 }
1562 printf("\n");
1563 }
drh47ad6842006-11-08 12:25:42 +00001564 }else{
1565 rc = 1;
drhe3710332000-09-29 13:30:53 +00001566 }
danielk19776f8a5032004-05-10 10:34:51 +00001567 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001568 }else
1569
drh3b1a9882007-11-02 12:53:03 +00001570 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001571 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001572 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001573 }else
drh3b1a9882007-11-02 12:53:03 +00001574
1575#if HAS_TIMER
1576 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
1577 enableTimer = booleanValue(azArg[1]);
1578 }else
1579#endif
drh2dfbbca2000-07-28 14:32:48 +00001580
drh75897232000-05-29 14:26:00 +00001581 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1582 int j;
drh43617e92006-03-06 20:55:46 +00001583 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001584 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1585 p->colWidth[j-1] = atoi(azArg[j]);
1586 }
1587 }else
1588
drh3b1a9882007-11-02 12:53:03 +00001589
drh75897232000-05-29 14:26:00 +00001590 {
drh67505e72002-04-19 12:34:06 +00001591 fprintf(stderr, "unknown command or invalid arguments: "
1592 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001593 }
drh67505e72002-04-19 12:34:06 +00001594
1595 return rc;
drh75897232000-05-29 14:26:00 +00001596}
1597
drh67505e72002-04-19 12:34:06 +00001598/*
drh91a66392007-09-07 01:12:32 +00001599** Return TRUE if a semicolon occurs anywhere in the first N characters
1600** of string z[].
drh324ccef2003-02-05 14:06:20 +00001601*/
drh91a66392007-09-07 01:12:32 +00001602static int _contains_semicolon(const char *z, int N){
1603 int i;
1604 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
1605 return 0;
drh324ccef2003-02-05 14:06:20 +00001606}
1607
1608/*
drh70c7a4b2003-04-26 03:03:06 +00001609** Test to see if a line consists entirely of whitespace.
1610*/
1611static int _all_whitespace(const char *z){
1612 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001613 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001614 if( *z=='/' && z[1]=='*' ){
1615 z += 2;
1616 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1617 if( *z==0 ) return 0;
1618 z++;
1619 continue;
1620 }
1621 if( *z=='-' && z[1]=='-' ){
1622 z += 2;
1623 while( *z && *z!='\n' ){ z++; }
1624 if( *z==0 ) return 1;
1625 continue;
1626 }
1627 return 0;
1628 }
1629 return 1;
1630}
1631
1632/*
drha9b17162003-04-29 18:01:28 +00001633** Return TRUE if the line typed in is an SQL command terminator other
1634** than a semi-colon. The SQL Server style "go" command is understood
1635** as is the Oracle "/".
1636*/
1637static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001638 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drha9b17162003-04-29 18:01:28 +00001639 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
drhc8d74412004-08-31 23:41:26 +00001640 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1641 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001642 return 1; /* SQL Server */
1643 }
1644 return 0;
1645}
1646
1647/*
drh67505e72002-04-19 12:34:06 +00001648** Read input from *in and process it. If *in==0 then input
1649** is interactive - the user is typing it it. Otherwise, input
1650** is coming from a file or device. A prompt is issued and history
1651** is saved only if input is interactive. An interrupt signal will
1652** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001653**
1654** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001655*/
drhc28490c2006-10-26 14:25:58 +00001656static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001657 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001658 char *zSql = 0;
1659 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00001660 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00001661 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001662 int rc;
1663 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001664 int lineno = 0;
1665 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001666
1667 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1668 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001669 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001670 zLine = one_input_line(zSql, in);
1671 if( zLine==0 ){
1672 break; /* We have reached EOF */
1673 }
drh67505e72002-04-19 12:34:06 +00001674 if( seenInterrupt ){
1675 if( in!=0 ) break;
1676 seenInterrupt = 0;
1677 }
drhc28490c2006-10-26 14:25:58 +00001678 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001679 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001680 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001681 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001682 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001683 if( rc==2 ){
1684 break;
1685 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001686 errCnt++;
1687 }
drhdaffd0e2001-04-11 14:28:42 +00001688 continue;
1689 }
drha9b17162003-04-29 18:01:28 +00001690 if( _is_command_terminator(zLine) ){
drh5bb3eb92007-05-04 13:15:55 +00001691 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001692 }
drh91a66392007-09-07 01:12:32 +00001693 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00001694 if( zSql==0 ){
1695 int i;
drh4c755c02004-08-08 20:22:17 +00001696 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001697 if( zLine[i]!=0 ){
1698 nSql = strlen(zLine);
1699 zSql = malloc( nSql+1 );
drhc1f44942006-05-10 14:39:13 +00001700 if( zSql==0 ){
1701 fprintf(stderr, "out of memory\n");
1702 exit(1);
1703 }
drh5bb3eb92007-05-04 13:15:55 +00001704 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001705 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001706 }
1707 }else{
1708 int len = strlen(zLine);
1709 zSql = realloc( zSql, nSql + len + 2 );
1710 if( zSql==0 ){
1711 fprintf(stderr,"%s: out of memory!\n", Argv0);
1712 exit(1);
1713 }
drh5bb3eb92007-05-04 13:15:55 +00001714 zSql[nSql++] = '\n';
1715 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001716 nSql += len;
1717 }
drh91a66392007-09-07 01:12:32 +00001718 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1719 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001720 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001721 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00001722 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00001723 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00001724 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00001725 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001726 char zPrefix[100];
1727 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001728 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1729 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001730 }else{
drh5bb3eb92007-05-04 13:15:55 +00001731 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001732 }
drh7f953e22002-07-13 17:33:45 +00001733 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001734 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001735 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001736 zErrMsg = 0;
1737 }else{
drhc28490c2006-10-26 14:25:58 +00001738 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001739 }
drhc49f44e2006-10-26 18:15:42 +00001740 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001741 }
1742 free(zSql);
1743 zSql = 0;
1744 nSql = 0;
1745 }
1746 }
1747 if( zSql ){
drh70c7a4b2003-04-26 03:03:06 +00001748 if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001749 free(zSql);
1750 }
danielk19772ac27622007-07-03 05:31:16 +00001751 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001752 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001753}
1754
drh67505e72002-04-19 12:34:06 +00001755/*
1756** Return a pathname which is the user's home directory. A
1757** 0 return indicates an error of some kind. Space to hold the
1758** resulting string is obtained from malloc(). The calling
1759** function should free the result.
1760*/
1761static char *find_home_dir(void){
1762 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001763
drh454ad582007-11-26 22:54:27 +00001764#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE)
drh67505e72002-04-19 12:34:06 +00001765 struct passwd *pwent;
1766 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001767 if( (pwent=getpwuid(uid)) != NULL) {
1768 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001769 }
1770#endif
1771
chw65d3c132007-11-12 21:09:10 +00001772#if defined(_WIN32_WCE)
1773 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
1774 */
1775 home_dir = strdup("/");
1776#else
1777
drh164a1b62006-08-19 11:15:20 +00001778#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1779 if (!home_dir) {
1780 home_dir = getenv("USERPROFILE");
1781 }
1782#endif
1783
drh67505e72002-04-19 12:34:06 +00001784 if (!home_dir) {
1785 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001786 }
1787
drhcdb36b72006-06-12 12:57:45 +00001788#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001789 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001790 char *zDrive, *zPath;
1791 int n;
1792 zDrive = getenv("HOMEDRIVE");
1793 zPath = getenv("HOMEPATH");
1794 if( zDrive && zPath ){
1795 n = strlen(zDrive) + strlen(zPath) + 1;
1796 home_dir = malloc( n );
1797 if( home_dir==0 ) return 0;
1798 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1799 return home_dir;
1800 }
1801 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001802 }
1803#endif
1804
chw65d3c132007-11-12 21:09:10 +00001805#endif /* !_WIN32_WCE */
1806
drh67505e72002-04-19 12:34:06 +00001807 if( home_dir ){
drh5bb3eb92007-05-04 13:15:55 +00001808 int n = strlen(home_dir) + 1;
1809 char *z = malloc( n );
1810 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001811 home_dir = z;
1812 }
drhe98d4fa2002-04-21 19:06:22 +00001813
drh67505e72002-04-19 12:34:06 +00001814 return home_dir;
1815}
1816
1817/*
1818** Read input from the file given by sqliterc_override. Or if that
1819** parameter is NULL, take input from ~/.sqliterc
1820*/
drh22fbcb82004-02-01 01:22:50 +00001821static void process_sqliterc(
1822 struct callback_data *p, /* Configuration data */
1823 const char *sqliterc_override /* Name of config file. NULL to use default */
1824){
persicom7e2dfdd2002-04-18 02:46:52 +00001825 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001826 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001827 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001828 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001829 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001830
1831 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001832 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001833 if( home_dir==0 ){
1834 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
1835 return;
1836 }
drha959ac42007-06-20 13:10:00 +00001837 nBuf = strlen(home_dir) + 16;
1838 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001839 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001840 fprintf(stderr,"%s: out of memory!\n", Argv0);
1841 exit(1);
1842 }
drha959ac42007-06-20 13:10:00 +00001843 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001844 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001845 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001846 }
drha1f9b5e2004-02-14 16:31:02 +00001847 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001848 if( in ){
drhc28490c2006-10-26 14:25:58 +00001849 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00001850 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00001851 }
persicom7e2dfdd2002-04-18 02:46:52 +00001852 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001853 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001854 }
drh43617e92006-03-06 20:55:46 +00001855 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001856 return;
1857}
1858
drh67505e72002-04-19 12:34:06 +00001859/*
drhe1e38c42003-05-04 18:30:59 +00001860** Show available command line options
1861*/
1862static const char zOptions[] =
1863 " -init filename read/process named file\n"
1864 " -echo print commands before execution\n"
1865 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001866 " -bail stop after hitting an error\n"
1867 " -interactive force interactive I/O\n"
1868 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001869 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001870 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001871 " -html set output mode to HTML\n"
1872 " -line set output mode to 'line'\n"
1873 " -list set output mode to 'list'\n"
1874 " -separator 'x' set output field separator (|)\n"
1875 " -nullvalue 'text' set text string for NULL values\n"
1876 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001877;
1878static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001879 fprintf(stderr,
1880 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1881 "FILENAME is the name of an SQLite database. A new database is created\n"
1882 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001883 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001884 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001885 }else{
1886 fprintf(stderr, "Use the -help option for additional information\n");
1887 }
1888 exit(1);
1889}
1890
1891/*
drh67505e72002-04-19 12:34:06 +00001892** Initialize the state information in data
1893*/
drh0850b532006-01-31 19:31:43 +00001894static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001895 memset(data, 0, sizeof(*data));
1896 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001897 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001898 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001899 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1900 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001901}
1902
drh75897232000-05-29 14:26:00 +00001903int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001904 char *zErrMsg = 0;
1905 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001906 const char *zInitFile = 0;
1907 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001908 int i;
drhc28490c2006-10-26 14:25:58 +00001909 int rc = 0;
drh75897232000-05-29 14:26:00 +00001910
drhdaffd0e2001-04-11 14:28:42 +00001911 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001912 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001913 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001914
drh44c2eb12003-04-30 11:38:26 +00001915 /* Make sure we have a valid signal handler early, before anything
1916 ** else is done.
1917 */
drh4c504392000-10-16 22:06:40 +00001918#ifdef SIGINT
1919 signal(SIGINT, interrupt_handler);
1920#endif
drh44c2eb12003-04-30 11:38:26 +00001921
drh22fbcb82004-02-01 01:22:50 +00001922 /* Do an initial pass through the command-line argument to locate
1923 ** the name of the database file, the name of the initialization file,
1924 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001925 */
drh22fbcb82004-02-01 01:22:50 +00001926 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001927 char *z;
drh44c2eb12003-04-30 11:38:26 +00001928 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001929 z = argv[i];
1930 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001931 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1932 i++;
drh22fbcb82004-02-01 01:22:50 +00001933 }else if( strcmp(argv[i],"-init")==0 ){
1934 i++;
1935 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001936 }
1937 }
drh22fbcb82004-02-01 01:22:50 +00001938 if( i<argc ){
1939 data.zDbFilename = argv[i++];
1940 }else{
danielk197703aded42004-11-22 05:26:27 +00001941#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00001942 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00001943#else
1944 data.zDbFilename = 0;
1945#endif
drh22fbcb82004-02-01 01:22:50 +00001946 }
1947 if( i<argc ){
1948 zFirstCmd = argv[i++];
1949 }
drh44c2eb12003-04-30 11:38:26 +00001950 data.out = stdout;
1951
drh01b41712005-08-29 23:06:23 +00001952#ifdef SQLITE_OMIT_MEMORYDB
1953 if( data.zDbFilename==0 ){
1954 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
1955 exit(1);
1956 }
1957#endif
1958
drh44c2eb12003-04-30 11:38:26 +00001959 /* Go ahead and open the database file if it already exists. If the
1960 ** file does not exist, delay opening it. This prevents empty database
1961 ** files from being created if a user mistypes the database name argument
1962 ** to the sqlite command-line tool.
1963 */
drhc8d74412004-08-31 23:41:26 +00001964 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00001965 open_db(&data);
1966 }
1967
drh22fbcb82004-02-01 01:22:50 +00001968 /* Process the initialization file if there is one. If no -init option
1969 ** is given on the command line, look for a file named ~/.sqliterc and
1970 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00001971 */
drh22fbcb82004-02-01 01:22:50 +00001972 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00001973
drh22fbcb82004-02-01 01:22:50 +00001974 /* Make a second pass through the command-line argument and set
1975 ** options. This second pass is delayed until after the initialization
1976 ** file is processed so that the command-line arguments will override
1977 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00001978 */
drh22fbcb82004-02-01 01:22:50 +00001979 for(i=1; i<argc && argv[i][0]=='-'; i++){
1980 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00001981 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00001982 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00001983 i++;
1984 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001985 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00001986 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001987 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00001988 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001989 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00001990 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00001991 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00001992 }else if( strcmp(z,"-csv")==0 ){
1993 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001994 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00001995 }else if( strcmp(z,"-separator")==0 ){
1996 i++;
drh5bb3eb92007-05-04 13:15:55 +00001997 sqlite3_snprintf(sizeof(data.separator), data.separator,
1998 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00001999 }else if( strcmp(z,"-nullvalue")==0 ){
2000 i++;
drh5bb3eb92007-05-04 13:15:55 +00002001 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2002 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002003 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002004 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002005 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002006 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002007 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002008 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002009 }else if( strcmp(z,"-bail")==0 ){
2010 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002011 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002012 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002013 return 0;
drhc28490c2006-10-26 14:25:58 +00002014 }else if( strcmp(z,"-interactive")==0 ){
2015 stdin_is_interactive = 1;
2016 }else if( strcmp(z,"-batch")==0 ){
2017 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002018 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002019 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002020 }else{
drh22fbcb82004-02-01 01:22:50 +00002021 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002022 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002023 return 1;
2024 }
2025 }
drh44c2eb12003-04-30 11:38:26 +00002026
drh22fbcb82004-02-01 01:22:50 +00002027 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002028 /* Run just the command that follows the database name
2029 */
drh22fbcb82004-02-01 01:22:50 +00002030 if( zFirstCmd[0]=='.' ){
2031 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002032 exit(0);
2033 }else{
2034 int rc;
drh44c2eb12003-04-30 11:38:26 +00002035 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00002036 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00002037 if( rc!=0 && zErrMsg!=0 ){
2038 fprintf(stderr,"SQL error: %s\n", zErrMsg);
2039 exit(1);
2040 }
drh75897232000-05-29 14:26:00 +00002041 }
2042 }else{
drh44c2eb12003-04-30 11:38:26 +00002043 /* Run commands received from standard input
2044 */
drhc28490c2006-10-26 14:25:58 +00002045 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002046 char *zHome;
2047 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002048 int nHistory;
drh75897232000-05-29 14:26:00 +00002049 printf(
drhb217a572000-08-22 13:40:18 +00002050 "SQLite version %s\n"
2051 "Enter \".help\" for instructions\n",
drhc8d74412004-08-31 23:41:26 +00002052 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002053 );
drh67505e72002-04-19 12:34:06 +00002054 zHome = find_home_dir();
drh5bb3eb92007-05-04 13:15:55 +00002055 if( zHome && (zHistory = malloc(nHistory = strlen(zHome)+20))!=0 ){
2056 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
drh67505e72002-04-19 12:34:06 +00002057 }
danielk19774af00c62005-01-23 23:43:21 +00002058#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002059 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002060#endif
drhc28490c2006-10-26 14:25:58 +00002061 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002062 if( zHistory ){
2063 stifle_history(100);
2064 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002065 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002066 }
adamd0a3daa32006-07-28 20:16:14 +00002067 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002068 }else{
drhc28490c2006-10-26 14:25:58 +00002069 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002070 }
2071 }
drh33048c02001-10-01 14:29:22 +00002072 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002073 if( db ){
2074 if( sqlite3_close(db)!=SQLITE_OK ){
2075 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2076 }
2077 }
drhc28490c2006-10-26 14:25:58 +00002078 return rc;
drh75897232000-05-29 14:26:00 +00002079}