blob: e215496746d5217af7259fda270ee7fa02b3245a [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**
drhb0603412007-02-28 04:47:26 +000015** $Id: shell.c,v 1.159 2007/02/28 04:47:27 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
drhcdb36b72006-06-12 12:57:45 +000025#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) && !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
drh820f3812003-01-08 13:02:52 +000032#ifdef __MACOS__
33# include <console.h>
34# include <signal.h>
35# include <unistd.h>
36# include <extras.h>
37# include <Files.h>
38# include <Folders.h>
39#endif
40
drhcdb36b72006-06-12 12:57:45 +000041#ifdef __OS2__
42# include <unistd.h>
43#endif
44
drh16e59552000-07-31 11:57:37 +000045#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000046# include <readline/readline.h>
47# include <readline/history.h>
48#else
drh9347b202003-07-18 01:30:59 +000049# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000050# define add_history(X)
drh67505e72002-04-19 12:34:06 +000051# define read_history(X)
52# define write_history(X)
53# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000054#endif
55
adamd2e8464a2006-09-06 21:39:40 +000056#if defined(_WIN32) || defined(WIN32)
57# include <io.h>
58#else
drh4328c8b2003-04-26 02:50:11 +000059/* Make sure isatty() has a prototype.
60*/
61extern int isatty();
adamd2e8464a2006-09-06 21:39:40 +000062#endif
drh4328c8b2003-04-26 02:50:11 +000063
drh75897232000-05-29 14:26:00 +000064/*
drhc49f44e2006-10-26 18:15:42 +000065** If the following flag is set, then command execution stops
66** at an error if we are not interactive.
67*/
68static int bail_on_error = 0;
69
70/*
drhc28490c2006-10-26 14:25:58 +000071** Threat stdin as an interactive input if the following variable
72** is true. Otherwise, assume stdin is connected to a file or pipe.
73*/
74static int stdin_is_interactive = 1;
75
76/*
drh4c504392000-10-16 22:06:40 +000077** The following is the open SQLite database. We make a pointer
78** to this database a static variable so that it can be accessed
79** by the SIGINT handler to interrupt database processing.
80*/
danielk197792f9a1b2004-06-19 09:08:16 +000081static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +000082
83/*
drh67505e72002-04-19 12:34:06 +000084** True if an interrupt (Control-C) has been received.
85*/
drh43617e92006-03-06 20:55:46 +000086static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +000087
88/*
persicom7e2dfdd2002-04-18 02:46:52 +000089** This is the name of our program. It is set in main(), used
90** in a number of other places, mostly for error messages.
91*/
92static char *Argv0;
93
94/*
95** Prompt strings. Initialized in main. Settable with
96** .prompt main continue
97*/
98static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
99static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
100
drhb0603412007-02-28 04:47:26 +0000101/*
102** Write I/O traces to the following stream.
103*/
104static FILE *iotrace = 0;
105
106/*
107** This routine works like printf in that its first argument is a
108** format string and subsequent arguments are values to be substituted
109** in place of % fields. The result of formatting this string
110** is written to iotrace.
111*/
112static void iotracePrintf(const char *zFormat, ...){
113 va_list ap;
114 if( iotrace==0 ) return;
115 va_start(ap, zFormat);
116 vfprintf(iotrace, zFormat, ap);
117 va_end(ap);
118}
119
drh44c2eb12003-04-30 11:38:26 +0000120
persicom7e2dfdd2002-04-18 02:46:52 +0000121/*
drh83965662003-04-17 02:54:13 +0000122** Determines if a string is a number of not.
123*/
danielk19772e588c72005-12-09 14:25:08 +0000124static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000125 if( *z=='-' || *z=='+' ) z++;
126 if( !isdigit(*z) ){
127 return 0;
128 }
129 z++;
130 if( realnum ) *realnum = 0;
131 while( isdigit(*z) ){ z++; }
132 if( *z=='.' ){
133 z++;
134 if( !isdigit(*z) ) return 0;
135 while( isdigit(*z) ){ z++; }
136 if( realnum ) *realnum = 1;
137 }
138 if( *z=='e' || *z=='E' ){
139 z++;
140 if( *z=='+' || *z=='-' ) z++;
141 if( !isdigit(*z) ) return 0;
142 while( isdigit(*z) ){ z++; }
143 if( realnum ) *realnum = 1;
144 }
145 return *z==0;
146}
drh83965662003-04-17 02:54:13 +0000147
148/*
danielk1977bc6ada42004-06-30 08:20:16 +0000149** A global char* and an SQL function to access its current value
150** from within an SQL statement. This program used to use the
151** sqlite_exec_printf() API to substitue a string into an SQL statement.
152** The correct way to do this with sqlite3 is to use the bind API, but
153** since the shell is built around the callback paradigm it would be a lot
154** of work. Instead just use this hack, which is quite harmless.
155*/
156static const char *zShellStatic = 0;
157static void shellstaticFunc(
158 sqlite3_context *context,
159 int argc,
160 sqlite3_value **argv
161){
162 assert( 0==argc );
163 assert( zShellStatic );
164 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
165}
166
167
168/*
drhfeac5f82004-08-01 00:10:45 +0000169** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000170** the text in memory obtained from malloc() and returns a pointer
171** to the text. NULL is returned at end of file, or if malloc()
172** fails.
173**
174** The interface is like "readline" but no command-line editing
175** is done.
176*/
drh9347b202003-07-18 01:30:59 +0000177static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000178 char *zLine;
179 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000180 int n;
181 int eol;
182
183 if( zPrompt && *zPrompt ){
184 printf("%s",zPrompt);
185 fflush(stdout);
186 }
187 nLine = 100;
188 zLine = malloc( nLine );
189 if( zLine==0 ) return 0;
190 n = 0;
191 eol = 0;
192 while( !eol ){
193 if( n+100>nLine ){
194 nLine = nLine*2 + 100;
195 zLine = realloc(zLine, nLine);
196 if( zLine==0 ) return 0;
197 }
drhdaffd0e2001-04-11 14:28:42 +0000198 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000199 if( n==0 ){
200 free(zLine);
201 return 0;
202 }
203 zLine[n] = 0;
204 eol = 1;
205 break;
206 }
207 while( zLine[n] ){ n++; }
208 if( n>0 && zLine[n-1]=='\n' ){
209 n--;
210 zLine[n] = 0;
211 eol = 1;
212 }
213 }
214 zLine = realloc( zLine, n+1 );
215 return zLine;
216}
217
218/*
drhc28490c2006-10-26 14:25:58 +0000219** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000220**
221** zPrior is a string of prior text retrieved. If not the empty
222** string, then issue a continuation prompt.
223*/
drhdaffd0e2001-04-11 14:28:42 +0000224static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000225 char *zPrompt;
226 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000227 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000228 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000229 }
230 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000231 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000232 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000233 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000234 }
235 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000236#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000237 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000238#endif
drh8e7e7a22000-05-30 18:45:23 +0000239 return zResult;
240}
241
persicom7e2dfdd2002-04-18 02:46:52 +0000242struct previous_mode_data {
243 int valid; /* Is there legit data in here? */
244 int mode;
245 int showHeader;
246 int colWidth[100];
247};
drh45e29d82006-11-20 16:21:10 +0000248
drh8e7e7a22000-05-30 18:45:23 +0000249/*
drh75897232000-05-29 14:26:00 +0000250** An pointer to an instance of this structure is passed from
251** the main program to the callback. This is used to communicate
252** state and mode information.
253*/
254struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000255 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000256 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000257 int cnt; /* Number of records displayed so far */
258 FILE *out; /* Write results here */
259 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000260 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000261 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000262 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000263 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000264 int colWidth[100]; /* Requested width of each column when in column mode*/
265 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000266 char nullvalue[20]; /* The text to print when a NULL comes back from
267 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000268 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000269 /* Holds the mode information just before
270 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000271 char outfile[FILENAME_MAX]; /* Filename for *out */
272 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000273};
274
275/*
276** These are the allowed modes.
277*/
drh967e8b72000-06-21 13:59:10 +0000278#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000279#define MODE_Column 1 /* One record per line in neat columns */
280#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000281#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
282#define MODE_Html 4 /* Generate an XHTML table */
283#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000284#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000285#define MODE_Csv 7 /* Quote strings, numbers are plain */
286#define MODE_NUM_OF 8 /* The number of modes (not a mode itself) */
persicom7e2dfdd2002-04-18 02:46:52 +0000287
drh0850b532006-01-31 19:31:43 +0000288static const char *modeDescr[MODE_NUM_OF] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000289 "line",
290 "column",
291 "list",
292 "semi",
293 "html",
drhfeac5f82004-08-01 00:10:45 +0000294 "insert",
295 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000296 "csv",
persicom7e2dfdd2002-04-18 02:46:52 +0000297};
drh75897232000-05-29 14:26:00 +0000298
299/*
300** Number of elements in an array
301*/
302#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
303
304/*
drh28bd4bc2000-06-15 15:57:22 +0000305** Output the given string as a quoted string using SQL quoting conventions.
306*/
307static void output_quoted_string(FILE *out, const char *z){
308 int i;
309 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000310 for(i=0; z[i]; i++){
311 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000312 }
313 if( nSingle==0 ){
314 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000315 }else{
316 fprintf(out,"'");
317 while( *z ){
318 for(i=0; z[i] && z[i]!='\''; i++){}
319 if( i==0 ){
320 fprintf(out,"''");
321 z++;
322 }else if( z[i]=='\'' ){
323 fprintf(out,"%.*s''",i,z);
324 z += i+1;
325 }else{
drhcd7d2732002-02-26 23:24:26 +0000326 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000327 break;
328 }
329 }
drhcd7d2732002-02-26 23:24:26 +0000330 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000331 }
332}
333
334/*
drhfeac5f82004-08-01 00:10:45 +0000335** Output the given string as a quoted according to C or TCL quoting rules.
336*/
337static void output_c_string(FILE *out, const char *z){
338 unsigned int c;
339 fputc('"', out);
340 while( (c = *(z++))!=0 ){
341 if( c=='\\' ){
342 fputc(c, out);
343 fputc(c, out);
344 }else if( c=='\t' ){
345 fputc('\\', out);
346 fputc('t', out);
347 }else if( c=='\n' ){
348 fputc('\\', out);
349 fputc('n', out);
350 }else if( c=='\r' ){
351 fputc('\\', out);
352 fputc('r', out);
353 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000354 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000355 }else{
356 fputc(c, out);
357 }
358 }
359 fputc('"', out);
360}
361
362/*
drhc08a4f12000-06-15 16:49:48 +0000363** Output the given string with characters that are special to
364** HTML escaped.
365*/
366static void output_html_string(FILE *out, const char *z){
367 int i;
368 while( *z ){
369 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
370 if( i>0 ){
371 fprintf(out,"%.*s",i,z);
372 }
373 if( z[i]=='<' ){
374 fprintf(out,"&lt;");
375 }else if( z[i]=='&' ){
376 fprintf(out,"&amp;");
377 }else{
378 break;
379 }
380 z += i + 1;
381 }
382}
383
384/*
drhc49f44e2006-10-26 18:15:42 +0000385** If a field contains any character identified by a 1 in the following
386** array, then the string must be quoted for CSV.
387*/
388static const char needCsvQuote[] = {
389 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
390 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
391 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
392 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
395 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
396 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
397 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
398 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
399 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
400 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
401 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
402 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
403 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
404 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
405};
406
407/*
drh8e64d1c2004-10-07 00:32:39 +0000408** Output a single term of CSV. Actually, p->separator is used for
409** the separator, which may or may not be a comma. p->nullvalue is
410** the null value. Strings are quoted using ANSI-C rules. Numbers
411** appear outside of quotes.
412*/
413static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000414 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000415 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000416 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000417 }else{
drhc49f44e2006-10-26 18:15:42 +0000418 int i;
419 for(i=0; z[i]; i++){
420 if( needCsvQuote[((unsigned char*)z)[i]] ){
421 i = 0;
422 break;
423 }
424 }
425 if( i==0 ){
426 putc('"', out);
427 for(i=0; z[i]; i++){
428 if( z[i]=='"' ) putc('"', out);
429 putc(z[i], out);
430 }
431 putc('"', out);
432 }else{
433 fprintf(out, "%s", z);
434 }
drh8e64d1c2004-10-07 00:32:39 +0000435 }
436 if( bSep ){
437 fprintf(p->out, p->separator);
438 }
439}
440
danielk19774af00c62005-01-23 23:43:21 +0000441#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000442/*
drh4c504392000-10-16 22:06:40 +0000443** This routine runs when the user presses Ctrl-C
444*/
445static void interrupt_handler(int NotUsed){
drh67505e72002-04-19 12:34:06 +0000446 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000447 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000448}
danielk19774af00c62005-01-23 23:43:21 +0000449#endif
drh4c504392000-10-16 22:06:40 +0000450
451/*
drh75897232000-05-29 14:26:00 +0000452** This is the callback routine that the SQLite library
453** invokes for each row of a query result.
454*/
455static int callback(void *pArg, int nArg, char **azArg, char **azCol){
456 int i;
457 struct callback_data *p = (struct callback_data*)pArg;
458 switch( p->mode ){
459 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000460 int w = 5;
drh6a535342001-10-19 16:44:56 +0000461 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000462 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000463 int len = strlen(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000464 if( len>w ) w = len;
465 }
drh75897232000-05-29 14:26:00 +0000466 if( p->cnt++>0 ) fprintf(p->out,"\n");
467 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000468 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000469 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000470 }
471 break;
472 }
473 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000474 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000475 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000476 int w, n;
477 if( i<ArraySize(p->colWidth) ){
drh75897232000-05-29 14:26:00 +0000478 w = p->colWidth[i];
479 }else{
drha0c66f52000-07-29 13:20:21 +0000480 w = 0;
drh75897232000-05-29 14:26:00 +0000481 }
drha0c66f52000-07-29 13:20:21 +0000482 if( w<=0 ){
drhff6e9112000-08-28 16:21:58 +0000483 w = strlen(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000484 if( w<10 ) w = 10;
persicom7e2dfdd2002-04-18 02:46:52 +0000485 n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000486 if( w<n ) w = n;
487 }
488 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000489 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000490 }
491 if( p->showHeader ){
492 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
493 }
494 }
495 if( p->showHeader ){
496 for(i=0; i<nArg; i++){
497 int w;
498 if( i<ArraySize(p->actualWidth) ){
499 w = p->actualWidth[i];
500 }else{
501 w = 10;
502 }
503 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
504 "----------------------------------------------------------",
505 i==nArg-1 ? "\n": " ");
506 }
drh75897232000-05-29 14:26:00 +0000507 }
508 }
drh6a535342001-10-19 16:44:56 +0000509 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000510 for(i=0; i<nArg; i++){
511 int w;
drha0c66f52000-07-29 13:20:21 +0000512 if( i<ArraySize(p->actualWidth) ){
513 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000514 }else{
515 w = 10;
516 }
drhc61053b2000-06-04 12:58:36 +0000517 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000518 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000519 }
520 break;
521 }
drhe3710332000-09-29 13:30:53 +0000522 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000523 case MODE_List: {
524 if( p->cnt++==0 && p->showHeader ){
525 for(i=0; i<nArg; i++){
526 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
527 }
528 }
drh6a535342001-10-19 16:44:56 +0000529 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000530 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000531 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000532 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000533 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000534 if( i<nArg-1 ){
535 fprintf(p->out, "%s", p->separator);
536 }else if( p->mode==MODE_Semi ){
537 fprintf(p->out, ";\n");
538 }else{
539 fprintf(p->out, "\n");
540 }
drh75897232000-05-29 14:26:00 +0000541 }
542 break;
543 }
drh1e5d0e92000-05-31 23:33:17 +0000544 case MODE_Html: {
545 if( p->cnt++==0 && p->showHeader ){
546 fprintf(p->out,"<TR>");
547 for(i=0; i<nArg; i++){
548 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
549 }
550 fprintf(p->out,"</TR>\n");
551 }
drh6a535342001-10-19 16:44:56 +0000552 if( azArg==0 ) break;
drh28bd4bc2000-06-15 15:57:22 +0000553 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000554 for(i=0; i<nArg; i++){
drhc08a4f12000-06-15 16:49:48 +0000555 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000556 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
drhc08a4f12000-06-15 16:49:48 +0000557 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000558 }
drh7d686b22002-11-11 13:56:47 +0000559 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000560 break;
561 }
drhfeac5f82004-08-01 00:10:45 +0000562 case MODE_Tcl: {
563 if( p->cnt++==0 && p->showHeader ){
564 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000565 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000566 fprintf(p->out, "%s", p->separator);
567 }
568 fprintf(p->out,"\n");
569 }
570 if( azArg==0 ) break;
571 for(i=0; i<nArg; i++){
572 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
573 fprintf(p->out, "%s", p->separator);
574 }
575 fprintf(p->out,"\n");
576 break;
577 }
drh8e64d1c2004-10-07 00:32:39 +0000578 case MODE_Csv: {
579 if( p->cnt++==0 && p->showHeader ){
580 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000581 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000582 }
583 fprintf(p->out,"\n");
584 }
585 if( azArg==0 ) break;
586 for(i=0; i<nArg; i++){
587 output_csv(p, azArg[i], i<nArg-1);
588 }
589 fprintf(p->out,"\n");
590 break;
591 }
drh28bd4bc2000-06-15 15:57:22 +0000592 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000593 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000594 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000595 for(i=0; i<nArg; i++){
596 char *zSep = i>0 ? ",": "";
597 if( azArg[i]==0 ){
598 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000599 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000600 fprintf(p->out,"%s%s",zSep, azArg[i]);
601 }else{
602 if( zSep[0] ) fprintf(p->out,"%s",zSep);
603 output_quoted_string(p->out, azArg[i]);
604 }
605 }
606 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000607 break;
drh28bd4bc2000-06-15 15:57:22 +0000608 }
persicom1d0b8722002-04-18 02:53:04 +0000609 }
drh75897232000-05-29 14:26:00 +0000610 return 0;
611}
612
613/*
drh33048c02001-10-01 14:29:22 +0000614** Set the destination table field of the callback_data structure to
615** the name of the table given. Escape any quote characters in the
616** table name.
617*/
618static void set_table_name(struct callback_data *p, const char *zName){
619 int i, n;
620 int needQuote;
621 char *z;
622
623 if( p->zDestTable ){
624 free(p->zDestTable);
625 p->zDestTable = 0;
626 }
627 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000628 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000629 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000630 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000631 needQuote = 1;
632 if( zName[i]=='\'' ) n++;
633 }
634 }
635 if( needQuote ) n += 2;
636 z = p->zDestTable = malloc( n+1 );
637 if( z==0 ){
638 fprintf(stderr,"Out of memory!\n");
639 exit(1);
640 }
641 n = 0;
642 if( needQuote ) z[n++] = '\'';
643 for(i=0; zName[i]; i++){
644 z[n++] = zName[i];
645 if( zName[i]=='\'' ) z[n++] = '\'';
646 }
647 if( needQuote ) z[n++] = '\'';
648 z[n] = 0;
649}
650
danielk19772a02e332004-06-05 08:04:36 +0000651/* zIn is either a pointer to a NULL-terminated string in memory obtained
652** from malloc(), or a NULL pointer. The string pointed to by zAppend is
653** added to zIn, and the result returned in memory obtained from malloc().
654** zIn, if it was not NULL, is freed.
655**
656** If the third argument, quote, is not '\0', then it is used as a
657** quote character for zAppend.
658*/
drhc28490c2006-10-26 14:25:58 +0000659static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000660 int len;
661 int i;
662 int nAppend = strlen(zAppend);
663 int nIn = (zIn?strlen(zIn):0);
664
665 len = nAppend+nIn+1;
666 if( quote ){
667 len += 2;
668 for(i=0; i<nAppend; i++){
669 if( zAppend[i]==quote ) len++;
670 }
671 }
672
673 zIn = (char *)realloc(zIn, len);
674 if( !zIn ){
675 return 0;
676 }
677
678 if( quote ){
679 char *zCsr = &zIn[nIn];
680 *zCsr++ = quote;
681 for(i=0; i<nAppend; i++){
682 *zCsr++ = zAppend[i];
683 if( zAppend[i]==quote ) *zCsr++ = quote;
684 }
685 *zCsr++ = quote;
686 *zCsr++ = '\0';
687 assert( (zCsr-zIn)==len );
688 }else{
689 memcpy(&zIn[nIn], zAppend, nAppend);
690 zIn[len-1] = '\0';
691 }
692
693 return zIn;
694}
695
drhdd3d4592004-08-30 01:54:05 +0000696
697/*
698** Execute a query statement that has a single result column. Print
699** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000700**
701** This is used, for example, to show the schema of the database by
702** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000703*/
704static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
705 sqlite3_stmt *pSelect;
706 int rc;
707 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
708 if( rc!=SQLITE_OK || !pSelect ){
709 return rc;
710 }
711 rc = sqlite3_step(pSelect);
712 while( rc==SQLITE_ROW ){
713 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
714 rc = sqlite3_step(pSelect);
715 }
716 return sqlite3_finalize(pSelect);
717}
718
719
drh33048c02001-10-01 14:29:22 +0000720/*
drh4c653a02000-06-07 01:27:47 +0000721** This is a different callback routine used for dumping the database.
722** Each row received by this callback consists of a table name,
723** the table type ("index" or "table") and SQL to create the table.
724** This routine should print text sufficient to recreate the table.
725*/
726static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000727 int rc;
728 const char *zTable;
729 const char *zType;
730 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000731 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000732
drh4c653a02000-06-07 01:27:47 +0000733 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000734 zTable = azArg[0];
735 zType = azArg[1];
736 zSql = azArg[2];
737
drh00b950d2005-09-11 02:03:03 +0000738 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000739 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000740 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
741 fprintf(p->out, "ANALYZE sqlite_master;\n");
742 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
743 return 0;
drh45e29d82006-11-20 16:21:10 +0000744 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
745 char *zIns;
746 if( !p->writableSchema ){
747 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
748 p->writableSchema = 1;
749 }
750 zIns = sqlite3_mprintf(
751 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
752 "VALUES('table','%q','%q',0,'%q');",
753 zTable, zTable, zSql);
754 fprintf(p->out, "%s\n", zIns);
755 sqlite3_free(zIns);
756 return 0;
drh00b950d2005-09-11 02:03:03 +0000757 }else{
758 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000759 }
danielk19772a02e332004-06-05 08:04:36 +0000760
761 if( strcmp(zType, "table")==0 ){
762 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000763 char *zSelect = 0;
764 char *zTableInfo = 0;
765 char *zTmp = 0;
766
767 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
768 zTableInfo = appendText(zTableInfo, zTable, '"');
769 zTableInfo = appendText(zTableInfo, ");", 0);
770
771 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
772 if( zTableInfo ) free(zTableInfo);
773 if( rc!=SQLITE_OK || !pTableInfo ){
774 return 1;
775 }
776
777 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
778 zTmp = appendText(zTmp, zTable, '"');
779 if( zTmp ){
780 zSelect = appendText(zSelect, zTmp, '\'');
781 }
782 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
783 rc = sqlite3_step(pTableInfo);
784 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000785 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000786 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000787 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000788 rc = sqlite3_step(pTableInfo);
789 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000790 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000791 }else{
792 zSelect = appendText(zSelect, ") ", 0);
793 }
794 }
795 rc = sqlite3_finalize(pTableInfo);
796 if( rc!=SQLITE_OK ){
797 if( zSelect ) free(zSelect);
798 return 1;
799 }
800 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
801 zSelect = appendText(zSelect, zTable, '"');
802
drhdd3d4592004-08-30 01:54:05 +0000803 rc = run_table_dump_query(p->out, p->db, zSelect);
804 if( rc==SQLITE_CORRUPT ){
805 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
806 rc = run_table_dump_query(p->out, p->db, zSelect);
807 }
danielk19772a02e332004-06-05 08:04:36 +0000808 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000809 }
drh4c653a02000-06-07 01:27:47 +0000810 return 0;
811}
812
813/*
drh45e29d82006-11-20 16:21:10 +0000814** Run zQuery. Use dump_callback() as the callback routine so that
815** the contents of the query are output as SQL statements.
816**
drhdd3d4592004-08-30 01:54:05 +0000817** If we get a SQLITE_CORRUPT error, rerun the query after appending
818** "ORDER BY rowid DESC" to the end.
819*/
820static int run_schema_dump_query(
821 struct callback_data *p,
822 const char *zQuery,
823 char **pzErrMsg
824){
825 int rc;
826 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
827 if( rc==SQLITE_CORRUPT ){
828 char *zQ2;
829 int len = strlen(zQuery);
830 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
831 zQ2 = malloc( len+100 );
832 if( zQ2==0 ) return rc;
833 sprintf(zQ2, "%s ORDER BY rowid DESC", zQuery);
834 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
835 free(zQ2);
836 }
837 return rc;
838}
839
840/*
drh75897232000-05-29 14:26:00 +0000841** Text of a help message
842*/
persicom1d0b8722002-04-18 02:53:04 +0000843static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000844 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000845 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000846 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000847 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000848 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000849 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000850 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000851 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000852 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000853 ".indices TABLE Show names of all indices on TABLE\n"
drh70df4fe2006-06-13 15:12:21 +0000854#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000855 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000856#endif
danielk19776b77a362005-01-13 11:10:25 +0000857 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000858 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000859 " column Left-aligned columns. (See .width)\n"
860 " html HTML <table> code\n"
861 " insert SQL insert statements for TABLE\n"
862 " line One value per line\n"
863 " list Values delimited by .separator string\n"
864 " tabs Tab-separated values\n"
865 " tcl TCL list elements\n"
866 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000867 ".output FILENAME Send output to FILENAME\n"
868 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000869 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000870 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000871 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000872 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000873 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000874 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000875 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000876 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh75897232000-05-29 14:26:00 +0000877 ".width NUM NUM ... Set column widths for \"column\" mode\n"
878;
879
drhdaffd0e2001-04-11 14:28:42 +0000880/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000881static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000882
drh75897232000-05-29 14:26:00 +0000883/*
drh44c2eb12003-04-30 11:38:26 +0000884** Make sure the database is open. If it is not, then open it. If
885** the database fails to open, print an error message and exit.
886*/
887static void open_db(struct callback_data *p){
888 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000889 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000890 db = p->db;
danielk1977bc6ada42004-06-30 08:20:16 +0000891 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
892 shellstaticFunc, 0, 0);
danielk197780290862004-05-22 09:21:21 +0000893 if( SQLITE_OK!=sqlite3_errcode(db) ){
894 fprintf(stderr,"Unable to open database \"%s\": %s\n",
895 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000896 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000897 }
drhc2e87a32006-06-27 15:16:14 +0000898#ifndef SQLITE_OMIT_LOAD_EXTENSION
899 sqlite3_enable_load_extension(p->db, 1);
900#endif
drh44c2eb12003-04-30 11:38:26 +0000901 }
902}
903
904/*
drhfeac5f82004-08-01 00:10:45 +0000905** Do C-language style dequoting.
906**
907** \t -> tab
908** \n -> newline
909** \r -> carriage return
910** \NNN -> ascii character NNN in octal
911** \\ -> backslash
912*/
913static void resolve_backslashes(char *z){
914 int i, j, c;
915 for(i=j=0; (c = z[i])!=0; i++, j++){
916 if( c=='\\' ){
917 c = z[++i];
918 if( c=='n' ){
919 c = '\n';
920 }else if( c=='t' ){
921 c = '\t';
922 }else if( c=='r' ){
923 c = '\r';
924 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +0000925 c -= '0';
drhfeac5f82004-08-01 00:10:45 +0000926 if( z[i+1]>='0' && z[i+1]<='7' ){
927 i++;
928 c = (c<<3) + z[i] - '0';
929 if( z[i+1]>='0' && z[i+1]<='7' ){
930 i++;
931 c = (c<<3) + z[i] - '0';
932 }
933 }
934 }
935 }
936 z[j] = c;
937 }
938 z[j] = 0;
939}
940
941/*
drhc28490c2006-10-26 14:25:58 +0000942** Interpret zArg as a boolean value. Return either 0 or 1.
943*/
944static int booleanValue(char *zArg){
945 int val = atoi(zArg);
946 int j;
947 for(j=0; zArg[j]; j++){
948 zArg[j] = tolower(zArg[j]);
949 }
950 if( strcmp(zArg,"on")==0 ){
951 val = 1;
952 }else if( strcmp(zArg,"yes")==0 ){
953 val = 1;
954 }
955 return val;
956}
957
958/*
drh75897232000-05-29 14:26:00 +0000959** If an input line begins with "." then invoke this routine to
960** process that line.
drh67505e72002-04-19 12:34:06 +0000961**
drh47ad6842006-11-08 12:25:42 +0000962** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +0000963*/
drh44c2eb12003-04-30 11:38:26 +0000964static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +0000965 int i = 1;
966 int nArg = 0;
967 int n, c;
drh67505e72002-04-19 12:34:06 +0000968 int rc = 0;
drh75897232000-05-29 14:26:00 +0000969 char *azArg[50];
970
971 /* Parse the input line into tokens.
972 */
973 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +0000974 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +0000975 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +0000976 if( zLine[i]=='\'' || zLine[i]=='"' ){
977 int delim = zLine[i++];
978 azArg[nArg++] = &zLine[i];
979 while( zLine[i] && zLine[i]!=delim ){ i++; }
980 if( zLine[i]==delim ){
981 zLine[i++] = 0;
982 }
drhfeac5f82004-08-01 00:10:45 +0000983 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +0000984 }else{
985 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +0000986 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +0000987 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +0000988 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +0000989 }
990 }
991
992 /* Process the input line.
993 */
drh67505e72002-04-19 12:34:06 +0000994 if( nArg==0 ) return rc;
drh75897232000-05-29 14:26:00 +0000995 n = strlen(azArg[0]);
996 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +0000997 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
998 bail_on_error = booleanValue(azArg[1]);
999 }else
1000
jplyon6a65bb32003-05-04 07:25:57 +00001001 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001002 struct callback_data data;
1003 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001004 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001005 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001006 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001007 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001008 data.colWidth[0] = 3;
1009 data.colWidth[1] = 15;
1010 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001011 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001012 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001013 if( zErrMsg ){
1014 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001015 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001016 }
1017 }else
1018
drh4c653a02000-06-07 01:27:47 +00001019 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1020 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001021 open_db(p);
drh33048c02001-10-01 14:29:22 +00001022 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001023 p->writableSchema = 0;
drh4c653a02000-06-07 01:27:47 +00001024 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001025 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001026 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001027 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001028 );
1029 run_table_dump_query(p->out, p->db,
1030 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001031 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001032 );
drh4c653a02000-06-07 01:27:47 +00001033 }else{
1034 int i;
drhdd3d4592004-08-30 01:54:05 +00001035 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001036 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001037 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001038 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001039 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001040 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001041 run_table_dump_query(p->out, p->db,
1042 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001043 "WHERE sql NOT NULL"
1044 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001045 " AND tbl_name LIKE shellstatic()"
1046 );
danielk1977bc6ada42004-06-30 08:20:16 +00001047 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001048 }
1049 }
drh45e29d82006-11-20 16:21:10 +00001050 if( p->writableSchema ){
1051 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1052 p->writableSchema = 0;
1053 }
drh4c653a02000-06-07 01:27:47 +00001054 if( zErrMsg ){
1055 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001056 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001057 }else{
1058 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001059 }
1060 }else
drh75897232000-05-29 14:26:00 +00001061
drhdaffd0e2001-04-11 14:28:42 +00001062 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001063 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001064 }else
1065
drh75897232000-05-29 14:26:00 +00001066 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001067 rc = 2;
drh75897232000-05-29 14:26:00 +00001068 }else
1069
drhdd45df82002-04-18 12:39:03 +00001070 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001071 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001072 if(val == 1) {
1073 if(!p->explainPrev.valid) {
1074 p->explainPrev.valid = 1;
1075 p->explainPrev.mode = p->mode;
1076 p->explainPrev.showHeader = p->showHeader;
1077 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1078 }
1079 /* We could put this code under the !p->explainValid
1080 ** condition so that it does not execute if we are already in
1081 ** explain mode. However, always executing it allows us an easy
1082 ** was to reset to explain mode in case the user previously
1083 ** did an .explain followed by a .width, .mode or .header
1084 ** command.
1085 */
1086 p->mode = MODE_Column;
1087 p->showHeader = 1;
1088 memset(p->colWidth,0,ArraySize(p->colWidth));
1089 p->colWidth[0] = 4;
drhe69cc5b2005-08-27 01:50:53 +00001090 p->colWidth[1] = 14;
persicom7e2dfdd2002-04-18 02:46:52 +00001091 p->colWidth[2] = 10;
1092 p->colWidth[3] = 10;
drhe69cc5b2005-08-27 01:50:53 +00001093 p->colWidth[4] = 33;
persicom7e2dfdd2002-04-18 02:46:52 +00001094 }else if (p->explainPrev.valid) {
1095 p->explainPrev.valid = 0;
1096 p->mode = p->explainPrev.mode;
1097 p->showHeader = p->explainPrev.showHeader;
1098 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1099 }
drh75897232000-05-29 14:26:00 +00001100 }else
1101
drhc28490c2006-10-26 14:25:58 +00001102 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001103 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001104 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001105 }else
1106
1107 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1108 fprintf(stderr,zHelp);
1109 }else
1110
drhfeac5f82004-08-01 00:10:45 +00001111 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1112 char *zTable = azArg[2]; /* Insert data into this table */
1113 char *zFile = azArg[1]; /* The file from which to extract data */
1114 sqlite3_stmt *pStmt; /* A statement */
1115 int rc; /* Result code */
1116 int nCol; /* Number of columns in the table */
1117 int nByte; /* Number of bytes in an SQL string */
1118 int i, j; /* Loop counters */
1119 int nSep; /* Number of bytes in p->separator[] */
1120 char *zSql; /* An SQL statement */
1121 char *zLine; /* A single line of input from the file */
1122 char **azCol; /* zLine[] broken up into columns */
1123 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001124 FILE *in; /* The input file */
1125 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001126
drha543c822006-06-08 16:10:14 +00001127 open_db(p);
drhfeac5f82004-08-01 00:10:45 +00001128 nSep = strlen(p->separator);
1129 if( nSep==0 ){
1130 fprintf(stderr, "non-null separator required for import\n");
1131 return 0;
1132 }
1133 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1134 if( zSql==0 ) return 0;
1135 nByte = strlen(zSql);
drh5e6078b2006-01-31 19:07:22 +00001136 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001137 sqlite3_free(zSql);
1138 if( rc ){
1139 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1140 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001141 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001142 }else{
1143 nCol = sqlite3_column_count(pStmt);
1144 }
1145 sqlite3_finalize(pStmt);
1146 if( nCol==0 ) return 0;
1147 zSql = malloc( nByte + 20 + nCol*2 );
1148 if( zSql==0 ) return 0;
1149 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
1150 j = strlen(zSql);
1151 for(i=1; i<nCol; i++){
1152 zSql[j++] = ',';
1153 zSql[j++] = '?';
1154 }
1155 zSql[j++] = ')';
1156 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001157 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001158 free(zSql);
1159 if( rc ){
1160 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1161 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001162 return 1;
drhfeac5f82004-08-01 00:10:45 +00001163 }
1164 in = fopen(zFile, "rb");
1165 if( in==0 ){
1166 fprintf(stderr, "cannot open file: %s\n", zFile);
1167 sqlite3_finalize(pStmt);
1168 return 0;
1169 }
1170 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001171 if( azCol==0 ){
1172 fclose(in);
1173 return 0;
1174 }
drhfeac5f82004-08-01 00:10:45 +00001175 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1176 zCommit = "COMMIT";
1177 while( (zLine = local_getline(0, in))!=0 ){
1178 char *z;
1179 i = 0;
drhb860bc92004-08-04 15:16:55 +00001180 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001181 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001182 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001183 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1184 *z = 0;
1185 i++;
drhb860bc92004-08-04 15:16:55 +00001186 if( i<nCol ){
1187 azCol[i] = &z[nSep];
1188 z += nSep-1;
1189 }
drhfeac5f82004-08-01 00:10:45 +00001190 }
1191 }
drh1cd7f832005-08-05 18:50:51 +00001192 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001193 if( i+1!=nCol ){
1194 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1195 zFile, lineno, nCol, i+1);
1196 zCommit = "ROLLBACK";
1197 break;
1198 }
drhfeac5f82004-08-01 00:10:45 +00001199 for(i=0; i<nCol; i++){
1200 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1201 }
1202 sqlite3_step(pStmt);
1203 rc = sqlite3_reset(pStmt);
1204 free(zLine);
1205 if( rc!=SQLITE_OK ){
1206 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1207 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001208 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001209 break;
1210 }
1211 }
1212 free(azCol);
1213 fclose(in);
1214 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001215 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001216 }else
1217
drh75897232000-05-29 14:26:00 +00001218 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1219 struct callback_data data;
1220 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001221 open_db(p);
drh75897232000-05-29 14:26:00 +00001222 memcpy(&data, p, sizeof(data));
1223 data.showHeader = 0;
1224 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001225 zShellStatic = azArg[1];
1226 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001227 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001228 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001229 "UNION ALL "
1230 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001231 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001232 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001233 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001234 );
danielk1977bc6ada42004-06-30 08:20:16 +00001235 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001236 if( zErrMsg ){
1237 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001238 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001239 }
1240 }else
1241
drhb0603412007-02-28 04:47:26 +00001242 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
1243 extern void (*sqlite3_io_trace)(const char*, ...);
1244 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1245 iotrace = 0;
1246 if( nArg<2 ){
1247 sqlite3_io_trace = 0;
1248 }else if( strcmp(azArg[1], "-")==0 ){
1249 sqlite3_io_trace = iotracePrintf;
1250 iotrace = stdout;
1251 }else{
1252 iotrace = fopen(azArg[1], "w");
1253 if( iotrace==0 ){
1254 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
1255 sqlite3_io_trace = 0;
1256 }else{
1257 sqlite3_io_trace = iotracePrintf;
1258 }
1259 }
1260 }else
1261
drh70df4fe2006-06-13 15:12:21 +00001262#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001263 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1264 const char *zFile, *zProc;
1265 char *zErrMsg = 0;
1266 int rc;
1267 zFile = azArg[1];
1268 zProc = nArg>=3 ? azArg[2] : 0;
1269 open_db(p);
1270 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1271 if( rc!=SQLITE_OK ){
1272 fprintf(stderr, "%s\n", zErrMsg);
1273 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001274 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001275 }
1276 }else
drh70df4fe2006-06-13 15:12:21 +00001277#endif
drh1e397f82006-06-08 15:28:43 +00001278
drh28bd4bc2000-06-15 15:57:22 +00001279 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh75897232000-05-29 14:26:00 +00001280 int n2 = strlen(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001281 if( strncmp(azArg[1],"line",n2)==0
1282 ||
1283 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001284 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001285 }else if( strncmp(azArg[1],"column",n2)==0
1286 ||
1287 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001288 p->mode = MODE_Column;
1289 }else if( strncmp(azArg[1],"list",n2)==0 ){
1290 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001291 }else if( strncmp(azArg[1],"html",n2)==0 ){
1292 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001293 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1294 p->mode = MODE_Tcl;
1295 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001296 p->mode = MODE_Csv;
drhfeac5f82004-08-01 00:10:45 +00001297 strcpy(p->separator, ",");
1298 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1299 p->mode = MODE_List;
1300 strcpy(p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001301 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1302 p->mode = MODE_Insert;
1303 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001304 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001305 }else{
drh33048c02001-10-01 14:29:22 +00001306 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001307 }
drhdaffd0e2001-04-11 14:28:42 +00001308 }else {
drhcf68ae92006-12-19 18:47:41 +00001309 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001310 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001311 }
1312 }else
1313
persicom7e2dfdd2002-04-18 02:46:52 +00001314 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
1315 sprintf(p->nullvalue, "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
1316 }else
1317
drh75897232000-05-29 14:26:00 +00001318 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1319 if( p->out!=stdout ){
1320 fclose(p->out);
1321 }
1322 if( strcmp(azArg[1],"stdout")==0 ){
1323 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001324 strcpy(p->outfile,"stdout");
drh75897232000-05-29 14:26:00 +00001325 }else{
drha1f9b5e2004-02-14 16:31:02 +00001326 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001327 if( p->out==0 ){
1328 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1329 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001330 } else {
1331 strcpy(p->outfile,azArg[1]);
drh75897232000-05-29 14:26:00 +00001332 }
1333 }
1334 }else
1335
drhdd45df82002-04-18 12:39:03 +00001336 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001337 if( nArg >= 2) {
1338 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1339 }
1340 if( nArg >= 3) {
1341 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1342 }
1343 }else
1344
1345 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001346 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001347 }else
1348
drhdaffd0e2001-04-11 14:28:42 +00001349 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001350 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001351 if( alt==0 ){
1352 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1353 }else{
1354 process_input(p, alt);
1355 fclose(alt);
1356 }
1357 }else
1358
drh75897232000-05-29 14:26:00 +00001359 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1360 struct callback_data data;
1361 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001362 open_db(p);
drh75897232000-05-29 14:26:00 +00001363 memcpy(&data, p, sizeof(data));
1364 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001365 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001366 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001367 int i;
1368 for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
1369 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001370 char *new_argv[2], *new_colv[2];
1371 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1372 " type text,\n"
1373 " name text,\n"
1374 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001375 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001376 " sql text\n"
1377 ")";
1378 new_argv[1] = 0;
1379 new_colv[0] = "sql";
1380 new_colv[1] = 0;
1381 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001382 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001383 char *new_argv[2], *new_colv[2];
1384 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1385 " type text,\n"
1386 " name text,\n"
1387 " tbl_name text,\n"
1388 " rootpage integer,\n"
1389 " sql text\n"
1390 ")";
1391 new_argv[1] = 0;
1392 new_colv[0] = "sql";
1393 new_colv[1] = 0;
1394 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001395 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001396 zShellStatic = azArg[1];
1397 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001398 "SELECT sql FROM "
1399 " (SELECT * FROM sqlite_master UNION ALL"
1400 " SELECT * FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001401 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001402 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001403 callback, &data, &zErrMsg);
1404 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001405 }
drh75897232000-05-29 14:26:00 +00001406 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001407 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001408 "SELECT sql FROM "
1409 " (SELECT * FROM sqlite_master UNION ALL"
1410 " SELECT * FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001411 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001412 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001413 callback, &data, &zErrMsg
1414 );
drh75897232000-05-29 14:26:00 +00001415 }
drh75897232000-05-29 14:26:00 +00001416 if( zErrMsg ){
1417 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001418 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001419 }
1420 }else
1421
1422 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
1423 sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]);
1424 }else
1425
persicom7e2dfdd2002-04-18 02:46:52 +00001426 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1427 int i;
1428 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001429 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001430 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001431 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001432 fprintf(p->out,"%9.9s: ", "nullvalue");
1433 output_c_string(p->out, p->nullvalue);
1434 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001435 fprintf(p->out,"%9.9s: %s\n","output",
1436 strlen(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001437 fprintf(p->out,"%9.9s: ", "separator");
1438 output_c_string(p->out, p->separator);
1439 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001440 fprintf(p->out,"%9.9s: ","width");
1441 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001442 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001443 }
drhfeac5f82004-08-01 00:10:45 +00001444 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001445 }else
1446
drh2dfbbca2000-07-28 14:32:48 +00001447 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001448 char **azResult;
1449 int nRow, rc;
1450 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001451 open_db(p);
drha50da102000-08-08 20:19:09 +00001452 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001453 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001454 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001455 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001456 "UNION ALL "
1457 "SELECT name FROM sqlite_temp_master "
1458 "WHERE type IN ('table','view') "
1459 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001460 &azResult, &nRow, 0, &zErrMsg
1461 );
drha50da102000-08-08 20:19:09 +00001462 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001463 zShellStatic = azArg[1];
1464 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001465 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001466 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001467 "UNION ALL "
1468 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001469 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001470 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001471 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001472 );
danielk1977bc6ada42004-06-30 08:20:16 +00001473 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001474 }
drh75897232000-05-29 14:26:00 +00001475 if( zErrMsg ){
1476 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001477 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001478 }
drhe3710332000-09-29 13:30:53 +00001479 if( rc==SQLITE_OK ){
1480 int len, maxlen = 0;
1481 int i, j;
1482 int nPrintCol, nPrintRow;
1483 for(i=1; i<=nRow; i++){
1484 if( azResult[i]==0 ) continue;
1485 len = strlen(azResult[i]);
1486 if( len>maxlen ) maxlen = len;
1487 }
1488 nPrintCol = 80/(maxlen+2);
1489 if( nPrintCol<1 ) nPrintCol = 1;
1490 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1491 for(i=0; i<nPrintRow; i++){
1492 for(j=i+1; j<=nRow; j+=nPrintRow){
1493 char *zSp = j<=nPrintRow ? "" : " ";
1494 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1495 }
1496 printf("\n");
1497 }
drh47ad6842006-11-08 12:25:42 +00001498 }else{
1499 rc = 1;
drhe3710332000-09-29 13:30:53 +00001500 }
danielk19776f8a5032004-05-10 10:34:51 +00001501 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001502 }else
1503
drh2dfbbca2000-07-28 14:32:48 +00001504 if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001505 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001506 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001507 }else
1508
drh75897232000-05-29 14:26:00 +00001509 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1510 int j;
drh43617e92006-03-06 20:55:46 +00001511 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001512 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1513 p->colWidth[j-1] = atoi(azArg[j]);
1514 }
1515 }else
1516
1517 {
drh67505e72002-04-19 12:34:06 +00001518 fprintf(stderr, "unknown command or invalid arguments: "
1519 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001520 }
drh67505e72002-04-19 12:34:06 +00001521
1522 return rc;
drh75897232000-05-29 14:26:00 +00001523}
1524
drh67505e72002-04-19 12:34:06 +00001525/*
drh324ccef2003-02-05 14:06:20 +00001526** Return TRUE if the last non-whitespace character in z[] is a semicolon.
1527** z[] is N characters long.
1528*/
1529static int _ends_with_semicolon(const char *z, int N){
drh4c755c02004-08-08 20:22:17 +00001530 while( N>0 && isspace((unsigned char)z[N-1]) ){ N--; }
drh324ccef2003-02-05 14:06:20 +00001531 return N>0 && z[N-1]==';';
1532}
1533
1534/*
drh70c7a4b2003-04-26 03:03:06 +00001535** Test to see if a line consists entirely of whitespace.
1536*/
1537static int _all_whitespace(const char *z){
1538 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001539 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001540 if( *z=='/' && z[1]=='*' ){
1541 z += 2;
1542 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1543 if( *z==0 ) return 0;
1544 z++;
1545 continue;
1546 }
1547 if( *z=='-' && z[1]=='-' ){
1548 z += 2;
1549 while( *z && *z!='\n' ){ z++; }
1550 if( *z==0 ) return 1;
1551 continue;
1552 }
1553 return 0;
1554 }
1555 return 1;
1556}
1557
1558/*
drha9b17162003-04-29 18:01:28 +00001559** Return TRUE if the line typed in is an SQL command terminator other
1560** than a semi-colon. The SQL Server style "go" command is understood
1561** as is the Oracle "/".
1562*/
1563static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001564 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drha9b17162003-04-29 18:01:28 +00001565 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
drhc8d74412004-08-31 23:41:26 +00001566 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1567 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001568 return 1; /* SQL Server */
1569 }
1570 return 0;
1571}
1572
1573/*
drh67505e72002-04-19 12:34:06 +00001574** Read input from *in and process it. If *in==0 then input
1575** is interactive - the user is typing it it. Otherwise, input
1576** is coming from a file or device. A prompt is issued and history
1577** is saved only if input is interactive. An interrupt signal will
1578** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001579**
1580** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001581*/
drhc28490c2006-10-26 14:25:58 +00001582static int process_input(struct callback_data *p, FILE *in){
drhdaffd0e2001-04-11 14:28:42 +00001583 char *zLine;
1584 char *zSql = 0;
1585 int nSql = 0;
1586 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001587 int rc;
1588 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001589 int lineno = 0;
1590 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001591
1592 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1593 fflush(p->out);
1594 zLine = one_input_line(zSql, in);
1595 if( zLine==0 ){
1596 break; /* We have reached EOF */
1597 }
drh67505e72002-04-19 12:34:06 +00001598 if( seenInterrupt ){
1599 if( in!=0 ) break;
1600 seenInterrupt = 0;
1601 }
drhc28490c2006-10-26 14:25:58 +00001602 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001603 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001604 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001605 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001606 rc = do_meta_command(zLine, p);
drhdaffd0e2001-04-11 14:28:42 +00001607 free(zLine);
drh47ad6842006-11-08 12:25:42 +00001608 if( rc==2 ){
1609 break;
1610 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001611 errCnt++;
1612 }
drhdaffd0e2001-04-11 14:28:42 +00001613 continue;
1614 }
drha9b17162003-04-29 18:01:28 +00001615 if( _is_command_terminator(zLine) ){
1616 strcpy(zLine,";");
1617 }
drhdaffd0e2001-04-11 14:28:42 +00001618 if( zSql==0 ){
1619 int i;
drh4c755c02004-08-08 20:22:17 +00001620 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001621 if( zLine[i]!=0 ){
1622 nSql = strlen(zLine);
1623 zSql = malloc( nSql+1 );
drhc1f44942006-05-10 14:39:13 +00001624 if( zSql==0 ){
1625 fprintf(stderr, "out of memory\n");
1626 exit(1);
1627 }
drhdaffd0e2001-04-11 14:28:42 +00001628 strcpy(zSql, zLine);
drhc28490c2006-10-26 14:25:58 +00001629 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001630 }
1631 }else{
1632 int len = strlen(zLine);
1633 zSql = realloc( zSql, nSql + len + 2 );
1634 if( zSql==0 ){
1635 fprintf(stderr,"%s: out of memory!\n", Argv0);
1636 exit(1);
1637 }
1638 strcpy(&zSql[nSql++], "\n");
1639 strcpy(&zSql[nSql], zLine);
1640 nSql += len;
1641 }
1642 free(zLine);
danielk19776f8a5032004-05-10 10:34:51 +00001643 if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001644 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001645 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001646 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001647 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001648 char zPrefix[100];
1649 if( in!=0 || !stdin_is_interactive ){
1650 sprintf(zPrefix, "SQL error near line %d:", startline);
1651 }else{
1652 sprintf(zPrefix, "SQL error:");
1653 }
drh7f953e22002-07-13 17:33:45 +00001654 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001655 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001656 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001657 zErrMsg = 0;
1658 }else{
drhc28490c2006-10-26 14:25:58 +00001659 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001660 }
drhc49f44e2006-10-26 18:15:42 +00001661 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001662 }
1663 free(zSql);
1664 zSql = 0;
1665 nSql = 0;
1666 }
1667 }
1668 if( zSql ){
drh70c7a4b2003-04-26 03:03:06 +00001669 if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001670 free(zSql);
1671 }
drhc49f44e2006-10-26 18:15:42 +00001672 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001673}
1674
drh67505e72002-04-19 12:34:06 +00001675/*
1676** Return a pathname which is the user's home directory. A
1677** 0 return indicates an error of some kind. Space to hold the
1678** resulting string is obtained from malloc(). The calling
1679** function should free the result.
1680*/
1681static char *find_home_dir(void){
1682 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001683
drhcdb36b72006-06-12 12:57:45 +00001684#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) && !defined(__OS2__)
drh67505e72002-04-19 12:34:06 +00001685 struct passwd *pwent;
1686 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001687 if( (pwent=getpwuid(uid)) != NULL) {
1688 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001689 }
1690#endif
1691
drh820f3812003-01-08 13:02:52 +00001692#ifdef __MACOS__
1693 char home_path[_MAX_PATH+1];
1694 home_dir = getcwd(home_path, _MAX_PATH);
1695#endif
1696
drh164a1b62006-08-19 11:15:20 +00001697#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1698 if (!home_dir) {
1699 home_dir = getenv("USERPROFILE");
1700 }
1701#endif
1702
drh67505e72002-04-19 12:34:06 +00001703 if (!home_dir) {
1704 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001705 }
1706
drhcdb36b72006-06-12 12:57:45 +00001707#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001708 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001709 char *zDrive, *zPath;
1710 int n;
1711 zDrive = getenv("HOMEDRIVE");
1712 zPath = getenv("HOMEPATH");
1713 if( zDrive && zPath ){
1714 n = strlen(zDrive) + strlen(zPath) + 1;
1715 home_dir = malloc( n );
1716 if( home_dir==0 ) return 0;
1717 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1718 return home_dir;
1719 }
1720 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001721 }
1722#endif
1723
drh67505e72002-04-19 12:34:06 +00001724 if( home_dir ){
1725 char *z = malloc( strlen(home_dir)+1 );
1726 if( z ) strcpy(z, home_dir);
1727 home_dir = z;
1728 }
drhe98d4fa2002-04-21 19:06:22 +00001729
drh67505e72002-04-19 12:34:06 +00001730 return home_dir;
1731}
1732
1733/*
1734** Read input from the file given by sqliterc_override. Or if that
1735** parameter is NULL, take input from ~/.sqliterc
1736*/
drh22fbcb82004-02-01 01:22:50 +00001737static void process_sqliterc(
1738 struct callback_data *p, /* Configuration data */
1739 const char *sqliterc_override /* Name of config file. NULL to use default */
1740){
persicom7e2dfdd2002-04-18 02:46:52 +00001741 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001742 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001743 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001744 FILE *in = NULL;
1745
1746 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001747 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001748 if( home_dir==0 ){
1749 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
1750 return;
1751 }
drh22fbcb82004-02-01 01:22:50 +00001752 zBuf = malloc(strlen(home_dir) + 15);
1753 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001754 fprintf(stderr,"%s: out of memory!\n", Argv0);
1755 exit(1);
1756 }
drh22fbcb82004-02-01 01:22:50 +00001757 sprintf(zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001758 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001759 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001760 }
drha1f9b5e2004-02-14 16:31:02 +00001761 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001762 if( in ){
drhc28490c2006-10-26 14:25:58 +00001763 if( stdin_is_interactive ){
drh22fbcb82004-02-01 01:22:50 +00001764 printf("Loading resources from %s\n",sqliterc);
1765 }
persicom7e2dfdd2002-04-18 02:46:52 +00001766 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001767 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001768 }
drh43617e92006-03-06 20:55:46 +00001769 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001770 return;
1771}
1772
drh67505e72002-04-19 12:34:06 +00001773/*
drhe1e38c42003-05-04 18:30:59 +00001774** Show available command line options
1775*/
1776static const char zOptions[] =
1777 " -init filename read/process named file\n"
1778 " -echo print commands before execution\n"
1779 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001780 " -bail stop after hitting an error\n"
1781 " -interactive force interactive I/O\n"
1782 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001783 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001784 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001785 " -html set output mode to HTML\n"
1786 " -line set output mode to 'line'\n"
1787 " -list set output mode to 'list'\n"
1788 " -separator 'x' set output field separator (|)\n"
1789 " -nullvalue 'text' set text string for NULL values\n"
1790 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001791;
1792static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001793 fprintf(stderr,
1794 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1795 "FILENAME is the name of an SQLite database. A new database is created\n"
1796 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001797 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001798 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001799 }else{
1800 fprintf(stderr, "Use the -help option for additional information\n");
1801 }
1802 exit(1);
1803}
1804
1805/*
drh67505e72002-04-19 12:34:06 +00001806** Initialize the state information in data
1807*/
drh0850b532006-01-31 19:31:43 +00001808static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001809 memset(data, 0, sizeof(*data));
1810 data->mode = MODE_List;
1811 strcpy(data->separator,"|");
1812 data->showHeader = 0;
1813 strcpy(mainPrompt,"sqlite> ");
1814 strcpy(continuePrompt," ...> ");
1815}
1816
drh75897232000-05-29 14:26:00 +00001817int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001818 char *zErrMsg = 0;
1819 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001820 const char *zInitFile = 0;
1821 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001822 int i;
drhc28490c2006-10-26 14:25:58 +00001823 int rc = 0;
drh75897232000-05-29 14:26:00 +00001824
drh820f3812003-01-08 13:02:52 +00001825#ifdef __MACOS__
1826 argc = ccommand(&argv);
drh820f3812003-01-08 13:02:52 +00001827#endif
1828
drhdaffd0e2001-04-11 14:28:42 +00001829 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001830 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001831 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001832
drh44c2eb12003-04-30 11:38:26 +00001833 /* Make sure we have a valid signal handler early, before anything
1834 ** else is done.
1835 */
drh4c504392000-10-16 22:06:40 +00001836#ifdef SIGINT
1837 signal(SIGINT, interrupt_handler);
1838#endif
drh44c2eb12003-04-30 11:38:26 +00001839
drh22fbcb82004-02-01 01:22:50 +00001840 /* Do an initial pass through the command-line argument to locate
1841 ** the name of the database file, the name of the initialization file,
1842 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001843 */
drh22fbcb82004-02-01 01:22:50 +00001844 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001845 char *z;
drh44c2eb12003-04-30 11:38:26 +00001846 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001847 z = argv[i];
1848 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001849 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1850 i++;
drh22fbcb82004-02-01 01:22:50 +00001851 }else if( strcmp(argv[i],"-init")==0 ){
1852 i++;
1853 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001854 }
1855 }
drh22fbcb82004-02-01 01:22:50 +00001856 if( i<argc ){
1857 data.zDbFilename = argv[i++];
1858 }else{
danielk197703aded42004-11-22 05:26:27 +00001859#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00001860 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00001861#else
1862 data.zDbFilename = 0;
1863#endif
drh22fbcb82004-02-01 01:22:50 +00001864 }
1865 if( i<argc ){
1866 zFirstCmd = argv[i++];
1867 }
drh44c2eb12003-04-30 11:38:26 +00001868 data.out = stdout;
1869
drh01b41712005-08-29 23:06:23 +00001870#ifdef SQLITE_OMIT_MEMORYDB
1871 if( data.zDbFilename==0 ){
1872 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
1873 exit(1);
1874 }
1875#endif
1876
drh44c2eb12003-04-30 11:38:26 +00001877 /* Go ahead and open the database file if it already exists. If the
1878 ** file does not exist, delay opening it. This prevents empty database
1879 ** files from being created if a user mistypes the database name argument
1880 ** to the sqlite command-line tool.
1881 */
drhc8d74412004-08-31 23:41:26 +00001882 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00001883 open_db(&data);
1884 }
1885
drh22fbcb82004-02-01 01:22:50 +00001886 /* Process the initialization file if there is one. If no -init option
1887 ** is given on the command line, look for a file named ~/.sqliterc and
1888 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00001889 */
drh22fbcb82004-02-01 01:22:50 +00001890 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00001891
drh22fbcb82004-02-01 01:22:50 +00001892 /* Make a second pass through the command-line argument and set
1893 ** options. This second pass is delayed until after the initialization
1894 ** file is processed so that the command-line arguments will override
1895 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00001896 */
drh22fbcb82004-02-01 01:22:50 +00001897 for(i=1; i<argc && argv[i][0]=='-'; i++){
1898 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00001899 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00001900 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00001901 i++;
1902 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001903 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00001904 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001905 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00001906 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001907 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00001908 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00001909 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00001910 }else if( strcmp(z,"-csv")==0 ){
1911 data.mode = MODE_Csv;
1912 strcpy(data.separator,",");
drh22fbcb82004-02-01 01:22:50 +00001913 }else if( strcmp(z,"-separator")==0 ){
1914 i++;
1915 sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]);
1916 }else if( strcmp(z,"-nullvalue")==0 ){
1917 i++;
1918 sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
1919 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001920 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00001921 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001922 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00001923 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00001924 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00001925 }else if( strcmp(z,"-bail")==0 ){
1926 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00001927 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00001928 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00001929 return 0;
drhc28490c2006-10-26 14:25:58 +00001930 }else if( strcmp(z,"-interactive")==0 ){
1931 stdin_is_interactive = 1;
1932 }else if( strcmp(z,"-batch")==0 ){
1933 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00001934 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00001935 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00001936 }else{
drh22fbcb82004-02-01 01:22:50 +00001937 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00001938 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00001939 return 1;
1940 }
1941 }
drh44c2eb12003-04-30 11:38:26 +00001942
drh22fbcb82004-02-01 01:22:50 +00001943 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00001944 /* Run just the command that follows the database name
1945 */
drh22fbcb82004-02-01 01:22:50 +00001946 if( zFirstCmd[0]=='.' ){
1947 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00001948 exit(0);
1949 }else{
1950 int rc;
drh44c2eb12003-04-30 11:38:26 +00001951 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00001952 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00001953 if( rc!=0 && zErrMsg!=0 ){
1954 fprintf(stderr,"SQL error: %s\n", zErrMsg);
1955 exit(1);
1956 }
drh75897232000-05-29 14:26:00 +00001957 }
1958 }else{
drh44c2eb12003-04-30 11:38:26 +00001959 /* Run commands received from standard input
1960 */
drhc28490c2006-10-26 14:25:58 +00001961 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00001962 char *zHome;
1963 char *zHistory = 0;
drh75897232000-05-29 14:26:00 +00001964 printf(
drhb217a572000-08-22 13:40:18 +00001965 "SQLite version %s\n"
1966 "Enter \".help\" for instructions\n",
drhc8d74412004-08-31 23:41:26 +00001967 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00001968 );
drh67505e72002-04-19 12:34:06 +00001969 zHome = find_home_dir();
1970 if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){
1971 sprintf(zHistory,"%s/.sqlite_history", zHome);
1972 }
danielk19774af00c62005-01-23 23:43:21 +00001973#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00001974 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00001975#endif
drhc28490c2006-10-26 14:25:58 +00001976 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00001977 if( zHistory ){
1978 stifle_history(100);
1979 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00001980 free(zHistory);
drh67505e72002-04-19 12:34:06 +00001981 }
adamd0a3daa32006-07-28 20:16:14 +00001982 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00001983 }else{
drhc28490c2006-10-26 14:25:58 +00001984 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00001985 }
1986 }
drh33048c02001-10-01 14:29:22 +00001987 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00001988 if( db ){
1989 if( sqlite3_close(db)!=SQLITE_OK ){
1990 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
1991 }
1992 }
drhc28490c2006-10-26 14:25:58 +00001993 return rc;
drh75897232000-05-29 14:26:00 +00001994}