blob: 319c343327d0dbd17ce64f14aa3614d967caca83 [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**
pweilbacherd190be82008-04-15 18:50:02 +000015** $Id: shell.c,v 1.177 2008/04/15 18:50:02 pweilbacher 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;
danielk1977bc6ada42004-06-30 08:20:16 +0000958 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
959 shellstaticFunc, 0, 0);
danielk197780290862004-05-22 09:21:21 +0000960 if( SQLITE_OK!=sqlite3_errcode(db) ){
961 fprintf(stderr,"Unable to open database \"%s\": %s\n",
962 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000963 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000964 }
drhc2e87a32006-06-27 15:16:14 +0000965#ifndef SQLITE_OMIT_LOAD_EXTENSION
966 sqlite3_enable_load_extension(p->db, 1);
967#endif
drh44c2eb12003-04-30 11:38:26 +0000968 }
969}
970
971/*
drhfeac5f82004-08-01 00:10:45 +0000972** Do C-language style dequoting.
973**
974** \t -> tab
975** \n -> newline
976** \r -> carriage return
977** \NNN -> ascii character NNN in octal
978** \\ -> backslash
979*/
980static void resolve_backslashes(char *z){
981 int i, j, c;
982 for(i=j=0; (c = z[i])!=0; i++, j++){
983 if( c=='\\' ){
984 c = z[++i];
985 if( c=='n' ){
986 c = '\n';
987 }else if( c=='t' ){
988 c = '\t';
989 }else if( c=='r' ){
990 c = '\r';
991 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +0000992 c -= '0';
drhfeac5f82004-08-01 00:10:45 +0000993 if( z[i+1]>='0' && z[i+1]<='7' ){
994 i++;
995 c = (c<<3) + z[i] - '0';
996 if( z[i+1]>='0' && z[i+1]<='7' ){
997 i++;
998 c = (c<<3) + z[i] - '0';
999 }
1000 }
1001 }
1002 }
1003 z[j] = c;
1004 }
1005 z[j] = 0;
1006}
1007
1008/*
drhc28490c2006-10-26 14:25:58 +00001009** Interpret zArg as a boolean value. Return either 0 or 1.
1010*/
1011static int booleanValue(char *zArg){
1012 int val = atoi(zArg);
1013 int j;
1014 for(j=0; zArg[j]; j++){
1015 zArg[j] = tolower(zArg[j]);
1016 }
1017 if( strcmp(zArg,"on")==0 ){
1018 val = 1;
1019 }else if( strcmp(zArg,"yes")==0 ){
1020 val = 1;
1021 }
1022 return val;
1023}
1024
1025/*
drh75897232000-05-29 14:26:00 +00001026** If an input line begins with "." then invoke this routine to
1027** process that line.
drh67505e72002-04-19 12:34:06 +00001028**
drh47ad6842006-11-08 12:25:42 +00001029** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001030*/
drh44c2eb12003-04-30 11:38:26 +00001031static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001032 int i = 1;
1033 int nArg = 0;
1034 int n, c;
drh67505e72002-04-19 12:34:06 +00001035 int rc = 0;
drh75897232000-05-29 14:26:00 +00001036 char *azArg[50];
1037
1038 /* Parse the input line into tokens.
1039 */
1040 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001041 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001042 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001043 if( zLine[i]=='\'' || zLine[i]=='"' ){
1044 int delim = zLine[i++];
1045 azArg[nArg++] = &zLine[i];
1046 while( zLine[i] && zLine[i]!=delim ){ i++; }
1047 if( zLine[i]==delim ){
1048 zLine[i++] = 0;
1049 }
drhfeac5f82004-08-01 00:10:45 +00001050 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001051 }else{
1052 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001053 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001054 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001055 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001056 }
1057 }
1058
1059 /* Process the input line.
1060 */
drh67505e72002-04-19 12:34:06 +00001061 if( nArg==0 ) return rc;
drh75897232000-05-29 14:26:00 +00001062 n = strlen(azArg[0]);
1063 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001064 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1065 bail_on_error = booleanValue(azArg[1]);
1066 }else
1067
jplyon6a65bb32003-05-04 07:25:57 +00001068 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001069 struct callback_data data;
1070 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001071 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001072 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001073 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001074 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001075 data.colWidth[0] = 3;
1076 data.colWidth[1] = 15;
1077 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001078 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001079 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001080 if( zErrMsg ){
1081 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001082 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001083 }
1084 }else
1085
drh4c653a02000-06-07 01:27:47 +00001086 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1087 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001088 open_db(p);
drh33048c02001-10-01 14:29:22 +00001089 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001090 p->writableSchema = 0;
drh4c653a02000-06-07 01:27:47 +00001091 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001092 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001093 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001094 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001095 );
1096 run_table_dump_query(p->out, p->db,
1097 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001098 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001099 );
drh4c653a02000-06-07 01:27:47 +00001100 }else{
1101 int i;
drhdd3d4592004-08-30 01:54:05 +00001102 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001103 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001104 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001105 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001106 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001107 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001108 run_table_dump_query(p->out, p->db,
1109 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001110 "WHERE sql NOT NULL"
1111 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001112 " AND tbl_name LIKE shellstatic()"
1113 );
danielk1977bc6ada42004-06-30 08:20:16 +00001114 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001115 }
1116 }
drh45e29d82006-11-20 16:21:10 +00001117 if( p->writableSchema ){
1118 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1119 p->writableSchema = 0;
1120 }
drh4c653a02000-06-07 01:27:47 +00001121 if( zErrMsg ){
1122 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001123 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001124 }else{
1125 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001126 }
1127 }else
drh75897232000-05-29 14:26:00 +00001128
drhdaffd0e2001-04-11 14:28:42 +00001129 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001130 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001131 }else
1132
drh75897232000-05-29 14:26:00 +00001133 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001134 rc = 2;
drh75897232000-05-29 14:26:00 +00001135 }else
1136
drhdd45df82002-04-18 12:39:03 +00001137 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001138 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001139 if(val == 1) {
1140 if(!p->explainPrev.valid) {
1141 p->explainPrev.valid = 1;
1142 p->explainPrev.mode = p->mode;
1143 p->explainPrev.showHeader = p->showHeader;
1144 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1145 }
1146 /* We could put this code under the !p->explainValid
1147 ** condition so that it does not execute if we are already in
1148 ** explain mode. However, always executing it allows us an easy
1149 ** was to reset to explain mode in case the user previously
1150 ** did an .explain followed by a .width, .mode or .header
1151 ** command.
1152 */
danielk19770d78bae2008-01-03 07:09:48 +00001153 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001154 p->showHeader = 1;
1155 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001156 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001157 p->colWidth[1] = 13; /* opcode */
1158 p->colWidth[2] = 4; /* P1 */
1159 p->colWidth[3] = 4; /* P2 */
1160 p->colWidth[4] = 4; /* P3 */
1161 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001162 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001163 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001164 }else if (p->explainPrev.valid) {
1165 p->explainPrev.valid = 0;
1166 p->mode = p->explainPrev.mode;
1167 p->showHeader = p->explainPrev.showHeader;
1168 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1169 }
drh75897232000-05-29 14:26:00 +00001170 }else
1171
drhc28490c2006-10-26 14:25:58 +00001172 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001173 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001174 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001175 }else
1176
1177 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1178 fprintf(stderr,zHelp);
1179 }else
1180
drhfeac5f82004-08-01 00:10:45 +00001181 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1182 char *zTable = azArg[2]; /* Insert data into this table */
1183 char *zFile = azArg[1]; /* The file from which to extract data */
1184 sqlite3_stmt *pStmt; /* A statement */
1185 int rc; /* Result code */
1186 int nCol; /* Number of columns in the table */
1187 int nByte; /* Number of bytes in an SQL string */
1188 int i, j; /* Loop counters */
1189 int nSep; /* Number of bytes in p->separator[] */
1190 char *zSql; /* An SQL statement */
1191 char *zLine; /* A single line of input from the file */
1192 char **azCol; /* zLine[] broken up into columns */
1193 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001194 FILE *in; /* The input file */
1195 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001196
drha543c822006-06-08 16:10:14 +00001197 open_db(p);
drhfeac5f82004-08-01 00:10:45 +00001198 nSep = strlen(p->separator);
1199 if( nSep==0 ){
1200 fprintf(stderr, "non-null separator required for import\n");
1201 return 0;
1202 }
1203 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1204 if( zSql==0 ) return 0;
1205 nByte = strlen(zSql);
drh5e6078b2006-01-31 19:07:22 +00001206 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001207 sqlite3_free(zSql);
1208 if( rc ){
1209 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1210 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001211 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001212 }else{
1213 nCol = sqlite3_column_count(pStmt);
1214 }
1215 sqlite3_finalize(pStmt);
1216 if( nCol==0 ) return 0;
1217 zSql = malloc( nByte + 20 + nCol*2 );
1218 if( zSql==0 ) return 0;
1219 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
1220 j = strlen(zSql);
1221 for(i=1; i<nCol; i++){
1222 zSql[j++] = ',';
1223 zSql[j++] = '?';
1224 }
1225 zSql[j++] = ')';
1226 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001227 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001228 free(zSql);
1229 if( rc ){
1230 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1231 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001232 return 1;
drhfeac5f82004-08-01 00:10:45 +00001233 }
1234 in = fopen(zFile, "rb");
1235 if( in==0 ){
1236 fprintf(stderr, "cannot open file: %s\n", zFile);
1237 sqlite3_finalize(pStmt);
1238 return 0;
1239 }
1240 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001241 if( azCol==0 ){
1242 fclose(in);
1243 return 0;
1244 }
drhfeac5f82004-08-01 00:10:45 +00001245 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1246 zCommit = "COMMIT";
1247 while( (zLine = local_getline(0, in))!=0 ){
1248 char *z;
1249 i = 0;
drhb860bc92004-08-04 15:16:55 +00001250 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001251 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001252 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001253 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1254 *z = 0;
1255 i++;
drhb860bc92004-08-04 15:16:55 +00001256 if( i<nCol ){
1257 azCol[i] = &z[nSep];
1258 z += nSep-1;
1259 }
drhfeac5f82004-08-01 00:10:45 +00001260 }
1261 }
drh1cd7f832005-08-05 18:50:51 +00001262 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001263 if( i+1!=nCol ){
1264 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1265 zFile, lineno, nCol, i+1);
1266 zCommit = "ROLLBACK";
1267 break;
1268 }
drhfeac5f82004-08-01 00:10:45 +00001269 for(i=0; i<nCol; i++){
1270 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1271 }
1272 sqlite3_step(pStmt);
1273 rc = sqlite3_reset(pStmt);
1274 free(zLine);
1275 if( rc!=SQLITE_OK ){
1276 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1277 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001278 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001279 break;
1280 }
1281 }
1282 free(azCol);
1283 fclose(in);
1284 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001285 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001286 }else
1287
drh75897232000-05-29 14:26:00 +00001288 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1289 struct callback_data data;
1290 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001291 open_db(p);
drh75897232000-05-29 14:26:00 +00001292 memcpy(&data, p, sizeof(data));
1293 data.showHeader = 0;
1294 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001295 zShellStatic = azArg[1];
1296 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001297 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001298 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001299 "UNION ALL "
1300 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001301 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001302 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001303 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001304 );
danielk1977bc6ada42004-06-30 08:20:16 +00001305 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001306 if( zErrMsg ){
1307 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001308 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001309 }
1310 }else
1311
drhae5e4452007-05-03 17:18:36 +00001312#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001313 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001314 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001315 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1316 iotrace = 0;
1317 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001318 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001319 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001320 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001321 iotrace = stdout;
1322 }else{
1323 iotrace = fopen(azArg[1], "w");
1324 if( iotrace==0 ){
1325 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001326 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001327 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001328 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001329 }
1330 }
1331 }else
drhae5e4452007-05-03 17:18:36 +00001332#endif
drhb0603412007-02-28 04:47:26 +00001333
drh70df4fe2006-06-13 15:12:21 +00001334#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001335 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1336 const char *zFile, *zProc;
1337 char *zErrMsg = 0;
1338 int rc;
1339 zFile = azArg[1];
1340 zProc = nArg>=3 ? azArg[2] : 0;
1341 open_db(p);
1342 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1343 if( rc!=SQLITE_OK ){
1344 fprintf(stderr, "%s\n", zErrMsg);
1345 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001346 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001347 }
1348 }else
drh70df4fe2006-06-13 15:12:21 +00001349#endif
drh1e397f82006-06-08 15:28:43 +00001350
drh28bd4bc2000-06-15 15:57:22 +00001351 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh75897232000-05-29 14:26:00 +00001352 int n2 = strlen(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001353 if( strncmp(azArg[1],"line",n2)==0
1354 ||
1355 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001356 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001357 }else if( strncmp(azArg[1],"column",n2)==0
1358 ||
1359 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001360 p->mode = MODE_Column;
1361 }else if( strncmp(azArg[1],"list",n2)==0 ){
1362 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001363 }else if( strncmp(azArg[1],"html",n2)==0 ){
1364 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001365 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1366 p->mode = MODE_Tcl;
1367 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001368 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001369 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001370 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1371 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001372 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001373 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1374 p->mode = MODE_Insert;
1375 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001376 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001377 }else{
drh33048c02001-10-01 14:29:22 +00001378 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001379 }
drhdaffd0e2001-04-11 14:28:42 +00001380 }else {
drhcf68ae92006-12-19 18:47:41 +00001381 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001382 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001383 }
1384 }else
1385
persicom7e2dfdd2002-04-18 02:46:52 +00001386 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001387 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1388 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001389 }else
1390
drh75897232000-05-29 14:26:00 +00001391 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1392 if( p->out!=stdout ){
1393 fclose(p->out);
1394 }
1395 if( strcmp(azArg[1],"stdout")==0 ){
1396 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001397 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001398 }else{
drha1f9b5e2004-02-14 16:31:02 +00001399 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001400 if( p->out==0 ){
1401 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1402 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001403 } else {
drh5bb3eb92007-05-04 13:15:55 +00001404 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001405 }
1406 }
1407 }else
1408
drhdd45df82002-04-18 12:39:03 +00001409 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001410 if( nArg >= 2) {
1411 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1412 }
1413 if( nArg >= 3) {
1414 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1415 }
1416 }else
1417
1418 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001419 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001420 }else
1421
drhdaffd0e2001-04-11 14:28:42 +00001422 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001423 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001424 if( alt==0 ){
1425 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1426 }else{
1427 process_input(p, alt);
1428 fclose(alt);
1429 }
1430 }else
1431
drh75897232000-05-29 14:26:00 +00001432 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1433 struct callback_data data;
1434 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001435 open_db(p);
drh75897232000-05-29 14:26:00 +00001436 memcpy(&data, p, sizeof(data));
1437 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001438 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001439 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001440 int i;
1441 for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
1442 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001443 char *new_argv[2], *new_colv[2];
1444 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1445 " type text,\n"
1446 " name text,\n"
1447 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001448 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001449 " sql text\n"
1450 ")";
1451 new_argv[1] = 0;
1452 new_colv[0] = "sql";
1453 new_colv[1] = 0;
1454 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001455 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001456 char *new_argv[2], *new_colv[2];
1457 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1458 " type text,\n"
1459 " name text,\n"
1460 " tbl_name text,\n"
1461 " rootpage integer,\n"
1462 " sql text\n"
1463 ")";
1464 new_argv[1] = 0;
1465 new_colv[0] = "sql";
1466 new_colv[1] = 0;
1467 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001468 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001469 zShellStatic = azArg[1];
1470 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001471 "SELECT sql FROM "
1472 " (SELECT * FROM sqlite_master UNION ALL"
1473 " SELECT * FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001474 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001475 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001476 callback, &data, &zErrMsg);
1477 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001478 }
drh75897232000-05-29 14:26:00 +00001479 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001480 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001481 "SELECT sql FROM "
1482 " (SELECT * FROM sqlite_master UNION ALL"
1483 " SELECT * FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001484 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001485 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001486 callback, &data, &zErrMsg
1487 );
drh75897232000-05-29 14:26:00 +00001488 }
drh75897232000-05-29 14:26:00 +00001489 if( zErrMsg ){
1490 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001491 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001492 }
1493 }else
1494
1495 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001496 sqlite3_snprintf(sizeof(p->separator), p->separator,
1497 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001498 }else
1499
persicom7e2dfdd2002-04-18 02:46:52 +00001500 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1501 int i;
1502 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001503 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001504 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001505 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001506 fprintf(p->out,"%9.9s: ", "nullvalue");
1507 output_c_string(p->out, p->nullvalue);
1508 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001509 fprintf(p->out,"%9.9s: %s\n","output",
1510 strlen(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001511 fprintf(p->out,"%9.9s: ", "separator");
1512 output_c_string(p->out, p->separator);
1513 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001514 fprintf(p->out,"%9.9s: ","width");
1515 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001516 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001517 }
drhfeac5f82004-08-01 00:10:45 +00001518 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001519 }else
1520
drh2dfbbca2000-07-28 14:32:48 +00001521 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001522 char **azResult;
1523 int nRow, rc;
1524 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001525 open_db(p);
drha50da102000-08-08 20:19:09 +00001526 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001527 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001528 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001529 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001530 "UNION ALL "
1531 "SELECT name FROM sqlite_temp_master "
1532 "WHERE type IN ('table','view') "
1533 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001534 &azResult, &nRow, 0, &zErrMsg
1535 );
drha50da102000-08-08 20:19:09 +00001536 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001537 zShellStatic = azArg[1];
1538 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001539 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001540 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001541 "UNION ALL "
1542 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001543 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001544 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001545 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001546 );
danielk1977bc6ada42004-06-30 08:20:16 +00001547 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001548 }
drh75897232000-05-29 14:26:00 +00001549 if( zErrMsg ){
1550 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001551 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001552 }
drhe3710332000-09-29 13:30:53 +00001553 if( rc==SQLITE_OK ){
1554 int len, maxlen = 0;
1555 int i, j;
1556 int nPrintCol, nPrintRow;
1557 for(i=1; i<=nRow; i++){
1558 if( azResult[i]==0 ) continue;
1559 len = strlen(azResult[i]);
1560 if( len>maxlen ) maxlen = len;
1561 }
1562 nPrintCol = 80/(maxlen+2);
1563 if( nPrintCol<1 ) nPrintCol = 1;
1564 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1565 for(i=0; i<nPrintRow; i++){
1566 for(j=i+1; j<=nRow; j+=nPrintRow){
1567 char *zSp = j<=nPrintRow ? "" : " ";
1568 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1569 }
1570 printf("\n");
1571 }
drh47ad6842006-11-08 12:25:42 +00001572 }else{
1573 rc = 1;
drhe3710332000-09-29 13:30:53 +00001574 }
danielk19776f8a5032004-05-10 10:34:51 +00001575 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001576 }else
1577
drh3b1a9882007-11-02 12:53:03 +00001578 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001579 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001580 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001581 }else
drh3b1a9882007-11-02 12:53:03 +00001582
1583#if HAS_TIMER
1584 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
1585 enableTimer = booleanValue(azArg[1]);
1586 }else
1587#endif
drh2dfbbca2000-07-28 14:32:48 +00001588
drh75897232000-05-29 14:26:00 +00001589 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1590 int j;
drh43617e92006-03-06 20:55:46 +00001591 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001592 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1593 p->colWidth[j-1] = atoi(azArg[j]);
1594 }
1595 }else
1596
drh3b1a9882007-11-02 12:53:03 +00001597
drh75897232000-05-29 14:26:00 +00001598 {
drh67505e72002-04-19 12:34:06 +00001599 fprintf(stderr, "unknown command or invalid arguments: "
1600 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001601 }
drh67505e72002-04-19 12:34:06 +00001602
1603 return rc;
drh75897232000-05-29 14:26:00 +00001604}
1605
drh67505e72002-04-19 12:34:06 +00001606/*
drh91a66392007-09-07 01:12:32 +00001607** Return TRUE if a semicolon occurs anywhere in the first N characters
1608** of string z[].
drh324ccef2003-02-05 14:06:20 +00001609*/
drh91a66392007-09-07 01:12:32 +00001610static int _contains_semicolon(const char *z, int N){
1611 int i;
1612 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
1613 return 0;
drh324ccef2003-02-05 14:06:20 +00001614}
1615
1616/*
drh70c7a4b2003-04-26 03:03:06 +00001617** Test to see if a line consists entirely of whitespace.
1618*/
1619static int _all_whitespace(const char *z){
1620 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001621 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001622 if( *z=='/' && z[1]=='*' ){
1623 z += 2;
1624 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1625 if( *z==0 ) return 0;
1626 z++;
1627 continue;
1628 }
1629 if( *z=='-' && z[1]=='-' ){
1630 z += 2;
1631 while( *z && *z!='\n' ){ z++; }
1632 if( *z==0 ) return 1;
1633 continue;
1634 }
1635 return 0;
1636 }
1637 return 1;
1638}
1639
1640/*
drha9b17162003-04-29 18:01:28 +00001641** Return TRUE if the line typed in is an SQL command terminator other
1642** than a semi-colon. The SQL Server style "go" command is understood
1643** as is the Oracle "/".
1644*/
1645static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001646 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drha9b17162003-04-29 18:01:28 +00001647 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
drhc8d74412004-08-31 23:41:26 +00001648 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1649 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001650 return 1; /* SQL Server */
1651 }
1652 return 0;
1653}
1654
1655/*
drh67505e72002-04-19 12:34:06 +00001656** Read input from *in and process it. If *in==0 then input
1657** is interactive - the user is typing it it. Otherwise, input
1658** is coming from a file or device. A prompt is issued and history
1659** is saved only if input is interactive. An interrupt signal will
1660** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001661**
1662** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001663*/
drhc28490c2006-10-26 14:25:58 +00001664static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001665 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001666 char *zSql = 0;
1667 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00001668 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00001669 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001670 int rc;
1671 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001672 int lineno = 0;
1673 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001674
1675 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1676 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001677 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001678 zLine = one_input_line(zSql, in);
1679 if( zLine==0 ){
1680 break; /* We have reached EOF */
1681 }
drh67505e72002-04-19 12:34:06 +00001682 if( seenInterrupt ){
1683 if( in!=0 ) break;
1684 seenInterrupt = 0;
1685 }
drhc28490c2006-10-26 14:25:58 +00001686 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001687 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001688 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001689 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001690 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001691 if( rc==2 ){
1692 break;
1693 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001694 errCnt++;
1695 }
drhdaffd0e2001-04-11 14:28:42 +00001696 continue;
1697 }
drha9b17162003-04-29 18:01:28 +00001698 if( _is_command_terminator(zLine) ){
drh5bb3eb92007-05-04 13:15:55 +00001699 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001700 }
drh91a66392007-09-07 01:12:32 +00001701 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00001702 if( zSql==0 ){
1703 int i;
drh4c755c02004-08-08 20:22:17 +00001704 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001705 if( zLine[i]!=0 ){
1706 nSql = strlen(zLine);
1707 zSql = malloc( nSql+1 );
drhc1f44942006-05-10 14:39:13 +00001708 if( zSql==0 ){
1709 fprintf(stderr, "out of memory\n");
1710 exit(1);
1711 }
drh5bb3eb92007-05-04 13:15:55 +00001712 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001713 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001714 }
1715 }else{
1716 int len = strlen(zLine);
1717 zSql = realloc( zSql, nSql + len + 2 );
1718 if( zSql==0 ){
1719 fprintf(stderr,"%s: out of memory!\n", Argv0);
1720 exit(1);
1721 }
drh5bb3eb92007-05-04 13:15:55 +00001722 zSql[nSql++] = '\n';
1723 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001724 nSql += len;
1725 }
drh91a66392007-09-07 01:12:32 +00001726 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1727 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001728 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001729 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00001730 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00001731 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00001732 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00001733 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001734 char zPrefix[100];
1735 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001736 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1737 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001738 }else{
drh5bb3eb92007-05-04 13:15:55 +00001739 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001740 }
drh7f953e22002-07-13 17:33:45 +00001741 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001742 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001743 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001744 zErrMsg = 0;
1745 }else{
drhc28490c2006-10-26 14:25:58 +00001746 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001747 }
drhc49f44e2006-10-26 18:15:42 +00001748 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001749 }
1750 free(zSql);
1751 zSql = 0;
1752 nSql = 0;
1753 }
1754 }
1755 if( zSql ){
drh70c7a4b2003-04-26 03:03:06 +00001756 if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001757 free(zSql);
1758 }
danielk19772ac27622007-07-03 05:31:16 +00001759 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001760 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001761}
1762
drh67505e72002-04-19 12:34:06 +00001763/*
1764** Return a pathname which is the user's home directory. A
1765** 0 return indicates an error of some kind. Space to hold the
1766** resulting string is obtained from malloc(). The calling
1767** function should free the result.
1768*/
1769static char *find_home_dir(void){
1770 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001771
drh454ad582007-11-26 22:54:27 +00001772#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE)
drh67505e72002-04-19 12:34:06 +00001773 struct passwd *pwent;
1774 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001775 if( (pwent=getpwuid(uid)) != NULL) {
1776 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001777 }
1778#endif
1779
chw65d3c132007-11-12 21:09:10 +00001780#if defined(_WIN32_WCE)
1781 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
1782 */
1783 home_dir = strdup("/");
1784#else
1785
drh164a1b62006-08-19 11:15:20 +00001786#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1787 if (!home_dir) {
1788 home_dir = getenv("USERPROFILE");
1789 }
1790#endif
1791
drh67505e72002-04-19 12:34:06 +00001792 if (!home_dir) {
1793 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001794 }
1795
drhcdb36b72006-06-12 12:57:45 +00001796#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001797 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001798 char *zDrive, *zPath;
1799 int n;
1800 zDrive = getenv("HOMEDRIVE");
1801 zPath = getenv("HOMEPATH");
1802 if( zDrive && zPath ){
1803 n = strlen(zDrive) + strlen(zPath) + 1;
1804 home_dir = malloc( n );
1805 if( home_dir==0 ) return 0;
1806 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1807 return home_dir;
1808 }
1809 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001810 }
1811#endif
1812
chw65d3c132007-11-12 21:09:10 +00001813#endif /* !_WIN32_WCE */
1814
drh67505e72002-04-19 12:34:06 +00001815 if( home_dir ){
drh5bb3eb92007-05-04 13:15:55 +00001816 int n = strlen(home_dir) + 1;
1817 char *z = malloc( n );
1818 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001819 home_dir = z;
1820 }
drhe98d4fa2002-04-21 19:06:22 +00001821
drh67505e72002-04-19 12:34:06 +00001822 return home_dir;
1823}
1824
1825/*
1826** Read input from the file given by sqliterc_override. Or if that
1827** parameter is NULL, take input from ~/.sqliterc
1828*/
drh22fbcb82004-02-01 01:22:50 +00001829static void process_sqliterc(
1830 struct callback_data *p, /* Configuration data */
1831 const char *sqliterc_override /* Name of config file. NULL to use default */
1832){
persicom7e2dfdd2002-04-18 02:46:52 +00001833 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001834 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001835 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001836 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001837 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001838
1839 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001840 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001841 if( home_dir==0 ){
1842 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
1843 return;
1844 }
drha959ac42007-06-20 13:10:00 +00001845 nBuf = strlen(home_dir) + 16;
1846 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001847 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001848 fprintf(stderr,"%s: out of memory!\n", Argv0);
1849 exit(1);
1850 }
drha959ac42007-06-20 13:10:00 +00001851 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001852 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001853 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001854 }
drha1f9b5e2004-02-14 16:31:02 +00001855 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001856 if( in ){
drhc28490c2006-10-26 14:25:58 +00001857 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00001858 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00001859 }
persicom7e2dfdd2002-04-18 02:46:52 +00001860 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001861 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001862 }
drh43617e92006-03-06 20:55:46 +00001863 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001864 return;
1865}
1866
drh67505e72002-04-19 12:34:06 +00001867/*
drhe1e38c42003-05-04 18:30:59 +00001868** Show available command line options
1869*/
1870static const char zOptions[] =
1871 " -init filename read/process named file\n"
1872 " -echo print commands before execution\n"
1873 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001874 " -bail stop after hitting an error\n"
1875 " -interactive force interactive I/O\n"
1876 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001877 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001878 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001879 " -html set output mode to HTML\n"
1880 " -line set output mode to 'line'\n"
1881 " -list set output mode to 'list'\n"
1882 " -separator 'x' set output field separator (|)\n"
1883 " -nullvalue 'text' set text string for NULL values\n"
1884 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001885;
1886static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001887 fprintf(stderr,
1888 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1889 "FILENAME is the name of an SQLite database. A new database is created\n"
1890 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001891 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001892 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001893 }else{
1894 fprintf(stderr, "Use the -help option for additional information\n");
1895 }
1896 exit(1);
1897}
1898
1899/*
drh67505e72002-04-19 12:34:06 +00001900** Initialize the state information in data
1901*/
drh0850b532006-01-31 19:31:43 +00001902static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001903 memset(data, 0, sizeof(*data));
1904 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001905 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001906 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001907 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1908 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001909}
1910
drh75897232000-05-29 14:26:00 +00001911int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001912 char *zErrMsg = 0;
1913 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001914 const char *zInitFile = 0;
1915 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001916 int i;
drhc28490c2006-10-26 14:25:58 +00001917 int rc = 0;
drh75897232000-05-29 14:26:00 +00001918
drhdaffd0e2001-04-11 14:28:42 +00001919 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001920 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001921 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001922
drh44c2eb12003-04-30 11:38:26 +00001923 /* Make sure we have a valid signal handler early, before anything
1924 ** else is done.
1925 */
drh4c504392000-10-16 22:06:40 +00001926#ifdef SIGINT
1927 signal(SIGINT, interrupt_handler);
1928#endif
drh44c2eb12003-04-30 11:38:26 +00001929
drh22fbcb82004-02-01 01:22:50 +00001930 /* Do an initial pass through the command-line argument to locate
1931 ** the name of the database file, the name of the initialization file,
1932 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001933 */
drh22fbcb82004-02-01 01:22:50 +00001934 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001935 char *z;
drh44c2eb12003-04-30 11:38:26 +00001936 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001937 z = argv[i];
1938 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001939 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1940 i++;
drh22fbcb82004-02-01 01:22:50 +00001941 }else if( strcmp(argv[i],"-init")==0 ){
1942 i++;
1943 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001944 }
1945 }
drh22fbcb82004-02-01 01:22:50 +00001946 if( i<argc ){
pweilbacherd190be82008-04-15 18:50:02 +00001947#ifdef OS_OS2
1948 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
1949#else
drh22fbcb82004-02-01 01:22:50 +00001950 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00001951#endif
drh22fbcb82004-02-01 01:22:50 +00001952 }else{
danielk197703aded42004-11-22 05:26:27 +00001953#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00001954 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00001955#else
1956 data.zDbFilename = 0;
1957#endif
drh22fbcb82004-02-01 01:22:50 +00001958 }
1959 if( i<argc ){
1960 zFirstCmd = argv[i++];
1961 }
drh44c2eb12003-04-30 11:38:26 +00001962 data.out = stdout;
1963
drh01b41712005-08-29 23:06:23 +00001964#ifdef SQLITE_OMIT_MEMORYDB
1965 if( data.zDbFilename==0 ){
1966 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
1967 exit(1);
1968 }
1969#endif
1970
drh44c2eb12003-04-30 11:38:26 +00001971 /* Go ahead and open the database file if it already exists. If the
1972 ** file does not exist, delay opening it. This prevents empty database
1973 ** files from being created if a user mistypes the database name argument
1974 ** to the sqlite command-line tool.
1975 */
drhc8d74412004-08-31 23:41:26 +00001976 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00001977 open_db(&data);
1978 }
1979
drh22fbcb82004-02-01 01:22:50 +00001980 /* Process the initialization file if there is one. If no -init option
1981 ** is given on the command line, look for a file named ~/.sqliterc and
1982 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00001983 */
drh22fbcb82004-02-01 01:22:50 +00001984 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00001985
drh22fbcb82004-02-01 01:22:50 +00001986 /* Make a second pass through the command-line argument and set
1987 ** options. This second pass is delayed until after the initialization
1988 ** file is processed so that the command-line arguments will override
1989 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00001990 */
drh22fbcb82004-02-01 01:22:50 +00001991 for(i=1; i<argc && argv[i][0]=='-'; i++){
1992 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00001993 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00001994 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00001995 i++;
1996 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001997 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00001998 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001999 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002000 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002001 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002002 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002003 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002004 }else if( strcmp(z,"-csv")==0 ){
2005 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002006 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002007 }else if( strcmp(z,"-separator")==0 ){
2008 i++;
drh5bb3eb92007-05-04 13:15:55 +00002009 sqlite3_snprintf(sizeof(data.separator), data.separator,
2010 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002011 }else if( strcmp(z,"-nullvalue")==0 ){
2012 i++;
drh5bb3eb92007-05-04 13:15:55 +00002013 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2014 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002015 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002016 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002017 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002018 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002019 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002020 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002021 }else if( strcmp(z,"-bail")==0 ){
2022 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002023 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002024 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002025 return 0;
drhc28490c2006-10-26 14:25:58 +00002026 }else if( strcmp(z,"-interactive")==0 ){
2027 stdin_is_interactive = 1;
2028 }else if( strcmp(z,"-batch")==0 ){
2029 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002030 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002031 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002032 }else{
drh22fbcb82004-02-01 01:22:50 +00002033 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002034 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002035 return 1;
2036 }
2037 }
drh44c2eb12003-04-30 11:38:26 +00002038
drh22fbcb82004-02-01 01:22:50 +00002039 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002040 /* Run just the command that follows the database name
2041 */
drh22fbcb82004-02-01 01:22:50 +00002042 if( zFirstCmd[0]=='.' ){
2043 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002044 exit(0);
2045 }else{
2046 int rc;
drh44c2eb12003-04-30 11:38:26 +00002047 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00002048 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00002049 if( rc!=0 && zErrMsg!=0 ){
2050 fprintf(stderr,"SQL error: %s\n", zErrMsg);
2051 exit(1);
2052 }
drh75897232000-05-29 14:26:00 +00002053 }
2054 }else{
drh44c2eb12003-04-30 11:38:26 +00002055 /* Run commands received from standard input
2056 */
drhc28490c2006-10-26 14:25:58 +00002057 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002058 char *zHome;
2059 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002060 int nHistory;
drh75897232000-05-29 14:26:00 +00002061 printf(
drhb217a572000-08-22 13:40:18 +00002062 "SQLite version %s\n"
2063 "Enter \".help\" for instructions\n",
drhc8d74412004-08-31 23:41:26 +00002064 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002065 );
drh67505e72002-04-19 12:34:06 +00002066 zHome = find_home_dir();
drh5bb3eb92007-05-04 13:15:55 +00002067 if( zHome && (zHistory = malloc(nHistory = strlen(zHome)+20))!=0 ){
2068 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
drh67505e72002-04-19 12:34:06 +00002069 }
danielk19774af00c62005-01-23 23:43:21 +00002070#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002071 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002072#endif
drhc28490c2006-10-26 14:25:58 +00002073 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002074 if( zHistory ){
2075 stifle_history(100);
2076 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002077 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002078 }
adamd0a3daa32006-07-28 20:16:14 +00002079 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002080 }else{
drhc28490c2006-10-26 14:25:58 +00002081 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002082 }
2083 }
drh33048c02001-10-01 14:29:22 +00002084 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002085 if( db ){
2086 if( sqlite3_close(db)!=SQLITE_OK ){
2087 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2088 }
2089 }
drhc28490c2006-10-26 14:25:58 +00002090 return rc;
drh75897232000-05-29 14:26:00 +00002091}