blob: c472b21acda35600efbbe91aa88ffaeb10828e9b [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**
drh8f800a72009-01-14 23:17:55 +000015** $Id: shell.c,v 1.197 2009/01/14 23:17:55 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 );
drh902b9ee2008-12-05 17:17:07 +0000230 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000231 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
232}
233
234
235/*
drhfeac5f82004-08-01 00:10:45 +0000236** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000237** the text in memory obtained from malloc() and returns a pointer
238** to the text. NULL is returned at end of file, or if malloc()
239** fails.
240**
241** The interface is like "readline" but no command-line editing
242** is done.
243*/
drh9347b202003-07-18 01:30:59 +0000244static char *local_getline(char *zPrompt, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000245 char *zLine;
246 int nLine;
drh8e7e7a22000-05-30 18:45:23 +0000247 int n;
248 int eol;
249
250 if( zPrompt && *zPrompt ){
251 printf("%s",zPrompt);
252 fflush(stdout);
253 }
254 nLine = 100;
255 zLine = malloc( nLine );
256 if( zLine==0 ) return 0;
257 n = 0;
258 eol = 0;
259 while( !eol ){
260 if( n+100>nLine ){
261 nLine = nLine*2 + 100;
262 zLine = realloc(zLine, nLine);
263 if( zLine==0 ) return 0;
264 }
drhdaffd0e2001-04-11 14:28:42 +0000265 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000266 if( n==0 ){
267 free(zLine);
268 return 0;
269 }
270 zLine[n] = 0;
271 eol = 1;
272 break;
273 }
274 while( zLine[n] ){ n++; }
275 if( n>0 && zLine[n-1]=='\n' ){
276 n--;
277 zLine[n] = 0;
278 eol = 1;
279 }
280 }
281 zLine = realloc( zLine, n+1 );
282 return zLine;
283}
284
285/*
drhc28490c2006-10-26 14:25:58 +0000286** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000287**
288** zPrior is a string of prior text retrieved. If not the empty
289** string, then issue a continuation prompt.
290*/
drhdaffd0e2001-04-11 14:28:42 +0000291static char *one_input_line(const char *zPrior, FILE *in){
drh8e7e7a22000-05-30 18:45:23 +0000292 char *zPrompt;
293 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000294 if( in!=0 ){
drh9347b202003-07-18 01:30:59 +0000295 return local_getline(0, in);
drh8e7e7a22000-05-30 18:45:23 +0000296 }
297 if( zPrior && zPrior[0] ){
persicom7e2dfdd2002-04-18 02:46:52 +0000298 zPrompt = continuePrompt;
drh8e7e7a22000-05-30 18:45:23 +0000299 }else{
persicom7e2dfdd2002-04-18 02:46:52 +0000300 zPrompt = mainPrompt;
drh8e7e7a22000-05-30 18:45:23 +0000301 }
302 zResult = readline(zPrompt);
danielk19774af00c62005-01-23 23:43:21 +0000303#if defined(HAVE_READLINE) && HAVE_READLINE==1
drheb741d52006-06-03 17:37:25 +0000304 if( zResult && *zResult ) add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000305#endif
drh8e7e7a22000-05-30 18:45:23 +0000306 return zResult;
307}
308
persicom7e2dfdd2002-04-18 02:46:52 +0000309struct previous_mode_data {
310 int valid; /* Is there legit data in here? */
311 int mode;
312 int showHeader;
313 int colWidth[100];
314};
drh45e29d82006-11-20 16:21:10 +0000315
drh8e7e7a22000-05-30 18:45:23 +0000316/*
drh75897232000-05-29 14:26:00 +0000317** An pointer to an instance of this structure is passed from
318** the main program to the callback. This is used to communicate
319** state and mode information.
320*/
321struct callback_data {
danielk197792f9a1b2004-06-19 09:08:16 +0000322 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000323 int echoOn; /* True to echo input commands */
drh28bd4bc2000-06-15 15:57:22 +0000324 int cnt; /* Number of records displayed so far */
325 FILE *out; /* Write results here */
326 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000327 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000328 int showHeader; /* True to show column names in List or Column mode */
drh33048c02001-10-01 14:29:22 +0000329 char *zDestTable; /* Name of destination table when MODE_Insert */
drh28bd4bc2000-06-15 15:57:22 +0000330 char separator[20]; /* Separator character for MODE_List */
drha0c66f52000-07-29 13:20:21 +0000331 int colWidth[100]; /* Requested width of each column when in column mode*/
332 int actualWidth[100]; /* Actual width of each column */
drh83965662003-04-17 02:54:13 +0000333 char nullvalue[20]; /* The text to print when a NULL comes back from
334 ** the database */
persicom7e2dfdd2002-04-18 02:46:52 +0000335 struct previous_mode_data explainPrev;
drh83965662003-04-17 02:54:13 +0000336 /* Holds the mode information just before
337 ** .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000338 char outfile[FILENAME_MAX]; /* Filename for *out */
339 const char *zDbFilename; /* name of the database file */
drh75897232000-05-29 14:26:00 +0000340};
341
342/*
343** These are the allowed modes.
344*/
drh967e8b72000-06-21 13:59:10 +0000345#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000346#define MODE_Column 1 /* One record per line in neat columns */
347#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000348#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
349#define MODE_Html 4 /* Generate an XHTML table */
350#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000351#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000352#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000353#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
persicom7e2dfdd2002-04-18 02:46:52 +0000354
drh66ce4d02008-02-15 17:38:06 +0000355static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000356 "line",
357 "column",
358 "list",
359 "semi",
360 "html",
drhfeac5f82004-08-01 00:10:45 +0000361 "insert",
362 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000363 "csv",
drh66ce4d02008-02-15 17:38:06 +0000364 "explain",
persicom7e2dfdd2002-04-18 02:46:52 +0000365};
drh75897232000-05-29 14:26:00 +0000366
367/*
368** Number of elements in an array
369*/
drh902b9ee2008-12-05 17:17:07 +0000370#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000371
372/*
drhea678832008-12-10 19:26:22 +0000373** Compute a string length that is limited to what can be stored in
374** lower 30 bits of a 32-bit signed integer.
375*/
drh4f21c4a2008-12-10 22:15:00 +0000376static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000377 const char *z2 = z;
378 while( *z2 ){ z2++; }
379 return 0x3fffffff & (int)(z2 - z);
380}
381
382/*
drh28bd4bc2000-06-15 15:57:22 +0000383** Output the given string as a quoted string using SQL quoting conventions.
384*/
385static void output_quoted_string(FILE *out, const char *z){
386 int i;
387 int nSingle = 0;
drh28bd4bc2000-06-15 15:57:22 +0000388 for(i=0; z[i]; i++){
389 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000390 }
391 if( nSingle==0 ){
392 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000393 }else{
394 fprintf(out,"'");
395 while( *z ){
396 for(i=0; z[i] && z[i]!='\''; i++){}
397 if( i==0 ){
398 fprintf(out,"''");
399 z++;
400 }else if( z[i]=='\'' ){
401 fprintf(out,"%.*s''",i,z);
402 z += i+1;
403 }else{
drhcd7d2732002-02-26 23:24:26 +0000404 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000405 break;
406 }
407 }
drhcd7d2732002-02-26 23:24:26 +0000408 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000409 }
410}
411
412/*
drhfeac5f82004-08-01 00:10:45 +0000413** Output the given string as a quoted according to C or TCL quoting rules.
414*/
415static void output_c_string(FILE *out, const char *z){
416 unsigned int c;
417 fputc('"', out);
418 while( (c = *(z++))!=0 ){
419 if( c=='\\' ){
420 fputc(c, out);
421 fputc(c, out);
422 }else if( c=='\t' ){
423 fputc('\\', out);
424 fputc('t', out);
425 }else if( c=='\n' ){
426 fputc('\\', out);
427 fputc('n', out);
428 }else if( c=='\r' ){
429 fputc('\\', out);
430 fputc('r', out);
431 }else if( !isprint(c) ){
drh0a8640d2005-08-30 20:12:02 +0000432 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000433 }else{
434 fputc(c, out);
435 }
436 }
437 fputc('"', out);
438}
439
440/*
drhc08a4f12000-06-15 16:49:48 +0000441** Output the given string with characters that are special to
442** HTML escaped.
443*/
444static void output_html_string(FILE *out, const char *z){
445 int i;
446 while( *z ){
447 for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
448 if( i>0 ){
449 fprintf(out,"%.*s",i,z);
450 }
451 if( z[i]=='<' ){
452 fprintf(out,"&lt;");
453 }else if( z[i]=='&' ){
454 fprintf(out,"&amp;");
455 }else{
456 break;
457 }
458 z += i + 1;
459 }
460}
461
462/*
drhc49f44e2006-10-26 18:15:42 +0000463** If a field contains any character identified by a 1 in the following
464** array, then the string must be quoted for CSV.
465*/
466static const char needCsvQuote[] = {
467 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
468 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
469 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
470 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,
475 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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};
484
485/*
drh8e64d1c2004-10-07 00:32:39 +0000486** Output a single term of CSV. Actually, p->separator is used for
487** the separator, which may or may not be a comma. p->nullvalue is
488** the null value. Strings are quoted using ANSI-C rules. Numbers
489** appear outside of quotes.
490*/
491static void output_csv(struct callback_data *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000492 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000493 if( z==0 ){
drhc49f44e2006-10-26 18:15:42 +0000494 fprintf(out,"%s",p->nullvalue);
drh8e64d1c2004-10-07 00:32:39 +0000495 }else{
drhc49f44e2006-10-26 18:15:42 +0000496 int i;
drh4f21c4a2008-12-10 22:15:00 +0000497 int nSep = strlen30(p->separator);
drhc49f44e2006-10-26 18:15:42 +0000498 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000499 if( needCsvQuote[((unsigned char*)z)[i]]
500 || (z[i]==p->separator[0] &&
501 (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000502 i = 0;
503 break;
504 }
505 }
506 if( i==0 ){
507 putc('"', out);
508 for(i=0; z[i]; i++){
509 if( z[i]=='"' ) putc('"', out);
510 putc(z[i], out);
511 }
512 putc('"', out);
513 }else{
514 fprintf(out, "%s", z);
515 }
drh8e64d1c2004-10-07 00:32:39 +0000516 }
517 if( bSep ){
drhd0e77882008-01-14 15:20:08 +0000518 fprintf(p->out, "%s", p->separator);
drh8e64d1c2004-10-07 00:32:39 +0000519 }
520}
521
danielk19774af00c62005-01-23 23:43:21 +0000522#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000523/*
drh4c504392000-10-16 22:06:40 +0000524** This routine runs when the user presses Ctrl-C
525*/
526static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000527 UNUSED_PARAMETER(NotUsed);
drh67505e72002-04-19 12:34:06 +0000528 seenInterrupt = 1;
danielk19776f8a5032004-05-10 10:34:51 +0000529 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000530}
danielk19774af00c62005-01-23 23:43:21 +0000531#endif
drh4c504392000-10-16 22:06:40 +0000532
533/*
drh75897232000-05-29 14:26:00 +0000534** This is the callback routine that the SQLite library
535** invokes for each row of a query result.
536*/
537static int callback(void *pArg, int nArg, char **azArg, char **azCol){
538 int i;
539 struct callback_data *p = (struct callback_data*)pArg;
540 switch( p->mode ){
541 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000542 int w = 5;
drh6a535342001-10-19 16:44:56 +0000543 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000544 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000545 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000546 if( len>w ) w = len;
547 }
drh75897232000-05-29 14:26:00 +0000548 if( p->cnt++>0 ) fprintf(p->out,"\n");
549 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000550 fprintf(p->out,"%*s = %s\n", w, azCol[i],
drha69d9162003-04-17 22:57:53 +0000551 azArg[i] ? azArg[i] : p->nullvalue);
drh75897232000-05-29 14:26:00 +0000552 }
553 break;
554 }
danielk19770d78bae2008-01-03 07:09:48 +0000555 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000556 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000557 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000558 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000559 int w, n;
560 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000561 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000562 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000563 w = 0;
drh75897232000-05-29 14:26:00 +0000564 }
drha0c66f52000-07-29 13:20:21 +0000565 if( w<=0 ){
drh4f21c4a2008-12-10 22:15:00 +0000566 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000567 if( w<10 ) w = 10;
drh4f21c4a2008-12-10 22:15:00 +0000568 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
drha0c66f52000-07-29 13:20:21 +0000569 if( w<n ) w = n;
570 }
571 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000572 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000573 }
574 if( p->showHeader ){
575 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
576 }
577 }
578 if( p->showHeader ){
579 for(i=0; i<nArg; i++){
580 int w;
581 if( i<ArraySize(p->actualWidth) ){
582 w = p->actualWidth[i];
583 }else{
584 w = 10;
585 }
586 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
587 "----------------------------------------------------------",
588 i==nArg-1 ? "\n": " ");
589 }
drh75897232000-05-29 14:26:00 +0000590 }
591 }
drh6a535342001-10-19 16:44:56 +0000592 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000593 for(i=0; i<nArg; i++){
594 int w;
drha0c66f52000-07-29 13:20:21 +0000595 if( i<ArraySize(p->actualWidth) ){
596 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000597 }else{
598 w = 10;
599 }
drhea678832008-12-10 19:26:22 +0000600 if( p->mode==MODE_Explain && azArg[i] &&
drh4f21c4a2008-12-10 22:15:00 +0000601 strlen30(azArg[i])>w ){
602 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000603 }
drhc61053b2000-06-04 12:58:36 +0000604 fprintf(p->out,"%-*.*s%s",w,w,
persicom7e2dfdd2002-04-18 02:46:52 +0000605 azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000606 }
607 break;
608 }
drhe3710332000-09-29 13:30:53 +0000609 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000610 case MODE_List: {
611 if( p->cnt++==0 && p->showHeader ){
612 for(i=0; i<nArg; i++){
613 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
614 }
615 }
drh6a535342001-10-19 16:44:56 +0000616 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000617 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000618 char *z = azArg[i];
persicom7e2dfdd2002-04-18 02:46:52 +0000619 if( z==0 ) z = p->nullvalue;
drh71172c52002-01-24 00:00:21 +0000620 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000621 if( i<nArg-1 ){
622 fprintf(p->out, "%s", p->separator);
623 }else if( p->mode==MODE_Semi ){
624 fprintf(p->out, ";\n");
625 }else{
626 fprintf(p->out, "\n");
627 }
drh75897232000-05-29 14:26:00 +0000628 }
629 break;
630 }
drh1e5d0e92000-05-31 23:33:17 +0000631 case MODE_Html: {
632 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000633 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000634 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000635 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
drh1e5d0e92000-05-31 23:33:17 +0000636 }
mihailim57c591a2008-06-23 21:26:05 +0000637 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000638 }
drh6a535342001-10-19 16:44:56 +0000639 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000640 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000641 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000642 fprintf(p->out,"<TD>");
persicom7e2dfdd2002-04-18 02:46:52 +0000643 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
mihailim57c591a2008-06-23 21:26:05 +0000644 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000645 }
mihailim57c591a2008-06-23 21:26:05 +0000646 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000647 break;
648 }
drhfeac5f82004-08-01 00:10:45 +0000649 case MODE_Tcl: {
650 if( p->cnt++==0 && p->showHeader ){
651 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000652 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhfeac5f82004-08-01 00:10:45 +0000653 fprintf(p->out, "%s", p->separator);
654 }
655 fprintf(p->out,"\n");
656 }
657 if( azArg==0 ) break;
658 for(i=0; i<nArg; i++){
659 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
660 fprintf(p->out, "%s", p->separator);
661 }
662 fprintf(p->out,"\n");
663 break;
664 }
drh8e64d1c2004-10-07 00:32:39 +0000665 case MODE_Csv: {
666 if( p->cnt++==0 && p->showHeader ){
667 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000668 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000669 }
670 fprintf(p->out,"\n");
671 }
672 if( azArg==0 ) break;
673 for(i=0; i<nArg; i++){
674 output_csv(p, azArg[i], i<nArg-1);
675 }
676 fprintf(p->out,"\n");
677 break;
678 }
drh28bd4bc2000-06-15 15:57:22 +0000679 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +0000680 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000681 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000682 for(i=0; i<nArg; i++){
683 char *zSep = i>0 ? ",": "";
684 if( azArg[i]==0 ){
685 fprintf(p->out,"%sNULL",zSep);
drhc8d74412004-08-31 23:41:26 +0000686 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000687 fprintf(p->out,"%s%s",zSep, azArg[i]);
688 }else{
689 if( zSep[0] ) fprintf(p->out,"%s",zSep);
690 output_quoted_string(p->out, azArg[i]);
691 }
692 }
693 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000694 break;
drh28bd4bc2000-06-15 15:57:22 +0000695 }
persicom1d0b8722002-04-18 02:53:04 +0000696 }
drh75897232000-05-29 14:26:00 +0000697 return 0;
698}
699
700/*
drh33048c02001-10-01 14:29:22 +0000701** Set the destination table field of the callback_data structure to
702** the name of the table given. Escape any quote characters in the
703** table name.
704*/
705static void set_table_name(struct callback_data *p, const char *zName){
706 int i, n;
707 int needQuote;
708 char *z;
709
710 if( p->zDestTable ){
711 free(p->zDestTable);
712 p->zDestTable = 0;
713 }
714 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +0000715 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +0000716 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +0000717 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +0000718 needQuote = 1;
719 if( zName[i]=='\'' ) n++;
720 }
721 }
722 if( needQuote ) n += 2;
723 z = p->zDestTable = malloc( n+1 );
724 if( z==0 ){
725 fprintf(stderr,"Out of memory!\n");
726 exit(1);
727 }
728 n = 0;
729 if( needQuote ) z[n++] = '\'';
730 for(i=0; zName[i]; i++){
731 z[n++] = zName[i];
732 if( zName[i]=='\'' ) z[n++] = '\'';
733 }
734 if( needQuote ) z[n++] = '\'';
735 z[n] = 0;
736}
737
danielk19772a02e332004-06-05 08:04:36 +0000738/* zIn is either a pointer to a NULL-terminated string in memory obtained
739** from malloc(), or a NULL pointer. The string pointed to by zAppend is
740** added to zIn, and the result returned in memory obtained from malloc().
741** zIn, if it was not NULL, is freed.
742**
743** If the third argument, quote, is not '\0', then it is used as a
744** quote character for zAppend.
745*/
drhc28490c2006-10-26 14:25:58 +0000746static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +0000747 int len;
748 int i;
drh4f21c4a2008-12-10 22:15:00 +0000749 int nAppend = strlen30(zAppend);
750 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +0000751
752 len = nAppend+nIn+1;
753 if( quote ){
754 len += 2;
755 for(i=0; i<nAppend; i++){
756 if( zAppend[i]==quote ) len++;
757 }
758 }
759
760 zIn = (char *)realloc(zIn, len);
761 if( !zIn ){
762 return 0;
763 }
764
765 if( quote ){
766 char *zCsr = &zIn[nIn];
767 *zCsr++ = quote;
768 for(i=0; i<nAppend; i++){
769 *zCsr++ = zAppend[i];
770 if( zAppend[i]==quote ) *zCsr++ = quote;
771 }
772 *zCsr++ = quote;
773 *zCsr++ = '\0';
774 assert( (zCsr-zIn)==len );
775 }else{
776 memcpy(&zIn[nIn], zAppend, nAppend);
777 zIn[len-1] = '\0';
778 }
779
780 return zIn;
781}
782
drhdd3d4592004-08-30 01:54:05 +0000783
784/*
785** Execute a query statement that has a single result column. Print
786** that result column on a line by itself with a semicolon terminator.
drh45e29d82006-11-20 16:21:10 +0000787**
788** This is used, for example, to show the schema of the database by
789** querying the SQLITE_MASTER table.
drhdd3d4592004-08-30 01:54:05 +0000790*/
791static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
792 sqlite3_stmt *pSelect;
793 int rc;
794 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
795 if( rc!=SQLITE_OK || !pSelect ){
796 return rc;
797 }
798 rc = sqlite3_step(pSelect);
799 while( rc==SQLITE_ROW ){
800 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
801 rc = sqlite3_step(pSelect);
802 }
803 return sqlite3_finalize(pSelect);
804}
805
806
drh33048c02001-10-01 14:29:22 +0000807/*
drh4c653a02000-06-07 01:27:47 +0000808** This is a different callback routine used for dumping the database.
809** Each row received by this callback consists of a table name,
810** the table type ("index" or "table") and SQL to create the table.
811** This routine should print text sufficient to recreate the table.
812*/
813static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +0000814 int rc;
815 const char *zTable;
816 const char *zType;
817 const char *zSql;
drhdaffd0e2001-04-11 14:28:42 +0000818 struct callback_data *p = (struct callback_data *)pArg;
danielk19772a02e332004-06-05 08:04:36 +0000819
drh902b9ee2008-12-05 17:17:07 +0000820 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +0000821 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +0000822 zTable = azArg[0];
823 zType = azArg[1];
824 zSql = azArg[2];
825
drh00b950d2005-09-11 02:03:03 +0000826 if( strcmp(zTable, "sqlite_sequence")==0 ){
drhf8eb96a2005-02-03 00:42:34 +0000827 fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
drh00b950d2005-09-11 02:03:03 +0000828 }else if( strcmp(zTable, "sqlite_stat1")==0 ){
829 fprintf(p->out, "ANALYZE sqlite_master;\n");
830 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
831 return 0;
drh45e29d82006-11-20 16:21:10 +0000832 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
833 char *zIns;
834 if( !p->writableSchema ){
835 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
836 p->writableSchema = 1;
837 }
838 zIns = sqlite3_mprintf(
839 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
840 "VALUES('table','%q','%q',0,'%q');",
841 zTable, zTable, zSql);
842 fprintf(p->out, "%s\n", zIns);
843 sqlite3_free(zIns);
844 return 0;
drh00b950d2005-09-11 02:03:03 +0000845 }else{
846 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +0000847 }
danielk19772a02e332004-06-05 08:04:36 +0000848
849 if( strcmp(zType, "table")==0 ){
850 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +0000851 char *zSelect = 0;
852 char *zTableInfo = 0;
853 char *zTmp = 0;
854
855 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
856 zTableInfo = appendText(zTableInfo, zTable, '"');
857 zTableInfo = appendText(zTableInfo, ");", 0);
858
859 rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
860 if( zTableInfo ) free(zTableInfo);
861 if( rc!=SQLITE_OK || !pTableInfo ){
862 return 1;
863 }
864
865 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
866 zTmp = appendText(zTmp, zTable, '"');
867 if( zTmp ){
868 zSelect = appendText(zSelect, zTmp, '\'');
869 }
870 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
871 rc = sqlite3_step(pTableInfo);
872 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +0000873 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +0000874 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +0000875 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +0000876 rc = sqlite3_step(pTableInfo);
877 if( rc==SQLITE_ROW ){
drh45e29d82006-11-20 16:21:10 +0000878 zSelect = appendText(zSelect, ") || ',' || ", 0);
danielk19772a02e332004-06-05 08:04:36 +0000879 }else{
880 zSelect = appendText(zSelect, ") ", 0);
881 }
882 }
883 rc = sqlite3_finalize(pTableInfo);
884 if( rc!=SQLITE_OK ){
885 if( zSelect ) free(zSelect);
886 return 1;
887 }
888 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
889 zSelect = appendText(zSelect, zTable, '"');
890
drhdd3d4592004-08-30 01:54:05 +0000891 rc = run_table_dump_query(p->out, p->db, zSelect);
892 if( rc==SQLITE_CORRUPT ){
893 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
894 rc = run_table_dump_query(p->out, p->db, zSelect);
895 }
danielk19772a02e332004-06-05 08:04:36 +0000896 if( zSelect ) free(zSelect);
drh4c653a02000-06-07 01:27:47 +0000897 }
drh4c653a02000-06-07 01:27:47 +0000898 return 0;
899}
900
901/*
drh45e29d82006-11-20 16:21:10 +0000902** Run zQuery. Use dump_callback() as the callback routine so that
903** the contents of the query are output as SQL statements.
904**
drhdd3d4592004-08-30 01:54:05 +0000905** If we get a SQLITE_CORRUPT error, rerun the query after appending
906** "ORDER BY rowid DESC" to the end.
907*/
908static int run_schema_dump_query(
909 struct callback_data *p,
910 const char *zQuery,
911 char **pzErrMsg
912){
913 int rc;
914 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
915 if( rc==SQLITE_CORRUPT ){
916 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +0000917 int len = strlen30(zQuery);
drhdd3d4592004-08-30 01:54:05 +0000918 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
919 zQ2 = malloc( len+100 );
920 if( zQ2==0 ) return rc;
drh5bb3eb92007-05-04 13:15:55 +0000921 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
drhdd3d4592004-08-30 01:54:05 +0000922 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
923 free(zQ2);
924 }
925 return rc;
926}
927
928/*
drh75897232000-05-29 14:26:00 +0000929** Text of a help message
930*/
persicom1d0b8722002-04-18 02:53:04 +0000931static char zHelp[] =
drh20f99c42007-01-08 14:31:35 +0000932 ".bail ON|OFF Stop after hitting an error. Default OFF\n"
jplyon6a65bb32003-05-04 07:25:57 +0000933 ".databases List names and files of attached databases\n"
drhb860bc92004-08-04 15:16:55 +0000934 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
drhdaffd0e2001-04-11 14:28:42 +0000935 ".echo ON|OFF Turn command echo on or off\n"
drh75897232000-05-29 14:26:00 +0000936 ".exit Exit this program\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000937 ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000938 ".header(s) ON|OFF Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +0000939 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +0000940 ".import FILE TABLE Import data from FILE into TABLE\n"
drh75897232000-05-29 14:26:00 +0000941 ".indices TABLE Show names of all indices on TABLE\n"
drhae5e4452007-05-03 17:18:36 +0000942#ifdef SQLITE_ENABLE_IOTRACE
943 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
944#endif
drh70df4fe2006-06-13 15:12:21 +0000945#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +0000946 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +0000947#endif
danielk19776b77a362005-01-13 11:10:25 +0000948 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
drh3b584fa2004-09-24 12:50:03 +0000949 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +0000950 " column Left-aligned columns. (See .width)\n"
951 " html HTML <table> code\n"
952 " insert SQL insert statements for TABLE\n"
953 " line One value per line\n"
954 " list Values delimited by .separator string\n"
955 " tabs Tab-separated values\n"
956 " tcl TCL list elements\n"
957 ".nullvalue STRING Print STRING in place of NULL values\n"
drh75897232000-05-29 14:26:00 +0000958 ".output FILENAME Send output to FILENAME\n"
959 ".output stdout Send output to the screen\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000960 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +0000961 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +0000962 ".read FILENAME Execute SQL in FILENAME\n"
drh75897232000-05-29 14:26:00 +0000963 ".schema ?TABLE? Show the CREATE statements\n"
drhb860bc92004-08-04 15:16:55 +0000964 ".separator STRING Change separator used by output mode and .import\n"
drhdd45df82002-04-18 12:39:03 +0000965 ".show Show the current values for various settings\n"
drhfeac5f82004-08-01 00:10:45 +0000966 ".tables ?PATTERN? List names of tables matching a LIKE pattern\n"
drh2dfbbca2000-07-28 14:32:48 +0000967 ".timeout MS Try opening locked tables for MS milliseconds\n"
drh3b1a9882007-11-02 12:53:03 +0000968#if HAS_TIMER
969 ".timer ON|OFF Turn the CPU timer measurement on or off\n"
970#endif
drh75897232000-05-29 14:26:00 +0000971 ".width NUM NUM ... Set column widths for \"column\" mode\n"
972;
973
drhdaffd0e2001-04-11 14:28:42 +0000974/* Forward reference */
drhc28490c2006-10-26 14:25:58 +0000975static int process_input(struct callback_data *p, FILE *in);
drhdaffd0e2001-04-11 14:28:42 +0000976
drh75897232000-05-29 14:26:00 +0000977/*
drh44c2eb12003-04-30 11:38:26 +0000978** Make sure the database is open. If it is not, then open it. If
979** the database fails to open, print an error message and exit.
980*/
981static void open_db(struct callback_data *p){
982 if( p->db==0 ){
danielk19774f057f92004-06-08 00:02:33 +0000983 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +0000984 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +0000985 if( db && sqlite3_errcode(db)==SQLITE_OK ){
986 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
987 shellstaticFunc, 0, 0);
988 }
989 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
danielk197780290862004-05-22 09:21:21 +0000990 fprintf(stderr,"Unable to open database \"%s\": %s\n",
991 p->zDbFilename, sqlite3_errmsg(db));
drh22fbcb82004-02-01 01:22:50 +0000992 exit(1);
drh44c2eb12003-04-30 11:38:26 +0000993 }
drhc2e87a32006-06-27 15:16:14 +0000994#ifndef SQLITE_OMIT_LOAD_EXTENSION
995 sqlite3_enable_load_extension(p->db, 1);
996#endif
drh44c2eb12003-04-30 11:38:26 +0000997 }
998}
999
1000/*
drhfeac5f82004-08-01 00:10:45 +00001001** Do C-language style dequoting.
1002**
1003** \t -> tab
1004** \n -> newline
1005** \r -> carriage return
1006** \NNN -> ascii character NNN in octal
1007** \\ -> backslash
1008*/
1009static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001010 int i, j;
1011 char c;
drhfeac5f82004-08-01 00:10:45 +00001012 for(i=j=0; (c = z[i])!=0; i++, j++){
1013 if( c=='\\' ){
1014 c = z[++i];
1015 if( c=='n' ){
1016 c = '\n';
1017 }else if( c=='t' ){
1018 c = '\t';
1019 }else if( c=='r' ){
1020 c = '\r';
1021 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001022 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001023 if( z[i+1]>='0' && z[i+1]<='7' ){
1024 i++;
1025 c = (c<<3) + z[i] - '0';
1026 if( z[i+1]>='0' && z[i+1]<='7' ){
1027 i++;
1028 c = (c<<3) + z[i] - '0';
1029 }
1030 }
1031 }
1032 }
1033 z[j] = c;
1034 }
1035 z[j] = 0;
1036}
1037
1038/*
drhc28490c2006-10-26 14:25:58 +00001039** Interpret zArg as a boolean value. Return either 0 or 1.
1040*/
1041static int booleanValue(char *zArg){
1042 int val = atoi(zArg);
1043 int j;
1044 for(j=0; zArg[j]; j++){
shane7d3846a2008-12-11 02:58:26 +00001045 zArg[j] = (char)tolower(zArg[j]);
drhc28490c2006-10-26 14:25:58 +00001046 }
1047 if( strcmp(zArg,"on")==0 ){
1048 val = 1;
1049 }else if( strcmp(zArg,"yes")==0 ){
1050 val = 1;
1051 }
1052 return val;
1053}
1054
1055/*
drh75897232000-05-29 14:26:00 +00001056** If an input line begins with "." then invoke this routine to
1057** process that line.
drh67505e72002-04-19 12:34:06 +00001058**
drh47ad6842006-11-08 12:25:42 +00001059** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00001060*/
drh44c2eb12003-04-30 11:38:26 +00001061static int do_meta_command(char *zLine, struct callback_data *p){
drh75897232000-05-29 14:26:00 +00001062 int i = 1;
1063 int nArg = 0;
1064 int n, c;
drh67505e72002-04-19 12:34:06 +00001065 int rc = 0;
drh75897232000-05-29 14:26:00 +00001066 char *azArg[50];
1067
1068 /* Parse the input line into tokens.
1069 */
1070 while( zLine[i] && nArg<ArraySize(azArg) ){
drh4c755c02004-08-08 20:22:17 +00001071 while( isspace((unsigned char)zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00001072 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00001073 if( zLine[i]=='\'' || zLine[i]=='"' ){
1074 int delim = zLine[i++];
1075 azArg[nArg++] = &zLine[i];
1076 while( zLine[i] && zLine[i]!=delim ){ i++; }
1077 if( zLine[i]==delim ){
1078 zLine[i++] = 0;
1079 }
drhfeac5f82004-08-01 00:10:45 +00001080 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001081 }else{
1082 azArg[nArg++] = &zLine[i];
drh4c755c02004-08-08 20:22:17 +00001083 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00001084 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00001085 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00001086 }
1087 }
1088
1089 /* Process the input line.
1090 */
drh67505e72002-04-19 12:34:06 +00001091 if( nArg==0 ) return rc;
drh4f21c4a2008-12-10 22:15:00 +00001092 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00001093 c = azArg[0][0];
drhc49f44e2006-10-26 18:15:42 +00001094 if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){
1095 bail_on_error = booleanValue(azArg[1]);
1096 }else
1097
jplyon6a65bb32003-05-04 07:25:57 +00001098 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
jplyon672a1ed2003-05-11 20:07:05 +00001099 struct callback_data data;
1100 char *zErrMsg = 0;
jplyon6a65bb32003-05-04 07:25:57 +00001101 open_db(p);
jplyon672a1ed2003-05-11 20:07:05 +00001102 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00001103 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00001104 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00001105 data.colWidth[0] = 3;
1106 data.colWidth[1] = 15;
1107 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00001108 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00001109 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00001110 if( zErrMsg ){
1111 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001112 sqlite3_free(zErrMsg);
jplyon6a65bb32003-05-04 07:25:57 +00001113 }
1114 }else
1115
drh4c653a02000-06-07 01:27:47 +00001116 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1117 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001118 open_db(p);
drh33048c02001-10-01 14:29:22 +00001119 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00001120 p->writableSchema = 0;
drh93f41e52008-08-11 19:12:34 +00001121 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001122 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00001123 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001124 "SELECT name, type, sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001125 "WHERE sql NOT NULL AND type=='table'", 0
drh0b9a5942006-09-13 20:22:02 +00001126 );
1127 run_table_dump_query(p->out, p->db,
1128 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001129 "WHERE sql NOT NULL AND type IN ('index','trigger','view')"
drha18c5682000-10-08 22:20:57 +00001130 );
drh4c653a02000-06-07 01:27:47 +00001131 }else{
1132 int i;
drhdd3d4592004-08-30 01:54:05 +00001133 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00001134 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00001135 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00001136 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00001137 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh45e29d82006-11-20 16:21:10 +00001138 " AND sql NOT NULL", 0);
drh0b9a5942006-09-13 20:22:02 +00001139 run_table_dump_query(p->out, p->db,
1140 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00001141 "WHERE sql NOT NULL"
1142 " AND type IN ('index','trigger','view')"
drh0b9a5942006-09-13 20:22:02 +00001143 " AND tbl_name LIKE shellstatic()"
1144 );
danielk1977bc6ada42004-06-30 08:20:16 +00001145 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00001146 }
1147 }
drh45e29d82006-11-20 16:21:10 +00001148 if( p->writableSchema ){
1149 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1150 p->writableSchema = 0;
1151 }
drh93f41e52008-08-11 19:12:34 +00001152 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
drh4c653a02000-06-07 01:27:47 +00001153 if( zErrMsg ){
1154 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001155 sqlite3_free(zErrMsg);
drh33048c02001-10-01 14:29:22 +00001156 }else{
1157 fprintf(p->out, "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00001158 }
1159 }else
drh75897232000-05-29 14:26:00 +00001160
drhdaffd0e2001-04-11 14:28:42 +00001161 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001162 p->echoOn = booleanValue(azArg[1]);
drhdaffd0e2001-04-11 14:28:42 +00001163 }else
1164
drh75897232000-05-29 14:26:00 +00001165 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001166 rc = 2;
drh75897232000-05-29 14:26:00 +00001167 }else
1168
drhdd45df82002-04-18 12:39:03 +00001169 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00001170 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00001171 if(val == 1) {
1172 if(!p->explainPrev.valid) {
1173 p->explainPrev.valid = 1;
1174 p->explainPrev.mode = p->mode;
1175 p->explainPrev.showHeader = p->showHeader;
1176 memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
1177 }
1178 /* We could put this code under the !p->explainValid
1179 ** condition so that it does not execute if we are already in
1180 ** explain mode. However, always executing it allows us an easy
1181 ** was to reset to explain mode in case the user previously
1182 ** did an .explain followed by a .width, .mode or .header
1183 ** command.
1184 */
danielk19770d78bae2008-01-03 07:09:48 +00001185 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00001186 p->showHeader = 1;
1187 memset(p->colWidth,0,ArraySize(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00001188 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00001189 p->colWidth[1] = 13; /* opcode */
1190 p->colWidth[2] = 4; /* P1 */
1191 p->colWidth[3] = 4; /* P2 */
1192 p->colWidth[4] = 4; /* P3 */
1193 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00001194 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00001195 p->colWidth[7] = 13; /* Comment */
persicom7e2dfdd2002-04-18 02:46:52 +00001196 }else if (p->explainPrev.valid) {
1197 p->explainPrev.valid = 0;
1198 p->mode = p->explainPrev.mode;
1199 p->showHeader = p->explainPrev.showHeader;
1200 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
1201 }
drh75897232000-05-29 14:26:00 +00001202 }else
1203
drhc28490c2006-10-26 14:25:58 +00001204 if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
persicom7e2dfdd2002-04-18 02:46:52 +00001205 strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
drhc28490c2006-10-26 14:25:58 +00001206 p->showHeader = booleanValue(azArg[1]);
drh75897232000-05-29 14:26:00 +00001207 }else
1208
1209 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1210 fprintf(stderr,zHelp);
1211 }else
1212
drhfeac5f82004-08-01 00:10:45 +00001213 if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
1214 char *zTable = azArg[2]; /* Insert data into this table */
1215 char *zFile = azArg[1]; /* The file from which to extract data */
1216 sqlite3_stmt *pStmt; /* A statement */
1217 int rc; /* Result code */
1218 int nCol; /* Number of columns in the table */
1219 int nByte; /* Number of bytes in an SQL string */
1220 int i, j; /* Loop counters */
1221 int nSep; /* Number of bytes in p->separator[] */
1222 char *zSql; /* An SQL statement */
1223 char *zLine; /* A single line of input from the file */
1224 char **azCol; /* zLine[] broken up into columns */
1225 char *zCommit; /* How to commit changes */
drhb860bc92004-08-04 15:16:55 +00001226 FILE *in; /* The input file */
1227 int lineno = 0; /* Line number of input file */
drhfeac5f82004-08-01 00:10:45 +00001228
drha543c822006-06-08 16:10:14 +00001229 open_db(p);
drh4f21c4a2008-12-10 22:15:00 +00001230 nSep = strlen30(p->separator);
drhfeac5f82004-08-01 00:10:45 +00001231 if( nSep==0 ){
1232 fprintf(stderr, "non-null separator required for import\n");
1233 return 0;
1234 }
1235 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1236 if( zSql==0 ) return 0;
drh4f21c4a2008-12-10 22:15:00 +00001237 nByte = strlen30(zSql);
drh5e6078b2006-01-31 19:07:22 +00001238 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001239 sqlite3_free(zSql);
1240 if( rc ){
1241 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1242 nCol = 0;
drh47ad6842006-11-08 12:25:42 +00001243 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001244 }else{
1245 nCol = sqlite3_column_count(pStmt);
1246 }
1247 sqlite3_finalize(pStmt);
1248 if( nCol==0 ) return 0;
1249 zSql = malloc( nByte + 20 + nCol*2 );
1250 if( zSql==0 ) return 0;
1251 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00001252 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00001253 for(i=1; i<nCol; i++){
1254 zSql[j++] = ',';
1255 zSql[j++] = '?';
1256 }
1257 zSql[j++] = ')';
1258 zSql[j] = 0;
drh5e6078b2006-01-31 19:07:22 +00001259 rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
drhfeac5f82004-08-01 00:10:45 +00001260 free(zSql);
1261 if( rc ){
1262 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
1263 sqlite3_finalize(pStmt);
drh47ad6842006-11-08 12:25:42 +00001264 return 1;
drhfeac5f82004-08-01 00:10:45 +00001265 }
1266 in = fopen(zFile, "rb");
1267 if( in==0 ){
1268 fprintf(stderr, "cannot open file: %s\n", zFile);
1269 sqlite3_finalize(pStmt);
1270 return 0;
1271 }
1272 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
drh43617e92006-03-06 20:55:46 +00001273 if( azCol==0 ){
1274 fclose(in);
1275 return 0;
1276 }
drhfeac5f82004-08-01 00:10:45 +00001277 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1278 zCommit = "COMMIT";
1279 while( (zLine = local_getline(0, in))!=0 ){
1280 char *z;
1281 i = 0;
drhb860bc92004-08-04 15:16:55 +00001282 lineno++;
drhfeac5f82004-08-01 00:10:45 +00001283 azCol[0] = zLine;
drh36d4e972004-10-06 14:39:06 +00001284 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
drhfeac5f82004-08-01 00:10:45 +00001285 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1286 *z = 0;
1287 i++;
drhb860bc92004-08-04 15:16:55 +00001288 if( i<nCol ){
1289 azCol[i] = &z[nSep];
1290 z += nSep-1;
1291 }
drhfeac5f82004-08-01 00:10:45 +00001292 }
1293 }
drh1cd7f832005-08-05 18:50:51 +00001294 *z = 0;
drhb860bc92004-08-04 15:16:55 +00001295 if( i+1!=nCol ){
1296 fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
1297 zFile, lineno, nCol, i+1);
1298 zCommit = "ROLLBACK";
drh1822eee2008-12-04 12:26:00 +00001299 free(zLine);
drhb860bc92004-08-04 15:16:55 +00001300 break;
1301 }
drhfeac5f82004-08-01 00:10:45 +00001302 for(i=0; i<nCol; i++){
1303 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1304 }
1305 sqlite3_step(pStmt);
1306 rc = sqlite3_reset(pStmt);
1307 free(zLine);
1308 if( rc!=SQLITE_OK ){
1309 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1310 zCommit = "ROLLBACK";
drh47ad6842006-11-08 12:25:42 +00001311 rc = 1;
drhfeac5f82004-08-01 00:10:45 +00001312 break;
1313 }
1314 }
1315 free(azCol);
1316 fclose(in);
1317 sqlite3_finalize(pStmt);
drhb860bc92004-08-04 15:16:55 +00001318 sqlite3_exec(p->db, zCommit, 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00001319 }else
1320
drh75897232000-05-29 14:26:00 +00001321 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
1322 struct callback_data data;
1323 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001324 open_db(p);
drh75897232000-05-29 14:26:00 +00001325 memcpy(&data, p, sizeof(data));
1326 data.showHeader = 0;
1327 data.mode = MODE_List;
danielk1977bc6ada42004-06-30 08:20:16 +00001328 zShellStatic = azArg[1];
1329 sqlite3_exec(p->db,
drha18c5682000-10-08 22:20:57 +00001330 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001331 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001332 "UNION ALL "
1333 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001334 "WHERE type='index' AND tbl_name LIKE shellstatic() "
drhe0bc4042002-06-25 01:09:11 +00001335 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001336 callback, &data, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001337 );
danielk1977bc6ada42004-06-30 08:20:16 +00001338 zShellStatic = 0;
drh75897232000-05-29 14:26:00 +00001339 if( zErrMsg ){
1340 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001341 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001342 }
1343 }else
1344
drhae5e4452007-05-03 17:18:36 +00001345#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00001346 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001347 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00001348 if( iotrace && iotrace!=stdout ) fclose(iotrace);
1349 iotrace = 0;
1350 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00001351 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001352 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00001353 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001354 iotrace = stdout;
1355 }else{
1356 iotrace = fopen(azArg[1], "w");
1357 if( iotrace==0 ){
1358 fprintf(stderr, "cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00001359 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00001360 }else{
mlcreech3a00f902008-03-04 17:45:01 +00001361 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00001362 }
1363 }
1364 }else
drhae5e4452007-05-03 17:18:36 +00001365#endif
drhb0603412007-02-28 04:47:26 +00001366
drh70df4fe2006-06-13 15:12:21 +00001367#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001368 if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
1369 const char *zFile, *zProc;
1370 char *zErrMsg = 0;
1371 int rc;
1372 zFile = azArg[1];
1373 zProc = nArg>=3 ? azArg[2] : 0;
1374 open_db(p);
1375 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
1376 if( rc!=SQLITE_OK ){
1377 fprintf(stderr, "%s\n", zErrMsg);
1378 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00001379 rc = 1;
drh1e397f82006-06-08 15:28:43 +00001380 }
1381 }else
drh70df4fe2006-06-13 15:12:21 +00001382#endif
drh1e397f82006-06-08 15:28:43 +00001383
drh28bd4bc2000-06-15 15:57:22 +00001384 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh4f21c4a2008-12-10 22:15:00 +00001385 int n2 = strlen30(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001386 if( strncmp(azArg[1],"line",n2)==0
1387 ||
1388 strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001389 p->mode = MODE_Line;
persicom7e2dfdd2002-04-18 02:46:52 +00001390 }else if( strncmp(azArg[1],"column",n2)==0
1391 ||
1392 strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00001393 p->mode = MODE_Column;
1394 }else if( strncmp(azArg[1],"list",n2)==0 ){
1395 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +00001396 }else if( strncmp(azArg[1],"html",n2)==0 ){
1397 p->mode = MODE_Html;
drhfeac5f82004-08-01 00:10:45 +00001398 }else if( strncmp(azArg[1],"tcl",n2)==0 ){
1399 p->mode = MODE_Tcl;
1400 }else if( strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00001401 p->mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00001402 sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
drhfeac5f82004-08-01 00:10:45 +00001403 }else if( strncmp(azArg[1],"tabs",n2)==0 ){
1404 p->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001405 sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
drh28bd4bc2000-06-15 15:57:22 +00001406 }else if( strncmp(azArg[1],"insert",n2)==0 ){
1407 p->mode = MODE_Insert;
1408 if( nArg>=3 ){
drh33048c02001-10-01 14:29:22 +00001409 set_table_name(p, azArg[2]);
drh28bd4bc2000-06-15 15:57:22 +00001410 }else{
drh33048c02001-10-01 14:29:22 +00001411 set_table_name(p, "table");
drh28bd4bc2000-06-15 15:57:22 +00001412 }
drhdaffd0e2001-04-11 14:28:42 +00001413 }else {
drhcf68ae92006-12-19 18:47:41 +00001414 fprintf(stderr,"mode should be one of: "
drhfeac5f82004-08-01 00:10:45 +00001415 "column csv html insert line list tabs tcl\n");
drh75897232000-05-29 14:26:00 +00001416 }
1417 }else
1418
persicom7e2dfdd2002-04-18 02:46:52 +00001419 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
drh5bb3eb92007-05-04 13:15:55 +00001420 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
1421 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00001422 }else
1423
drh75897232000-05-29 14:26:00 +00001424 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
1425 if( p->out!=stdout ){
1426 fclose(p->out);
1427 }
1428 if( strcmp(azArg[1],"stdout")==0 ){
1429 p->out = stdout;
drh5bb3eb92007-05-04 13:15:55 +00001430 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout");
drh75897232000-05-29 14:26:00 +00001431 }else{
drha1f9b5e2004-02-14 16:31:02 +00001432 p->out = fopen(azArg[1], "wb");
drh75897232000-05-29 14:26:00 +00001433 if( p->out==0 ){
1434 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
1435 p->out = stdout;
persicom7e2dfdd2002-04-18 02:46:52 +00001436 } else {
drh5bb3eb92007-05-04 13:15:55 +00001437 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
drh75897232000-05-29 14:26:00 +00001438 }
1439 }
1440 }else
1441
drhdd45df82002-04-18 12:39:03 +00001442 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
persicom7e2dfdd2002-04-18 02:46:52 +00001443 if( nArg >= 2) {
1444 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
1445 }
1446 if( nArg >= 3) {
1447 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
1448 }
1449 }else
1450
1451 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00001452 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00001453 }else
1454
drhdaffd0e2001-04-11 14:28:42 +00001455 if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
drha1f9b5e2004-02-14 16:31:02 +00001456 FILE *alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00001457 if( alt==0 ){
1458 fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
1459 }else{
1460 process_input(p, alt);
1461 fclose(alt);
1462 }
1463 }else
1464
drh75897232000-05-29 14:26:00 +00001465 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1466 struct callback_data data;
1467 char *zErrMsg = 0;
drh44c2eb12003-04-30 11:38:26 +00001468 open_db(p);
drh75897232000-05-29 14:26:00 +00001469 memcpy(&data, p, sizeof(data));
1470 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00001471 data.mode = MODE_Semi;
drh75897232000-05-29 14:26:00 +00001472 if( nArg>1 ){
drhc8d74412004-08-31 23:41:26 +00001473 int i;
shane7d3846a2008-12-11 02:58:26 +00001474 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00001475 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00001476 char *new_argv[2], *new_colv[2];
1477 new_argv[0] = "CREATE TABLE sqlite_master (\n"
1478 " type text,\n"
1479 " name text,\n"
1480 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00001481 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00001482 " sql text\n"
1483 ")";
1484 new_argv[1] = 0;
1485 new_colv[0] = "sql";
1486 new_colv[1] = 0;
1487 callback(&data, 1, new_argv, new_colv);
drhc8d74412004-08-31 23:41:26 +00001488 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00001489 char *new_argv[2], *new_colv[2];
1490 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
1491 " type text,\n"
1492 " name text,\n"
1493 " tbl_name text,\n"
1494 " rootpage integer,\n"
1495 " sql text\n"
1496 ")";
1497 new_argv[1] = 0;
1498 new_colv[0] = "sql";
1499 new_colv[1] = 0;
1500 callback(&data, 1, new_argv, new_colv);
drha18c5682000-10-08 22:20:57 +00001501 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001502 zShellStatic = azArg[1];
1503 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001504 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00001505 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
1506 " FROM sqlite_master UNION ALL"
1507 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
danielk1977bc6ada42004-06-30 08:20:16 +00001508 "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
drhe0bc4042002-06-25 01:09:11 +00001509 "ORDER BY substr(type,2,1), name",
danielk1977bc6ada42004-06-30 08:20:16 +00001510 callback, &data, &zErrMsg);
1511 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00001512 }
drh75897232000-05-29 14:26:00 +00001513 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001514 sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00001515 "SELECT sql FROM "
drh8f800a72009-01-14 23:17:55 +00001516 " (SELECT sql sql, type type, tbl_name tbl_name, name name"
1517 " FROM sqlite_master UNION ALL"
1518 " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
drh0c356672005-09-10 22:40:53 +00001519 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001520 "ORDER BY substr(type,2,1), name",
drha18c5682000-10-08 22:20:57 +00001521 callback, &data, &zErrMsg
1522 );
drh75897232000-05-29 14:26:00 +00001523 }
drh75897232000-05-29 14:26:00 +00001524 if( zErrMsg ){
1525 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001526 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001527 }
1528 }else
1529
1530 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
drh5bb3eb92007-05-04 13:15:55 +00001531 sqlite3_snprintf(sizeof(p->separator), p->separator,
1532 "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
drh75897232000-05-29 14:26:00 +00001533 }else
1534
persicom7e2dfdd2002-04-18 02:46:52 +00001535 if( c=='s' && strncmp(azArg[0], "show", n)==0){
1536 int i;
1537 fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
drh67505e72002-04-19 12:34:06 +00001538 fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
drhdd45df82002-04-18 12:39:03 +00001539 fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
persicom7e2dfdd2002-04-18 02:46:52 +00001540 fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
drhfeac5f82004-08-01 00:10:45 +00001541 fprintf(p->out,"%9.9s: ", "nullvalue");
1542 output_c_string(p->out, p->nullvalue);
1543 fprintf(p->out, "\n");
drh67505e72002-04-19 12:34:06 +00001544 fprintf(p->out,"%9.9s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00001545 strlen30(p->outfile) ? p->outfile : "stdout");
drhfeac5f82004-08-01 00:10:45 +00001546 fprintf(p->out,"%9.9s: ", "separator");
1547 output_c_string(p->out, p->separator);
1548 fprintf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001549 fprintf(p->out,"%9.9s: ","width");
1550 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00001551 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00001552 }
drhfeac5f82004-08-01 00:10:45 +00001553 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00001554 }else
1555
drh2dfbbca2000-07-28 14:32:48 +00001556 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drhe3710332000-09-29 13:30:53 +00001557 char **azResult;
1558 int nRow, rc;
1559 char *zErrMsg;
drh44c2eb12003-04-30 11:38:26 +00001560 open_db(p);
drha50da102000-08-08 20:19:09 +00001561 if( nArg==1 ){
danielk19776f8a5032004-05-10 10:34:51 +00001562 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001563 "SELECT name FROM sqlite_master "
drh0c356672005-09-10 22:40:53 +00001564 "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
drhe0bc4042002-06-25 01:09:11 +00001565 "UNION ALL "
1566 "SELECT name FROM sqlite_temp_master "
1567 "WHERE type IN ('table','view') "
1568 "ORDER BY 1",
drha18c5682000-10-08 22:20:57 +00001569 &azResult, &nRow, 0, &zErrMsg
1570 );
drha50da102000-08-08 20:19:09 +00001571 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00001572 zShellStatic = azArg[1];
1573 rc = sqlite3_get_table(p->db,
drha50da102000-08-08 20:19:09 +00001574 "SELECT name FROM sqlite_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001575 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001576 "UNION ALL "
1577 "SELECT name FROM sqlite_temp_master "
danielk1977bc6ada42004-06-30 08:20:16 +00001578 "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
drhe0bc4042002-06-25 01:09:11 +00001579 "ORDER BY 1",
danielk1977bc6ada42004-06-30 08:20:16 +00001580 &azResult, &nRow, 0, &zErrMsg
drha18c5682000-10-08 22:20:57 +00001581 );
danielk1977bc6ada42004-06-30 08:20:16 +00001582 zShellStatic = 0;
drha50da102000-08-08 20:19:09 +00001583 }
drh75897232000-05-29 14:26:00 +00001584 if( zErrMsg ){
1585 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001586 sqlite3_free(zErrMsg);
drh75897232000-05-29 14:26:00 +00001587 }
drhe3710332000-09-29 13:30:53 +00001588 if( rc==SQLITE_OK ){
1589 int len, maxlen = 0;
1590 int i, j;
1591 int nPrintCol, nPrintRow;
1592 for(i=1; i<=nRow; i++){
1593 if( azResult[i]==0 ) continue;
drh4f21c4a2008-12-10 22:15:00 +00001594 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00001595 if( len>maxlen ) maxlen = len;
1596 }
1597 nPrintCol = 80/(maxlen+2);
1598 if( nPrintCol<1 ) nPrintCol = 1;
1599 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
1600 for(i=0; i<nPrintRow; i++){
1601 for(j=i+1; j<=nRow; j+=nPrintRow){
1602 char *zSp = j<=nPrintRow ? "" : " ";
1603 printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1604 }
1605 printf("\n");
1606 }
drh47ad6842006-11-08 12:25:42 +00001607 }else{
1608 rc = 1;
drhe3710332000-09-29 13:30:53 +00001609 }
danielk19776f8a5032004-05-10 10:34:51 +00001610 sqlite3_free_table(azResult);
drh75897232000-05-29 14:26:00 +00001611 }else
1612
drh3b1a9882007-11-02 12:53:03 +00001613 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
drh44c2eb12003-04-30 11:38:26 +00001614 open_db(p);
danielk19776f8a5032004-05-10 10:34:51 +00001615 sqlite3_busy_timeout(p->db, atoi(azArg[1]));
drh2dfbbca2000-07-28 14:32:48 +00001616 }else
drh3b1a9882007-11-02 12:53:03 +00001617
1618#if HAS_TIMER
1619 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){
1620 enableTimer = booleanValue(azArg[1]);
1621 }else
1622#endif
drh2dfbbca2000-07-28 14:32:48 +00001623
drh75897232000-05-29 14:26:00 +00001624 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1625 int j;
drh43617e92006-03-06 20:55:46 +00001626 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00001627 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1628 p->colWidth[j-1] = atoi(azArg[j]);
1629 }
1630 }else
1631
drh3b1a9882007-11-02 12:53:03 +00001632
drh75897232000-05-29 14:26:00 +00001633 {
drh67505e72002-04-19 12:34:06 +00001634 fprintf(stderr, "unknown command or invalid arguments: "
1635 " \"%s\". Enter \".help\" for help\n", azArg[0]);
drh75897232000-05-29 14:26:00 +00001636 }
drh67505e72002-04-19 12:34:06 +00001637
1638 return rc;
drh75897232000-05-29 14:26:00 +00001639}
1640
drh67505e72002-04-19 12:34:06 +00001641/*
drh91a66392007-09-07 01:12:32 +00001642** Return TRUE if a semicolon occurs anywhere in the first N characters
1643** of string z[].
drh324ccef2003-02-05 14:06:20 +00001644*/
drh91a66392007-09-07 01:12:32 +00001645static int _contains_semicolon(const char *z, int N){
1646 int i;
1647 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
1648 return 0;
drh324ccef2003-02-05 14:06:20 +00001649}
1650
1651/*
drh70c7a4b2003-04-26 03:03:06 +00001652** Test to see if a line consists entirely of whitespace.
1653*/
1654static int _all_whitespace(const char *z){
1655 for(; *z; z++){
drh4c755c02004-08-08 20:22:17 +00001656 if( isspace(*(unsigned char*)z) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00001657 if( *z=='/' && z[1]=='*' ){
1658 z += 2;
1659 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
1660 if( *z==0 ) return 0;
1661 z++;
1662 continue;
1663 }
1664 if( *z=='-' && z[1]=='-' ){
1665 z += 2;
1666 while( *z && *z!='\n' ){ z++; }
1667 if( *z==0 ) return 1;
1668 continue;
1669 }
1670 return 0;
1671 }
1672 return 1;
1673}
1674
1675/*
drha9b17162003-04-29 18:01:28 +00001676** Return TRUE if the line typed in is an SQL command terminator other
1677** than a semi-colon. The SQL Server style "go" command is understood
1678** as is the Oracle "/".
1679*/
1680static int _is_command_terminator(const char *zLine){
drh4c755c02004-08-08 20:22:17 +00001681 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00001682 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
1683 return 1; /* Oracle */
1684 }
drhc8d74412004-08-31 23:41:26 +00001685 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
1686 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00001687 return 1; /* SQL Server */
1688 }
1689 return 0;
1690}
1691
1692/*
drh233a5312008-12-18 22:25:13 +00001693** Return true if zSql is a complete SQL statement. Return false if it
1694** ends in the middle of a string literal or C-style comment.
1695*/
1696static int _is_complete(char *zSql, int nSql){
1697 int rc;
1698 if( zSql==0 ) return 1;
1699 zSql[nSql] = ';';
1700 zSql[nSql+1] = 0;
1701 rc = sqlite3_complete(zSql);
1702 zSql[nSql] = 0;
1703 return rc;
1704}
1705
1706/*
drh67505e72002-04-19 12:34:06 +00001707** Read input from *in and process it. If *in==0 then input
1708** is interactive - the user is typing it it. Otherwise, input
1709** is coming from a file or device. A prompt is issued and history
1710** is saved only if input is interactive. An interrupt signal will
1711** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00001712**
1713** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00001714*/
drhc28490c2006-10-26 14:25:58 +00001715static int process_input(struct callback_data *p, FILE *in){
danielk19772ac27622007-07-03 05:31:16 +00001716 char *zLine = 0;
drhdaffd0e2001-04-11 14:28:42 +00001717 char *zSql = 0;
1718 int nSql = 0;
drh91a66392007-09-07 01:12:32 +00001719 int nSqlPrior = 0;
drhdaffd0e2001-04-11 14:28:42 +00001720 char *zErrMsg;
drhc49f44e2006-10-26 18:15:42 +00001721 int rc;
1722 int errCnt = 0;
drhc28490c2006-10-26 14:25:58 +00001723 int lineno = 0;
1724 int startline = 0;
drhc49f44e2006-10-26 18:15:42 +00001725
1726 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
1727 fflush(p->out);
danielk19772ac27622007-07-03 05:31:16 +00001728 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001729 zLine = one_input_line(zSql, in);
1730 if( zLine==0 ){
1731 break; /* We have reached EOF */
1732 }
drh67505e72002-04-19 12:34:06 +00001733 if( seenInterrupt ){
1734 if( in!=0 ) break;
1735 seenInterrupt = 0;
1736 }
drhc28490c2006-10-26 14:25:58 +00001737 lineno++;
drhdaffd0e2001-04-11 14:28:42 +00001738 if( p->echoOn ) printf("%s\n", zLine);
drhf817b6b2003-06-16 00:16:41 +00001739 if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
drh2af0b2d2002-02-21 02:25:02 +00001740 if( zLine && zLine[0]=='.' && nSql==0 ){
drhc49f44e2006-10-26 18:15:42 +00001741 rc = do_meta_command(zLine, p);
drh47ad6842006-11-08 12:25:42 +00001742 if( rc==2 ){
1743 break;
1744 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00001745 errCnt++;
1746 }
drhdaffd0e2001-04-11 14:28:42 +00001747 continue;
1748 }
drh233a5312008-12-18 22:25:13 +00001749 if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00001750 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00001751 }
drh91a66392007-09-07 01:12:32 +00001752 nSqlPrior = nSql;
drhdaffd0e2001-04-11 14:28:42 +00001753 if( zSql==0 ){
1754 int i;
drh4c755c02004-08-08 20:22:17 +00001755 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
drhdaffd0e2001-04-11 14:28:42 +00001756 if( zLine[i]!=0 ){
drh4f21c4a2008-12-10 22:15:00 +00001757 nSql = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00001758 zSql = malloc( nSql+3 );
drhc1f44942006-05-10 14:39:13 +00001759 if( zSql==0 ){
1760 fprintf(stderr, "out of memory\n");
1761 exit(1);
1762 }
drh5bb3eb92007-05-04 13:15:55 +00001763 memcpy(zSql, zLine, nSql+1);
drhc28490c2006-10-26 14:25:58 +00001764 startline = lineno;
drhdaffd0e2001-04-11 14:28:42 +00001765 }
1766 }else{
drh4f21c4a2008-12-10 22:15:00 +00001767 int len = strlen30(zLine);
drh233a5312008-12-18 22:25:13 +00001768 zSql = realloc( zSql, nSql + len + 4 );
drhdaffd0e2001-04-11 14:28:42 +00001769 if( zSql==0 ){
1770 fprintf(stderr,"%s: out of memory!\n", Argv0);
1771 exit(1);
1772 }
drh5bb3eb92007-05-04 13:15:55 +00001773 zSql[nSql++] = '\n';
1774 memcpy(&zSql[nSql], zLine, len+1);
drhdaffd0e2001-04-11 14:28:42 +00001775 nSql += len;
1776 }
drh91a66392007-09-07 01:12:32 +00001777 if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1778 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00001779 p->cnt = 0;
drh44c2eb12003-04-30 11:38:26 +00001780 open_db(p);
drh3b1a9882007-11-02 12:53:03 +00001781 BEGIN_TIMER;
danielk19776f8a5032004-05-10 10:34:51 +00001782 rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00001783 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00001784 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00001785 char zPrefix[100];
1786 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00001787 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
1788 "SQL error near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00001789 }else{
drh5bb3eb92007-05-04 13:15:55 +00001790 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:");
drhc28490c2006-10-26 14:25:58 +00001791 }
drh7f953e22002-07-13 17:33:45 +00001792 if( zErrMsg!=0 ){
drhc28490c2006-10-26 14:25:58 +00001793 printf("%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00001794 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00001795 zErrMsg = 0;
1796 }else{
drhc28490c2006-10-26 14:25:58 +00001797 printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00001798 }
drhc49f44e2006-10-26 18:15:42 +00001799 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00001800 }
1801 free(zSql);
1802 zSql = 0;
1803 nSql = 0;
1804 }
1805 }
1806 if( zSql ){
drhdfef4992008-11-11 18:55:03 +00001807 if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql);
drhdaffd0e2001-04-11 14:28:42 +00001808 free(zSql);
1809 }
danielk19772ac27622007-07-03 05:31:16 +00001810 free(zLine);
drhc49f44e2006-10-26 18:15:42 +00001811 return errCnt;
drhdaffd0e2001-04-11 14:28:42 +00001812}
1813
drh67505e72002-04-19 12:34:06 +00001814/*
1815** Return a pathname which is the user's home directory. A
1816** 0 return indicates an error of some kind. Space to hold the
1817** resulting string is obtained from malloc(). The calling
1818** function should free the result.
1819*/
1820static char *find_home_dir(void){
1821 char *home_dir = NULL;
persicom7e2dfdd2002-04-18 02:46:52 +00001822
chw97185482008-11-17 08:05:31 +00001823#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
drh67505e72002-04-19 12:34:06 +00001824 struct passwd *pwent;
1825 uid_t uid = getuid();
drhbd842ba2002-08-21 11:26:41 +00001826 if( (pwent=getpwuid(uid)) != NULL) {
1827 home_dir = pwent->pw_dir;
drh67505e72002-04-19 12:34:06 +00001828 }
1829#endif
1830
chw65d3c132007-11-12 21:09:10 +00001831#if defined(_WIN32_WCE)
1832 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
1833 */
1834 home_dir = strdup("/");
1835#else
1836
drh164a1b62006-08-19 11:15:20 +00001837#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
1838 if (!home_dir) {
1839 home_dir = getenv("USERPROFILE");
1840 }
1841#endif
1842
drh67505e72002-04-19 12:34:06 +00001843 if (!home_dir) {
1844 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00001845 }
1846
drhcdb36b72006-06-12 12:57:45 +00001847#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
drhe98d4fa2002-04-21 19:06:22 +00001848 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00001849 char *zDrive, *zPath;
1850 int n;
1851 zDrive = getenv("HOMEDRIVE");
1852 zPath = getenv("HOMEPATH");
1853 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00001854 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00001855 home_dir = malloc( n );
1856 if( home_dir==0 ) return 0;
1857 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
1858 return home_dir;
1859 }
1860 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00001861 }
1862#endif
1863
chw65d3c132007-11-12 21:09:10 +00001864#endif /* !_WIN32_WCE */
1865
drh67505e72002-04-19 12:34:06 +00001866 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00001867 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00001868 char *z = malloc( n );
1869 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00001870 home_dir = z;
1871 }
drhe98d4fa2002-04-21 19:06:22 +00001872
drh67505e72002-04-19 12:34:06 +00001873 return home_dir;
1874}
1875
1876/*
1877** Read input from the file given by sqliterc_override. Or if that
1878** parameter is NULL, take input from ~/.sqliterc
1879*/
drh22fbcb82004-02-01 01:22:50 +00001880static void process_sqliterc(
1881 struct callback_data *p, /* Configuration data */
1882 const char *sqliterc_override /* Name of config file. NULL to use default */
1883){
persicom7e2dfdd2002-04-18 02:46:52 +00001884 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00001885 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00001886 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00001887 FILE *in = NULL;
drha959ac42007-06-20 13:10:00 +00001888 int nBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001889
1890 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00001891 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00001892 if( home_dir==0 ){
chw97185482008-11-17 08:05:31 +00001893#if !defined(__RTP__) && !defined(_WRS_KERNEL)
drhe98d4fa2002-04-21 19:06:22 +00001894 fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
chw97185482008-11-17 08:05:31 +00001895#endif
drhe98d4fa2002-04-21 19:06:22 +00001896 return;
1897 }
drh4f21c4a2008-12-10 22:15:00 +00001898 nBuf = strlen30(home_dir) + 16;
drha959ac42007-06-20 13:10:00 +00001899 zBuf = malloc( nBuf );
drh22fbcb82004-02-01 01:22:50 +00001900 if( zBuf==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00001901 fprintf(stderr,"%s: out of memory!\n", Argv0);
1902 exit(1);
1903 }
drha959ac42007-06-20 13:10:00 +00001904 sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir);
drh67505e72002-04-19 12:34:06 +00001905 free(home_dir);
drh22fbcb82004-02-01 01:22:50 +00001906 sqliterc = (const char*)zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00001907 }
drha1f9b5e2004-02-14 16:31:02 +00001908 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00001909 if( in ){
drhc28490c2006-10-26 14:25:58 +00001910 if( stdin_is_interactive ){
drhb695aca2007-07-30 20:41:52 +00001911 printf("-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00001912 }
persicom7e2dfdd2002-04-18 02:46:52 +00001913 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00001914 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00001915 }
drh43617e92006-03-06 20:55:46 +00001916 free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00001917 return;
1918}
1919
drh67505e72002-04-19 12:34:06 +00001920/*
drhe1e38c42003-05-04 18:30:59 +00001921** Show available command line options
1922*/
1923static const char zOptions[] =
1924 " -init filename read/process named file\n"
1925 " -echo print commands before execution\n"
1926 " -[no]header turn headers on or off\n"
drhc49f44e2006-10-26 18:15:42 +00001927 " -bail stop after hitting an error\n"
1928 " -interactive force interactive I/O\n"
1929 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00001930 " -column set output mode to 'column'\n"
drhc49f44e2006-10-26 18:15:42 +00001931 " -csv set output mode to 'csv'\n"
drhe1e38c42003-05-04 18:30:59 +00001932 " -html set output mode to HTML\n"
1933 " -line set output mode to 'line'\n"
1934 " -list set output mode to 'list'\n"
1935 " -separator 'x' set output field separator (|)\n"
1936 " -nullvalue 'text' set text string for NULL values\n"
1937 " -version show SQLite version\n"
drhe1e38c42003-05-04 18:30:59 +00001938;
1939static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00001940 fprintf(stderr,
1941 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1942 "FILENAME is the name of an SQLite database. A new database is created\n"
1943 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00001944 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00001945 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00001946 }else{
1947 fprintf(stderr, "Use the -help option for additional information\n");
1948 }
1949 exit(1);
1950}
1951
1952/*
drh67505e72002-04-19 12:34:06 +00001953** Initialize the state information in data
1954*/
drh0850b532006-01-31 19:31:43 +00001955static void main_init(struct callback_data *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00001956 memset(data, 0, sizeof(*data));
1957 data->mode = MODE_List;
drh5bb3eb92007-05-04 13:15:55 +00001958 memcpy(data->separator,"|", 2);
persicom7e2dfdd2002-04-18 02:46:52 +00001959 data->showHeader = 0;
drh5bb3eb92007-05-04 13:15:55 +00001960 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
1961 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00001962}
1963
drh75897232000-05-29 14:26:00 +00001964int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00001965 char *zErrMsg = 0;
1966 struct callback_data data;
drh22fbcb82004-02-01 01:22:50 +00001967 const char *zInitFile = 0;
1968 char *zFirstCmd = 0;
drh44c2eb12003-04-30 11:38:26 +00001969 int i;
drhc28490c2006-10-26 14:25:58 +00001970 int rc = 0;
drh75897232000-05-29 14:26:00 +00001971
drhdaffd0e2001-04-11 14:28:42 +00001972 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00001973 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00001974 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00001975
drh44c2eb12003-04-30 11:38:26 +00001976 /* Make sure we have a valid signal handler early, before anything
1977 ** else is done.
1978 */
drh4c504392000-10-16 22:06:40 +00001979#ifdef SIGINT
1980 signal(SIGINT, interrupt_handler);
1981#endif
drh44c2eb12003-04-30 11:38:26 +00001982
drh22fbcb82004-02-01 01:22:50 +00001983 /* Do an initial pass through the command-line argument to locate
1984 ** the name of the database file, the name of the initialization file,
1985 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00001986 */
drh22fbcb82004-02-01 01:22:50 +00001987 for(i=1; i<argc-1; i++){
drhc28490c2006-10-26 14:25:58 +00001988 char *z;
drh44c2eb12003-04-30 11:38:26 +00001989 if( argv[i][0]!='-' ) break;
drhc28490c2006-10-26 14:25:58 +00001990 z = argv[i];
1991 if( z[0]=='-' && z[1]=='-' ) z++;
drh44c2eb12003-04-30 11:38:26 +00001992 if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1993 i++;
drh22fbcb82004-02-01 01:22:50 +00001994 }else if( strcmp(argv[i],"-init")==0 ){
1995 i++;
1996 zInitFile = argv[i];
drh44c2eb12003-04-30 11:38:26 +00001997 }
1998 }
drh22fbcb82004-02-01 01:22:50 +00001999 if( i<argc ){
danielk197729bafea2008-06-26 10:41:19 +00002000#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
pweilbacherd190be82008-04-15 18:50:02 +00002001 data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
2002#else
drh22fbcb82004-02-01 01:22:50 +00002003 data.zDbFilename = argv[i++];
pweilbacherd190be82008-04-15 18:50:02 +00002004#endif
drh22fbcb82004-02-01 01:22:50 +00002005 }else{
danielk197703aded42004-11-22 05:26:27 +00002006#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00002007 data.zDbFilename = ":memory:";
danielk197703aded42004-11-22 05:26:27 +00002008#else
2009 data.zDbFilename = 0;
2010#endif
drh22fbcb82004-02-01 01:22:50 +00002011 }
2012 if( i<argc ){
2013 zFirstCmd = argv[i++];
2014 }
drh44c2eb12003-04-30 11:38:26 +00002015 data.out = stdout;
2016
drh01b41712005-08-29 23:06:23 +00002017#ifdef SQLITE_OMIT_MEMORYDB
2018 if( data.zDbFilename==0 ){
2019 fprintf(stderr,"%s: no database filename specified\n", argv[0]);
2020 exit(1);
2021 }
2022#endif
2023
drh44c2eb12003-04-30 11:38:26 +00002024 /* Go ahead and open the database file if it already exists. If the
2025 ** file does not exist, delay opening it. This prevents empty database
2026 ** files from being created if a user mistypes the database name argument
2027 ** to the sqlite command-line tool.
2028 */
drhc8d74412004-08-31 23:41:26 +00002029 if( access(data.zDbFilename, 0)==0 ){
drh44c2eb12003-04-30 11:38:26 +00002030 open_db(&data);
2031 }
2032
drh22fbcb82004-02-01 01:22:50 +00002033 /* Process the initialization file if there is one. If no -init option
2034 ** is given on the command line, look for a file named ~/.sqliterc and
2035 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00002036 */
drh22fbcb82004-02-01 01:22:50 +00002037 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00002038
drh22fbcb82004-02-01 01:22:50 +00002039 /* Make a second pass through the command-line argument and set
2040 ** options. This second pass is delayed until after the initialization
2041 ** file is processed so that the command-line arguments will override
2042 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00002043 */
drh22fbcb82004-02-01 01:22:50 +00002044 for(i=1; i<argc && argv[i][0]=='-'; i++){
2045 char *z = argv[i];
drhc28490c2006-10-26 14:25:58 +00002046 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00002047 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00002048 i++;
2049 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002050 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00002051 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002052 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00002053 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002054 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00002055 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00002056 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00002057 }else if( strcmp(z,"-csv")==0 ){
2058 data.mode = MODE_Csv;
drh5bb3eb92007-05-04 13:15:55 +00002059 memcpy(data.separator,",",2);
drh22fbcb82004-02-01 01:22:50 +00002060 }else if( strcmp(z,"-separator")==0 ){
2061 i++;
drh5bb3eb92007-05-04 13:15:55 +00002062 sqlite3_snprintf(sizeof(data.separator), data.separator,
2063 "%.*s",(int)sizeof(data.separator)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002064 }else if( strcmp(z,"-nullvalue")==0 ){
2065 i++;
drh5bb3eb92007-05-04 13:15:55 +00002066 sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
2067 "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
drh22fbcb82004-02-01 01:22:50 +00002068 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002069 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00002070 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00002071 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00002072 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00002073 data.echoOn = 1;
drhc49f44e2006-10-26 18:15:42 +00002074 }else if( strcmp(z,"-bail")==0 ){
2075 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00002076 }else if( strcmp(z,"-version")==0 ){
drhc8d74412004-08-31 23:41:26 +00002077 printf("%s\n", sqlite3_libversion());
drh151e3e12006-06-06 12:32:21 +00002078 return 0;
drhc28490c2006-10-26 14:25:58 +00002079 }else if( strcmp(z,"-interactive")==0 ){
2080 stdin_is_interactive = 1;
2081 }else if( strcmp(z,"-batch")==0 ){
2082 stdin_is_interactive = 0;
drh80e8be92006-08-29 12:04:19 +00002083 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00002084 usage(1);
drh1e5d0e92000-05-31 23:33:17 +00002085 }else{
drh22fbcb82004-02-01 01:22:50 +00002086 fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00002087 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00002088 return 1;
2089 }
2090 }
drh44c2eb12003-04-30 11:38:26 +00002091
drh22fbcb82004-02-01 01:22:50 +00002092 if( zFirstCmd ){
drh44c2eb12003-04-30 11:38:26 +00002093 /* Run just the command that follows the database name
2094 */
drh22fbcb82004-02-01 01:22:50 +00002095 if( zFirstCmd[0]=='.' ){
2096 do_meta_command(zFirstCmd, &data);
drh6ff13852001-11-25 13:18:23 +00002097 exit(0);
2098 }else{
2099 int rc;
drh44c2eb12003-04-30 11:38:26 +00002100 open_db(&data);
danielk19776f8a5032004-05-10 10:34:51 +00002101 rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
drh6ff13852001-11-25 13:18:23 +00002102 if( rc!=0 && zErrMsg!=0 ){
2103 fprintf(stderr,"SQL error: %s\n", zErrMsg);
2104 exit(1);
2105 }
drh75897232000-05-29 14:26:00 +00002106 }
2107 }else{
drh44c2eb12003-04-30 11:38:26 +00002108 /* Run commands received from standard input
2109 */
drhc28490c2006-10-26 14:25:58 +00002110 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00002111 char *zHome;
2112 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00002113 int nHistory;
drh75897232000-05-29 14:26:00 +00002114 printf(
drhb217a572000-08-22 13:40:18 +00002115 "SQLite version %s\n"
mihailim65df9db2008-06-28 11:29:22 +00002116 "Enter \".help\" for instructions\n"
2117 "Enter SQL statements terminated with a \";\"\n",
drhc8d74412004-08-31 23:41:26 +00002118 sqlite3_libversion()
drh75897232000-05-29 14:26:00 +00002119 );
drh67505e72002-04-19 12:34:06 +00002120 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00002121 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00002122 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00002123 if( (zHistory = malloc(nHistory))!=0 ){
2124 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
2125 }
drh67505e72002-04-19 12:34:06 +00002126 }
danielk19774af00c62005-01-23 23:43:21 +00002127#if defined(HAVE_READLINE) && HAVE_READLINE==1
drh67505e72002-04-19 12:34:06 +00002128 if( zHistory ) read_history(zHistory);
danielk19774af00c62005-01-23 23:43:21 +00002129#endif
drhc28490c2006-10-26 14:25:58 +00002130 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00002131 if( zHistory ){
2132 stifle_history(100);
2133 write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00002134 free(zHistory);
drh67505e72002-04-19 12:34:06 +00002135 }
adamd0a3daa32006-07-28 20:16:14 +00002136 free(zHome);
drhdaffd0e2001-04-11 14:28:42 +00002137 }else{
drhc28490c2006-10-26 14:25:58 +00002138 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00002139 }
2140 }
drh33048c02001-10-01 14:29:22 +00002141 set_table_name(&data, 0);
adamd0a3daa32006-07-28 20:16:14 +00002142 if( db ){
2143 if( sqlite3_close(db)!=SQLITE_OK ){
2144 fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db));
2145 }
2146 }
drhc28490c2006-10-26 14:25:58 +00002147 return rc;
drh75897232000-05-29 14:26:00 +00002148}