blob: 99f8f95adc1a6ed7b4ff5e2d05024325df49fffa [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**
drh4cea5ba2008-05-05 16:27:24 +000015** $Id: shell.c,v 1.178 2008/05/05 16:27:24 drh Exp $
drh75897232000-05-29 14:26:00 +000016*/
17#include <stdlib.h>
18#include <string.h>
19#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000020#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000021#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000022#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000023#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000024
drh454ad582007-11-26 22:54:27 +000025#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000026# include <signal.h>
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 */
drh66ce4d02008-02-15 17:38:06 +0000339#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000340
drh66ce4d02008-02-15 17:38:06 +0000341static const char *modeDescr[] = {
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",
drh66ce4d02008-02-15 17:38:06 +0000350 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000351};
drh75897232000-05-29 14:26:00 +0000352
353/*
354** Number of elements in an array
355*/
356#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
357
358/*
drh28bd4bc2000-06-15 15:57:22 +0000359** Output the given string as a quoted string using SQL quoting conventions.
360*/
361static void output_quoted_string(FILE *out, const char *z){
362 int i;
363 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000364 for(i=0; z[i]; i++){
365 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000366 }
367 if( nSingle==0 ){
368 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000369 }else{
370 fprintf(out,"'");
371 while( *z ){
372 for(i=0; z[i] && z[i]!='\''; i++){}
373 if( i==0 ){
374 fprintf(out,"''");
375 z++;
376 }else if( z[i]=='\'' ){
377 fprintf(out,"%.*s''",i,z);
378 z += i+1;
379 }else{
drhcd7d2732002-02-26 23:24:26 +0000380 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000381 break;
382 }
383 }
drhcd7d2732002-02-26 23:24:26 +0000384 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000385 }
386}
387
388/*
drhfeac5f82004-08-01 00:10:45 +0000389** Output the given string as a quoted according to C or TCL quoting rules.
390*/
391static void output_c_string(FILE *out, const char *z){
392 unsigned int c;
393 fputc('"', out);
394 while( (c = *(z++))!=0 ){
395 if( c=='\\' ){
396 fputc(c, out);
397 fputc(c, out);
398 }else if( c=='\t' ){
399 fputc('\\', out);
400 fputc('t', out);
401 }else if( c=='\n' ){
402 fputc('\\', out);
403 fputc('n', out);
404 }else if( c=='\r' ){
405 fputc('\\', out);
406 fputc('r', out);
407 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000408 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000409 }else{
410 fputc(c, out);
411 }
412 }
413 fputc('"', out);
414}
415
416/*
drhc08a4f12000-06-15 16:49:48 +0000417** Output the given string with characters that are special to
418** HTML escaped.
419*/
420static void output_html_string(FILE *out, const char *z){
421 int i;
422 while( *z ){
423 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
424 if( i>0 ){
425 fprintf(out,"%.*s",i,z);
426 }
427 if( z[i]=='<' ){
428 fprintf(out,"&lt;");
429 }else if( z[i]=='&' ){
430 fprintf(out,"&amp;");
431 }else{
432 break;
433 }
434 z += i + 1;
435 }
436}
437
438/*
drhc49f44e2006-10-26 18:15:42 +0000439** If a field contains any character identified by a 1 in the following
440** array, then the string must be quoted for CSV.
441*/
442static const char needCsvQuote[] = {
443 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
444 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
445 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
450 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
459};
460
461/*
drh8e64d1c2004-10-07 00:32:39 +0000462** Output a single term of CSV. Actually, p->separator is used for
463** the separator, which may or may not be a comma. p->nullvalue is
464** the null value. Strings are quoted using ANSI-C rules. Numbers
465** appear outside of quotes.
466*/
467static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000468 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000469 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000470 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000471 }else{
drhc49f44e2006-10-26 18:15:42 +0000472 int i;
drhc85375d2007-12-18 15:41:44 +0000473 int nSep = strlen(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000474 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000475 if( needCsvQuote[((unsigned char*)z)[i]]
476 || (z[i]==p->separator[0] &&
477 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000478 i = 0;
479 break;
480 }
481 }
482 if( i==0 ){
483 putc('"', out);
484 for(i=0; z[i]; i++){
485 if( z[i]=='"' ) putc('"', out);
486 putc(z[i], out);
487 }
488 putc('"', out);
489 }else{
490 fprintf(out, "%s", z);
491 }
drh8e64d1c2004-10-07 00:32:39 +0000492 }
493 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000494 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000495 }
496}
497
danielk19774af00c62005-01-23 23:43:21 +0000498#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000499/*
drh4c504392000-10-16 22:06:40 +0000500** This routine runs when the user presses Ctrl-C
501*/
502static void interrupt_handler(int NotUsed){
drh67505e72002-04-19 12:34:06 +0000503 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000504 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000505}
danielk19774af00c62005-01-23 23:43:21 +0000506#endif
drh4c504392000-10-16 22:06:40 +0000507
508/*
drh75897232000-05-29 14:26:00 +0000509** This is the callback routine that the SQLite library
510** invokes for each row of a query result.
511*/
512static int callback(void *pArg, int nArg, char **azArg, char **azCol){
513 int i;
514 struct callback_data *p = (struct callback_data*)pArg;
515 switch( p->mode ){
516 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000517 int w = 5;
drh6a535342001-10-19 16:44:56 +0000518 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000519 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000520 int len = strlen(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000521 if( len>w ) w = len;
522 }
drh75897232000-05-29 14:26:00 +0000523 if( p->cnt++>0 ) fprintf(p->out,"\n");
524 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000525 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000526 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000527 }
528 break;
529 }
danielk19770d78bae2008-01-03 07:09:48 +0000530 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000531 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000532 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000533 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000534 int w, n;
535 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000536 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000537 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000538 w = 0;
drh75897232000-05-29 14:26:00 +0000539 }
drha0c66f52000-07-29 13:20:21 +0000540 if( w<=0 ){
drhff6e9112000-08-28 16:21:58 +0000541 w = strlen(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000542 if( w<10 ) w = 10;
persicom7e2dfdd2002-04-18 02:46:52 +0000543 n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000544 if( w<n ) w = n;
545 }
546 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000547 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000548 }
549 if( p->showHeader ){
550 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
551 }
552 }
553 if( p->showHeader ){
554 for(i=0; i<nArg; i++){
555 int w;
556 if( i<ArraySize(p->actualWidth) ){
557 w = p->actualWidth[i];
558 }else{
559 w = 10;
560 }
561 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
562 "----------------------------------------------------------",
563 i==nArg-1 ? "\n": " ");
564 }
drh75897232000-05-29 14:26:00 +0000565 }
566 }
drh6a535342001-10-19 16:44:56 +0000567 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000568 for(i=0; i<nArg; i++){
569 int w;
drha0c66f52000-07-29 13:20:21 +0000570 if( i<ArraySize(p->actualWidth) ){
571 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000572 }else{
573 w = 10;
574 }
danielk19770d78bae2008-01-03 07:09:48 +0000575 if( p->mode==MODE_Explain && azArg[i] && strlen(azArg[i])>w ){
576 w = strlen(azArg[i]);
577 }
drhc61053b2000-06-04 12:58:36 +0000578 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000579 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000580 }
581 break;
582 }
drhe3710332000-09-29 13:30:53 +0000583 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000584 case MODE_List: {
585 if( p->cnt++==0 && p->showHeader ){
586 for(i=0; i<nArg; i++){
587 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
588 }
589 }
drh6a535342001-10-19 16:44:56 +0000590 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000591 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000592 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000593 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000594 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000595 if( i<nArg-1 ){
596 fprintf(p->out, "%s", p->separator);
597 }else if( p->mode==MODE_Semi ){
598 fprintf(p->out, ";\n");
599 }else{
600 fprintf(p->out, "\n");
601 }
drh75897232000-05-29 14:26:00 +0000602 }
603 break;
604 }
drh1e5d0e92000-05-31 23:33:17 +0000605 case MODE_Html: {
606 if( p->cnt++==0 && p->showHeader ){
607 fprintf(p->out,"<TR>");
608 for(i=0; i<nArg; i++){
609 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
610 }
611 fprintf(p->out,"</TR>\n");
612 }
drh6a535342001-10-19 16:44:56 +0000613 if( azArg==0 ) break;
drh28bd4bc2000-06-15 15:57:22 +0000614 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000615 for(i=0; i<nArg; i++){
drhc08a4f12000-06-15 16:49:48 +0000616 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000617 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
drhc08a4f12000-06-15 16:49:48 +0000618 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000619 }
drh7d686b22002-11-11 13:56:47 +0000620 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000621 break;
622 }
drhfeac5f82004-08-01 00:10:45 +0000623 case MODE_Tcl: {
624 if( p->cnt++==0 && p->showHeader ){
625 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000626 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000627 fprintf(p->out, "%s", p->separator);
628 }
629 fprintf(p->out,"\n");
630 }
631 if( azArg==0 ) break;
632 for(i=0; i<nArg; i++){
633 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
634 fprintf(p->out, "%s", p->separator);
635 }
636 fprintf(p->out,"\n");
637 break;
638 }
drh8e64d1c2004-10-07 00:32:39 +0000639 case MODE_Csv: {
640 if( p->cnt++==0 && p->showHeader ){
641 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000642 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000643 }
644 fprintf(p->out,"\n");
645 }
646 if( azArg==0 ) break;
647 for(i=0; i<nArg; i++){
648 output_csv(p, azArg[i], i<nArg-1);
649 }
650 fprintf(p->out,"\n");
651 break;
652 }
drh28bd4bc2000-06-15 15:57:22 +0000653 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000654 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000655 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000656 for(i=0; i<nArg; i++){
657 char *zSep = i>0 ? ",": "";
658 if( azArg[i]==0 ){
659 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000660 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000661 fprintf(p->out,"%s%s",zSep, azArg[i]);
662 }else{
663 if( zSep[0] ) fprintf(p->out,"%s",zSep);
664 output_quoted_string(p->out, azArg[i]);
665 }
666 }
667 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000668 break;
drh28bd4bc2000-06-15 15:57:22 +0000669 }
persicom1d0b8722002-04-18 02:53:04 +0000670 }
drh75897232000-05-29 14:26:00 +0000671 return 0;
672}
673
674/*
drh33048c02001-10-01 14:29:22 +0000675** Set the destination table field of the callback_data structure to
676** the name of the table given. Escape any quote characters in the
677** table name.
678*/
679static void set_table_name(struct callback_data *p, const char *zName){
680 int i, n;
681 int needQuote;
682 char *z;
683
684 if( p->zDestTable ){
685 free(p->zDestTable);
686 p->zDestTable = 0;
687 }
688 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000689 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000690 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000691 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000692 needQuote = 1;
693 if( zName[i]=='\'' ) n++;
694 }
695 }
696 if( needQuote ) n += 2;
697 z = p->zDestTable = malloc( n+1 );
698 if( z==0 ){
699 fprintf(stderr,"Out of memory!\n");
700 exit(1);
701 }
702 n = 0;
703 if( needQuote ) z[n++] = '\'';
704 for(i=0; zName[i]; i++){
705 z[n++] = zName[i];
706 if( zName[i]=='\'' ) z[n++] = '\'';
707 }
708 if( needQuote ) z[n++] = '\'';
709 z[n] = 0;
710}
711
danielk19772a02e332004-06-05 08:04:36 +0000712/* zIn is either a pointer to a NULL-terminated string in memory obtained
713** from malloc(), or a NULL pointer. The string pointed to by zAppend is
714** added to zIn, and the result returned in memory obtained from malloc().
715** zIn, if it was not NULL, is freed.
716**
717** If the third argument, quote, is not '\0', then it is used as a
718** quote character for zAppend.
719*/
drhc28490c2006-10-26 14:25:58 +0000720static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000721 int len;
722 int i;
723 int nAppend = strlen(zAppend);
724 int nIn = (zIn?strlen(zIn):0);
725
726 len = nAppend+nIn+1;
727 if( quote ){
728 len += 2;
729 for(i=0; i<nAppend; i++){
730 if( zAppend[i]==quote ) len++;
731 }
732 }
733
734 zIn = (char *)realloc(zIn, len);
735 if( !zIn ){
736 return 0;
737 }
738
739 if( quote ){
740 char *zCsr = &zIn[nIn];
741 *zCsr++ = quote;
742 for(i=0; i<nAppend; i++){
743 *zCsr++ = zAppend[i];
744 if( zAppend[i]==quote ) *zCsr++ = quote;
745 }
746 *zCsr++ = quote;
747 *zCsr++ = '\0';
748 assert( (zCsr-zIn)==len );
749 }else{
750 memcpy(&zIn[nIn], zAppend, nAppend);
751 zIn[len-1] = '\0';
752 }
753
754 return zIn;
755}
756
drhdd3d4592004-08-30 01:54:05 +0000757
758/*
759** Execute a query statement that has a single result column. Print
760** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000761**
762** This is used, for example, to show the schema of the database by
763** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000764*/
765static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
766 sqlite3_stmt *pSelect;
767 int rc;
768 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
769 if( rc!=SQLITE_OK || !pSelect ){
770 return rc;
771 }
772 rc = sqlite3_step(pSelect);
773 while( rc==SQLITE_ROW ){
774 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
775 rc = sqlite3_step(pSelect);
776 }
777 return sqlite3_finalize(pSelect);
778}
779
780
drh33048c02001-10-01 14:29:22 +0000781/*
drh4c653a02000-06-07 01:27:47 +0000782** This is a different callback routine used for dumping the database.
783** Each row received by this callback consists of a table name,
784** the table type ("index" or "table") and SQL to create the table.
785** This routine should print text sufficient to recreate the table.
786*/
787static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000788 int rc;
789 const char *zTable;
790 const char *zType;
791 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000792 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000793
drh4c653a02000-06-07 01:27:47 +0000794 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000795 zTable = azArg[0];
796 zType = azArg[1];
797 zSql = azArg[2];
798
drh00b950d2005-09-11 02:03:03 +0000799 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000800 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000801 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
802 fprintf(p->out, "ANALYZE sqlite_master;\n");
803 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
804 return 0;
drh45e29d82006-11-20 16:21:10 +0000805 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
806 char *zIns;
807 if( !p->writableSchema ){
808 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
809 p->writableSchema = 1;
810 }
811 zIns = sqlite3_mprintf(
812 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
813 "VALUES('table','%q','%q',0,'%q');",
814 zTable, zTable, zSql);
815 fprintf(p->out, "%s\n", zIns);
816 sqlite3_free(zIns);
817 return 0;
drh00b950d2005-09-11 02:03:03 +0000818 }else{
819 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000820 }
danielk19772a02e332004-06-05 08:04:36 +0000821
822 if( strcmp(zType, "table")==0 ){
823 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000824 char *zSelect = 0;
825 char *zTableInfo = 0;
826 char *zTmp = 0;
827
828 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
829 zTableInfo = appendText(zTableInfo, zTable, '"');
830 zTableInfo = appendText(zTableInfo, ");", 0);
831
832 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
833 if( zTableInfo ) free(zTableInfo);
834 if( rc!=SQLITE_OK || !pTableInfo ){
835 return 1;
836 }
837
838 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
839 zTmp = appendText(zTmp, zTable, '"');
840 if( zTmp ){
841 zSelect = appendText(zSelect, zTmp, '\'');
842 }
843 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
844 rc = sqlite3_step(pTableInfo);
845 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000846 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000847 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000848 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000849 rc = sqlite3_step(pTableInfo);
850 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000851 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000852 }else{
853 zSelect = appendText(zSelect, ") ", 0);
854 }
855 }
856 rc = sqlite3_finalize(pTableInfo);
857 if( rc!=SQLITE_OK ){
858 if( zSelect ) free(zSelect);
859 return 1;
860 }
861 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
862 zSelect = appendText(zSelect, zTable, '"');
863
drhdd3d4592004-08-30 01:54:05 +0000864 rc = run_table_dump_query(p->out, p->db, zSelect);
865 if( rc==SQLITE_CORRUPT ){
866 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
867 rc = run_table_dump_query(p->out, p->db, zSelect);
868 }
danielk19772a02e332004-06-05 08:04:36 +0000869 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000870 }
drh4c653a02000-06-07 01:27:47 +0000871 return 0;
872}
873
874/*
drh45e29d82006-11-20 16:21:10 +0000875** Run zQuery. Use dump_callback() as the callback routine so that
876** the contents of the query are output as SQL statements.
877**
drhdd3d4592004-08-30 01:54:05 +0000878** If we get a SQLITE_CORRUPT error, rerun the query after appending
879** "ORDER BY rowid DESC" to the end.
880*/
881static int run_schema_dump_query(
882 struct callback_data *p,
883 const char *zQuery,
884 char **pzErrMsg
885){
886 int rc;
887 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
888 if( rc==SQLITE_CORRUPT ){
889 char *zQ2;
890 int len = strlen(zQuery);
891 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
892 zQ2 = malloc( len+100 );
893 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000894 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000895 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
896 free(zQ2);
897 }
898 return rc;
899}
900
901/*
drh75897232000-05-29 14:26:00 +0000902** Text of a help message
903*/
persicom1d0b8722002-04-18 02:53:04 +0000904static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000905 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000906 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000907 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000908 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000909 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000910 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000911 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000912 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000913 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000914 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000915#ifdef SQLITE_ENABLE_IOTRACE
916 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
917#endif
drh70df4fe2006-06-13 15:12:21 +0000918#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000919 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000920#endif
danielk19776b77a362005-01-13 11:10:25 +0000921 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000922 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000923 " column Left-aligned columns. (See .width)\n"
924 " html HTML <table> code\n"
925 " insert SQL insert statements for TABLE\n"
926 " line One value per line\n"
927 " list Values delimited by .separator string\n"
928 " tabs Tab-separated values\n"
929 " tcl TCL list elements\n"
930 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000931 ".output FILENAME Send output to FILENAME\n"
932 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000933 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000934 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000935 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000936 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000937 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000938 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000939 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000940 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +0000941#if HAS_TIMER
942 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
943#endif
drh75897232000-05-29 14:26:00 +0000944 ".width NUM NUM ... Set column widths for \"column\" mode\n"
945;
946
drhdaffd0e2001-04-11 14:28:42 +0000947/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000948static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000949
drh75897232000-05-29 14:26:00 +0000950/*
drh44c2eb12003-04-30 11:38:26 +0000951** Make sure the database is open. If it is not, then open it. If
952** the database fails to open, print an error message and exit.
953*/
954static void open_db(struct callback_data *p){
955 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000956 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000957 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +0000958 if( db && sqlite3_errcode(db)==SQLITE_OK ){
959 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
960 shellstaticFunc, 0, 0);
961 }
962 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +0000963 fprintf(stderr,"Unable to open database \"%s\": %s\n",
964 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000965 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000966 }
drhc2e87a32006-06-27 15:16:14 +0000967#ifndef SQLITE_OMIT_LOAD_EXTENSION
968 sqlite3_enable_load_extension(p->db, 1);
969#endif
drh44c2eb12003-04-30 11:38:26 +0000970 }
971}
972
973/*
drhfeac5f82004-08-01 00:10:45 +0000974** Do C-language style dequoting.
975**
976** \t -> tab
977** \n -> newline
978** \r -> carriage return
979** \NNN -> ascii character NNN in octal
980** \\ -> backslash
981*/
982static void resolve_backslashes(char *z){
983 int i, j, c;
984 for(i=j=0; (c = z[i])!=0; i++, j++){
985 if( c=='\\' ){
986 c = z[++i];
987 if( c=='n' ){
988 c = '\n';
989 }else if( c=='t' ){
990 c = '\t';
991 }else if( c=='r' ){
992 c = '\r';
993 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +0000994 c -= '0';
drhfeac5f82004-08-01 00:10:45 +0000995 if( z[i+1]>='0' && z[i+1]<='7' ){
996 i++;
997 c = (c<<3) + z[i] - '0';
998 if( z[i+1]>='0' && z[i+1]<='7' ){
999 i++;
1000 c = (c<<3) + z[i] - '0';
1001 }
1002 }
1003 }
1004 }
1005 z[j] = c;
1006 }
1007 z[j] = 0;
1008}
1009
1010/*
drhc28490c2006-10-26 14:25:58 +00001011** Interpret zArg as a boolean value. Return either 0 or 1.
1012*/
1013static int booleanValue(char *zArg){
1014 int val = atoi(zArg);
1015 int j;
1016 for(j=0; zArg[j]; j++){
1017 zArg[j] = tolower(zArg[j]);
1018 }
1019 if( strcmp(zArg,"on")==0 ){
1020 val = 1;
1021 }else if( strcmp(zArg,"yes")==0 ){
1022 val = 1;
1023 }
1024 return val;
1025}
1026
1027/*
drh75897232000-05-29 14:26:00 +00001028** If an input line begins with "." then invoke this routine to
1029** process that line.
drh67505e72002-04-19 12:34:06 +00001030**
drh47ad6842006-11-08 12:25:42 +00001031** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001032*/
drh44c2eb12003-04-30 11:38:26 +00001033static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001034 int i = 1;
1035 int nArg = 0;
1036 int n, c;
drh67505e72002-04-19 12:34:06 +00001037 int rc = 0;
drh75897232000-05-29 14:26:00 +00001038 char *azArg[50];
1039
1040 /* Parse the input line into tokens.
1041 */
1042 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001043 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001044 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001045 if( zLine[i]=='\'' || zLine[i]=='"' ){
1046 int delim = zLine[i++];
1047 azArg[nArg++] = &zLine[i];
1048 while( zLine[i] && zLine[i]!=delim ){ i++; }
1049 if( zLine[i]==delim ){
1050 zLine[i++] = 0;
1051 }
drhfeac5f82004-08-01 00:10:45 +00001052 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001053 }else{
1054 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001055 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001056 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001057 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001058 }
1059 }
1060
1061 /* Process the input line.
1062 */
drh67505e72002-04-19 12:34:06 +00001063 if( nArg==0 ) return rc;
drh75897232000-05-29 14:26:00 +00001064 n = strlen(azArg[0]);
1065 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001066 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1067 bail_on_error = booleanValue(azArg[1]);
1068 }else
1069
jplyon6a65bb32003-05-04 07:25:57 +00001070 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001071 struct callback_data data;
1072 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001073 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001074 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001075 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001076 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001077 data.colWidth[0] = 3;
1078 data.colWidth[1] = 15;
1079 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001080 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001081 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001082 if( zErrMsg ){
1083 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001084 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001085 }
1086 }else
1087
drh4c653a02000-06-07 01:27:47 +00001088 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1089 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001090 open_db(p);
drh33048c02001-10-01 14:29:22 +00001091 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001092 p->writableSchema = 0;
drh4c653a02000-06-07 01:27:47 +00001093 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001094 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001095 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001096 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001097 );
1098 run_table_dump_query(p->out, p->db,
1099 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001100 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001101 );
drh4c653a02000-06-07 01:27:47 +00001102 }else{
1103 int i;
drhdd3d4592004-08-30 01:54:05 +00001104 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001105 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001106 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001107 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001108 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001109 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001110 run_table_dump_query(p->out, p->db,
1111 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001112 "WHERE sql NOT NULL"
1113 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001114 " AND tbl_name LIKE shellstatic()"
1115 );
danielk1977bc6ada42004-06-30 08:20:16 +00001116 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001117 }
1118 }
drh45e29d82006-11-20 16:21:10 +00001119 if( p->writableSchema ){
1120 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1121 p->writableSchema = 0;
1122 }
drh4c653a02000-06-07 01:27:47 +00001123 if( zErrMsg ){
1124 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001125 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001126 }else{
1127 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001128 }
1129 }else
drh75897232000-05-29 14:26:00 +00001130
drhdaffd0e2001-04-11 14:28:42 +00001131 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001132 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001133 }else
1134
drh75897232000-05-29 14:26:00 +00001135 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001136 rc = 2;
drh75897232000-05-29 14:26:00 +00001137 }else
1138
drhdd45df82002-04-18 12:39:03 +00001139 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001140 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001141 if(val == 1) {
1142 if(!p->explainPrev.valid) {
1143 p->explainPrev.valid = 1;
1144 p->explainPrev.mode = p->mode;
1145 p->explainPrev.showHeader = p->showHeader;
1146 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1147 }
1148 /* We could put this code under the !p->explainValid
1149 ** condition so that it does not execute if we are already in
1150 ** explain mode. However, always executing it allows us an easy
1151 ** was to reset to explain mode in case the user previously
1152 ** did an .explain followed by a .width, .mode or .header
1153 ** command.
1154 */
danielk19770d78bae2008-01-03 07:09:48 +00001155 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001156 p->showHeader = 1;
1157 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001158 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001159 p->colWidth[1] = 13; /* opcode */
1160 p->colWidth[2] = 4; /* P1 */
1161 p->colWidth[3] = 4; /* P2 */
1162 p->colWidth[4] = 4; /* P3 */
1163 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001164 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001165 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001166 }else if (p->explainPrev.valid) {
1167 p->explainPrev.valid = 0;
1168 p->mode = p->explainPrev.mode;
1169 p->showHeader = p->explainPrev.showHeader;
1170 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1171 }
drh75897232000-05-29 14:26:00 +00001172 }else
1173
drhc28490c2006-10-26 14:25:58 +00001174 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001175 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001176 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001177 }else
1178
1179 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1180 fprintf(stderr,zHelp);
1181 }else
1182
drhfeac5f82004-08-01 00:10:45 +00001183 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1184 char *zTable = azArg[2]; /* Insert data into this table */
1185 char *zFile = azArg[1]; /* The file from which to extract data */
1186 sqlite3_stmt *pStmt; /* A statement */
1187 int rc; /* Result code */
1188 int nCol; /* Number of columns in the table */
1189 int nByte; /* Number of bytes in an SQL string */
1190 int i, j; /* Loop counters */
1191 int nSep; /* Number of bytes in p->separator[] */
1192 char *zSql; /* An SQL statement */
1193 char *zLine; /* A single line of input from the file */
1194 char **azCol; /* zLine[] broken up into columns */
1195 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001196 FILE *in; /* The input file */
1197 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001198
drha543c822006-06-08 16:10:14 +00001199 open_db(p);
drhfeac5f82004-08-01 00:10:45 +00001200 nSep = strlen(p->separator);
1201 if( nSep==0 ){
1202 fprintf(stderr, "non-null separator required for import\n");
1203 return 0;
1204 }
1205 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1206 if( zSql==0 ) return 0;
1207 nByte = strlen(zSql);
drh5e6078b2006-01-31 19:07:22 +00001208 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001209 sqlite3_free(zSql);
1210 if( rc ){
1211 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1212 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001213 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001214 }else{
1215 nCol = sqlite3_column_count(pStmt);
1216 }
1217 sqlite3_finalize(pStmt);
1218 if( nCol==0 ) return 0;
1219 zSql = malloc( nByte + 20 + nCol*2 );
1220 if( zSql==0 ) return 0;
1221 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
1222 j = strlen(zSql);
1223 for(i=1; i<nCol; i++){
1224 zSql[j++] = ',';
1225 zSql[j++] = '?';
1226 }
1227 zSql[j++] = ')';
1228 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001229 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001230 free(zSql);
1231 if( rc ){
1232 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1233 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001234 return 1;
drhfeac5f82004-08-01 00:10:45 +00001235 }
1236 in = fopen(zFile, "rb");
1237 if( in==0 ){
1238 fprintf(stderr, "cannot open file: %s\n", zFile);
1239 sqlite3_finalize(pStmt);
1240 return 0;
1241 }
1242 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001243 if( azCol==0 ){
1244 fclose(in);
1245 return 0;
1246 }
drhfeac5f82004-08-01 00:10:45 +00001247 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1248 zCommit = "COMMIT";
1249 while( (zLine = local_getline(0, in))!=0 ){
1250 char *z;
1251 i = 0;
drhb860bc92004-08-04 15:16:55 +00001252 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001253 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001254 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001255 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1256 *z = 0;
1257 i++;
drhb860bc92004-08-04 15:16:55 +00001258 if( i<nCol ){
1259 azCol[i] = &z[nSep];
1260 z += nSep-1;
1261 }
drhfeac5f82004-08-01 00:10:45 +00001262 }
1263 }
drh1cd7f832005-08-05 18:50:51 +00001264 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001265 if( i+1!=nCol ){
1266 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1267 zFile, lineno, nCol, i+1);
1268 zCommit = "ROLLBACK";
1269 break;
1270 }
drhfeac5f82004-08-01 00:10:45 +00001271 for(i=0; i<nCol; i++){
1272 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1273 }
1274 sqlite3_step(pStmt);
1275 rc = sqlite3_reset(pStmt);
1276 free(zLine);
1277 if( rc!=SQLITE_OK ){
1278 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1279 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001280 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001281 break;
1282 }
1283 }
1284 free(azCol);
1285 fclose(in);
1286 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001287 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001288 }else
1289
drh75897232000-05-29 14:26:00 +00001290 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1291 struct callback_data data;
1292 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001293 open_db(p);
drh75897232000-05-29 14:26:00 +00001294 memcpy(&data, p, sizeof(data));
1295 data.showHeader = 0;
1296 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001297 zShellStatic = azArg[1];
1298 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001299 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001300 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001301 "UNION ALL "
1302 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001303 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001304 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001305 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001306 );
danielk1977bc6ada42004-06-30 08:20:16 +00001307 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001308 if( zErrMsg ){
1309 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001310 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001311 }
1312 }else
1313
drhae5e4452007-05-03 17:18:36 +00001314#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001315 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001316 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001317 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1318 iotrace = 0;
1319 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001320 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001321 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001322 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001323 iotrace = stdout;
1324 }else{
1325 iotrace = fopen(azArg[1], "w");
1326 if( iotrace==0 ){
1327 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001328 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001329 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001330 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001331 }
1332 }
1333 }else
drhae5e4452007-05-03 17:18:36 +00001334#endif
drhb0603412007-02-28 04:47:26 +00001335
drh70df4fe2006-06-13 15:12:21 +00001336#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001337 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1338 const char *zFile, *zProc;
1339 char *zErrMsg = 0;
1340 int rc;
1341 zFile = azArg[1];
1342 zProc = nArg>=3 ? azArg[2] : 0;
1343 open_db(p);
1344 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1345 if( rc!=SQLITE_OK ){
1346 fprintf(stderr, "%s\n", zErrMsg);
1347 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001348 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001349 }
1350 }else
drh70df4fe2006-06-13 15:12:21 +00001351#endif
drh1e397f82006-06-08 15:28:43 +00001352
drh28bd4bc2000-06-15 15:57:22 +00001353 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh75897232000-05-29 14:26:00 +00001354 int n2 = strlen(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001355 if( strncmp(azArg[1],"line",n2)==0
1356 ||
1357 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001358 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001359 }else if( strncmp(azArg[1],"column",n2)==0
1360 ||
1361 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001362 p->mode = MODE_Column;
1363 }else if( strncmp(azArg[1],"list",n2)==0 ){
1364 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001365 }else if( strncmp(azArg[1],"html",n2)==0 ){
1366 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001367 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1368 p->mode = MODE_Tcl;
1369 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001370 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001371 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001372 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1373 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001374 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001375 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1376 p->mode = MODE_Insert;
1377 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001378 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001379 }else{
drh33048c02001-10-01 14:29:22 +00001380 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001381 }
drhdaffd0e2001-04-11 14:28:42 +00001382 }else {
drhcf68ae92006-12-19 18:47:41 +00001383 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001384 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001385 }
1386 }else
1387
persicom7e2dfdd2002-04-18 02:46:52 +00001388 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001389 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1390 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001391 }else
1392
drh75897232000-05-29 14:26:00 +00001393 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1394 if( p->out!=stdout ){
1395 fclose(p->out);
1396 }
1397 if( strcmp(azArg[1],"stdout")==0 ){
1398 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001399 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001400 }else{
drha1f9b5e2004-02-14 16:31:02 +00001401 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001402 if( p->out==0 ){
1403 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1404 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001405 } else {
drh5bb3eb92007-05-04 13:15:55 +00001406 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001407 }
1408 }
1409 }else
1410
drhdd45df82002-04-18 12:39:03 +00001411 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001412 if( nArg >= 2) {
1413 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1414 }
1415 if( nArg >= 3) {
1416 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1417 }
1418 }else
1419
1420 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001421 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001422 }else
1423
drhdaffd0e2001-04-11 14:28:42 +00001424 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001425 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001426 if( alt==0 ){
1427 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1428 }else{
1429 process_input(p, alt);
1430 fclose(alt);
1431 }
1432 }else
1433
drh75897232000-05-29 14:26:00 +00001434 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1435 struct callback_data data;
1436 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001437 open_db(p);
drh75897232000-05-29 14:26:00 +00001438 memcpy(&data, p, sizeof(data));
1439 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001440 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001441 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001442 int i;
1443 for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
1444 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001445 char *new_argv[2], *new_colv[2];
1446 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1447 " type text,\n"
1448 " name text,\n"
1449 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001450 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001451 " sql text\n"
1452 ")";
1453 new_argv[1] = 0;
1454 new_colv[0] = "sql";
1455 new_colv[1] = 0;
1456 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001457 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001458 char *new_argv[2], *new_colv[2];
1459 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1460 " type text,\n"
1461 " name text,\n"
1462 " tbl_name text,\n"
1463 " rootpage integer,\n"
1464 " sql text\n"
1465 ")";
1466 new_argv[1] = 0;
1467 new_colv[0] = "sql";
1468 new_colv[1] = 0;
1469 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001470 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001471 zShellStatic = azArg[1];
1472 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) "
danielk1977bc6ada42004-06-30 08:20:16 +00001476 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001477 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001478 callback, &data, &zErrMsg);
1479 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001480 }
drh75897232000-05-29 14:26:00 +00001481 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001482 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001483 "SELECT sql FROM "
1484 " (SELECT * FROM sqlite_master UNION ALL"
1485 " SELECT * FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001486 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001487 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001488 callback, &data, &zErrMsg
1489 );
drh75897232000-05-29 14:26:00 +00001490 }
drh75897232000-05-29 14:26:00 +00001491 if( zErrMsg ){
1492 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001493 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001494 }
1495 }else
1496
1497 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001498 sqlite3_snprintf(sizeof(p->separator), p->separator,
1499 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001500 }else
1501
persicom7e2dfdd2002-04-18 02:46:52 +00001502 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1503 int i;
1504 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001505 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001506 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001507 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001508 fprintf(p->out,"%9.9s: ", "nullvalue");
1509 output_c_string(p->out, p->nullvalue);
1510 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001511 fprintf(p->out,"%9.9s: %s\n","output",
1512 strlen(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001513 fprintf(p->out,"%9.9s: ", "separator");
1514 output_c_string(p->out, p->separator);
1515 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001516 fprintf(p->out,"%9.9s: ","width");
1517 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001518 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001519 }
drhfeac5f82004-08-01 00:10:45 +00001520 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001521 }else
1522
drh2dfbbca2000-07-28 14:32:48 +00001523 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001524 char **azResult;
1525 int nRow, rc;
1526 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001527 open_db(p);
drha50da102000-08-08 20:19:09 +00001528 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001529 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001530 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001531 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001532 "UNION ALL "
1533 "SELECT name FROM sqlite_temp_master "
1534 "WHERE type IN ('table','view') "
1535 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001536 &azResult, &nRow, 0, &zErrMsg
1537 );
drha50da102000-08-08 20:19:09 +00001538 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001539 zShellStatic = azArg[1];
1540 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001541 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001542 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001543 "UNION ALL "
1544 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001545 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001546 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001547 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001548 );
danielk1977bc6ada42004-06-30 08:20:16 +00001549 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001550 }
drh75897232000-05-29 14:26:00 +00001551 if( zErrMsg ){
1552 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001553 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001554 }
drhe3710332000-09-29 13:30:53 +00001555 if( rc==SQLITE_OK ){
1556 int len, maxlen = 0;
1557 int i, j;
1558 int nPrintCol, nPrintRow;
1559 for(i=1; i<=nRow; i++){
1560 if( azResult[i]==0 ) continue;
1561 len = strlen(azResult[i]);
1562 if( len>maxlen ) maxlen = len;
1563 }
1564 nPrintCol = 80/(maxlen+2);
1565 if( nPrintCol<1 ) nPrintCol = 1;
1566 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1567 for(i=0; i<nPrintRow; i++){
1568 for(j=i+1; j<=nRow; j+=nPrintRow){
1569 char *zSp = j<=nPrintRow ? "" : " ";
1570 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1571 }
1572 printf("\n");
1573 }
drh47ad6842006-11-08 12:25:42 +00001574 }else{
1575 rc = 1;
drhe3710332000-09-29 13:30:53 +00001576 }
danielk19776f8a5032004-05-10 10:34:51 +00001577 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001578 }else
1579
drh3b1a9882007-11-02 12:53:03 +00001580 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001581 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001582 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001583 }else
drh3b1a9882007-11-02 12:53:03 +00001584
1585#if HAS_TIMER
1586 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
1587 enableTimer = booleanValue(azArg[1]);
1588 }else
1589#endif
drh2dfbbca2000-07-28 14:32:48 +00001590
drh75897232000-05-29 14:26:00 +00001591 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1592 int j;
drh43617e92006-03-06 20:55:46 +00001593 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001594 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1595 p->colWidth[j-1] = atoi(azArg[j]);
1596 }
1597 }else
1598
drh3b1a9882007-11-02 12:53:03 +00001599
drh75897232000-05-29 14:26:00 +00001600 {
drh67505e72002-04-19 12:34:06 +00001601 fprintf(stderr, "unknown command or invalid arguments: "
1602 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001603 }
drh67505e72002-04-19 12:34:06 +00001604
1605 return rc;
drh75897232000-05-29 14:26:00 +00001606}
1607
drh67505e72002-04-19 12:34:06 +00001608/*
drh91a66392007-09-07 01:12:32 +00001609** Return TRUE if a semicolon occurs anywhere in the first N characters
1610** of string z[].
drh324ccef2003-02-05 14:06:20 +00001611*/
drh91a66392007-09-07 01:12:32 +00001612static int _contains_semicolon(const char *z, int N){
1613 int i;
1614 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
1615 return 0;
drh324ccef2003-02-05 14:06:20 +00001616}
1617
1618/*
drh70c7a4b2003-04-26 03:03:06 +00001619** Test to see if a line consists entirely of whitespace.
1620*/
1621static int _all_whitespace(const char *z){
1622 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001623 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001624 if( *z=='/' && z[1]=='*' ){
1625 z += 2;
1626 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1627 if( *z==0 ) return 0;
1628 z++;
1629 continue;
1630 }
1631 if( *z=='-' && z[1]=='-' ){
1632 z += 2;
1633 while( *z && *z!='\n' ){ z++; }
1634 if( *z==0 ) return 1;
1635 continue;
1636 }
1637 return 0;
1638 }
1639 return 1;
1640}
1641
1642/*
drha9b17162003-04-29 18:01:28 +00001643** Return TRUE if the line typed in is an SQL command terminator other
1644** than a semi-colon. The SQL Server style "go" command is understood
1645** as is the Oracle "/".
1646*/
1647static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001648 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drha9b17162003-04-29 18:01:28 +00001649 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
drhc8d74412004-08-31 23:41:26 +00001650 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1651 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001652 return 1; /* SQL Server */
1653 }
1654 return 0;
1655}
1656
1657/*
drh67505e72002-04-19 12:34:06 +00001658** Read input from *in and process it. If *in==0 then input
1659** is interactive - the user is typing it it. Otherwise, input
1660** is coming from a file or device. A prompt is issued and history
1661** is saved only if input is interactive. An interrupt signal will
1662** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001663**
1664** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001665*/
drhc28490c2006-10-26 14:25:58 +00001666static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001667 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001668 char *zSql = 0;
1669 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00001670 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00001671 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001672 int rc;
1673 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001674 int lineno = 0;
1675 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001676
1677 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1678 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001679 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001680 zLine = one_input_line(zSql, in);
1681 if( zLine==0 ){
1682 break; /* We have reached EOF */
1683 }
drh67505e72002-04-19 12:34:06 +00001684 if( seenInterrupt ){
1685 if( in!=0 ) break;
1686 seenInterrupt = 0;
1687 }
drhc28490c2006-10-26 14:25:58 +00001688 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001689 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001690 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001691 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001692 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001693 if( rc==2 ){
1694 break;
1695 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001696 errCnt++;
1697 }
drhdaffd0e2001-04-11 14:28:42 +00001698 continue;
1699 }
drha9b17162003-04-29 18:01:28 +00001700 if( _is_command_terminator(zLine) ){
drh5bb3eb92007-05-04 13:15:55 +00001701 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001702 }
drh91a66392007-09-07 01:12:32 +00001703 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00001704 if( zSql==0 ){
1705 int i;
drh4c755c02004-08-08 20:22:17 +00001706 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001707 if( zLine[i]!=0 ){
1708 nSql = strlen(zLine);
1709 zSql = malloc( nSql+1 );
drhc1f44942006-05-10 14:39:13 +00001710 if( zSql==0 ){
1711 fprintf(stderr, "out of memory\n");
1712 exit(1);
1713 }
drh5bb3eb92007-05-04 13:15:55 +00001714 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001715 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001716 }
1717 }else{
1718 int len = strlen(zLine);
1719 zSql = realloc( zSql, nSql + len + 2 );
1720 if( zSql==0 ){
1721 fprintf(stderr,"%s: out of memory!\n", Argv0);
1722 exit(1);
1723 }
drh5bb3eb92007-05-04 13:15:55 +00001724 zSql[nSql++] = '\n';
1725 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001726 nSql += len;
1727 }
drh91a66392007-09-07 01:12:32 +00001728 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1729 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001730 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001731 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00001732 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00001733 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00001734 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00001735 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001736 char zPrefix[100];
1737 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001738 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1739 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001740 }else{
drh5bb3eb92007-05-04 13:15:55 +00001741 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001742 }
drh7f953e22002-07-13 17:33:45 +00001743 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001744 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001745 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001746 zErrMsg = 0;
1747 }else{
drhc28490c2006-10-26 14:25:58 +00001748 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001749 }
drhc49f44e2006-10-26 18:15:42 +00001750 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001751 }
1752 free(zSql);
1753 zSql = 0;
1754 nSql = 0;
1755 }
1756 }
1757 if( zSql ){
drh70c7a4b2003-04-26 03:03:06 +00001758 if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001759 free(zSql);
1760 }
danielk19772ac27622007-07-03 05:31:16 +00001761 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001762 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001763}
1764
drh67505e72002-04-19 12:34:06 +00001765/*
1766** Return a pathname which is the user's home directory. A
1767** 0 return indicates an error of some kind. Space to hold the
1768** resulting string is obtained from malloc(). The calling
1769** function should free the result.
1770*/
1771static char *find_home_dir(void){
1772 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001773
drh454ad582007-11-26 22:54:27 +00001774#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE)
drh67505e72002-04-19 12:34:06 +00001775 struct passwd *pwent;
1776 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001777 if( (pwent=getpwuid(uid)) != NULL) {
1778 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001779 }
1780#endif
1781
chw65d3c132007-11-12 21:09:10 +00001782#if defined(_WIN32_WCE)
1783 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
1784 */
1785 home_dir = strdup("/");
1786#else
1787
drh164a1b62006-08-19 11:15:20 +00001788#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1789 if (!home_dir) {
1790 home_dir = getenv("USERPROFILE");
1791 }
1792#endif
1793
drh67505e72002-04-19 12:34:06 +00001794 if (!home_dir) {
1795 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001796 }
1797
drhcdb36b72006-06-12 12:57:45 +00001798#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001799 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001800 char *zDrive, *zPath;
1801 int n;
1802 zDrive = getenv("HOMEDRIVE");
1803 zPath = getenv("HOMEPATH");
1804 if( zDrive && zPath ){
1805 n = strlen(zDrive) + strlen(zPath) + 1;
1806 home_dir = malloc( n );
1807 if( home_dir==0 ) return 0;
1808 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1809 return home_dir;
1810 }
1811 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001812 }
1813#endif
1814
chw65d3c132007-11-12 21:09:10 +00001815#endif /* !_WIN32_WCE */
1816
drh67505e72002-04-19 12:34:06 +00001817 if( home_dir ){
drh5bb3eb92007-05-04 13:15:55 +00001818 int n = strlen(home_dir) + 1;
1819 char *z = malloc( n );
1820 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001821 home_dir = z;
1822 }
drhe98d4fa2002-04-21 19:06:22 +00001823
drh67505e72002-04-19 12:34:06 +00001824 return home_dir;
1825}
1826
1827/*
1828** Read input from the file given by sqliterc_override. Or if that
1829** parameter is NULL, take input from ~/.sqliterc
1830*/
drh22fbcb82004-02-01 01:22:50 +00001831static void process_sqliterc(
1832 struct callback_data *p, /* Configuration data */
1833 const char *sqliterc_override /* Name of config file. NULL to use default */
1834){
persicom7e2dfdd2002-04-18 02:46:52 +00001835 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001836 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001837 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001838 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001839 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001840
1841 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001842 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001843 if( home_dir==0 ){
1844 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
1845 return;
1846 }
drha959ac42007-06-20 13:10:00 +00001847 nBuf = strlen(home_dir) + 16;
1848 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001849 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001850 fprintf(stderr,"%s: out of memory!\n", Argv0);
1851 exit(1);
1852 }
drha959ac42007-06-20 13:10:00 +00001853 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001854 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001855 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001856 }
drha1f9b5e2004-02-14 16:31:02 +00001857 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001858 if( in ){
drhc28490c2006-10-26 14:25:58 +00001859 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00001860 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00001861 }
persicom7e2dfdd2002-04-18 02:46:52 +00001862 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001863 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001864 }
drh43617e92006-03-06 20:55:46 +00001865 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001866 return;
1867}
1868
drh67505e72002-04-19 12:34:06 +00001869/*
drhe1e38c42003-05-04 18:30:59 +00001870** Show available command line options
1871*/
1872static const char zOptions[] =
1873 " -init filename read/process named file\n"
1874 " -echo print commands before execution\n"
1875 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001876 " -bail stop after hitting an error\n"
1877 " -interactive force interactive I/O\n"
1878 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001879 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001880 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001881 " -html set output mode to HTML\n"
1882 " -line set output mode to 'line'\n"
1883 " -list set output mode to 'list'\n"
1884 " -separator 'x' set output field separator (|)\n"
1885 " -nullvalue 'text' set text string for NULL values\n"
1886 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001887;
1888static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001889 fprintf(stderr,
1890 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1891 "FILENAME is the name of an SQLite database. A new database is created\n"
1892 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001893 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001894 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001895 }else{
1896 fprintf(stderr, "Use the -help option for additional information\n");
1897 }
1898 exit(1);
1899}
1900
1901/*
drh67505e72002-04-19 12:34:06 +00001902** Initialize the state information in data
1903*/
drh0850b532006-01-31 19:31:43 +00001904static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001905 memset(data, 0, sizeof(*data));
1906 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001907 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001908 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001909 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1910 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001911}
1912
drh75897232000-05-29 14:26:00 +00001913int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001914 char *zErrMsg = 0;
1915 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001916 const char *zInitFile = 0;
1917 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001918 int i;
drhc28490c2006-10-26 14:25:58 +00001919 int rc = 0;
drh75897232000-05-29 14:26:00 +00001920
drhdaffd0e2001-04-11 14:28:42 +00001921 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001922 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001923 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001924
drh44c2eb12003-04-30 11:38:26 +00001925 /* Make sure we have a valid signal handler early, before anything
1926 ** else is done.
1927 */
drh4c504392000-10-16 22:06:40 +00001928#ifdef SIGINT
1929 signal(SIGINT, interrupt_handler);
1930#endif
drh44c2eb12003-04-30 11:38:26 +00001931
drh22fbcb82004-02-01 01:22:50 +00001932 /* Do an initial pass through the command-line argument to locate
1933 ** the name of the database file, the name of the initialization file,
1934 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001935 */
drh22fbcb82004-02-01 01:22:50 +00001936 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001937 char *z;
drh44c2eb12003-04-30 11:38:26 +00001938 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001939 z = argv[i];
1940 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001941 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1942 i++;
drh22fbcb82004-02-01 01:22:50 +00001943 }else if( strcmp(argv[i],"-init")==0 ){
1944 i++;
1945 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001946 }
1947 }
drh22fbcb82004-02-01 01:22:50 +00001948 if( i<argc ){
pweilbacherd190be82008-04-15 18:50:02 +00001949#ifdef OS_OS2
1950 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
1951#else
drh22fbcb82004-02-01 01:22:50 +00001952 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00001953#endif
drh22fbcb82004-02-01 01:22:50 +00001954 }else{
danielk197703aded42004-11-22 05:26:27 +00001955#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00001956 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00001957#else
1958 data.zDbFilename = 0;
1959#endif
drh22fbcb82004-02-01 01:22:50 +00001960 }
1961 if( i<argc ){
1962 zFirstCmd = argv[i++];
1963 }
drh44c2eb12003-04-30 11:38:26 +00001964 data.out = stdout;
1965
drh01b41712005-08-29 23:06:23 +00001966#ifdef SQLITE_OMIT_MEMORYDB
1967 if( data.zDbFilename==0 ){
1968 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
1969 exit(1);
1970 }
1971#endif
1972
drh44c2eb12003-04-30 11:38:26 +00001973 /* Go ahead and open the database file if it already exists. If the
1974 ** file does not exist, delay opening it. This prevents empty database
1975 ** files from being created if a user mistypes the database name argument
1976 ** to the sqlite command-line tool.
1977 */
drhc8d74412004-08-31 23:41:26 +00001978 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00001979 open_db(&data);
1980 }
1981
drh22fbcb82004-02-01 01:22:50 +00001982 /* Process the initialization file if there is one. If no -init option
1983 ** is given on the command line, look for a file named ~/.sqliterc and
1984 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00001985 */
drh22fbcb82004-02-01 01:22:50 +00001986 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00001987
drh22fbcb82004-02-01 01:22:50 +00001988 /* Make a second pass through the command-line argument and set
1989 ** options. This second pass is delayed until after the initialization
1990 ** file is processed so that the command-line arguments will override
1991 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00001992 */
drh22fbcb82004-02-01 01:22:50 +00001993 for(i=1; i<argc && argv[i][0]=='-'; i++){
1994 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00001995 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00001996 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00001997 i++;
1998 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001999 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002000 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002001 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002002 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002003 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002004 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002005 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002006 }else if( strcmp(z,"-csv")==0 ){
2007 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002008 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002009 }else if( strcmp(z,"-separator")==0 ){
2010 i++;
drh5bb3eb92007-05-04 13:15:55 +00002011 sqlite3_snprintf(sizeof(data.separator), data.separator,
2012 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002013 }else if( strcmp(z,"-nullvalue")==0 ){
2014 i++;
drh5bb3eb92007-05-04 13:15:55 +00002015 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2016 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002017 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002018 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002019 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002020 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002021 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002022 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002023 }else if( strcmp(z,"-bail")==0 ){
2024 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002025 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002026 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002027 return 0;
drhc28490c2006-10-26 14:25:58 +00002028 }else if( strcmp(z,"-interactive")==0 ){
2029 stdin_is_interactive = 1;
2030 }else if( strcmp(z,"-batch")==0 ){
2031 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002032 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002033 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002034 }else{
drh22fbcb82004-02-01 01:22:50 +00002035 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002036 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002037 return 1;
2038 }
2039 }
drh44c2eb12003-04-30 11:38:26 +00002040
drh22fbcb82004-02-01 01:22:50 +00002041 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002042 /* Run just the command that follows the database name
2043 */
drh22fbcb82004-02-01 01:22:50 +00002044 if( zFirstCmd[0]=='.' ){
2045 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002046 exit(0);
2047 }else{
2048 int rc;
drh44c2eb12003-04-30 11:38:26 +00002049 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00002050 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00002051 if( rc!=0 && zErrMsg!=0 ){
2052 fprintf(stderr,"SQL error: %s\n", zErrMsg);
2053 exit(1);
2054 }
drh75897232000-05-29 14:26:00 +00002055 }
2056 }else{
drh44c2eb12003-04-30 11:38:26 +00002057 /* Run commands received from standard input
2058 */
drhc28490c2006-10-26 14:25:58 +00002059 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002060 char *zHome;
2061 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002062 int nHistory;
drh75897232000-05-29 14:26:00 +00002063 printf(
drhb217a572000-08-22 13:40:18 +00002064 "SQLite version %s\n"
2065 "Enter \".help\" for instructions\n",
drhc8d74412004-08-31 23:41:26 +00002066 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002067 );
drh67505e72002-04-19 12:34:06 +00002068 zHome = find_home_dir();
drh5bb3eb92007-05-04 13:15:55 +00002069 if( zHome && (zHistory = malloc(nHistory = strlen(zHome)+20))!=0 ){
2070 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
drh67505e72002-04-19 12:34:06 +00002071 }
danielk19774af00c62005-01-23 23:43:21 +00002072#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002073 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002074#endif
drhc28490c2006-10-26 14:25:58 +00002075 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002076 if( zHistory ){
2077 stifle_history(100);
2078 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002079 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002080 }
adamd0a3daa32006-07-28 20:16:14 +00002081 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002082 }else{
drhc28490c2006-10-26 14:25:58 +00002083 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002084 }
2085 }
drh33048c02001-10-01 14:29:22 +00002086 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002087 if( db ){
2088 if( sqlite3_close(db)!=SQLITE_OK ){
2089 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2090 }
2091 }
drhc28490c2006-10-26 14:25:58 +00002092 return rc;
drh75897232000-05-29 14:26:00 +00002093}