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