Annotation of src/usr.bin/sqlite3/shell.c, Revision 1.9
1.1 espie 1: /*
2: ** 2001 September 15
3: **
4: ** The author disclaims copyright to this source code. In place of
5: ** a legal notice, here is a blessing:
6: **
7: ** 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.
10: **
11: *************************************************************************
12: ** This file contains code to implement the "sqlite" command line
13: ** utility for accessing SQLite databases.
14: */
15: #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
16: /* This needs to come before any includes for MSVC compiler */
17: #define _CRT_SECURE_NO_WARNINGS
18: #endif
19:
20: /*
21: ** Enable large-file support for fopen() and friends on unix.
22: */
23: #ifndef SQLITE_DISABLE_LFS
24: # define _LARGE_FILE 1
25: # ifndef _FILE_OFFSET_BITS
26: # define _FILE_OFFSET_BITS 64
27: # endif
28: # define _LARGEFILE_SOURCE 1
29: #endif
30:
31: #include <stdlib.h>
32: #include <string.h>
33: #include <stdio.h>
34: #include <assert.h>
35: #include "sqlite3.h"
36: #include <ctype.h>
37: #include <stdarg.h>
38:
1.4 espie 39: #if !defined(_WIN32) && !defined(WIN32)
1.1 espie 40: # include <signal.h>
41: # if !defined(__RTP__) && !defined(_WRS_KERNEL)
42: # include <pwd.h>
43: # endif
44: # include <unistd.h>
45: # include <sys/types.h>
46: #endif
47:
1.8 jturner 48: #if defined(HAVE_READLINE) && HAVE_READLINE!=0
1.1 espie 49: # include <readline/readline.h>
50: # include <readline/history.h>
1.8 jturner 51: #else
52: # undef HAVE_READLINE
1.1 espie 53: #endif
1.8 jturner 54: #if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE)
55: # define HAVE_READLINE 1
56: # include <editline/readline.h>
57: #endif
58: #if !defined(HAVE_READLINE)
1.1 espie 59: # define add_history(X)
60: # define read_history(X)
61: # define write_history(X)
62: # define stifle_history(X)
63: #endif
64:
65: #if defined(_WIN32) || defined(WIN32)
66: # include <io.h>
1.9 ! jturner 67: # include <fcntl.h>
1.1 espie 68: #define isatty(h) _isatty(h)
1.8 jturner 69: #ifndef access
70: # define access(f,m) _access((f),(m))
71: #endif
1.4 espie 72: #undef popen
1.7 jturner 73: #define popen _popen
1.4 espie 74: #undef pclose
1.7 jturner 75: #define pclose _pclose
1.1 espie 76: #else
77: /* Make sure isatty() has a prototype.
78: */
79: extern int isatty(int);
80:
1.7 jturner 81: /* popen and pclose are not C89 functions and so are sometimes omitted from
82: ** the <stdio.h> header */
1.8 jturner 83: extern FILE *popen(const char*,const char*);
84: extern int pclose(FILE*);
85: #endif
1.7 jturner 86:
1.1 espie 87: #if defined(_WIN32_WCE)
88: /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
89: * thus we always assume that we have a console. That can be
90: * overridden with the -batch command line option.
91: */
92: #define isatty(x) 1
93: #endif
94:
95: /* ctype macros that work with signed characters */
96: #define IsSpace(X) isspace((unsigned char)X)
97: #define IsDigit(X) isdigit((unsigned char)X)
98: #define ToLower(X) (char)tolower((unsigned char)X)
99:
1.8 jturner 100:
101: /* True if the timer is enabled */
102: static int enableTimer = 0;
103:
104: /* Return the current wall-clock time */
105: static sqlite3_int64 timeOfDay(void){
106: static sqlite3_vfs *clockVfs = 0;
107: sqlite3_int64 t;
108: if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
109: if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
110: clockVfs->xCurrentTimeInt64(clockVfs, &t);
111: }else{
112: double r;
113: clockVfs->xCurrentTime(clockVfs, &r);
114: t = (sqlite3_int64)(r*86400000.0);
115: }
116: return t;
117: }
118:
1.6 landry 119: #if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
120: && !defined(__minux)
1.1 espie 121: #include <sys/time.h>
122: #include <sys/resource.h>
123:
124: /* Saved resource information for the beginning of an operation */
1.8 jturner 125: static struct rusage sBegin; /* CPU time at start */
126: static sqlite3_int64 iBegin; /* Wall-clock time at start */
1.1 espie 127:
128: /*
129: ** Begin timing an operation
130: */
131: static void beginTimer(void){
132: if( enableTimer ){
133: getrusage(RUSAGE_SELF, &sBegin);
1.8 jturner 134: iBegin = timeOfDay();
1.1 espie 135: }
136: }
137:
138: /* Return the difference of two time_structs in seconds */
139: static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
140: return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
141: (double)(pEnd->tv_sec - pStart->tv_sec);
142: }
143:
144: /*
145: ** Print the timing results.
146: */
147: static void endTimer(void){
148: if( enableTimer ){
149: struct rusage sEnd;
1.8 jturner 150: sqlite3_int64 iEnd = timeOfDay();
1.1 espie 151: getrusage(RUSAGE_SELF, &sEnd);
1.8 jturner 152: printf("Run Time: real %.3f user %f sys %f\n",
153: (iEnd - iBegin)*0.001,
1.1 espie 154: timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
155: timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
156: }
157: }
158:
159: #define BEGIN_TIMER beginTimer()
160: #define END_TIMER endTimer()
161: #define HAS_TIMER 1
162:
163: #elif (defined(_WIN32) || defined(WIN32))
164:
165: #include <windows.h>
166:
167: /* Saved resource information for the beginning of an operation */
168: static HANDLE hProcess;
169: static FILETIME ftKernelBegin;
170: static FILETIME ftUserBegin;
1.8 jturner 171: static sqlite3_int64 ftWallBegin;
1.1 espie 172: typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
173: static GETPROCTIMES getProcessTimesAddr = NULL;
174:
175: /*
176: ** Check to see if we have timer support. Return 1 if necessary
177: ** support found (or found previously).
178: */
179: static int hasTimer(void){
180: if( getProcessTimesAddr ){
181: return 1;
182: } else {
183: /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions.
184: ** See if the version we are running on has it, and if it does, save off
185: ** a pointer to it and the current process handle.
186: */
187: hProcess = GetCurrentProcess();
188: if( hProcess ){
189: HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
190: if( NULL != hinstLib ){
191: getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
192: if( NULL != getProcessTimesAddr ){
193: return 1;
194: }
195: FreeLibrary(hinstLib);
196: }
197: }
198: }
199: return 0;
200: }
201:
202: /*
203: ** Begin timing an operation
204: */
205: static void beginTimer(void){
206: if( enableTimer && getProcessTimesAddr ){
207: FILETIME ftCreation, ftExit;
208: getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
1.8 jturner 209: ftWallBegin = timeOfDay();
1.1 espie 210: }
211: }
212:
213: /* Return the difference of two FILETIME structs in seconds */
214: static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
215: sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
216: sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
217: return (double) ((i64End - i64Start) / 10000000.0);
218: }
219:
220: /*
221: ** Print the timing results.
222: */
223: static void endTimer(void){
224: if( enableTimer && getProcessTimesAddr){
225: FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
1.8 jturner 226: sqlite3_int64 ftWallEnd = timeOfDay();
1.1 espie 227: getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
1.8 jturner 228: printf("Run Time: real %.3f user %f sys %f\n",
229: (ftWallEnd - ftWallBegin)*0.001,
1.1 espie 230: timeDiff(&ftUserBegin, &ftUserEnd),
231: timeDiff(&ftKernelBegin, &ftKernelEnd));
232: }
233: }
234:
235: #define BEGIN_TIMER beginTimer()
236: #define END_TIMER endTimer()
237: #define HAS_TIMER hasTimer()
238:
239: #else
240: #define BEGIN_TIMER
241: #define END_TIMER
242: #define HAS_TIMER 0
243: #endif
244:
245: /*
246: ** Used to prevent warnings about unused parameters
247: */
248: #define UNUSED_PARAMETER(x) (void)(x)
249:
250: /*
251: ** If the following flag is set, then command execution stops
252: ** at an error if we are not interactive.
253: */
254: static int bail_on_error = 0;
255:
256: /*
257: ** Threat stdin as an interactive input if the following variable
258: ** is true. Otherwise, assume stdin is connected to a file or pipe.
259: */
260: static int stdin_is_interactive = 1;
261:
262: /*
263: ** The following is the open SQLite database. We make a pointer
264: ** to this database a static variable so that it can be accessed
265: ** by the SIGINT handler to interrupt database processing.
266: */
267: static sqlite3 *db = 0;
268:
269: /*
270: ** True if an interrupt (Control-C) has been received.
271: */
272: static volatile int seenInterrupt = 0;
273:
274: /*
275: ** This is the name of our program. It is set in main(), used
276: ** in a number of other places, mostly for error messages.
277: */
278: static char *Argv0;
279:
280: /*
281: ** Prompt strings. Initialized in main. Settable with
282: ** .prompt main continue
283: */
284: static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
285: static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
286:
287: /*
288: ** Write I/O traces to the following stream.
289: */
290: #ifdef SQLITE_ENABLE_IOTRACE
291: static FILE *iotrace = 0;
292: #endif
293:
294: /*
295: ** This routine works like printf in that its first argument is a
296: ** format string and subsequent arguments are values to be substituted
297: ** in place of % fields. The result of formatting this string
298: ** is written to iotrace.
299: */
300: #ifdef SQLITE_ENABLE_IOTRACE
301: static void iotracePrintf(const char *zFormat, ...){
302: va_list ap;
303: char *z;
304: if( iotrace==0 ) return;
305: va_start(ap, zFormat);
306: z = sqlite3_vmprintf(zFormat, ap);
307: va_end(ap);
308: fprintf(iotrace, "%s", z);
309: sqlite3_free(z);
310: }
311: #endif
312:
313:
314: /*
315: ** Determines if a string is a number of not.
316: */
317: static int isNumber(const char *z, int *realnum){
318: if( *z=='-' || *z=='+' ) z++;
319: if( !IsDigit(*z) ){
320: return 0;
321: }
322: z++;
323: if( realnum ) *realnum = 0;
324: while( IsDigit(*z) ){ z++; }
325: if( *z=='.' ){
326: z++;
327: if( !IsDigit(*z) ) return 0;
328: while( IsDigit(*z) ){ z++; }
329: if( realnum ) *realnum = 1;
330: }
331: if( *z=='e' || *z=='E' ){
332: z++;
333: if( *z=='+' || *z=='-' ) z++;
334: if( !IsDigit(*z) ) return 0;
335: while( IsDigit(*z) ){ z++; }
336: if( realnum ) *realnum = 1;
337: }
338: return *z==0;
339: }
340:
341: /*
342: ** A global char* and an SQL function to access its current value
343: ** from within an SQL statement. This program used to use the
344: ** sqlite_exec_printf() API to substitue a string into an SQL statement.
345: ** The correct way to do this with sqlite3 is to use the bind API, but
346: ** since the shell is built around the callback paradigm it would be a lot
347: ** of work. Instead just use this hack, which is quite harmless.
348: */
349: static const char *zShellStatic = 0;
350: static void shellstaticFunc(
351: sqlite3_context *context,
352: int argc,
353: sqlite3_value **argv
354: ){
355: assert( 0==argc );
356: assert( zShellStatic );
357: UNUSED_PARAMETER(argc);
358: UNUSED_PARAMETER(argv);
359: sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
360: }
361:
362:
363: /*
364: ** This routine reads a line of text from FILE in, stores
365: ** the text in memory obtained from malloc() and returns a pointer
366: ** to the text. NULL is returned at end of file, or if malloc()
367: ** fails.
368: **
1.7 jturner 369: ** If zLine is not NULL then it is a malloced buffer returned from
370: ** a previous call to this routine that may be reused.
1.1 espie 371: */
1.7 jturner 372: static char *local_getline(char *zLine, FILE *in){
373: int nLine = zLine==0 ? 0 : 100;
374: int n = 0;
1.1 espie 375:
376: while( 1 ){
377: if( n+100>nLine ){
378: nLine = nLine*2 + 100;
379: zLine = realloc(zLine, nLine);
380: if( zLine==0 ) return 0;
381: }
382: if( fgets(&zLine[n], nLine - n, in)==0 ){
383: if( n==0 ){
384: free(zLine);
385: return 0;
386: }
387: zLine[n] = 0;
388: break;
389: }
1.7 jturner 390: while( zLine[n] ) n++;
391: if( n>0 && zLine[n-1]=='\n' ){
1.1 espie 392: n--;
393: if( n>0 && zLine[n-1]=='\r' ) n--;
394: zLine[n] = 0;
395: break;
396: }
397: }
398: return zLine;
399: }
400:
401: /*
402: ** Retrieve a single line of input text.
403: **
1.7 jturner 404: ** If in==0 then read from standard input and prompt before each line.
405: ** If isContinuation is true, then a continuation prompt is appropriate.
406: ** If isContinuation is zero, then the main prompt should be used.
407: **
408: ** If zPrior is not NULL then it is a buffer from a prior call to this
409: ** routine that can be reused.
410: **
411: ** The result is stored in space obtained from malloc() and must either
412: ** be freed by the caller or else passed back into this routine via the
413: ** zPrior argument for reuse.
1.1 espie 414: */
1.7 jturner 415: static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
1.1 espie 416: char *zPrompt;
417: char *zResult;
418: if( in!=0 ){
1.7 jturner 419: zResult = local_getline(zPrior, in);
1.1 espie 420: }else{
1.7 jturner 421: zPrompt = isContinuation ? continuePrompt : mainPrompt;
1.8 jturner 422: #if defined(HAVE_READLINE)
1.7 jturner 423: free(zPrior);
424: zResult = readline(zPrompt);
425: if( zResult && *zResult ) add_history(zResult);
426: #else
427: printf("%s", zPrompt);
428: fflush(stdout);
429: zResult = local_getline(zPrior, stdin);
1.1 espie 430: #endif
1.7 jturner 431: }
1.1 espie 432: return zResult;
433: }
434:
435: struct previous_mode_data {
436: int valid; /* Is there legit data in here? */
437: int mode;
438: int showHeader;
439: int colWidth[100];
440: };
441:
442: /*
443: ** An pointer to an instance of this structure is passed from
444: ** the main program to the callback. This is used to communicate
445: ** state and mode information.
446: */
447: struct callback_data {
448: sqlite3 *db; /* The database */
449: int echoOn; /* True to echo input commands */
1.9 ! jturner 450: int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
1.1 espie 451: int statsOn; /* True to display memory stats before each finalize */
1.9 ! jturner 452: int outCount; /* Revert to stdout when reaching zero */
1.1 espie 453: int cnt; /* Number of records displayed so far */
454: FILE *out; /* Write results here */
1.2 espie 455: FILE *traceOut; /* Output for sqlite3_trace() */
1.1 espie 456: int nErr; /* Number of errors seen */
457: int mode; /* An output mode setting */
458: int writableSchema; /* True if PRAGMA writable_schema=ON */
459: int showHeader; /* True to show column names in List or Column mode */
460: char *zDestTable; /* Name of destination table when MODE_Insert */
461: char separator[20]; /* Separator character for MODE_List */
1.9 ! jturner 462: char newline[20]; /* Record separator in MODE_Csv */
1.1 espie 463: int colWidth[100]; /* Requested width of each column when in column mode*/
464: int actualWidth[100]; /* Actual width of each column */
465: char nullvalue[20]; /* The text to print when a NULL comes back from
466: ** the database */
467: struct previous_mode_data explainPrev;
468: /* Holds the mode information just before
469: ** .explain ON */
470: char outfile[FILENAME_MAX]; /* Filename for *out */
471: const char *zDbFilename; /* name of the database file */
1.8 jturner 472: char *zFreeOnClose; /* Filename to free when closing */
1.1 espie 473: const char *zVfs; /* Name of VFS to use */
474: sqlite3_stmt *pStmt; /* Current statement if any. */
475: FILE *pLog; /* Write log output here */
1.8 jturner 476: int *aiIndent; /* Array of indents used in MODE_Explain */
477: int nIndent; /* Size of array aiIndent[] */
478: int iIndent; /* Index of current op in aiIndent[] */
1.1 espie 479: };
480:
481: /*
482: ** These are the allowed modes.
483: */
484: #define MODE_Line 0 /* One column per line. Blank line between records */
485: #define MODE_Column 1 /* One record per line in neat columns */
486: #define MODE_List 2 /* One record per line with a separator */
487: #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
488: #define MODE_Html 4 /* Generate an XHTML table */
489: #define MODE_Insert 5 /* Generate SQL "insert" statements */
490: #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
491: #define MODE_Csv 7 /* Quote strings, numbers are plain */
492: #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
493:
494: static const char *modeDescr[] = {
495: "line",
496: "column",
497: "list",
498: "semi",
499: "html",
500: "insert",
501: "tcl",
502: "csv",
503: "explain",
504: };
505:
506: /*
507: ** Number of elements in an array
508: */
509: #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
510:
511: /*
512: ** Compute a string length that is limited to what can be stored in
513: ** lower 30 bits of a 32-bit signed integer.
514: */
515: static int strlen30(const char *z){
516: const char *z2 = z;
517: while( *z2 ){ z2++; }
518: return 0x3fffffff & (int)(z2 - z);
519: }
520:
521: /*
522: ** A callback for the sqlite3_log() interface.
523: */
524: static void shellLog(void *pArg, int iErrCode, const char *zMsg){
525: struct callback_data *p = (struct callback_data*)pArg;
526: if( p->pLog==0 ) return;
527: fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
528: fflush(p->pLog);
529: }
530:
531: /*
532: ** Output the given string as a hex-encoded blob (eg. X'1234' )
533: */
534: static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
535: int i;
536: char *zBlob = (char *)pBlob;
537: fprintf(out,"X'");
1.2 espie 538: for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
1.1 espie 539: fprintf(out,"'");
540: }
541:
542: /*
543: ** Output the given string as a quoted string using SQL quoting conventions.
544: */
545: static void output_quoted_string(FILE *out, const char *z){
546: int i;
547: int nSingle = 0;
548: for(i=0; z[i]; i++){
549: if( z[i]=='\'' ) nSingle++;
550: }
551: if( nSingle==0 ){
552: fprintf(out,"'%s'",z);
553: }else{
554: fprintf(out,"'");
555: while( *z ){
556: for(i=0; z[i] && z[i]!='\''; i++){}
557: if( i==0 ){
558: fprintf(out,"''");
559: z++;
560: }else if( z[i]=='\'' ){
561: fprintf(out,"%.*s''",i,z);
562: z += i+1;
563: }else{
564: fprintf(out,"%s",z);
565: break;
566: }
567: }
568: fprintf(out,"'");
569: }
570: }
571:
572: /*
573: ** Output the given string as a quoted according to C or TCL quoting rules.
574: */
575: static void output_c_string(FILE *out, const char *z){
576: unsigned int c;
577: fputc('"', out);
578: while( (c = *(z++))!=0 ){
579: if( c=='\\' ){
580: fputc(c, out);
581: fputc(c, out);
1.5 espie 582: }else if( c=='"' ){
583: fputc('\\', out);
584: fputc('"', out);
1.1 espie 585: }else if( c=='\t' ){
586: fputc('\\', out);
587: fputc('t', out);
588: }else if( c=='\n' ){
589: fputc('\\', out);
590: fputc('n', out);
591: }else if( c=='\r' ){
592: fputc('\\', out);
593: fputc('r', out);
1.8 jturner 594: }else if( !isprint(c&0xff) ){
1.1 espie 595: fprintf(out, "\\%03o", c&0xff);
596: }else{
597: fputc(c, out);
598: }
599: }
600: fputc('"', out);
601: }
602:
603: /*
604: ** Output the given string with characters that are special to
605: ** HTML escaped.
606: */
607: static void output_html_string(FILE *out, const char *z){
608: int i;
1.8 jturner 609: if( z==0 ) z = "";
1.1 espie 610: while( *z ){
611: for(i=0; z[i]
612: && z[i]!='<'
613: && z[i]!='&'
614: && z[i]!='>'
615: && z[i]!='\"'
616: && z[i]!='\'';
617: i++){}
618: if( i>0 ){
619: fprintf(out,"%.*s",i,z);
620: }
621: if( z[i]=='<' ){
622: fprintf(out,"<");
623: }else if( z[i]=='&' ){
624: fprintf(out,"&");
625: }else if( z[i]=='>' ){
626: fprintf(out,">");
627: }else if( z[i]=='\"' ){
628: fprintf(out,""");
629: }else if( z[i]=='\'' ){
630: fprintf(out,"'");
631: }else{
632: break;
633: }
634: z += i + 1;
635: }
636: }
637:
638: /*
639: ** If a field contains any character identified by a 1 in the following
640: ** array, then the string must be quoted for CSV.
641: */
642: static const char needCsvQuote[] = {
643: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
644: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
645: 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
646: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
647: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
648: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
649: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
650: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
651: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
652: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
653: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
654: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
655: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
656: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
657: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
658: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
659: };
660:
661: /*
662: ** Output a single term of CSV. Actually, p->separator is used for
663: ** the separator, which may or may not be a comma. p->nullvalue is
1.9 ! jturner 664: ** the null value. Strings are quoted if necessary. The separator
! 665: ** is only issued if bSep is true.
1.1 espie 666: */
667: static void output_csv(struct callback_data *p, const char *z, int bSep){
668: FILE *out = p->out;
669: if( z==0 ){
670: fprintf(out,"%s",p->nullvalue);
671: }else{
672: int i;
673: int nSep = strlen30(p->separator);
674: for(i=0; z[i]; i++){
675: if( needCsvQuote[((unsigned char*)z)[i]]
676: || (z[i]==p->separator[0] &&
677: (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
678: i = 0;
679: break;
680: }
681: }
682: if( i==0 ){
683: putc('"', out);
684: for(i=0; z[i]; i++){
685: if( z[i]=='"' ) putc('"', out);
686: putc(z[i], out);
687: }
688: putc('"', out);
689: }else{
690: fprintf(out, "%s", z);
691: }
692: }
693: if( bSep ){
694: fprintf(p->out, "%s", p->separator);
695: }
696: }
697:
698: #ifdef SIGINT
699: /*
700: ** This routine runs when the user presses Ctrl-C
701: */
702: static void interrupt_handler(int NotUsed){
703: UNUSED_PARAMETER(NotUsed);
1.9 ! jturner 704: seenInterrupt++;
! 705: if( seenInterrupt>2 ) exit(1);
1.1 espie 706: if( db ) sqlite3_interrupt(db);
707: }
708: #endif
709:
710: /*
711: ** This is the callback routine that the shell
712: ** invokes for each row of a query result.
713: */
714: static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
715: int i;
716: struct callback_data *p = (struct callback_data*)pArg;
717:
718: switch( p->mode ){
719: case MODE_Line: {
720: int w = 5;
721: if( azArg==0 ) break;
722: for(i=0; i<nArg; i++){
723: int len = strlen30(azCol[i] ? azCol[i] : "");
724: if( len>w ) w = len;
725: }
726: if( p->cnt++>0 ) fprintf(p->out,"\n");
727: for(i=0; i<nArg; i++){
728: fprintf(p->out,"%*s = %s\n", w, azCol[i],
729: azArg[i] ? azArg[i] : p->nullvalue);
730: }
731: break;
732: }
733: case MODE_Explain:
734: case MODE_Column: {
735: if( p->cnt++==0 ){
736: for(i=0; i<nArg; i++){
737: int w, n;
738: if( i<ArraySize(p->colWidth) ){
739: w = p->colWidth[i];
740: }else{
741: w = 0;
742: }
1.5 espie 743: if( w==0 ){
1.1 espie 744: w = strlen30(azCol[i] ? azCol[i] : "");
745: if( w<10 ) w = 10;
746: n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
747: if( w<n ) w = n;
748: }
749: if( i<ArraySize(p->actualWidth) ){
750: p->actualWidth[i] = w;
751: }
752: if( p->showHeader ){
1.5 espie 753: if( w<0 ){
754: fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
755: }else{
756: fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
757: }
1.1 espie 758: }
759: }
760: if( p->showHeader ){
761: for(i=0; i<nArg; i++){
762: int w;
763: if( i<ArraySize(p->actualWidth) ){
764: w = p->actualWidth[i];
1.5 espie 765: if( w<0 ) w = -w;
1.1 espie 766: }else{
767: w = 10;
768: }
769: fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
770: "----------------------------------------------------------",
771: i==nArg-1 ? "\n": " ");
772: }
773: }
774: }
775: if( azArg==0 ) break;
776: for(i=0; i<nArg; i++){
777: int w;
778: if( i<ArraySize(p->actualWidth) ){
779: w = p->actualWidth[i];
780: }else{
781: w = 10;
782: }
1.8 jturner 783: if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
1.1 espie 784: w = strlen30(azArg[i]);
785: }
1.8 jturner 786: if( i==1 && p->aiIndent && p->pStmt ){
787: if( p->iIndent<p->nIndent ){
788: fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
789: }
790: p->iIndent++;
791: }
1.5 espie 792: if( w<0 ){
793: fprintf(p->out,"%*.*s%s",-w,-w,
794: azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
795: }else{
796: fprintf(p->out,"%-*.*s%s",w,w,
797: azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
798: }
1.1 espie 799: }
800: break;
801: }
802: case MODE_Semi:
803: case MODE_List: {
804: if( p->cnt++==0 && p->showHeader ){
805: for(i=0; i<nArg; i++){
806: fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
807: }
808: }
809: if( azArg==0 ) break;
810: for(i=0; i<nArg; i++){
811: char *z = azArg[i];
812: if( z==0 ) z = p->nullvalue;
813: fprintf(p->out, "%s", z);
814: if( i<nArg-1 ){
815: fprintf(p->out, "%s", p->separator);
816: }else if( p->mode==MODE_Semi ){
817: fprintf(p->out, ";\n");
818: }else{
819: fprintf(p->out, "\n");
820: }
821: }
822: break;
823: }
824: case MODE_Html: {
825: if( p->cnt++==0 && p->showHeader ){
826: fprintf(p->out,"<TR>");
827: for(i=0; i<nArg; i++){
828: fprintf(p->out,"<TH>");
829: output_html_string(p->out, azCol[i]);
830: fprintf(p->out,"</TH>\n");
831: }
832: fprintf(p->out,"</TR>\n");
833: }
834: if( azArg==0 ) break;
835: fprintf(p->out,"<TR>");
836: for(i=0; i<nArg; i++){
837: fprintf(p->out,"<TD>");
838: output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
839: fprintf(p->out,"</TD>\n");
840: }
841: fprintf(p->out,"</TR>\n");
842: break;
843: }
844: case MODE_Tcl: {
845: if( p->cnt++==0 && p->showHeader ){
846: for(i=0; i<nArg; i++){
847: output_c_string(p->out,azCol[i] ? azCol[i] : "");
1.5 espie 848: if(i<nArg-1) fprintf(p->out, "%s", p->separator);
1.1 espie 849: }
850: fprintf(p->out,"\n");
851: }
852: if( azArg==0 ) break;
853: for(i=0; i<nArg; i++){
854: output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
1.5 espie 855: if(i<nArg-1) fprintf(p->out, "%s", p->separator);
1.1 espie 856: }
857: fprintf(p->out,"\n");
858: break;
859: }
860: case MODE_Csv: {
1.9 ! jturner 861: #if defined(WIN32) || defined(_WIN32)
! 862: fflush(p->out);
! 863: _setmode(_fileno(p->out), _O_BINARY);
! 864: #endif
1.1 espie 865: if( p->cnt++==0 && p->showHeader ){
866: for(i=0; i<nArg; i++){
867: output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
868: }
1.9 ! jturner 869: fprintf(p->out,"%s",p->newline);
1.1 espie 870: }
1.9 ! jturner 871: if( azArg>0 ){
! 872: for(i=0; i<nArg; i++){
! 873: output_csv(p, azArg[i], i<nArg-1);
! 874: }
! 875: fprintf(p->out,"%s",p->newline);
1.1 espie 876: }
1.9 ! jturner 877: #if defined(WIN32) || defined(_WIN32)
! 878: fflush(p->out);
! 879: _setmode(_fileno(p->out), _O_TEXT);
! 880: #endif
1.1 espie 881: break;
882: }
883: case MODE_Insert: {
884: p->cnt++;
885: if( azArg==0 ) break;
886: fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
887: for(i=0; i<nArg; i++){
888: char *zSep = i>0 ? ",": "";
889: if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
890: fprintf(p->out,"%sNULL",zSep);
891: }else if( aiType && aiType[i]==SQLITE_TEXT ){
892: if( zSep[0] ) fprintf(p->out,"%s",zSep);
893: output_quoted_string(p->out, azArg[i]);
1.9 ! jturner 894: }else if( aiType && (aiType[i]==SQLITE_INTEGER
! 895: || aiType[i]==SQLITE_FLOAT) ){
1.1 espie 896: fprintf(p->out,"%s%s",zSep, azArg[i]);
897: }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
898: const void *pBlob = sqlite3_column_blob(p->pStmt, i);
899: int nBlob = sqlite3_column_bytes(p->pStmt, i);
900: if( zSep[0] ) fprintf(p->out,"%s",zSep);
901: output_hex_blob(p->out, pBlob, nBlob);
902: }else if( isNumber(azArg[i], 0) ){
903: fprintf(p->out,"%s%s",zSep, azArg[i]);
904: }else{
905: if( zSep[0] ) fprintf(p->out,"%s",zSep);
906: output_quoted_string(p->out, azArg[i]);
907: }
908: }
909: fprintf(p->out,");\n");
910: break;
911: }
912: }
913: return 0;
914: }
915:
916: /*
917: ** This is the callback routine that the SQLite library
918: ** invokes for each row of a query result.
919: */
920: static int callback(void *pArg, int nArg, char **azArg, char **azCol){
921: /* since we don't have type info, call the shell_callback with a NULL value */
922: return shell_callback(pArg, nArg, azArg, azCol, NULL);
923: }
924:
925: /*
926: ** Set the destination table field of the callback_data structure to
927: ** the name of the table given. Escape any quote characters in the
928: ** table name.
929: */
930: static void set_table_name(struct callback_data *p, const char *zName){
931: int i, n;
932: int needQuote;
933: char *z;
934:
935: if( p->zDestTable ){
936: free(p->zDestTable);
937: p->zDestTable = 0;
938: }
939: if( zName==0 ) return;
940: needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
941: for(i=n=0; zName[i]; i++, n++){
942: if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
943: needQuote = 1;
944: if( zName[i]=='\'' ) n++;
945: }
946: }
947: if( needQuote ) n += 2;
948: z = p->zDestTable = malloc( n+1 );
949: if( z==0 ){
950: fprintf(stderr,"Error: out of memory\n");
951: exit(1);
952: }
953: n = 0;
954: if( needQuote ) z[n++] = '\'';
955: for(i=0; zName[i]; i++){
956: z[n++] = zName[i];
957: if( zName[i]=='\'' ) z[n++] = '\'';
958: }
959: if( needQuote ) z[n++] = '\'';
960: z[n] = 0;
961: }
962:
963: /* zIn is either a pointer to a NULL-terminated string in memory obtained
964: ** from malloc(), or a NULL pointer. The string pointed to by zAppend is
965: ** added to zIn, and the result returned in memory obtained from malloc().
966: ** zIn, if it was not NULL, is freed.
967: **
968: ** If the third argument, quote, is not '\0', then it is used as a
969: ** quote character for zAppend.
970: */
971: static char *appendText(char *zIn, char const *zAppend, char quote){
972: int len;
973: int i;
974: int nAppend = strlen30(zAppend);
975: int nIn = (zIn?strlen30(zIn):0);
976:
977: len = nAppend+nIn+1;
978: if( quote ){
979: len += 2;
980: for(i=0; i<nAppend; i++){
981: if( zAppend[i]==quote ) len++;
982: }
983: }
984:
985: zIn = (char *)realloc(zIn, len);
986: if( !zIn ){
987: return 0;
988: }
989:
990: if( quote ){
991: char *zCsr = &zIn[nIn];
992: *zCsr++ = quote;
993: for(i=0; i<nAppend; i++){
994: *zCsr++ = zAppend[i];
995: if( zAppend[i]==quote ) *zCsr++ = quote;
996: }
997: *zCsr++ = quote;
998: *zCsr++ = '\0';
999: assert( (zCsr-zIn)==len );
1000: }else{
1001: memcpy(&zIn[nIn], zAppend, nAppend);
1002: zIn[len-1] = '\0';
1003: }
1004:
1005: return zIn;
1006: }
1007:
1008:
1009: /*
1010: ** Execute a query statement that will generate SQL output. Print
1011: ** the result columns, comma-separated, on a line and then add a
1012: ** semicolon terminator to the end of that line.
1013: **
1014: ** If the number of columns is 1 and that column contains text "--"
1015: ** then write the semicolon on a separate line. That way, if a
1016: ** "--" comment occurs at the end of the statement, the comment
1017: ** won't consume the semicolon terminator.
1018: */
1019: static int run_table_dump_query(
1020: struct callback_data *p, /* Query context */
1021: const char *zSelect, /* SELECT statement to extract content */
1022: const char *zFirstRow /* Print before first row, if not NULL */
1023: ){
1024: sqlite3_stmt *pSelect;
1025: int rc;
1026: int nResult;
1027: int i;
1028: const char *z;
1.8 jturner 1029: rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
1.1 espie 1030: if( rc!=SQLITE_OK || !pSelect ){
1031: fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
1.8 jturner 1032: if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
1.1 espie 1033: return rc;
1034: }
1035: rc = sqlite3_step(pSelect);
1036: nResult = sqlite3_column_count(pSelect);
1037: while( rc==SQLITE_ROW ){
1038: if( zFirstRow ){
1039: fprintf(p->out, "%s", zFirstRow);
1040: zFirstRow = 0;
1041: }
1042: z = (const char*)sqlite3_column_text(pSelect, 0);
1043: fprintf(p->out, "%s", z);
1044: for(i=1; i<nResult; i++){
1045: fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1046: }
1047: if( z==0 ) z = "";
1048: while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1049: if( z[0] ){
1050: fprintf(p->out, "\n;\n");
1051: }else{
1052: fprintf(p->out, ";\n");
1053: }
1054: rc = sqlite3_step(pSelect);
1055: }
1056: rc = sqlite3_finalize(pSelect);
1057: if( rc!=SQLITE_OK ){
1058: fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
1.8 jturner 1059: if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
1.1 espie 1060: }
1061: return rc;
1062: }
1063:
1064: /*
1065: ** Allocate space and save off current error string.
1066: */
1067: static char *save_err_msg(
1068: sqlite3 *db /* Database to query */
1069: ){
1070: int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1071: char *zErrMsg = sqlite3_malloc(nErrMsg);
1072: if( zErrMsg ){
1073: memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1074: }
1075: return zErrMsg;
1076: }
1077:
1078: /*
1079: ** Display memory stats.
1080: */
1081: static int display_stats(
1082: sqlite3 *db, /* Database to query */
1083: struct callback_data *pArg, /* Pointer to struct callback_data */
1084: int bReset /* True to reset the stats */
1085: ){
1086: int iCur;
1087: int iHiwtr;
1088:
1089: if( pArg && pArg->out ){
1090:
1091: iHiwtr = iCur = -1;
1092: sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
1093: fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr);
1094: iHiwtr = iCur = -1;
1095: sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
1096: fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr);
1097: /*
1098: ** Not currently used by the CLI.
1099: ** iHiwtr = iCur = -1;
1100: ** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
1101: ** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr);
1102: */
1103: iHiwtr = iCur = -1;
1104: sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
1105: fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1106: /*
1107: ** Not currently used by the CLI.
1108: ** iHiwtr = iCur = -1;
1109: ** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
1110: ** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr);
1111: */
1112: iHiwtr = iCur = -1;
1113: sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
1114: fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr);
1115: iHiwtr = iCur = -1;
1116: sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
1117: fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr);
1118: iHiwtr = iCur = -1;
1119: sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
1120: fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr);
1121: iHiwtr = iCur = -1;
1122: sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
1123: fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr);
1124: #ifdef YYTRACKMAXSTACKDEPTH
1125: iHiwtr = iCur = -1;
1126: sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
1127: fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr);
1128: #endif
1129: }
1130:
1131: if( pArg && pArg->out && db ){
1132: iHiwtr = iCur = -1;
1133: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
1134: fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
1135: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
1136: fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
1137: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
1138: fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1139: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1140: fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1141: iHiwtr = iCur = -1;
1142: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
1143: fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1144: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1145: fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1146: iHiwtr = iCur = -1;
1147: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1148: fprintf(pArg->out, "Page cache misses: %d\n", iCur);
1149: iHiwtr = iCur = -1;
1.2 espie 1150: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1151: fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1152: iHiwtr = iCur = -1;
1.1 espie 1153: sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1154: fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1155: iHiwtr = iCur = -1;
1156: sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1157: fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur);
1158: }
1159:
1160: if( pArg && pArg->out && db && pArg->pStmt ){
1161: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
1162: fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1163: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1164: fprintf(pArg->out, "Sort Operations: %d\n", iCur);
1165: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
1166: fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
1.7 jturner 1167: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1168: fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
1.1 espie 1169: }
1170:
1171: return 0;
1172: }
1173:
1174: /*
1.8 jturner 1175: ** Parameter azArray points to a zero-terminated array of strings. zStr
1176: ** points to a single nul-terminated string. Return non-zero if zStr
1177: ** is equal, according to strcmp(), to any of the strings in the array.
1178: ** Otherwise, return zero.
1179: */
1180: static int str_in_array(const char *zStr, const char **azArray){
1181: int i;
1182: for(i=0; azArray[i]; i++){
1183: if( 0==strcmp(zStr, azArray[i]) ) return 1;
1184: }
1185: return 0;
1186: }
1187:
1188: /*
1189: ** If compiled statement pSql appears to be an EXPLAIN statement, allocate
1190: ** and populate the callback_data.aiIndent[] array with the number of
1191: ** spaces each opcode should be indented before it is output.
1192: **
1193: ** The indenting rules are:
1194: **
1195: ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1196: ** all opcodes that occur between the p2 jump destination and the opcode
1197: ** itself by 2 spaces.
1198: **
1199: ** * For each "Goto", if the jump destination is earlier in the program
1200: ** and ends on one of:
1201: ** Yield SeekGt SeekLt RowSetRead Rewind
1202: ** or if the P1 parameter is one instead of zero,
1203: ** then indent all opcodes between the earlier instruction
1204: ** and "Goto" by 2 spaces.
1205: */
1206: static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
1207: const char *zSql; /* The text of the SQL statement */
1208: const char *z; /* Used to check if this is an EXPLAIN */
1209: int *abYield = 0; /* True if op is an OP_Yield */
1210: int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
1211: int iOp; /* Index of operation in p->aiIndent[] */
1212:
1.9 ! jturner 1213: const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
! 1214: "NextIfOpen", "PrevIfOpen", 0 };
! 1215: const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 };
1.8 jturner 1216: const char *azGoto[] = { "Goto", 0 };
1217:
1218: /* Try to figure out if this is really an EXPLAIN statement. If this
1219: ** cannot be verified, return early. */
1220: zSql = sqlite3_sql(pSql);
1221: if( zSql==0 ) return;
1222: for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1223: if( sqlite3_strnicmp(z, "explain", 7) ) return;
1224:
1225: for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1226: int i;
1227: int iAddr = sqlite3_column_int(pSql, 0);
1228: const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
1229:
1230: /* Set p2 to the P2 field of the current opcode. Then, assuming that
1231: ** p2 is an instruction address, set variable p2op to the index of that
1232: ** instruction in the aiIndent[] array. p2 and p2op may be different if
1233: ** the current instruction is part of a sub-program generated by an
1234: ** SQL trigger or foreign key. */
1235: int p2 = sqlite3_column_int(pSql, 3);
1236: int p2op = (p2 + (iOp-iAddr));
1237:
1238: /* Grow the p->aiIndent array as required */
1239: if( iOp>=nAlloc ){
1240: nAlloc += 100;
1241: p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1242: abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1243: }
1244: abYield[iOp] = str_in_array(zOp, azYield);
1245: p->aiIndent[iOp] = 0;
1246: p->nIndent = iOp+1;
1247:
1248: if( str_in_array(zOp, azNext) ){
1249: for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
1250: }
1251: if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1252: && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1253: ){
1254: for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
1255: }
1256: }
1257:
1258: p->iIndent = 0;
1259: sqlite3_free(abYield);
1260: sqlite3_reset(pSql);
1261: }
1262:
1263: /*
1264: ** Free the array allocated by explain_data_prepare().
1265: */
1266: static void explain_data_delete(struct callback_data *p){
1267: sqlite3_free(p->aiIndent);
1268: p->aiIndent = 0;
1269: p->nIndent = 0;
1270: p->iIndent = 0;
1271: }
1272:
1273: /*
1.1 espie 1274: ** Execute a statement or set of statements. Print
1275: ** any result rows/columns depending on the current mode
1276: ** set via the supplied callback.
1277: **
1278: ** This is very similar to SQLite's built-in sqlite3_exec()
1279: ** function except it takes a slightly different callback
1280: ** and callback data argument.
1281: */
1282: static int shell_exec(
1283: sqlite3 *db, /* An open database */
1284: const char *zSql, /* SQL to be evaluated */
1285: int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
1286: /* (not the same as sqlite3_exec) */
1287: struct callback_data *pArg, /* Pointer to struct callback_data */
1288: char **pzErrMsg /* Error msg written here */
1289: ){
1290: sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1291: int rc = SQLITE_OK; /* Return Code */
1292: int rc2;
1293: const char *zLeftover; /* Tail of unprocessed SQL */
1294:
1295: if( pzErrMsg ){
1296: *pzErrMsg = NULL;
1297: }
1298:
1299: while( zSql[0] && (SQLITE_OK == rc) ){
1300: rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1301: if( SQLITE_OK != rc ){
1302: if( pzErrMsg ){
1303: *pzErrMsg = save_err_msg(db);
1304: }
1305: }else{
1306: if( !pStmt ){
1307: /* this happens for a comment or white-space */
1308: zSql = zLeftover;
1309: while( IsSpace(zSql[0]) ) zSql++;
1310: continue;
1311: }
1312:
1313: /* save off the prepared statment handle and reset row count */
1314: if( pArg ){
1315: pArg->pStmt = pStmt;
1316: pArg->cnt = 0;
1317: }
1318:
1319: /* echo the sql statement if echo on */
1320: if( pArg && pArg->echoOn ){
1321: const char *zStmtSql = sqlite3_sql(pStmt);
1322: fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
1323: }
1324:
1.8 jturner 1325: /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1326: if( pArg && pArg->autoEQP ){
1327: sqlite3_stmt *pExplain;
1328: char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
1329: rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1330: if( rc==SQLITE_OK ){
1331: while( sqlite3_step(pExplain)==SQLITE_ROW ){
1332: fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1333: fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1334: fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1335: fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1336: }
1337: }
1338: sqlite3_finalize(pExplain);
1339: sqlite3_free(zEQP);
1340: }
1341:
1.1 espie 1342: /* Output TESTCTRL_EXPLAIN text of requested */
1343: if( pArg && pArg->mode==MODE_Explain ){
1344: const char *zExplain = 0;
1345: sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
1346: if( zExplain && zExplain[0] ){
1347: fprintf(pArg->out, "%s", zExplain);
1348: }
1349: }
1350:
1.8 jturner 1351: /* If the shell is currently in ".explain" mode, gather the extra
1352: ** data required to add indents to the output.*/
1353: if( pArg && pArg->mode==MODE_Explain ){
1354: explain_data_prepare(pArg, pStmt);
1355: }
1356:
1.1 espie 1357: /* perform the first step. this will tell us if we
1358: ** have a result set or not and how wide it is.
1359: */
1360: rc = sqlite3_step(pStmt);
1361: /* if we have a result set... */
1362: if( SQLITE_ROW == rc ){
1363: /* if we have a callback... */
1364: if( xCallback ){
1365: /* allocate space for col name ptr, value ptr, and type */
1366: int nCol = sqlite3_column_count(pStmt);
1367: void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1368: if( !pData ){
1369: rc = SQLITE_NOMEM;
1370: }else{
1371: char **azCols = (char **)pData; /* Names of result columns */
1372: char **azVals = &azCols[nCol]; /* Results */
1373: int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1.8 jturner 1374: int i, x;
1.1 espie 1375: assert(sizeof(int) <= sizeof(char *));
1376: /* save off ptrs to column names */
1377: for(i=0; i<nCol; i++){
1378: azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1379: }
1380: do{
1381: /* extract the data and data types */
1382: for(i=0; i<nCol; i++){
1.8 jturner 1383: aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1384: if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
1385: azVals[i] = "";
1386: }else{
1387: azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1388: }
1.1 espie 1389: if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1390: rc = SQLITE_NOMEM;
1391: break; /* from for */
1392: }
1393: } /* end for */
1394:
1395: /* if data and types extracted successfully... */
1396: if( SQLITE_ROW == rc ){
1397: /* call the supplied callback with the result row data */
1398: if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1399: rc = SQLITE_ABORT;
1400: }else{
1401: rc = sqlite3_step(pStmt);
1402: }
1403: }
1404: } while( SQLITE_ROW == rc );
1405: sqlite3_free(pData);
1406: }
1407: }else{
1408: do{
1409: rc = sqlite3_step(pStmt);
1410: } while( rc == SQLITE_ROW );
1411: }
1412: }
1413:
1.8 jturner 1414: explain_data_delete(pArg);
1415:
1.1 espie 1416: /* print usage stats if stats on */
1417: if( pArg && pArg->statsOn ){
1418: display_stats(db, pArg, 0);
1419: }
1420:
1421: /* Finalize the statement just executed. If this fails, save a
1422: ** copy of the error message. Otherwise, set zSql to point to the
1423: ** next statement to execute. */
1424: rc2 = sqlite3_finalize(pStmt);
1425: if( rc!=SQLITE_NOMEM ) rc = rc2;
1426: if( rc==SQLITE_OK ){
1427: zSql = zLeftover;
1428: while( IsSpace(zSql[0]) ) zSql++;
1429: }else if( pzErrMsg ){
1430: *pzErrMsg = save_err_msg(db);
1431: }
1432:
1433: /* clear saved stmt handle */
1434: if( pArg ){
1435: pArg->pStmt = NULL;
1436: }
1437: }
1438: } /* end while */
1439:
1440: return rc;
1441: }
1442:
1443:
1444: /*
1445: ** This is a different callback routine used for dumping the database.
1446: ** Each row received by this callback consists of a table name,
1447: ** the table type ("index" or "table") and SQL to create the table.
1448: ** This routine should print text sufficient to recreate the table.
1449: */
1450: static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
1451: int rc;
1452: const char *zTable;
1453: const char *zType;
1454: const char *zSql;
1455: const char *zPrepStmt = 0;
1456: struct callback_data *p = (struct callback_data *)pArg;
1457:
1458: UNUSED_PARAMETER(azCol);
1459: if( nArg!=3 ) return 1;
1460: zTable = azArg[0];
1461: zType = azArg[1];
1462: zSql = azArg[2];
1463:
1464: if( strcmp(zTable, "sqlite_sequence")==0 ){
1465: zPrepStmt = "DELETE FROM sqlite_sequence;\n";
1.8 jturner 1466: }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
1.1 espie 1467: fprintf(p->out, "ANALYZE sqlite_master;\n");
1468: }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1469: return 0;
1470: }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1471: char *zIns;
1472: if( !p->writableSchema ){
1473: fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1474: p->writableSchema = 1;
1475: }
1476: zIns = sqlite3_mprintf(
1477: "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1478: "VALUES('table','%q','%q',0,'%q');",
1479: zTable, zTable, zSql);
1480: fprintf(p->out, "%s\n", zIns);
1481: sqlite3_free(zIns);
1482: return 0;
1483: }else{
1484: fprintf(p->out, "%s;\n", zSql);
1485: }
1486:
1487: if( strcmp(zType, "table")==0 ){
1488: sqlite3_stmt *pTableInfo = 0;
1489: char *zSelect = 0;
1490: char *zTableInfo = 0;
1491: char *zTmp = 0;
1492: int nRow = 0;
1493:
1494: zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1495: zTableInfo = appendText(zTableInfo, zTable, '"');
1496: zTableInfo = appendText(zTableInfo, ");", 0);
1497:
1.8 jturner 1498: rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
1.1 espie 1499: free(zTableInfo);
1500: if( rc!=SQLITE_OK || !pTableInfo ){
1501: return 1;
1502: }
1503:
1504: zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
1.2 espie 1505: /* Always quote the table name, even if it appears to be pure ascii,
1506: ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1507: zTmp = appendText(zTmp, zTable, '"');
1.1 espie 1508: if( zTmp ){
1509: zSelect = appendText(zSelect, zTmp, '\'');
1.2 espie 1510: free(zTmp);
1.1 espie 1511: }
1512: zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1513: rc = sqlite3_step(pTableInfo);
1514: while( rc==SQLITE_ROW ){
1515: const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
1516: zSelect = appendText(zSelect, "quote(", 0);
1517: zSelect = appendText(zSelect, zText, '"');
1518: rc = sqlite3_step(pTableInfo);
1519: if( rc==SQLITE_ROW ){
1520: zSelect = appendText(zSelect, "), ", 0);
1521: }else{
1522: zSelect = appendText(zSelect, ") ", 0);
1523: }
1524: nRow++;
1525: }
1526: rc = sqlite3_finalize(pTableInfo);
1527: if( rc!=SQLITE_OK || nRow==0 ){
1528: free(zSelect);
1529: return 1;
1530: }
1531: zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1532: zSelect = appendText(zSelect, zTable, '"');
1533:
1534: rc = run_table_dump_query(p, zSelect, zPrepStmt);
1535: if( rc==SQLITE_CORRUPT ){
1536: zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
1537: run_table_dump_query(p, zSelect, 0);
1538: }
1.2 espie 1539: free(zSelect);
1.1 espie 1540: }
1541: return 0;
1542: }
1543:
1544: /*
1545: ** Run zQuery. Use dump_callback() as the callback routine so that
1546: ** the contents of the query are output as SQL statements.
1547: **
1548: ** If we get a SQLITE_CORRUPT error, rerun the query after appending
1549: ** "ORDER BY rowid DESC" to the end.
1550: */
1551: static int run_schema_dump_query(
1552: struct callback_data *p,
1553: const char *zQuery
1554: ){
1555: int rc;
1556: char *zErr = 0;
1557: rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
1558: if( rc==SQLITE_CORRUPT ){
1559: char *zQ2;
1560: int len = strlen30(zQuery);
1561: fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1562: if( zErr ){
1563: fprintf(p->out, "/****** %s ******/\n", zErr);
1564: sqlite3_free(zErr);
1565: zErr = 0;
1566: }
1567: zQ2 = malloc( len+100 );
1568: if( zQ2==0 ) return rc;
1.2 espie 1569: sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
1.1 espie 1570: rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1571: if( rc ){
1572: fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1573: }else{
1574: rc = SQLITE_CORRUPT;
1575: }
1576: sqlite3_free(zErr);
1577: free(zQ2);
1578: }
1579: return rc;
1580: }
1581:
1582: /*
1583: ** Text of a help message
1584: */
1585: static char zHelp[] =
1586: ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
1.9 ! jturner 1587: ".bail on|off Stop after hitting an error. Default OFF\n"
1.8 jturner 1588: ".clone NEWDB Clone data into NEWDB from the existing database\n"
1.1 espie 1589: ".databases List names and files of attached databases\n"
1590: ".dump ?TABLE? ... Dump the database in an SQL text format\n"
1591: " If TABLE specified, only dump tables matching\n"
1592: " LIKE pattern TABLE.\n"
1.9 ! jturner 1593: ".echo on|off Turn command echo on or off\n"
! 1594: ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
1.1 espie 1595: ".exit Exit this program\n"
1.9 ! jturner 1596: ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
1.1 espie 1597: " With no args, it turns EXPLAIN on.\n"
1.9 ! jturner 1598: ".fullschema Show schema and the content of sqlite_stat tables\n"
! 1599: ".headers on|off Turn display of headers on or off\n"
1.1 espie 1600: ".help Show this message\n"
1601: ".import FILE TABLE Import data from FILE into TABLE\n"
1602: ".indices ?TABLE? Show names of all indices\n"
1603: " If TABLE specified, only show indices for tables\n"
1604: " matching LIKE pattern TABLE.\n"
1605: #ifdef SQLITE_ENABLE_IOTRACE
1606: ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1607: #endif
1608: #ifndef SQLITE_OMIT_LOAD_EXTENSION
1609: ".load FILE ?ENTRY? Load an extension library\n"
1610: #endif
1611: ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
1612: ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
1613: " csv Comma-separated values\n"
1614: " column Left-aligned columns. (See .width)\n"
1615: " html HTML <table> code\n"
1616: " insert SQL insert statements for TABLE\n"
1617: " line One value per line\n"
1618: " list Values delimited by .separator string\n"
1619: " tabs Tab-separated values\n"
1620: " tcl TCL list elements\n"
1.5 espie 1621: ".nullvalue STRING Use STRING in place of NULL values\n"
1.9 ! jturner 1622: ".once FILENAME Output for the next SQL command only to FILENAME\n"
1.8 jturner 1623: ".open ?FILENAME? Close existing database and reopen FILENAME\n"
1.9 ! jturner 1624: ".output ?FILENAME? Send output to FILENAME or stdout\n"
1.5 espie 1625: ".print STRING... Print literal STRING\n"
1.1 espie 1626: ".prompt MAIN CONTINUE Replace the standard prompts\n"
1627: ".quit Exit this program\n"
1628: ".read FILENAME Execute SQL in FILENAME\n"
1629: ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
1.8 jturner 1630: ".save FILE Write in-memory database into FILE\n"
1.1 espie 1631: ".schema ?TABLE? Show the CREATE statements\n"
1632: " If TABLE specified, only show tables matching\n"
1633: " LIKE pattern TABLE.\n"
1.9 ! jturner 1634: ".separator STRING ?NL? Change separator used by output mode and .import\n"
! 1635: " NL is the end-of-line mark for CSV\n"
! 1636: ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
1.1 espie 1637: ".show Show the current values for various settings\n"
1.9 ! jturner 1638: ".stats on|off Turn stats on or off\n"
! 1639: ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
1.1 espie 1640: ".tables ?TABLE? List names of tables\n"
1641: " If TABLE specified, only list tables matching\n"
1642: " LIKE pattern TABLE.\n"
1643: ".timeout MS Try opening locked tables for MS milliseconds\n"
1.9 ! jturner 1644: ".timer on|off Turn SQL timer on or off\n"
1.2 espie 1645: ".trace FILE|off Output each SQL statement as it is run\n"
1.1 espie 1646: ".vfsname ?AUX? Print the name of the VFS stack\n"
1647: ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
1.9 ! jturner 1648: " Negative values right-justify\n"
1.1 espie 1649: ;
1650:
1651: /* Forward reference */
1652: static int process_input(struct callback_data *p, FILE *in);
1.9 ! jturner 1653: /*
! 1654: ** Implementation of the "readfile(X)" SQL function. The entire content
! 1655: ** of the file named X is read and returned as a BLOB. NULL is returned
! 1656: ** if the file does not exist or is unreadable.
! 1657: */
! 1658: static void readfileFunc(
! 1659: sqlite3_context *context,
! 1660: int argc,
! 1661: sqlite3_value **argv
! 1662: ){
! 1663: const char *zName;
! 1664: FILE *in;
! 1665: long nIn;
! 1666: void *pBuf;
! 1667:
! 1668: zName = (const char*)sqlite3_value_text(argv[0]);
! 1669: if( zName==0 ) return;
! 1670: in = fopen(zName, "rb");
! 1671: if( in==0 ) return;
! 1672: fseek(in, 0, SEEK_END);
! 1673: nIn = ftell(in);
! 1674: rewind(in);
! 1675: pBuf = sqlite3_malloc( nIn );
! 1676: if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
! 1677: sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
! 1678: }else{
! 1679: sqlite3_free(pBuf);
! 1680: }
! 1681: fclose(in);
! 1682: }
! 1683:
! 1684: /*
! 1685: ** Implementation of the "writefile(X,Y)" SQL function. The argument Y
! 1686: ** is written into file X. The number of bytes written is returned. Or
! 1687: ** NULL is returned if something goes wrong, such as being unable to open
! 1688: ** file X for writing.
! 1689: */
! 1690: static void writefileFunc(
! 1691: sqlite3_context *context,
! 1692: int argc,
! 1693: sqlite3_value **argv
! 1694: ){
! 1695: FILE *out;
! 1696: const char *z;
! 1697: sqlite3_int64 rc;
! 1698: const char *zFile;
! 1699:
! 1700: zFile = (const char*)sqlite3_value_text(argv[0]);
! 1701: if( zFile==0 ) return;
! 1702: out = fopen(zFile, "wb");
! 1703: if( out==0 ) return;
! 1704: z = (const char*)sqlite3_value_blob(argv[1]);
! 1705: if( z==0 ){
! 1706: rc = 0;
! 1707: }else{
! 1708: rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
! 1709: }
! 1710: fclose(out);
! 1711: sqlite3_result_int64(context, rc);
! 1712: }
1.1 espie 1713:
1714: /*
1715: ** Make sure the database is open. If it is not, then open it. If
1716: ** the database fails to open, print an error message and exit.
1717: */
1.8 jturner 1718: static void open_db(struct callback_data *p, int keepAlive){
1.1 espie 1719: if( p->db==0 ){
1.4 espie 1720: sqlite3_initialize();
1.1 espie 1721: sqlite3_open(p->zDbFilename, &p->db);
1722: db = p->db;
1723: if( db && sqlite3_errcode(db)==SQLITE_OK ){
1724: sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1725: shellstaticFunc, 0, 0);
1726: }
1727: if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
1728: fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
1729: p->zDbFilename, sqlite3_errmsg(db));
1.8 jturner 1730: if( keepAlive ) return;
1.1 espie 1731: exit(1);
1732: }
1733: #ifndef SQLITE_OMIT_LOAD_EXTENSION
1734: sqlite3_enable_load_extension(p->db, 1);
1735: #endif
1.9 ! jturner 1736: sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
! 1737: readfileFunc, 0, 0);
! 1738: sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
! 1739: writefileFunc, 0, 0);
1.1 espie 1740: }
1741: }
1742:
1743: /*
1744: ** Do C-language style dequoting.
1745: **
1746: ** \t -> tab
1747: ** \n -> newline
1748: ** \r -> carriage return
1.7 jturner 1749: ** \" -> "
1.1 espie 1750: ** \NNN -> ascii character NNN in octal
1751: ** \\ -> backslash
1752: */
1753: static void resolve_backslashes(char *z){
1754: int i, j;
1755: char c;
1.9 ! jturner 1756: while( *z && *z!='\\' ) z++;
1.1 espie 1757: for(i=j=0; (c = z[i])!=0; i++, j++){
1758: if( c=='\\' ){
1759: c = z[++i];
1760: if( c=='n' ){
1761: c = '\n';
1762: }else if( c=='t' ){
1763: c = '\t';
1764: }else if( c=='r' ){
1765: c = '\r';
1.7 jturner 1766: }else if( c=='\\' ){
1767: c = '\\';
1.1 espie 1768: }else if( c>='0' && c<='7' ){
1769: c -= '0';
1770: if( z[i+1]>='0' && z[i+1]<='7' ){
1771: i++;
1772: c = (c<<3) + z[i] - '0';
1773: if( z[i+1]>='0' && z[i+1]<='7' ){
1774: i++;
1775: c = (c<<3) + z[i] - '0';
1776: }
1777: }
1778: }
1779: }
1780: z[j] = c;
1781: }
1.9 ! jturner 1782: if( j<i ) z[j] = 0;
1.1 espie 1783: }
1784:
1785: /*
1.7 jturner 1786: ** Return the value of a hexadecimal digit. Return -1 if the input
1787: ** is not a hex digit.
1.1 espie 1788: */
1.7 jturner 1789: static int hexDigitValue(char c){
1790: if( c>='0' && c<='9' ) return c - '0';
1791: if( c>='a' && c<='f' ) return c - 'a' + 10;
1792: if( c>='A' && c<='F' ) return c - 'A' + 10;
1793: return -1;
1.6 landry 1794: }
1795:
1796: /*
1797: ** Interpret zArg as an integer value, possibly with suffixes.
1798: */
1799: static sqlite3_int64 integerValue(const char *zArg){
1800: sqlite3_int64 v = 0;
1801: static const struct { char *zSuffix; int iMult; } aMult[] = {
1802: { "KiB", 1024 },
1803: { "MiB", 1024*1024 },
1804: { "GiB", 1024*1024*1024 },
1805: { "KB", 1000 },
1806: { "MB", 1000000 },
1807: { "GB", 1000000000 },
1808: { "K", 1000 },
1809: { "M", 1000000 },
1810: { "G", 1000000000 },
1811: };
1812: int i;
1813: int isNeg = 0;
1814: if( zArg[0]=='-' ){
1815: isNeg = 1;
1816: zArg++;
1817: }else if( zArg[0]=='+' ){
1818: zArg++;
1819: }
1.7 jturner 1820: if( zArg[0]=='0' && zArg[1]=='x' ){
1821: int x;
1822: zArg += 2;
1823: while( (x = hexDigitValue(zArg[0]))>=0 ){
1824: v = (v<<4) + x;
1825: zArg++;
1826: }
1827: }else{
1828: while( IsDigit(zArg[0]) ){
1829: v = v*10 + zArg[0] - '0';
1830: zArg++;
1831: }
1.6 landry 1832: }
1.7 jturner 1833: for(i=0; i<ArraySize(aMult); i++){
1.6 landry 1834: if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
1835: v *= aMult[i].iMult;
1836: break;
1837: }
1.1 espie 1838: }
1.6 landry 1839: return isNeg? -v : v;
1.1 espie 1840: }
1841:
1842: /*
1.7 jturner 1843: ** Interpret zArg as either an integer or a boolean value. Return 1 or 0
1844: ** for TRUE and FALSE. Return the integer value if appropriate.
1845: */
1846: static int booleanValue(char *zArg){
1847: int i;
1848: if( zArg[0]=='0' && zArg[1]=='x' ){
1849: for(i=2; hexDigitValue(zArg[i])>=0; i++){}
1850: }else{
1851: for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1852: }
1853: if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
1854: if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1855: return 1;
1856: }
1857: if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1858: return 0;
1859: }
1860: fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1861: zArg);
1862: return 0;
1863: }
1864:
1865: /*
1.2 espie 1866: ** Close an output file, assuming it is not stderr or stdout
1867: */
1868: static void output_file_close(FILE *f){
1869: if( f && f!=stdout && f!=stderr ) fclose(f);
1870: }
1871:
1872: /*
1873: ** Try to open an output file. The names "stdout" and "stderr" are
1874: ** recognized and do the right thing. NULL is returned if the output
1875: ** filename is "off".
1876: */
1877: static FILE *output_file_open(const char *zFile){
1878: FILE *f;
1879: if( strcmp(zFile,"stdout")==0 ){
1880: f = stdout;
1881: }else if( strcmp(zFile, "stderr")==0 ){
1882: f = stderr;
1883: }else if( strcmp(zFile, "off")==0 ){
1884: f = 0;
1885: }else{
1886: f = fopen(zFile, "wb");
1887: if( f==0 ){
1888: fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
1889: }
1890: }
1891: return f;
1892: }
1893:
1894: /*
1895: ** A routine for handling output from sqlite3_trace().
1896: */
1897: static void sql_trace_callback(void *pArg, const char *z){
1898: FILE *f = (FILE*)pArg;
1899: if( f ) fprintf(f, "%s\n", z);
1900: }
1901:
1902: /*
1903: ** A no-op routine that runs with the ".breakpoint" doc-command. This is
1904: ** a useful spot to set a debugger breakpoint.
1905: */
1906: static void test_breakpoint(void){
1907: static int nCall = 0;
1908: nCall++;
1909: }
1910:
1911: /*
1.7 jturner 1912: ** An object used to read a CSV file
1913: */
1914: typedef struct CSVReader CSVReader;
1915: struct CSVReader {
1916: const char *zFile; /* Name of the input file */
1917: FILE *in; /* Read the CSV text from this input stream */
1918: char *z; /* Accumulated text for a field */
1919: int n; /* Number of bytes in z */
1920: int nAlloc; /* Space allocated for z[] */
1921: int nLine; /* Current line number */
1922: int cTerm; /* Character that terminated the most recent field */
1923: int cSeparator; /* The separator character. (Usually ",") */
1924: };
1925:
1926: /* Append a single byte to z[] */
1927: static void csv_append_char(CSVReader *p, int c){
1928: if( p->n+1>=p->nAlloc ){
1929: p->nAlloc += p->nAlloc + 100;
1930: p->z = sqlite3_realloc(p->z, p->nAlloc);
1931: if( p->z==0 ){
1932: fprintf(stderr, "out of memory\n");
1933: exit(1);
1934: }
1935: }
1936: p->z[p->n++] = (char)c;
1937: }
1938:
1939: /* Read a single field of CSV text. Compatible with rfc4180 and extended
1940: ** with the option of having a separator other than ",".
1941: **
1942: ** + Input comes from p->in.
1943: ** + Store results in p->z of length p->n. Space to hold p->z comes
1944: ** from sqlite3_malloc().
1945: ** + Use p->cSep as the separator. The default is ",".
1946: ** + Keep track of the line number in p->nLine.
1947: ** + Store the character that terminates the field in p->cTerm. Store
1948: ** EOF on end-of-file.
1949: ** + Report syntax errors on stderr
1950: */
1951: static char *csv_read_one_field(CSVReader *p){
1.8 jturner 1952: int c, pc, ppc;
1.7 jturner 1953: int cSep = p->cSeparator;
1954: p->n = 0;
1955: c = fgetc(p->in);
1956: if( c==EOF || seenInterrupt ){
1957: p->cTerm = EOF;
1958: return 0;
1959: }
1960: if( c=='"' ){
1961: int startLine = p->nLine;
1962: int cQuote = c;
1.8 jturner 1963: pc = ppc = 0;
1.7 jturner 1964: while( 1 ){
1965: c = fgetc(p->in);
1966: if( c=='\n' ) p->nLine++;
1967: if( c==cQuote ){
1968: if( pc==cQuote ){
1969: pc = 0;
1970: continue;
1971: }
1972: }
1973: if( (c==cSep && pc==cQuote)
1974: || (c=='\n' && pc==cQuote)
1.8 jturner 1975: || (c=='\n' && pc=='\r' && ppc==cQuote)
1.7 jturner 1976: || (c==EOF && pc==cQuote)
1977: ){
1978: do{ p->n--; }while( p->z[p->n]!=cQuote );
1979: p->cTerm = c;
1980: break;
1981: }
1982: if( pc==cQuote && c!='\r' ){
1983: fprintf(stderr, "%s:%d: unescaped %c character\n",
1984: p->zFile, p->nLine, cQuote);
1985: }
1986: if( c==EOF ){
1987: fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
1988: p->zFile, startLine, cQuote);
1989: p->cTerm = EOF;
1990: break;
1991: }
1992: csv_append_char(p, c);
1.8 jturner 1993: ppc = pc;
1.7 jturner 1994: pc = c;
1995: }
1996: }else{
1997: while( c!=EOF && c!=cSep && c!='\n' ){
1998: csv_append_char(p, c);
1999: c = fgetc(p->in);
2000: }
2001: if( c=='\n' ){
2002: p->nLine++;
1.8 jturner 2003: if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
1.7 jturner 2004: }
2005: p->cTerm = c;
2006: }
2007: if( p->z ) p->z[p->n] = 0;
2008: return p->z;
2009: }
2010:
2011: /*
1.8 jturner 2012: ** Try to transfer data for table zTable. If an error is seen while
2013: ** moving forward, try to go backwards. The backwards movement won't
2014: ** work for WITHOUT ROWID tables.
2015: */
2016: static void tryToCloneData(
2017: struct callback_data *p,
2018: sqlite3 *newDb,
2019: const char *zTable
2020: ){
2021: sqlite3_stmt *pQuery = 0;
2022: sqlite3_stmt *pInsert = 0;
2023: char *zQuery = 0;
2024: char *zInsert = 0;
2025: int rc;
2026: int i, j, n;
2027: int nTable = (int)strlen(zTable);
2028: int k = 0;
2029: int cnt = 0;
2030: const int spinRate = 10000;
2031:
2032: zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2033: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2034: if( rc ){
2035: fprintf(stderr, "Error %d: %s on [%s]\n",
2036: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2037: zQuery);
2038: goto end_data_xfer;
2039: }
2040: n = sqlite3_column_count(pQuery);
2041: zInsert = sqlite3_malloc(200 + nTable + n*3);
2042: if( zInsert==0 ){
2043: fprintf(stderr, "out of memory\n");
2044: goto end_data_xfer;
2045: }
2046: sqlite3_snprintf(200+nTable,zInsert,
2047: "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2048: i = (int)strlen(zInsert);
2049: for(j=1; j<n; j++){
2050: memcpy(zInsert+i, ",?", 2);
2051: i += 2;
2052: }
2053: memcpy(zInsert+i, ");", 3);
2054: rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2055: if( rc ){
2056: fprintf(stderr, "Error %d: %s on [%s]\n",
2057: sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2058: zQuery);
2059: goto end_data_xfer;
2060: }
2061: for(k=0; k<2; k++){
2062: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2063: for(i=0; i<n; i++){
2064: switch( sqlite3_column_type(pQuery, i) ){
2065: case SQLITE_NULL: {
2066: sqlite3_bind_null(pInsert, i+1);
2067: break;
2068: }
2069: case SQLITE_INTEGER: {
2070: sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2071: break;
2072: }
2073: case SQLITE_FLOAT: {
2074: sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2075: break;
2076: }
2077: case SQLITE_TEXT: {
2078: sqlite3_bind_text(pInsert, i+1,
2079: (const char*)sqlite3_column_text(pQuery,i),
2080: -1, SQLITE_STATIC);
2081: break;
2082: }
2083: case SQLITE_BLOB: {
2084: sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2085: sqlite3_column_bytes(pQuery,i),
2086: SQLITE_STATIC);
2087: break;
2088: }
2089: }
2090: } /* End for */
2091: rc = sqlite3_step(pInsert);
2092: if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2093: fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2094: sqlite3_errmsg(newDb));
2095: }
2096: sqlite3_reset(pInsert);
2097: cnt++;
2098: if( (cnt%spinRate)==0 ){
2099: printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2100: fflush(stdout);
2101: }
2102: } /* End while */
2103: if( rc==SQLITE_DONE ) break;
2104: sqlite3_finalize(pQuery);
2105: sqlite3_free(zQuery);
2106: zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2107: zTable);
2108: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2109: if( rc ){
2110: fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2111: break;
2112: }
2113: } /* End for(k=0...) */
2114:
2115: end_data_xfer:
2116: sqlite3_finalize(pQuery);
2117: sqlite3_finalize(pInsert);
2118: sqlite3_free(zQuery);
2119: sqlite3_free(zInsert);
2120: }
2121:
2122:
2123: /*
2124: ** Try to transfer all rows of the schema that match zWhere. For
2125: ** each row, invoke xForEach() on the object defined by that row.
2126: ** If an error is encountered while moving forward through the
2127: ** sqlite_master table, try again moving backwards.
2128: */
2129: static void tryToCloneSchema(
2130: struct callback_data *p,
2131: sqlite3 *newDb,
2132: const char *zWhere,
2133: void (*xForEach)(struct callback_data*,sqlite3*,const char*)
2134: ){
2135: sqlite3_stmt *pQuery = 0;
2136: char *zQuery = 0;
2137: int rc;
2138: const unsigned char *zName;
2139: const unsigned char *zSql;
2140: char *zErrMsg = 0;
2141:
2142: zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2143: " WHERE %s", zWhere);
2144: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2145: if( rc ){
2146: fprintf(stderr, "Error: (%d) %s on [%s]\n",
2147: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2148: zQuery);
2149: goto end_schema_xfer;
2150: }
2151: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2152: zName = sqlite3_column_text(pQuery, 0);
2153: zSql = sqlite3_column_text(pQuery, 1);
2154: printf("%s... ", zName); fflush(stdout);
2155: sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2156: if( zErrMsg ){
2157: fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2158: sqlite3_free(zErrMsg);
2159: zErrMsg = 0;
2160: }
2161: if( xForEach ){
2162: xForEach(p, newDb, (const char*)zName);
2163: }
2164: printf("done\n");
2165: }
2166: if( rc!=SQLITE_DONE ){
2167: sqlite3_finalize(pQuery);
2168: sqlite3_free(zQuery);
2169: zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2170: " WHERE %s ORDER BY rowid DESC", zWhere);
2171: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2172: if( rc ){
2173: fprintf(stderr, "Error: (%d) %s on [%s]\n",
2174: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2175: zQuery);
2176: goto end_schema_xfer;
2177: }
2178: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2179: zName = sqlite3_column_text(pQuery, 0);
2180: zSql = sqlite3_column_text(pQuery, 1);
2181: printf("%s... ", zName); fflush(stdout);
2182: sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2183: if( zErrMsg ){
2184: fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2185: sqlite3_free(zErrMsg);
2186: zErrMsg = 0;
2187: }
2188: if( xForEach ){
2189: xForEach(p, newDb, (const char*)zName);
2190: }
2191: printf("done\n");
2192: }
2193: }
2194: end_schema_xfer:
2195: sqlite3_finalize(pQuery);
2196: sqlite3_free(zQuery);
2197: }
2198:
2199: /*
2200: ** Open a new database file named "zNewDb". Try to recover as much information
2201: ** as possible out of the main database (which might be corrupt) and write it
2202: ** into zNewDb.
2203: */
2204: static void tryToClone(struct callback_data *p, const char *zNewDb){
2205: int rc;
2206: sqlite3 *newDb = 0;
2207: if( access(zNewDb,0)==0 ){
2208: fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2209: return;
2210: }
2211: rc = sqlite3_open(zNewDb, &newDb);
2212: if( rc ){
2213: fprintf(stderr, "Cannot create output database: %s\n",
2214: sqlite3_errmsg(newDb));
2215: }else{
1.9 ! jturner 2216: sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
1.8 jturner 2217: sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
2218: tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2219: tryToCloneSchema(p, newDb, "type!='table'", 0);
2220: sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
1.9 ! jturner 2221: sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1.8 jturner 2222: }
2223: sqlite3_close(newDb);
2224: }
2225:
2226: /*
1.9 ! jturner 2227: ** Change the output file back to stdout
! 2228: */
! 2229: static void output_reset(struct callback_data *p){
! 2230: if( p->outfile[0]=='|' ){
! 2231: pclose(p->out);
! 2232: }else{
! 2233: output_file_close(p->out);
! 2234: }
! 2235: p->outfile[0] = 0;
! 2236: p->out = stdout;
! 2237: }
! 2238:
! 2239: /*
1.1 espie 2240: ** If an input line begins with "." then invoke this routine to
2241: ** process that line.
2242: **
2243: ** Return 1 on error, 2 to exit, and 0 otherwise.
2244: */
2245: static int do_meta_command(char *zLine, struct callback_data *p){
2246: int i = 1;
2247: int nArg = 0;
2248: int n, c;
2249: int rc = 0;
2250: char *azArg[50];
2251:
2252: /* Parse the input line into tokens.
2253: */
2254: while( zLine[i] && nArg<ArraySize(azArg) ){
2255: while( IsSpace(zLine[i]) ){ i++; }
2256: if( zLine[i]==0 ) break;
2257: if( zLine[i]=='\'' || zLine[i]=='"' ){
2258: int delim = zLine[i++];
2259: azArg[nArg++] = &zLine[i];
1.7 jturner 2260: while( zLine[i] && zLine[i]!=delim ){
2261: if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2262: i++;
2263: }
1.1 espie 2264: if( zLine[i]==delim ){
2265: zLine[i++] = 0;
2266: }
2267: if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
2268: }else{
2269: azArg[nArg++] = &zLine[i];
2270: while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
2271: if( zLine[i] ) zLine[i++] = 0;
2272: resolve_backslashes(azArg[nArg-1]);
2273: }
2274: }
2275:
2276: /* Process the input line.
2277: */
2278: if( nArg==0 ) return 0; /* no tokens, no error */
2279: n = strlen30(azArg[0]);
2280: c = azArg[0][0];
1.8 jturner 2281: if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2282: || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2283: ){
1.6 landry 2284: const char *zDestFile = 0;
2285: const char *zDb = 0;
1.1 espie 2286: sqlite3 *pDest;
2287: sqlite3_backup *pBackup;
1.6 landry 2288: int j;
2289: for(j=1; j<nArg; j++){
2290: const char *z = azArg[j];
2291: if( z[0]=='-' ){
2292: while( z[0]=='-' ) z++;
1.7 jturner 2293: /* No options to process at this time */
1.6 landry 2294: {
2295: fprintf(stderr, "unknown option: %s\n", azArg[j]);
2296: return 1;
2297: }
2298: }else if( zDestFile==0 ){
2299: zDestFile = azArg[j];
2300: }else if( zDb==0 ){
2301: zDb = zDestFile;
2302: zDestFile = azArg[j];
2303: }else{
2304: fprintf(stderr, "too many arguments to .backup\n");
2305: return 1;
2306: }
2307: }
2308: if( zDestFile==0 ){
2309: fprintf(stderr, "missing FILENAME argument on .backup\n");
2310: return 1;
1.1 espie 2311: }
1.6 landry 2312: if( zDb==0 ) zDb = "main";
1.1 espie 2313: rc = sqlite3_open(zDestFile, &pDest);
2314: if( rc!=SQLITE_OK ){
2315: fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
2316: sqlite3_close(pDest);
2317: return 1;
2318: }
1.8 jturner 2319: open_db(p, 0);
1.1 espie 2320: pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2321: if( pBackup==0 ){
2322: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2323: sqlite3_close(pDest);
2324: return 1;
2325: }
2326: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2327: sqlite3_backup_finish(pBackup);
2328: if( rc==SQLITE_DONE ){
2329: rc = 0;
2330: }else{
2331: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2332: rc = 1;
2333: }
2334: sqlite3_close(pDest);
2335: }else
2336:
1.9 ! jturner 2337: if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
! 2338: if( nArg==2 ){
! 2339: bail_on_error = booleanValue(azArg[1]);
! 2340: }else{
! 2341: fprintf(stderr, "Usage: .bail on|off\n");
! 2342: rc = 1;
! 2343: }
1.1 espie 2344: }else
2345:
1.2 espie 2346: /* The undocumented ".breakpoint" command causes a call to the no-op
2347: ** routine named test_breakpoint().
2348: */
2349: if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2350: test_breakpoint();
2351: }else
2352:
1.9 ! jturner 2353: if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
! 2354: if( nArg==2 ){
! 2355: tryToClone(p, azArg[1]);
! 2356: }else{
! 2357: fprintf(stderr, "Usage: .clone FILENAME\n");
! 2358: rc = 1;
! 2359: }
1.8 jturner 2360: }else
2361:
1.9 ! jturner 2362: if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
1.1 espie 2363: struct callback_data data;
2364: char *zErrMsg = 0;
1.8 jturner 2365: open_db(p, 0);
1.1 espie 2366: memcpy(&data, p, sizeof(data));
2367: data.showHeader = 1;
2368: data.mode = MODE_Column;
2369: data.colWidth[0] = 3;
2370: data.colWidth[1] = 15;
2371: data.colWidth[2] = 58;
2372: data.cnt = 0;
2373: sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
2374: if( zErrMsg ){
2375: fprintf(stderr,"Error: %s\n", zErrMsg);
2376: sqlite3_free(zErrMsg);
2377: rc = 1;
2378: }
2379: }else
2380:
1.9 ! jturner 2381: if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1.8 jturner 2382: open_db(p, 0);
1.1 espie 2383: /* When playing back a "dump", the content might appear in an order
2384: ** which causes immediate foreign key constraints to be violated.
2385: ** So disable foreign-key constraint enforcement to prevent problems. */
1.9 ! jturner 2386: if( nArg!=1 && nArg!=2 ){
! 2387: fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
! 2388: rc = 1;
! 2389: goto meta_command_exit;
! 2390: }
1.1 espie 2391: fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
2392: fprintf(p->out, "BEGIN TRANSACTION;\n");
2393: p->writableSchema = 0;
2394: sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
2395: p->nErr = 0;
2396: if( nArg==1 ){
2397: run_schema_dump_query(p,
2398: "SELECT name, type, sql FROM sqlite_master "
2399: "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
2400: );
2401: run_schema_dump_query(p,
2402: "SELECT name, type, sql FROM sqlite_master "
2403: "WHERE name=='sqlite_sequence'"
2404: );
2405: run_table_dump_query(p,
2406: "SELECT sql FROM sqlite_master "
2407: "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
2408: );
2409: }else{
2410: int i;
2411: for(i=1; i<nArg; i++){
2412: zShellStatic = azArg[i];
2413: run_schema_dump_query(p,
2414: "SELECT name, type, sql FROM sqlite_master "
2415: "WHERE tbl_name LIKE shellstatic() AND type=='table'"
2416: " AND sql NOT NULL");
2417: run_table_dump_query(p,
2418: "SELECT sql FROM sqlite_master "
2419: "WHERE sql NOT NULL"
2420: " AND type IN ('index','trigger','view')"
2421: " AND tbl_name LIKE shellstatic()", 0
2422: );
2423: zShellStatic = 0;
2424: }
2425: }
2426: if( p->writableSchema ){
2427: fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
2428: p->writableSchema = 0;
2429: }
2430: sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2431: sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
2432: fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
2433: }else
2434:
1.9 ! jturner 2435: if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
! 2436: if( nArg==2 ){
! 2437: p->echoOn = booleanValue(azArg[1]);
! 2438: }else{
! 2439: fprintf(stderr, "Usage: .echo on|off\n");
! 2440: rc = 1;
! 2441: }
1.1 espie 2442: }else
2443:
1.9 ! jturner 2444: if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
! 2445: if( nArg==2 ){
! 2446: p->autoEQP = booleanValue(azArg[1]);
! 2447: }else{
! 2448: fprintf(stderr, "Usage: .eqp on|off\n");
! 2449: rc = 1;
! 2450: }
1.8 jturner 2451: }else
2452:
1.6 landry 2453: if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
1.7 jturner 2454: if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
1.1 espie 2455: rc = 2;
2456: }else
2457:
1.9 ! jturner 2458: if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
1.1 espie 2459: int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
2460: if(val == 1) {
2461: if(!p->explainPrev.valid) {
2462: p->explainPrev.valid = 1;
2463: p->explainPrev.mode = p->mode;
2464: p->explainPrev.showHeader = p->showHeader;
2465: memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
2466: }
2467: /* We could put this code under the !p->explainValid
2468: ** condition so that it does not execute if we are already in
2469: ** explain mode. However, always executing it allows us an easy
2470: ** was to reset to explain mode in case the user previously
2471: ** did an .explain followed by a .width, .mode or .header
2472: ** command.
2473: */
2474: p->mode = MODE_Explain;
2475: p->showHeader = 1;
1.8 jturner 2476: memset(p->colWidth,0,sizeof(p->colWidth));
1.1 espie 2477: p->colWidth[0] = 4; /* addr */
2478: p->colWidth[1] = 13; /* opcode */
2479: p->colWidth[2] = 4; /* P1 */
2480: p->colWidth[3] = 4; /* P2 */
2481: p->colWidth[4] = 4; /* P3 */
2482: p->colWidth[5] = 13; /* P4 */
2483: p->colWidth[6] = 2; /* P5 */
2484: p->colWidth[7] = 13; /* Comment */
2485: }else if (p->explainPrev.valid) {
2486: p->explainPrev.valid = 0;
2487: p->mode = p->explainPrev.mode;
2488: p->showHeader = p->explainPrev.showHeader;
2489: memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2490: }
2491: }else
2492:
1.9 ! jturner 2493: if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
! 2494: struct callback_data data;
! 2495: char *zErrMsg = 0;
! 2496: int doStats = 0;
! 2497: if( nArg!=1 ){
! 2498: fprintf(stderr, "Usage: .fullschema\n");
! 2499: rc = 1;
! 2500: goto meta_command_exit;
! 2501: }
! 2502: open_db(p, 0);
! 2503: memcpy(&data, p, sizeof(data));
! 2504: data.showHeader = 0;
! 2505: data.mode = MODE_Semi;
! 2506: rc = sqlite3_exec(p->db,
! 2507: "SELECT sql FROM"
! 2508: " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
! 2509: " FROM sqlite_master UNION ALL"
! 2510: " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
! 2511: "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
! 2512: "ORDER BY rowid",
! 2513: callback, &data, &zErrMsg
! 2514: );
! 2515: if( rc==SQLITE_OK ){
! 2516: sqlite3_stmt *pStmt;
! 2517: rc = sqlite3_prepare_v2(p->db,
! 2518: "SELECT rowid FROM sqlite_master"
! 2519: " WHERE name GLOB 'sqlite_stat[134]'",
! 2520: -1, &pStmt, 0);
! 2521: doStats = sqlite3_step(pStmt)==SQLITE_ROW;
! 2522: sqlite3_finalize(pStmt);
! 2523: }
! 2524: if( doStats==0 ){
! 2525: fprintf(p->out, "/* No STAT tables available */\n");
! 2526: }else{
! 2527: fprintf(p->out, "ANALYZE sqlite_master;\n");
! 2528: sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
! 2529: callback, &data, &zErrMsg);
! 2530: data.mode = MODE_Insert;
! 2531: data.zDestTable = "sqlite_stat1";
! 2532: shell_exec(p->db, "SELECT * FROM sqlite_stat1",
! 2533: shell_callback, &data,&zErrMsg);
! 2534: data.zDestTable = "sqlite_stat3";
! 2535: shell_exec(p->db, "SELECT * FROM sqlite_stat3",
! 2536: shell_callback, &data,&zErrMsg);
! 2537: data.zDestTable = "sqlite_stat4";
! 2538: shell_exec(p->db, "SELECT * FROM sqlite_stat4",
! 2539: shell_callback, &data, &zErrMsg);
! 2540: fprintf(p->out, "ANALYZE sqlite_master;\n");
! 2541: }
! 2542: }else
! 2543:
! 2544: if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
! 2545: if( nArg==2 ){
! 2546: p->showHeader = booleanValue(azArg[1]);
! 2547: }else{
! 2548: fprintf(stderr, "Usage: .headers on|off\n");
! 2549: rc = 1;
! 2550: }
1.1 espie 2551: }else
2552:
2553: if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1.9 ! jturner 2554: fprintf(p->out, "%s", zHelp);
1.1 espie 2555: }else
2556:
1.9 ! jturner 2557: if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
! 2558: char *zTable; /* Insert data into this table */
! 2559: char *zFile; /* Name of file to extra content from */
1.1 espie 2560: sqlite3_stmt *pStmt = NULL; /* A statement */
2561: int nCol; /* Number of columns in the table */
2562: int nByte; /* Number of bytes in an SQL string */
2563: int i, j; /* Loop counters */
1.7 jturner 2564: int needCommit; /* True to COMMIT or ROLLBACK at end */
1.1 espie 2565: int nSep; /* Number of bytes in p->separator[] */
2566: char *zSql; /* An SQL statement */
1.7 jturner 2567: CSVReader sCsv; /* Reader context */
2568: int (*xCloser)(FILE*); /* Procedure to close th3 connection */
1.1 espie 2569:
1.9 ! jturner 2570: if( nArg!=3 ){
! 2571: fprintf(stderr, "Usage: .import FILE TABLE\n");
! 2572: goto meta_command_exit;
! 2573: }
! 2574: zFile = azArg[1];
! 2575: zTable = azArg[2];
1.7 jturner 2576: seenInterrupt = 0;
2577: memset(&sCsv, 0, sizeof(sCsv));
1.8 jturner 2578: open_db(p, 0);
1.1 espie 2579: nSep = strlen30(p->separator);
2580: if( nSep==0 ){
2581: fprintf(stderr, "Error: non-null separator required for import\n");
2582: return 1;
2583: }
1.7 jturner 2584: if( nSep>1 ){
2585: fprintf(stderr, "Error: multi-character separators not allowed"
2586: " for import\n");
2587: return 1;
2588: }
2589: sCsv.zFile = zFile;
2590: sCsv.nLine = 1;
2591: if( sCsv.zFile[0]=='|' ){
2592: sCsv.in = popen(sCsv.zFile+1, "r");
2593: sCsv.zFile = "<pipe>";
2594: xCloser = pclose;
2595: }else{
2596: sCsv.in = fopen(sCsv.zFile, "rb");
2597: xCloser = fclose;
2598: }
2599: if( sCsv.in==0 ){
2600: fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2601: return 1;
2602: }
2603: sCsv.cSeparator = p->separator[0];
1.1 espie 2604: zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
2605: if( zSql==0 ){
2606: fprintf(stderr, "Error: out of memory\n");
1.7 jturner 2607: xCloser(sCsv.in);
1.1 espie 2608: return 1;
2609: }
2610: nByte = strlen30(zSql);
1.8 jturner 2611: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
1.9 ! jturner 2612: csv_append_char(&sCsv, 0); /* To ensure sCsv.z is allocated */
1.7 jturner 2613: if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2614: char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2615: char cSep = '(';
2616: while( csv_read_one_field(&sCsv) ){
2617: zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
2618: cSep = ',';
2619: if( sCsv.cTerm!=sCsv.cSeparator ) break;
2620: }
2621: if( cSep=='(' ){
2622: sqlite3_free(zCreate);
2623: sqlite3_free(sCsv.z);
2624: xCloser(sCsv.in);
2625: fprintf(stderr,"%s: empty file\n", sCsv.zFile);
2626: return 1;
2627: }
2628: zCreate = sqlite3_mprintf("%z\n)", zCreate);
2629: rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2630: sqlite3_free(zCreate);
2631: if( rc ){
2632: fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2633: sqlite3_errmsg(db));
2634: sqlite3_free(sCsv.z);
2635: xCloser(sCsv.in);
2636: return 1;
2637: }
1.8 jturner 2638: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
1.7 jturner 2639: }
1.1 espie 2640: sqlite3_free(zSql);
2641: if( rc ){
2642: if (pStmt) sqlite3_finalize(pStmt);
2643: fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
1.7 jturner 2644: xCloser(sCsv.in);
1.1 espie 2645: return 1;
2646: }
2647: nCol = sqlite3_column_count(pStmt);
2648: sqlite3_finalize(pStmt);
2649: pStmt = 0;
2650: if( nCol==0 ) return 0; /* no columns, no error */
1.7 jturner 2651: zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
1.1 espie 2652: if( zSql==0 ){
2653: fprintf(stderr, "Error: out of memory\n");
1.7 jturner 2654: xCloser(sCsv.in);
1.1 espie 2655: return 1;
2656: }
1.7 jturner 2657: sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
1.1 espie 2658: j = strlen30(zSql);
2659: for(i=1; i<nCol; i++){
2660: zSql[j++] = ',';
2661: zSql[j++] = '?';
2662: }
2663: zSql[j++] = ')';
2664: zSql[j] = 0;
1.8 jturner 2665: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
1.7 jturner 2666: sqlite3_free(zSql);
1.1 espie 2667: if( rc ){
2668: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
2669: if (pStmt) sqlite3_finalize(pStmt);
1.7 jturner 2670: xCloser(sCsv.in);
1.1 espie 2671: return 1;
2672: }
1.7 jturner 2673: needCommit = sqlite3_get_autocommit(db);
2674: if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
2675: do{
2676: int startLine = sCsv.nLine;
2677: for(i=0; i<nCol; i++){
2678: char *z = csv_read_one_field(&sCsv);
2679: if( z==0 && i==0 ) break;
2680: sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
2681: if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
2682: fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2683: "filling the rest with NULL\n",
2684: sCsv.zFile, startLine, nCol, i+1);
1.1 espie 2685: i++;
1.9 ! jturner 2686: while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
1.1 espie 2687: }
2688: }
1.7 jturner 2689: if( sCsv.cTerm==sCsv.cSeparator ){
2690: do{
2691: csv_read_one_field(&sCsv);
2692: i++;
2693: }while( sCsv.cTerm==sCsv.cSeparator );
2694: fprintf(stderr, "%s:%d: expected %d columns but found %d - "
2695: "extras ignored\n",
2696: sCsv.zFile, startLine, nCol, i);
2697: }
2698: if( i>=nCol ){
2699: sqlite3_step(pStmt);
2700: rc = sqlite3_reset(pStmt);
2701: if( rc!=SQLITE_OK ){
2702: fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
2703: sqlite3_errmsg(db));
1.1 espie 2704: }
2705: }
1.7 jturner 2706: }while( sCsv.cTerm!=EOF );
2707:
2708: xCloser(sCsv.in);
2709: sqlite3_free(sCsv.z);
1.1 espie 2710: sqlite3_finalize(pStmt);
1.7 jturner 2711: if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
1.1 espie 2712: }else
2713:
1.9 ! jturner 2714: if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
1.1 espie 2715: struct callback_data data;
2716: char *zErrMsg = 0;
1.8 jturner 2717: open_db(p, 0);
1.1 espie 2718: memcpy(&data, p, sizeof(data));
2719: data.showHeader = 0;
2720: data.mode = MODE_List;
2721: if( nArg==1 ){
2722: rc = sqlite3_exec(p->db,
2723: "SELECT name FROM sqlite_master "
2724: "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
2725: "UNION ALL "
2726: "SELECT name FROM sqlite_temp_master "
2727: "WHERE type='index' "
2728: "ORDER BY 1",
2729: callback, &data, &zErrMsg
2730: );
1.9 ! jturner 2731: }else if( nArg==2 ){
1.1 espie 2732: zShellStatic = azArg[1];
2733: rc = sqlite3_exec(p->db,
2734: "SELECT name FROM sqlite_master "
2735: "WHERE type='index' AND tbl_name LIKE shellstatic() "
2736: "UNION ALL "
2737: "SELECT name FROM sqlite_temp_master "
2738: "WHERE type='index' AND tbl_name LIKE shellstatic() "
2739: "ORDER BY 1",
2740: callback, &data, &zErrMsg
2741: );
2742: zShellStatic = 0;
1.9 ! jturner 2743: }else{
! 2744: fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
! 2745: rc = 1;
! 2746: goto meta_command_exit;
1.1 espie 2747: }
2748: if( zErrMsg ){
2749: fprintf(stderr,"Error: %s\n", zErrMsg);
2750: sqlite3_free(zErrMsg);
2751: rc = 1;
2752: }else if( rc != SQLITE_OK ){
2753: fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
2754: rc = 1;
2755: }
2756: }else
2757:
2758: #ifdef SQLITE_ENABLE_IOTRACE
2759: if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
2760: extern void (*sqlite3IoTrace)(const char*, ...);
2761: if( iotrace && iotrace!=stdout ) fclose(iotrace);
2762: iotrace = 0;
2763: if( nArg<2 ){
2764: sqlite3IoTrace = 0;
2765: }else if( strcmp(azArg[1], "-")==0 ){
2766: sqlite3IoTrace = iotracePrintf;
2767: iotrace = stdout;
2768: }else{
2769: iotrace = fopen(azArg[1], "w");
2770: if( iotrace==0 ){
2771: fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
2772: sqlite3IoTrace = 0;
2773: rc = 1;
2774: }else{
2775: sqlite3IoTrace = iotracePrintf;
2776: }
2777: }
2778: }else
2779: #endif
2780:
2781: #ifndef SQLITE_OMIT_LOAD_EXTENSION
1.9 ! jturner 2782: if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
1.1 espie 2783: const char *zFile, *zProc;
2784: char *zErrMsg = 0;
1.9 ! jturner 2785: if( nArg<2 ){
! 2786: fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
! 2787: rc = 1;
! 2788: goto meta_command_exit;
! 2789: }
1.1 espie 2790: zFile = azArg[1];
2791: zProc = nArg>=3 ? azArg[2] : 0;
1.8 jturner 2792: open_db(p, 0);
1.1 espie 2793: rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
2794: if( rc!=SQLITE_OK ){
2795: fprintf(stderr, "Error: %s\n", zErrMsg);
2796: sqlite3_free(zErrMsg);
2797: rc = 1;
2798: }
2799: }else
2800: #endif
2801:
1.9 ! jturner 2802: if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
! 2803: if( nArg!=2 ){
! 2804: fprintf(stderr, "Usage: .log FILENAME\n");
! 2805: rc = 1;
! 2806: }else{
! 2807: const char *zFile = azArg[1];
! 2808: output_file_close(p->pLog);
! 2809: p->pLog = output_file_open(zFile);
! 2810: }
1.1 espie 2811: }else
2812:
1.9 ! jturner 2813: if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
! 2814: const char *zMode = nArg>=2 ? azArg[1] : "";
! 2815: int n2 = (int)strlen(zMode);
! 2816: int c2 = zMode[0];
! 2817: if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
1.1 espie 2818: p->mode = MODE_Line;
1.9 ! jturner 2819: }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
1.1 espie 2820: p->mode = MODE_Column;
1.9 ! jturner 2821: }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
1.1 espie 2822: p->mode = MODE_List;
1.9 ! jturner 2823: }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
1.1 espie 2824: p->mode = MODE_Html;
1.9 ! jturner 2825: }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
1.1 espie 2826: p->mode = MODE_Tcl;
1.5 espie 2827: sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
1.9 ! jturner 2828: }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
1.1 espie 2829: p->mode = MODE_Csv;
2830: sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
1.9 ! jturner 2831: sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n");
! 2832: }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
1.1 espie 2833: p->mode = MODE_List;
2834: sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
1.9 ! jturner 2835: }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
1.1 espie 2836: p->mode = MODE_Insert;
1.9 ! jturner 2837: set_table_name(p, nArg>=3 ? azArg[2] : "table");
1.1 espie 2838: }else {
2839: fprintf(stderr,"Error: mode should be one of: "
2840: "column csv html insert line list tabs tcl\n");
2841: rc = 1;
2842: }
2843: }else
2844:
1.9 ! jturner 2845: if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
! 2846: if( nArg==2 ){
! 2847: sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
! 2848: "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
! 2849: }else{
! 2850: fprintf(stderr, "Usage: .nullvalue STRING\n");
1.1 espie 2851: rc = 1;
2852: }
2853: }else
2854:
1.8 jturner 2855: if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
2856: sqlite3 *savedDb = p->db;
2857: const char *zSavedFilename = p->zDbFilename;
2858: char *zNewFilename = 0;
2859: p->db = 0;
2860: if( nArg>=2 ){
2861: p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
2862: }
2863: open_db(p, 1);
2864: if( p->db!=0 ){
2865: sqlite3_close(savedDb);
2866: sqlite3_free(p->zFreeOnClose);
2867: p->zFreeOnClose = zNewFilename;
2868: }else{
2869: sqlite3_free(zNewFilename);
2870: p->db = savedDb;
2871: p->zDbFilename = zSavedFilename;
2872: }
2873: }else
2874:
1.9 ! jturner 2875: if( c=='o'
! 2876: && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
! 2877: ){
! 2878: const char *zFile = nArg>=2 ? azArg[1] : "stdout";
! 2879: if( nArg>2 ){
! 2880: fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
! 2881: rc = 1;
! 2882: goto meta_command_exit;
! 2883: }
! 2884: if( n>1 && strncmp(azArg[0], "once", n)==0 ){
! 2885: if( nArg<2 ){
! 2886: fprintf(stderr, "Usage: .once FILE\n");
! 2887: rc = 1;
! 2888: goto meta_command_exit;
! 2889: }
! 2890: p->outCount = 2;
! 2891: }else{
! 2892: p->outCount = 0;
! 2893: }
! 2894: output_reset(p);
! 2895: if( zFile[0]=='|' ){
! 2896: p->out = popen(zFile + 1, "w");
1.2 espie 2897: if( p->out==0 ){
1.9 ! jturner 2898: fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
1.2 espie 2899: p->out = stdout;
2900: rc = 1;
2901: }else{
1.9 ! jturner 2902: sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
1.2 espie 2903: }
1.1 espie 2904: }else{
1.9 ! jturner 2905: p->out = output_file_open(zFile);
1.1 espie 2906: if( p->out==0 ){
1.9 ! jturner 2907: if( strcmp(zFile,"off")!=0 ){
! 2908: fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
1.2 espie 2909: }
1.1 espie 2910: p->out = stdout;
2911: rc = 1;
2912: } else {
1.9 ! jturner 2913: sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
1.1 espie 2914: }
2915: }
2916: }else
2917:
1.5 espie 2918: if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
2919: int i;
2920: for(i=1; i<nArg; i++){
2921: if( i>1 ) fprintf(p->out, " ");
2922: fprintf(p->out, "%s", azArg[i]);
2923: }
2924: fprintf(p->out, "\n");
2925: }else
2926:
1.9 ! jturner 2927: if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
1.1 espie 2928: if( nArg >= 2) {
2929: strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
2930: }
2931: if( nArg >= 3) {
2932: strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
2933: }
2934: }else
2935:
1.9 ! jturner 2936: if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
1.1 espie 2937: rc = 2;
2938: }else
2939:
1.9 ! jturner 2940: if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
! 2941: FILE *alt;
! 2942: if( nArg!=2 ){
! 2943: fprintf(stderr, "Usage: .read FILE\n");
! 2944: rc = 1;
! 2945: goto meta_command_exit;
! 2946: }
! 2947: alt = fopen(azArg[1], "rb");
1.1 espie 2948: if( alt==0 ){
2949: fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
2950: rc = 1;
2951: }else{
2952: rc = process_input(p, alt);
2953: fclose(alt);
2954: }
2955: }else
2956:
1.9 ! jturner 2957: if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
1.1 espie 2958: const char *zSrcFile;
2959: const char *zDb;
2960: sqlite3 *pSrc;
2961: sqlite3_backup *pBackup;
2962: int nTimeout = 0;
2963:
2964: if( nArg==2 ){
2965: zSrcFile = azArg[1];
2966: zDb = "main";
1.9 ! jturner 2967: }else if( nArg==3 ){
1.1 espie 2968: zSrcFile = azArg[2];
2969: zDb = azArg[1];
1.9 ! jturner 2970: }else{
! 2971: fprintf(stderr, "Usage: .restore ?DB? FILE\n");
! 2972: rc = 1;
! 2973: goto meta_command_exit;
1.1 espie 2974: }
2975: rc = sqlite3_open(zSrcFile, &pSrc);
2976: if( rc!=SQLITE_OK ){
2977: fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
2978: sqlite3_close(pSrc);
2979: return 1;
2980: }
1.8 jturner 2981: open_db(p, 0);
1.1 espie 2982: pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
2983: if( pBackup==0 ){
2984: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
2985: sqlite3_close(pSrc);
2986: return 1;
2987: }
2988: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2989: || rc==SQLITE_BUSY ){
2990: if( rc==SQLITE_BUSY ){
2991: if( nTimeout++ >= 3 ) break;
2992: sqlite3_sleep(100);
2993: }
2994: }
2995: sqlite3_backup_finish(pBackup);
2996: if( rc==SQLITE_DONE ){
2997: rc = 0;
2998: }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2999: fprintf(stderr, "Error: source database is busy\n");
3000: rc = 1;
3001: }else{
3002: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3003: rc = 1;
3004: }
3005: sqlite3_close(pSrc);
3006: }else
3007:
1.9 ! jturner 3008: if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1.1 espie 3009: struct callback_data data;
3010: char *zErrMsg = 0;
1.8 jturner 3011: open_db(p, 0);
1.1 espie 3012: memcpy(&data, p, sizeof(data));
3013: data.showHeader = 0;
3014: data.mode = MODE_Semi;
1.9 ! jturner 3015: if( nArg==2 ){
1.1 espie 3016: int i;
3017: for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
3018: if( strcmp(azArg[1],"sqlite_master")==0 ){
3019: char *new_argv[2], *new_colv[2];
3020: new_argv[0] = "CREATE TABLE sqlite_master (\n"
3021: " type text,\n"
3022: " name text,\n"
3023: " tbl_name text,\n"
3024: " rootpage integer,\n"
3025: " sql text\n"
3026: ")";
3027: new_argv[1] = 0;
3028: new_colv[0] = "sql";
3029: new_colv[1] = 0;
3030: callback(&data, 1, new_argv, new_colv);
3031: rc = SQLITE_OK;
3032: }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
3033: char *new_argv[2], *new_colv[2];
3034: new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3035: " type text,\n"
3036: " name text,\n"
3037: " tbl_name text,\n"
3038: " rootpage integer,\n"
3039: " sql text\n"
3040: ")";
3041: new_argv[1] = 0;
3042: new_colv[0] = "sql";
3043: new_colv[1] = 0;
3044: callback(&data, 1, new_argv, new_colv);
3045: rc = SQLITE_OK;
3046: }else{
3047: zShellStatic = azArg[1];
3048: rc = sqlite3_exec(p->db,
3049: "SELECT sql FROM "
1.3 espie 3050: " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
1.1 espie 3051: " FROM sqlite_master UNION ALL"
1.3 espie 3052: " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
1.1 espie 3053: "WHERE lower(tbl_name) LIKE shellstatic()"
3054: " AND type!='meta' AND sql NOTNULL "
1.6 landry 3055: "ORDER BY rowid",
1.1 espie 3056: callback, &data, &zErrMsg);
3057: zShellStatic = 0;
3058: }
1.9 ! jturner 3059: }else if( nArg==1 ){
1.1 espie 3060: rc = sqlite3_exec(p->db,
3061: "SELECT sql FROM "
1.3 espie 3062: " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
1.1 espie 3063: " FROM sqlite_master UNION ALL"
1.3 espie 3064: " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
1.1 espie 3065: "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
1.6 landry 3066: "ORDER BY rowid",
1.1 espie 3067: callback, &data, &zErrMsg
3068: );
1.9 ! jturner 3069: }else{
! 3070: fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
! 3071: rc = 1;
! 3072: goto meta_command_exit;
1.1 espie 3073: }
3074: if( zErrMsg ){
3075: fprintf(stderr,"Error: %s\n", zErrMsg);
3076: sqlite3_free(zErrMsg);
3077: rc = 1;
3078: }else if( rc != SQLITE_OK ){
3079: fprintf(stderr,"Error: querying schema information\n");
3080: rc = 1;
3081: }else{
3082: rc = 0;
3083: }
3084: }else
3085:
1.7 jturner 3086: #ifdef SQLITE_DEBUG
3087: /* Undocumented commands for internal testing. Subject to change
3088: ** without notice. */
3089: if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3090: if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3091: int i, v;
3092: for(i=1; i<nArg; i++){
3093: v = booleanValue(azArg[i]);
3094: fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3095: }
3096: }
3097: if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3098: int i; sqlite3_int64 v;
3099: for(i=1; i<nArg; i++){
3100: char zBuf[200];
3101: v = integerValue(azArg[i]);
1.9 ! jturner 3102: sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
1.7 jturner 3103: fprintf(p->out, "%s", zBuf);
3104: }
3105: }
3106: }else
3107: #endif
3108:
1.9 ! jturner 3109: if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
! 3110: if( nArg<2 || nArg>3 ){
! 3111: fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n");
! 3112: rc = 1;
! 3113: }
! 3114: if( nArg>=2 ){
! 3115: sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]);
! 3116: }
! 3117: if( nArg>=3 ){
! 3118: sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]);
! 3119: }
! 3120: }else
! 3121:
! 3122: if( c=='s'
! 3123: && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
! 3124: ){
! 3125: char *zCmd;
! 3126: int i, x;
! 3127: if( nArg<2 ){
! 3128: fprintf(stderr, "Usage: .system COMMAND\n");
! 3129: rc = 1;
! 3130: goto meta_command_exit;
! 3131: }
! 3132: zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
! 3133: for(i=2; i<nArg; i++){
! 3134: zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
! 3135: zCmd, azArg[i]);
! 3136: }
! 3137: x = system(zCmd);
! 3138: sqlite3_free(zCmd);
! 3139: if( x ) fprintf(stderr, "System command returns %d\n", x);
1.1 espie 3140: }else
3141:
1.9 ! jturner 3142: if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
1.1 espie 3143: int i;
1.9 ! jturner 3144: if( nArg!=1 ){
! 3145: fprintf(stderr, "Usage: .show\n");
! 3146: rc = 1;
! 3147: goto meta_command_exit;
! 3148: }
1.1 espie 3149: fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
1.8 jturner 3150: fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
1.1 espie 3151: fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
3152: fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
3153: fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
3154: fprintf(p->out,"%9.9s: ", "nullvalue");
3155: output_c_string(p->out, p->nullvalue);
3156: fprintf(p->out, "\n");
3157: fprintf(p->out,"%9.9s: %s\n","output",
3158: strlen30(p->outfile) ? p->outfile : "stdout");
3159: fprintf(p->out,"%9.9s: ", "separator");
3160: output_c_string(p->out, p->separator);
1.9 ! jturner 3161: fprintf(p->out," ");
! 3162: output_c_string(p->out, p->newline);
1.1 espie 3163: fprintf(p->out, "\n");
3164: fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
3165: fprintf(p->out,"%9.9s: ","width");
3166: for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
3167: fprintf(p->out,"%d ",p->colWidth[i]);
3168: }
3169: fprintf(p->out,"\n");
3170: }else
3171:
1.9 ! jturner 3172: if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
! 3173: if( nArg==2 ){
! 3174: p->statsOn = booleanValue(azArg[1]);
! 3175: }else{
! 3176: fprintf(stderr, "Usage: .stats on|off\n");
! 3177: rc = 1;
! 3178: }
1.1 espie 3179: }else
3180:
1.9 ! jturner 3181: if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
1.2 espie 3182: sqlite3_stmt *pStmt;
1.1 espie 3183: char **azResult;
1.2 espie 3184: int nRow, nAlloc;
3185: char *zSql = 0;
3186: int ii;
1.8 jturner 3187: open_db(p, 0);
1.2 espie 3188: rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3189: if( rc ) return rc;
3190: zSql = sqlite3_mprintf(
3191: "SELECT name FROM sqlite_master"
3192: " WHERE type IN ('table','view')"
3193: " AND name NOT LIKE 'sqlite_%%'"
3194: " AND name LIKE ?1");
3195: while( sqlite3_step(pStmt)==SQLITE_ROW ){
3196: const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3197: if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3198: if( strcmp(zDbName,"temp")==0 ){
3199: zSql = sqlite3_mprintf(
3200: "%z UNION ALL "
3201: "SELECT 'temp.' || name FROM sqlite_temp_master"
3202: " WHERE type IN ('table','view')"
3203: " AND name NOT LIKE 'sqlite_%%'"
3204: " AND name LIKE ?1", zSql);
3205: }else{
3206: zSql = sqlite3_mprintf(
3207: "%z UNION ALL "
3208: "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3209: " WHERE type IN ('table','view')"
3210: " AND name NOT LIKE 'sqlite_%%'"
3211: " AND name LIKE ?1", zSql, zDbName, zDbName);
3212: }
3213: }
3214: sqlite3_finalize(pStmt);
3215: zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3216: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3217: sqlite3_free(zSql);
3218: if( rc ) return rc;
3219: nRow = nAlloc = 0;
3220: azResult = 0;
3221: if( nArg>1 ){
3222: sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
1.1 espie 3223: }else{
1.2 espie 3224: sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3225: }
3226: while( sqlite3_step(pStmt)==SQLITE_ROW ){
3227: if( nRow>=nAlloc ){
3228: char **azNew;
3229: int n = nAlloc*2 + 10;
3230: azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3231: if( azNew==0 ){
3232: fprintf(stderr, "Error: out of memory\n");
3233: break;
3234: }
3235: nAlloc = n;
3236: azResult = azNew;
3237: }
3238: azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3239: if( azResult[nRow] ) nRow++;
1.1 espie 3240: }
1.2 espie 3241: sqlite3_finalize(pStmt);
3242: if( nRow>0 ){
1.1 espie 3243: int len, maxlen = 0;
3244: int i, j;
3245: int nPrintCol, nPrintRow;
1.2 espie 3246: for(i=0; i<nRow; i++){
1.1 espie 3247: len = strlen30(azResult[i]);
3248: if( len>maxlen ) maxlen = len;
3249: }
3250: nPrintCol = 80/(maxlen+2);
3251: if( nPrintCol<1 ) nPrintCol = 1;
3252: nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3253: for(i=0; i<nPrintRow; i++){
1.2 espie 3254: for(j=i; j<nRow; j+=nPrintRow){
3255: char *zSp = j<nPrintRow ? "" : " ";
1.6 landry 3256: fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
1.1 espie 3257: }
1.6 landry 3258: fprintf(p->out, "\n");
1.1 espie 3259: }
3260: }
1.2 espie 3261: for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3262: sqlite3_free(azResult);
1.1 espie 3263: }else
3264:
3265: if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
3266: static const struct {
3267: const char *zCtrlName; /* Name of a test-control option */
3268: int ctrlCode; /* Integer code for that option */
3269: } aCtrl[] = {
3270: { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3271: { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3272: { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3273: { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3274: { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3275: { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3276: { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3277: { "assert", SQLITE_TESTCTRL_ASSERT },
3278: { "always", SQLITE_TESTCTRL_ALWAYS },
3279: { "reserve", SQLITE_TESTCTRL_RESERVE },
3280: { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3281: { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
3282: { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
1.9 ! jturner 3283: { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
1.1 espie 3284: };
3285: int testctrl = -1;
3286: int rc = 0;
3287: int i, n;
1.8 jturner 3288: open_db(p, 0);
1.1 espie 3289:
3290: /* convert testctrl text option to value. allow any unique prefix
3291: ** of the option name, or a numerical value. */
3292: n = strlen30(azArg[1]);
3293: for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
3294: if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3295: if( testctrl<0 ){
3296: testctrl = aCtrl[i].ctrlCode;
3297: }else{
3298: fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
3299: testctrl = -1;
3300: break;
3301: }
3302: }
3303: }
1.7 jturner 3304: if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
1.1 espie 3305: if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3306: fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3307: }else{
3308: switch(testctrl){
3309:
3310: /* sqlite3_test_control(int, db, int) */
3311: case SQLITE_TESTCTRL_OPTIMIZATIONS:
3312: case SQLITE_TESTCTRL_RESERVE:
3313: if( nArg==3 ){
3314: int opt = (int)strtol(azArg[2], 0, 0);
3315: rc = sqlite3_test_control(testctrl, p->db, opt);
1.6 landry 3316: fprintf(p->out, "%d (0x%08x)\n", rc, rc);
1.1 espie 3317: } else {
3318: fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3319: azArg[1]);
3320: }
3321: break;
3322:
3323: /* sqlite3_test_control(int) */
1.9 ! jturner 3324: case SQLITE_TESTCTRL_PRNG_SAVE:
! 3325: case SQLITE_TESTCTRL_PRNG_RESTORE:
1.1 espie 3326: case SQLITE_TESTCTRL_PRNG_RESET:
1.9 ! jturner 3327: case SQLITE_TESTCTRL_BYTEORDER:
1.1 espie 3328: if( nArg==2 ){
3329: rc = sqlite3_test_control(testctrl);
1.6 landry 3330: fprintf(p->out, "%d (0x%08x)\n", rc, rc);
1.1 espie 3331: } else {
3332: fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3333: }
3334: break;
3335:
3336: /* sqlite3_test_control(int, uint) */
3337: case SQLITE_TESTCTRL_PENDING_BYTE:
3338: if( nArg==3 ){
1.7 jturner 3339: unsigned int opt = (unsigned int)integerValue(azArg[2]);
1.1 espie 3340: rc = sqlite3_test_control(testctrl, opt);
1.6 landry 3341: fprintf(p->out, "%d (0x%08x)\n", rc, rc);
1.1 espie 3342: } else {
3343: fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3344: " int option\n", azArg[1]);
3345: }
3346: break;
3347:
3348: /* sqlite3_test_control(int, int) */
3349: case SQLITE_TESTCTRL_ASSERT:
3350: case SQLITE_TESTCTRL_ALWAYS:
3351: if( nArg==3 ){
1.7 jturner 3352: int opt = booleanValue(azArg[2]);
1.1 espie 3353: rc = sqlite3_test_control(testctrl, opt);
1.6 landry 3354: fprintf(p->out, "%d (0x%08x)\n", rc, rc);
1.1 espie 3355: } else {
3356: fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3357: azArg[1]);
3358: }
3359: break;
3360:
3361: /* sqlite3_test_control(int, char *) */
3362: #ifdef SQLITE_N_KEYWORD
3363: case SQLITE_TESTCTRL_ISKEYWORD:
3364: if( nArg==3 ){
3365: const char *opt = azArg[2];
3366: rc = sqlite3_test_control(testctrl, opt);
1.6 landry 3367: fprintf(p->out, "%d (0x%08x)\n", rc, rc);
1.1 espie 3368: } else {
3369: fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3370: azArg[1]);
3371: }
3372: break;
3373: #endif
3374:
3375: case SQLITE_TESTCTRL_BITVEC_TEST:
3376: case SQLITE_TESTCTRL_FAULT_INSTALL:
3377: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3378: case SQLITE_TESTCTRL_SCRATCHMALLOC:
3379: default:
3380: fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3381: azArg[1]);
3382: break;
3383: }
3384: }
3385: }else
3386:
1.9 ! jturner 3387: if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
1.8 jturner 3388: open_db(p, 0);
1.9 ! jturner 3389: sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
1.1 espie 3390: }else
3391:
1.9 ! jturner 3392: if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
! 3393: if( nArg==2 ){
! 3394: enableTimer = booleanValue(azArg[1]);
! 3395: if( enableTimer && !HAS_TIMER ){
! 3396: fprintf(stderr, "Error: timer not available on this system.\n");
! 3397: enableTimer = 0;
! 3398: }
! 3399: }else{
! 3400: fprintf(stderr, "Usage: .timer on|off\n");
! 3401: rc = 1;
! 3402: }
1.1 espie 3403: }else
3404:
1.9 ! jturner 3405: if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
1.8 jturner 3406: open_db(p, 0);
1.2 espie 3407: output_file_close(p->traceOut);
1.9 ! jturner 3408: if( nArg!=2 ){
! 3409: fprintf(stderr, "Usage: .trace FILE|off\n");
! 3410: rc = 1;
! 3411: goto meta_command_exit;
! 3412: }
1.2 espie 3413: p->traceOut = output_file_open(azArg[1]);
1.4 espie 3414: #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
1.2 espie 3415: if( p->traceOut==0 ){
3416: sqlite3_trace(p->db, 0, 0);
3417: }else{
3418: sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3419: }
3420: #endif
3421: }else
3422:
1.1 espie 3423: if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
1.6 landry 3424: fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
1.1 espie 3425: sqlite3_libversion(), sqlite3_sourceid());
3426: }else
3427:
3428: if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3429: const char *zDbName = nArg==2 ? azArg[1] : "main";
3430: char *zVfsName = 0;
3431: if( p->db ){
3432: sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3433: if( zVfsName ){
1.6 landry 3434: fprintf(p->out, "%s\n", zVfsName);
1.1 espie 3435: sqlite3_free(zVfsName);
3436: }
3437: }
3438: }else
3439:
1.5 espie 3440: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3441: if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3442: extern int sqlite3WhereTrace;
1.9 ! jturner 3443: sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
1.5 espie 3444: }else
3445: #endif
3446:
1.9 ! jturner 3447: if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1.1 espie 3448: int j;
3449: assert( nArg<=ArraySize(azArg) );
3450: for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1.7 jturner 3451: p->colWidth[j-1] = (int)integerValue(azArg[j]);
1.1 espie 3452: }
3453: }else
3454:
3455: {
3456: fprintf(stderr, "Error: unknown command or invalid arguments: "
3457: " \"%s\". Enter \".help\" for help\n", azArg[0]);
3458: rc = 1;
3459: }
3460:
1.9 ! jturner 3461: meta_command_exit:
! 3462: if( p->outCount ){
! 3463: p->outCount--;
! 3464: if( p->outCount==0 ) output_reset(p);
! 3465: }
1.1 espie 3466: return rc;
3467: }
3468:
3469: /*
3470: ** Return TRUE if a semicolon occurs anywhere in the first N characters
3471: ** of string z[].
3472: */
1.7 jturner 3473: static int line_contains_semicolon(const char *z, int N){
1.1 espie 3474: int i;
3475: for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3476: return 0;
3477: }
3478:
3479: /*
3480: ** Test to see if a line consists entirely of whitespace.
3481: */
3482: static int _all_whitespace(const char *z){
3483: for(; *z; z++){
3484: if( IsSpace(z[0]) ) continue;
3485: if( *z=='/' && z[1]=='*' ){
3486: z += 2;
3487: while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3488: if( *z==0 ) return 0;
3489: z++;
3490: continue;
3491: }
3492: if( *z=='-' && z[1]=='-' ){
3493: z += 2;
3494: while( *z && *z!='\n' ){ z++; }
3495: if( *z==0 ) return 1;
3496: continue;
3497: }
3498: return 0;
3499: }
3500: return 1;
3501: }
3502:
3503: /*
3504: ** Return TRUE if the line typed in is an SQL command terminator other
3505: ** than a semi-colon. The SQL Server style "go" command is understood
3506: ** as is the Oracle "/".
3507: */
1.7 jturner 3508: static int line_is_command_terminator(const char *zLine){
1.1 espie 3509: while( IsSpace(zLine[0]) ){ zLine++; };
3510: if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3511: return 1; /* Oracle */
3512: }
3513: if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
3514: && _all_whitespace(&zLine[2]) ){
3515: return 1; /* SQL Server */
3516: }
3517: return 0;
3518: }
3519:
3520: /*
3521: ** Return true if zSql is a complete SQL statement. Return false if it
3522: ** ends in the middle of a string literal or C-style comment.
3523: */
1.7 jturner 3524: static int line_is_complete(char *zSql, int nSql){
1.1 espie 3525: int rc;
3526: if( zSql==0 ) return 1;
3527: zSql[nSql] = ';';
3528: zSql[nSql+1] = 0;
3529: rc = sqlite3_complete(zSql);
3530: zSql[nSql] = 0;
3531: return rc;
3532: }
3533:
3534: /*
3535: ** Read input from *in and process it. If *in==0 then input
3536: ** is interactive - the user is typing it it. Otherwise, input
3537: ** is coming from a file or device. A prompt is issued and history
3538: ** is saved only if input is interactive. An interrupt signal will
3539: ** cause this routine to exit immediately, unless input is interactive.
3540: **
3541: ** Return the number of errors.
3542: */
3543: static int process_input(struct callback_data *p, FILE *in){
1.7 jturner 3544: char *zLine = 0; /* A single input line */
3545: char *zSql = 0; /* Accumulated SQL text */
3546: int nLine; /* Length of current line */
3547: int nSql = 0; /* Bytes of zSql[] used */
3548: int nAlloc = 0; /* Allocated zSql[] space */
3549: int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
3550: char *zErrMsg; /* Error message returned */
3551: int rc; /* Error code */
3552: int errCnt = 0; /* Number of errors seen */
3553: int lineno = 0; /* Current line number */
3554: int startline = 0; /* Line number for start of current input */
1.1 espie 3555:
3556: while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
3557: fflush(p->out);
1.7 jturner 3558: zLine = one_input_line(in, zLine, nSql>0);
1.1 espie 3559: if( zLine==0 ){
1.2 espie 3560: /* End of input */
3561: if( stdin_is_interactive ) printf("\n");
3562: break;
1.1 espie 3563: }
3564: if( seenInterrupt ){
3565: if( in!=0 ) break;
3566: seenInterrupt = 0;
3567: }
3568: lineno++;
1.8 jturner 3569: if( nSql==0 && _all_whitespace(zLine) ){
3570: if( p->echoOn ) printf("%s\n", zLine);
3571: continue;
3572: }
1.1 espie 3573: if( zLine && zLine[0]=='.' && nSql==0 ){
3574: if( p->echoOn ) printf("%s\n", zLine);
3575: rc = do_meta_command(zLine, p);
3576: if( rc==2 ){ /* exit requested */
3577: break;
3578: }else if( rc ){
3579: errCnt++;
3580: }
3581: continue;
3582: }
1.7 jturner 3583: if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
1.1 espie 3584: memcpy(zLine,";",2);
3585: }
1.7 jturner 3586: nLine = strlen30(zLine);
3587: if( nSql+nLine+2>=nAlloc ){
3588: nAlloc = nSql+nLine+100;
3589: zSql = realloc(zSql, nAlloc);
3590: if( zSql==0 ){
3591: fprintf(stderr, "Error: out of memory\n");
3592: exit(1);
3593: }
3594: }
1.1 espie 3595: nSqlPrior = nSql;
1.7 jturner 3596: if( nSql==0 ){
1.1 espie 3597: int i;
3598: for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
1.7 jturner 3599: assert( nAlloc>0 && zSql!=0 );
3600: memcpy(zSql, zLine+i, nLine+1-i);
3601: startline = lineno;
3602: nSql = nLine-i;
1.1 espie 3603: }else{
3604: zSql[nSql++] = '\n';
1.7 jturner 3605: memcpy(zSql+nSql, zLine, nLine+1);
3606: nSql += nLine;
1.1 espie 3607: }
1.7 jturner 3608: if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1.1 espie 3609: && sqlite3_complete(zSql) ){
3610: p->cnt = 0;
1.8 jturner 3611: open_db(p, 0);
1.1 espie 3612: BEGIN_TIMER;
3613: rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
3614: END_TIMER;
3615: if( rc || zErrMsg ){
3616: char zPrefix[100];
3617: if( in!=0 || !stdin_is_interactive ){
3618: sqlite3_snprintf(sizeof(zPrefix), zPrefix,
3619: "Error: near line %d:", startline);
3620: }else{
3621: sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
3622: }
3623: if( zErrMsg!=0 ){
3624: fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
3625: sqlite3_free(zErrMsg);
3626: zErrMsg = 0;
3627: }else{
3628: fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
3629: }
3630: errCnt++;
3631: }
3632: nSql = 0;
1.9 ! jturner 3633: if( p->outCount ){
! 3634: output_reset(p);
! 3635: p->outCount = 0;
! 3636: }
1.7 jturner 3637: }else if( nSql && _all_whitespace(zSql) ){
1.8 jturner 3638: if( p->echoOn ) printf("%s\n", zSql);
1.6 landry 3639: nSql = 0;
1.1 espie 3640: }
3641: }
1.7 jturner 3642: if( nSql ){
1.1 espie 3643: if( !_all_whitespace(zSql) ){
3644: fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
3645: }
3646: free(zSql);
3647: }
3648: free(zLine);
1.5 espie 3649: return errCnt>0;
1.1 espie 3650: }
3651:
3652: /*
3653: ** Return a pathname which is the user's home directory. A
1.2 espie 3654: ** 0 return indicates an error of some kind.
1.1 espie 3655: */
3656: static char *find_home_dir(void){
1.2 espie 3657: static char *home_dir = NULL;
3658: if( home_dir ) return home_dir;
1.1 espie 3659:
1.4 espie 3660: #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
1.2 espie 3661: {
1.4 espie 3662: struct passwd *pwent;
3663: uid_t uid = getuid();
3664: if( (pwent=getpwuid(uid)) != NULL) {
3665: home_dir = pwent->pw_dir;
3666: }
1.1 espie 3667: }
3668: #endif
3669:
3670: #if defined(_WIN32_WCE)
3671: /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
3672: */
1.2 espie 3673: home_dir = "/";
1.1 espie 3674: #else
3675:
1.4 espie 3676: #if defined(_WIN32) || defined(WIN32)
1.1 espie 3677: if (!home_dir) {
3678: home_dir = getenv("USERPROFILE");
3679: }
3680: #endif
3681:
3682: if (!home_dir) {
3683: home_dir = getenv("HOME");
3684: }
3685:
1.4 espie 3686: #if defined(_WIN32) || defined(WIN32)
1.1 espie 3687: if (!home_dir) {
3688: char *zDrive, *zPath;
3689: int n;
3690: zDrive = getenv("HOMEDRIVE");
3691: zPath = getenv("HOMEPATH");
3692: if( zDrive && zPath ){
3693: n = strlen30(zDrive) + strlen30(zPath) + 1;
3694: home_dir = malloc( n );
3695: if( home_dir==0 ) return 0;
3696: sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
3697: return home_dir;
3698: }
3699: home_dir = "c:\\";
3700: }
3701: #endif
3702:
3703: #endif /* !_WIN32_WCE */
3704:
3705: if( home_dir ){
3706: int n = strlen30(home_dir) + 1;
3707: char *z = malloc( n );
3708: if( z ) memcpy(z, home_dir, n);
3709: home_dir = z;
3710: }
3711:
3712: return home_dir;
3713: }
3714:
3715: /*
3716: ** Read input from the file given by sqliterc_override. Or if that
3717: ** parameter is NULL, take input from ~/.sqliterc
3718: **
3719: ** Returns the number of errors.
3720: */
3721: static int process_sqliterc(
3722: struct callback_data *p, /* Configuration data */
3723: const char *sqliterc_override /* Name of config file. NULL to use default */
3724: ){
3725: char *home_dir = NULL;
3726: const char *sqliterc = sqliterc_override;
3727: char *zBuf = 0;
3728: FILE *in = NULL;
3729: int rc = 0;
3730:
3731: if (sqliterc == NULL) {
3732: home_dir = find_home_dir();
3733: if( home_dir==0 ){
3734: #if !defined(__RTP__) && !defined(_WRS_KERNEL)
3735: fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
3736: #endif
3737: return 1;
3738: }
1.4 espie 3739: sqlite3_initialize();
1.2 espie 3740: zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
3741: sqliterc = zBuf;
1.1 espie 3742: }
3743: in = fopen(sqliterc,"rb");
3744: if( in ){
3745: if( stdin_is_interactive ){
3746: fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
3747: }
3748: rc = process_input(p,in);
3749: fclose(in);
3750: }
1.2 espie 3751: sqlite3_free(zBuf);
1.1 espie 3752: return rc;
3753: }
3754:
3755: /*
3756: ** Show available command line options
3757: */
3758: static const char zOptions[] =
3759: " -bail stop after hitting an error\n"
3760: " -batch force batch I/O\n"
3761: " -column set output mode to 'column'\n"
1.5 espie 3762: " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
1.1 espie 3763: " -csv set output mode to 'csv'\n"
3764: " -echo print commands before execution\n"
1.5 espie 3765: " -init FILENAME read/process named file\n"
1.1 espie 3766: " -[no]header turn headers on or off\n"
1.5 espie 3767: #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3768: " -heap SIZE Size of heap for memsys3 or memsys5\n"
3769: #endif
1.1 espie 3770: " -help show this message\n"
3771: " -html set output mode to HTML\n"
3772: " -interactive force interactive I/O\n"
3773: " -line set output mode to 'line'\n"
3774: " -list set output mode to 'list'\n"
1.6 landry 3775: " -mmap N default mmap size set to N\n"
1.1 espie 3776: #ifdef SQLITE_ENABLE_MULTIPLEX
3777: " -multiplex enable the multiplexor VFS\n"
3778: #endif
1.9 ! jturner 3779: " -newline SEP set newline character(s) for CSV\n"
1.5 espie 3780: " -nullvalue TEXT set text string for NULL values. Default ''\n"
3781: " -separator SEP set output field separator. Default: '|'\n"
1.1 espie 3782: " -stats print memory stats before each finalize\n"
3783: " -version show SQLite version\n"
3784: " -vfs NAME use NAME as the default VFS\n"
3785: #ifdef SQLITE_ENABLE_VFSTRACE
3786: " -vfstrace enable tracing of all VFS calls\n"
3787: #endif
3788: ;
3789: static void usage(int showDetail){
3790: fprintf(stderr,
3791: "Usage: %s [OPTIONS] FILENAME [SQL]\n"
3792: "FILENAME is the name of an SQLite database. A new database is created\n"
3793: "if the file does not previously exist.\n", Argv0);
3794: if( showDetail ){
3795: fprintf(stderr, "OPTIONS include:\n%s", zOptions);
3796: }else{
3797: fprintf(stderr, "Use the -help option for additional information\n");
3798: }
3799: exit(1);
3800: }
3801:
3802: /*
3803: ** Initialize the state information in data
3804: */
3805: static void main_init(struct callback_data *data) {
3806: memset(data, 0, sizeof(*data));
3807: data->mode = MODE_List;
3808: memcpy(data->separator,"|", 2);
1.9 ! jturner 3809: memcpy(data->newline,"\r\n", 3);
1.1 espie 3810: data->showHeader = 0;
3811: sqlite3_config(SQLITE_CONFIG_URI, 1);
3812: sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
3813: sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
3814: sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
3815: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
3816: }
3817:
1.5 espie 3818: /*
1.8 jturner 3819: ** Output text to the console in a font that attracts extra attention.
3820: */
3821: #ifdef _WIN32
3822: static void printBold(const char *zText){
3823: HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
3824: CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
3825: GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
3826: SetConsoleTextAttribute(out,
3827: FOREGROUND_RED|FOREGROUND_INTENSITY
3828: );
3829: printf("%s", zText);
3830: SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
3831: }
3832: #else
3833: static void printBold(const char *zText){
3834: printf("\033[1m%s\033[0m", zText);
3835: }
3836: #endif
3837:
3838: /*
1.5 espie 3839: ** Get the argument to an --option. Throw an error and die if no argument
3840: ** is available.
3841: */
3842: static char *cmdline_option_value(int argc, char **argv, int i){
3843: if( i==argc ){
3844: fprintf(stderr, "%s: Error: missing argument to %s\n",
3845: argv[0], argv[argc-1]);
3846: exit(1);
3847: }
3848: return argv[i];
3849: }
3850:
1.1 espie 3851: int main(int argc, char **argv){
3852: char *zErrMsg = 0;
3853: struct callback_data data;
3854: const char *zInitFile = 0;
3855: char *zFirstCmd = 0;
3856: int i;
3857: int rc = 0;
1.8 jturner 3858: int warnInmemoryDb = 0;
1.1 espie 3859:
1.8 jturner 3860: #if USE_SYSTEM_SQLITE+0!=1
1.1 espie 3861: if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
3862: fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
3863: sqlite3_sourceid(), SQLITE_SOURCE_ID);
3864: exit(1);
3865: }
1.8 jturner 3866: #endif
1.1 espie 3867: Argv0 = argv[0];
3868: main_init(&data);
3869: stdin_is_interactive = isatty(0);
3870:
3871: /* Make sure we have a valid signal handler early, before anything
3872: ** else is done.
3873: */
3874: #ifdef SIGINT
3875: signal(SIGINT, interrupt_handler);
3876: #endif
3877:
3878: /* Do an initial pass through the command-line argument to locate
3879: ** the name of the database file, the name of the initialization file,
3880: ** the size of the alternative malloc heap,
3881: ** and the first command to execute.
3882: */
1.5 espie 3883: for(i=1; i<argc; i++){
1.1 espie 3884: char *z;
3885: z = argv[i];
1.5 espie 3886: if( z[0]!='-' ){
3887: if( data.zDbFilename==0 ){
3888: data.zDbFilename = z;
3889: continue;
3890: }
3891: if( zFirstCmd==0 ){
3892: zFirstCmd = z;
3893: continue;
3894: }
3895: fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
3896: fprintf(stderr,"Use -help for a list of options.\n");
3897: return 1;
3898: }
1.1 espie 3899: if( z[1]=='-' ) z++;
3900: if( strcmp(z,"-separator")==0
3901: || strcmp(z,"-nullvalue")==0
1.9 ! jturner 3902: || strcmp(z,"-newline")==0
1.1 espie 3903: || strcmp(z,"-cmd")==0
3904: ){
1.5 espie 3905: (void)cmdline_option_value(argc, argv, ++i);
1.1 espie 3906: }else if( strcmp(z,"-init")==0 ){
1.5 espie 3907: zInitFile = cmdline_option_value(argc, argv, ++i);
1.1 espie 3908: }else if( strcmp(z,"-batch")==0 ){
1.5 espie 3909: /* Need to check for batch mode here to so we can avoid printing
3910: ** informational messages (like from process_sqliterc) before
3911: ** we do the actual processing of arguments later in a second pass.
3912: */
1.1 espie 3913: stdin_is_interactive = 0;
3914: }else if( strcmp(z,"-heap")==0 ){
3915: #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
3916: const char *zSize;
3917: sqlite3_int64 szHeap;
3918:
1.5 espie 3919: zSize = cmdline_option_value(argc, argv, ++i);
1.6 landry 3920: szHeap = integerValue(zSize);
1.1 espie 3921: if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
3922: sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
3923: #endif
3924: #ifdef SQLITE_ENABLE_VFSTRACE
3925: }else if( strcmp(z,"-vfstrace")==0 ){
3926: extern int vfstrace_register(
3927: const char *zTraceName,
3928: const char *zOldVfsName,
3929: int (*xOut)(const char*,void*),
3930: void *pOutArg,
3931: int makeDefault
3932: );
3933: vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
3934: #endif
3935: #ifdef SQLITE_ENABLE_MULTIPLEX
3936: }else if( strcmp(z,"-multiplex")==0 ){
3937: extern int sqlite3_multiple_initialize(const char*,int);
3938: sqlite3_multiplex_initialize(0, 1);
3939: #endif
1.6 landry 3940: }else if( strcmp(z,"-mmap")==0 ){
3941: sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
3942: sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
1.1 espie 3943: }else if( strcmp(z,"-vfs")==0 ){
1.5 espie 3944: sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
1.1 espie 3945: if( pVfs ){
3946: sqlite3_vfs_register(pVfs, 1);
3947: }else{
3948: fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
3949: exit(1);
3950: }
3951: }
3952: }
1.5 espie 3953: if( data.zDbFilename==0 ){
1.1 espie 3954: #ifndef SQLITE_OMIT_MEMORYDB
3955: data.zDbFilename = ":memory:";
1.8 jturner 3956: warnInmemoryDb = argc==1;
1.1 espie 3957: #else
1.5 espie 3958: fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
3959: return 1;
1.1 espie 3960: #endif
1.8 jturner 3961: #ifdef SQLITE_SHELL_DBNAME_PROC
3962: { extern void SQLITE_SHELL_DBNAME_PROC(const char**);
3963: SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
3964: warnInmemoryDb = 0; }
3965: #endif
1.1 espie 3966: }
3967: data.out = stdout;
3968:
3969: /* Go ahead and open the database file if it already exists. If the
3970: ** file does not exist, delay opening it. This prevents empty database
3971: ** files from being created if a user mistypes the database name argument
3972: ** to the sqlite command-line tool.
3973: */
3974: if( access(data.zDbFilename, 0)==0 ){
1.8 jturner 3975: open_db(&data, 0);
1.1 espie 3976: }
3977:
3978: /* Process the initialization file if there is one. If no -init option
3979: ** is given on the command line, look for a file named ~/.sqliterc and
3980: ** try to process it.
3981: */
3982: rc = process_sqliterc(&data,zInitFile);
3983: if( rc>0 ){
3984: return rc;
3985: }
3986:
3987: /* Make a second pass through the command-line argument and set
3988: ** options. This second pass is delayed until after the initialization
3989: ** file is processed so that the command-line arguments will override
3990: ** settings in the initialization file.
3991: */
1.5 espie 3992: for(i=1; i<argc; i++){
1.1 espie 3993: char *z = argv[i];
1.5 espie 3994: if( z[0]!='-' ) continue;
1.1 espie 3995: if( z[1]=='-' ){ z++; }
3996: if( strcmp(z,"-init")==0 ){
3997: i++;
3998: }else if( strcmp(z,"-html")==0 ){
3999: data.mode = MODE_Html;
4000: }else if( strcmp(z,"-list")==0 ){
4001: data.mode = MODE_List;
4002: }else if( strcmp(z,"-line")==0 ){
4003: data.mode = MODE_Line;
4004: }else if( strcmp(z,"-column")==0 ){
4005: data.mode = MODE_Column;
4006: }else if( strcmp(z,"-csv")==0 ){
4007: data.mode = MODE_Csv;
4008: memcpy(data.separator,",",2);
4009: }else if( strcmp(z,"-separator")==0 ){
4010: sqlite3_snprintf(sizeof(data.separator), data.separator,
1.9 ! jturner 4011: "%s",cmdline_option_value(argc,argv,++i));
! 4012: }else if( strcmp(z,"-newline")==0 ){
! 4013: sqlite3_snprintf(sizeof(data.newline), data.newline,
1.5 espie 4014: "%s",cmdline_option_value(argc,argv,++i));
1.1 espie 4015: }else if( strcmp(z,"-nullvalue")==0 ){
4016: sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
1.5 espie 4017: "%s",cmdline_option_value(argc,argv,++i));
1.1 espie 4018: }else if( strcmp(z,"-header")==0 ){
4019: data.showHeader = 1;
4020: }else if( strcmp(z,"-noheader")==0 ){
4021: data.showHeader = 0;
4022: }else if( strcmp(z,"-echo")==0 ){
4023: data.echoOn = 1;
1.8 jturner 4024: }else if( strcmp(z,"-eqp")==0 ){
4025: data.autoEQP = 1;
1.1 espie 4026: }else if( strcmp(z,"-stats")==0 ){
4027: data.statsOn = 1;
4028: }else if( strcmp(z,"-bail")==0 ){
4029: bail_on_error = 1;
4030: }else if( strcmp(z,"-version")==0 ){
4031: printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
4032: return 0;
4033: }else if( strcmp(z,"-interactive")==0 ){
4034: stdin_is_interactive = 1;
4035: }else if( strcmp(z,"-batch")==0 ){
4036: stdin_is_interactive = 0;
4037: }else if( strcmp(z,"-heap")==0 ){
4038: i++;
1.6 landry 4039: }else if( strcmp(z,"-mmap")==0 ){
4040: i++;
1.1 espie 4041: }else if( strcmp(z,"-vfs")==0 ){
4042: i++;
4043: #ifdef SQLITE_ENABLE_VFSTRACE
4044: }else if( strcmp(z,"-vfstrace")==0 ){
4045: i++;
4046: #endif
4047: #ifdef SQLITE_ENABLE_MULTIPLEX
4048: }else if( strcmp(z,"-multiplex")==0 ){
4049: i++;
4050: #endif
4051: }else if( strcmp(z,"-help")==0 ){
4052: usage(1);
4053: }else if( strcmp(z,"-cmd")==0 ){
4054: if( i==argc-1 ) break;
1.5 espie 4055: z = cmdline_option_value(argc,argv,++i);
1.1 espie 4056: if( z[0]=='.' ){
4057: rc = do_meta_command(z, &data);
1.6 landry 4058: if( rc && bail_on_error ) return rc==2 ? 0 : rc;
1.1 espie 4059: }else{
1.8 jturner 4060: open_db(&data, 0);
1.1 espie 4061: rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4062: if( zErrMsg!=0 ){
4063: fprintf(stderr,"Error: %s\n", zErrMsg);
4064: if( bail_on_error ) return rc!=0 ? rc : 1;
4065: }else if( rc!=0 ){
4066: fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4067: if( bail_on_error ) return rc;
4068: }
4069: }
4070: }else{
4071: fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
4072: fprintf(stderr,"Use -help for a list of options.\n");
4073: return 1;
4074: }
4075: }
4076:
4077: if( zFirstCmd ){
4078: /* Run just the command that follows the database name
4079: */
4080: if( zFirstCmd[0]=='.' ){
4081: rc = do_meta_command(zFirstCmd, &data);
1.6 landry 4082: if( rc==2 ) rc = 0;
1.1 espie 4083: }else{
1.8 jturner 4084: open_db(&data, 0);
1.1 espie 4085: rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
4086: if( zErrMsg!=0 ){
4087: fprintf(stderr,"Error: %s\n", zErrMsg);
4088: return rc!=0 ? rc : 1;
4089: }else if( rc!=0 ){
4090: fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
4091: return rc;
4092: }
4093: }
4094: }else{
4095: /* Run commands received from standard input
4096: */
4097: if( stdin_is_interactive ){
4098: char *zHome;
4099: char *zHistory = 0;
4100: int nHistory;
4101: printf(
4102: "SQLite version %s %.19s\n" /*extra-version-info*/
1.8 jturner 4103: "Enter \".help\" for usage hints.\n",
1.1 espie 4104: sqlite3_libversion(), sqlite3_sourceid()
4105: );
1.8 jturner 4106: if( warnInmemoryDb ){
4107: printf("Connected to a ");
4108: printBold("transient in-memory database");
4109: printf(".\nUse \".open FILENAME\" to reopen on a "
4110: "persistent database.\n");
4111: }
1.1 espie 4112: zHome = find_home_dir();
4113: if( zHome ){
4114: nHistory = strlen30(zHome) + 20;
4115: if( (zHistory = malloc(nHistory))!=0 ){
4116: sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4117: }
4118: }
1.8 jturner 4119: #if defined(HAVE_READLINE)
1.1 espie 4120: if( zHistory ) read_history(zHistory);
4121: #endif
4122: rc = process_input(&data, 0);
4123: if( zHistory ){
4124: stifle_history(100);
4125: write_history(zHistory);
4126: free(zHistory);
4127: }
4128: }else{
4129: rc = process_input(&data, stdin);
4130: }
4131: }
4132: set_table_name(&data, 0);
4133: if( data.db ){
4134: sqlite3_close(data.db);
4135: }
1.8 jturner 4136: sqlite3_free(data.zFreeOnClose);
1.1 espie 4137: return rc;
4138: }