blob: a7d555b2b5587b3c3ba98dc8146e6d80abf14ae8 [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**
rsebe0a9092007-07-30 18:24:38 +000015** $Id: shell.c,v 1.165 2007/07/30 18:24:39 rse 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*/
rsebe0a9092007-07-30 18:24:38 +0000104#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000105static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000106#endif
drhb0603412007-02-28 04:47:26 +0000107
108/*
109** This routine works like printf in that its first argument is a
110** format string and subsequent arguments are values to be substituted
111** in place of % fields. The result of formatting this string
112** is written to iotrace.
113*/
rsebe0a9092007-07-30 18:24:38 +0000114#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000115static void iotracePrintf(const char *zFormat, ...){
116 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000117 char *z;
drhb0603412007-02-28 04:47:26 +0000118 if( iotrace==0 ) return;
119 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000120 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000121 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000122 fprintf(iotrace, "%s", z);
123 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000124}
rsebe0a9092007-07-30 18:24:38 +0000125#endif
drhb0603412007-02-28 04:47:26 +0000126
drh44c2eb12003-04-30 11:38:26 +0000127
persicom7e2dfdd2002-04-18 02:46:52 +0000128/*
drh83965662003-04-17 02:54:13 +0000129** Determines if a string is a number of not.
130*/
danielk19772e588c72005-12-09 14:25:08 +0000131static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000132 if( *z=='-' || *z=='+' ) z++;
133 if( !isdigit(*z) ){
134 return 0;
135 }
136 z++;
137 if( realnum ) *realnum = 0;
138 while( isdigit(*z) ){ z++; }
139 if( *z=='.' ){
140 z++;
141 if( !isdigit(*z) ) return 0;
142 while( isdigit(*z) ){ z++; }
143 if( realnum ) *realnum = 1;
144 }
145 if( *z=='e' || *z=='E' ){
146 z++;
147 if( *z=='+' || *z=='-' ) z++;
148 if( !isdigit(*z) ) return 0;
149 while( isdigit(*z) ){ z++; }
150 if( realnum ) *realnum = 1;
151 }
152 return *z==0;
153}
drh83965662003-04-17 02:54:13 +0000154
155/*
danielk1977bc6ada42004-06-30 08:20:16 +0000156** A global char* and an SQL function to access its current value
157** from within an SQL statement. This program used to use the
158** sqlite_exec_printf() API to substitue a string into an SQL statement.
159** The correct way to do this with sqlite3 is to use the bind API, but
160** since the shell is built around the callback paradigm it would be a lot
161** of work. Instead just use this hack, which is quite harmless.
162*/
163static const char *zShellStatic = 0;
164static void shellstaticFunc(
165 sqlite3_context *context,
166 int argc,
167 sqlite3_value **argv
168){
169 assert( 0==argc );
170 assert( zShellStatic );
171 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
172}
173
174
175/*
drhfeac5f82004-08-01 00:10:45 +0000176** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000177** the text in memory obtained from malloc() and returns a pointer
178** to the text. NULL is returned at end of file, or if malloc()
179** fails.
180**
181** The interface is like "readline" but no command-line editing
182** is done.
183*/
drh9347b202003-07-18 01:30:59 +0000184static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000185 char *zLine;
186 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000187 int n;
188 int eol;
189
190 if( zPrompt && *zPrompt ){
191 printf("%s",zPrompt);
192 fflush(stdout);
193 }
194 nLine = 100;
195 zLine = malloc( nLine );
196 if( zLine==0 ) return 0;
197 n = 0;
198 eol = 0;
199 while( !eol ){
200 if( n+100>nLine ){
201 nLine = nLine*2 + 100;
202 zLine = realloc(zLine, nLine);
203 if( zLine==0 ) return 0;
204 }
drhdaffd0e2001-04-11 14:28:42 +0000205 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000206 if( n==0 ){
207 free(zLine);
208 return 0;
209 }
210 zLine[n] = 0;
211 eol = 1;
212 break;
213 }
214 while( zLine[n] ){ n++; }
215 if( n>0 && zLine[n-1]=='\n' ){
216 n--;
217 zLine[n] = 0;
218 eol = 1;
219 }
220 }
221 zLine = realloc( zLine, n+1 );
222 return zLine;
223}
224
225/*
drhc28490c2006-10-26 14:25:58 +0000226** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000227**
228** zPrior is a string of prior text retrieved. If not the empty
229** string, then issue a continuation prompt.
230*/
drhdaffd0e2001-04-11 14:28:42 +0000231static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000232 char *zPrompt;
233 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000234 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000235 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000236 }
237 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000238 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000239 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000240 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000241 }
242 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000243#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000244 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000245#endif
drh8e7e7a22000-05-30 18:45:23 +0000246 return zResult;
247}
248
persicom7e2dfdd2002-04-18 02:46:52 +0000249struct previous_mode_data {
250 int valid; /* Is there legit data in here? */
251 int mode;
252 int showHeader;
253 int colWidth[100];
254};
drh45e29d82006-11-20 16:21:10 +0000255
drh8e7e7a22000-05-30 18:45:23 +0000256/*
drh75897232000-05-29 14:26:00 +0000257** An pointer to an instance of this structure is passed from
258** the main program to the callback. This is used to communicate
259** state and mode information.
260*/
261struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000262 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000263 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000264 int cnt; /* Number of records displayed so far */
265 FILE *out; /* Write results here */
266 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000267 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000268 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000269 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000270 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000271 int colWidth[100]; /* Requested width of each column when in column mode*/
272 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000273 char nullvalue[20]; /* The text to print when a NULL comes back from
274 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000275 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000276 /* Holds the mode information just before
277 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000278 char outfile[FILENAME_MAX]; /* Filename for *out */
279 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000280};
281
282/*
283** These are the allowed modes.
284*/
drh967e8b72000-06-21 13:59:10 +0000285#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000286#define MODE_Column 1 /* One record per line in neat columns */
287#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000288#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
289#define MODE_Html 4 /* Generate an XHTML table */
290#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000291#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000292#define MODE_Csv 7 /* Quote strings, numbers are plain */
293#define MODE_NUM_OF 8 /* The number of modes (not a mode itself) */
persicom7e2dfdd2002-04-18 02:46:52 +0000294
drh0850b532006-01-31 19:31:43 +0000295static const char *modeDescr[MODE_NUM_OF] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000296 "line",
297 "column",
298 "list",
299 "semi",
300 "html",
drhfeac5f82004-08-01 00:10:45 +0000301 "insert",
302 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000303 "csv",
persicom7e2dfdd2002-04-18 02:46:52 +0000304};
drh75897232000-05-29 14:26:00 +0000305
306/*
307** Number of elements in an array
308*/
309#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
310
311/*
drh28bd4bc2000-06-15 15:57:22 +0000312** Output the given string as a quoted string using SQL quoting conventions.
313*/
314static void output_quoted_string(FILE *out, const char *z){
315 int i;
316 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000317 for(i=0; z[i]; i++){
318 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000319 }
320 if( nSingle==0 ){
321 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000322 }else{
323 fprintf(out,"'");
324 while( *z ){
325 for(i=0; z[i] && z[i]!='\''; i++){}
326 if( i==0 ){
327 fprintf(out,"''");
328 z++;
329 }else if( z[i]=='\'' ){
330 fprintf(out,"%.*s''",i,z);
331 z += i+1;
332 }else{
drhcd7d2732002-02-26 23:24:26 +0000333 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000334 break;
335 }
336 }
drhcd7d2732002-02-26 23:24:26 +0000337 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000338 }
339}
340
341/*
drhfeac5f82004-08-01 00:10:45 +0000342** Output the given string as a quoted according to C or TCL quoting rules.
343*/
344static void output_c_string(FILE *out, const char *z){
345 unsigned int c;
346 fputc('"', out);
347 while( (c = *(z++))!=0 ){
348 if( c=='\\' ){
349 fputc(c, out);
350 fputc(c, out);
351 }else if( c=='\t' ){
352 fputc('\\', out);
353 fputc('t', out);
354 }else if( c=='\n' ){
355 fputc('\\', out);
356 fputc('n', out);
357 }else if( c=='\r' ){
358 fputc('\\', out);
359 fputc('r', out);
360 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000361 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000362 }else{
363 fputc(c, out);
364 }
365 }
366 fputc('"', out);
367}
368
369/*
drhc08a4f12000-06-15 16:49:48 +0000370** Output the given string with characters that are special to
371** HTML escaped.
372*/
373static void output_html_string(FILE *out, const char *z){
374 int i;
375 while( *z ){
376 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
377 if( i>0 ){
378 fprintf(out,"%.*s",i,z);
379 }
380 if( z[i]=='<' ){
381 fprintf(out,"&lt;");
382 }else if( z[i]=='&' ){
383 fprintf(out,"&amp;");
384 }else{
385 break;
386 }
387 z += i + 1;
388 }
389}
390
391/*
drhc49f44e2006-10-26 18:15:42 +0000392** If a field contains any character identified by a 1 in the following
393** array, then the string must be quoted for CSV.
394*/
395static const char needCsvQuote[] = {
396 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
397 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
398 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
399 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
400 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
401 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
402 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
403 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
409 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
410 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
411 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
412};
413
414/*
drh8e64d1c2004-10-07 00:32:39 +0000415** Output a single term of CSV. Actually, p->separator is used for
416** the separator, which may or may not be a comma. p->nullvalue is
417** the null value. Strings are quoted using ANSI-C rules. Numbers
418** appear outside of quotes.
419*/
420static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000421 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000422 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000423 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000424 }else{
drhc49f44e2006-10-26 18:15:42 +0000425 int i;
426 for(i=0; z[i]; i++){
427 if( needCsvQuote[((unsigned char*)z)[i]] ){
428 i = 0;
429 break;
430 }
431 }
432 if( i==0 ){
433 putc('"', out);
434 for(i=0; z[i]; i++){
435 if( z[i]=='"' ) putc('"', out);
436 putc(z[i], out);
437 }
438 putc('"', out);
439 }else{
440 fprintf(out, "%s", z);
441 }
drh8e64d1c2004-10-07 00:32:39 +0000442 }
443 if( bSep ){
444 fprintf(p->out, p->separator);
445 }
446}
447
danielk19774af00c62005-01-23 23:43:21 +0000448#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000449/*
drh4c504392000-10-16 22:06:40 +0000450** This routine runs when the user presses Ctrl-C
451*/
452static void interrupt_handler(int NotUsed){
drh67505e72002-04-19 12:34:06 +0000453 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000454 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000455}
danielk19774af00c62005-01-23 23:43:21 +0000456#endif
drh4c504392000-10-16 22:06:40 +0000457
458/*
drh75897232000-05-29 14:26:00 +0000459** This is the callback routine that the SQLite library
460** invokes for each row of a query result.
461*/
462static int callback(void *pArg, int nArg, char **azArg, char **azCol){
463 int i;
464 struct callback_data *p = (struct callback_data*)pArg;
465 switch( p->mode ){
466 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000467 int w = 5;
drh6a535342001-10-19 16:44:56 +0000468 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000469 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000470 int len = strlen(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000471 if( len>w ) w = len;
472 }
drh75897232000-05-29 14:26:00 +0000473 if( p->cnt++>0 ) fprintf(p->out,"\n");
474 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000475 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000476 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000477 }
478 break;
479 }
480 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000481 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000482 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000483 int w, n;
484 if( i<ArraySize(p->colWidth) ){
drh75897232000-05-29 14:26:00 +0000485 w = p->colWidth[i];
486 }else{
drha0c66f52000-07-29 13:20:21 +0000487 w = 0;
drh75897232000-05-29 14:26:00 +0000488 }
drha0c66f52000-07-29 13:20:21 +0000489 if( w<=0 ){
drhff6e9112000-08-28 16:21:58 +0000490 w = strlen(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000491 if( w<10 ) w = 10;
persicom7e2dfdd2002-04-18 02:46:52 +0000492 n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000493 if( w<n ) w = n;
494 }
495 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000496 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000497 }
498 if( p->showHeader ){
499 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
500 }
501 }
502 if( p->showHeader ){
503 for(i=0; i<nArg; i++){
504 int w;
505 if( i<ArraySize(p->actualWidth) ){
506 w = p->actualWidth[i];
507 }else{
508 w = 10;
509 }
510 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
511 "----------------------------------------------------------",
512 i==nArg-1 ? "\n": " ");
513 }
drh75897232000-05-29 14:26:00 +0000514 }
515 }
drh6a535342001-10-19 16:44:56 +0000516 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000517 for(i=0; i<nArg; i++){
518 int w;
drha0c66f52000-07-29 13:20:21 +0000519 if( i<ArraySize(p->actualWidth) ){
520 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000521 }else{
522 w = 10;
523 }
drhc61053b2000-06-04 12:58:36 +0000524 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000525 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000526 }
527 break;
528 }
drhe3710332000-09-29 13:30:53 +0000529 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000530 case MODE_List: {
531 if( p->cnt++==0 && p->showHeader ){
532 for(i=0; i<nArg; i++){
533 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
534 }
535 }
drh6a535342001-10-19 16:44:56 +0000536 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000537 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000538 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000539 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000540 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000541 if( i<nArg-1 ){
542 fprintf(p->out, "%s", p->separator);
543 }else if( p->mode==MODE_Semi ){
544 fprintf(p->out, ";\n");
545 }else{
546 fprintf(p->out, "\n");
547 }
drh75897232000-05-29 14:26:00 +0000548 }
549 break;
550 }
drh1e5d0e92000-05-31 23:33:17 +0000551 case MODE_Html: {
552 if( p->cnt++==0 && p->showHeader ){
553 fprintf(p->out,"<TR>");
554 for(i=0; i<nArg; i++){
555 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
556 }
557 fprintf(p->out,"</TR>\n");
558 }
drh6a535342001-10-19 16:44:56 +0000559 if( azArg==0 ) break;
drh28bd4bc2000-06-15 15:57:22 +0000560 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000561 for(i=0; i<nArg; i++){
drhc08a4f12000-06-15 16:49:48 +0000562 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000563 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
drhc08a4f12000-06-15 16:49:48 +0000564 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000565 }
drh7d686b22002-11-11 13:56:47 +0000566 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000567 break;
568 }
drhfeac5f82004-08-01 00:10:45 +0000569 case MODE_Tcl: {
570 if( p->cnt++==0 && p->showHeader ){
571 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000572 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000573 fprintf(p->out, "%s", p->separator);
574 }
575 fprintf(p->out,"\n");
576 }
577 if( azArg==0 ) break;
578 for(i=0; i<nArg; i++){
579 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
580 fprintf(p->out, "%s", p->separator);
581 }
582 fprintf(p->out,"\n");
583 break;
584 }
drh8e64d1c2004-10-07 00:32:39 +0000585 case MODE_Csv: {
586 if( p->cnt++==0 && p->showHeader ){
587 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000588 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000589 }
590 fprintf(p->out,"\n");
591 }
592 if( azArg==0 ) break;
593 for(i=0; i<nArg; i++){
594 output_csv(p, azArg[i], i<nArg-1);
595 }
596 fprintf(p->out,"\n");
597 break;
598 }
drh28bd4bc2000-06-15 15:57:22 +0000599 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000600 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000601 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000602 for(i=0; i<nArg; i++){
603 char *zSep = i>0 ? ",": "";
604 if( azArg[i]==0 ){
605 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000606 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000607 fprintf(p->out,"%s%s",zSep, azArg[i]);
608 }else{
609 if( zSep[0] ) fprintf(p->out,"%s",zSep);
610 output_quoted_string(p->out, azArg[i]);
611 }
612 }
613 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000614 break;
drh28bd4bc2000-06-15 15:57:22 +0000615 }
persicom1d0b8722002-04-18 02:53:04 +0000616 }
drh75897232000-05-29 14:26:00 +0000617 return 0;
618}
619
620/*
drh33048c02001-10-01 14:29:22 +0000621** Set the destination table field of the callback_data structure to
622** the name of the table given. Escape any quote characters in the
623** table name.
624*/
625static void set_table_name(struct callback_data *p, const char *zName){
626 int i, n;
627 int needQuote;
628 char *z;
629
630 if( p->zDestTable ){
631 free(p->zDestTable);
632 p->zDestTable = 0;
633 }
634 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000635 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000636 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000637 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000638 needQuote = 1;
639 if( zName[i]=='\'' ) n++;
640 }
641 }
642 if( needQuote ) n += 2;
643 z = p->zDestTable = malloc( n+1 );
644 if( z==0 ){
645 fprintf(stderr,"Out of memory!\n");
646 exit(1);
647 }
648 n = 0;
649 if( needQuote ) z[n++] = '\'';
650 for(i=0; zName[i]; i++){
651 z[n++] = zName[i];
652 if( zName[i]=='\'' ) z[n++] = '\'';
653 }
654 if( needQuote ) z[n++] = '\'';
655 z[n] = 0;
656}
657
danielk19772a02e332004-06-05 08:04:36 +0000658/* zIn is either a pointer to a NULL-terminated string in memory obtained
659** from malloc(), or a NULL pointer. The string pointed to by zAppend is
660** added to zIn, and the result returned in memory obtained from malloc().
661** zIn, if it was not NULL, is freed.
662**
663** If the third argument, quote, is not '\0', then it is used as a
664** quote character for zAppend.
665*/
drhc28490c2006-10-26 14:25:58 +0000666static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000667 int len;
668 int i;
669 int nAppend = strlen(zAppend);
670 int nIn = (zIn?strlen(zIn):0);
671
672 len = nAppend+nIn+1;
673 if( quote ){
674 len += 2;
675 for(i=0; i<nAppend; i++){
676 if( zAppend[i]==quote ) len++;
677 }
678 }
679
680 zIn = (char *)realloc(zIn, len);
681 if( !zIn ){
682 return 0;
683 }
684
685 if( quote ){
686 char *zCsr = &zIn[nIn];
687 *zCsr++ = quote;
688 for(i=0; i<nAppend; i++){
689 *zCsr++ = zAppend[i];
690 if( zAppend[i]==quote ) *zCsr++ = quote;
691 }
692 *zCsr++ = quote;
693 *zCsr++ = '\0';
694 assert( (zCsr-zIn)==len );
695 }else{
696 memcpy(&zIn[nIn], zAppend, nAppend);
697 zIn[len-1] = '\0';
698 }
699
700 return zIn;
701}
702
drhdd3d4592004-08-30 01:54:05 +0000703
704/*
705** Execute a query statement that has a single result column. Print
706** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000707**
708** This is used, for example, to show the schema of the database by
709** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000710*/
711static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
712 sqlite3_stmt *pSelect;
713 int rc;
714 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
715 if( rc!=SQLITE_OK || !pSelect ){
716 return rc;
717 }
718 rc = sqlite3_step(pSelect);
719 while( rc==SQLITE_ROW ){
720 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
721 rc = sqlite3_step(pSelect);
722 }
723 return sqlite3_finalize(pSelect);
724}
725
726
drh33048c02001-10-01 14:29:22 +0000727/*
drh4c653a02000-06-07 01:27:47 +0000728** This is a different callback routine used for dumping the database.
729** Each row received by this callback consists of a table name,
730** the table type ("index" or "table") and SQL to create the table.
731** This routine should print text sufficient to recreate the table.
732*/
733static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000734 int rc;
735 const char *zTable;
736 const char *zType;
737 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000738 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000739
drh4c653a02000-06-07 01:27:47 +0000740 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000741 zTable = azArg[0];
742 zType = azArg[1];
743 zSql = azArg[2];
744
drh00b950d2005-09-11 02:03:03 +0000745 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000746 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000747 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
748 fprintf(p->out, "ANALYZE sqlite_master;\n");
749 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
750 return 0;
drh45e29d82006-11-20 16:21:10 +0000751 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
752 char *zIns;
753 if( !p->writableSchema ){
754 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
755 p->writableSchema = 1;
756 }
757 zIns = sqlite3_mprintf(
758 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
759 "VALUES('table','%q','%q',0,'%q');",
760 zTable, zTable, zSql);
761 fprintf(p->out, "%s\n", zIns);
762 sqlite3_free(zIns);
763 return 0;
drh00b950d2005-09-11 02:03:03 +0000764 }else{
765 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000766 }
danielk19772a02e332004-06-05 08:04:36 +0000767
768 if( strcmp(zType, "table")==0 ){
769 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000770 char *zSelect = 0;
771 char *zTableInfo = 0;
772 char *zTmp = 0;
773
774 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
775 zTableInfo = appendText(zTableInfo, zTable, '"');
776 zTableInfo = appendText(zTableInfo, ");", 0);
777
778 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
779 if( zTableInfo ) free(zTableInfo);
780 if( rc!=SQLITE_OK || !pTableInfo ){
781 return 1;
782 }
783
784 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
785 zTmp = appendText(zTmp, zTable, '"');
786 if( zTmp ){
787 zSelect = appendText(zSelect, zTmp, '\'');
788 }
789 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
790 rc = sqlite3_step(pTableInfo);
791 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000792 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000793 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000794 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000795 rc = sqlite3_step(pTableInfo);
796 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000797 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000798 }else{
799 zSelect = appendText(zSelect, ") ", 0);
800 }
801 }
802 rc = sqlite3_finalize(pTableInfo);
803 if( rc!=SQLITE_OK ){
804 if( zSelect ) free(zSelect);
805 return 1;
806 }
807 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
808 zSelect = appendText(zSelect, zTable, '"');
809
drhdd3d4592004-08-30 01:54:05 +0000810 rc = run_table_dump_query(p->out, p->db, zSelect);
811 if( rc==SQLITE_CORRUPT ){
812 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
813 rc = run_table_dump_query(p->out, p->db, zSelect);
814 }
danielk19772a02e332004-06-05 08:04:36 +0000815 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000816 }
drh4c653a02000-06-07 01:27:47 +0000817 return 0;
818}
819
820/*
drh45e29d82006-11-20 16:21:10 +0000821** Run zQuery. Use dump_callback() as the callback routine so that
822** the contents of the query are output as SQL statements.
823**
drhdd3d4592004-08-30 01:54:05 +0000824** If we get a SQLITE_CORRUPT error, rerun the query after appending
825** "ORDER BY rowid DESC" to the end.
826*/
827static int run_schema_dump_query(
828 struct callback_data *p,
829 const char *zQuery,
830 char **pzErrMsg
831){
832 int rc;
833 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
834 if( rc==SQLITE_CORRUPT ){
835 char *zQ2;
836 int len = strlen(zQuery);
837 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
838 zQ2 = malloc( len+100 );
839 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000840 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000841 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
842 free(zQ2);
843 }
844 return rc;
845}
846
847/*
drh75897232000-05-29 14:26:00 +0000848** Text of a help message
849*/
persicom1d0b8722002-04-18 02:53:04 +0000850static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000851 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000852 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000853 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000854 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000855 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000856 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000857 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000858 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000859 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000860 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000861#ifdef SQLITE_ENABLE_IOTRACE
862 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
863#endif
drh70df4fe2006-06-13 15:12:21 +0000864#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000865 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000866#endif
danielk19776b77a362005-01-13 11:10:25 +0000867 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000868 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000869 " column Left-aligned columns. (See .width)\n"
870 " html HTML <table> code\n"
871 " insert SQL insert statements for TABLE\n"
872 " line One value per line\n"
873 " list Values delimited by .separator string\n"
874 " tabs Tab-separated values\n"
875 " tcl TCL list elements\n"
876 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000877 ".output FILENAME Send output to FILENAME\n"
878 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000879 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000880 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000881 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000882 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000883 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000884 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000885 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000886 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh75897232000-05-29 14:26:00 +0000887 ".width NUM NUM ... Set column widths for \"column\" mode\n"
888;
889
drhdaffd0e2001-04-11 14:28:42 +0000890/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000891static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000892
drh75897232000-05-29 14:26:00 +0000893/*
drh44c2eb12003-04-30 11:38:26 +0000894** Make sure the database is open. If it is not, then open it. If
895** the database fails to open, print an error message and exit.
896*/
897static void open_db(struct callback_data *p){
898 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000899 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000900 db = p->db;
danielk1977bc6ada42004-06-30 08:20:16 +0000901 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
902 shellstaticFunc, 0, 0);
danielk197780290862004-05-22 09:21:21 +0000903 if( SQLITE_OK!=sqlite3_errcode(db) ){
904 fprintf(stderr,"Unable to open database \"%s\": %s\n",
905 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000906 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000907 }
drhc2e87a32006-06-27 15:16:14 +0000908#ifndef SQLITE_OMIT_LOAD_EXTENSION
909 sqlite3_enable_load_extension(p->db, 1);
910#endif
drh44c2eb12003-04-30 11:38:26 +0000911 }
912}
913
914/*
drhfeac5f82004-08-01 00:10:45 +0000915** Do C-language style dequoting.
916**
917** \t -> tab
918** \n -> newline
919** \r -> carriage return
920** \NNN -> ascii character NNN in octal
921** \\ -> backslash
922*/
923static void resolve_backslashes(char *z){
924 int i, j, c;
925 for(i=j=0; (c = z[i])!=0; i++, j++){
926 if( c=='\\' ){
927 c = z[++i];
928 if( c=='n' ){
929 c = '\n';
930 }else if( c=='t' ){
931 c = '\t';
932 }else if( c=='r' ){
933 c = '\r';
934 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +0000935 c -= '0';
drhfeac5f82004-08-01 00:10:45 +0000936 if( z[i+1]>='0' && z[i+1]<='7' ){
937 i++;
938 c = (c<<3) + z[i] - '0';
939 if( z[i+1]>='0' && z[i+1]<='7' ){
940 i++;
941 c = (c<<3) + z[i] - '0';
942 }
943 }
944 }
945 }
946 z[j] = c;
947 }
948 z[j] = 0;
949}
950
951/*
drhc28490c2006-10-26 14:25:58 +0000952** Interpret zArg as a boolean value. Return either 0 or 1.
953*/
954static int booleanValue(char *zArg){
955 int val = atoi(zArg);
956 int j;
957 for(j=0; zArg[j]; j++){
958 zArg[j] = tolower(zArg[j]);
959 }
960 if( strcmp(zArg,"on")==0 ){
961 val = 1;
962 }else if( strcmp(zArg,"yes")==0 ){
963 val = 1;
964 }
965 return val;
966}
967
968/*
drh75897232000-05-29 14:26:00 +0000969** If an input line begins with "." then invoke this routine to
970** process that line.
drh67505e72002-04-19 12:34:06 +0000971**
drh47ad6842006-11-08 12:25:42 +0000972** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +0000973*/
drh44c2eb12003-04-30 11:38:26 +0000974static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +0000975 int i = 1;
976 int nArg = 0;
977 int n, c;
drh67505e72002-04-19 12:34:06 +0000978 int rc = 0;
drh75897232000-05-29 14:26:00 +0000979 char *azArg[50];
980
981 /* Parse the input line into tokens.
982 */
983 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +0000984 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +0000985 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +0000986 if( zLine[i]=='\'' || zLine[i]=='"' ){
987 int delim = zLine[i++];
988 azArg[nArg++] = &zLine[i];
989 while( zLine[i] && zLine[i]!=delim ){ i++; }
990 if( zLine[i]==delim ){
991 zLine[i++] = 0;
992 }
drhfeac5f82004-08-01 00:10:45 +0000993 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +0000994 }else{
995 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +0000996 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +0000997 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +0000998 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +0000999 }
1000 }
1001
1002 /* Process the input line.
1003 */
drh67505e72002-04-19 12:34:06 +00001004 if( nArg==0 ) return rc;
drh75897232000-05-29 14:26:00 +00001005 n = strlen(azArg[0]);
1006 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001007 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1008 bail_on_error = booleanValue(azArg[1]);
1009 }else
1010
jplyon6a65bb32003-05-04 07:25:57 +00001011 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001012 struct callback_data data;
1013 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001014 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001015 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001016 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001017 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001018 data.colWidth[0] = 3;
1019 data.colWidth[1] = 15;
1020 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001021 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001022 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001023 if( zErrMsg ){
1024 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001025 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001026 }
1027 }else
1028
drh4c653a02000-06-07 01:27:47 +00001029 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1030 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001031 open_db(p);
drh33048c02001-10-01 14:29:22 +00001032 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001033 p->writableSchema = 0;
drh4c653a02000-06-07 01:27:47 +00001034 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001035 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001036 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001037 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001038 );
1039 run_table_dump_query(p->out, p->db,
1040 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001041 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001042 );
drh4c653a02000-06-07 01:27:47 +00001043 }else{
1044 int i;
drhdd3d4592004-08-30 01:54:05 +00001045 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001046 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001047 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001048 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001049 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001050 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001051 run_table_dump_query(p->out, p->db,
1052 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001053 "WHERE sql NOT NULL"
1054 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001055 " AND tbl_name LIKE shellstatic()"
1056 );
danielk1977bc6ada42004-06-30 08:20:16 +00001057 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001058 }
1059 }
drh45e29d82006-11-20 16:21:10 +00001060 if( p->writableSchema ){
1061 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1062 p->writableSchema = 0;
1063 }
drh4c653a02000-06-07 01:27:47 +00001064 if( zErrMsg ){
1065 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001066 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001067 }else{
1068 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001069 }
1070 }else
drh75897232000-05-29 14:26:00 +00001071
drhdaffd0e2001-04-11 14:28:42 +00001072 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001073 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001074 }else
1075
drh75897232000-05-29 14:26:00 +00001076 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001077 rc = 2;
drh75897232000-05-29 14:26:00 +00001078 }else
1079
drhdd45df82002-04-18 12:39:03 +00001080 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001081 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001082 if(val == 1) {
1083 if(!p->explainPrev.valid) {
1084 p->explainPrev.valid = 1;
1085 p->explainPrev.mode = p->mode;
1086 p->explainPrev.showHeader = p->showHeader;
1087 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1088 }
1089 /* We could put this code under the !p->explainValid
1090 ** condition so that it does not execute if we are already in
1091 ** explain mode. However, always executing it allows us an easy
1092 ** was to reset to explain mode in case the user previously
1093 ** did an .explain followed by a .width, .mode or .header
1094 ** command.
1095 */
1096 p->mode = MODE_Column;
1097 p->showHeader = 1;
1098 memset(p->colWidth,0,ArraySize(p->colWidth));
1099 p->colWidth[0] = 4;
drhe69cc5b2005-08-27 01:50:53 +00001100 p->colWidth[1] = 14;
persicom7e2dfdd2002-04-18 02:46:52 +00001101 p->colWidth[2] = 10;
1102 p->colWidth[3] = 10;
drhe69cc5b2005-08-27 01:50:53 +00001103 p->colWidth[4] = 33;
persicom7e2dfdd2002-04-18 02:46:52 +00001104 }else if (p->explainPrev.valid) {
1105 p->explainPrev.valid = 0;
1106 p->mode = p->explainPrev.mode;
1107 p->showHeader = p->explainPrev.showHeader;
1108 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1109 }
drh75897232000-05-29 14:26:00 +00001110 }else
1111
drhc28490c2006-10-26 14:25:58 +00001112 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001113 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001114 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001115 }else
1116
1117 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1118 fprintf(stderr,zHelp);
1119 }else
1120
drhfeac5f82004-08-01 00:10:45 +00001121 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1122 char *zTable = azArg[2]; /* Insert data into this table */
1123 char *zFile = azArg[1]; /* The file from which to extract data */
1124 sqlite3_stmt *pStmt; /* A statement */
1125 int rc; /* Result code */
1126 int nCol; /* Number of columns in the table */
1127 int nByte; /* Number of bytes in an SQL string */
1128 int i, j; /* Loop counters */
1129 int nSep; /* Number of bytes in p->separator[] */
1130 char *zSql; /* An SQL statement */
1131 char *zLine; /* A single line of input from the file */
1132 char **azCol; /* zLine[] broken up into columns */
1133 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001134 FILE *in; /* The input file */
1135 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001136
drha543c822006-06-08 16:10:14 +00001137 open_db(p);
drhfeac5f82004-08-01 00:10:45 +00001138 nSep = strlen(p->separator);
1139 if( nSep==0 ){
1140 fprintf(stderr, "non-null separator required for import\n");
1141 return 0;
1142 }
1143 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1144 if( zSql==0 ) return 0;
1145 nByte = strlen(zSql);
drh5e6078b2006-01-31 19:07:22 +00001146 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001147 sqlite3_free(zSql);
1148 if( rc ){
1149 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1150 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001151 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001152 }else{
1153 nCol = sqlite3_column_count(pStmt);
1154 }
1155 sqlite3_finalize(pStmt);
1156 if( nCol==0 ) return 0;
1157 zSql = malloc( nByte + 20 + nCol*2 );
1158 if( zSql==0 ) return 0;
1159 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
1160 j = strlen(zSql);
1161 for(i=1; i<nCol; i++){
1162 zSql[j++] = ',';
1163 zSql[j++] = '?';
1164 }
1165 zSql[j++] = ')';
1166 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001167 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001168 free(zSql);
1169 if( rc ){
1170 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1171 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001172 return 1;
drhfeac5f82004-08-01 00:10:45 +00001173 }
1174 in = fopen(zFile, "rb");
1175 if( in==0 ){
1176 fprintf(stderr, "cannot open file: %s\n", zFile);
1177 sqlite3_finalize(pStmt);
1178 return 0;
1179 }
1180 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001181 if( azCol==0 ){
1182 fclose(in);
1183 return 0;
1184 }
drhfeac5f82004-08-01 00:10:45 +00001185 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1186 zCommit = "COMMIT";
1187 while( (zLine = local_getline(0, in))!=0 ){
1188 char *z;
1189 i = 0;
drhb860bc92004-08-04 15:16:55 +00001190 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001191 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001192 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001193 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1194 *z = 0;
1195 i++;
drhb860bc92004-08-04 15:16:55 +00001196 if( i<nCol ){
1197 azCol[i] = &z[nSep];
1198 z += nSep-1;
1199 }
drhfeac5f82004-08-01 00:10:45 +00001200 }
1201 }
drh1cd7f832005-08-05 18:50:51 +00001202 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001203 if( i+1!=nCol ){
1204 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1205 zFile, lineno, nCol, i+1);
1206 zCommit = "ROLLBACK";
1207 break;
1208 }
drhfeac5f82004-08-01 00:10:45 +00001209 for(i=0; i<nCol; i++){
1210 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1211 }
1212 sqlite3_step(pStmt);
1213 rc = sqlite3_reset(pStmt);
1214 free(zLine);
1215 if( rc!=SQLITE_OK ){
1216 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1217 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001218 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001219 break;
1220 }
1221 }
1222 free(azCol);
1223 fclose(in);
1224 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001225 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001226 }else
1227
drh75897232000-05-29 14:26:00 +00001228 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1229 struct callback_data data;
1230 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001231 open_db(p);
drh75897232000-05-29 14:26:00 +00001232 memcpy(&data, p, sizeof(data));
1233 data.showHeader = 0;
1234 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001235 zShellStatic = azArg[1];
1236 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001237 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001238 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001239 "UNION ALL "
1240 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001241 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001242 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001243 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001244 );
danielk1977bc6ada42004-06-30 08:20:16 +00001245 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001246 if( zErrMsg ){
1247 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001248 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001249 }
1250 }else
1251
drhae5e4452007-05-03 17:18:36 +00001252#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001253 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
1254 extern void (*sqlite3_io_trace)(const char*, ...);
1255 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1256 iotrace = 0;
1257 if( nArg<2 ){
1258 sqlite3_io_trace = 0;
1259 }else if( strcmp(azArg[1], "-")==0 ){
1260 sqlite3_io_trace = iotracePrintf;
1261 iotrace = stdout;
1262 }else{
1263 iotrace = fopen(azArg[1], "w");
1264 if( iotrace==0 ){
1265 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
1266 sqlite3_io_trace = 0;
1267 }else{
1268 sqlite3_io_trace = iotracePrintf;
1269 }
1270 }
1271 }else
drhae5e4452007-05-03 17:18:36 +00001272#endif
drhb0603412007-02-28 04:47:26 +00001273
drh70df4fe2006-06-13 15:12:21 +00001274#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001275 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1276 const char *zFile, *zProc;
1277 char *zErrMsg = 0;
1278 int rc;
1279 zFile = azArg[1];
1280 zProc = nArg>=3 ? azArg[2] : 0;
1281 open_db(p);
1282 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1283 if( rc!=SQLITE_OK ){
1284 fprintf(stderr, "%s\n", zErrMsg);
1285 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001286 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001287 }
1288 }else
drh70df4fe2006-06-13 15:12:21 +00001289#endif
drh1e397f82006-06-08 15:28:43 +00001290
drh28bd4bc2000-06-15 15:57:22 +00001291 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh75897232000-05-29 14:26:00 +00001292 int n2 = strlen(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001293 if( strncmp(azArg[1],"line",n2)==0
1294 ||
1295 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001296 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001297 }else if( strncmp(azArg[1],"column",n2)==0
1298 ||
1299 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001300 p->mode = MODE_Column;
1301 }else if( strncmp(azArg[1],"list",n2)==0 ){
1302 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001303 }else if( strncmp(azArg[1],"html",n2)==0 ){
1304 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001305 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1306 p->mode = MODE_Tcl;
1307 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001308 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001309 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001310 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1311 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001312 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001313 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1314 p->mode = MODE_Insert;
1315 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001316 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001317 }else{
drh33048c02001-10-01 14:29:22 +00001318 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001319 }
drhdaffd0e2001-04-11 14:28:42 +00001320 }else {
drhcf68ae92006-12-19 18:47:41 +00001321 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001322 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001323 }
1324 }else
1325
persicom7e2dfdd2002-04-18 02:46:52 +00001326 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001327 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1328 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001329 }else
1330
drh75897232000-05-29 14:26:00 +00001331 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1332 if( p->out!=stdout ){
1333 fclose(p->out);
1334 }
1335 if( strcmp(azArg[1],"stdout")==0 ){
1336 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001337 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001338 }else{
drha1f9b5e2004-02-14 16:31:02 +00001339 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001340 if( p->out==0 ){
1341 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1342 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001343 } else {
drh5bb3eb92007-05-04 13:15:55 +00001344 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001345 }
1346 }
1347 }else
1348
drhdd45df82002-04-18 12:39:03 +00001349 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001350 if( nArg >= 2) {
1351 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1352 }
1353 if( nArg >= 3) {
1354 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1355 }
1356 }else
1357
1358 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001359 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001360 }else
1361
drhdaffd0e2001-04-11 14:28:42 +00001362 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001363 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001364 if( alt==0 ){
1365 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1366 }else{
1367 process_input(p, alt);
1368 fclose(alt);
1369 }
1370 }else
1371
drh75897232000-05-29 14:26:00 +00001372 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1373 struct callback_data data;
1374 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001375 open_db(p);
drh75897232000-05-29 14:26:00 +00001376 memcpy(&data, p, sizeof(data));
1377 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001378 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001379 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001380 int i;
1381 for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
1382 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001383 char *new_argv[2], *new_colv[2];
1384 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1385 " type text,\n"
1386 " name text,\n"
1387 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001388 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001389 " 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);
drhc8d74412004-08-31 23:41:26 +00001395 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001396 char *new_argv[2], *new_colv[2];
1397 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1398 " type text,\n"
1399 " name text,\n"
1400 " tbl_name text,\n"
1401 " rootpage integer,\n"
1402 " sql text\n"
1403 ")";
1404 new_argv[1] = 0;
1405 new_colv[0] = "sql";
1406 new_colv[1] = 0;
1407 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001408 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001409 zShellStatic = azArg[1];
1410 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001411 "SELECT sql FROM "
1412 " (SELECT * FROM sqlite_master UNION ALL"
1413 " SELECT * FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001414 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001415 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001416 callback, &data, &zErrMsg);
1417 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001418 }
drh75897232000-05-29 14:26:00 +00001419 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001420 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001421 "SELECT sql FROM "
1422 " (SELECT * FROM sqlite_master UNION ALL"
1423 " SELECT * FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001424 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001425 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001426 callback, &data, &zErrMsg
1427 );
drh75897232000-05-29 14:26:00 +00001428 }
drh75897232000-05-29 14:26:00 +00001429 if( zErrMsg ){
1430 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001431 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001432 }
1433 }else
1434
1435 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001436 sqlite3_snprintf(sizeof(p->separator), p->separator,
1437 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001438 }else
1439
persicom7e2dfdd2002-04-18 02:46:52 +00001440 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1441 int i;
1442 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001443 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001444 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001445 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001446 fprintf(p->out,"%9.9s: ", "nullvalue");
1447 output_c_string(p->out, p->nullvalue);
1448 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001449 fprintf(p->out,"%9.9s: %s\n","output",
1450 strlen(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001451 fprintf(p->out,"%9.9s: ", "separator");
1452 output_c_string(p->out, p->separator);
1453 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001454 fprintf(p->out,"%9.9s: ","width");
1455 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001456 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001457 }
drhfeac5f82004-08-01 00:10:45 +00001458 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001459 }else
1460
drh2dfbbca2000-07-28 14:32:48 +00001461 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001462 char **azResult;
1463 int nRow, rc;
1464 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001465 open_db(p);
drha50da102000-08-08 20:19:09 +00001466 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001467 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001468 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001469 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001470 "UNION ALL "
1471 "SELECT name FROM sqlite_temp_master "
1472 "WHERE type IN ('table','view') "
1473 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001474 &azResult, &nRow, 0, &zErrMsg
1475 );
drha50da102000-08-08 20:19:09 +00001476 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001477 zShellStatic = azArg[1];
1478 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001479 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001480 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001481 "UNION ALL "
1482 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001483 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001484 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001485 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001486 );
danielk1977bc6ada42004-06-30 08:20:16 +00001487 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001488 }
drh75897232000-05-29 14:26:00 +00001489 if( zErrMsg ){
1490 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001491 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001492 }
drhe3710332000-09-29 13:30:53 +00001493 if( rc==SQLITE_OK ){
1494 int len, maxlen = 0;
1495 int i, j;
1496 int nPrintCol, nPrintRow;
1497 for(i=1; i<=nRow; i++){
1498 if( azResult[i]==0 ) continue;
1499 len = strlen(azResult[i]);
1500 if( len>maxlen ) maxlen = len;
1501 }
1502 nPrintCol = 80/(maxlen+2);
1503 if( nPrintCol<1 ) nPrintCol = 1;
1504 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1505 for(i=0; i<nPrintRow; i++){
1506 for(j=i+1; j<=nRow; j+=nPrintRow){
1507 char *zSp = j<=nPrintRow ? "" : " ";
1508 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1509 }
1510 printf("\n");
1511 }
drh47ad6842006-11-08 12:25:42 +00001512 }else{
1513 rc = 1;
drhe3710332000-09-29 13:30:53 +00001514 }
danielk19776f8a5032004-05-10 10:34:51 +00001515 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001516 }else
1517
drh2dfbbca2000-07-28 14:32:48 +00001518 if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001519 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001520 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001521 }else
1522
drh75897232000-05-29 14:26:00 +00001523 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1524 int j;
drh43617e92006-03-06 20:55:46 +00001525 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001526 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1527 p->colWidth[j-1] = atoi(azArg[j]);
1528 }
1529 }else
1530
1531 {
drh67505e72002-04-19 12:34:06 +00001532 fprintf(stderr, "unknown command or invalid arguments: "
1533 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001534 }
drh67505e72002-04-19 12:34:06 +00001535
1536 return rc;
drh75897232000-05-29 14:26:00 +00001537}
1538
drh67505e72002-04-19 12:34:06 +00001539/*
drh324ccef2003-02-05 14:06:20 +00001540** Return TRUE if the last non-whitespace character in z[] is a semicolon.
1541** z[] is N characters long.
1542*/
1543static int _ends_with_semicolon(const char *z, int N){
drh4c755c02004-08-08 20:22:17 +00001544 while( N>0 && isspace((unsigned char)z[N-1]) ){ N--; }
drh324ccef2003-02-05 14:06:20 +00001545 return N>0 && z[N-1]==';';
1546}
1547
1548/*
drh70c7a4b2003-04-26 03:03:06 +00001549** Test to see if a line consists entirely of whitespace.
1550*/
1551static int _all_whitespace(const char *z){
1552 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001553 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001554 if( *z=='/' && z[1]=='*' ){
1555 z += 2;
1556 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1557 if( *z==0 ) return 0;
1558 z++;
1559 continue;
1560 }
1561 if( *z=='-' && z[1]=='-' ){
1562 z += 2;
1563 while( *z && *z!='\n' ){ z++; }
1564 if( *z==0 ) return 1;
1565 continue;
1566 }
1567 return 0;
1568 }
1569 return 1;
1570}
1571
1572/*
drha9b17162003-04-29 18:01:28 +00001573** Return TRUE if the line typed in is an SQL command terminator other
1574** than a semi-colon. The SQL Server style "go" command is understood
1575** as is the Oracle "/".
1576*/
1577static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001578 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drha9b17162003-04-29 18:01:28 +00001579 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
drhc8d74412004-08-31 23:41:26 +00001580 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1581 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001582 return 1; /* SQL Server */
1583 }
1584 return 0;
1585}
1586
1587/*
drh67505e72002-04-19 12:34:06 +00001588** Read input from *in and process it. If *in==0 then input
1589** is interactive - the user is typing it it. Otherwise, input
1590** is coming from a file or device. A prompt is issued and history
1591** is saved only if input is interactive. An interrupt signal will
1592** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001593**
1594** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001595*/
drhc28490c2006-10-26 14:25:58 +00001596static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001597 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001598 char *zSql = 0;
1599 int nSql = 0;
1600 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001601 int rc;
1602 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001603 int lineno = 0;
1604 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001605
1606 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1607 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001608 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001609 zLine = one_input_line(zSql, in);
1610 if( zLine==0 ){
1611 break; /* We have reached EOF */
1612 }
drh67505e72002-04-19 12:34:06 +00001613 if( seenInterrupt ){
1614 if( in!=0 ) break;
1615 seenInterrupt = 0;
1616 }
drhc28490c2006-10-26 14:25:58 +00001617 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001618 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001619 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001620 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001621 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001622 if( rc==2 ){
1623 break;
1624 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001625 errCnt++;
1626 }
drhdaffd0e2001-04-11 14:28:42 +00001627 continue;
1628 }
drha9b17162003-04-29 18:01:28 +00001629 if( _is_command_terminator(zLine) ){
drh5bb3eb92007-05-04 13:15:55 +00001630 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001631 }
drhdaffd0e2001-04-11 14:28:42 +00001632 if( zSql==0 ){
1633 int i;
drh4c755c02004-08-08 20:22:17 +00001634 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001635 if( zLine[i]!=0 ){
1636 nSql = strlen(zLine);
1637 zSql = malloc( nSql+1 );
drhc1f44942006-05-10 14:39:13 +00001638 if( zSql==0 ){
1639 fprintf(stderr, "out of memory\n");
1640 exit(1);
1641 }
drh5bb3eb92007-05-04 13:15:55 +00001642 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001643 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001644 }
1645 }else{
1646 int len = strlen(zLine);
1647 zSql = realloc( zSql, nSql + len + 2 );
1648 if( zSql==0 ){
1649 fprintf(stderr,"%s: out of memory!\n", Argv0);
1650 exit(1);
1651 }
drh5bb3eb92007-05-04 13:15:55 +00001652 zSql[nSql++] = '\n';
1653 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001654 nSql += len;
1655 }
danielk19776f8a5032004-05-10 10:34:51 +00001656 if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001657 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001658 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001659 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001660 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001661 char zPrefix[100];
1662 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001663 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1664 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001665 }else{
drh5bb3eb92007-05-04 13:15:55 +00001666 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001667 }
drh7f953e22002-07-13 17:33:45 +00001668 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001669 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001670 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001671 zErrMsg = 0;
1672 }else{
drhc28490c2006-10-26 14:25:58 +00001673 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001674 }
drhc49f44e2006-10-26 18:15:42 +00001675 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001676 }
1677 free(zSql);
1678 zSql = 0;
1679 nSql = 0;
1680 }
1681 }
1682 if( zSql ){
drh70c7a4b2003-04-26 03:03:06 +00001683 if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001684 free(zSql);
1685 }
danielk19772ac27622007-07-03 05:31:16 +00001686 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001687 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001688}
1689
drh67505e72002-04-19 12:34:06 +00001690/*
1691** Return a pathname which is the user's home directory. A
1692** 0 return indicates an error of some kind. Space to hold the
1693** resulting string is obtained from malloc(). The calling
1694** function should free the result.
1695*/
1696static char *find_home_dir(void){
1697 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001698
drhcdb36b72006-06-12 12:57:45 +00001699#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) && !defined(__OS2__)
drh67505e72002-04-19 12:34:06 +00001700 struct passwd *pwent;
1701 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001702 if( (pwent=getpwuid(uid)) != NULL) {
1703 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001704 }
1705#endif
1706
drh820f3812003-01-08 13:02:52 +00001707#ifdef __MACOS__
1708 char home_path[_MAX_PATH+1];
1709 home_dir = getcwd(home_path, _MAX_PATH);
1710#endif
1711
drh164a1b62006-08-19 11:15:20 +00001712#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1713 if (!home_dir) {
1714 home_dir = getenv("USERPROFILE");
1715 }
1716#endif
1717
drh67505e72002-04-19 12:34:06 +00001718 if (!home_dir) {
1719 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001720 }
1721
drhcdb36b72006-06-12 12:57:45 +00001722#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001723 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001724 char *zDrive, *zPath;
1725 int n;
1726 zDrive = getenv("HOMEDRIVE");
1727 zPath = getenv("HOMEPATH");
1728 if( zDrive && zPath ){
1729 n = strlen(zDrive) + strlen(zPath) + 1;
1730 home_dir = malloc( n );
1731 if( home_dir==0 ) return 0;
1732 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1733 return home_dir;
1734 }
1735 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001736 }
1737#endif
1738
drh67505e72002-04-19 12:34:06 +00001739 if( home_dir ){
drh5bb3eb92007-05-04 13:15:55 +00001740 int n = strlen(home_dir) + 1;
1741 char *z = malloc( n );
1742 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001743 home_dir = z;
1744 }
drhe98d4fa2002-04-21 19:06:22 +00001745
drh67505e72002-04-19 12:34:06 +00001746 return home_dir;
1747}
1748
1749/*
1750** Read input from the file given by sqliterc_override. Or if that
1751** parameter is NULL, take input from ~/.sqliterc
1752*/
drh22fbcb82004-02-01 01:22:50 +00001753static void process_sqliterc(
1754 struct callback_data *p, /* Configuration data */
1755 const char *sqliterc_override /* Name of config file. NULL to use default */
1756){
persicom7e2dfdd2002-04-18 02:46:52 +00001757 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001758 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001759 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001760 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001761 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001762
1763 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001764 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001765 if( home_dir==0 ){
1766 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
1767 return;
1768 }
drha959ac42007-06-20 13:10:00 +00001769 nBuf = strlen(home_dir) + 16;
1770 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001771 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001772 fprintf(stderr,"%s: out of memory!\n", Argv0);
1773 exit(1);
1774 }
drha959ac42007-06-20 13:10:00 +00001775 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001776 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001777 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001778 }
drha1f9b5e2004-02-14 16:31:02 +00001779 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001780 if( in ){
drhc28490c2006-10-26 14:25:58 +00001781 if( stdin_is_interactive ){
drh22fbcb82004-02-01 01:22:50 +00001782 printf("Loading resources from %s\n",sqliterc);
1783 }
persicom7e2dfdd2002-04-18 02:46:52 +00001784 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001785 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001786 }
drh43617e92006-03-06 20:55:46 +00001787 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001788 return;
1789}
1790
drh67505e72002-04-19 12:34:06 +00001791/*
drhe1e38c42003-05-04 18:30:59 +00001792** Show available command line options
1793*/
1794static const char zOptions[] =
1795 " -init filename read/process named file\n"
1796 " -echo print commands before execution\n"
1797 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001798 " -bail stop after hitting an error\n"
1799 " -interactive force interactive I/O\n"
1800 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001801 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001802 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001803 " -html set output mode to HTML\n"
1804 " -line set output mode to 'line'\n"
1805 " -list set output mode to 'list'\n"
1806 " -separator 'x' set output field separator (|)\n"
1807 " -nullvalue 'text' set text string for NULL values\n"
1808 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001809;
1810static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001811 fprintf(stderr,
1812 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1813 "FILENAME is the name of an SQLite database. A new database is created\n"
1814 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001815 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001816 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001817 }else{
1818 fprintf(stderr, "Use the -help option for additional information\n");
1819 }
1820 exit(1);
1821}
1822
1823/*
drh67505e72002-04-19 12:34:06 +00001824** Initialize the state information in data
1825*/
drh0850b532006-01-31 19:31:43 +00001826static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001827 memset(data, 0, sizeof(*data));
1828 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001829 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001830 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001831 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1832 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001833}
1834
drh75897232000-05-29 14:26:00 +00001835int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001836 char *zErrMsg = 0;
1837 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001838 const char *zInitFile = 0;
1839 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001840 int i;
drhc28490c2006-10-26 14:25:58 +00001841 int rc = 0;
drh75897232000-05-29 14:26:00 +00001842
drh820f3812003-01-08 13:02:52 +00001843#ifdef __MACOS__
1844 argc = ccommand(&argv);
drh820f3812003-01-08 13:02:52 +00001845#endif
1846
drhdaffd0e2001-04-11 14:28:42 +00001847 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001848 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001849 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001850
drh44c2eb12003-04-30 11:38:26 +00001851 /* Make sure we have a valid signal handler early, before anything
1852 ** else is done.
1853 */
drh4c504392000-10-16 22:06:40 +00001854#ifdef SIGINT
1855 signal(SIGINT, interrupt_handler);
1856#endif
drh44c2eb12003-04-30 11:38:26 +00001857
drh22fbcb82004-02-01 01:22:50 +00001858 /* Do an initial pass through the command-line argument to locate
1859 ** the name of the database file, the name of the initialization file,
1860 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001861 */
drh22fbcb82004-02-01 01:22:50 +00001862 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001863 char *z;
drh44c2eb12003-04-30 11:38:26 +00001864 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001865 z = argv[i];
1866 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001867 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1868 i++;
drh22fbcb82004-02-01 01:22:50 +00001869 }else if( strcmp(argv[i],"-init")==0 ){
1870 i++;
1871 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001872 }
1873 }
drh22fbcb82004-02-01 01:22:50 +00001874 if( i<argc ){
1875 data.zDbFilename = argv[i++];
1876 }else{
danielk197703aded42004-11-22 05:26:27 +00001877#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00001878 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00001879#else
1880 data.zDbFilename = 0;
1881#endif
drh22fbcb82004-02-01 01:22:50 +00001882 }
1883 if( i<argc ){
1884 zFirstCmd = argv[i++];
1885 }
drh44c2eb12003-04-30 11:38:26 +00001886 data.out = stdout;
1887
drh01b41712005-08-29 23:06:23 +00001888#ifdef SQLITE_OMIT_MEMORYDB
1889 if( data.zDbFilename==0 ){
1890 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
1891 exit(1);
1892 }
1893#endif
1894
drh44c2eb12003-04-30 11:38:26 +00001895 /* Go ahead and open the database file if it already exists. If the
1896 ** file does not exist, delay opening it. This prevents empty database
1897 ** files from being created if a user mistypes the database name argument
1898 ** to the sqlite command-line tool.
1899 */
drhc8d74412004-08-31 23:41:26 +00001900 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00001901 open_db(&data);
1902 }
1903
drh22fbcb82004-02-01 01:22:50 +00001904 /* Process the initialization file if there is one. If no -init option
1905 ** is given on the command line, look for a file named ~/.sqliterc and
1906 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00001907 */
drh22fbcb82004-02-01 01:22:50 +00001908 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00001909
drh22fbcb82004-02-01 01:22:50 +00001910 /* Make a second pass through the command-line argument and set
1911 ** options. This second pass is delayed until after the initialization
1912 ** file is processed so that the command-line arguments will override
1913 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00001914 */
drh22fbcb82004-02-01 01:22:50 +00001915 for(i=1; i<argc && argv[i][0]=='-'; i++){
1916 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00001917 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00001918 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00001919 i++;
1920 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001921 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00001922 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001923 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00001924 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001925 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00001926 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00001927 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00001928 }else if( strcmp(z,"-csv")==0 ){
1929 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001930 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00001931 }else if( strcmp(z,"-separator")==0 ){
1932 i++;
drh5bb3eb92007-05-04 13:15:55 +00001933 sqlite3_snprintf(sizeof(data.separator), data.separator,
1934 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00001935 }else if( strcmp(z,"-nullvalue")==0 ){
1936 i++;
drh5bb3eb92007-05-04 13:15:55 +00001937 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
1938 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00001939 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001940 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00001941 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00001942 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00001943 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00001944 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00001945 }else if( strcmp(z,"-bail")==0 ){
1946 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00001947 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00001948 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00001949 return 0;
drhc28490c2006-10-26 14:25:58 +00001950 }else if( strcmp(z,"-interactive")==0 ){
1951 stdin_is_interactive = 1;
1952 }else if( strcmp(z,"-batch")==0 ){
1953 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00001954 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00001955 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00001956 }else{
drh22fbcb82004-02-01 01:22:50 +00001957 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00001958 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00001959 return 1;
1960 }
1961 }
drh44c2eb12003-04-30 11:38:26 +00001962
drh22fbcb82004-02-01 01:22:50 +00001963 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00001964 /* Run just the command that follows the database name
1965 */
drh22fbcb82004-02-01 01:22:50 +00001966 if( zFirstCmd[0]=='.' ){
1967 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00001968 exit(0);
1969 }else{
1970 int rc;
drh44c2eb12003-04-30 11:38:26 +00001971 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00001972 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00001973 if( rc!=0 && zErrMsg!=0 ){
1974 fprintf(stderr,"SQL error: %s\n", zErrMsg);
1975 exit(1);
1976 }
drh75897232000-05-29 14:26:00 +00001977 }
1978 }else{
drh44c2eb12003-04-30 11:38:26 +00001979 /* Run commands received from standard input
1980 */
drhc28490c2006-10-26 14:25:58 +00001981 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00001982 char *zHome;
1983 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00001984 int nHistory;
drh75897232000-05-29 14:26:00 +00001985 printf(
drhb217a572000-08-22 13:40:18 +00001986 "SQLite version %s\n"
1987 "Enter \".help\" for instructions\n",
drhc8d74412004-08-31 23:41:26 +00001988 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00001989 );
drh67505e72002-04-19 12:34:06 +00001990 zHome = find_home_dir();
drh5bb3eb92007-05-04 13:15:55 +00001991 if( zHome && (zHistory = malloc(nHistory = strlen(zHome)+20))!=0 ){
1992 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
drh67505e72002-04-19 12:34:06 +00001993 }
danielk19774af00c62005-01-23 23:43:21 +00001994#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00001995 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00001996#endif
drhc28490c2006-10-26 14:25:58 +00001997 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00001998 if( zHistory ){
1999 stifle_history(100);
2000 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002001 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002002 }
adamd0a3daa32006-07-28 20:16:14 +00002003 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002004 }else{
drhc28490c2006-10-26 14:25:58 +00002005 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002006 }
2007 }
drh33048c02001-10-01 14:29:22 +00002008 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002009 if( db ){
2010 if( sqlite3_close(db)!=SQLITE_OK ){
2011 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2012 }
2013 }
drhc28490c2006-10-26 14:25:58 +00002014 return rc;
drh75897232000-05-29 14:26:00 +00002015}