blob: b1f0f6cab3480ebd7d88e2096f867d28493bff25 [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**
drh9ff849f2009-02-04 20:55:57 +000015** $Id: shell.c,v 1.200 2009/02/04 20:55:58 drh Exp $
drh75897232000-05-29 14:26:00 +000016*/
shane18e526c2008-12-10 22:30:24 +000017#if defined(_WIN32) || defined(WIN32)
18/* This needs to come before any includes for MSVC compiler */
19#define _CRT_SECURE_NO_WARNINGS
20#endif
21
drh75897232000-05-29 14:26:00 +000022#include <stdlib.h>
23#include <string.h>
24#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000025#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000026#include "sqlite3.h"
drh75897232000-05-29 14:26:00 +000027#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000028#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000029
drh454ad582007-11-26 22:54:27 +000030#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__)
drh4c504392000-10-16 22:06:40 +000031# include <signal.h>
chw97185482008-11-17 08:05:31 +000032# if !defined(__RTP__) && !defined(_WRS_KERNEL)
33# include <pwd.h>
34# endif
drhdd45df82002-04-18 12:39:03 +000035# include <unistd.h>
36# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000037#endif
drh75897232000-05-29 14:26:00 +000038
drhcdb36b72006-06-12 12:57:45 +000039#ifdef __OS2__
40# include <unistd.h>
41#endif
42
drh16e59552000-07-31 11:57:37 +000043#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh8e7e7a22000-05-30 18:45:23 +000044# include <readline/readline.h>
45# include <readline/history.h>
46#else
drh9347b202003-07-18 01:30:59 +000047# define readline(p) local_getline(p,stdin)
persicom1d0b8722002-04-18 02:53:04 +000048# define add_history(X)
drh67505e72002-04-19 12:34:06 +000049# define read_history(X)
50# define write_history(X)
51# define stifle_history(X)
drh75897232000-05-29 14:26:00 +000052#endif
53
adamd2e8464a2006-09-06 21:39:40 +000054#if defined(_WIN32) || defined(WIN32)
55# include <io.h>
shane18e526c2008-12-10 22:30:24 +000056#define isatty(h) _isatty(h)
57#define access(f,m) _access((f),(m))
adamd2e8464a2006-09-06 21:39:40 +000058#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
chw65d3c132007-11-12 21:09:10 +000064#if defined(_WIN32_WCE)
65/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
66 * thus we always assume that we have a console. That can be
67 * overridden with the -batch command line option.
68 */
69#define isatty(x) 1
70#endif
71
chw97185482008-11-17 08:05:31 +000072#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh3b1a9882007-11-02 12:53:03 +000073#include <sys/time.h>
74#include <sys/resource.h>
75
76/* Saved resource information for the beginning of an operation */
77static struct rusage sBegin;
78
79/* True if the timer is enabled */
80static int enableTimer = 0;
81
82/*
83** Begin timing an operation
84*/
85static void beginTimer(void){
86 if( enableTimer ){
87 getrusage(RUSAGE_SELF, &sBegin);
88 }
89}
90
drhf4608092008-07-11 17:23:24 +000091/* Return the difference of two time_structs in seconds */
92static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
93 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
94 (double)(pEnd->tv_sec - pStart->tv_sec);
drh3b1a9882007-11-02 12:53:03 +000095}
96
97/*
98** Print the timing results.
99*/
100static void endTimer(void){
101 if( enableTimer ){
102 struct rusage sEnd;
103 getrusage(RUSAGE_SELF, &sEnd);
104 printf("CPU Time: user %f sys %f\n",
drhf4608092008-07-11 17:23:24 +0000105 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
106 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
drh3b1a9882007-11-02 12:53:03 +0000107 }
108}
109#define BEGIN_TIMER beginTimer()
110#define END_TIMER endTimer()
111#define HAS_TIMER 1
112#else
113#define BEGIN_TIMER
114#define END_TIMER
115#define HAS_TIMER 0
116#endif
117
drhe91d16b2008-12-08 18:27:31 +0000118/*
119** Used to prevent warnings about unused parameters
120*/
121#define UNUSED_PARAMETER(x) (void)(x)
drh3b1a9882007-11-02 12:53:03 +0000122
drh75897232000-05-29 14:26:00 +0000123/*
drhc49f44e2006-10-26 18:15:42 +0000124** If the following flag is set, then command execution stops
125** at an error if we are not interactive.
126*/
127static int bail_on_error = 0;
128
129/*
drhc28490c2006-10-26 14:25:58 +0000130** Threat stdin as an interactive input if the following variable
131** is true. Otherwise, assume stdin is connected to a file or pipe.
132*/
133static int stdin_is_interactive = 1;
134
135/*
drh4c504392000-10-16 22:06:40 +0000136** The following is the open SQLite database. We make a pointer
137** to this database a static variable so that it can be accessed
138** by the SIGINT handler to interrupt database processing.
139*/
danielk197792f9a1b2004-06-19 09:08:16 +0000140static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000141
142/*
drh67505e72002-04-19 12:34:06 +0000143** True if an interrupt (Control-C) has been received.
144*/
drh43617e92006-03-06 20:55:46 +0000145static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000146
147/*
persicom7e2dfdd2002-04-18 02:46:52 +0000148** This is the name of our program. It is set in main(), used
149** in a number of other places, mostly for error messages.
150*/
151static char *Argv0;
152
153/*
154** Prompt strings. Initialized in main. Settable with
155** .prompt main continue
156*/
157static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
158static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
159
drhb0603412007-02-28 04:47:26 +0000160/*
161** Write I/O traces to the following stream.
162*/
rsebe0a9092007-07-30 18:24:38 +0000163#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000164static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000165#endif
drhb0603412007-02-28 04:47:26 +0000166
167/*
168** This routine works like printf in that its first argument is a
169** format string and subsequent arguments are values to be substituted
170** in place of % fields. The result of formatting this string
171** is written to iotrace.
172*/
rsebe0a9092007-07-30 18:24:38 +0000173#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000174static void iotracePrintf(const char *zFormat, ...){
175 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000176 char *z;
drhb0603412007-02-28 04:47:26 +0000177 if( iotrace==0 ) return;
178 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000179 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000180 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000181 fprintf(iotrace, "%s", z);
182 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000183}
rsebe0a9092007-07-30 18:24:38 +0000184#endif
drhb0603412007-02-28 04:47:26 +0000185
drh44c2eb12003-04-30 11:38:26 +0000186
persicom7e2dfdd2002-04-18 02:46:52 +0000187/*
drh83965662003-04-17 02:54:13 +0000188** Determines if a string is a number of not.
189*/
danielk19772e588c72005-12-09 14:25:08 +0000190static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000191 if( *z=='-' || *z=='+' ) z++;
192 if( !isdigit(*z) ){
193 return 0;
194 }
195 z++;
196 if( realnum ) *realnum = 0;
197 while( isdigit(*z) ){ z++; }
198 if( *z=='.' ){
199 z++;
200 if( !isdigit(*z) ) return 0;
201 while( isdigit(*z) ){ z++; }
202 if( realnum ) *realnum = 1;
203 }
204 if( *z=='e' || *z=='E' ){
205 z++;
206 if( *z=='+' || *z=='-' ) z++;
207 if( !isdigit(*z) ) return 0;
208 while( isdigit(*z) ){ z++; }
209 if( realnum ) *realnum = 1;
210 }
211 return *z==0;
212}
drh83965662003-04-17 02:54:13 +0000213
214/*
danielk1977bc6ada42004-06-30 08:20:16 +0000215** A global char* and an SQL function to access its current value
216** from within an SQL statement. This program used to use the
217** sqlite_exec_printf() API to substitue a string into an SQL statement.
218** The correct way to do this with sqlite3 is to use the bind API, but
219** since the shell is built around the callback paradigm it would be a lot
220** of work. Instead just use this hack, which is quite harmless.
221*/
222static const char *zShellStatic = 0;
223static void shellstaticFunc(
224 sqlite3_context *context,
225 int argc,
226 sqlite3_value **argv
227){
228 assert( 0==argc );
229 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000230 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000231 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000232 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
233}
234
235
236/*
drhfeac5f82004-08-01 00:10:45 +0000237** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000238** the text in memory obtained from malloc() and returns a pointer
239** to the text. NULL is returned at end of file, or if malloc()
240** fails.
241**
242** The interface is like "readline" but no command-line editing
243** is done.
244*/
drh9347b202003-07-18 01:30:59 +0000245static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000246 char *zLine;
247 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000248 int n;
249 int eol;
250
251 if( zPrompt && *zPrompt ){
252 printf("%s",zPrompt);
253 fflush(stdout);
254 }
255 nLine = 100;
256 zLine = malloc( nLine );
257 if( zLine==0 ) return 0;
258 n = 0;
259 eol = 0;
260 while( !eol ){
261 if( n+100>nLine ){
262 nLine = nLine*2 + 100;
263 zLine = realloc(zLine, nLine);
264 if( zLine==0 ) return 0;
265 }
drhdaffd0e2001-04-11 14:28:42 +0000266 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000267 if( n==0 ){
268 free(zLine);
269 return 0;
270 }
271 zLine[n] = 0;
272 eol = 1;
273 break;
274 }
275 while( zLine[n] ){ n++; }
276 if( n>0 && zLine[n-1]=='\n' ){
277 n--;
278 zLine[n] = 0;
279 eol = 1;
280 }
281 }
282 zLine = realloc( zLine, n+1 );
283 return zLine;
284}
285
286/*
drhc28490c2006-10-26 14:25:58 +0000287** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000288**
289** zPrior is a string of prior text retrieved. If not the empty
290** string, then issue a continuation prompt.
291*/
drhdaffd0e2001-04-11 14:28:42 +0000292static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000293 char *zPrompt;
294 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000295 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000296 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000297 }
298 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000299 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000300 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000301 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000302 }
303 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000304#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000305 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000306#endif
drh8e7e7a22000-05-30 18:45:23 +0000307 return zResult;
308}
309
persicom7e2dfdd2002-04-18 02:46:52 +0000310struct previous_mode_data {
311 int valid; /* Is there legit data in here? */
312 int mode;
313 int showHeader;
314 int colWidth[100];
315};
drh45e29d82006-11-20 16:21:10 +0000316
drh8e7e7a22000-05-30 18:45:23 +0000317/*
drh75897232000-05-29 14:26:00 +0000318** An pointer to an instance of this structure is passed from
319** the main program to the callback. This is used to communicate
320** state and mode information.
321*/
322struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000323 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000324 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000325 int cnt; /* Number of records displayed so far */
326 FILE *out; /* Write results here */
327 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000328 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000329 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000330 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000331 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000332 int colWidth[100]; /* Requested width of each column when in column mode*/
333 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000334 char nullvalue[20]; /* The text to print when a NULL comes back from
335 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000336 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000337 /* Holds the mode information just before
338 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000339 char outfile[FILENAME_MAX]; /* Filename for *out */
340 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000341};
342
343/*
344** These are the allowed modes.
345*/
drh967e8b72000-06-21 13:59:10 +0000346#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000347#define MODE_Column 1 /* One record per line in neat columns */
348#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000349#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
350#define MODE_Html 4 /* Generate an XHTML table */
351#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000352#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000353#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000354#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000355
drh66ce4d02008-02-15 17:38:06 +0000356static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000357 "line",
358 "column",
359 "list",
360 "semi",
361 "html",
drhfeac5f82004-08-01 00:10:45 +0000362 "insert",
363 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000364 "csv",
drh66ce4d02008-02-15 17:38:06 +0000365 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000366};
drh75897232000-05-29 14:26:00 +0000367
368/*
369** Number of elements in an array
370*/
drh902b9ee2008-12-05 17:17:07 +0000371#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000372
373/*
drhea678832008-12-10 19:26:22 +0000374** Compute a string length that is limited to what can be stored in
375** lower 30 bits of a 32-bit signed integer.
376*/
drh4f21c4a2008-12-10 22:15:00 +0000377static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000378 const char *z2 = z;
379 while( *z2 ){ z2++; }
380 return 0x3fffffff & (int)(z2 - z);
381}
382
383/*
drh28bd4bc2000-06-15 15:57:22 +0000384** Output the given string as a quoted string using SQL quoting conventions.
385*/
386static void output_quoted_string(FILE *out, const char *z){
387 int i;
388 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000389 for(i=0; z[i]; i++){
390 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000391 }
392 if( nSingle==0 ){
393 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000394 }else{
395 fprintf(out,"'");
396 while( *z ){
397 for(i=0; z[i] && z[i]!='\''; i++){}
398 if( i==0 ){
399 fprintf(out,"''");
400 z++;
401 }else if( z[i]=='\'' ){
402 fprintf(out,"%.*s''",i,z);
403 z += i+1;
404 }else{
drhcd7d2732002-02-26 23:24:26 +0000405 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000406 break;
407 }
408 }
drhcd7d2732002-02-26 23:24:26 +0000409 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000410 }
411}
412
413/*
drhfeac5f82004-08-01 00:10:45 +0000414** Output the given string as a quoted according to C or TCL quoting rules.
415*/
416static void output_c_string(FILE *out, const char *z){
417 unsigned int c;
418 fputc('"', out);
419 while( (c = *(z++))!=0 ){
420 if( c=='\\' ){
421 fputc(c, out);
422 fputc(c, out);
423 }else if( c=='\t' ){
424 fputc('\\', out);
425 fputc('t', out);
426 }else if( c=='\n' ){
427 fputc('\\', out);
428 fputc('n', out);
429 }else if( c=='\r' ){
430 fputc('\\', out);
431 fputc('r', out);
432 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000433 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000434 }else{
435 fputc(c, out);
436 }
437 }
438 fputc('"', out);
439}
440
441/*
drhc08a4f12000-06-15 16:49:48 +0000442** Output the given string with characters that are special to
443** HTML escaped.
444*/
445static void output_html_string(FILE *out, const char *z){
446 int i;
447 while( *z ){
448 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
449 if( i>0 ){
450 fprintf(out,"%.*s",i,z);
451 }
452 if( z[i]=='<' ){
453 fprintf(out,"&lt;");
454 }else if( z[i]=='&' ){
455 fprintf(out,"&amp;");
456 }else{
457 break;
458 }
459 z += i + 1;
460 }
461}
462
463/*
drhc49f44e2006-10-26 18:15:42 +0000464** If a field contains any character identified by a 1 in the following
465** array, then the string must be quoted for CSV.
466*/
467static const char needCsvQuote[] = {
468 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
469 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
470 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
471 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
472 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
473 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
474 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
475 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
476 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
477 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
478 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
479 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
480 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
481 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
482 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
483 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
484};
485
486/*
drh8e64d1c2004-10-07 00:32:39 +0000487** Output a single term of CSV. Actually, p->separator is used for
488** the separator, which may or may not be a comma. p->nullvalue is
489** the null value. Strings are quoted using ANSI-C rules. Numbers
490** appear outside of quotes.
491*/
492static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000493 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000494 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000495 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000496 }else{
drhc49f44e2006-10-26 18:15:42 +0000497 int i;
drh4f21c4a2008-12-10 22:15:00 +0000498 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000499 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000500 if( needCsvQuote[((unsigned char*)z)[i]]
501 || (z[i]==p->separator[0] &&
502 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000503 i = 0;
504 break;
505 }
506 }
507 if( i==0 ){
508 putc('"', out);
509 for(i=0; z[i]; i++){
510 if( z[i]=='"' ) putc('"', out);
511 putc(z[i], out);
512 }
513 putc('"', out);
514 }else{
515 fprintf(out, "%s", z);
516 }
drh8e64d1c2004-10-07 00:32:39 +0000517 }
518 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000519 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000520 }
521}
522
danielk19774af00c62005-01-23 23:43:21 +0000523#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000524/*
drh4c504392000-10-16 22:06:40 +0000525** This routine runs when the user presses Ctrl-C
526*/
527static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000528 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000529 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000530 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000531}
danielk19774af00c62005-01-23 23:43:21 +0000532#endif
drh4c504392000-10-16 22:06:40 +0000533
534/*
drh75897232000-05-29 14:26:00 +0000535** This is the callback routine that the SQLite library
536** invokes for each row of a query result.
537*/
538static int callback(void *pArg, int nArg, char **azArg, char **azCol){
539 int i;
540 struct callback_data *p = (struct callback_data*)pArg;
541 switch( p->mode ){
542 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000543 int w = 5;
drh6a535342001-10-19 16:44:56 +0000544 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000545 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000546 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000547 if( len>w ) w = len;
548 }
drh75897232000-05-29 14:26:00 +0000549 if( p->cnt++>0 ) fprintf(p->out,"\n");
550 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000551 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000552 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000553 }
554 break;
555 }
danielk19770d78bae2008-01-03 07:09:48 +0000556 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000557 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000558 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000559 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000560 int w, n;
561 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000562 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000563 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000564 w = 0;
drh75897232000-05-29 14:26:00 +0000565 }
drha0c66f52000-07-29 13:20:21 +0000566 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000567 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000568 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000569 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000570 if( w<n ) w = n;
571 }
572 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000573 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000574 }
575 if( p->showHeader ){
576 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
577 }
578 }
579 if( p->showHeader ){
580 for(i=0; i<nArg; i++){
581 int w;
582 if( i<ArraySize(p->actualWidth) ){
583 w = p->actualWidth[i];
584 }else{
585 w = 10;
586 }
587 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
588 "----------------------------------------------------------",
589 i==nArg-1 ? "\n": " ");
590 }
drh75897232000-05-29 14:26:00 +0000591 }
592 }
drh6a535342001-10-19 16:44:56 +0000593 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000594 for(i=0; i<nArg; i++){
595 int w;
drha0c66f52000-07-29 13:20:21 +0000596 if( i<ArraySize(p->actualWidth) ){
597 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000598 }else{
599 w = 10;
600 }
drhea678832008-12-10 19:26:22 +0000601 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000602 strlen30(azArg[i])>w ){
603 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000604 }
drhc61053b2000-06-04 12:58:36 +0000605 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000606 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000607 }
608 break;
609 }
drhe3710332000-09-29 13:30:53 +0000610 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000611 case MODE_List: {
612 if( p->cnt++==0 && p->showHeader ){
613 for(i=0; i<nArg; i++){
614 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
615 }
616 }
drh6a535342001-10-19 16:44:56 +0000617 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000618 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000619 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000620 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000621 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000622 if( i<nArg-1 ){
623 fprintf(p->out, "%s", p->separator);
624 }else if( p->mode==MODE_Semi ){
625 fprintf(p->out, ";\n");
626 }else{
627 fprintf(p->out, "\n");
628 }
drh75897232000-05-29 14:26:00 +0000629 }
630 break;
631 }
drh1e5d0e92000-05-31 23:33:17 +0000632 case MODE_Html: {
633 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000634 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000635 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000636 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
drh1e5d0e92000-05-31 23:33:17 +0000637 }
mihailim57c591a2008-06-23 21:26:05 +0000638 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000639 }
drh6a535342001-10-19 16:44:56 +0000640 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000641 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000642 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000643 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000644 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000645 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000646 }
mihailim57c591a2008-06-23 21:26:05 +0000647 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000648 break;
649 }
drhfeac5f82004-08-01 00:10:45 +0000650 case MODE_Tcl: {
651 if( p->cnt++==0 && p->showHeader ){
652 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000653 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000654 fprintf(p->out, "%s", p->separator);
655 }
656 fprintf(p->out,"\n");
657 }
658 if( azArg==0 ) break;
659 for(i=0; i<nArg; i++){
660 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
661 fprintf(p->out, "%s", p->separator);
662 }
663 fprintf(p->out,"\n");
664 break;
665 }
drh8e64d1c2004-10-07 00:32:39 +0000666 case MODE_Csv: {
667 if( p->cnt++==0 && p->showHeader ){
668 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000669 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000670 }
671 fprintf(p->out,"\n");
672 }
673 if( azArg==0 ) break;
674 for(i=0; i<nArg; i++){
675 output_csv(p, azArg[i], i<nArg-1);
676 }
677 fprintf(p->out,"\n");
678 break;
679 }
drh28bd4bc2000-06-15 15:57:22 +0000680 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000681 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000682 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000683 for(i=0; i<nArg; i++){
684 char *zSep = i>0 ? ",": "";
685 if( azArg[i]==0 ){
686 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000687 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000688 fprintf(p->out,"%s%s",zSep, azArg[i]);
689 }else{
690 if( zSep[0] ) fprintf(p->out,"%s",zSep);
691 output_quoted_string(p->out, azArg[i]);
692 }
693 }
694 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000695 break;
drh28bd4bc2000-06-15 15:57:22 +0000696 }
persicom1d0b8722002-04-18 02:53:04 +0000697 }
drh75897232000-05-29 14:26:00 +0000698 return 0;
699}
700
701/*
drh33048c02001-10-01 14:29:22 +0000702** Set the destination table field of the callback_data structure to
703** the name of the table given. Escape any quote characters in the
704** table name.
705*/
706static void set_table_name(struct callback_data *p, const char *zName){
707 int i, n;
708 int needQuote;
709 char *z;
710
711 if( p->zDestTable ){
712 free(p->zDestTable);
713 p->zDestTable = 0;
714 }
715 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000716 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000717 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000718 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000719 needQuote = 1;
720 if( zName[i]=='\'' ) n++;
721 }
722 }
723 if( needQuote ) n += 2;
724 z = p->zDestTable = malloc( n+1 );
725 if( z==0 ){
726 fprintf(stderr,"Out of memory!\n");
727 exit(1);
728 }
729 n = 0;
730 if( needQuote ) z[n++] = '\'';
731 for(i=0; zName[i]; i++){
732 z[n++] = zName[i];
733 if( zName[i]=='\'' ) z[n++] = '\'';
734 }
735 if( needQuote ) z[n++] = '\'';
736 z[n] = 0;
737}
738
danielk19772a02e332004-06-05 08:04:36 +0000739/* zIn is either a pointer to a NULL-terminated string in memory obtained
740** from malloc(), or a NULL pointer. The string pointed to by zAppend is
741** added to zIn, and the result returned in memory obtained from malloc().
742** zIn, if it was not NULL, is freed.
743**
744** If the third argument, quote, is not '\0', then it is used as a
745** quote character for zAppend.
746*/
drhc28490c2006-10-26 14:25:58 +0000747static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000748 int len;
749 int i;
drh4f21c4a2008-12-10 22:15:00 +0000750 int nAppend = strlen30(zAppend);
751 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000752
753 len = nAppend+nIn+1;
754 if( quote ){
755 len += 2;
756 for(i=0; i<nAppend; i++){
757 if( zAppend[i]==quote ) len++;
758 }
759 }
760
761 zIn = (char *)realloc(zIn, len);
762 if( !zIn ){
763 return 0;
764 }
765
766 if( quote ){
767 char *zCsr = &zIn[nIn];
768 *zCsr++ = quote;
769 for(i=0; i<nAppend; i++){
770 *zCsr++ = zAppend[i];
771 if( zAppend[i]==quote ) *zCsr++ = quote;
772 }
773 *zCsr++ = quote;
774 *zCsr++ = '\0';
775 assert( (zCsr-zIn)==len );
776 }else{
777 memcpy(&zIn[nIn], zAppend, nAppend);
778 zIn[len-1] = '\0';
779 }
780
781 return zIn;
782}
783
drhdd3d4592004-08-30 01:54:05 +0000784
785/*
786** Execute a query statement that has a single result column. Print
787** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000788**
789** This is used, for example, to show the schema of the database by
790** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000791*/
792static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
793 sqlite3_stmt *pSelect;
794 int rc;
795 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
796 if( rc!=SQLITE_OK || !pSelect ){
797 return rc;
798 }
799 rc = sqlite3_step(pSelect);
800 while( rc==SQLITE_ROW ){
801 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
802 rc = sqlite3_step(pSelect);
803 }
804 return sqlite3_finalize(pSelect);
805}
806
807
drh33048c02001-10-01 14:29:22 +0000808/*
drh4c653a02000-06-07 01:27:47 +0000809** This is a different callback routine used for dumping the database.
810** Each row received by this callback consists of a table name,
811** the table type ("index" or "table") and SQL to create the table.
812** This routine should print text sufficient to recreate the table.
813*/
814static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000815 int rc;
816 const char *zTable;
817 const char *zType;
818 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000819 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000820
drh902b9ee2008-12-05 17:17:07 +0000821 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +0000822 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000823 zTable = azArg[0];
824 zType = azArg[1];
825 zSql = azArg[2];
826
drh00b950d2005-09-11 02:03:03 +0000827 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000828 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000829 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
830 fprintf(p->out, "ANALYZE sqlite_master;\n");
831 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
832 return 0;
drh45e29d82006-11-20 16:21:10 +0000833 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
834 char *zIns;
835 if( !p->writableSchema ){
836 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
837 p->writableSchema = 1;
838 }
839 zIns = sqlite3_mprintf(
840 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
841 "VALUES('table','%q','%q',0,'%q');",
842 zTable, zTable, zSql);
843 fprintf(p->out, "%s\n", zIns);
844 sqlite3_free(zIns);
845 return 0;
drh00b950d2005-09-11 02:03:03 +0000846 }else{
847 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000848 }
danielk19772a02e332004-06-05 08:04:36 +0000849
850 if( strcmp(zType, "table")==0 ){
851 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000852 char *zSelect = 0;
853 char *zTableInfo = 0;
854 char *zTmp = 0;
855
856 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
857 zTableInfo = appendText(zTableInfo, zTable, '"');
858 zTableInfo = appendText(zTableInfo, ");", 0);
859
860 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
861 if( zTableInfo ) free(zTableInfo);
862 if( rc!=SQLITE_OK || !pTableInfo ){
863 return 1;
864 }
865
866 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
867 zTmp = appendText(zTmp, zTable, '"');
868 if( zTmp ){
869 zSelect = appendText(zSelect, zTmp, '\'');
870 }
871 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
872 rc = sqlite3_step(pTableInfo);
873 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000874 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000875 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000876 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000877 rc = sqlite3_step(pTableInfo);
878 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000879 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000880 }else{
881 zSelect = appendText(zSelect, ") ", 0);
882 }
883 }
884 rc = sqlite3_finalize(pTableInfo);
885 if( rc!=SQLITE_OK ){
886 if( zSelect ) free(zSelect);
887 return 1;
888 }
889 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
890 zSelect = appendText(zSelect, zTable, '"');
891
drhdd3d4592004-08-30 01:54:05 +0000892 rc = run_table_dump_query(p->out, p->db, zSelect);
893 if( rc==SQLITE_CORRUPT ){
894 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
895 rc = run_table_dump_query(p->out, p->db, zSelect);
896 }
danielk19772a02e332004-06-05 08:04:36 +0000897 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000898 }
drh4c653a02000-06-07 01:27:47 +0000899 return 0;
900}
901
902/*
drh45e29d82006-11-20 16:21:10 +0000903** Run zQuery. Use dump_callback() as the callback routine so that
904** the contents of the query are output as SQL statements.
905**
drhdd3d4592004-08-30 01:54:05 +0000906** If we get a SQLITE_CORRUPT error, rerun the query after appending
907** "ORDER BY rowid DESC" to the end.
908*/
909static int run_schema_dump_query(
910 struct callback_data *p,
911 const char *zQuery,
912 char **pzErrMsg
913){
914 int rc;
915 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
916 if( rc==SQLITE_CORRUPT ){
917 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +0000918 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +0000919 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
920 zQ2 = malloc( len+100 );
921 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000922 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000923 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
924 free(zQ2);
925 }
926 return rc;
927}
928
929/*
drh75897232000-05-29 14:26:00 +0000930** Text of a help message
931*/
persicom1d0b8722002-04-18 02:53:04 +0000932static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +0000933 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drh20f99c42007-01-08 14:31:35 +0000934 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000935 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000936 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000937 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000938 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000939 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000940 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000941 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000942 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000943 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000944#ifdef SQLITE_ENABLE_IOTRACE
945 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
946#endif
drh70df4fe2006-06-13 15:12:21 +0000947#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000948 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000949#endif
danielk19776b77a362005-01-13 11:10:25 +0000950 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000951 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000952 " column Left-aligned columns. (See .width)\n"
953 " html HTML <table> code\n"
954 " insert SQL insert statements for TABLE\n"
955 " line One value per line\n"
956 " list Values delimited by .separator string\n"
957 " tabs Tab-separated values\n"
958 " tcl TCL list elements\n"
959 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000960 ".output FILENAME Send output to FILENAME\n"
961 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000962 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000963 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000964 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +0000965 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh75897232000-05-29 14:26:00 +0000966 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000967 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000968 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000969 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000970 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +0000971#if HAS_TIMER
972 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
973#endif
drh75897232000-05-29 14:26:00 +0000974 ".width NUM NUM ... Set column widths for \"column\" mode\n"
975;
976
drhdaffd0e2001-04-11 14:28:42 +0000977/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000978static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000979
drh75897232000-05-29 14:26:00 +0000980/*
drh44c2eb12003-04-30 11:38:26 +0000981** Make sure the database is open. If it is not, then open it. If
982** the database fails to open, print an error message and exit.
983*/
984static void open_db(struct callback_data *p){
985 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000986 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000987 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +0000988 if( db && sqlite3_errcode(db)==SQLITE_OK ){
989 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
990 shellstaticFunc, 0, 0);
991 }
992 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +0000993 fprintf(stderr,"Unable to open database \"%s\": %s\n",
994 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000995 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000996 }
drhc2e87a32006-06-27 15:16:14 +0000997#ifndef SQLITE_OMIT_LOAD_EXTENSION
998 sqlite3_enable_load_extension(p->db, 1);
999#endif
drh44c2eb12003-04-30 11:38:26 +00001000 }
1001}
1002
1003/*
drhfeac5f82004-08-01 00:10:45 +00001004** Do C-language style dequoting.
1005**
1006** \t -> tab
1007** \n -> newline
1008** \r -> carriage return
1009** \NNN -> ascii character NNN in octal
1010** \\ -> backslash
1011*/
1012static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001013 int i, j;
1014 char c;
drhfeac5f82004-08-01 00:10:45 +00001015 for(i=j=0; (c = z[i])!=0; i++, j++){
1016 if( c=='\\' ){
1017 c = z[++i];
1018 if( c=='n' ){
1019 c = '\n';
1020 }else if( c=='t' ){
1021 c = '\t';
1022 }else if( c=='r' ){
1023 c = '\r';
1024 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001025 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001026 if( z[i+1]>='0' && z[i+1]<='7' ){
1027 i++;
1028 c = (c<<3) + z[i] - '0';
1029 if( z[i+1]>='0' && z[i+1]<='7' ){
1030 i++;
1031 c = (c<<3) + z[i] - '0';
1032 }
1033 }
1034 }
1035 }
1036 z[j] = c;
1037 }
1038 z[j] = 0;
1039}
1040
1041/*
drhc28490c2006-10-26 14:25:58 +00001042** Interpret zArg as a boolean value. Return either 0 or 1.
1043*/
1044static int booleanValue(char *zArg){
1045 int val = atoi(zArg);
1046 int j;
1047 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001048 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001049 }
1050 if( strcmp(zArg,"on")==0 ){
1051 val = 1;
1052 }else if( strcmp(zArg,"yes")==0 ){
1053 val = 1;
1054 }
1055 return val;
1056}
1057
1058/*
drh75897232000-05-29 14:26:00 +00001059** If an input line begins with "." then invoke this routine to
1060** process that line.
drh67505e72002-04-19 12:34:06 +00001061**
drh47ad6842006-11-08 12:25:42 +00001062** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001063*/
drh44c2eb12003-04-30 11:38:26 +00001064static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001065 int i = 1;
1066 int nArg = 0;
1067 int n, c;
drh67505e72002-04-19 12:34:06 +00001068 int rc = 0;
drh75897232000-05-29 14:26:00 +00001069 char *azArg[50];
1070
1071 /* Parse the input line into tokens.
1072 */
1073 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001074 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001075 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001076 if( zLine[i]=='\'' || zLine[i]=='"' ){
1077 int delim = zLine[i++];
1078 azArg[nArg++] = &zLine[i];
1079 while( zLine[i] && zLine[i]!=delim ){ i++; }
1080 if( zLine[i]==delim ){
1081 zLine[i++] = 0;
1082 }
drhfeac5f82004-08-01 00:10:45 +00001083 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001084 }else{
1085 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001086 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001087 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001088 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001089 }
1090 }
1091
1092 /* Process the input line.
1093 */
drh67505e72002-04-19 12:34:06 +00001094 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00001095 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001096 c = azArg[0][0];
drh9ff849f2009-02-04 20:55:57 +00001097 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){
1098 const char *zDestFile;
1099 const char *zDb;
1100 sqlite3 *pDest;
1101 sqlite3_backup *pBackup;
1102 int rc;
1103 if( nArg==2 ){
1104 zDestFile = azArg[1];
1105 zDb = "main";
1106 }else{
1107 zDestFile = azArg[2];
1108 zDb = azArg[1];
1109 }
1110 rc = sqlite3_open(zDestFile, &pDest);
1111 if( rc!=SQLITE_OK ){
1112 fprintf(stderr, "Error: cannot open %s\n", zDestFile);
1113 sqlite3_close(pDest);
1114 return 1;
1115 }
1116 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1117 if( pBackup==0 ){
1118 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1119 sqlite3_close(pDest);
1120 return 1;
1121 }
1122 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1123 sqlite3_backup_finish(pBackup);
1124 if( rc==SQLITE_DONE ){
1125 rc = SQLITE_OK;
1126 }else{
1127 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1128 }
1129 sqlite3_close(pDest);
1130 }else
1131
1132 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
drhc49f44e2006-10-26 18:15:42 +00001133 bail_on_error = booleanValue(azArg[1]);
1134 }else
1135
jplyon6a65bb32003-05-04 07:25:57 +00001136 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001137 struct callback_data data;
1138 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001139 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001140 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001141 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001142 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001143 data.colWidth[0] = 3;
1144 data.colWidth[1] = 15;
1145 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001146 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001147 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001148 if( zErrMsg ){
1149 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001150 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001151 }
1152 }else
1153
drh4c653a02000-06-07 01:27:47 +00001154 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1155 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001156 open_db(p);
drh33048c02001-10-01 14:29:22 +00001157 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001158 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001159 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001160 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001161 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001162 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001163 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001164 );
1165 run_table_dump_query(p->out, p->db,
1166 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001167 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001168 );
drh4c653a02000-06-07 01:27:47 +00001169 }else{
1170 int i;
drhdd3d4592004-08-30 01:54:05 +00001171 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001172 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001173 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001174 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001175 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001176 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001177 run_table_dump_query(p->out, p->db,
1178 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001179 "WHERE sql NOT NULL"
1180 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001181 " AND tbl_name LIKE shellstatic()"
1182 );
danielk1977bc6ada42004-06-30 08:20:16 +00001183 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001184 }
1185 }
drh45e29d82006-11-20 16:21:10 +00001186 if( p->writableSchema ){
1187 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1188 p->writableSchema = 0;
1189 }
drh93f41e52008-08-11 19:12:34 +00001190 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001191 if( zErrMsg ){
1192 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001193 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001194 }else{
1195 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001196 }
1197 }else
drh75897232000-05-29 14:26:00 +00001198
drhdaffd0e2001-04-11 14:28:42 +00001199 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001200 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001201 }else
1202
drh75897232000-05-29 14:26:00 +00001203 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001204 rc = 2;
drh75897232000-05-29 14:26:00 +00001205 }else
1206
drhdd45df82002-04-18 12:39:03 +00001207 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001208 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001209 if(val == 1) {
1210 if(!p->explainPrev.valid) {
1211 p->explainPrev.valid = 1;
1212 p->explainPrev.mode = p->mode;
1213 p->explainPrev.showHeader = p->showHeader;
1214 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1215 }
1216 /* We could put this code under the !p->explainValid
1217 ** condition so that it does not execute if we are already in
1218 ** explain mode. However, always executing it allows us an easy
1219 ** was to reset to explain mode in case the user previously
1220 ** did an .explain followed by a .width, .mode or .header
1221 ** command.
1222 */
danielk19770d78bae2008-01-03 07:09:48 +00001223 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001224 p->showHeader = 1;
1225 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001226 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001227 p->colWidth[1] = 13; /* opcode */
1228 p->colWidth[2] = 4; /* P1 */
1229 p->colWidth[3] = 4; /* P2 */
1230 p->colWidth[4] = 4; /* P3 */
1231 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001232 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001233 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001234 }else if (p->explainPrev.valid) {
1235 p->explainPrev.valid = 0;
1236 p->mode = p->explainPrev.mode;
1237 p->showHeader = p->explainPrev.showHeader;
1238 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1239 }
drh75897232000-05-29 14:26:00 +00001240 }else
1241
drhc28490c2006-10-26 14:25:58 +00001242 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001243 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001244 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001245 }else
1246
1247 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drha81c64a2009-01-14 23:38:02 +00001248 fprintf(stderr,"%s",zHelp);
drh75897232000-05-29 14:26:00 +00001249 }else
1250
drhfeac5f82004-08-01 00:10:45 +00001251 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1252 char *zTable = azArg[2]; /* Insert data into this table */
1253 char *zFile = azArg[1]; /* The file from which to extract data */
1254 sqlite3_stmt *pStmt; /* A statement */
1255 int rc; /* Result code */
1256 int nCol; /* Number of columns in the table */
1257 int nByte; /* Number of bytes in an SQL string */
1258 int i, j; /* Loop counters */
1259 int nSep; /* Number of bytes in p->separator[] */
1260 char *zSql; /* An SQL statement */
1261 char *zLine; /* A single line of input from the file */
1262 char **azCol; /* zLine[] broken up into columns */
1263 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001264 FILE *in; /* The input file */
1265 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001266
drha543c822006-06-08 16:10:14 +00001267 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001268 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001269 if( nSep==0 ){
1270 fprintf(stderr, "non-null separator required for import\n");
1271 return 0;
1272 }
1273 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1274 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00001275 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001276 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001277 sqlite3_free(zSql);
1278 if( rc ){
1279 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1280 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001281 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001282 }else{
1283 nCol = sqlite3_column_count(pStmt);
1284 }
1285 sqlite3_finalize(pStmt);
1286 if( nCol==0 ) return 0;
1287 zSql = malloc( nByte + 20 + nCol*2 );
1288 if( zSql==0 ) return 0;
1289 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001290 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001291 for(i=1; i<nCol; i++){
1292 zSql[j++] = ',';
1293 zSql[j++] = '?';
1294 }
1295 zSql[j++] = ')';
1296 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001297 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001298 free(zSql);
1299 if( rc ){
1300 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1301 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001302 return 1;
drhfeac5f82004-08-01 00:10:45 +00001303 }
1304 in = fopen(zFile, "rb");
1305 if( in==0 ){
1306 fprintf(stderr, "cannot open file: %s\n", zFile);
1307 sqlite3_finalize(pStmt);
1308 return 0;
1309 }
1310 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001311 if( azCol==0 ){
1312 fclose(in);
1313 return 0;
1314 }
drhfeac5f82004-08-01 00:10:45 +00001315 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1316 zCommit = "COMMIT";
1317 while( (zLine = local_getline(0, in))!=0 ){
1318 char *z;
1319 i = 0;
drhb860bc92004-08-04 15:16:55 +00001320 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001321 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001322 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001323 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1324 *z = 0;
1325 i++;
drhb860bc92004-08-04 15:16:55 +00001326 if( i<nCol ){
1327 azCol[i] = &z[nSep];
1328 z += nSep-1;
1329 }
drhfeac5f82004-08-01 00:10:45 +00001330 }
1331 }
drh1cd7f832005-08-05 18:50:51 +00001332 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001333 if( i+1!=nCol ){
1334 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1335 zFile, lineno, nCol, i+1);
1336 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001337 free(zLine);
drhb860bc92004-08-04 15:16:55 +00001338 break;
1339 }
drhfeac5f82004-08-01 00:10:45 +00001340 for(i=0; i<nCol; i++){
1341 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1342 }
1343 sqlite3_step(pStmt);
1344 rc = sqlite3_reset(pStmt);
1345 free(zLine);
1346 if( rc!=SQLITE_OK ){
1347 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1348 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001349 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001350 break;
1351 }
1352 }
1353 free(azCol);
1354 fclose(in);
1355 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001356 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001357 }else
1358
drh75897232000-05-29 14:26:00 +00001359 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1360 struct callback_data data;
1361 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001362 open_db(p);
drh75897232000-05-29 14:26:00 +00001363 memcpy(&data, p, sizeof(data));
1364 data.showHeader = 0;
1365 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001366 zShellStatic = azArg[1];
1367 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001368 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001369 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001370 "UNION ALL "
1371 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001372 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001373 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001374 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001375 );
danielk1977bc6ada42004-06-30 08:20:16 +00001376 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001377 if( zErrMsg ){
1378 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001379 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001380 }
1381 }else
1382
drhae5e4452007-05-03 17:18:36 +00001383#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001384 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001385 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001386 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1387 iotrace = 0;
1388 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001389 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001390 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001391 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001392 iotrace = stdout;
1393 }else{
1394 iotrace = fopen(azArg[1], "w");
1395 if( iotrace==0 ){
1396 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001397 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001398 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001399 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001400 }
1401 }
1402 }else
drhae5e4452007-05-03 17:18:36 +00001403#endif
drhb0603412007-02-28 04:47:26 +00001404
drh70df4fe2006-06-13 15:12:21 +00001405#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001406 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1407 const char *zFile, *zProc;
1408 char *zErrMsg = 0;
1409 int rc;
1410 zFile = azArg[1];
1411 zProc = nArg>=3 ? azArg[2] : 0;
1412 open_db(p);
1413 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1414 if( rc!=SQLITE_OK ){
1415 fprintf(stderr, "%s\n", zErrMsg);
1416 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001417 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001418 }
1419 }else
drh70df4fe2006-06-13 15:12:21 +00001420#endif
drh1e397f82006-06-08 15:28:43 +00001421
drh28bd4bc2000-06-15 15:57:22 +00001422 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00001423 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001424 if( strncmp(azArg[1],"line",n2)==0
1425 ||
1426 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001427 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001428 }else if( strncmp(azArg[1],"column",n2)==0
1429 ||
1430 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001431 p->mode = MODE_Column;
1432 }else if( strncmp(azArg[1],"list",n2)==0 ){
1433 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001434 }else if( strncmp(azArg[1],"html",n2)==0 ){
1435 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001436 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1437 p->mode = MODE_Tcl;
1438 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001439 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001440 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001441 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1442 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001443 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001444 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1445 p->mode = MODE_Insert;
1446 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001447 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001448 }else{
drh33048c02001-10-01 14:29:22 +00001449 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001450 }
drhdaffd0e2001-04-11 14:28:42 +00001451 }else {
drhcf68ae92006-12-19 18:47:41 +00001452 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001453 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001454 }
1455 }else
1456
persicom7e2dfdd2002-04-18 02:46:52 +00001457 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001458 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1459 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001460 }else
1461
drh75897232000-05-29 14:26:00 +00001462 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1463 if( p->out!=stdout ){
1464 fclose(p->out);
1465 }
1466 if( strcmp(azArg[1],"stdout")==0 ){
1467 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001468 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001469 }else{
drha1f9b5e2004-02-14 16:31:02 +00001470 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001471 if( p->out==0 ){
1472 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1473 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001474 } else {
drh5bb3eb92007-05-04 13:15:55 +00001475 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001476 }
1477 }
1478 }else
1479
drhdd45df82002-04-18 12:39:03 +00001480 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001481 if( nArg >= 2) {
1482 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1483 }
1484 if( nArg >= 3) {
1485 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1486 }
1487 }else
1488
1489 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001490 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001491 }else
1492
drh9ff849f2009-02-04 20:55:57 +00001493 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001494 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001495 if( alt==0 ){
1496 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1497 }else{
1498 process_input(p, alt);
1499 fclose(alt);
1500 }
1501 }else
1502
drh9ff849f2009-02-04 20:55:57 +00001503 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){
1504 const char *zSrcFile;
1505 const char *zDb;
1506 sqlite3 *pSrc;
1507 sqlite3_backup *pBackup;
1508 int rc;
1509 if( nArg==2 ){
1510 zSrcFile = azArg[1];
1511 zDb = "main";
1512 }else{
1513 zSrcFile = azArg[2];
1514 zDb = azArg[1];
1515 }
1516 rc = sqlite3_open(zSrcFile, &pSrc);
1517 if( rc!=SQLITE_OK ){
1518 fprintf(stderr, "Error: cannot open %s\n", zSrcFile);
1519 sqlite3_close(pSrc);
1520 return 1;
1521 }
1522 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
1523 if( pBackup==0 ){
1524 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1525 sqlite3_close(pSrc);
1526 return 1;
1527 }
1528 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){
1529 if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
1530 sqlite3_sleep(10);
1531 }
1532 }
1533 sqlite3_backup_finish(pBackup);
1534 if( rc==SQLITE_DONE ){
1535 rc = SQLITE_OK;
1536 }else{
1537 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1538 }
1539 sqlite3_close(pSrc);
1540 }else
1541
drh75897232000-05-29 14:26:00 +00001542 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1543 struct callback_data data;
1544 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001545 open_db(p);
drh75897232000-05-29 14:26:00 +00001546 memcpy(&data, p, sizeof(data));
1547 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001548 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001549 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001550 int i;
shane7d3846a2008-12-11 02:58:26 +00001551 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00001552 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001553 char *new_argv[2], *new_colv[2];
1554 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1555 " type text,\n"
1556 " name text,\n"
1557 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001558 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001559 " sql text\n"
1560 ")";
1561 new_argv[1] = 0;
1562 new_colv[0] = "sql";
1563 new_colv[1] = 0;
1564 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001565 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001566 char *new_argv[2], *new_colv[2];
1567 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1568 " type text,\n"
1569 " name text,\n"
1570 " tbl_name text,\n"
1571 " rootpage integer,\n"
1572 " sql text\n"
1573 ")";
1574 new_argv[1] = 0;
1575 new_colv[0] = "sql";
1576 new_colv[1] = 0;
1577 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001578 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001579 zShellStatic = azArg[1];
1580 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001581 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00001582 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
1583 " FROM sqlite_master UNION ALL"
1584 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001585 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001586 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001587 callback, &data, &zErrMsg);
1588 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001589 }
drh75897232000-05-29 14:26:00 +00001590 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001591 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001592 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00001593 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
1594 " FROM sqlite_master UNION ALL"
1595 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001596 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001597 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001598 callback, &data, &zErrMsg
1599 );
drh75897232000-05-29 14:26:00 +00001600 }
drh75897232000-05-29 14:26:00 +00001601 if( zErrMsg ){
1602 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001603 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001604 }
1605 }else
1606
1607 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001608 sqlite3_snprintf(sizeof(p->separator), p->separator,
1609 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001610 }else
1611
persicom7e2dfdd2002-04-18 02:46:52 +00001612 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1613 int i;
1614 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001615 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001616 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001617 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001618 fprintf(p->out,"%9.9s: ", "nullvalue");
1619 output_c_string(p->out, p->nullvalue);
1620 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001621 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00001622 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001623 fprintf(p->out,"%9.9s: ", "separator");
1624 output_c_string(p->out, p->separator);
1625 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001626 fprintf(p->out,"%9.9s: ","width");
1627 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001628 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001629 }
drhfeac5f82004-08-01 00:10:45 +00001630 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001631 }else
1632
drh2dfbbca2000-07-28 14:32:48 +00001633 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001634 char **azResult;
1635 int nRow, rc;
1636 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001637 open_db(p);
drha50da102000-08-08 20:19:09 +00001638 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001639 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001640 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001641 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001642 "UNION ALL "
1643 "SELECT name FROM sqlite_temp_master "
1644 "WHERE type IN ('table','view') "
1645 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001646 &azResult, &nRow, 0, &zErrMsg
1647 );
drha50da102000-08-08 20:19:09 +00001648 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001649 zShellStatic = azArg[1];
1650 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001651 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001652 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001653 "UNION ALL "
1654 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001655 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001656 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001657 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001658 );
danielk1977bc6ada42004-06-30 08:20:16 +00001659 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001660 }
drh75897232000-05-29 14:26:00 +00001661 if( zErrMsg ){
1662 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001663 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001664 }
drhe3710332000-09-29 13:30:53 +00001665 if( rc==SQLITE_OK ){
1666 int len, maxlen = 0;
1667 int i, j;
1668 int nPrintCol, nPrintRow;
1669 for(i=1; i<=nRow; i++){
1670 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00001671 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00001672 if( len>maxlen ) maxlen = len;
1673 }
1674 nPrintCol = 80/(maxlen+2);
1675 if( nPrintCol<1 ) nPrintCol = 1;
1676 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1677 for(i=0; i<nPrintRow; i++){
1678 for(j=i+1; j<=nRow; j+=nPrintRow){
1679 char *zSp = j<=nPrintRow ? "" : " ";
1680 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1681 }
1682 printf("\n");
1683 }
drh47ad6842006-11-08 12:25:42 +00001684 }else{
1685 rc = 1;
drhe3710332000-09-29 13:30:53 +00001686 }
danielk19776f8a5032004-05-10 10:34:51 +00001687 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001688 }else
1689
drh3b1a9882007-11-02 12:53:03 +00001690 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001691 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001692 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001693 }else
drh3b1a9882007-11-02 12:53:03 +00001694
1695#if HAS_TIMER
1696 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
1697 enableTimer = booleanValue(azArg[1]);
1698 }else
1699#endif
drh2dfbbca2000-07-28 14:32:48 +00001700
drh75897232000-05-29 14:26:00 +00001701 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1702 int j;
drh43617e92006-03-06 20:55:46 +00001703 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001704 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1705 p->colWidth[j-1] = atoi(azArg[j]);
1706 }
1707 }else
1708
drh3b1a9882007-11-02 12:53:03 +00001709
drh75897232000-05-29 14:26:00 +00001710 {
drh67505e72002-04-19 12:34:06 +00001711 fprintf(stderr, "unknown command or invalid arguments: "
1712 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001713 }
drh67505e72002-04-19 12:34:06 +00001714
1715 return rc;
drh75897232000-05-29 14:26:00 +00001716}
1717
drh67505e72002-04-19 12:34:06 +00001718/*
drh91a66392007-09-07 01:12:32 +00001719** Return TRUE if a semicolon occurs anywhere in the first N characters
1720** of string z[].
drh324ccef2003-02-05 14:06:20 +00001721*/
drh91a66392007-09-07 01:12:32 +00001722static int _contains_semicolon(const char *z, int N){
1723 int i;
1724 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
1725 return 0;
drh324ccef2003-02-05 14:06:20 +00001726}
1727
1728/*
drh70c7a4b2003-04-26 03:03:06 +00001729** Test to see if a line consists entirely of whitespace.
1730*/
1731static int _all_whitespace(const char *z){
1732 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001733 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001734 if( *z=='/' && z[1]=='*' ){
1735 z += 2;
1736 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1737 if( *z==0 ) return 0;
1738 z++;
1739 continue;
1740 }
1741 if( *z=='-' && z[1]=='-' ){
1742 z += 2;
1743 while( *z && *z!='\n' ){ z++; }
1744 if( *z==0 ) return 1;
1745 continue;
1746 }
1747 return 0;
1748 }
1749 return 1;
1750}
1751
1752/*
drha9b17162003-04-29 18:01:28 +00001753** Return TRUE if the line typed in is an SQL command terminator other
1754** than a semi-colon. The SQL Server style "go" command is understood
1755** as is the Oracle "/".
1756*/
1757static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001758 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00001759 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
1760 return 1; /* Oracle */
1761 }
drhc8d74412004-08-31 23:41:26 +00001762 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1763 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001764 return 1; /* SQL Server */
1765 }
1766 return 0;
1767}
1768
1769/*
drh233a5312008-12-18 22:25:13 +00001770** Return true if zSql is a complete SQL statement. Return false if it
1771** ends in the middle of a string literal or C-style comment.
1772*/
1773static int _is_complete(char *zSql, int nSql){
1774 int rc;
1775 if( zSql==0 ) return 1;
1776 zSql[nSql] = ';';
1777 zSql[nSql+1] = 0;
1778 rc = sqlite3_complete(zSql);
1779 zSql[nSql] = 0;
1780 return rc;
1781}
1782
1783/*
drh67505e72002-04-19 12:34:06 +00001784** Read input from *in and process it. If *in==0 then input
1785** is interactive - the user is typing it it. Otherwise, input
1786** is coming from a file or device. A prompt is issued and history
1787** is saved only if input is interactive. An interrupt signal will
1788** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001789**
1790** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001791*/
drhc28490c2006-10-26 14:25:58 +00001792static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001793 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001794 char *zSql = 0;
1795 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00001796 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00001797 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001798 int rc;
1799 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001800 int lineno = 0;
1801 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001802
1803 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1804 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001805 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001806 zLine = one_input_line(zSql, in);
1807 if( zLine==0 ){
1808 break; /* We have reached EOF */
1809 }
drh67505e72002-04-19 12:34:06 +00001810 if( seenInterrupt ){
1811 if( in!=0 ) break;
1812 seenInterrupt = 0;
1813 }
drhc28490c2006-10-26 14:25:58 +00001814 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001815 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001816 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001817 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001818 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001819 if( rc==2 ){
1820 break;
1821 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001822 errCnt++;
1823 }
drhdaffd0e2001-04-11 14:28:42 +00001824 continue;
1825 }
drh233a5312008-12-18 22:25:13 +00001826 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00001827 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001828 }
drh91a66392007-09-07 01:12:32 +00001829 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00001830 if( zSql==0 ){
1831 int i;
drh4c755c02004-08-08 20:22:17 +00001832 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001833 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001834 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00001835 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00001836 if( zSql==0 ){
1837 fprintf(stderr, "out of memory\n");
1838 exit(1);
1839 }
drh5bb3eb92007-05-04 13:15:55 +00001840 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001841 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001842 }
1843 }else{
drh4f21c4a2008-12-10 22:15:00 +00001844 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00001845 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00001846 if( zSql==0 ){
1847 fprintf(stderr,"%s: out of memory!\n", Argv0);
1848 exit(1);
1849 }
drh5bb3eb92007-05-04 13:15:55 +00001850 zSql[nSql++] = '\n';
1851 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001852 nSql += len;
1853 }
drh91a66392007-09-07 01:12:32 +00001854 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1855 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001856 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001857 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00001858 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00001859 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00001860 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00001861 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001862 char zPrefix[100];
1863 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001864 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1865 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001866 }else{
drh5bb3eb92007-05-04 13:15:55 +00001867 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001868 }
drh7f953e22002-07-13 17:33:45 +00001869 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001870 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001871 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001872 zErrMsg = 0;
1873 }else{
drhc28490c2006-10-26 14:25:58 +00001874 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001875 }
drhc49f44e2006-10-26 18:15:42 +00001876 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001877 }
1878 free(zSql);
1879 zSql = 0;
1880 nSql = 0;
1881 }
1882 }
1883 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00001884 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001885 free(zSql);
1886 }
danielk19772ac27622007-07-03 05:31:16 +00001887 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001888 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001889}
1890
drh67505e72002-04-19 12:34:06 +00001891/*
1892** Return a pathname which is the user's home directory. A
1893** 0 return indicates an error of some kind. Space to hold the
1894** resulting string is obtained from malloc(). The calling
1895** function should free the result.
1896*/
1897static char *find_home_dir(void){
1898 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001899
chw97185482008-11-17 08:05:31 +00001900#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00001901 struct passwd *pwent;
1902 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001903 if( (pwent=getpwuid(uid)) != NULL) {
1904 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001905 }
1906#endif
1907
chw65d3c132007-11-12 21:09:10 +00001908#if defined(_WIN32_WCE)
1909 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
1910 */
1911 home_dir = strdup("/");
1912#else
1913
drh164a1b62006-08-19 11:15:20 +00001914#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1915 if (!home_dir) {
1916 home_dir = getenv("USERPROFILE");
1917 }
1918#endif
1919
drh67505e72002-04-19 12:34:06 +00001920 if (!home_dir) {
1921 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001922 }
1923
drhcdb36b72006-06-12 12:57:45 +00001924#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001925 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001926 char *zDrive, *zPath;
1927 int n;
1928 zDrive = getenv("HOMEDRIVE");
1929 zPath = getenv("HOMEPATH");
1930 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00001931 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00001932 home_dir = malloc( n );
1933 if( home_dir==0 ) return 0;
1934 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1935 return home_dir;
1936 }
1937 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001938 }
1939#endif
1940
chw65d3c132007-11-12 21:09:10 +00001941#endif /* !_WIN32_WCE */
1942
drh67505e72002-04-19 12:34:06 +00001943 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00001944 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00001945 char *z = malloc( n );
1946 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001947 home_dir = z;
1948 }
drhe98d4fa2002-04-21 19:06:22 +00001949
drh67505e72002-04-19 12:34:06 +00001950 return home_dir;
1951}
1952
1953/*
1954** Read input from the file given by sqliterc_override. Or if that
1955** parameter is NULL, take input from ~/.sqliterc
1956*/
drh22fbcb82004-02-01 01:22:50 +00001957static void process_sqliterc(
1958 struct callback_data *p, /* Configuration data */
1959 const char *sqliterc_override /* Name of config file. NULL to use default */
1960){
persicom7e2dfdd2002-04-18 02:46:52 +00001961 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001962 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001963 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001964 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001965 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001966
1967 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001968 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001969 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00001970#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00001971 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00001972#endif
drhe98d4fa2002-04-21 19:06:22 +00001973 return;
1974 }
drh4f21c4a2008-12-10 22:15:00 +00001975 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00001976 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001977 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001978 fprintf(stderr,"%s: out of memory!\n", Argv0);
1979 exit(1);
1980 }
drha959ac42007-06-20 13:10:00 +00001981 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001982 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001983 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001984 }
drha1f9b5e2004-02-14 16:31:02 +00001985 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001986 if( in ){
drhc28490c2006-10-26 14:25:58 +00001987 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00001988 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00001989 }
persicom7e2dfdd2002-04-18 02:46:52 +00001990 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001991 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001992 }
drh43617e92006-03-06 20:55:46 +00001993 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001994 return;
1995}
1996
drh67505e72002-04-19 12:34:06 +00001997/*
drhe1e38c42003-05-04 18:30:59 +00001998** Show available command line options
1999*/
2000static const char zOptions[] =
2001 " -init filename read/process named file\n"
2002 " -echo print commands before execution\n"
2003 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00002004 " -bail stop after hitting an error\n"
2005 " -interactive force interactive I/O\n"
2006 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00002007 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00002008 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00002009 " -html set output mode to HTML\n"
2010 " -line set output mode to 'line'\n"
2011 " -list set output mode to 'list'\n"
2012 " -separator 'x' set output field separator (|)\n"
2013 " -nullvalue 'text' set text string for NULL values\n"
2014 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00002015;
2016static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00002017 fprintf(stderr,
2018 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2019 "FILENAME is the name of an SQLite database. A new database is created\n"
2020 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00002021 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00002022 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00002023 }else{
2024 fprintf(stderr, "Use the -help option for additional information\n");
2025 }
2026 exit(1);
2027}
2028
2029/*
drh67505e72002-04-19 12:34:06 +00002030** Initialize the state information in data
2031*/
drh0850b532006-01-31 19:31:43 +00002032static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00002033 memset(data, 0, sizeof(*data));
2034 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00002035 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00002036 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00002037 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
2038 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00002039}
2040
drh75897232000-05-29 14:26:00 +00002041int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00002042 char *zErrMsg = 0;
2043 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00002044 const char *zInitFile = 0;
2045 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00002046 int i;
drhc28490c2006-10-26 14:25:58 +00002047 int rc = 0;
drh75897232000-05-29 14:26:00 +00002048
drhdaffd0e2001-04-11 14:28:42 +00002049 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00002050 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00002051 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00002052
drh44c2eb12003-04-30 11:38:26 +00002053 /* Make sure we have a valid signal handler early, before anything
2054 ** else is done.
2055 */
drh4c504392000-10-16 22:06:40 +00002056#ifdef SIGINT
2057 signal(SIGINT, interrupt_handler);
2058#endif
drh44c2eb12003-04-30 11:38:26 +00002059
drh22fbcb82004-02-01 01:22:50 +00002060 /* Do an initial pass through the command-line argument to locate
2061 ** the name of the database file, the name of the initialization file,
2062 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00002063 */
drh22fbcb82004-02-01 01:22:50 +00002064 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00002065 char *z;
drh44c2eb12003-04-30 11:38:26 +00002066 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00002067 z = argv[i];
2068 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00002069 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
2070 i++;
drh22fbcb82004-02-01 01:22:50 +00002071 }else if( strcmp(argv[i],"-init")==0 ){
2072 i++;
2073 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00002074 }
2075 }
drh22fbcb82004-02-01 01:22:50 +00002076 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002077#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002078 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2079#else
drh22fbcb82004-02-01 01:22:50 +00002080 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002081#endif
drh22fbcb82004-02-01 01:22:50 +00002082 }else{
danielk197703aded42004-11-22 05:26:27 +00002083#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002084 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002085#else
2086 data.zDbFilename = 0;
2087#endif
drh22fbcb82004-02-01 01:22:50 +00002088 }
2089 if( i<argc ){
2090 zFirstCmd = argv[i++];
2091 }
drh44c2eb12003-04-30 11:38:26 +00002092 data.out = stdout;
2093
drh01b41712005-08-29 23:06:23 +00002094#ifdef SQLITE_OMIT_MEMORYDB
2095 if( data.zDbFilename==0 ){
2096 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
2097 exit(1);
2098 }
2099#endif
2100
drh44c2eb12003-04-30 11:38:26 +00002101 /* Go ahead and open the database file if it already exists. If the
2102 ** file does not exist, delay opening it. This prevents empty database
2103 ** files from being created if a user mistypes the database name argument
2104 ** to the sqlite command-line tool.
2105 */
drhc8d74412004-08-31 23:41:26 +00002106 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002107 open_db(&data);
2108 }
2109
drh22fbcb82004-02-01 01:22:50 +00002110 /* Process the initialization file if there is one. If no -init option
2111 ** is given on the command line, look for a file named ~/.sqliterc and
2112 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002113 */
drh22fbcb82004-02-01 01:22:50 +00002114 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00002115
drh22fbcb82004-02-01 01:22:50 +00002116 /* Make a second pass through the command-line argument and set
2117 ** options. This second pass is delayed until after the initialization
2118 ** file is processed so that the command-line arguments will override
2119 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002120 */
drh22fbcb82004-02-01 01:22:50 +00002121 for(i=1; i<argc && argv[i][0]=='-'; i++){
2122 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002123 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002124 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002125 i++;
2126 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002127 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002128 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002129 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002130 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002131 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002132 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002133 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002134 }else if( strcmp(z,"-csv")==0 ){
2135 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002136 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002137 }else if( strcmp(z,"-separator")==0 ){
2138 i++;
drh5bb3eb92007-05-04 13:15:55 +00002139 sqlite3_snprintf(sizeof(data.separator), data.separator,
2140 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002141 }else if( strcmp(z,"-nullvalue")==0 ){
2142 i++;
drh5bb3eb92007-05-04 13:15:55 +00002143 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2144 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002145 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002146 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002147 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002148 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002149 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002150 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002151 }else if( strcmp(z,"-bail")==0 ){
2152 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002153 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002154 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002155 return 0;
drhc28490c2006-10-26 14:25:58 +00002156 }else if( strcmp(z,"-interactive")==0 ){
2157 stdin_is_interactive = 1;
2158 }else if( strcmp(z,"-batch")==0 ){
2159 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002160 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002161 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002162 }else{
drh22fbcb82004-02-01 01:22:50 +00002163 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002164 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002165 return 1;
2166 }
2167 }
drh44c2eb12003-04-30 11:38:26 +00002168
drh22fbcb82004-02-01 01:22:50 +00002169 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002170 /* Run just the command that follows the database name
2171 */
drh22fbcb82004-02-01 01:22:50 +00002172 if( zFirstCmd[0]=='.' ){
2173 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002174 exit(0);
2175 }else{
2176 int rc;
drh44c2eb12003-04-30 11:38:26 +00002177 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00002178 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00002179 if( rc!=0 && zErrMsg!=0 ){
2180 fprintf(stderr,"SQL error: %s\n", zErrMsg);
2181 exit(1);
2182 }
drh75897232000-05-29 14:26:00 +00002183 }
2184 }else{
drh44c2eb12003-04-30 11:38:26 +00002185 /* Run commands received from standard input
2186 */
drhc28490c2006-10-26 14:25:58 +00002187 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002188 char *zHome;
2189 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002190 int nHistory;
drh75897232000-05-29 14:26:00 +00002191 printf(
drhb217a572000-08-22 13:40:18 +00002192 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002193 "Enter \".help\" for instructions\n"
2194 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002195 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002196 );
drh67505e72002-04-19 12:34:06 +00002197 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002198 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002199 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002200 if( (zHistory = malloc(nHistory))!=0 ){
2201 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2202 }
drh67505e72002-04-19 12:34:06 +00002203 }
danielk19774af00c62005-01-23 23:43:21 +00002204#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002205 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002206#endif
drhc28490c2006-10-26 14:25:58 +00002207 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002208 if( zHistory ){
2209 stifle_history(100);
2210 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002211 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002212 }
adamd0a3daa32006-07-28 20:16:14 +00002213 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002214 }else{
drhc28490c2006-10-26 14:25:58 +00002215 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002216 }
2217 }
drh33048c02001-10-01 14:29:22 +00002218 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002219 if( db ){
2220 if( sqlite3_close(db)!=SQLITE_OK ){
2221 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2222 }
2223 }
drhc28490c2006-10-26 14:25:58 +00002224 return rc;
drh75897232000-05-29 14:26:00 +00002225}