blob: 287022344db80c0db747f090897d1fd429b27ba2 [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**
drh5bb3eb92007-05-04 13:15:55 +000015** $Id: shell.c,v 1.162 2007/05/04 13:15:56 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;
drhf075cd02007-02-28 06:14:25 +0000114 char *z;
drhb0603412007-02-28 04:47:26 +0000115 if( iotrace==0 ) return;
116 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000117 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000118 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000119 fprintf(iotrace, "%s", z);
120 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000121}
122
drh44c2eb12003-04-30 11:38:26 +0000123
persicom7e2dfdd2002-04-18 02:46:52 +0000124/*
drh83965662003-04-17 02:54:13 +0000125** Determines if a string is a number of not.
126*/
danielk19772e588c72005-12-09 14:25:08 +0000127static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000128 if( *z=='-' || *z=='+' ) z++;
129 if( !isdigit(*z) ){
130 return 0;
131 }
132 z++;
133 if( realnum ) *realnum = 0;
134 while( isdigit(*z) ){ z++; }
135 if( *z=='.' ){
136 z++;
137 if( !isdigit(*z) ) return 0;
138 while( isdigit(*z) ){ z++; }
139 if( realnum ) *realnum = 1;
140 }
141 if( *z=='e' || *z=='E' ){
142 z++;
143 if( *z=='+' || *z=='-' ) z++;
144 if( !isdigit(*z) ) return 0;
145 while( isdigit(*z) ){ z++; }
146 if( realnum ) *realnum = 1;
147 }
148 return *z==0;
149}
drh83965662003-04-17 02:54:13 +0000150
151/*
danielk1977bc6ada42004-06-30 08:20:16 +0000152** A global char* and an SQL function to access its current value
153** from within an SQL statement. This program used to use the
154** sqlite_exec_printf() API to substitue a string into an SQL statement.
155** The correct way to do this with sqlite3 is to use the bind API, but
156** since the shell is built around the callback paradigm it would be a lot
157** of work. Instead just use this hack, which is quite harmless.
158*/
159static const char *zShellStatic = 0;
160static void shellstaticFunc(
161 sqlite3_context *context,
162 int argc,
163 sqlite3_value **argv
164){
165 assert( 0==argc );
166 assert( zShellStatic );
167 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
168}
169
170
171/*
drhfeac5f82004-08-01 00:10:45 +0000172** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000173** the text in memory obtained from malloc() and returns a pointer
174** to the text. NULL is returned at end of file, or if malloc()
175** fails.
176**
177** The interface is like "readline" but no command-line editing
178** is done.
179*/
drh9347b202003-07-18 01:30:59 +0000180static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000181 char *zLine;
182 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000183 int n;
184 int eol;
185
186 if( zPrompt && *zPrompt ){
187 printf("%s",zPrompt);
188 fflush(stdout);
189 }
190 nLine = 100;
191 zLine = malloc( nLine );
192 if( zLine==0 ) return 0;
193 n = 0;
194 eol = 0;
195 while( !eol ){
196 if( n+100>nLine ){
197 nLine = nLine*2 + 100;
198 zLine = realloc(zLine, nLine);
199 if( zLine==0 ) return 0;
200 }
drhdaffd0e2001-04-11 14:28:42 +0000201 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000202 if( n==0 ){
203 free(zLine);
204 return 0;
205 }
206 zLine[n] = 0;
207 eol = 1;
208 break;
209 }
210 while( zLine[n] ){ n++; }
211 if( n>0 && zLine[n-1]=='\n' ){
212 n--;
213 zLine[n] = 0;
214 eol = 1;
215 }
216 }
217 zLine = realloc( zLine, n+1 );
218 return zLine;
219}
220
221/*
drhc28490c2006-10-26 14:25:58 +0000222** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000223**
224** zPrior is a string of prior text retrieved. If not the empty
225** string, then issue a continuation prompt.
226*/
drhdaffd0e2001-04-11 14:28:42 +0000227static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000228 char *zPrompt;
229 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000230 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000231 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000232 }
233 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000234 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000235 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000236 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000237 }
238 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000239#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000240 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000241#endif
drh8e7e7a22000-05-30 18:45:23 +0000242 return zResult;
243}
244
persicom7e2dfdd2002-04-18 02:46:52 +0000245struct previous_mode_data {
246 int valid; /* Is there legit data in here? */
247 int mode;
248 int showHeader;
249 int colWidth[100];
250};
drh45e29d82006-11-20 16:21:10 +0000251
drh8e7e7a22000-05-30 18:45:23 +0000252/*
drh75897232000-05-29 14:26:00 +0000253** An pointer to an instance of this structure is passed from
254** the main program to the callback. This is used to communicate
255** state and mode information.
256*/
257struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000258 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000259 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000260 int cnt; /* Number of records displayed so far */
261 FILE *out; /* Write results here */
262 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000263 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000264 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000265 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000266 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000267 int colWidth[100]; /* Requested width of each column when in column mode*/
268 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000269 char nullvalue[20]; /* The text to print when a NULL comes back from
270 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000271 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000272 /* Holds the mode information just before
273 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000274 char outfile[FILENAME_MAX]; /* Filename for *out */
275 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000276};
277
278/*
279** These are the allowed modes.
280*/
drh967e8b72000-06-21 13:59:10 +0000281#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000282#define MODE_Column 1 /* One record per line in neat columns */
283#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000284#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
285#define MODE_Html 4 /* Generate an XHTML table */
286#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000287#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000288#define MODE_Csv 7 /* Quote strings, numbers are plain */
289#define MODE_NUM_OF 8 /* The number of modes (not a mode itself) */
persicom7e2dfdd2002-04-18 02:46:52 +0000290
drh0850b532006-01-31 19:31:43 +0000291static const char *modeDescr[MODE_NUM_OF] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000292 "line",
293 "column",
294 "list",
295 "semi",
296 "html",
drhfeac5f82004-08-01 00:10:45 +0000297 "insert",
298 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000299 "csv",
persicom7e2dfdd2002-04-18 02:46:52 +0000300};
drh75897232000-05-29 14:26:00 +0000301
302/*
303** Number of elements in an array
304*/
305#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
306
307/*
drh28bd4bc2000-06-15 15:57:22 +0000308** Output the given string as a quoted string using SQL quoting conventions.
309*/
310static void output_quoted_string(FILE *out, const char *z){
311 int i;
312 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000313 for(i=0; z[i]; i++){
314 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000315 }
316 if( nSingle==0 ){
317 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000318 }else{
319 fprintf(out,"'");
320 while( *z ){
321 for(i=0; z[i] && z[i]!='\''; i++){}
322 if( i==0 ){
323 fprintf(out,"''");
324 z++;
325 }else if( z[i]=='\'' ){
326 fprintf(out,"%.*s''",i,z);
327 z += i+1;
328 }else{
drhcd7d2732002-02-26 23:24:26 +0000329 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000330 break;
331 }
332 }
drhcd7d2732002-02-26 23:24:26 +0000333 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000334 }
335}
336
337/*
drhfeac5f82004-08-01 00:10:45 +0000338** Output the given string as a quoted according to C or TCL quoting rules.
339*/
340static void output_c_string(FILE *out, const char *z){
341 unsigned int c;
342 fputc('"', out);
343 while( (c = *(z++))!=0 ){
344 if( c=='\\' ){
345 fputc(c, out);
346 fputc(c, out);
347 }else if( c=='\t' ){
348 fputc('\\', out);
349 fputc('t', out);
350 }else if( c=='\n' ){
351 fputc('\\', out);
352 fputc('n', out);
353 }else if( c=='\r' ){
354 fputc('\\', out);
355 fputc('r', out);
356 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000357 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000358 }else{
359 fputc(c, out);
360 }
361 }
362 fputc('"', out);
363}
364
365/*
drhc08a4f12000-06-15 16:49:48 +0000366** Output the given string with characters that are special to
367** HTML escaped.
368*/
369static void output_html_string(FILE *out, const char *z){
370 int i;
371 while( *z ){
372 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
373 if( i>0 ){
374 fprintf(out,"%.*s",i,z);
375 }
376 if( z[i]=='<' ){
377 fprintf(out,"&lt;");
378 }else if( z[i]=='&' ){
379 fprintf(out,"&amp;");
380 }else{
381 break;
382 }
383 z += i + 1;
384 }
385}
386
387/*
drhc49f44e2006-10-26 18:15:42 +0000388** If a field contains any character identified by a 1 in the following
389** array, then the string must be quoted for CSV.
390*/
391static const char needCsvQuote[] = {
392 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
393 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
394 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
399 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
406 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
407 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
408};
409
410/*
drh8e64d1c2004-10-07 00:32:39 +0000411** Output a single term of CSV. Actually, p->separator is used for
412** the separator, which may or may not be a comma. p->nullvalue is
413** the null value. Strings are quoted using ANSI-C rules. Numbers
414** appear outside of quotes.
415*/
416static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000417 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000418 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000419 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000420 }else{
drhc49f44e2006-10-26 18:15:42 +0000421 int i;
422 for(i=0; z[i]; i++){
423 if( needCsvQuote[((unsigned char*)z)[i]] ){
424 i = 0;
425 break;
426 }
427 }
428 if( i==0 ){
429 putc('"', out);
430 for(i=0; z[i]; i++){
431 if( z[i]=='"' ) putc('"', out);
432 putc(z[i], out);
433 }
434 putc('"', out);
435 }else{
436 fprintf(out, "%s", z);
437 }
drh8e64d1c2004-10-07 00:32:39 +0000438 }
439 if( bSep ){
440 fprintf(p->out, p->separator);
441 }
442}
443
danielk19774af00c62005-01-23 23:43:21 +0000444#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000445/*
drh4c504392000-10-16 22:06:40 +0000446** This routine runs when the user presses Ctrl-C
447*/
448static void interrupt_handler(int NotUsed){
drh67505e72002-04-19 12:34:06 +0000449 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000450 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000451}
danielk19774af00c62005-01-23 23:43:21 +0000452#endif
drh4c504392000-10-16 22:06:40 +0000453
454/*
drh75897232000-05-29 14:26:00 +0000455** This is the callback routine that the SQLite library
456** invokes for each row of a query result.
457*/
458static int callback(void *pArg, int nArg, char **azArg, char **azCol){
459 int i;
460 struct callback_data *p = (struct callback_data*)pArg;
461 switch( p->mode ){
462 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000463 int w = 5;
drh6a535342001-10-19 16:44:56 +0000464 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000465 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000466 int len = strlen(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000467 if( len>w ) w = len;
468 }
drh75897232000-05-29 14:26:00 +0000469 if( p->cnt++>0 ) fprintf(p->out,"\n");
470 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000471 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000472 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000473 }
474 break;
475 }
476 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000477 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000478 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000479 int w, n;
480 if( i<ArraySize(p->colWidth) ){
drh75897232000-05-29 14:26:00 +0000481 w = p->colWidth[i];
482 }else{
drha0c66f52000-07-29 13:20:21 +0000483 w = 0;
drh75897232000-05-29 14:26:00 +0000484 }
drha0c66f52000-07-29 13:20:21 +0000485 if( w<=0 ){
drhff6e9112000-08-28 16:21:58 +0000486 w = strlen(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000487 if( w<10 ) w = 10;
persicom7e2dfdd2002-04-18 02:46:52 +0000488 n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000489 if( w<n ) w = n;
490 }
491 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000492 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000493 }
494 if( p->showHeader ){
495 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
496 }
497 }
498 if( p->showHeader ){
499 for(i=0; i<nArg; i++){
500 int w;
501 if( i<ArraySize(p->actualWidth) ){
502 w = p->actualWidth[i];
503 }else{
504 w = 10;
505 }
506 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
507 "----------------------------------------------------------",
508 i==nArg-1 ? "\n": " ");
509 }
drh75897232000-05-29 14:26:00 +0000510 }
511 }
drh6a535342001-10-19 16:44:56 +0000512 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000513 for(i=0; i<nArg; i++){
514 int w;
drha0c66f52000-07-29 13:20:21 +0000515 if( i<ArraySize(p->actualWidth) ){
516 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000517 }else{
518 w = 10;
519 }
drhc61053b2000-06-04 12:58:36 +0000520 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000521 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000522 }
523 break;
524 }
drhe3710332000-09-29 13:30:53 +0000525 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000526 case MODE_List: {
527 if( p->cnt++==0 && p->showHeader ){
528 for(i=0; i<nArg; i++){
529 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
530 }
531 }
drh6a535342001-10-19 16:44:56 +0000532 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000533 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000534 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000535 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000536 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000537 if( i<nArg-1 ){
538 fprintf(p->out, "%s", p->separator);
539 }else if( p->mode==MODE_Semi ){
540 fprintf(p->out, ";\n");
541 }else{
542 fprintf(p->out, "\n");
543 }
drh75897232000-05-29 14:26:00 +0000544 }
545 break;
546 }
drh1e5d0e92000-05-31 23:33:17 +0000547 case MODE_Html: {
548 if( p->cnt++==0 && p->showHeader ){
549 fprintf(p->out,"<TR>");
550 for(i=0; i<nArg; i++){
551 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
552 }
553 fprintf(p->out,"</TR>\n");
554 }
drh6a535342001-10-19 16:44:56 +0000555 if( azArg==0 ) break;
drh28bd4bc2000-06-15 15:57:22 +0000556 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000557 for(i=0; i<nArg; i++){
drhc08a4f12000-06-15 16:49:48 +0000558 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000559 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
drhc08a4f12000-06-15 16:49:48 +0000560 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000561 }
drh7d686b22002-11-11 13:56:47 +0000562 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000563 break;
564 }
drhfeac5f82004-08-01 00:10:45 +0000565 case MODE_Tcl: {
566 if( p->cnt++==0 && p->showHeader ){
567 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000568 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000569 fprintf(p->out, "%s", p->separator);
570 }
571 fprintf(p->out,"\n");
572 }
573 if( azArg==0 ) break;
574 for(i=0; i<nArg; i++){
575 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
576 fprintf(p->out, "%s", p->separator);
577 }
578 fprintf(p->out,"\n");
579 break;
580 }
drh8e64d1c2004-10-07 00:32:39 +0000581 case MODE_Csv: {
582 if( p->cnt++==0 && p->showHeader ){
583 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000584 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000585 }
586 fprintf(p->out,"\n");
587 }
588 if( azArg==0 ) break;
589 for(i=0; i<nArg; i++){
590 output_csv(p, azArg[i], i<nArg-1);
591 }
592 fprintf(p->out,"\n");
593 break;
594 }
drh28bd4bc2000-06-15 15:57:22 +0000595 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000596 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000597 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000598 for(i=0; i<nArg; i++){
599 char *zSep = i>0 ? ",": "";
600 if( azArg[i]==0 ){
601 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000602 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000603 fprintf(p->out,"%s%s",zSep, azArg[i]);
604 }else{
605 if( zSep[0] ) fprintf(p->out,"%s",zSep);
606 output_quoted_string(p->out, azArg[i]);
607 }
608 }
609 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000610 break;
drh28bd4bc2000-06-15 15:57:22 +0000611 }
persicom1d0b8722002-04-18 02:53:04 +0000612 }
drh75897232000-05-29 14:26:00 +0000613 return 0;
614}
615
616/*
drh33048c02001-10-01 14:29:22 +0000617** Set the destination table field of the callback_data structure to
618** the name of the table given. Escape any quote characters in the
619** table name.
620*/
621static void set_table_name(struct callback_data *p, const char *zName){
622 int i, n;
623 int needQuote;
624 char *z;
625
626 if( p->zDestTable ){
627 free(p->zDestTable);
628 p->zDestTable = 0;
629 }
630 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000631 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000632 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000633 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000634 needQuote = 1;
635 if( zName[i]=='\'' ) n++;
636 }
637 }
638 if( needQuote ) n += 2;
639 z = p->zDestTable = malloc( n+1 );
640 if( z==0 ){
641 fprintf(stderr,"Out of memory!\n");
642 exit(1);
643 }
644 n = 0;
645 if( needQuote ) z[n++] = '\'';
646 for(i=0; zName[i]; i++){
647 z[n++] = zName[i];
648 if( zName[i]=='\'' ) z[n++] = '\'';
649 }
650 if( needQuote ) z[n++] = '\'';
651 z[n] = 0;
652}
653
danielk19772a02e332004-06-05 08:04:36 +0000654/* zIn is either a pointer to a NULL-terminated string in memory obtained
655** from malloc(), or a NULL pointer. The string pointed to by zAppend is
656** added to zIn, and the result returned in memory obtained from malloc().
657** zIn, if it was not NULL, is freed.
658**
659** If the third argument, quote, is not '\0', then it is used as a
660** quote character for zAppend.
661*/
drhc28490c2006-10-26 14:25:58 +0000662static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000663 int len;
664 int i;
665 int nAppend = strlen(zAppend);
666 int nIn = (zIn?strlen(zIn):0);
667
668 len = nAppend+nIn+1;
669 if( quote ){
670 len += 2;
671 for(i=0; i<nAppend; i++){
672 if( zAppend[i]==quote ) len++;
673 }
674 }
675
676 zIn = (char *)realloc(zIn, len);
677 if( !zIn ){
678 return 0;
679 }
680
681 if( quote ){
682 char *zCsr = &zIn[nIn];
683 *zCsr++ = quote;
684 for(i=0; i<nAppend; i++){
685 *zCsr++ = zAppend[i];
686 if( zAppend[i]==quote ) *zCsr++ = quote;
687 }
688 *zCsr++ = quote;
689 *zCsr++ = '\0';
690 assert( (zCsr-zIn)==len );
691 }else{
692 memcpy(&zIn[nIn], zAppend, nAppend);
693 zIn[len-1] = '\0';
694 }
695
696 return zIn;
697}
698
drhdd3d4592004-08-30 01:54:05 +0000699
700/*
701** Execute a query statement that has a single result column. Print
702** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000703**
704** This is used, for example, to show the schema of the database by
705** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000706*/
707static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
708 sqlite3_stmt *pSelect;
709 int rc;
710 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
711 if( rc!=SQLITE_OK || !pSelect ){
712 return rc;
713 }
714 rc = sqlite3_step(pSelect);
715 while( rc==SQLITE_ROW ){
716 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
717 rc = sqlite3_step(pSelect);
718 }
719 return sqlite3_finalize(pSelect);
720}
721
722
drh33048c02001-10-01 14:29:22 +0000723/*
drh4c653a02000-06-07 01:27:47 +0000724** This is a different callback routine used for dumping the database.
725** Each row received by this callback consists of a table name,
726** the table type ("index" or "table") and SQL to create the table.
727** This routine should print text sufficient to recreate the table.
728*/
729static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000730 int rc;
731 const char *zTable;
732 const char *zType;
733 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000734 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000735
drh4c653a02000-06-07 01:27:47 +0000736 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000737 zTable = azArg[0];
738 zType = azArg[1];
739 zSql = azArg[2];
740
drh00b950d2005-09-11 02:03:03 +0000741 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000742 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000743 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
744 fprintf(p->out, "ANALYZE sqlite_master;\n");
745 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
746 return 0;
drh45e29d82006-11-20 16:21:10 +0000747 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
748 char *zIns;
749 if( !p->writableSchema ){
750 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
751 p->writableSchema = 1;
752 }
753 zIns = sqlite3_mprintf(
754 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
755 "VALUES('table','%q','%q',0,'%q');",
756 zTable, zTable, zSql);
757 fprintf(p->out, "%s\n", zIns);
758 sqlite3_free(zIns);
759 return 0;
drh00b950d2005-09-11 02:03:03 +0000760 }else{
761 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000762 }
danielk19772a02e332004-06-05 08:04:36 +0000763
764 if( strcmp(zType, "table")==0 ){
765 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000766 char *zSelect = 0;
767 char *zTableInfo = 0;
768 char *zTmp = 0;
769
770 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
771 zTableInfo = appendText(zTableInfo, zTable, '"');
772 zTableInfo = appendText(zTableInfo, ");", 0);
773
774 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
775 if( zTableInfo ) free(zTableInfo);
776 if( rc!=SQLITE_OK || !pTableInfo ){
777 return 1;
778 }
779
780 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
781 zTmp = appendText(zTmp, zTable, '"');
782 if( zTmp ){
783 zSelect = appendText(zSelect, zTmp, '\'');
784 }
785 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
786 rc = sqlite3_step(pTableInfo);
787 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000788 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000789 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000790 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000791 rc = sqlite3_step(pTableInfo);
792 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000793 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000794 }else{
795 zSelect = appendText(zSelect, ") ", 0);
796 }
797 }
798 rc = sqlite3_finalize(pTableInfo);
799 if( rc!=SQLITE_OK ){
800 if( zSelect ) free(zSelect);
801 return 1;
802 }
803 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
804 zSelect = appendText(zSelect, zTable, '"');
805
drhdd3d4592004-08-30 01:54:05 +0000806 rc = run_table_dump_query(p->out, p->db, zSelect);
807 if( rc==SQLITE_CORRUPT ){
808 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
809 rc = run_table_dump_query(p->out, p->db, zSelect);
810 }
danielk19772a02e332004-06-05 08:04:36 +0000811 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000812 }
drh4c653a02000-06-07 01:27:47 +0000813 return 0;
814}
815
816/*
drh45e29d82006-11-20 16:21:10 +0000817** Run zQuery. Use dump_callback() as the callback routine so that
818** the contents of the query are output as SQL statements.
819**
drhdd3d4592004-08-30 01:54:05 +0000820** If we get a SQLITE_CORRUPT error, rerun the query after appending
821** "ORDER BY rowid DESC" to the end.
822*/
823static int run_schema_dump_query(
824 struct callback_data *p,
825 const char *zQuery,
826 char **pzErrMsg
827){
828 int rc;
829 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
830 if( rc==SQLITE_CORRUPT ){
831 char *zQ2;
832 int len = strlen(zQuery);
833 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
834 zQ2 = malloc( len+100 );
835 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000836 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000837 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
838 free(zQ2);
839 }
840 return rc;
841}
842
843/*
drh75897232000-05-29 14:26:00 +0000844** Text of a help message
845*/
persicom1d0b8722002-04-18 02:53:04 +0000846static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000847 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000848 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000849 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000850 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000851 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000852 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000853 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000854 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000855 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000856 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000857#ifdef SQLITE_ENABLE_IOTRACE
858 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
859#endif
drh70df4fe2006-06-13 15:12:21 +0000860#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000861 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000862#endif
danielk19776b77a362005-01-13 11:10:25 +0000863 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000864 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000865 " column Left-aligned columns. (See .width)\n"
866 " html HTML <table> code\n"
867 " insert SQL insert statements for TABLE\n"
868 " line One value per line\n"
869 " list Values delimited by .separator string\n"
870 " tabs Tab-separated values\n"
871 " tcl TCL list elements\n"
872 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000873 ".output FILENAME Send output to FILENAME\n"
874 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000875 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000876 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000877 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000878 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000879 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000880 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000881 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000882 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh75897232000-05-29 14:26:00 +0000883 ".width NUM NUM ... Set column widths for \"column\" mode\n"
884;
885
drhdaffd0e2001-04-11 14:28:42 +0000886/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000887static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000888
drh75897232000-05-29 14:26:00 +0000889/*
drh44c2eb12003-04-30 11:38:26 +0000890** Make sure the database is open. If it is not, then open it. If
891** the database fails to open, print an error message and exit.
892*/
893static void open_db(struct callback_data *p){
894 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000895 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000896 db = p->db;
danielk1977bc6ada42004-06-30 08:20:16 +0000897 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
898 shellstaticFunc, 0, 0);
danielk197780290862004-05-22 09:21:21 +0000899 if( SQLITE_OK!=sqlite3_errcode(db) ){
900 fprintf(stderr,"Unable to open database \"%s\": %s\n",
901 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000902 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000903 }
drhc2e87a32006-06-27 15:16:14 +0000904#ifndef SQLITE_OMIT_LOAD_EXTENSION
905 sqlite3_enable_load_extension(p->db, 1);
906#endif
drh44c2eb12003-04-30 11:38:26 +0000907 }
908}
909
910/*
drhfeac5f82004-08-01 00:10:45 +0000911** Do C-language style dequoting.
912**
913** \t -> tab
914** \n -> newline
915** \r -> carriage return
916** \NNN -> ascii character NNN in octal
917** \\ -> backslash
918*/
919static void resolve_backslashes(char *z){
920 int i, j, c;
921 for(i=j=0; (c = z[i])!=0; i++, j++){
922 if( c=='\\' ){
923 c = z[++i];
924 if( c=='n' ){
925 c = '\n';
926 }else if( c=='t' ){
927 c = '\t';
928 }else if( c=='r' ){
929 c = '\r';
930 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +0000931 c -= '0';
drhfeac5f82004-08-01 00:10:45 +0000932 if( z[i+1]>='0' && z[i+1]<='7' ){
933 i++;
934 c = (c<<3) + z[i] - '0';
935 if( z[i+1]>='0' && z[i+1]<='7' ){
936 i++;
937 c = (c<<3) + z[i] - '0';
938 }
939 }
940 }
941 }
942 z[j] = c;
943 }
944 z[j] = 0;
945}
946
947/*
drhc28490c2006-10-26 14:25:58 +0000948** Interpret zArg as a boolean value. Return either 0 or 1.
949*/
950static int booleanValue(char *zArg){
951 int val = atoi(zArg);
952 int j;
953 for(j=0; zArg[j]; j++){
954 zArg[j] = tolower(zArg[j]);
955 }
956 if( strcmp(zArg,"on")==0 ){
957 val = 1;
958 }else if( strcmp(zArg,"yes")==0 ){
959 val = 1;
960 }
961 return val;
962}
963
964/*
drh75897232000-05-29 14:26:00 +0000965** If an input line begins with "." then invoke this routine to
966** process that line.
drh67505e72002-04-19 12:34:06 +0000967**
drh47ad6842006-11-08 12:25:42 +0000968** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +0000969*/
drh44c2eb12003-04-30 11:38:26 +0000970static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +0000971 int i = 1;
972 int nArg = 0;
973 int n, c;
drh67505e72002-04-19 12:34:06 +0000974 int rc = 0;
drh75897232000-05-29 14:26:00 +0000975 char *azArg[50];
976
977 /* Parse the input line into tokens.
978 */
979 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +0000980 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +0000981 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +0000982 if( zLine[i]=='\'' || zLine[i]=='"' ){
983 int delim = zLine[i++];
984 azArg[nArg++] = &zLine[i];
985 while( zLine[i] && zLine[i]!=delim ){ i++; }
986 if( zLine[i]==delim ){
987 zLine[i++] = 0;
988 }
drhfeac5f82004-08-01 00:10:45 +0000989 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +0000990 }else{
991 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +0000992 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +0000993 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +0000994 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +0000995 }
996 }
997
998 /* Process the input line.
999 */
drh67505e72002-04-19 12:34:06 +00001000 if( nArg==0 ) return rc;
drh75897232000-05-29 14:26:00 +00001001 n = strlen(azArg[0]);
1002 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001003 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1004 bail_on_error = booleanValue(azArg[1]);
1005 }else
1006
jplyon6a65bb32003-05-04 07:25:57 +00001007 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001008 struct callback_data data;
1009 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001010 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001011 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001012 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001013 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001014 data.colWidth[0] = 3;
1015 data.colWidth[1] = 15;
1016 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001017 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001018 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001019 if( zErrMsg ){
1020 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001021 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001022 }
1023 }else
1024
drh4c653a02000-06-07 01:27:47 +00001025 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1026 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001027 open_db(p);
drh33048c02001-10-01 14:29:22 +00001028 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001029 p->writableSchema = 0;
drh4c653a02000-06-07 01:27:47 +00001030 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001031 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001032 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001033 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001034 );
1035 run_table_dump_query(p->out, p->db,
1036 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001037 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001038 );
drh4c653a02000-06-07 01:27:47 +00001039 }else{
1040 int i;
drhdd3d4592004-08-30 01:54:05 +00001041 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001042 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001043 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001044 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001045 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001046 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001047 run_table_dump_query(p->out, p->db,
1048 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001049 "WHERE sql NOT NULL"
1050 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001051 " AND tbl_name LIKE shellstatic()"
1052 );
danielk1977bc6ada42004-06-30 08:20:16 +00001053 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001054 }
1055 }
drh45e29d82006-11-20 16:21:10 +00001056 if( p->writableSchema ){
1057 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1058 p->writableSchema = 0;
1059 }
drh4c653a02000-06-07 01:27:47 +00001060 if( zErrMsg ){
1061 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001062 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001063 }else{
1064 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001065 }
1066 }else
drh75897232000-05-29 14:26:00 +00001067
drhdaffd0e2001-04-11 14:28:42 +00001068 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001069 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001070 }else
1071
drh75897232000-05-29 14:26:00 +00001072 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001073 rc = 2;
drh75897232000-05-29 14:26:00 +00001074 }else
1075
drhdd45df82002-04-18 12:39:03 +00001076 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001077 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001078 if(val == 1) {
1079 if(!p->explainPrev.valid) {
1080 p->explainPrev.valid = 1;
1081 p->explainPrev.mode = p->mode;
1082 p->explainPrev.showHeader = p->showHeader;
1083 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1084 }
1085 /* We could put this code under the !p->explainValid
1086 ** condition so that it does not execute if we are already in
1087 ** explain mode. However, always executing it allows us an easy
1088 ** was to reset to explain mode in case the user previously
1089 ** did an .explain followed by a .width, .mode or .header
1090 ** command.
1091 */
1092 p->mode = MODE_Column;
1093 p->showHeader = 1;
1094 memset(p->colWidth,0,ArraySize(p->colWidth));
1095 p->colWidth[0] = 4;
drhe69cc5b2005-08-27 01:50:53 +00001096 p->colWidth[1] = 14;
persicom7e2dfdd2002-04-18 02:46:52 +00001097 p->colWidth[2] = 10;
1098 p->colWidth[3] = 10;
drhe69cc5b2005-08-27 01:50:53 +00001099 p->colWidth[4] = 33;
persicom7e2dfdd2002-04-18 02:46:52 +00001100 }else if (p->explainPrev.valid) {
1101 p->explainPrev.valid = 0;
1102 p->mode = p->explainPrev.mode;
1103 p->showHeader = p->explainPrev.showHeader;
1104 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1105 }
drh75897232000-05-29 14:26:00 +00001106 }else
1107
drhc28490c2006-10-26 14:25:58 +00001108 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001109 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001110 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001111 }else
1112
1113 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1114 fprintf(stderr,zHelp);
1115 }else
1116
drhfeac5f82004-08-01 00:10:45 +00001117 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1118 char *zTable = azArg[2]; /* Insert data into this table */
1119 char *zFile = azArg[1]; /* The file from which to extract data */
1120 sqlite3_stmt *pStmt; /* A statement */
1121 int rc; /* Result code */
1122 int nCol; /* Number of columns in the table */
1123 int nByte; /* Number of bytes in an SQL string */
1124 int i, j; /* Loop counters */
1125 int nSep; /* Number of bytes in p->separator[] */
1126 char *zSql; /* An SQL statement */
1127 char *zLine; /* A single line of input from the file */
1128 char **azCol; /* zLine[] broken up into columns */
1129 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001130 FILE *in; /* The input file */
1131 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001132
drha543c822006-06-08 16:10:14 +00001133 open_db(p);
drhfeac5f82004-08-01 00:10:45 +00001134 nSep = strlen(p->separator);
1135 if( nSep==0 ){
1136 fprintf(stderr, "non-null separator required for import\n");
1137 return 0;
1138 }
1139 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1140 if( zSql==0 ) return 0;
1141 nByte = strlen(zSql);
drh5e6078b2006-01-31 19:07:22 +00001142 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001143 sqlite3_free(zSql);
1144 if( rc ){
1145 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1146 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001147 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001148 }else{
1149 nCol = sqlite3_column_count(pStmt);
1150 }
1151 sqlite3_finalize(pStmt);
1152 if( nCol==0 ) return 0;
1153 zSql = malloc( nByte + 20 + nCol*2 );
1154 if( zSql==0 ) return 0;
1155 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
1156 j = strlen(zSql);
1157 for(i=1; i<nCol; i++){
1158 zSql[j++] = ',';
1159 zSql[j++] = '?';
1160 }
1161 zSql[j++] = ')';
1162 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001163 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001164 free(zSql);
1165 if( rc ){
1166 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1167 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001168 return 1;
drhfeac5f82004-08-01 00:10:45 +00001169 }
1170 in = fopen(zFile, "rb");
1171 if( in==0 ){
1172 fprintf(stderr, "cannot open file: %s\n", zFile);
1173 sqlite3_finalize(pStmt);
1174 return 0;
1175 }
1176 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001177 if( azCol==0 ){
1178 fclose(in);
1179 return 0;
1180 }
drhfeac5f82004-08-01 00:10:45 +00001181 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1182 zCommit = "COMMIT";
1183 while( (zLine = local_getline(0, in))!=0 ){
1184 char *z;
1185 i = 0;
drhb860bc92004-08-04 15:16:55 +00001186 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001187 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001188 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001189 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1190 *z = 0;
1191 i++;
drhb860bc92004-08-04 15:16:55 +00001192 if( i<nCol ){
1193 azCol[i] = &z[nSep];
1194 z += nSep-1;
1195 }
drhfeac5f82004-08-01 00:10:45 +00001196 }
1197 }
drh1cd7f832005-08-05 18:50:51 +00001198 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001199 if( i+1!=nCol ){
1200 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1201 zFile, lineno, nCol, i+1);
1202 zCommit = "ROLLBACK";
1203 break;
1204 }
drhfeac5f82004-08-01 00:10:45 +00001205 for(i=0; i<nCol; i++){
1206 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1207 }
1208 sqlite3_step(pStmt);
1209 rc = sqlite3_reset(pStmt);
1210 free(zLine);
1211 if( rc!=SQLITE_OK ){
1212 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1213 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001214 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001215 break;
1216 }
1217 }
1218 free(azCol);
1219 fclose(in);
1220 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001221 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001222 }else
1223
drh75897232000-05-29 14:26:00 +00001224 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1225 struct callback_data data;
1226 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001227 open_db(p);
drh75897232000-05-29 14:26:00 +00001228 memcpy(&data, p, sizeof(data));
1229 data.showHeader = 0;
1230 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001231 zShellStatic = azArg[1];
1232 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001233 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001234 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001235 "UNION ALL "
1236 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001237 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001238 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001239 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001240 );
danielk1977bc6ada42004-06-30 08:20:16 +00001241 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001242 if( zErrMsg ){
1243 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001244 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001245 }
1246 }else
1247
drhae5e4452007-05-03 17:18:36 +00001248#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001249 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
1250 extern void (*sqlite3_io_trace)(const char*, ...);
1251 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1252 iotrace = 0;
1253 if( nArg<2 ){
1254 sqlite3_io_trace = 0;
1255 }else if( strcmp(azArg[1], "-")==0 ){
1256 sqlite3_io_trace = iotracePrintf;
1257 iotrace = stdout;
1258 }else{
1259 iotrace = fopen(azArg[1], "w");
1260 if( iotrace==0 ){
1261 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
1262 sqlite3_io_trace = 0;
1263 }else{
1264 sqlite3_io_trace = iotracePrintf;
1265 }
1266 }
1267 }else
drhae5e4452007-05-03 17:18:36 +00001268#endif
drhb0603412007-02-28 04:47:26 +00001269
drh70df4fe2006-06-13 15:12:21 +00001270#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001271 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1272 const char *zFile, *zProc;
1273 char *zErrMsg = 0;
1274 int rc;
1275 zFile = azArg[1];
1276 zProc = nArg>=3 ? azArg[2] : 0;
1277 open_db(p);
1278 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1279 if( rc!=SQLITE_OK ){
1280 fprintf(stderr, "%s\n", zErrMsg);
1281 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001282 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001283 }
1284 }else
drh70df4fe2006-06-13 15:12:21 +00001285#endif
drh1e397f82006-06-08 15:28:43 +00001286
drh28bd4bc2000-06-15 15:57:22 +00001287 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh75897232000-05-29 14:26:00 +00001288 int n2 = strlen(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001289 if( strncmp(azArg[1],"line",n2)==0
1290 ||
1291 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001292 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001293 }else if( strncmp(azArg[1],"column",n2)==0
1294 ||
1295 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001296 p->mode = MODE_Column;
1297 }else if( strncmp(azArg[1],"list",n2)==0 ){
1298 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001299 }else if( strncmp(azArg[1],"html",n2)==0 ){
1300 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001301 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1302 p->mode = MODE_Tcl;
1303 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001304 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001305 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001306 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1307 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001308 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001309 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1310 p->mode = MODE_Insert;
1311 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001312 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001313 }else{
drh33048c02001-10-01 14:29:22 +00001314 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001315 }
drhdaffd0e2001-04-11 14:28:42 +00001316 }else {
drhcf68ae92006-12-19 18:47:41 +00001317 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001318 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001319 }
1320 }else
1321
persicom7e2dfdd2002-04-18 02:46:52 +00001322 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001323 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1324 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001325 }else
1326
drh75897232000-05-29 14:26:00 +00001327 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1328 if( p->out!=stdout ){
1329 fclose(p->out);
1330 }
1331 if( strcmp(azArg[1],"stdout")==0 ){
1332 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001333 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001334 }else{
drha1f9b5e2004-02-14 16:31:02 +00001335 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001336 if( p->out==0 ){
1337 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1338 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001339 } else {
drh5bb3eb92007-05-04 13:15:55 +00001340 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001341 }
1342 }
1343 }else
1344
drhdd45df82002-04-18 12:39:03 +00001345 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001346 if( nArg >= 2) {
1347 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1348 }
1349 if( nArg >= 3) {
1350 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1351 }
1352 }else
1353
1354 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001355 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001356 }else
1357
drhdaffd0e2001-04-11 14:28:42 +00001358 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001359 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001360 if( alt==0 ){
1361 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1362 }else{
1363 process_input(p, alt);
1364 fclose(alt);
1365 }
1366 }else
1367
drh75897232000-05-29 14:26:00 +00001368 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1369 struct callback_data data;
1370 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001371 open_db(p);
drh75897232000-05-29 14:26:00 +00001372 memcpy(&data, p, sizeof(data));
1373 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001374 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001375 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001376 int i;
1377 for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
1378 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001379 char *new_argv[2], *new_colv[2];
1380 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1381 " type text,\n"
1382 " name text,\n"
1383 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001384 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001385 " sql text\n"
1386 ")";
1387 new_argv[1] = 0;
1388 new_colv[0] = "sql";
1389 new_colv[1] = 0;
1390 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001391 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001392 char *new_argv[2], *new_colv[2];
1393 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1394 " type text,\n"
1395 " name text,\n"
1396 " tbl_name text,\n"
1397 " rootpage integer,\n"
1398 " sql text\n"
1399 ")";
1400 new_argv[1] = 0;
1401 new_colv[0] = "sql";
1402 new_colv[1] = 0;
1403 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001404 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001405 zShellStatic = azArg[1];
1406 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001407 "SELECT sql FROM "
1408 " (SELECT * FROM sqlite_master UNION ALL"
1409 " SELECT * FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001410 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001411 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001412 callback, &data, &zErrMsg);
1413 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001414 }
drh75897232000-05-29 14:26:00 +00001415 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001416 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001417 "SELECT sql FROM "
1418 " (SELECT * FROM sqlite_master UNION ALL"
1419 " SELECT * FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001420 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001421 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001422 callback, &data, &zErrMsg
1423 );
drh75897232000-05-29 14:26:00 +00001424 }
drh75897232000-05-29 14:26:00 +00001425 if( zErrMsg ){
1426 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001427 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001428 }
1429 }else
1430
1431 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001432 sqlite3_snprintf(sizeof(p->separator), p->separator,
1433 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001434 }else
1435
persicom7e2dfdd2002-04-18 02:46:52 +00001436 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1437 int i;
1438 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001439 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001440 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001441 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001442 fprintf(p->out,"%9.9s: ", "nullvalue");
1443 output_c_string(p->out, p->nullvalue);
1444 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001445 fprintf(p->out,"%9.9s: %s\n","output",
1446 strlen(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001447 fprintf(p->out,"%9.9s: ", "separator");
1448 output_c_string(p->out, p->separator);
1449 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001450 fprintf(p->out,"%9.9s: ","width");
1451 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001452 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001453 }
drhfeac5f82004-08-01 00:10:45 +00001454 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001455 }else
1456
drh2dfbbca2000-07-28 14:32:48 +00001457 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001458 char **azResult;
1459 int nRow, rc;
1460 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001461 open_db(p);
drha50da102000-08-08 20:19:09 +00001462 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001463 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001464 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001465 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001466 "UNION ALL "
1467 "SELECT name FROM sqlite_temp_master "
1468 "WHERE type IN ('table','view') "
1469 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001470 &azResult, &nRow, 0, &zErrMsg
1471 );
drha50da102000-08-08 20:19:09 +00001472 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001473 zShellStatic = azArg[1];
1474 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001475 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001476 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001477 "UNION ALL "
1478 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001479 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001480 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001481 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001482 );
danielk1977bc6ada42004-06-30 08:20:16 +00001483 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001484 }
drh75897232000-05-29 14:26:00 +00001485 if( zErrMsg ){
1486 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001487 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001488 }
drhe3710332000-09-29 13:30:53 +00001489 if( rc==SQLITE_OK ){
1490 int len, maxlen = 0;
1491 int i, j;
1492 int nPrintCol, nPrintRow;
1493 for(i=1; i<=nRow; i++){
1494 if( azResult[i]==0 ) continue;
1495 len = strlen(azResult[i]);
1496 if( len>maxlen ) maxlen = len;
1497 }
1498 nPrintCol = 80/(maxlen+2);
1499 if( nPrintCol<1 ) nPrintCol = 1;
1500 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1501 for(i=0; i<nPrintRow; i++){
1502 for(j=i+1; j<=nRow; j+=nPrintRow){
1503 char *zSp = j<=nPrintRow ? "" : " ";
1504 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1505 }
1506 printf("\n");
1507 }
drh47ad6842006-11-08 12:25:42 +00001508 }else{
1509 rc = 1;
drhe3710332000-09-29 13:30:53 +00001510 }
danielk19776f8a5032004-05-10 10:34:51 +00001511 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001512 }else
1513
drh2dfbbca2000-07-28 14:32:48 +00001514 if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001515 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001516 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001517 }else
1518
drh75897232000-05-29 14:26:00 +00001519 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1520 int j;
drh43617e92006-03-06 20:55:46 +00001521 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001522 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1523 p->colWidth[j-1] = atoi(azArg[j]);
1524 }
1525 }else
1526
1527 {
drh67505e72002-04-19 12:34:06 +00001528 fprintf(stderr, "unknown command or invalid arguments: "
1529 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001530 }
drh67505e72002-04-19 12:34:06 +00001531
1532 return rc;
drh75897232000-05-29 14:26:00 +00001533}
1534
drh67505e72002-04-19 12:34:06 +00001535/*
drh324ccef2003-02-05 14:06:20 +00001536** Return TRUE if the last non-whitespace character in z[] is a semicolon.
1537** z[] is N characters long.
1538*/
1539static int _ends_with_semicolon(const char *z, int N){
drh4c755c02004-08-08 20:22:17 +00001540 while( N>0 && isspace((unsigned char)z[N-1]) ){ N--; }
drh324ccef2003-02-05 14:06:20 +00001541 return N>0 && z[N-1]==';';
1542}
1543
1544/*
drh70c7a4b2003-04-26 03:03:06 +00001545** Test to see if a line consists entirely of whitespace.
1546*/
1547static int _all_whitespace(const char *z){
1548 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001549 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001550 if( *z=='/' && z[1]=='*' ){
1551 z += 2;
1552 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1553 if( *z==0 ) return 0;
1554 z++;
1555 continue;
1556 }
1557 if( *z=='-' && z[1]=='-' ){
1558 z += 2;
1559 while( *z && *z!='\n' ){ z++; }
1560 if( *z==0 ) return 1;
1561 continue;
1562 }
1563 return 0;
1564 }
1565 return 1;
1566}
1567
1568/*
drha9b17162003-04-29 18:01:28 +00001569** Return TRUE if the line typed in is an SQL command terminator other
1570** than a semi-colon. The SQL Server style "go" command is understood
1571** as is the Oracle "/".
1572*/
1573static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001574 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drha9b17162003-04-29 18:01:28 +00001575 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
drhc8d74412004-08-31 23:41:26 +00001576 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1577 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001578 return 1; /* SQL Server */
1579 }
1580 return 0;
1581}
1582
1583/*
drh67505e72002-04-19 12:34:06 +00001584** Read input from *in and process it. If *in==0 then input
1585** is interactive - the user is typing it it. Otherwise, input
1586** is coming from a file or device. A prompt is issued and history
1587** is saved only if input is interactive. An interrupt signal will
1588** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001589**
1590** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001591*/
drhc28490c2006-10-26 14:25:58 +00001592static int process_input(struct callback_data *p, FILE *in){
drhdaffd0e2001-04-11 14:28:42 +00001593 char *zLine;
1594 char *zSql = 0;
1595 int nSql = 0;
1596 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001597 int rc;
1598 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001599 int lineno = 0;
1600 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001601
1602 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1603 fflush(p->out);
1604 zLine = one_input_line(zSql, in);
1605 if( zLine==0 ){
1606 break; /* We have reached EOF */
1607 }
drh67505e72002-04-19 12:34:06 +00001608 if( seenInterrupt ){
1609 if( in!=0 ) break;
1610 seenInterrupt = 0;
1611 }
drhc28490c2006-10-26 14:25:58 +00001612 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001613 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001614 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001615 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001616 rc = do_meta_command(zLine, p);
drhdaffd0e2001-04-11 14:28:42 +00001617 free(zLine);
drh47ad6842006-11-08 12:25:42 +00001618 if( rc==2 ){
1619 break;
1620 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001621 errCnt++;
1622 }
drhdaffd0e2001-04-11 14:28:42 +00001623 continue;
1624 }
drha9b17162003-04-29 18:01:28 +00001625 if( _is_command_terminator(zLine) ){
drh5bb3eb92007-05-04 13:15:55 +00001626 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001627 }
drhdaffd0e2001-04-11 14:28:42 +00001628 if( zSql==0 ){
1629 int i;
drh4c755c02004-08-08 20:22:17 +00001630 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001631 if( zLine[i]!=0 ){
1632 nSql = strlen(zLine);
1633 zSql = malloc( nSql+1 );
drhc1f44942006-05-10 14:39:13 +00001634 if( zSql==0 ){
1635 fprintf(stderr, "out of memory\n");
1636 exit(1);
1637 }
drh5bb3eb92007-05-04 13:15:55 +00001638 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001639 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001640 }
1641 }else{
1642 int len = strlen(zLine);
1643 zSql = realloc( zSql, nSql + len + 2 );
1644 if( zSql==0 ){
1645 fprintf(stderr,"%s: out of memory!\n", Argv0);
1646 exit(1);
1647 }
drh5bb3eb92007-05-04 13:15:55 +00001648 zSql[nSql++] = '\n';
1649 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001650 nSql += len;
1651 }
1652 free(zLine);
danielk19776f8a5032004-05-10 10:34:51 +00001653 if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001654 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001655 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001656 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001657 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001658 char zPrefix[100];
1659 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001660 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1661 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001662 }else{
drh5bb3eb92007-05-04 13:15:55 +00001663 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001664 }
drh7f953e22002-07-13 17:33:45 +00001665 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001666 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001667 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001668 zErrMsg = 0;
1669 }else{
drhc28490c2006-10-26 14:25:58 +00001670 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001671 }
drhc49f44e2006-10-26 18:15:42 +00001672 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001673 }
1674 free(zSql);
1675 zSql = 0;
1676 nSql = 0;
1677 }
1678 }
1679 if( zSql ){
drh70c7a4b2003-04-26 03:03:06 +00001680 if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001681 free(zSql);
1682 }
drhc49f44e2006-10-26 18:15:42 +00001683 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001684}
1685
drh67505e72002-04-19 12:34:06 +00001686/*
1687** Return a pathname which is the user's home directory. A
1688** 0 return indicates an error of some kind. Space to hold the
1689** resulting string is obtained from malloc(). The calling
1690** function should free the result.
1691*/
1692static char *find_home_dir(void){
1693 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001694
drhcdb36b72006-06-12 12:57:45 +00001695#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) && !defined(__OS2__)
drh67505e72002-04-19 12:34:06 +00001696 struct passwd *pwent;
1697 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001698 if( (pwent=getpwuid(uid)) != NULL) {
1699 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001700 }
1701#endif
1702
drh820f3812003-01-08 13:02:52 +00001703#ifdef __MACOS__
1704 char home_path[_MAX_PATH+1];
1705 home_dir = getcwd(home_path, _MAX_PATH);
1706#endif
1707
drh164a1b62006-08-19 11:15:20 +00001708#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1709 if (!home_dir) {
1710 home_dir = getenv("USERPROFILE");
1711 }
1712#endif
1713
drh67505e72002-04-19 12:34:06 +00001714 if (!home_dir) {
1715 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001716 }
1717
drhcdb36b72006-06-12 12:57:45 +00001718#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001719 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001720 char *zDrive, *zPath;
1721 int n;
1722 zDrive = getenv("HOMEDRIVE");
1723 zPath = getenv("HOMEPATH");
1724 if( zDrive && zPath ){
1725 n = strlen(zDrive) + strlen(zPath) + 1;
1726 home_dir = malloc( n );
1727 if( home_dir==0 ) return 0;
1728 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1729 return home_dir;
1730 }
1731 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001732 }
1733#endif
1734
drh67505e72002-04-19 12:34:06 +00001735 if( home_dir ){
drh5bb3eb92007-05-04 13:15:55 +00001736 int n = strlen(home_dir) + 1;
1737 char *z = malloc( n );
1738 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001739 home_dir = z;
1740 }
drhe98d4fa2002-04-21 19:06:22 +00001741
drh67505e72002-04-19 12:34:06 +00001742 return home_dir;
1743}
1744
1745/*
1746** Read input from the file given by sqliterc_override. Or if that
1747** parameter is NULL, take input from ~/.sqliterc
1748*/
drh22fbcb82004-02-01 01:22:50 +00001749static void process_sqliterc(
1750 struct callback_data *p, /* Configuration data */
1751 const char *sqliterc_override /* Name of config file. NULL to use default */
1752){
persicom7e2dfdd2002-04-18 02:46:52 +00001753 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001754 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001755 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001756 FILE *in = NULL;
1757
1758 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001759 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001760 if( home_dir==0 ){
1761 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
1762 return;
1763 }
drh22fbcb82004-02-01 01:22:50 +00001764 zBuf = malloc(strlen(home_dir) + 15);
1765 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001766 fprintf(stderr,"%s: out of memory!\n", Argv0);
1767 exit(1);
1768 }
drh5bb3eb92007-05-04 13:15:55 +00001769 sqlite3_snprintf(sizeof(zBuf), zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001770 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001771 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001772 }
drha1f9b5e2004-02-14 16:31:02 +00001773 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001774 if( in ){
drhc28490c2006-10-26 14:25:58 +00001775 if( stdin_is_interactive ){
drh22fbcb82004-02-01 01:22:50 +00001776 printf("Loading resources from %s\n",sqliterc);
1777 }
persicom7e2dfdd2002-04-18 02:46:52 +00001778 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001779 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001780 }
drh43617e92006-03-06 20:55:46 +00001781 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001782 return;
1783}
1784
drh67505e72002-04-19 12:34:06 +00001785/*
drhe1e38c42003-05-04 18:30:59 +00001786** Show available command line options
1787*/
1788static const char zOptions[] =
1789 " -init filename read/process named file\n"
1790 " -echo print commands before execution\n"
1791 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001792 " -bail stop after hitting an error\n"
1793 " -interactive force interactive I/O\n"
1794 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001795 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001796 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001797 " -html set output mode to HTML\n"
1798 " -line set output mode to 'line'\n"
1799 " -list set output mode to 'list'\n"
1800 " -separator 'x' set output field separator (|)\n"
1801 " -nullvalue 'text' set text string for NULL values\n"
1802 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001803;
1804static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001805 fprintf(stderr,
1806 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1807 "FILENAME is the name of an SQLite database. A new database is created\n"
1808 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001809 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001810 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001811 }else{
1812 fprintf(stderr, "Use the -help option for additional information\n");
1813 }
1814 exit(1);
1815}
1816
1817/*
drh67505e72002-04-19 12:34:06 +00001818** Initialize the state information in data
1819*/
drh0850b532006-01-31 19:31:43 +00001820static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001821 memset(data, 0, sizeof(*data));
1822 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001823 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001824 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001825 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1826 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001827}
1828
drh75897232000-05-29 14:26:00 +00001829int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001830 char *zErrMsg = 0;
1831 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001832 const char *zInitFile = 0;
1833 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001834 int i;
drhc28490c2006-10-26 14:25:58 +00001835 int rc = 0;
drh75897232000-05-29 14:26:00 +00001836
drh820f3812003-01-08 13:02:52 +00001837#ifdef __MACOS__
1838 argc = ccommand(&argv);
drh820f3812003-01-08 13:02:52 +00001839#endif
1840
drhdaffd0e2001-04-11 14:28:42 +00001841 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001842 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001843 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001844
drh44c2eb12003-04-30 11:38:26 +00001845 /* Make sure we have a valid signal handler early, before anything
1846 ** else is done.
1847 */
drh4c504392000-10-16 22:06:40 +00001848#ifdef SIGINT
1849 signal(SIGINT, interrupt_handler);
1850#endif
drh44c2eb12003-04-30 11:38:26 +00001851
drh22fbcb82004-02-01 01:22:50 +00001852 /* Do an initial pass through the command-line argument to locate
1853 ** the name of the database file, the name of the initialization file,
1854 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001855 */
drh22fbcb82004-02-01 01:22:50 +00001856 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001857 char *z;
drh44c2eb12003-04-30 11:38:26 +00001858 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001859 z = argv[i];
1860 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001861 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1862 i++;
drh22fbcb82004-02-01 01:22:50 +00001863 }else if( strcmp(argv[i],"-init")==0 ){
1864 i++;
1865 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001866 }
1867 }
drh22fbcb82004-02-01 01:22:50 +00001868 if( i<argc ){
1869 data.zDbFilename = argv[i++];
1870 }else{
danielk197703aded42004-11-22 05:26:27 +00001871#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00001872 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00001873#else
1874 data.zDbFilename = 0;
1875#endif
drh22fbcb82004-02-01 01:22:50 +00001876 }
1877 if( i<argc ){
1878 zFirstCmd = argv[i++];
1879 }
drh44c2eb12003-04-30 11:38:26 +00001880 data.out = stdout;
1881
drh01b41712005-08-29 23:06:23 +00001882#ifdef SQLITE_OMIT_MEMORYDB
1883 if( data.zDbFilename==0 ){
1884 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
1885 exit(1);
1886 }
1887#endif
1888
drh44c2eb12003-04-30 11:38:26 +00001889 /* Go ahead and open the database file if it already exists. If the
1890 ** file does not exist, delay opening it. This prevents empty database
1891 ** files from being created if a user mistypes the database name argument
1892 ** to the sqlite command-line tool.
1893 */
drhc8d74412004-08-31 23:41:26 +00001894 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00001895 open_db(&data);
1896 }
1897
drh22fbcb82004-02-01 01:22:50 +00001898 /* Process the initialization file if there is one. If no -init option
1899 ** is given on the command line, look for a file named ~/.sqliterc and
1900 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00001901 */
drh22fbcb82004-02-01 01:22:50 +00001902 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00001903
drh22fbcb82004-02-01 01:22:50 +00001904 /* Make a second pass through the command-line argument and set
1905 ** options. This second pass is delayed until after the initialization
1906 ** file is processed so that the command-line arguments will override
1907 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00001908 */
drh22fbcb82004-02-01 01:22:50 +00001909 for(i=1; i<argc && argv[i][0]=='-'; i++){
1910 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00001911 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00001912 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00001913 i++;
1914 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001915 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00001916 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001917 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00001918 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001919 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00001920 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00001921 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00001922 }else if( strcmp(z,"-csv")==0 ){
1923 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001924 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00001925 }else if( strcmp(z,"-separator")==0 ){
1926 i++;
drh5bb3eb92007-05-04 13:15:55 +00001927 sqlite3_snprintf(sizeof(data.separator), data.separator,
1928 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00001929 }else if( strcmp(z,"-nullvalue")==0 ){
1930 i++;
drh5bb3eb92007-05-04 13:15:55 +00001931 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
1932 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00001933 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001934 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00001935 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001936 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00001937 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00001938 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00001939 }else if( strcmp(z,"-bail")==0 ){
1940 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00001941 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00001942 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00001943 return 0;
drhc28490c2006-10-26 14:25:58 +00001944 }else if( strcmp(z,"-interactive")==0 ){
1945 stdin_is_interactive = 1;
1946 }else if( strcmp(z,"-batch")==0 ){
1947 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00001948 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00001949 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00001950 }else{
drh22fbcb82004-02-01 01:22:50 +00001951 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00001952 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00001953 return 1;
1954 }
1955 }
drh44c2eb12003-04-30 11:38:26 +00001956
drh22fbcb82004-02-01 01:22:50 +00001957 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00001958 /* Run just the command that follows the database name
1959 */
drh22fbcb82004-02-01 01:22:50 +00001960 if( zFirstCmd[0]=='.' ){
1961 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00001962 exit(0);
1963 }else{
1964 int rc;
drh44c2eb12003-04-30 11:38:26 +00001965 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00001966 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00001967 if( rc!=0 && zErrMsg!=0 ){
1968 fprintf(stderr,"SQL error: %s\n", zErrMsg);
1969 exit(1);
1970 }
drh75897232000-05-29 14:26:00 +00001971 }
1972 }else{
drh44c2eb12003-04-30 11:38:26 +00001973 /* Run commands received from standard input
1974 */
drhc28490c2006-10-26 14:25:58 +00001975 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00001976 char *zHome;
1977 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00001978 int nHistory;
drh75897232000-05-29 14:26:00 +00001979 printf(
drhb217a572000-08-22 13:40:18 +00001980 "SQLite version %s\n"
1981 "Enter \".help\" for instructions\n",
drhc8d74412004-08-31 23:41:26 +00001982 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00001983 );
drh67505e72002-04-19 12:34:06 +00001984 zHome = find_home_dir();
drh5bb3eb92007-05-04 13:15:55 +00001985 if( zHome && (zHistory = malloc(nHistory = strlen(zHome)+20))!=0 ){
1986 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
drh67505e72002-04-19 12:34:06 +00001987 }
danielk19774af00c62005-01-23 23:43:21 +00001988#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00001989 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00001990#endif
drhc28490c2006-10-26 14:25:58 +00001991 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00001992 if( zHistory ){
1993 stifle_history(100);
1994 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00001995 free(zHistory);
drh67505e72002-04-19 12:34:06 +00001996 }
adamd0a3daa32006-07-28 20:16:14 +00001997 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00001998 }else{
drhc28490c2006-10-26 14:25:58 +00001999 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002000 }
2001 }
drh33048c02001-10-01 14:29:22 +00002002 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002003 if( db ){
2004 if( sqlite3_close(db)!=SQLITE_OK ){
2005 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2006 }
2007 }
drhc28490c2006-10-26 14:25:58 +00002008 return rc;
drh75897232000-05-29 14:26:00 +00002009}