Annotation of elwix/files/sqlite/dist/shell.c, revision 1.4.2.1
1.2 misho 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.4 misho 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: /*
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.2 misho 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.4 misho 50: #if SQLITE_USER_AUTHENTICATION
51: # include "sqlite3userauth.h"
52: #endif
1.2 misho 53: #include <ctype.h>
54: #include <stdarg.h>
55:
1.3 misho 56: #if !defined(_WIN32) && !defined(WIN32)
1.2 misho 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.4 misho 65: #if HAVE_READLINE
1.2 misho 66: # include <readline/readline.h>
67: # include <readline/history.h>
68: #endif
1.4 misho 69:
70: #if HAVE_EDITLINE
71: # include <editline/readline.h>
72: #endif
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.2 misho 98: #endif
99:
1.4 misho 100:
1.2 misho 101: #if defined(_WIN32) || defined(WIN32)
102: # include <io.h>
1.4 misho 103: # include <fcntl.h>
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.2 misho 112: #else
1.4 misho 113: /* Make sure isatty() has a prototype. */
114: extern int isatty(int);
115:
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.2 misho 124: #endif
125:
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.4 misho 139: #if defined(_WIN32) || defined(WIN32)
140: #include <windows.h>
141:
142: /* string conversion routines only needed on Win32 */
143: extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
144: extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
145: extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
1.4.2.1 ! misho 146: extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
1.4 misho 147: #endif
148:
149: /* On Windows, we normally run with output mode of TEXT so that \n characters
150: ** are automatically translated into \r\n. However, this behavior needs
151: ** to be disabled in some cases (ex: when generating CSV output and when
152: ** rendering quoted strings that contain \n characters). The following
153: ** routines take care of that.
154: */
155: #if defined(_WIN32) || defined(WIN32)
156: static void setBinaryMode(FILE *file, int isOutput){
157: if( isOutput ) fflush(file);
158: _setmode(_fileno(file), _O_BINARY);
159: }
160: static void setTextMode(FILE *file, int isOutput){
161: if( isOutput ) fflush(file);
162: _setmode(_fileno(file), _O_TEXT);
163: }
164: #else
165: # define setBinaryMode(X,Y)
166: # define setTextMode(X,Y)
167: #endif
168:
169:
170: /* True if the timer is enabled */
171: static int enableTimer = 0;
172:
173: /* Return the current wall-clock time */
174: static sqlite3_int64 timeOfDay(void){
175: static sqlite3_vfs *clockVfs = 0;
176: sqlite3_int64 t;
177: if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
178: if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
179: clockVfs->xCurrentTimeInt64(clockVfs, &t);
180: }else{
181: double r;
182: clockVfs->xCurrentTime(clockVfs, &r);
183: t = (sqlite3_int64)(r*86400000.0);
184: }
185: return t;
186: }
187:
188: #if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
1.2 misho 189: #include <sys/time.h>
190: #include <sys/resource.h>
191:
1.4 misho 192: /* VxWorks does not support getrusage() as far as we can determine */
193: #if defined(_WRS_KERNEL) || defined(__RTP__)
194: struct rusage {
195: struct timeval ru_utime; /* user CPU time used */
196: struct timeval ru_stime; /* system CPU time used */
197: };
198: #define getrusage(A,B) memset(B,0,sizeof(*B))
199: #endif
200:
1.2 misho 201: /* Saved resource information for the beginning of an operation */
1.4 misho 202: static struct rusage sBegin; /* CPU time at start */
203: static sqlite3_int64 iBegin; /* Wall-clock time at start */
1.2 misho 204:
205: /*
206: ** Begin timing an operation
207: */
208: static void beginTimer(void){
209: if( enableTimer ){
210: getrusage(RUSAGE_SELF, &sBegin);
1.4 misho 211: iBegin = timeOfDay();
1.2 misho 212: }
213: }
214:
215: /* Return the difference of two time_structs in seconds */
216: static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
1.4 misho 217: return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
1.2 misho 218: (double)(pEnd->tv_sec - pStart->tv_sec);
219: }
220:
221: /*
222: ** Print the timing results.
223: */
224: static void endTimer(void){
225: if( enableTimer ){
1.4 misho 226: sqlite3_int64 iEnd = timeOfDay();
1.2 misho 227: struct rusage sEnd;
228: getrusage(RUSAGE_SELF, &sEnd);
1.4 misho 229: printf("Run Time: real %.3f user %f sys %f\n",
230: (iEnd - iBegin)*0.001,
1.2 misho 231: timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
232: timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
233: }
234: }
235:
236: #define BEGIN_TIMER beginTimer()
237: #define END_TIMER endTimer()
238: #define HAS_TIMER 1
239:
240: #elif (defined(_WIN32) || defined(WIN32))
241:
242: /* Saved resource information for the beginning of an operation */
243: static HANDLE hProcess;
244: static FILETIME ftKernelBegin;
245: static FILETIME ftUserBegin;
1.4 misho 246: static sqlite3_int64 ftWallBegin;
247: typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
248: LPFILETIME, LPFILETIME);
1.2 misho 249: static GETPROCTIMES getProcessTimesAddr = NULL;
250:
251: /*
252: ** Check to see if we have timer support. Return 1 if necessary
253: ** support found (or found previously).
254: */
255: static int hasTimer(void){
256: if( getProcessTimesAddr ){
257: return 1;
258: } else {
1.4 misho 259: /* GetProcessTimes() isn't supported in WIN95 and some other Windows
260: ** versions. See if the version we are running on has it, and if it
261: ** does, save off a pointer to it and the current process handle.
1.2 misho 262: */
263: hProcess = GetCurrentProcess();
264: if( hProcess ){
265: HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
266: if( NULL != hinstLib ){
1.4 misho 267: getProcessTimesAddr =
268: (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
1.2 misho 269: if( NULL != getProcessTimesAddr ){
270: return 1;
271: }
1.4 misho 272: FreeLibrary(hinstLib);
1.2 misho 273: }
274: }
275: }
276: return 0;
277: }
278:
279: /*
280: ** Begin timing an operation
281: */
282: static void beginTimer(void){
283: if( enableTimer && getProcessTimesAddr ){
284: FILETIME ftCreation, ftExit;
1.4 misho 285: getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
286: &ftKernelBegin,&ftUserBegin);
287: ftWallBegin = timeOfDay();
1.2 misho 288: }
289: }
290:
291: /* Return the difference of two FILETIME structs in seconds */
292: static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
293: sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
294: sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
295: return (double) ((i64End - i64Start) / 10000000.0);
296: }
297:
298: /*
299: ** Print the timing results.
300: */
301: static void endTimer(void){
302: if( enableTimer && getProcessTimesAddr){
303: FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
1.4 misho 304: sqlite3_int64 ftWallEnd = timeOfDay();
305: getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
306: printf("Run Time: real %.3f user %f sys %f\n",
307: (ftWallEnd - ftWallBegin)*0.001,
1.2 misho 308: timeDiff(&ftUserBegin, &ftUserEnd),
309: timeDiff(&ftKernelBegin, &ftKernelEnd));
310: }
311: }
312:
313: #define BEGIN_TIMER beginTimer()
314: #define END_TIMER endTimer()
315: #define HAS_TIMER hasTimer()
316:
317: #else
1.4 misho 318: #define BEGIN_TIMER
1.2 misho 319: #define END_TIMER
320: #define HAS_TIMER 0
321: #endif
322:
323: /*
324: ** Used to prevent warnings about unused parameters
325: */
326: #define UNUSED_PARAMETER(x) (void)(x)
327:
328: /*
329: ** If the following flag is set, then command execution stops
330: ** at an error if we are not interactive.
331: */
332: static int bail_on_error = 0;
333:
334: /*
335: ** Threat stdin as an interactive input if the following variable
336: ** is true. Otherwise, assume stdin is connected to a file or pipe.
337: */
338: static int stdin_is_interactive = 1;
339:
340: /*
1.4 misho 341: ** On Windows systems we have to know if standard output is a console
342: ** in order to translate UTF-8 into MBCS. The following variable is
343: ** true if translation is required.
344: */
345: static int stdout_is_console = 1;
346:
347: /*
1.2 misho 348: ** The following is the open SQLite database. We make a pointer
349: ** to this database a static variable so that it can be accessed
350: ** by the SIGINT handler to interrupt database processing.
351: */
1.4 misho 352: static sqlite3 *globalDb = 0;
1.2 misho 353:
354: /*
355: ** True if an interrupt (Control-C) has been received.
356: */
357: static volatile int seenInterrupt = 0;
358:
359: /*
360: ** This is the name of our program. It is set in main(), used
361: ** in a number of other places, mostly for error messages.
362: */
363: static char *Argv0;
364:
365: /*
366: ** Prompt strings. Initialized in main. Settable with
367: ** .prompt main continue
368: */
369: static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
370: static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
371:
372: /*
1.4 misho 373: ** Render output like fprintf(). Except, if the output is going to the
374: ** console and if this is running on a Windows machine, translate the
375: ** output from UTF-8 into MBCS.
376: */
377: #if defined(_WIN32) || defined(WIN32)
378: void utf8_printf(FILE *out, const char *zFormat, ...){
379: va_list ap;
380: va_start(ap, zFormat);
381: if( stdout_is_console && (out==stdout || out==stderr) ){
382: char *z1 = sqlite3_vmprintf(zFormat, ap);
383: char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
384: sqlite3_free(z1);
385: fputs(z2, out);
386: sqlite3_free(z2);
387: }else{
388: vfprintf(out, zFormat, ap);
389: }
390: va_end(ap);
391: }
392: #elif !defined(utf8_printf)
393: # define utf8_printf fprintf
394: #endif
395:
396: /*
397: ** Render output like fprintf(). This should not be used on anything that
398: ** includes string formatting (e.g. "%s").
399: */
400: #if !defined(raw_printf)
401: # define raw_printf fprintf
402: #endif
403:
404: /*
1.2 misho 405: ** Write I/O traces to the following stream.
406: */
407: #ifdef SQLITE_ENABLE_IOTRACE
408: static FILE *iotrace = 0;
409: #endif
410:
411: /*
412: ** This routine works like printf in that its first argument is a
413: ** format string and subsequent arguments are values to be substituted
414: ** in place of % fields. The result of formatting this string
415: ** is written to iotrace.
416: */
417: #ifdef SQLITE_ENABLE_IOTRACE
1.4 misho 418: static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
1.2 misho 419: va_list ap;
420: char *z;
421: if( iotrace==0 ) return;
422: va_start(ap, zFormat);
423: z = sqlite3_vmprintf(zFormat, ap);
424: va_end(ap);
1.4 misho 425: utf8_printf(iotrace, "%s", z);
1.2 misho 426: sqlite3_free(z);
427: }
428: #endif
429:
1.4.2.1 ! misho 430: /*
! 431: ** Output string zUtf to stream pOut as w characters. If w is negative,
! 432: ** then right-justify the text. W is the width in UTF-8 characters, not
! 433: ** in bytes. This is different from the %*.*s specification in printf
! 434: ** since with %*.*s the width is measured in bytes, not characters.
! 435: */
! 436: static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
! 437: int i;
! 438: int n;
! 439: int aw = w<0 ? -w : w;
! 440: char zBuf[1000];
! 441: if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
! 442: for(i=n=0; zUtf[i]; i++){
! 443: if( (zUtf[i]&0xc0)!=0x80 ){
! 444: n++;
! 445: if( n==aw ){
! 446: do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
! 447: break;
! 448: }
! 449: }
! 450: }
! 451: if( n>=aw ){
! 452: utf8_printf(pOut, "%.*s", i, zUtf);
! 453: }else if( w<0 ){
! 454: utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
! 455: }else{
! 456: utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
! 457: }
! 458: }
! 459:
1.2 misho 460:
461: /*
462: ** Determines if a string is a number of not.
463: */
464: static int isNumber(const char *z, int *realnum){
465: if( *z=='-' || *z=='+' ) z++;
466: if( !IsDigit(*z) ){
467: return 0;
468: }
469: z++;
470: if( realnum ) *realnum = 0;
471: while( IsDigit(*z) ){ z++; }
472: if( *z=='.' ){
473: z++;
474: if( !IsDigit(*z) ) return 0;
475: while( IsDigit(*z) ){ z++; }
476: if( realnum ) *realnum = 1;
477: }
478: if( *z=='e' || *z=='E' ){
479: z++;
480: if( *z=='+' || *z=='-' ) z++;
481: if( !IsDigit(*z) ) return 0;
482: while( IsDigit(*z) ){ z++; }
483: if( realnum ) *realnum = 1;
484: }
485: return *z==0;
486: }
487:
488: /*
1.4 misho 489: ** Compute a string length that is limited to what can be stored in
490: ** lower 30 bits of a 32-bit signed integer.
491: */
492: static int strlen30(const char *z){
493: const char *z2 = z;
494: while( *z2 ){ z2++; }
495: return 0x3fffffff & (int)(z2 - z);
496: }
497:
498: /*
1.2 misho 499: ** This routine reads a line of text from FILE in, stores
500: ** the text in memory obtained from malloc() and returns a pointer
501: ** to the text. NULL is returned at end of file, or if malloc()
502: ** fails.
503: **
1.4 misho 504: ** If zLine is not NULL then it is a malloced buffer returned from
505: ** a previous call to this routine that may be reused.
1.2 misho 506: */
1.4 misho 507: static char *local_getline(char *zLine, FILE *in){
508: int nLine = zLine==0 ? 0 : 100;
509: int n = 0;
1.2 misho 510:
511: while( 1 ){
512: if( n+100>nLine ){
513: nLine = nLine*2 + 100;
514: zLine = realloc(zLine, nLine);
515: if( zLine==0 ) return 0;
516: }
517: if( fgets(&zLine[n], nLine - n, in)==0 ){
518: if( n==0 ){
519: free(zLine);
520: return 0;
521: }
522: zLine[n] = 0;
523: break;
524: }
1.4 misho 525: while( zLine[n] ) n++;
526: if( n>0 && zLine[n-1]=='\n' ){
1.2 misho 527: n--;
528: if( n>0 && zLine[n-1]=='\r' ) n--;
529: zLine[n] = 0;
530: break;
531: }
532: }
1.4 misho 533: #if defined(_WIN32) || defined(WIN32)
534: /* For interactive input on Windows systems, translate the
535: ** multi-byte characterset characters into UTF-8. */
536: if( stdin_is_interactive && in==stdin ){
537: char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
538: if( zTrans ){
539: int nTrans = strlen30(zTrans)+1;
540: if( nTrans>nLine ){
541: zLine = realloc(zLine, nTrans);
542: if( zLine==0 ){
543: sqlite3_free(zTrans);
544: return 0;
545: }
546: }
547: memcpy(zLine, zTrans, nTrans);
548: sqlite3_free(zTrans);
549: }
550: }
551: #endif /* defined(_WIN32) || defined(WIN32) */
1.2 misho 552: return zLine;
553: }
554:
555: /*
556: ** Retrieve a single line of input text.
557: **
1.4 misho 558: ** If in==0 then read from standard input and prompt before each line.
559: ** If isContinuation is true, then a continuation prompt is appropriate.
560: ** If isContinuation is zero, then the main prompt should be used.
561: **
562: ** If zPrior is not NULL then it is a buffer from a prior call to this
563: ** routine that can be reused.
564: **
565: ** The result is stored in space obtained from malloc() and must either
566: ** be freed by the caller or else passed back into this routine via the
567: ** zPrior argument for reuse.
1.2 misho 568: */
1.4 misho 569: static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
1.2 misho 570: char *zPrompt;
571: char *zResult;
572: if( in!=0 ){
1.4 misho 573: zResult = local_getline(zPrior, in);
1.2 misho 574: }else{
1.4 misho 575: zPrompt = isContinuation ? continuePrompt : mainPrompt;
576: #if SHELL_USE_LOCAL_GETLINE
577: printf("%s", zPrompt);
578: fflush(stdout);
579: zResult = local_getline(zPrior, stdin);
580: #else
581: free(zPrior);
582: zResult = shell_readline(zPrompt);
583: if( zResult && *zResult ) shell_add_history(zResult);
584: #endif
1.2 misho 585: }
586: return zResult;
587: }
1.4.2.1 ! misho 588: /*
! 589: ** A variable length string to which one can append text.
! 590: */
! 591: typedef struct ShellText ShellText;
! 592: struct ShellText {
! 593: char *z;
! 594: int n;
! 595: int nAlloc;
! 596: };
! 597:
! 598: /*
! 599: ** Initialize and destroy a ShellText object
! 600: */
! 601: static void initText(ShellText *p){
! 602: memset(p, 0, sizeof(*p));
! 603: }
! 604: static void freeText(ShellText *p){
! 605: free(p->z);
! 606: initText(p);
! 607: }
! 608:
! 609: /* zIn is either a pointer to a NULL-terminated string in memory obtained
! 610: ** from malloc(), or a NULL pointer. The string pointed to by zAppend is
! 611: ** added to zIn, and the result returned in memory obtained from malloc().
! 612: ** zIn, if it was not NULL, is freed.
! 613: **
! 614: ** If the third argument, quote, is not '\0', then it is used as a
! 615: ** quote character for zAppend.
! 616: */
! 617: static void appendText(ShellText *p, char const *zAppend, char quote){
! 618: int len;
! 619: int i;
! 620: int nAppend = strlen30(zAppend);
! 621:
! 622: len = nAppend+p->n+1;
! 623: if( quote ){
! 624: len += 2;
! 625: for(i=0; i<nAppend; i++){
! 626: if( zAppend[i]==quote ) len++;
! 627: }
! 628: }
! 629:
! 630: if( p->n+len>=p->nAlloc ){
! 631: p->nAlloc = p->nAlloc*2 + len + 20;
! 632: p->z = realloc(p->z, p->nAlloc);
! 633: if( p->z==0 ){
! 634: memset(p, 0, sizeof(*p));
! 635: return;
! 636: }
! 637: }
! 638:
! 639: if( quote ){
! 640: char *zCsr = p->z+p->n;
! 641: *zCsr++ = quote;
! 642: for(i=0; i<nAppend; i++){
! 643: *zCsr++ = zAppend[i];
! 644: if( zAppend[i]==quote ) *zCsr++ = quote;
! 645: }
! 646: *zCsr++ = quote;
! 647: p->n = (int)(zCsr - p->z);
! 648: *zCsr = '\0';
! 649: }else{
! 650: memcpy(p->z+p->n, zAppend, nAppend);
! 651: p->n += nAppend;
! 652: p->z[p->n] = '\0';
! 653: }
! 654: }
! 655:
! 656: /*
! 657: ** Attempt to determine if identifier zName needs to be quoted, either
! 658: ** because it contains non-alphanumeric characters, or because it is an
! 659: ** SQLite keyword. Be conservative in this estimate: When in doubt assume
! 660: ** that quoting is required.
! 661: **
! 662: ** Return '"' if quoting is required. Return 0 if no quoting is required.
! 663: */
! 664: static char quoteChar(const char *zName){
! 665: /* All SQLite keywords, in alphabetical order */
! 666: static const char *azKeywords[] = {
! 667: "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
! 668: "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
! 669: "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
! 670: "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
! 671: "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
! 672: "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
! 673: "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
! 674: "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
! 675: "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
! 676: "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
! 677: "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
! 678: "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
! 679: "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
! 680: "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
! 681: "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
! 682: "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
! 683: "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
! 684: "WITH", "WITHOUT",
! 685: };
! 686: int i, lwr, upr, mid, c;
! 687: if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
! 688: for(i=0; zName[i]; i++){
! 689: if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
! 690: }
! 691: lwr = 0;
! 692: upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
! 693: while( lwr<=upr ){
! 694: mid = (lwr+upr)/2;
! 695: c = sqlite3_stricmp(azKeywords[mid], zName);
! 696: if( c==0 ) return '"';
! 697: if( c<0 ){
! 698: lwr = mid+1;
! 699: }else{
! 700: upr = mid-1;
! 701: }
! 702: }
! 703: return 0;
! 704: }
! 705:
! 706: /******************************************************************************
! 707: ** SHA3 hash implementation copied from ../ext/misc/shathree.c
! 708: */
! 709: typedef sqlite3_uint64 u64;
! 710: /*
! 711: ** Macros to determine whether the machine is big or little endian,
! 712: ** and whether or not that determination is run-time or compile-time.
! 713: **
! 714: ** For best performance, an attempt is made to guess at the byte-order
! 715: ** using C-preprocessor macros. If that is unsuccessful, or if
! 716: ** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
! 717: ** at run-time.
! 718: */
! 719: #ifndef SHA3_BYTEORDER
! 720: # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
! 721: defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
! 722: defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
! 723: defined(__arm__)
! 724: # define SHA3_BYTEORDER 1234
! 725: # elif defined(sparc) || defined(__ppc__)
! 726: # define SHA3_BYTEORDER 4321
! 727: # else
! 728: # define SHA3_BYTEORDER 0
! 729: # endif
! 730: #endif
! 731:
! 732:
! 733: /*
! 734: ** State structure for a SHA3 hash in progress
! 735: */
! 736: typedef struct SHA3Context SHA3Context;
! 737: struct SHA3Context {
! 738: union {
! 739: u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */
! 740: unsigned char x[1600]; /* ... or 1600 bytes */
! 741: } u;
! 742: unsigned nRate; /* Bytes of input accepted per Keccak iteration */
! 743: unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
! 744: unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
! 745: };
! 746:
! 747: /* Allow the following routine to use the B0 variable, which is also
! 748: ** a macro in the termios.h header file */
! 749: #undef B0
! 750:
! 751: /*
! 752: ** A single step of the Keccak mixing function for a 1600-bit state
! 753: */
! 754: static void KeccakF1600Step(SHA3Context *p){
! 755: int i;
! 756: u64 B0, B1, B2, B3, B4;
! 757: u64 C0, C1, C2, C3, C4;
! 758: u64 D0, D1, D2, D3, D4;
! 759: static const u64 RC[] = {
! 760: 0x0000000000000001ULL, 0x0000000000008082ULL,
! 761: 0x800000000000808aULL, 0x8000000080008000ULL,
! 762: 0x000000000000808bULL, 0x0000000080000001ULL,
! 763: 0x8000000080008081ULL, 0x8000000000008009ULL,
! 764: 0x000000000000008aULL, 0x0000000000000088ULL,
! 765: 0x0000000080008009ULL, 0x000000008000000aULL,
! 766: 0x000000008000808bULL, 0x800000000000008bULL,
! 767: 0x8000000000008089ULL, 0x8000000000008003ULL,
! 768: 0x8000000000008002ULL, 0x8000000000000080ULL,
! 769: 0x000000000000800aULL, 0x800000008000000aULL,
! 770: 0x8000000080008081ULL, 0x8000000000008080ULL,
! 771: 0x0000000080000001ULL, 0x8000000080008008ULL
! 772: };
! 773: # define A00 (p->u.s[0])
! 774: # define A01 (p->u.s[1])
! 775: # define A02 (p->u.s[2])
! 776: # define A03 (p->u.s[3])
! 777: # define A04 (p->u.s[4])
! 778: # define A10 (p->u.s[5])
! 779: # define A11 (p->u.s[6])
! 780: # define A12 (p->u.s[7])
! 781: # define A13 (p->u.s[8])
! 782: # define A14 (p->u.s[9])
! 783: # define A20 (p->u.s[10])
! 784: # define A21 (p->u.s[11])
! 785: # define A22 (p->u.s[12])
! 786: # define A23 (p->u.s[13])
! 787: # define A24 (p->u.s[14])
! 788: # define A30 (p->u.s[15])
! 789: # define A31 (p->u.s[16])
! 790: # define A32 (p->u.s[17])
! 791: # define A33 (p->u.s[18])
! 792: # define A34 (p->u.s[19])
! 793: # define A40 (p->u.s[20])
! 794: # define A41 (p->u.s[21])
! 795: # define A42 (p->u.s[22])
! 796: # define A43 (p->u.s[23])
! 797: # define A44 (p->u.s[24])
! 798: # define ROL64(a,x) ((a<<x)|(a>>(64-x)))
! 799:
! 800: for(i=0; i<24; i+=4){
! 801: C0 = A00^A10^A20^A30^A40;
! 802: C1 = A01^A11^A21^A31^A41;
! 803: C2 = A02^A12^A22^A32^A42;
! 804: C3 = A03^A13^A23^A33^A43;
! 805: C4 = A04^A14^A24^A34^A44;
! 806: D0 = C4^ROL64(C1, 1);
! 807: D1 = C0^ROL64(C2, 1);
! 808: D2 = C1^ROL64(C3, 1);
! 809: D3 = C2^ROL64(C4, 1);
! 810: D4 = C3^ROL64(C0, 1);
! 811:
! 812: B0 = (A00^D0);
! 813: B1 = ROL64((A11^D1), 44);
! 814: B2 = ROL64((A22^D2), 43);
! 815: B3 = ROL64((A33^D3), 21);
! 816: B4 = ROL64((A44^D4), 14);
! 817: A00 = B0 ^((~B1)& B2 );
! 818: A00 ^= RC[i];
! 819: A11 = B1 ^((~B2)& B3 );
! 820: A22 = B2 ^((~B3)& B4 );
! 821: A33 = B3 ^((~B4)& B0 );
! 822: A44 = B4 ^((~B0)& B1 );
! 823:
! 824: B2 = ROL64((A20^D0), 3);
! 825: B3 = ROL64((A31^D1), 45);
! 826: B4 = ROL64((A42^D2), 61);
! 827: B0 = ROL64((A03^D3), 28);
! 828: B1 = ROL64((A14^D4), 20);
! 829: A20 = B0 ^((~B1)& B2 );
! 830: A31 = B1 ^((~B2)& B3 );
! 831: A42 = B2 ^((~B3)& B4 );
! 832: A03 = B3 ^((~B4)& B0 );
! 833: A14 = B4 ^((~B0)& B1 );
! 834:
! 835: B4 = ROL64((A40^D0), 18);
! 836: B0 = ROL64((A01^D1), 1);
! 837: B1 = ROL64((A12^D2), 6);
! 838: B2 = ROL64((A23^D3), 25);
! 839: B3 = ROL64((A34^D4), 8);
! 840: A40 = B0 ^((~B1)& B2 );
! 841: A01 = B1 ^((~B2)& B3 );
! 842: A12 = B2 ^((~B3)& B4 );
! 843: A23 = B3 ^((~B4)& B0 );
! 844: A34 = B4 ^((~B0)& B1 );
! 845:
! 846: B1 = ROL64((A10^D0), 36);
! 847: B2 = ROL64((A21^D1), 10);
! 848: B3 = ROL64((A32^D2), 15);
! 849: B4 = ROL64((A43^D3), 56);
! 850: B0 = ROL64((A04^D4), 27);
! 851: A10 = B0 ^((~B1)& B2 );
! 852: A21 = B1 ^((~B2)& B3 );
! 853: A32 = B2 ^((~B3)& B4 );
! 854: A43 = B3 ^((~B4)& B0 );
! 855: A04 = B4 ^((~B0)& B1 );
! 856:
! 857: B3 = ROL64((A30^D0), 41);
! 858: B4 = ROL64((A41^D1), 2);
! 859: B0 = ROL64((A02^D2), 62);
! 860: B1 = ROL64((A13^D3), 55);
! 861: B2 = ROL64((A24^D4), 39);
! 862: A30 = B0 ^((~B1)& B2 );
! 863: A41 = B1 ^((~B2)& B3 );
! 864: A02 = B2 ^((~B3)& B4 );
! 865: A13 = B3 ^((~B4)& B0 );
! 866: A24 = B4 ^((~B0)& B1 );
! 867:
! 868: C0 = A00^A20^A40^A10^A30;
! 869: C1 = A11^A31^A01^A21^A41;
! 870: C2 = A22^A42^A12^A32^A02;
! 871: C3 = A33^A03^A23^A43^A13;
! 872: C4 = A44^A14^A34^A04^A24;
! 873: D0 = C4^ROL64(C1, 1);
! 874: D1 = C0^ROL64(C2, 1);
! 875: D2 = C1^ROL64(C3, 1);
! 876: D3 = C2^ROL64(C4, 1);
! 877: D4 = C3^ROL64(C0, 1);
! 878:
! 879: B0 = (A00^D0);
! 880: B1 = ROL64((A31^D1), 44);
! 881: B2 = ROL64((A12^D2), 43);
! 882: B3 = ROL64((A43^D3), 21);
! 883: B4 = ROL64((A24^D4), 14);
! 884: A00 = B0 ^((~B1)& B2 );
! 885: A00 ^= RC[i+1];
! 886: A31 = B1 ^((~B2)& B3 );
! 887: A12 = B2 ^((~B3)& B4 );
! 888: A43 = B3 ^((~B4)& B0 );
! 889: A24 = B4 ^((~B0)& B1 );
! 890:
! 891: B2 = ROL64((A40^D0), 3);
! 892: B3 = ROL64((A21^D1), 45);
! 893: B4 = ROL64((A02^D2), 61);
! 894: B0 = ROL64((A33^D3), 28);
! 895: B1 = ROL64((A14^D4), 20);
! 896: A40 = B0 ^((~B1)& B2 );
! 897: A21 = B1 ^((~B2)& B3 );
! 898: A02 = B2 ^((~B3)& B4 );
! 899: A33 = B3 ^((~B4)& B0 );
! 900: A14 = B4 ^((~B0)& B1 );
! 901:
! 902: B4 = ROL64((A30^D0), 18);
! 903: B0 = ROL64((A11^D1), 1);
! 904: B1 = ROL64((A42^D2), 6);
! 905: B2 = ROL64((A23^D3), 25);
! 906: B3 = ROL64((A04^D4), 8);
! 907: A30 = B0 ^((~B1)& B2 );
! 908: A11 = B1 ^((~B2)& B3 );
! 909: A42 = B2 ^((~B3)& B4 );
! 910: A23 = B3 ^((~B4)& B0 );
! 911: A04 = B4 ^((~B0)& B1 );
! 912:
! 913: B1 = ROL64((A20^D0), 36);
! 914: B2 = ROL64((A01^D1), 10);
! 915: B3 = ROL64((A32^D2), 15);
! 916: B4 = ROL64((A13^D3), 56);
! 917: B0 = ROL64((A44^D4), 27);
! 918: A20 = B0 ^((~B1)& B2 );
! 919: A01 = B1 ^((~B2)& B3 );
! 920: A32 = B2 ^((~B3)& B4 );
! 921: A13 = B3 ^((~B4)& B0 );
! 922: A44 = B4 ^((~B0)& B1 );
! 923:
! 924: B3 = ROL64((A10^D0), 41);
! 925: B4 = ROL64((A41^D1), 2);
! 926: B0 = ROL64((A22^D2), 62);
! 927: B1 = ROL64((A03^D3), 55);
! 928: B2 = ROL64((A34^D4), 39);
! 929: A10 = B0 ^((~B1)& B2 );
! 930: A41 = B1 ^((~B2)& B3 );
! 931: A22 = B2 ^((~B3)& B4 );
! 932: A03 = B3 ^((~B4)& B0 );
! 933: A34 = B4 ^((~B0)& B1 );
! 934:
! 935: C0 = A00^A40^A30^A20^A10;
! 936: C1 = A31^A21^A11^A01^A41;
! 937: C2 = A12^A02^A42^A32^A22;
! 938: C3 = A43^A33^A23^A13^A03;
! 939: C4 = A24^A14^A04^A44^A34;
! 940: D0 = C4^ROL64(C1, 1);
! 941: D1 = C0^ROL64(C2, 1);
! 942: D2 = C1^ROL64(C3, 1);
! 943: D3 = C2^ROL64(C4, 1);
! 944: D4 = C3^ROL64(C0, 1);
! 945:
! 946: B0 = (A00^D0);
! 947: B1 = ROL64((A21^D1), 44);
! 948: B2 = ROL64((A42^D2), 43);
! 949: B3 = ROL64((A13^D3), 21);
! 950: B4 = ROL64((A34^D4), 14);
! 951: A00 = B0 ^((~B1)& B2 );
! 952: A00 ^= RC[i+2];
! 953: A21 = B1 ^((~B2)& B3 );
! 954: A42 = B2 ^((~B3)& B4 );
! 955: A13 = B3 ^((~B4)& B0 );
! 956: A34 = B4 ^((~B0)& B1 );
! 957:
! 958: B2 = ROL64((A30^D0), 3);
! 959: B3 = ROL64((A01^D1), 45);
! 960: B4 = ROL64((A22^D2), 61);
! 961: B0 = ROL64((A43^D3), 28);
! 962: B1 = ROL64((A14^D4), 20);
! 963: A30 = B0 ^((~B1)& B2 );
! 964: A01 = B1 ^((~B2)& B3 );
! 965: A22 = B2 ^((~B3)& B4 );
! 966: A43 = B3 ^((~B4)& B0 );
! 967: A14 = B4 ^((~B0)& B1 );
! 968:
! 969: B4 = ROL64((A10^D0), 18);
! 970: B0 = ROL64((A31^D1), 1);
! 971: B1 = ROL64((A02^D2), 6);
! 972: B2 = ROL64((A23^D3), 25);
! 973: B3 = ROL64((A44^D4), 8);
! 974: A10 = B0 ^((~B1)& B2 );
! 975: A31 = B1 ^((~B2)& B3 );
! 976: A02 = B2 ^((~B3)& B4 );
! 977: A23 = B3 ^((~B4)& B0 );
! 978: A44 = B4 ^((~B0)& B1 );
! 979:
! 980: B1 = ROL64((A40^D0), 36);
! 981: B2 = ROL64((A11^D1), 10);
! 982: B3 = ROL64((A32^D2), 15);
! 983: B4 = ROL64((A03^D3), 56);
! 984: B0 = ROL64((A24^D4), 27);
! 985: A40 = B0 ^((~B1)& B2 );
! 986: A11 = B1 ^((~B2)& B3 );
! 987: A32 = B2 ^((~B3)& B4 );
! 988: A03 = B3 ^((~B4)& B0 );
! 989: A24 = B4 ^((~B0)& B1 );
! 990:
! 991: B3 = ROL64((A20^D0), 41);
! 992: B4 = ROL64((A41^D1), 2);
! 993: B0 = ROL64((A12^D2), 62);
! 994: B1 = ROL64((A33^D3), 55);
! 995: B2 = ROL64((A04^D4), 39);
! 996: A20 = B0 ^((~B1)& B2 );
! 997: A41 = B1 ^((~B2)& B3 );
! 998: A12 = B2 ^((~B3)& B4 );
! 999: A33 = B3 ^((~B4)& B0 );
! 1000: A04 = B4 ^((~B0)& B1 );
! 1001:
! 1002: C0 = A00^A30^A10^A40^A20;
! 1003: C1 = A21^A01^A31^A11^A41;
! 1004: C2 = A42^A22^A02^A32^A12;
! 1005: C3 = A13^A43^A23^A03^A33;
! 1006: C4 = A34^A14^A44^A24^A04;
! 1007: D0 = C4^ROL64(C1, 1);
! 1008: D1 = C0^ROL64(C2, 1);
! 1009: D2 = C1^ROL64(C3, 1);
! 1010: D3 = C2^ROL64(C4, 1);
! 1011: D4 = C3^ROL64(C0, 1);
! 1012:
! 1013: B0 = (A00^D0);
! 1014: B1 = ROL64((A01^D1), 44);
! 1015: B2 = ROL64((A02^D2), 43);
! 1016: B3 = ROL64((A03^D3), 21);
! 1017: B4 = ROL64((A04^D4), 14);
! 1018: A00 = B0 ^((~B1)& B2 );
! 1019: A00 ^= RC[i+3];
! 1020: A01 = B1 ^((~B2)& B3 );
! 1021: A02 = B2 ^((~B3)& B4 );
! 1022: A03 = B3 ^((~B4)& B0 );
! 1023: A04 = B4 ^((~B0)& B1 );
! 1024:
! 1025: B2 = ROL64((A10^D0), 3);
! 1026: B3 = ROL64((A11^D1), 45);
! 1027: B4 = ROL64((A12^D2), 61);
! 1028: B0 = ROL64((A13^D3), 28);
! 1029: B1 = ROL64((A14^D4), 20);
! 1030: A10 = B0 ^((~B1)& B2 );
! 1031: A11 = B1 ^((~B2)& B3 );
! 1032: A12 = B2 ^((~B3)& B4 );
! 1033: A13 = B3 ^((~B4)& B0 );
! 1034: A14 = B4 ^((~B0)& B1 );
! 1035:
! 1036: B4 = ROL64((A20^D0), 18);
! 1037: B0 = ROL64((A21^D1), 1);
! 1038: B1 = ROL64((A22^D2), 6);
! 1039: B2 = ROL64((A23^D3), 25);
! 1040: B3 = ROL64((A24^D4), 8);
! 1041: A20 = B0 ^((~B1)& B2 );
! 1042: A21 = B1 ^((~B2)& B3 );
! 1043: A22 = B2 ^((~B3)& B4 );
! 1044: A23 = B3 ^((~B4)& B0 );
! 1045: A24 = B4 ^((~B0)& B1 );
! 1046:
! 1047: B1 = ROL64((A30^D0), 36);
! 1048: B2 = ROL64((A31^D1), 10);
! 1049: B3 = ROL64((A32^D2), 15);
! 1050: B4 = ROL64((A33^D3), 56);
! 1051: B0 = ROL64((A34^D4), 27);
! 1052: A30 = B0 ^((~B1)& B2 );
! 1053: A31 = B1 ^((~B2)& B3 );
! 1054: A32 = B2 ^((~B3)& B4 );
! 1055: A33 = B3 ^((~B4)& B0 );
! 1056: A34 = B4 ^((~B0)& B1 );
! 1057:
! 1058: B3 = ROL64((A40^D0), 41);
! 1059: B4 = ROL64((A41^D1), 2);
! 1060: B0 = ROL64((A42^D2), 62);
! 1061: B1 = ROL64((A43^D3), 55);
! 1062: B2 = ROL64((A44^D4), 39);
! 1063: A40 = B0 ^((~B1)& B2 );
! 1064: A41 = B1 ^((~B2)& B3 );
! 1065: A42 = B2 ^((~B3)& B4 );
! 1066: A43 = B3 ^((~B4)& B0 );
! 1067: A44 = B4 ^((~B0)& B1 );
! 1068: }
! 1069: }
! 1070:
! 1071: /*
! 1072: ** Initialize a new hash. iSize determines the size of the hash
! 1073: ** in bits and should be one of 224, 256, 384, or 512. Or iSize
! 1074: ** can be zero to use the default hash size of 256 bits.
! 1075: */
! 1076: static void SHA3Init(SHA3Context *p, int iSize){
! 1077: memset(p, 0, sizeof(*p));
! 1078: if( iSize>=128 && iSize<=512 ){
! 1079: p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
! 1080: }else{
! 1081: p->nRate = (1600 - 2*256)/8;
! 1082: }
! 1083: #if SHA3_BYTEORDER==1234
! 1084: /* Known to be little-endian at compile-time. No-op */
! 1085: #elif SHA3_BYTEORDER==4321
! 1086: p->ixMask = 7; /* Big-endian */
! 1087: #else
! 1088: {
! 1089: static unsigned int one = 1;
! 1090: if( 1==*(unsigned char*)&one ){
! 1091: /* Little endian. No byte swapping. */
! 1092: p->ixMask = 0;
! 1093: }else{
! 1094: /* Big endian. Byte swap. */
! 1095: p->ixMask = 7;
! 1096: }
! 1097: }
! 1098: #endif
! 1099: }
! 1100:
! 1101: /*
! 1102: ** Make consecutive calls to the SHA3Update function to add new content
! 1103: ** to the hash
! 1104: */
! 1105: static void SHA3Update(
! 1106: SHA3Context *p,
! 1107: const unsigned char *aData,
! 1108: unsigned int nData
! 1109: ){
! 1110: unsigned int i = 0;
! 1111: #if SHA3_BYTEORDER==1234
! 1112: if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
! 1113: for(; i+7<nData; i+=8){
! 1114: p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
! 1115: p->nLoaded += 8;
! 1116: if( p->nLoaded>=p->nRate ){
! 1117: KeccakF1600Step(p);
! 1118: p->nLoaded = 0;
! 1119: }
! 1120: }
! 1121: }
! 1122: #endif
! 1123: for(; i<nData; i++){
! 1124: #if SHA3_BYTEORDER==1234
! 1125: p->u.x[p->nLoaded] ^= aData[i];
! 1126: #elif SHA3_BYTEORDER==4321
! 1127: p->u.x[p->nLoaded^0x07] ^= aData[i];
! 1128: #else
! 1129: p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
! 1130: #endif
! 1131: p->nLoaded++;
! 1132: if( p->nLoaded==p->nRate ){
! 1133: KeccakF1600Step(p);
! 1134: p->nLoaded = 0;
! 1135: }
! 1136: }
! 1137: }
! 1138:
! 1139: /*
! 1140: ** After all content has been added, invoke SHA3Final() to compute
! 1141: ** the final hash. The function returns a pointer to the binary
! 1142: ** hash value.
! 1143: */
! 1144: static unsigned char *SHA3Final(SHA3Context *p){
! 1145: unsigned int i;
! 1146: if( p->nLoaded==p->nRate-1 ){
! 1147: const unsigned char c1 = 0x86;
! 1148: SHA3Update(p, &c1, 1);
! 1149: }else{
! 1150: const unsigned char c2 = 0x06;
! 1151: const unsigned char c3 = 0x80;
! 1152: SHA3Update(p, &c2, 1);
! 1153: p->nLoaded = p->nRate - 1;
! 1154: SHA3Update(p, &c3, 1);
! 1155: }
! 1156: for(i=0; i<p->nRate; i++){
! 1157: p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
! 1158: }
! 1159: return &p->u.x[p->nRate];
! 1160: }
! 1161:
! 1162: /*
! 1163: ** Implementation of the sha3(X,SIZE) function.
! 1164: **
! 1165: ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default
! 1166: ** size is 256. If X is a BLOB, it is hashed as is.
! 1167: ** For all other non-NULL types of input, X is converted into a UTF-8 string
! 1168: ** and the string is hashed without the trailing 0x00 terminator. The hash
! 1169: ** of a NULL value is NULL.
! 1170: */
! 1171: static void sha3Func(
! 1172: sqlite3_context *context,
! 1173: int argc,
! 1174: sqlite3_value **argv
! 1175: ){
! 1176: SHA3Context cx;
! 1177: int eType = sqlite3_value_type(argv[0]);
! 1178: int nByte = sqlite3_value_bytes(argv[0]);
! 1179: int iSize;
! 1180: if( argc==1 ){
! 1181: iSize = 256;
! 1182: }else{
! 1183: iSize = sqlite3_value_int(argv[1]);
! 1184: if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
! 1185: sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
! 1186: "384 512", -1);
! 1187: return;
! 1188: }
! 1189: }
! 1190: if( eType==SQLITE_NULL ) return;
! 1191: SHA3Init(&cx, iSize);
! 1192: if( eType==SQLITE_BLOB ){
! 1193: SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte);
! 1194: }else{
! 1195: SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte);
! 1196: }
! 1197: sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
! 1198: }
! 1199:
! 1200: /* Compute a string using sqlite3_vsnprintf() with a maximum length
! 1201: ** of 50 bytes and add it to the hash.
! 1202: */
! 1203: static void hash_step_vformat(
! 1204: SHA3Context *p, /* Add content to this context */
! 1205: const char *zFormat,
! 1206: ...
! 1207: ){
! 1208: va_list ap;
! 1209: int n;
! 1210: char zBuf[50];
! 1211: va_start(ap, zFormat);
! 1212: sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
! 1213: va_end(ap);
! 1214: n = (int)strlen(zBuf);
! 1215: SHA3Update(p, (unsigned char*)zBuf, n);
! 1216: }
! 1217:
! 1218: /*
! 1219: ** Implementation of the sha3_query(SQL,SIZE) function.
! 1220: **
! 1221: ** This function compiles and runs the SQL statement(s) given in the
! 1222: ** argument. The results are hashed using a SIZE-bit SHA3. The default
! 1223: ** size is 256.
! 1224: **
! 1225: ** The format of the byte stream that is hashed is summarized as follows:
! 1226: **
! 1227: ** S<n>:<sql>
! 1228: ** R
! 1229: ** N
! 1230: ** I<int>
! 1231: ** F<ieee-float>
! 1232: ** B<size>:<bytes>
! 1233: ** T<size>:<text>
! 1234: **
! 1235: ** <sql> is the original SQL text for each statement run and <n> is
! 1236: ** the size of that text. The SQL text is UTF-8. A single R character
! 1237: ** occurs before the start of each row. N means a NULL value.
! 1238: ** I mean an 8-byte little-endian integer <int>. F is a floating point
! 1239: ** number with an 8-byte little-endian IEEE floating point value <ieee-float>.
! 1240: ** B means blobs of <size> bytes. T means text rendered as <size>
! 1241: ** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII
! 1242: ** text integers.
! 1243: **
! 1244: ** For each SQL statement in the X input, there is one S segment. Each
! 1245: ** S segment is followed by zero or more R segments, one for each row in the
! 1246: ** result set. After each R, there are one or more N, I, F, B, or T segments,
! 1247: ** one for each column in the result set. Segments are concatentated directly
! 1248: ** with no delimiters of any kind.
! 1249: */
! 1250: static void sha3QueryFunc(
! 1251: sqlite3_context *context,
! 1252: int argc,
! 1253: sqlite3_value **argv
! 1254: ){
! 1255: sqlite3 *db = sqlite3_context_db_handle(context);
! 1256: const char *zSql = (const char*)sqlite3_value_text(argv[0]);
! 1257: sqlite3_stmt *pStmt = 0;
! 1258: int nCol; /* Number of columns in the result set */
! 1259: int i; /* Loop counter */
! 1260: int rc;
! 1261: int n;
! 1262: const char *z;
! 1263: SHA3Context cx;
! 1264: int iSize;
! 1265:
! 1266: if( argc==1 ){
! 1267: iSize = 256;
! 1268: }else{
! 1269: iSize = sqlite3_value_int(argv[1]);
! 1270: if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
! 1271: sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
! 1272: "384 512", -1);
! 1273: return;
! 1274: }
! 1275: }
! 1276: if( zSql==0 ) return;
! 1277: SHA3Init(&cx, iSize);
! 1278: while( zSql[0] ){
! 1279: rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
! 1280: if( rc ){
! 1281: char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
! 1282: zSql, sqlite3_errmsg(db));
! 1283: sqlite3_finalize(pStmt);
! 1284: sqlite3_result_error(context, zMsg, -1);
! 1285: sqlite3_free(zMsg);
! 1286: return;
! 1287: }
! 1288: if( !sqlite3_stmt_readonly(pStmt) ){
! 1289: char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
! 1290: sqlite3_finalize(pStmt);
! 1291: sqlite3_result_error(context, zMsg, -1);
! 1292: sqlite3_free(zMsg);
! 1293: return;
! 1294: }
! 1295: nCol = sqlite3_column_count(pStmt);
! 1296: z = sqlite3_sql(pStmt);
! 1297: if( z==0 ){
! 1298: sqlite3_finalize(pStmt);
! 1299: continue;
! 1300: }
! 1301: n = (int)strlen(z);
! 1302: hash_step_vformat(&cx,"S%d:",n);
! 1303: SHA3Update(&cx,(unsigned char*)z,n);
! 1304:
! 1305: /* Compute a hash over the result of the query */
! 1306: while( SQLITE_ROW==sqlite3_step(pStmt) ){
! 1307: SHA3Update(&cx,(const unsigned char*)"R",1);
! 1308: for(i=0; i<nCol; i++){
! 1309: switch( sqlite3_column_type(pStmt,i) ){
! 1310: case SQLITE_NULL: {
! 1311: SHA3Update(&cx, (const unsigned char*)"N",1);
! 1312: break;
! 1313: }
! 1314: case SQLITE_INTEGER: {
! 1315: sqlite3_uint64 u;
! 1316: int j;
! 1317: unsigned char x[9];
! 1318: sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
! 1319: memcpy(&u, &v, 8);
! 1320: for(j=8; j>=1; j--){
! 1321: x[j] = u & 0xff;
! 1322: u >>= 8;
! 1323: }
! 1324: x[0] = 'I';
! 1325: SHA3Update(&cx, x, 9);
! 1326: break;
! 1327: }
! 1328: case SQLITE_FLOAT: {
! 1329: sqlite3_uint64 u;
! 1330: int j;
! 1331: unsigned char x[9];
! 1332: double r = sqlite3_column_double(pStmt,i);
! 1333: memcpy(&u, &r, 8);
! 1334: for(j=8; j>=1; j--){
! 1335: x[j] = u & 0xff;
! 1336: u >>= 8;
! 1337: }
! 1338: x[0] = 'F';
! 1339: SHA3Update(&cx,x,9);
! 1340: break;
! 1341: }
! 1342: case SQLITE_TEXT: {
! 1343: int n2 = sqlite3_column_bytes(pStmt, i);
! 1344: const unsigned char *z2 = sqlite3_column_text(pStmt, i);
! 1345: hash_step_vformat(&cx,"T%d:",n2);
! 1346: SHA3Update(&cx, z2, n2);
! 1347: break;
! 1348: }
! 1349: case SQLITE_BLOB: {
! 1350: int n2 = sqlite3_column_bytes(pStmt, i);
! 1351: const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
! 1352: hash_step_vformat(&cx,"B%d:",n2);
! 1353: SHA3Update(&cx, z2, n2);
! 1354: break;
! 1355: }
! 1356: }
! 1357: }
! 1358: }
! 1359: sqlite3_finalize(pStmt);
! 1360: }
! 1361: sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
! 1362: }
! 1363: /* End of SHA3 hashing logic copy/pasted from ../ext/misc/shathree.c
! 1364: ********************************************************************************/
1.2 misho 1365:
1.4 misho 1366: #if defined(SQLITE_ENABLE_SESSION)
1367: /*
1368: ** State information for a single open session
1369: */
1370: typedef struct OpenSession OpenSession;
1371: struct OpenSession {
1372: char *zName; /* Symbolic name for this session */
1373: int nFilter; /* Number of xFilter rejection GLOB patterns */
1374: char **azFilter; /* Array of xFilter rejection GLOB patterns */
1375: sqlite3_session *p; /* The open session */
1376: };
1377: #endif
1378:
1379: /*
1380: ** Shell output mode information from before ".explain on",
1381: ** saved so that it can be restored by ".explain off"
1382: */
1383: typedef struct SavedModeInfo SavedModeInfo;
1384: struct SavedModeInfo {
1385: int valid; /* Is there legit data in here? */
1386: int mode; /* Mode prior to ".explain on" */
1387: int showHeader; /* The ".header" setting prior to ".explain on" */
1388: int colWidth[100]; /* Column widths prior to ".explain on" */
1.2 misho 1389: };
1390:
1391: /*
1.4 misho 1392: ** State information about the database connection is contained in an
1393: ** instance of the following structure.
1.2 misho 1394: */
1.4 misho 1395: typedef struct ShellState ShellState;
1396: struct ShellState {
1.2 misho 1397: sqlite3 *db; /* The database */
1.4 misho 1398: int autoExplain; /* Automatically turn on .explain mode */
1399: int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
1.2 misho 1400: int statsOn; /* True to display memory stats before each finalize */
1.4 misho 1401: int scanstatsOn; /* True to display scan stats before each finalize */
1402: int outCount; /* Revert to stdout when reaching zero */
1.2 misho 1403: int cnt; /* Number of records displayed so far */
1404: FILE *out; /* Write results here */
1.3 misho 1405: FILE *traceOut; /* Output for sqlite3_trace() */
1.2 misho 1406: int nErr; /* Number of errors seen */
1407: int mode; /* An output mode setting */
1.4 misho 1408: int cMode; /* temporary output mode for the current query */
1409: int normalMode; /* Output mode before ".explain on" */
1.2 misho 1410: int writableSchema; /* True if PRAGMA writable_schema=ON */
1411: int showHeader; /* True to show column names in List or Column mode */
1.4.2.1 ! misho 1412: int nCheck; /* Number of ".check" commands run */
1.4 misho 1413: unsigned shellFlgs; /* Various flags */
1.2 misho 1414: char *zDestTable; /* Name of destination table when MODE_Insert */
1.4.2.1 ! misho 1415: char zTestcase[30]; /* Name of current test case */
1.4 misho 1416: char colSeparator[20]; /* Column separator character for several modes */
1417: char rowSeparator[20]; /* Row separator character for MODE_Ascii */
1.2 misho 1418: int colWidth[100]; /* Requested width of each column when in column mode*/
1419: int actualWidth[100]; /* Actual width of each column */
1.4 misho 1420: char nullValue[20]; /* The text to print when a NULL comes back from
1.2 misho 1421: ** the database */
1422: char outfile[FILENAME_MAX]; /* Filename for *out */
1423: const char *zDbFilename; /* name of the database file */
1.4 misho 1424: char *zFreeOnClose; /* Filename to free when closing */
1.2 misho 1425: const char *zVfs; /* Name of VFS to use */
1426: sqlite3_stmt *pStmt; /* Current statement if any. */
1427: FILE *pLog; /* Write log output here */
1.4 misho 1428: int *aiIndent; /* Array of indents used in MODE_Explain */
1429: int nIndent; /* Size of array aiIndent[] */
1430: int iIndent; /* Index of current op in aiIndent[] */
1431: #if defined(SQLITE_ENABLE_SESSION)
1432: int nSession; /* Number of active sessions */
1433: OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
1434: #endif
1.2 misho 1435: };
1436:
1437: /*
1.4 misho 1438: ** These are the allowed shellFlgs values
1439: */
1.4.2.1 ! misho 1440: #define SHFLG_Scratch 0x00000001 /* The --scratch option is used */
! 1441: #define SHFLG_Pagecache 0x00000002 /* The --pagecache option is used */
! 1442: #define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */
! 1443: #define SHFLG_Backslash 0x00000008 /* The --backslash option is used */
! 1444: #define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */
! 1445: #define SHFLG_CountChanges 0x00000020 /* .changes setting */
! 1446: #define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
! 1447:
! 1448: /*
! 1449: ** Macros for testing and setting shellFlgs
! 1450: */
! 1451: #define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
! 1452: #define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
! 1453: #define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
1.4 misho 1454:
1455: /*
1.2 misho 1456: ** These are the allowed modes.
1457: */
1458: #define MODE_Line 0 /* One column per line. Blank line between records */
1459: #define MODE_Column 1 /* One record per line in neat columns */
1460: #define MODE_List 2 /* One record per line with a separator */
1461: #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
1462: #define MODE_Html 4 /* Generate an XHTML table */
1463: #define MODE_Insert 5 /* Generate SQL "insert" statements */
1.4.2.1 ! misho 1464: #define MODE_Quote 6 /* Quote values as for SQL */
! 1465: #define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
! 1466: #define MODE_Csv 8 /* Quote strings, numbers are plain */
! 1467: #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
! 1468: #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
! 1469: #define MODE_Pretty 11 /* Pretty-print schemas */
1.2 misho 1470:
1471: static const char *modeDescr[] = {
1472: "line",
1473: "column",
1474: "list",
1475: "semi",
1476: "html",
1477: "insert",
1.4.2.1 ! misho 1478: "quote",
1.2 misho 1479: "tcl",
1480: "csv",
1481: "explain",
1.4 misho 1482: "ascii",
1483: "prettyprint",
1.2 misho 1484: };
1485:
1486: /*
1.4 misho 1487: ** These are the column/row/line separators used by the various
1488: ** import/export modes.
1.2 misho 1489: */
1.4 misho 1490: #define SEP_Column "|"
1491: #define SEP_Row "\n"
1492: #define SEP_Tab "\t"
1493: #define SEP_Space " "
1494: #define SEP_Comma ","
1495: #define SEP_CrLf "\r\n"
1496: #define SEP_Unit "\x1F"
1497: #define SEP_Record "\x1E"
1.2 misho 1498:
1499: /*
1.4 misho 1500: ** Number of elements in an array
1.2 misho 1501: */
1.4 misho 1502: #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
1.2 misho 1503:
1504: /*
1505: ** A callback for the sqlite3_log() interface.
1506: */
1507: static void shellLog(void *pArg, int iErrCode, const char *zMsg){
1.4 misho 1508: ShellState *p = (ShellState*)pArg;
1.2 misho 1509: if( p->pLog==0 ) return;
1.4 misho 1510: utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
1.2 misho 1511: fflush(p->pLog);
1512: }
1513:
1514: /*
1515: ** Output the given string as a hex-encoded blob (eg. X'1234' )
1516: */
1517: static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
1518: int i;
1519: char *zBlob = (char *)pBlob;
1.4 misho 1520: raw_printf(out,"X'");
1521: for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
1522: raw_printf(out,"'");
1.2 misho 1523: }
1524:
1525: /*
1.4.2.1 ! misho 1526: ** Find a string that is not found anywhere in z[]. Return a pointer
! 1527: ** to that string.
! 1528: **
! 1529: ** Try to use zA and zB first. If both of those are already found in z[]
! 1530: ** then make up some string and store it in the buffer zBuf.
! 1531: */
! 1532: static const char *unused_string(
! 1533: const char *z, /* Result must not appear anywhere in z */
! 1534: const char *zA, const char *zB, /* Try these first */
! 1535: char *zBuf /* Space to store a generated string */
! 1536: ){
! 1537: unsigned i = 0;
! 1538: if( strstr(z, zA)==0 ) return zA;
! 1539: if( strstr(z, zB)==0 ) return zB;
! 1540: do{
! 1541: sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
! 1542: }while( strstr(z,zBuf)!=0 );
! 1543: return zBuf;
! 1544: }
! 1545:
! 1546: /*
1.2 misho 1547: ** Output the given string as a quoted string using SQL quoting conventions.
1.4.2.1 ! misho 1548: **
! 1549: ** See also: output_quoted_escaped_string()
1.2 misho 1550: */
1551: static void output_quoted_string(FILE *out, const char *z){
1552: int i;
1.4.2.1 ! misho 1553: char c;
1.4 misho 1554: setBinaryMode(out, 1);
1.4.2.1 ! misho 1555: for(i=0; (c = z[i])!=0 && c!='\''; i++){}
! 1556: if( c==0 ){
! 1557: utf8_printf(out,"'%s'",z);
! 1558: }else{
! 1559: raw_printf(out, "'");
! 1560: while( *z ){
! 1561: for(i=0; (c = z[i])!=0 && c!='\''; i++){}
! 1562: if( c=='\'' ) i++;
! 1563: if( i ){
! 1564: utf8_printf(out, "%.*s", i, z);
! 1565: z += i;
! 1566: }
! 1567: if( c=='\'' ){
! 1568: raw_printf(out, "'");
! 1569: continue;
! 1570: }
! 1571: if( c==0 ){
! 1572: break;
! 1573: }
! 1574: z++;
! 1575: }
! 1576: raw_printf(out, "'");
1.2 misho 1577: }
1.4.2.1 ! misho 1578: setTextMode(out, 1);
! 1579: }
! 1580:
! 1581: /*
! 1582: ** Output the given string as a quoted string using SQL quoting conventions.
! 1583: ** Additionallly , escape the "\n" and "\r" characters so that they do not
! 1584: ** get corrupted by end-of-line translation facilities in some operating
! 1585: ** systems.
! 1586: **
! 1587: ** This is like output_quoted_string() but with the addition of the \r\n
! 1588: ** escape mechanism.
! 1589: */
! 1590: static void output_quoted_escaped_string(FILE *out, const char *z){
! 1591: int i;
! 1592: char c;
! 1593: setBinaryMode(out, 1);
! 1594: for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
! 1595: if( c==0 ){
1.4 misho 1596: utf8_printf(out,"'%s'",z);
1.2 misho 1597: }else{
1.4.2.1 ! misho 1598: const char *zNL = 0;
! 1599: const char *zCR = 0;
! 1600: int nNL = 0;
! 1601: int nCR = 0;
! 1602: char zBuf1[20], zBuf2[20];
! 1603: for(i=0; z[i]; i++){
! 1604: if( z[i]=='\n' ) nNL++;
! 1605: if( z[i]=='\r' ) nCR++;
! 1606: }
! 1607: if( nNL ){
! 1608: raw_printf(out, "replace(");
! 1609: zNL = unused_string(z, "\\n", "\\012", zBuf1);
! 1610: }
! 1611: if( nCR ){
! 1612: raw_printf(out, "replace(");
! 1613: zCR = unused_string(z, "\\r", "\\015", zBuf2);
! 1614: }
! 1615: raw_printf(out, "'");
1.2 misho 1616: while( *z ){
1.4.2.1 ! misho 1617: for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
! 1618: if( c=='\'' ) i++;
! 1619: if( i ){
! 1620: utf8_printf(out, "%.*s", i, z);
! 1621: z += i;
! 1622: }
! 1623: if( c=='\'' ){
! 1624: raw_printf(out, "'");
! 1625: continue;
! 1626: }
! 1627: if( c==0 ){
1.2 misho 1628: break;
1629: }
1.4.2.1 ! misho 1630: z++;
! 1631: if( c=='\n' ){
! 1632: raw_printf(out, "%s", zNL);
! 1633: continue;
! 1634: }
! 1635: raw_printf(out, "%s", zCR);
! 1636: }
! 1637: raw_printf(out, "'");
! 1638: if( nCR ){
! 1639: raw_printf(out, ",'%s',char(13))", zCR);
! 1640: }
! 1641: if( nNL ){
! 1642: raw_printf(out, ",'%s',char(10))", zNL);
1.2 misho 1643: }
1644: }
1.4 misho 1645: setTextMode(out, 1);
1.2 misho 1646: }
1647:
1648: /*
1649: ** Output the given string as a quoted according to C or TCL quoting rules.
1650: */
1651: static void output_c_string(FILE *out, const char *z){
1652: unsigned int c;
1653: fputc('"', out);
1654: while( (c = *(z++))!=0 ){
1655: if( c=='\\' ){
1656: fputc(c, out);
1657: fputc(c, out);
1.3 misho 1658: }else if( c=='"' ){
1659: fputc('\\', out);
1660: fputc('"', out);
1.2 misho 1661: }else if( c=='\t' ){
1662: fputc('\\', out);
1663: fputc('t', out);
1664: }else if( c=='\n' ){
1665: fputc('\\', out);
1666: fputc('n', out);
1667: }else if( c=='\r' ){
1668: fputc('\\', out);
1669: fputc('r', out);
1.4 misho 1670: }else if( !isprint(c&0xff) ){
1671: raw_printf(out, "\\%03o", c&0xff);
1.2 misho 1672: }else{
1673: fputc(c, out);
1674: }
1675: }
1676: fputc('"', out);
1677: }
1678:
1679: /*
1680: ** Output the given string with characters that are special to
1681: ** HTML escaped.
1682: */
1683: static void output_html_string(FILE *out, const char *z){
1684: int i;
1.4 misho 1685: if( z==0 ) z = "";
1.2 misho 1686: while( *z ){
1.4 misho 1687: for(i=0; z[i]
1688: && z[i]!='<'
1689: && z[i]!='&'
1690: && z[i]!='>'
1691: && z[i]!='\"'
1.2 misho 1692: && z[i]!='\'';
1693: i++){}
1694: if( i>0 ){
1.4 misho 1695: utf8_printf(out,"%.*s",i,z);
1.2 misho 1696: }
1697: if( z[i]=='<' ){
1.4 misho 1698: raw_printf(out,"<");
1.2 misho 1699: }else if( z[i]=='&' ){
1.4 misho 1700: raw_printf(out,"&");
1.2 misho 1701: }else if( z[i]=='>' ){
1.4 misho 1702: raw_printf(out,">");
1.2 misho 1703: }else if( z[i]=='\"' ){
1.4 misho 1704: raw_printf(out,""");
1.2 misho 1705: }else if( z[i]=='\'' ){
1.4 misho 1706: raw_printf(out,"'");
1.2 misho 1707: }else{
1708: break;
1709: }
1710: z += i + 1;
1711: }
1712: }
1713:
1714: /*
1715: ** If a field contains any character identified by a 1 in the following
1716: ** array, then the string must be quoted for CSV.
1717: */
1718: static const char needCsvQuote[] = {
1.4 misho 1719: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1720: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1721: 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1722: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1723: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1724: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1725: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1726: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1727: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1728: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1729: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1730: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1731: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1732: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1733: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1734: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1.2 misho 1735: };
1736:
1737: /*
1.4 misho 1738: ** Output a single term of CSV. Actually, p->colSeparator is used for
1739: ** the separator, which may or may not be a comma. p->nullValue is
1740: ** the null value. Strings are quoted if necessary. The separator
1741: ** is only issued if bSep is true.
1.2 misho 1742: */
1.4 misho 1743: static void output_csv(ShellState *p, const char *z, int bSep){
1.2 misho 1744: FILE *out = p->out;
1745: if( z==0 ){
1.4 misho 1746: utf8_printf(out,"%s",p->nullValue);
1.2 misho 1747: }else{
1748: int i;
1.4 misho 1749: int nSep = strlen30(p->colSeparator);
1.2 misho 1750: for(i=0; z[i]; i++){
1.4 misho 1751: if( needCsvQuote[((unsigned char*)z)[i]]
1752: || (z[i]==p->colSeparator[0] &&
1753: (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
1.2 misho 1754: i = 0;
1755: break;
1756: }
1757: }
1758: if( i==0 ){
1759: putc('"', out);
1760: for(i=0; z[i]; i++){
1761: if( z[i]=='"' ) putc('"', out);
1762: putc(z[i], out);
1763: }
1764: putc('"', out);
1765: }else{
1.4 misho 1766: utf8_printf(out, "%s", z);
1.2 misho 1767: }
1768: }
1769: if( bSep ){
1.4 misho 1770: utf8_printf(p->out, "%s", p->colSeparator);
1.2 misho 1771: }
1772: }
1773:
1774: #ifdef SIGINT
1775: /*
1776: ** This routine runs when the user presses Ctrl-C
1777: */
1778: static void interrupt_handler(int NotUsed){
1779: UNUSED_PARAMETER(NotUsed);
1.4 misho 1780: seenInterrupt++;
1781: if( seenInterrupt>2 ) exit(1);
1782: if( globalDb ) sqlite3_interrupt(globalDb);
1.2 misho 1783: }
1784: #endif
1785:
1.4.2.1 ! misho 1786: #ifndef SQLITE_OMIT_AUTHORIZATION
1.2 misho 1787: /*
1.4 misho 1788: ** When the ".auth ON" is set, the following authorizer callback is
1789: ** invoked. It always returns SQLITE_OK.
1790: */
1791: static int shellAuth(
1792: void *pClientData,
1793: int op,
1794: const char *zA1,
1795: const char *zA2,
1796: const char *zA3,
1797: const char *zA4
1798: ){
1799: ShellState *p = (ShellState*)pClientData;
1800: static const char *azAction[] = { 0,
1801: "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
1802: "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
1803: "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
1804: "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
1805: "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
1806: "DROP_TRIGGER", "DROP_VIEW", "INSERT",
1807: "PRAGMA", "READ", "SELECT",
1808: "TRANSACTION", "UPDATE", "ATTACH",
1809: "DETACH", "ALTER_TABLE", "REINDEX",
1810: "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
1811: "FUNCTION", "SAVEPOINT", "RECURSIVE"
1812: };
1813: int i;
1814: const char *az[4];
1815: az[0] = zA1;
1816: az[1] = zA2;
1817: az[2] = zA3;
1818: az[3] = zA4;
1.4.2.1 ! misho 1819: utf8_printf(p->out, "authorizer: %s", azAction[op]);
1.4 misho 1820: for(i=0; i<4; i++){
1821: raw_printf(p->out, " ");
1822: if( az[i] ){
1823: output_c_string(p->out, az[i]);
1824: }else{
1825: raw_printf(p->out, "NULL");
1826: }
1827: }
1828: raw_printf(p->out, "\n");
1829: return SQLITE_OK;
1830: }
1.4.2.1 ! misho 1831: #endif
! 1832:
! 1833: /*
! 1834: ** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
! 1835: **
! 1836: ** This routine converts some CREATE TABLE statements for shadow tables
! 1837: ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
! 1838: */
! 1839: static void printSchemaLine(FILE *out, const char *z, const char *zTail){
! 1840: if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
! 1841: utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
! 1842: }else{
! 1843: utf8_printf(out, "%s%s", z, zTail);
! 1844: }
! 1845: }
! 1846: static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
! 1847: char c = z[n];
! 1848: z[n] = 0;
! 1849: printSchemaLine(out, z, zTail);
! 1850: z[n] = c;
! 1851: }
1.4 misho 1852:
1853: /*
1.2 misho 1854: ** This is the callback routine that the shell
1855: ** invokes for each row of a query result.
1856: */
1.4 misho 1857: static int shell_callback(
1858: void *pArg,
1859: int nArg, /* Number of result columns */
1860: char **azArg, /* Text of each result column */
1861: char **azCol, /* Column names */
1862: int *aiType /* Column types */
1863: ){
1.2 misho 1864: int i;
1.4 misho 1865: ShellState *p = (ShellState*)pArg;
1.2 misho 1866:
1.4 misho 1867: switch( p->cMode ){
1.2 misho 1868: case MODE_Line: {
1869: int w = 5;
1870: if( azArg==0 ) break;
1871: for(i=0; i<nArg; i++){
1872: int len = strlen30(azCol[i] ? azCol[i] : "");
1873: if( len>w ) w = len;
1874: }
1.4 misho 1875: if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
1.2 misho 1876: for(i=0; i<nArg; i++){
1.4 misho 1877: utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
1878: azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
1.2 misho 1879: }
1880: break;
1881: }
1882: case MODE_Explain:
1883: case MODE_Column: {
1.4 misho 1884: static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
1885: const int *colWidth;
1886: int showHdr;
1887: char *rowSep;
1888: if( p->cMode==MODE_Column ){
1889: colWidth = p->colWidth;
1890: showHdr = p->showHeader;
1891: rowSep = p->rowSeparator;
1892: }else{
1893: colWidth = aExplainWidths;
1894: showHdr = 1;
1895: rowSep = SEP_Row;
1896: }
1.2 misho 1897: if( p->cnt++==0 ){
1898: for(i=0; i<nArg; i++){
1899: int w, n;
1900: if( i<ArraySize(p->colWidth) ){
1.4 misho 1901: w = colWidth[i];
1.2 misho 1902: }else{
1903: w = 0;
1904: }
1.3 misho 1905: if( w==0 ){
1.2 misho 1906: w = strlen30(azCol[i] ? azCol[i] : "");
1907: if( w<10 ) w = 10;
1.4 misho 1908: n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
1.2 misho 1909: if( w<n ) w = n;
1910: }
1911: if( i<ArraySize(p->actualWidth) ){
1912: p->actualWidth[i] = w;
1913: }
1.4 misho 1914: if( showHdr ){
1.4.2.1 ! misho 1915: utf8_width_print(p->out, w, azCol[i]);
! 1916: utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
1.2 misho 1917: }
1918: }
1.4 misho 1919: if( showHdr ){
1.2 misho 1920: for(i=0; i<nArg; i++){
1921: int w;
1922: if( i<ArraySize(p->actualWidth) ){
1923: w = p->actualWidth[i];
1.3 misho 1924: if( w<0 ) w = -w;
1.2 misho 1925: }else{
1926: w = 10;
1927: }
1.4 misho 1928: utf8_printf(p->out,"%-*.*s%s",w,w,
1929: "----------------------------------------------------------"
1.2 misho 1930: "----------------------------------------------------------",
1.4 misho 1931: i==nArg-1 ? rowSep : " ");
1.2 misho 1932: }
1933: }
1934: }
1935: if( azArg==0 ) break;
1936: for(i=0; i<nArg; i++){
1937: int w;
1938: if( i<ArraySize(p->actualWidth) ){
1939: w = p->actualWidth[i];
1940: }else{
1941: w = 10;
1942: }
1.4 misho 1943: if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
1.2 misho 1944: w = strlen30(azArg[i]);
1945: }
1.4 misho 1946: if( i==1 && p->aiIndent && p->pStmt ){
1947: if( p->iIndent<p->nIndent ){
1948: utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
1949: }
1950: p->iIndent++;
1951: }
1.4.2.1 ! misho 1952: utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
! 1953: utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
1.4 misho 1954: }
1955: break;
1956: }
1957: case MODE_Semi: { /* .schema and .fullschema output */
1.4.2.1 ! misho 1958: printSchemaLine(p->out, azArg[0], ";\n");
1.4 misho 1959: break;
1960: }
1961: case MODE_Pretty: { /* .schema and .fullschema with --indent */
1962: char *z;
1963: int j;
1964: int nParen = 0;
1965: char cEnd = 0;
1966: char c;
1967: int nLine = 0;
1968: assert( nArg==1 );
1969: if( azArg[0]==0 ) break;
1970: if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1971: || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1972: ){
1973: utf8_printf(p->out, "%s;\n", azArg[0]);
1974: break;
1975: }
1976: z = sqlite3_mprintf("%s", azArg[0]);
1977: j = 0;
1978: for(i=0; IsSpace(z[i]); i++){}
1979: for(; (c = z[i])!=0; i++){
1980: if( IsSpace(c) ){
1981: if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1982: }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1983: j--;
1984: }
1985: z[j++] = c;
1986: }
1987: while( j>0 && IsSpace(z[j-1]) ){ j--; }
1988: z[j] = 0;
1989: if( strlen30(z)>=79 ){
1990: for(i=j=0; (c = z[i])!=0; i++){
1991: if( c==cEnd ){
1992: cEnd = 0;
1993: }else if( c=='"' || c=='\'' || c=='`' ){
1994: cEnd = c;
1995: }else if( c=='[' ){
1996: cEnd = ']';
1997: }else if( c=='(' ){
1998: nParen++;
1999: }else if( c==')' ){
2000: nParen--;
2001: if( nLine>0 && nParen==0 && j>0 ){
1.4.2.1 ! misho 2002: printSchemaLineN(p->out, z, j, "\n");
1.4 misho 2003: j = 0;
2004: }
2005: }
2006: z[j++] = c;
2007: if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
2008: if( c=='\n' ) j--;
1.4.2.1 ! misho 2009: printSchemaLineN(p->out, z, j, "\n ");
1.4 misho 2010: j = 0;
2011: nLine++;
2012: while( IsSpace(z[i+1]) ){ i++; }
2013: }
1.3 misho 2014: }
1.4 misho 2015: z[j] = 0;
1.2 misho 2016: }
1.4.2.1 ! misho 2017: printSchemaLine(p->out, z, ";\n");
1.4 misho 2018: sqlite3_free(z);
1.2 misho 2019: break;
2020: }
2021: case MODE_List: {
2022: if( p->cnt++==0 && p->showHeader ){
2023: for(i=0; i<nArg; i++){
1.4 misho 2024: utf8_printf(p->out,"%s%s",azCol[i],
2025: i==nArg-1 ? p->rowSeparator : p->colSeparator);
1.2 misho 2026: }
2027: }
2028: if( azArg==0 ) break;
2029: for(i=0; i<nArg; i++){
2030: char *z = azArg[i];
1.4 misho 2031: if( z==0 ) z = p->nullValue;
2032: utf8_printf(p->out, "%s", z);
1.2 misho 2033: if( i<nArg-1 ){
1.4 misho 2034: utf8_printf(p->out, "%s", p->colSeparator);
1.2 misho 2035: }else{
1.4 misho 2036: utf8_printf(p->out, "%s", p->rowSeparator);
1.2 misho 2037: }
2038: }
2039: break;
2040: }
2041: case MODE_Html: {
2042: if( p->cnt++==0 && p->showHeader ){
1.4 misho 2043: raw_printf(p->out,"<TR>");
1.2 misho 2044: for(i=0; i<nArg; i++){
1.4 misho 2045: raw_printf(p->out,"<TH>");
1.2 misho 2046: output_html_string(p->out, azCol[i]);
1.4 misho 2047: raw_printf(p->out,"</TH>\n");
1.2 misho 2048: }
1.4 misho 2049: raw_printf(p->out,"</TR>\n");
1.2 misho 2050: }
2051: if( azArg==0 ) break;
1.4 misho 2052: raw_printf(p->out,"<TR>");
1.2 misho 2053: for(i=0; i<nArg; i++){
1.4 misho 2054: raw_printf(p->out,"<TD>");
2055: output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
2056: raw_printf(p->out,"</TD>\n");
1.2 misho 2057: }
1.4 misho 2058: raw_printf(p->out,"</TR>\n");
1.2 misho 2059: break;
2060: }
2061: case MODE_Tcl: {
2062: if( p->cnt++==0 && p->showHeader ){
2063: for(i=0; i<nArg; i++){
2064: output_c_string(p->out,azCol[i] ? azCol[i] : "");
1.4 misho 2065: if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
1.2 misho 2066: }
1.4 misho 2067: utf8_printf(p->out, "%s", p->rowSeparator);
1.2 misho 2068: }
2069: if( azArg==0 ) break;
2070: for(i=0; i<nArg; i++){
1.4 misho 2071: output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
2072: if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
1.2 misho 2073: }
1.4 misho 2074: utf8_printf(p->out, "%s", p->rowSeparator);
1.2 misho 2075: break;
2076: }
2077: case MODE_Csv: {
1.4 misho 2078: setBinaryMode(p->out, 1);
1.2 misho 2079: if( p->cnt++==0 && p->showHeader ){
2080: for(i=0; i<nArg; i++){
2081: output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
2082: }
1.4 misho 2083: utf8_printf(p->out, "%s", p->rowSeparator);
1.2 misho 2084: }
1.4 misho 2085: if( nArg>0 ){
2086: for(i=0; i<nArg; i++){
2087: output_csv(p, azArg[i], i<nArg-1);
2088: }
2089: utf8_printf(p->out, "%s", p->rowSeparator);
1.2 misho 2090: }
1.4 misho 2091: setTextMode(p->out, 1);
1.2 misho 2092: break;
2093: }
2094: case MODE_Insert: {
2095: if( azArg==0 ) break;
1.4 misho 2096: utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
2097: if( p->showHeader ){
2098: raw_printf(p->out,"(");
2099: for(i=0; i<nArg; i++){
1.4.2.1 ! misho 2100: if( i>0 ) raw_printf(p->out, ",");
! 2101: if( quoteChar(azCol[i]) ){
! 2102: char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
! 2103: utf8_printf(p->out, "%s", z);
! 2104: sqlite3_free(z);
! 2105: }else{
! 2106: raw_printf(p->out, "%s", azCol[i]);
! 2107: }
1.4 misho 2108: }
2109: raw_printf(p->out,")");
2110: }
1.4.2.1 ! misho 2111: p->cnt++;
1.2 misho 2112: for(i=0; i<nArg; i++){
1.4.2.1 ! misho 2113: raw_printf(p->out, i>0 ? "," : " VALUES(");
1.2 misho 2114: if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
1.4.2.1 ! misho 2115: utf8_printf(p->out,"NULL");
! 2116: }else if( aiType && aiType[i]==SQLITE_TEXT ){
! 2117: output_quoted_escaped_string(p->out, azArg[i]);
! 2118: }else if( aiType && aiType[i]==SQLITE_INTEGER ){
! 2119: utf8_printf(p->out,"%s", azArg[i]);
! 2120: }else if( aiType && aiType[i]==SQLITE_FLOAT ){
! 2121: char z[50];
! 2122: double r = sqlite3_column_double(p->pStmt, i);
! 2123: sqlite3_snprintf(50,z,"%!.20g", r);
! 2124: raw_printf(p->out, "%s", z);
! 2125: }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
! 2126: const void *pBlob = sqlite3_column_blob(p->pStmt, i);
! 2127: int nBlob = sqlite3_column_bytes(p->pStmt, i);
! 2128: output_hex_blob(p->out, pBlob, nBlob);
! 2129: }else if( isNumber(azArg[i], 0) ){
! 2130: utf8_printf(p->out,"%s", azArg[i]);
! 2131: }else{
! 2132: output_quoted_escaped_string(p->out, azArg[i]);
! 2133: }
! 2134: }
! 2135: raw_printf(p->out,");\n");
! 2136: break;
! 2137: }
! 2138: case MODE_Quote: {
! 2139: if( azArg==0 ) break;
! 2140: if( p->cnt==0 && p->showHeader ){
! 2141: for(i=0; i<nArg; i++){
! 2142: if( i>0 ) raw_printf(p->out, ",");
! 2143: output_quoted_string(p->out, azCol[i]);
! 2144: }
! 2145: raw_printf(p->out,"\n");
! 2146: }
! 2147: p->cnt++;
! 2148: for(i=0; i<nArg; i++){
! 2149: if( i>0 ) raw_printf(p->out, ",");
! 2150: if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
! 2151: utf8_printf(p->out,"NULL");
1.2 misho 2152: }else if( aiType && aiType[i]==SQLITE_TEXT ){
2153: output_quoted_string(p->out, azArg[i]);
1.4.2.1 ! misho 2154: }else if( aiType && aiType[i]==SQLITE_INTEGER ){
! 2155: utf8_printf(p->out,"%s", azArg[i]);
! 2156: }else if( aiType && aiType[i]==SQLITE_FLOAT ){
! 2157: char z[50];
! 2158: double r = sqlite3_column_double(p->pStmt, i);
! 2159: sqlite3_snprintf(50,z,"%!.20g", r);
! 2160: raw_printf(p->out, "%s", z);
1.2 misho 2161: }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
2162: const void *pBlob = sqlite3_column_blob(p->pStmt, i);
2163: int nBlob = sqlite3_column_bytes(p->pStmt, i);
2164: output_hex_blob(p->out, pBlob, nBlob);
2165: }else if( isNumber(azArg[i], 0) ){
1.4.2.1 ! misho 2166: utf8_printf(p->out,"%s", azArg[i]);
1.2 misho 2167: }else{
2168: output_quoted_string(p->out, azArg[i]);
2169: }
2170: }
1.4.2.1 ! misho 2171: raw_printf(p->out,"\n");
1.4 misho 2172: break;
2173: }
2174: case MODE_Ascii: {
2175: if( p->cnt++==0 && p->showHeader ){
2176: for(i=0; i<nArg; i++){
2177: if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
2178: utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
2179: }
2180: utf8_printf(p->out, "%s", p->rowSeparator);
2181: }
2182: if( azArg==0 ) break;
2183: for(i=0; i<nArg; i++){
2184: if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
2185: utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
2186: }
2187: utf8_printf(p->out, "%s", p->rowSeparator);
1.2 misho 2188: break;
2189: }
2190: }
2191: return 0;
2192: }
2193:
2194: /*
2195: ** This is the callback routine that the SQLite library
2196: ** invokes for each row of a query result.
2197: */
2198: static int callback(void *pArg, int nArg, char **azArg, char **azCol){
2199: /* since we don't have type info, call the shell_callback with a NULL value */
2200: return shell_callback(pArg, nArg, azArg, azCol, NULL);
2201: }
2202:
2203: /*
1.4.2.1 ! misho 2204: ** This is the callback routine from sqlite3_exec() that appends all
! 2205: ** output onto the end of a ShellText object.
! 2206: */
! 2207: static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
! 2208: ShellText *p = (ShellText*)pArg;
! 2209: int i;
! 2210: UNUSED_PARAMETER(az);
! 2211: if( p->n ) appendText(p, "|", 0);
! 2212: for(i=0; i<nArg; i++){
! 2213: if( i ) appendText(p, ",", 0);
! 2214: if( azArg[i] ) appendText(p, azArg[i], 0);
! 2215: }
! 2216: return 0;
! 2217: }
! 2218:
! 2219: /*
! 2220: ** Generate an appropriate SELFTEST table in the main database.
! 2221: */
! 2222: static void createSelftestTable(ShellState *p){
! 2223: char *zErrMsg = 0;
! 2224: sqlite3_exec(p->db,
! 2225: "SAVEPOINT selftest_init;\n"
! 2226: "CREATE TABLE IF NOT EXISTS selftest(\n"
! 2227: " tno INTEGER PRIMARY KEY,\n" /* Test number */
! 2228: " op TEXT,\n" /* Operator: memo run */
! 2229: " cmd TEXT,\n" /* Command text */
! 2230: " ans TEXT\n" /* Desired answer */
! 2231: ");"
! 2232: "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n"
! 2233: "INSERT INTO [_shell$self](rowid,op,cmd)\n"
! 2234: " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n"
! 2235: " 'memo','Tests generated by --init');\n"
! 2236: "INSERT INTO [_shell$self]\n"
! 2237: " SELECT 'run',\n"
! 2238: " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql "
! 2239: "FROM sqlite_master ORDER BY 2'',224))',\n"
! 2240: " hex(sha3_query('SELECT type,name,tbl_name,sql "
! 2241: "FROM sqlite_master ORDER BY 2',224));\n"
! 2242: "INSERT INTO [_shell$self]\n"
! 2243: " SELECT 'run',"
! 2244: " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||"
! 2245: " printf('%w',name) || '\" NOT INDEXED'',224))',\n"
! 2246: " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n"
! 2247: " FROM (\n"
! 2248: " SELECT name FROM sqlite_master\n"
! 2249: " WHERE type='table'\n"
! 2250: " AND name<>'selftest'\n"
! 2251: " AND coalesce(rootpage,0)>0\n"
! 2252: " )\n"
! 2253: " ORDER BY name;\n"
! 2254: "INSERT INTO [_shell$self]\n"
! 2255: " VALUES('run','PRAGMA integrity_check','ok');\n"
! 2256: "INSERT INTO selftest(tno,op,cmd,ans)"
! 2257: " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
! 2258: "DROP TABLE [_shell$self];"
! 2259: ,0,0,&zErrMsg);
! 2260: if( zErrMsg ){
! 2261: utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
! 2262: sqlite3_free(zErrMsg);
! 2263: }
! 2264: sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
! 2265: }
! 2266:
! 2267:
! 2268: /*
1.4 misho 2269: ** Set the destination table field of the ShellState structure to
1.2 misho 2270: ** the name of the table given. Escape any quote characters in the
2271: ** table name.
2272: */
1.4 misho 2273: static void set_table_name(ShellState *p, const char *zName){
1.2 misho 2274: int i, n;
1.4.2.1 ! misho 2275: int cQuote;
1.2 misho 2276: char *z;
2277:
2278: if( p->zDestTable ){
2279: free(p->zDestTable);
2280: p->zDestTable = 0;
2281: }
2282: if( zName==0 ) return;
1.4.2.1 ! misho 2283: cQuote = quoteChar(zName);
! 2284: n = strlen30(zName);
! 2285: if( cQuote ) n += 2;
1.2 misho 2286: z = p->zDestTable = malloc( n+1 );
2287: if( z==0 ){
1.4 misho 2288: raw_printf(stderr,"Error: out of memory\n");
1.2 misho 2289: exit(1);
2290: }
2291: n = 0;
1.4.2.1 ! misho 2292: if( cQuote ) z[n++] = cQuote;
1.2 misho 2293: for(i=0; zName[i]; i++){
2294: z[n++] = zName[i];
1.4.2.1 ! misho 2295: if( zName[i]==cQuote ) z[n++] = cQuote;
1.2 misho 2296: }
1.4.2.1 ! misho 2297: if( cQuote ) z[n++] = cQuote;
1.2 misho 2298: z[n] = 0;
2299: }
2300:
2301:
2302: /*
1.3 misho 2303: ** Execute a query statement that will generate SQL output. Print
2304: ** the result columns, comma-separated, on a line and then add a
2305: ** semicolon terminator to the end of that line.
1.2 misho 2306: **
1.3 misho 2307: ** If the number of columns is 1 and that column contains text "--"
1.4 misho 2308: ** then write the semicolon on a separate line. That way, if a
1.3 misho 2309: ** "--" comment occurs at the end of the statement, the comment
2310: ** won't consume the semicolon terminator.
1.2 misho 2311: */
2312: static int run_table_dump_query(
1.4 misho 2313: ShellState *p, /* Query context */
1.2 misho 2314: const char *zSelect, /* SELECT statement to extract content */
2315: const char *zFirstRow /* Print before first row, if not NULL */
2316: ){
2317: sqlite3_stmt *pSelect;
2318: int rc;
1.3 misho 2319: int nResult;
2320: int i;
2321: const char *z;
1.4 misho 2322: rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
1.2 misho 2323: if( rc!=SQLITE_OK || !pSelect ){
1.4 misho 2324: utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
2325: sqlite3_errmsg(p->db));
2326: if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
1.2 misho 2327: return rc;
2328: }
2329: rc = sqlite3_step(pSelect);
1.3 misho 2330: nResult = sqlite3_column_count(pSelect);
1.2 misho 2331: while( rc==SQLITE_ROW ){
2332: if( zFirstRow ){
1.4 misho 2333: utf8_printf(p->out, "%s", zFirstRow);
1.2 misho 2334: zFirstRow = 0;
2335: }
1.3 misho 2336: z = (const char*)sqlite3_column_text(pSelect, 0);
1.4 misho 2337: utf8_printf(p->out, "%s", z);
2338: for(i=1; i<nResult; i++){
2339: utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1.3 misho 2340: }
2341: if( z==0 ) z = "";
2342: while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
2343: if( z[0] ){
1.4 misho 2344: raw_printf(p->out, "\n;\n");
1.3 misho 2345: }else{
1.4 misho 2346: raw_printf(p->out, ";\n");
2347: }
1.2 misho 2348: rc = sqlite3_step(pSelect);
2349: }
2350: rc = sqlite3_finalize(pSelect);
2351: if( rc!=SQLITE_OK ){
1.4 misho 2352: utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
2353: sqlite3_errmsg(p->db));
2354: if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
1.2 misho 2355: }
2356: return rc;
2357: }
2358:
2359: /*
2360: ** Allocate space and save off current error string.
2361: */
2362: static char *save_err_msg(
2363: sqlite3 *db /* Database to query */
2364: ){
2365: int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1.4 misho 2366: char *zErrMsg = sqlite3_malloc64(nErrMsg);
1.2 misho 2367: if( zErrMsg ){
2368: memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
2369: }
2370: return zErrMsg;
2371: }
2372:
1.4 misho 2373: #ifdef __linux__
2374: /*
2375: ** Attempt to display I/O stats on Linux using /proc/PID/io
2376: */
2377: static void displayLinuxIoStats(FILE *out){
2378: FILE *in;
2379: char z[200];
2380: sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
2381: in = fopen(z, "rb");
2382: if( in==0 ) return;
2383: while( fgets(z, sizeof(z), in)!=0 ){
2384: static const struct {
2385: const char *zPattern;
2386: const char *zDesc;
2387: } aTrans[] = {
2388: { "rchar: ", "Bytes received by read():" },
2389: { "wchar: ", "Bytes sent to write():" },
2390: { "syscr: ", "Read() system calls:" },
2391: { "syscw: ", "Write() system calls:" },
2392: { "read_bytes: ", "Bytes read from storage:" },
2393: { "write_bytes: ", "Bytes written to storage:" },
2394: { "cancelled_write_bytes: ", "Cancelled write bytes:" },
2395: };
2396: int i;
2397: for(i=0; i<ArraySize(aTrans); i++){
2398: int n = (int)strlen(aTrans[i].zPattern);
2399: if( strncmp(aTrans[i].zPattern, z, n)==0 ){
1.4.2.1 ! misho 2400: utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
1.4 misho 2401: break;
2402: }
2403: }
2404: }
2405: fclose(in);
2406: }
2407: #endif
2408:
1.4.2.1 ! misho 2409: /*
! 2410: ** Display a single line of status using 64-bit values.
! 2411: */
! 2412: static void displayStatLine(
! 2413: ShellState *p, /* The shell context */
! 2414: char *zLabel, /* Label for this one line */
! 2415: char *zFormat, /* Format for the result */
! 2416: int iStatusCtrl, /* Which status to display */
! 2417: int bReset /* True to reset the stats */
! 2418: ){
! 2419: sqlite3_int64 iCur = -1;
! 2420: sqlite3_int64 iHiwtr = -1;
! 2421: int i, nPercent;
! 2422: char zLine[200];
! 2423: sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset);
! 2424: for(i=0, nPercent=0; zFormat[i]; i++){
! 2425: if( zFormat[i]=='%' ) nPercent++;
! 2426: }
! 2427: if( nPercent>1 ){
! 2428: sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
! 2429: }else{
! 2430: sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
! 2431: }
! 2432: raw_printf(p->out, "%-36s %s\n", zLabel, zLine);
! 2433: }
1.4 misho 2434:
1.2 misho 2435: /*
2436: ** Display memory stats.
2437: */
2438: static int display_stats(
2439: sqlite3 *db, /* Database to query */
1.4 misho 2440: ShellState *pArg, /* Pointer to ShellState */
1.2 misho 2441: int bReset /* True to reset the stats */
2442: ){
2443: int iCur;
2444: int iHiwtr;
2445:
2446: if( pArg && pArg->out ){
1.4.2.1 ! misho 2447: displayStatLine(pArg, "Memory Used:",
! 2448: "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
! 2449: displayStatLine(pArg, "Number of Outstanding Allocations:",
! 2450: "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
1.4 misho 2451: if( pArg->shellFlgs & SHFLG_Pagecache ){
1.4.2.1 ! misho 2452: displayStatLine(pArg, "Number of Pcache Pages Used:",
! 2453: "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
1.4 misho 2454: }
1.4.2.1 ! misho 2455: displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
! 2456: "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
1.4 misho 2457: if( pArg->shellFlgs & SHFLG_Scratch ){
1.4.2.1 ! misho 2458: displayStatLine(pArg, "Number of Scratch Allocations Used:",
! 2459: "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset);
1.4 misho 2460: }
1.4.2.1 ! misho 2461: displayStatLine(pArg, "Number of Scratch Overflow Bytes:",
! 2462: "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset);
! 2463: displayStatLine(pArg, "Largest Allocation:",
! 2464: "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
! 2465: displayStatLine(pArg, "Largest Pcache Allocation:",
! 2466: "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
! 2467: displayStatLine(pArg, "Largest Scratch Allocation:",
! 2468: "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset);
1.2 misho 2469: #ifdef YYTRACKMAXSTACKDEPTH
1.4.2.1 ! misho 2470: displayStatLine(pArg, "Deepest Parser Stack:",
! 2471: "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
1.2 misho 2472: #endif
2473: }
2474:
2475: if( pArg && pArg->out && db ){
1.4 misho 2476: if( pArg->shellFlgs & SHFLG_Lookaside ){
2477: iHiwtr = iCur = -1;
2478: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
2479: &iCur, &iHiwtr, bReset);
2480: raw_printf(pArg->out,
2481: "Lookaside Slots Used: %d (max %d)\n",
2482: iCur, iHiwtr);
2483: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
2484: &iCur, &iHiwtr, bReset);
2485: raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
2486: iHiwtr);
2487: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
2488: &iCur, &iHiwtr, bReset);
2489: raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
2490: iHiwtr);
2491: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
2492: &iCur, &iHiwtr, bReset);
2493: raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
2494: iHiwtr);
2495: }
1.2 misho 2496: iHiwtr = iCur = -1;
1.4 misho 2497: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
2498: raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
2499: iCur);
1.2 misho 2500: iHiwtr = iCur = -1;
2501: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1.4 misho 2502: raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
1.2 misho 2503: iHiwtr = iCur = -1;
2504: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1.4 misho 2505: raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
1.2 misho 2506: iHiwtr = iCur = -1;
1.3 misho 2507: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1.4 misho 2508: raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
1.3 misho 2509: iHiwtr = iCur = -1;
1.2 misho 2510: sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1.4 misho 2511: raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
2512: iCur);
1.2 misho 2513: iHiwtr = iCur = -1;
2514: sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
1.4 misho 2515: raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
2516: iCur);
1.2 misho 2517: }
2518:
2519: if( pArg && pArg->out && db && pArg->pStmt ){
1.4 misho 2520: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
2521: bReset);
2522: raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
1.2 misho 2523: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1.4 misho 2524: raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
2525: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
2526: raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
2527: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
2528: raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
1.2 misho 2529: }
2530:
1.4 misho 2531: #ifdef __linux__
2532: displayLinuxIoStats(pArg->out);
2533: #endif
2534:
2535: /* Do not remove this machine readable comment: extra-stats-output-here */
2536:
1.2 misho 2537: return 0;
2538: }
2539:
2540: /*
1.4 misho 2541: ** Display scan stats.
1.2 misho 2542: */
1.4 misho 2543: static void display_scanstats(
2544: sqlite3 *db, /* Database to query */
2545: ShellState *pArg /* Pointer to ShellState */
1.2 misho 2546: ){
1.4 misho 2547: #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
2548: UNUSED_PARAMETER(db);
2549: UNUSED_PARAMETER(pArg);
2550: #else
2551: int i, k, n, mx;
2552: raw_printf(pArg->out, "-------- scanstats --------\n");
2553: mx = 0;
2554: for(k=0; k<=mx; k++){
2555: double rEstLoop = 1.0;
2556: for(i=n=0; 1; i++){
2557: sqlite3_stmt *p = pArg->pStmt;
2558: sqlite3_int64 nLoop, nVisit;
2559: double rEst;
2560: int iSid;
2561: const char *zExplain;
2562: if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
2563: break;
1.2 misho 2564: }
1.4 misho 2565: sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
2566: if( iSid>mx ) mx = iSid;
2567: if( iSid!=k ) continue;
2568: if( n==0 ){
2569: rEstLoop = (double)nLoop;
2570: if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
1.2 misho 2571: }
1.4 misho 2572: n++;
2573: sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
2574: sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
2575: sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
2576: utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
2577: rEstLoop *= rEst;
2578: raw_printf(pArg->out,
2579: " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
2580: nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
2581: );
2582: }
2583: }
2584: raw_printf(pArg->out, "---------------------------\n");
2585: #endif
2586: }
1.2 misho 2587:
1.4 misho 2588: /*
2589: ** Parameter azArray points to a zero-terminated array of strings. zStr
2590: ** points to a single nul-terminated string. Return non-zero if zStr
2591: ** is equal, according to strcmp(), to any of the strings in the array.
2592: ** Otherwise, return zero.
2593: */
2594: static int str_in_array(const char *zStr, const char **azArray){
2595: int i;
2596: for(i=0; azArray[i]; i++){
2597: if( 0==strcmp(zStr, azArray[i]) ) return 1;
2598: }
2599: return 0;
2600: }
1.2 misho 2601:
1.4 misho 2602: /*
2603: ** If compiled statement pSql appears to be an EXPLAIN statement, allocate
2604: ** and populate the ShellState.aiIndent[] array with the number of
2605: ** spaces each opcode should be indented before it is output.
2606: **
2607: ** The indenting rules are:
2608: **
2609: ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
2610: ** all opcodes that occur between the p2 jump destination and the opcode
2611: ** itself by 2 spaces.
2612: **
2613: ** * For each "Goto", if the jump destination is earlier in the program
2614: ** and ends on one of:
2615: ** Yield SeekGt SeekLt RowSetRead Rewind
2616: ** or if the P1 parameter is one instead of zero,
2617: ** then indent all opcodes between the earlier instruction
2618: ** and "Goto" by 2 spaces.
2619: */
2620: static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
2621: const char *zSql; /* The text of the SQL statement */
2622: const char *z; /* Used to check if this is an EXPLAIN */
2623: int *abYield = 0; /* True if op is an OP_Yield */
2624: int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
2625: int iOp; /* Index of operation in p->aiIndent[] */
2626:
2627: const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
2628: "NextIfOpen", "PrevIfOpen", 0 };
2629: const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
2630: "Rewind", 0 };
2631: const char *azGoto[] = { "Goto", 0 };
2632:
2633: /* Try to figure out if this is really an EXPLAIN statement. If this
2634: ** cannot be verified, return early. */
2635: if( sqlite3_column_count(pSql)!=8 ){
2636: p->cMode = p->mode;
2637: return;
2638: }
2639: zSql = sqlite3_sql(pSql);
2640: if( zSql==0 ) return;
2641: for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
2642: if( sqlite3_strnicmp(z, "explain", 7) ){
2643: p->cMode = p->mode;
2644: return;
2645: }
1.2 misho 2646:
1.4 misho 2647: for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
2648: int i;
2649: int iAddr = sqlite3_column_int(pSql, 0);
2650: const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
1.2 misho 2651:
1.4 misho 2652: /* Set p2 to the P2 field of the current opcode. Then, assuming that
2653: ** p2 is an instruction address, set variable p2op to the index of that
2654: ** instruction in the aiIndent[] array. p2 and p2op may be different if
2655: ** the current instruction is part of a sub-program generated by an
2656: ** SQL trigger or foreign key. */
2657: int p2 = sqlite3_column_int(pSql, 3);
2658: int p2op = (p2 + (iOp-iAddr));
2659:
2660: /* Grow the p->aiIndent array as required */
2661: if( iOp>=nAlloc ){
2662: if( iOp==0 ){
2663: /* Do further verfication that this is explain output. Abort if
2664: ** it is not */
2665: static const char *explainCols[] = {
2666: "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
2667: int jj;
2668: for(jj=0; jj<ArraySize(explainCols); jj++){
2669: if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
2670: p->cMode = p->mode;
2671: sqlite3_reset(pSql);
2672: return;
1.2 misho 2673: }
2674: }
2675: }
1.4 misho 2676: nAlloc += 100;
2677: p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
2678: abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
2679: }
2680: abYield[iOp] = str_in_array(zOp, azYield);
2681: p->aiIndent[iOp] = 0;
2682: p->nIndent = iOp+1;
2683:
2684: if( str_in_array(zOp, azNext) ){
2685: for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
2686: }
2687: if( str_in_array(zOp, azGoto) && p2op<p->nIndent
2688: && (abYield[p2op] || sqlite3_column_int(pSql, 2))
2689: ){
2690: for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
2691: }
2692: }
2693:
2694: p->iIndent = 0;
2695: sqlite3_free(abYield);
2696: sqlite3_reset(pSql);
2697: }
2698:
2699: /*
2700: ** Free the array allocated by explain_data_prepare().
2701: */
2702: static void explain_data_delete(ShellState *p){
2703: sqlite3_free(p->aiIndent);
2704: p->aiIndent = 0;
2705: p->nIndent = 0;
2706: p->iIndent = 0;
2707: }
2708:
2709: /*
2710: ** Disable and restore .wheretrace and .selecttrace settings.
2711: */
2712: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
2713: extern int sqlite3SelectTrace;
2714: static int savedSelectTrace;
2715: #endif
2716: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2717: extern int sqlite3WhereTrace;
2718: static int savedWhereTrace;
2719: #endif
2720: static void disable_debug_trace_modes(void){
2721: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
2722: savedSelectTrace = sqlite3SelectTrace;
2723: sqlite3SelectTrace = 0;
2724: #endif
2725: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2726: savedWhereTrace = sqlite3WhereTrace;
2727: sqlite3WhereTrace = 0;
2728: #endif
2729: }
2730: static void restore_debug_trace_modes(void){
2731: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
2732: sqlite3SelectTrace = savedSelectTrace;
2733: #endif
2734: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2735: sqlite3WhereTrace = savedWhereTrace;
2736: #endif
2737: }
2738:
2739: /*
2740: ** Run a prepared statement
2741: */
2742: static void exec_prepared_stmt(
2743: ShellState *pArg, /* Pointer to ShellState */
2744: sqlite3_stmt *pStmt, /* Statment to run */
2745: int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
2746: ){
2747: int rc;
2748:
2749: /* perform the first step. this will tell us if we
2750: ** have a result set or not and how wide it is.
2751: */
2752: rc = sqlite3_step(pStmt);
2753: /* if we have a result set... */
2754: if( SQLITE_ROW == rc ){
2755: /* if we have a callback... */
2756: if( xCallback ){
2757: /* allocate space for col name ptr, value ptr, and type */
2758: int nCol = sqlite3_column_count(pStmt);
2759: void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
2760: if( !pData ){
2761: rc = SQLITE_NOMEM;
2762: }else{
2763: char **azCols = (char **)pData; /* Names of result columns */
2764: char **azVals = &azCols[nCol]; /* Results */
2765: int *aiTypes = (int *)&azVals[nCol]; /* Result types */
2766: int i, x;
2767: assert(sizeof(int) <= sizeof(char *));
2768: /* save off ptrs to column names */
2769: for(i=0; i<nCol; i++){
2770: azCols[i] = (char *)sqlite3_column_name(pStmt, i);
2771: }
2772: do{
2773: /* extract the data and data types */
2774: for(i=0; i<nCol; i++){
2775: aiTypes[i] = x = sqlite3_column_type(pStmt, i);
2776: if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
2777: azVals[i] = "";
2778: }else{
2779: azVals[i] = (char*)sqlite3_column_text(pStmt, i);
2780: }
2781: if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
2782: rc = SQLITE_NOMEM;
2783: break; /* from for */
2784: }
2785: } /* end for */
2786:
2787: /* if data and types extracted successfully... */
2788: if( SQLITE_ROW == rc ){
2789: /* call the supplied callback with the result row data */
2790: if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
2791: rc = SQLITE_ABORT;
2792: }else{
2793: rc = sqlite3_step(pStmt);
2794: }
2795: }
2796: } while( SQLITE_ROW == rc );
2797: sqlite3_free(pData);
2798: }
2799: }else{
2800: do{
2801: rc = sqlite3_step(pStmt);
2802: } while( rc == SQLITE_ROW );
2803: }
2804: }
2805: }
2806:
2807: /*
2808: ** Execute a statement or set of statements. Print
2809: ** any result rows/columns depending on the current mode
2810: ** set via the supplied callback.
2811: **
2812: ** This is very similar to SQLite's built-in sqlite3_exec()
2813: ** function except it takes a slightly different callback
2814: ** and callback data argument.
2815: */
2816: static int shell_exec(
2817: sqlite3 *db, /* An open database */
2818: const char *zSql, /* SQL to be evaluated */
2819: int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
2820: /* (not the same as sqlite3_exec) */
2821: ShellState *pArg, /* Pointer to ShellState */
2822: char **pzErrMsg /* Error msg written here */
2823: ){
2824: sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
2825: int rc = SQLITE_OK; /* Return Code */
2826: int rc2;
2827: const char *zLeftover; /* Tail of unprocessed SQL */
2828:
2829: if( pzErrMsg ){
2830: *pzErrMsg = NULL;
2831: }
2832:
2833: while( zSql[0] && (SQLITE_OK == rc) ){
2834: static const char *zStmtSql;
2835: rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
2836: if( SQLITE_OK != rc ){
2837: if( pzErrMsg ){
2838: *pzErrMsg = save_err_msg(db);
2839: }
2840: }else{
2841: if( !pStmt ){
2842: /* this happens for a comment or white-space */
2843: zSql = zLeftover;
2844: while( IsSpace(zSql[0]) ) zSql++;
2845: continue;
2846: }
2847: zStmtSql = sqlite3_sql(pStmt);
1.4.2.1 ! misho 2848: if( zStmtSql==0 ) zStmtSql = "";
1.4 misho 2849: while( IsSpace(zStmtSql[0]) ) zStmtSql++;
2850:
2851: /* save off the prepared statment handle and reset row count */
2852: if( pArg ){
2853: pArg->pStmt = pStmt;
2854: pArg->cnt = 0;
2855: }
2856:
2857: /* echo the sql statement if echo on */
1.4.2.1 ! misho 2858: if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
1.4 misho 2859: utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
2860: }
2861:
2862: /* Show the EXPLAIN QUERY PLAN if .eqp is on */
2863: if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
2864: sqlite3_stmt *pExplain;
2865: char *zEQP;
2866: disable_debug_trace_modes();
2867: zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
2868: rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
2869: if( rc==SQLITE_OK ){
2870: while( sqlite3_step(pExplain)==SQLITE_ROW ){
2871: raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
2872: raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
2873: raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
2874: utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
2875: }
2876: }
2877: sqlite3_finalize(pExplain);
2878: sqlite3_free(zEQP);
2879: if( pArg->autoEQP>=2 ){
2880: /* Also do an EXPLAIN for ".eqp full" mode */
2881: zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
2882: rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
2883: if( rc==SQLITE_OK ){
2884: pArg->cMode = MODE_Explain;
2885: explain_data_prepare(pArg, pExplain);
2886: exec_prepared_stmt(pArg, pExplain, xCallback);
2887: explain_data_delete(pArg);
2888: }
2889: sqlite3_finalize(pExplain);
2890: sqlite3_free(zEQP);
2891: }
2892: restore_debug_trace_modes();
2893: }
2894:
2895: if( pArg ){
2896: pArg->cMode = pArg->mode;
2897: if( pArg->autoExplain
2898: && sqlite3_column_count(pStmt)==8
2899: && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
2900: ){
2901: pArg->cMode = MODE_Explain;
2902: }
2903:
2904: /* If the shell is currently in ".explain" mode, gather the extra
2905: ** data required to add indents to the output.*/
2906: if( pArg->cMode==MODE_Explain ){
2907: explain_data_prepare(pArg, pStmt);
2908: }
2909: }
2910:
2911: exec_prepared_stmt(pArg, pStmt, xCallback);
2912: explain_data_delete(pArg);
1.2 misho 2913:
2914: /* print usage stats if stats on */
2915: if( pArg && pArg->statsOn ){
2916: display_stats(db, pArg, 0);
2917: }
2918:
1.4 misho 2919: /* print loop-counters if required */
2920: if( pArg && pArg->scanstatsOn ){
2921: display_scanstats(db, pArg);
2922: }
2923:
2924: /* Finalize the statement just executed. If this fails, save a
1.2 misho 2925: ** copy of the error message. Otherwise, set zSql to point to the
2926: ** next statement to execute. */
2927: rc2 = sqlite3_finalize(pStmt);
2928: if( rc!=SQLITE_NOMEM ) rc = rc2;
2929: if( rc==SQLITE_OK ){
2930: zSql = zLeftover;
2931: while( IsSpace(zSql[0]) ) zSql++;
2932: }else if( pzErrMsg ){
2933: *pzErrMsg = save_err_msg(db);
2934: }
2935:
2936: /* clear saved stmt handle */
2937: if( pArg ){
2938: pArg->pStmt = NULL;
2939: }
2940: }
2941: } /* end while */
2942:
2943: return rc;
2944: }
2945:
1.4.2.1 ! misho 2946: /*
! 2947: ** Release memory previously allocated by tableColumnList().
! 2948: */
! 2949: static void freeColumnList(char **azCol){
! 2950: int i;
! 2951: for(i=1; azCol[i]; i++){
! 2952: sqlite3_free(azCol[i]);
! 2953: }
! 2954: /* azCol[0] is a static string */
! 2955: sqlite3_free(azCol);
! 2956: }
! 2957:
! 2958: /*
! 2959: ** Return a list of pointers to strings which are the names of all
! 2960: ** columns in table zTab. The memory to hold the names is dynamically
! 2961: ** allocated and must be released by the caller using a subsequent call
! 2962: ** to freeColumnList().
! 2963: **
! 2964: ** The azCol[0] entry is usually NULL. However, if zTab contains a rowid
! 2965: ** value that needs to be preserved, then azCol[0] is filled in with the
! 2966: ** name of the rowid column.
! 2967: **
! 2968: ** The first regular column in the table is azCol[1]. The list is terminated
! 2969: ** by an entry with azCol[i]==0.
! 2970: */
! 2971: static char **tableColumnList(ShellState *p, const char *zTab){
! 2972: char **azCol = 0;
! 2973: sqlite3_stmt *pStmt;
! 2974: char *zSql;
! 2975: int nCol = 0;
! 2976: int nAlloc = 0;
! 2977: int nPK = 0; /* Number of PRIMARY KEY columns seen */
! 2978: int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */
! 2979: int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid);
! 2980: int rc;
! 2981:
! 2982: zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab);
! 2983: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
! 2984: sqlite3_free(zSql);
! 2985: if( rc ) return 0;
! 2986: while( sqlite3_step(pStmt)==SQLITE_ROW ){
! 2987: if( nCol>=nAlloc-2 ){
! 2988: nAlloc = nAlloc*2 + nCol + 10;
! 2989: azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
! 2990: if( azCol==0 ){
! 2991: raw_printf(stderr, "Error: out of memory\n");
! 2992: exit(1);
! 2993: }
! 2994: }
! 2995: azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
! 2996: if( sqlite3_column_int(pStmt, 5) ){
! 2997: nPK++;
! 2998: if( nPK==1
! 2999: && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
! 3000: "INTEGER")==0
! 3001: ){
! 3002: isIPK = 1;
! 3003: }else{
! 3004: isIPK = 0;
! 3005: }
! 3006: }
! 3007: }
! 3008: sqlite3_finalize(pStmt);
! 3009: azCol[0] = 0;
! 3010: azCol[nCol+1] = 0;
! 3011:
! 3012: /* The decision of whether or not a rowid really needs to be preserved
! 3013: ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table
! 3014: ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve
! 3015: ** rowids on tables where the rowid is inaccessible because there are other
! 3016: ** columns in the table named "rowid", "_rowid_", and "oid".
! 3017: */
! 3018: if( preserveRowid && isIPK ){
! 3019: /* If a single PRIMARY KEY column with type INTEGER was seen, then it
! 3020: ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID
! 3021: ** table or a INTEGER PRIMARY KEY DESC column, neither of which are
! 3022: ** ROWID aliases. To distinguish these cases, check to see if
! 3023: ** there is a "pk" entry in "PRAGMA index_list". There will be
! 3024: ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID.
! 3025: */
! 3026: zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)"
! 3027: " WHERE origin='pk'", zTab);
! 3028: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
! 3029: sqlite3_free(zSql);
! 3030: if( rc ){
! 3031: freeColumnList(azCol);
! 3032: return 0;
! 3033: }
! 3034: rc = sqlite3_step(pStmt);
! 3035: sqlite3_finalize(pStmt);
! 3036: preserveRowid = rc==SQLITE_ROW;
! 3037: }
! 3038: if( preserveRowid ){
! 3039: /* Only preserve the rowid if we can find a name to use for the
! 3040: ** rowid */
! 3041: static char *azRowid[] = { "rowid", "_rowid_", "oid" };
! 3042: int i, j;
! 3043: for(j=0; j<3; j++){
! 3044: for(i=1; i<=nCol; i++){
! 3045: if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break;
! 3046: }
! 3047: if( i>nCol ){
! 3048: /* At this point, we know that azRowid[j] is not the name of any
! 3049: ** ordinary column in the table. Verify that azRowid[j] is a valid
! 3050: ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
! 3051: ** tables will fail this last check */
! 3052: rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
! 3053: if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
! 3054: break;
! 3055: }
! 3056: }
! 3057: }
! 3058: return azCol;
! 3059: }
! 3060:
! 3061: /*
! 3062: ** Toggle the reverse_unordered_selects setting.
! 3063: */
! 3064: static void toggleSelectOrder(sqlite3 *db){
! 3065: sqlite3_stmt *pStmt = 0;
! 3066: int iSetting = 0;
! 3067: char zStmt[100];
! 3068: sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0);
! 3069: if( sqlite3_step(pStmt)==SQLITE_ROW ){
! 3070: iSetting = sqlite3_column_int(pStmt, 0);
! 3071: }
! 3072: sqlite3_finalize(pStmt);
! 3073: sqlite3_snprintf(sizeof(zStmt), zStmt,
! 3074: "PRAGMA reverse_unordered_selects(%d)", !iSetting);
! 3075: sqlite3_exec(db, zStmt, 0, 0, 0);
! 3076: }
1.2 misho 3077:
3078: /*
3079: ** This is a different callback routine used for dumping the database.
3080: ** Each row received by this callback consists of a table name,
3081: ** the table type ("index" or "table") and SQL to create the table.
3082: ** This routine should print text sufficient to recreate the table.
3083: */
1.4.2.1 ! misho 3084: static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
1.2 misho 3085: int rc;
3086: const char *zTable;
3087: const char *zType;
3088: const char *zSql;
1.4 misho 3089: ShellState *p = (ShellState *)pArg;
1.2 misho 3090:
1.4.2.1 ! misho 3091: UNUSED_PARAMETER(azNotUsed);
1.2 misho 3092: if( nArg!=3 ) return 1;
3093: zTable = azArg[0];
3094: zType = azArg[1];
3095: zSql = azArg[2];
1.4 misho 3096:
1.2 misho 3097: if( strcmp(zTable, "sqlite_sequence")==0 ){
1.4.2.1 ! misho 3098: raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
1.4 misho 3099: }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
3100: raw_printf(p->out, "ANALYZE sqlite_master;\n");
1.2 misho 3101: }else if( strncmp(zTable, "sqlite_", 7)==0 ){
3102: return 0;
3103: }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
3104: char *zIns;
3105: if( !p->writableSchema ){
1.4 misho 3106: raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
1.2 misho 3107: p->writableSchema = 1;
3108: }
3109: zIns = sqlite3_mprintf(
3110: "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
3111: "VALUES('table','%q','%q',0,'%q');",
3112: zTable, zTable, zSql);
1.4 misho 3113: utf8_printf(p->out, "%s\n", zIns);
1.2 misho 3114: sqlite3_free(zIns);
3115: return 0;
3116: }else{
1.4.2.1 ! misho 3117: printSchemaLine(p->out, zSql, ";\n");
1.2 misho 3118: }
3119:
3120: if( strcmp(zType, "table")==0 ){
1.4.2.1 ! misho 3121: ShellText sSelect;
! 3122: ShellText sTable;
! 3123: char **azCol;
! 3124: int i;
! 3125: char *savedDestTable;
! 3126: int savedMode;
! 3127:
! 3128: azCol = tableColumnList(p, zTable);
! 3129: if( azCol==0 ){
! 3130: p->nErr++;
! 3131: return 0;
1.2 misho 3132: }
3133:
1.3 misho 3134: /* Always quote the table name, even if it appears to be pure ascii,
3135: ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1.4.2.1 ! misho 3136: initText(&sTable);
! 3137: appendText(&sTable, zTable, quoteChar(zTable));
! 3138: /* If preserving the rowid, add a column list after the table name.
! 3139: ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
! 3140: ** instead of the usual "INSERT INTO tab VALUES(...)".
! 3141: */
! 3142: if( azCol[0] ){
! 3143: appendText(&sTable, "(", 0);
! 3144: appendText(&sTable, azCol[0], 0);
! 3145: for(i=1; azCol[i]; i++){
! 3146: appendText(&sTable, ",", 0);
! 3147: appendText(&sTable, azCol[i], quoteChar(azCol[i]));
! 3148: }
! 3149: appendText(&sTable, ")", 0);
! 3150: }
! 3151:
! 3152: /* Build an appropriate SELECT statement */
! 3153: initText(&sSelect);
! 3154: appendText(&sSelect, "SELECT ", 0);
! 3155: if( azCol[0] ){
! 3156: appendText(&sSelect, azCol[0], 0);
! 3157: appendText(&sSelect, ",", 0);
! 3158: }
! 3159: for(i=1; azCol[i]; i++){
! 3160: appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
! 3161: if( azCol[i+1] ){
! 3162: appendText(&sSelect, ",", 0);
! 3163: }
! 3164: }
! 3165: freeColumnList(azCol);
! 3166: appendText(&sSelect, " FROM ", 0);
! 3167: appendText(&sSelect, zTable, quoteChar(zTable));
! 3168:
! 3169: savedDestTable = p->zDestTable;
! 3170: savedMode = p->mode;
! 3171: p->zDestTable = sTable.z;
! 3172: p->mode = p->cMode = MODE_Insert;
! 3173: rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0);
! 3174: if( (rc&0xff)==SQLITE_CORRUPT ){
! 3175: raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
! 3176: toggleSelectOrder(p->db);
! 3177: shell_exec(p->db, sSelect.z, shell_callback, p, 0);
! 3178: toggleSelectOrder(p->db);
! 3179: }
! 3180: p->zDestTable = savedDestTable;
! 3181: p->mode = savedMode;
! 3182: freeText(&sTable);
! 3183: freeText(&sSelect);
! 3184: if( rc ) p->nErr++;
1.2 misho 3185: }
3186: return 0;
3187: }
3188:
3189: /*
3190: ** Run zQuery. Use dump_callback() as the callback routine so that
3191: ** the contents of the query are output as SQL statements.
3192: **
3193: ** If we get a SQLITE_CORRUPT error, rerun the query after appending
3194: ** "ORDER BY rowid DESC" to the end.
3195: */
3196: static int run_schema_dump_query(
1.4 misho 3197: ShellState *p,
1.2 misho 3198: const char *zQuery
3199: ){
3200: int rc;
3201: char *zErr = 0;
3202: rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
3203: if( rc==SQLITE_CORRUPT ){
3204: char *zQ2;
3205: int len = strlen30(zQuery);
1.4 misho 3206: raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
1.2 misho 3207: if( zErr ){
1.4 misho 3208: utf8_printf(p->out, "/****** %s ******/\n", zErr);
1.2 misho 3209: sqlite3_free(zErr);
3210: zErr = 0;
3211: }
3212: zQ2 = malloc( len+100 );
3213: if( zQ2==0 ) return rc;
1.3 misho 3214: sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
1.2 misho 3215: rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
3216: if( rc ){
1.4 misho 3217: utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
1.2 misho 3218: }else{
3219: rc = SQLITE_CORRUPT;
3220: }
3221: sqlite3_free(zErr);
3222: free(zQ2);
3223: }
3224: return rc;
3225: }
3226:
3227: /*
3228: ** Text of a help message
3229: */
3230: static char zHelp[] =
1.4.2.1 ! misho 3231: #ifndef SQLITE_OMIT_AUTHORIZATION
1.4 misho 3232: ".auth ON|OFF Show authorizer callbacks\n"
1.4.2.1 ! misho 3233: #endif
1.2 misho 3234: ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
1.4 misho 3235: ".bail on|off Stop after hitting an error. Default OFF\n"
3236: ".binary on|off Turn binary output on or off. Default OFF\n"
3237: ".changes on|off Show number of rows changed by SQL\n"
1.4.2.1 ! misho 3238: ".check GLOB Fail if output since .testcase does not match\n"
1.4 misho 3239: ".clone NEWDB Clone data into NEWDB from the existing database\n"
1.2 misho 3240: ".databases List names and files of attached databases\n"
1.4 misho 3241: ".dbinfo ?DB? Show status information about the database\n"
1.2 misho 3242: ".dump ?TABLE? ... Dump the database in an SQL text format\n"
3243: " If TABLE specified, only dump tables matching\n"
3244: " LIKE pattern TABLE.\n"
1.4 misho 3245: ".echo on|off Turn command echo on or off\n"
3246: ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
1.2 misho 3247: ".exit Exit this program\n"
1.4 misho 3248: ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
3249: ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
3250: ".headers on|off Turn display of headers on or off\n"
1.2 misho 3251: ".help Show this message\n"
3252: ".import FILE TABLE Import data from FILE into TABLE\n"
1.4.2.1 ! misho 3253: #ifndef SQLITE_OMIT_TEST_CONTROL
! 3254: ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
! 3255: #endif
1.4 misho 3256: ".indexes ?TABLE? Show names of all indexes\n"
3257: " If TABLE specified, only show indexes for tables\n"
1.2 misho 3258: " matching LIKE pattern TABLE.\n"
3259: #ifdef SQLITE_ENABLE_IOTRACE
3260: ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
3261: #endif
1.4 misho 3262: ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
1.4.2.1 ! misho 3263: ".lint OPTIONS Report potential schema issues. Options:\n"
! 3264: " fkey-indexes Find missing foreign key indexes\n"
1.2 misho 3265: #ifndef SQLITE_OMIT_LOAD_EXTENSION
3266: ".load FILE ?ENTRY? Load an extension library\n"
3267: #endif
3268: ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
3269: ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
1.4 misho 3270: " ascii Columns/rows delimited by 0x1F and 0x1E\n"
1.2 misho 3271: " csv Comma-separated values\n"
3272: " column Left-aligned columns. (See .width)\n"
3273: " html HTML <table> code\n"
3274: " insert SQL insert statements for TABLE\n"
3275: " line One value per line\n"
1.4.2.1 ! misho 3276: " list Values delimited by \"|\"\n"
! 3277: " quote Escape answers as for SQL\n"
1.2 misho 3278: " tabs Tab-separated values\n"
3279: " tcl TCL list elements\n"
1.3 misho 3280: ".nullvalue STRING Use STRING in place of NULL values\n"
1.4 misho 3281: ".once FILENAME Output for the next SQL command only to FILENAME\n"
1.4.2.1 ! misho 3282: ".open ?--new? ?FILE? Close existing database and reopen FILE\n"
! 3283: " The --new starts with an empty file\n"
1.4 misho 3284: ".output ?FILENAME? Send output to FILENAME or stdout\n"
1.3 misho 3285: ".print STRING... Print literal STRING\n"
1.2 misho 3286: ".prompt MAIN CONTINUE Replace the standard prompts\n"
3287: ".quit Exit this program\n"
3288: ".read FILENAME Execute SQL in FILENAME\n"
3289: ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
1.4 misho 3290: ".save FILE Write in-memory database into FILE\n"
3291: ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
3292: ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
3293: " Add --indent for pretty-printing\n"
1.4.2.1 ! misho 3294: ".selftest ?--init? Run tests defined in the SELFTEST table\n"
1.4 misho 3295: ".separator COL ?ROW? Change the column separator and optionally the row\n"
3296: " separator for both the output mode and .import\n"
3297: #if defined(SQLITE_ENABLE_SESSION)
3298: ".session CMD ... Create or control sessions\n"
3299: #endif
1.4.2.1 ! misho 3300: ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n"
1.4 misho 3301: ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
1.2 misho 3302: ".show Show the current values for various settings\n"
1.4 misho 3303: ".stats ?on|off? Show stats or turn stats on or off\n"
3304: ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
1.2 misho 3305: ".tables ?TABLE? List names of tables\n"
3306: " If TABLE specified, only list tables matching\n"
3307: " LIKE pattern TABLE.\n"
1.4.2.1 ! misho 3308: ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
1.2 misho 3309: ".timeout MS Try opening locked tables for MS milliseconds\n"
1.4 misho 3310: ".timer on|off Turn SQL timer on or off\n"
1.3 misho 3311: ".trace FILE|off Output each SQL statement as it is run\n"
1.4 misho 3312: ".vfsinfo ?AUX? Information about the top-level VFS\n"
3313: ".vfslist List all available VFSes\n"
1.2 misho 3314: ".vfsname ?AUX? Print the name of the VFS stack\n"
3315: ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
1.4 misho 3316: " Negative values right-justify\n"
1.2 misho 3317: ;
3318:
1.4 misho 3319: #if defined(SQLITE_ENABLE_SESSION)
3320: /*
3321: ** Print help information for the ".sessions" command
3322: */
3323: void session_help(ShellState *p){
3324: raw_printf(p->out,
3325: ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
3326: "If ?NAME? is omitted, the first defined session is used.\n"
3327: "Subcommands:\n"
3328: " attach TABLE Attach TABLE\n"
3329: " changeset FILE Write a changeset into FILE\n"
3330: " close Close one session\n"
3331: " enable ?BOOLEAN? Set or query the enable bit\n"
3332: " filter GLOB... Reject tables matching GLOBs\n"
3333: " indirect ?BOOLEAN? Mark or query the indirect status\n"
3334: " isempty Query whether the session is empty\n"
3335: " list List currently open session names\n"
3336: " open DB NAME Open a new session on DB\n"
3337: " patchset FILE Write a patchset into FILE\n"
3338: );
3339: }
3340: #endif
3341:
1.2 misho 3342:
3343: /* Forward reference */
1.4 misho 3344: static int process_input(ShellState *p, FILE *in);
1.4.2.1 ! misho 3345:
! 3346: /*
! 3347: ** Read the content of file zName into memory obtained from sqlite3_malloc64()
! 3348: ** and return a pointer to the buffer. The caller is responsible for freeing
! 3349: ** the memory.
! 3350: **
! 3351: ** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
! 3352: ** read.
! 3353: **
! 3354: ** For convenience, a nul-terminator byte is always appended to the data read
! 3355: ** from the file before the buffer is returned. This byte is not included in
! 3356: ** the final value of (*pnByte), if applicable.
! 3357: **
! 3358: ** NULL is returned if any error is encountered. The final value of *pnByte
! 3359: ** is undefined in this case.
! 3360: */
! 3361: static char *readFile(const char *zName, int *pnByte){
! 3362: FILE *in = fopen(zName, "rb");
! 3363: long nIn;
! 3364: size_t nRead;
! 3365: char *pBuf;
! 3366: if( in==0 ) return 0;
! 3367: fseek(in, 0, SEEK_END);
! 3368: nIn = ftell(in);
! 3369: rewind(in);
! 3370: pBuf = sqlite3_malloc64( nIn+1 );
! 3371: if( pBuf==0 ) return 0;
! 3372: nRead = fread(pBuf, nIn, 1, in);
! 3373: fclose(in);
! 3374: if( nRead!=1 ){
! 3375: sqlite3_free(pBuf);
! 3376: return 0;
! 3377: }
! 3378: pBuf[nIn] = 0;
! 3379: if( pnByte ) *pnByte = nIn;
! 3380: return pBuf;
! 3381: }
! 3382:
1.4 misho 3383: /*
3384: ** Implementation of the "readfile(X)" SQL function. The entire content
3385: ** of the file named X is read and returned as a BLOB. NULL is returned
3386: ** if the file does not exist or is unreadable.
3387: */
3388: static void readfileFunc(
3389: sqlite3_context *context,
3390: int argc,
3391: sqlite3_value **argv
3392: ){
3393: const char *zName;
3394: void *pBuf;
1.4.2.1 ! misho 3395: int nBuf;
1.4 misho 3396:
3397: UNUSED_PARAMETER(argc);
3398: zName = (const char*)sqlite3_value_text(argv[0]);
3399: if( zName==0 ) return;
1.4.2.1 ! misho 3400: pBuf = readFile(zName, &nBuf);
! 3401: if( pBuf ) sqlite3_result_blob(context, pBuf, nBuf, sqlite3_free);
1.4 misho 3402: }
3403:
3404: /*
3405: ** Implementation of the "writefile(X,Y)" SQL function. The argument Y
3406: ** is written into file X. The number of bytes written is returned. Or
3407: ** NULL is returned if something goes wrong, such as being unable to open
3408: ** file X for writing.
3409: */
3410: static void writefileFunc(
3411: sqlite3_context *context,
3412: int argc,
3413: sqlite3_value **argv
3414: ){
3415: FILE *out;
3416: const char *z;
3417: sqlite3_int64 rc;
3418: const char *zFile;
3419:
3420: UNUSED_PARAMETER(argc);
3421: zFile = (const char*)sqlite3_value_text(argv[0]);
3422: if( zFile==0 ) return;
3423: out = fopen(zFile, "wb");
3424: if( out==0 ) return;
3425: z = (const char*)sqlite3_value_blob(argv[1]);
3426: if( z==0 ){
3427: rc = 0;
3428: }else{
3429: rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
3430: }
3431: fclose(out);
3432: sqlite3_result_int64(context, rc);
3433: }
3434:
3435: #if defined(SQLITE_ENABLE_SESSION)
3436: /*
3437: ** Close a single OpenSession object and release all of its associated
3438: ** resources.
3439: */
3440: static void session_close(OpenSession *pSession){
3441: int i;
3442: sqlite3session_delete(pSession->p);
3443: sqlite3_free(pSession->zName);
3444: for(i=0; i<pSession->nFilter; i++){
3445: sqlite3_free(pSession->azFilter[i]);
3446: }
3447: sqlite3_free(pSession->azFilter);
3448: memset(pSession, 0, sizeof(OpenSession));
3449: }
3450: #endif
3451:
3452: /*
3453: ** Close all OpenSession objects and release all associated resources.
3454: */
3455: #if defined(SQLITE_ENABLE_SESSION)
3456: static void session_close_all(ShellState *p){
3457: int i;
3458: for(i=0; i<p->nSession; i++){
3459: session_close(&p->aSession[i]);
3460: }
3461: p->nSession = 0;
3462: }
3463: #else
3464: # define session_close_all(X)
3465: #endif
3466:
3467: /*
3468: ** Implementation of the xFilter function for an open session. Omit
3469: ** any tables named by ".session filter" but let all other table through.
3470: */
3471: #if defined(SQLITE_ENABLE_SESSION)
3472: static int session_filter(void *pCtx, const char *zTab){
3473: OpenSession *pSession = (OpenSession*)pCtx;
3474: int i;
3475: for(i=0; i<pSession->nFilter; i++){
3476: if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
3477: }
3478: return 1;
3479: }
3480: #endif
1.2 misho 3481:
3482: /*
3483: ** Make sure the database is open. If it is not, then open it. If
3484: ** the database fails to open, print an error message and exit.
3485: */
1.4 misho 3486: static void open_db(ShellState *p, int keepAlive){
1.2 misho 3487: if( p->db==0 ){
1.3 misho 3488: sqlite3_initialize();
1.2 misho 3489: sqlite3_open(p->zDbFilename, &p->db);
1.4 misho 3490: globalDb = p->db;
3491: if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
3492: utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
3493: p->zDbFilename, sqlite3_errmsg(p->db));
3494: if( keepAlive ) return;
1.2 misho 3495: exit(1);
3496: }
3497: #ifndef SQLITE_OMIT_LOAD_EXTENSION
3498: sqlite3_enable_load_extension(p->db, 1);
3499: #endif
1.4 misho 3500: sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
3501: readfileFunc, 0, 0);
3502: sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
3503: writefileFunc, 0, 0);
1.4.2.1 ! misho 3504: sqlite3_create_function(p->db, "sha3", 1, SQLITE_UTF8, 0,
! 3505: sha3Func, 0, 0);
! 3506: sqlite3_create_function(p->db, "sha3", 2, SQLITE_UTF8, 0,
! 3507: sha3Func, 0, 0);
! 3508: sqlite3_create_function(p->db, "sha3_query", 1, SQLITE_UTF8, 0,
! 3509: sha3QueryFunc, 0, 0);
! 3510: sqlite3_create_function(p->db, "sha3_query", 2, SQLITE_UTF8, 0,
! 3511: sha3QueryFunc, 0, 0);
1.2 misho 3512: }
3513: }
3514:
3515: /*
3516: ** Do C-language style dequoting.
3517: **
1.4 misho 3518: ** \a -> alarm
3519: ** \b -> backspace
1.2 misho 3520: ** \t -> tab
3521: ** \n -> newline
1.4 misho 3522: ** \v -> vertical tab
3523: ** \f -> form feed
1.2 misho 3524: ** \r -> carriage return
1.4 misho 3525: ** \s -> space
3526: ** \" -> "
3527: ** \' -> '
3528: ** \\ -> backslash
1.2 misho 3529: ** \NNN -> ascii character NNN in octal
3530: */
3531: static void resolve_backslashes(char *z){
3532: int i, j;
3533: char c;
1.4 misho 3534: while( *z && *z!='\\' ) z++;
1.2 misho 3535: for(i=j=0; (c = z[i])!=0; i++, j++){
1.4 misho 3536: if( c=='\\' && z[i+1]!=0 ){
1.2 misho 3537: c = z[++i];
1.4 misho 3538: if( c=='a' ){
3539: c = '\a';
3540: }else if( c=='b' ){
3541: c = '\b';
1.2 misho 3542: }else if( c=='t' ){
3543: c = '\t';
1.4 misho 3544: }else if( c=='n' ){
3545: c = '\n';
3546: }else if( c=='v' ){
3547: c = '\v';
3548: }else if( c=='f' ){
3549: c = '\f';
1.2 misho 3550: }else if( c=='r' ){
3551: c = '\r';
1.4 misho 3552: }else if( c=='"' ){
3553: c = '"';
3554: }else if( c=='\'' ){
3555: c = '\'';
3556: }else if( c=='\\' ){
3557: c = '\\';
1.2 misho 3558: }else if( c>='0' && c<='7' ){
3559: c -= '0';
3560: if( z[i+1]>='0' && z[i+1]<='7' ){
3561: i++;
3562: c = (c<<3) + z[i] - '0';
3563: if( z[i+1]>='0' && z[i+1]<='7' ){
3564: i++;
3565: c = (c<<3) + z[i] - '0';
3566: }
3567: }
3568: }
3569: }
3570: z[j] = c;
3571: }
1.4 misho 3572: if( j<i ) z[j] = 0;
3573: }
3574:
3575: /*
3576: ** Return the value of a hexadecimal digit. Return -1 if the input
3577: ** is not a hex digit.
3578: */
3579: static int hexDigitValue(char c){
3580: if( c>='0' && c<='9' ) return c - '0';
3581: if( c>='a' && c<='f' ) return c - 'a' + 10;
3582: if( c>='A' && c<='F' ) return c - 'A' + 10;
3583: return -1;
3584: }
3585:
3586: /*
3587: ** Interpret zArg as an integer value, possibly with suffixes.
3588: */
3589: static sqlite3_int64 integerValue(const char *zArg){
3590: sqlite3_int64 v = 0;
3591: static const struct { char *zSuffix; int iMult; } aMult[] = {
3592: { "KiB", 1024 },
3593: { "MiB", 1024*1024 },
3594: { "GiB", 1024*1024*1024 },
3595: { "KB", 1000 },
3596: { "MB", 1000000 },
3597: { "GB", 1000000000 },
3598: { "K", 1000 },
3599: { "M", 1000000 },
3600: { "G", 1000000000 },
3601: };
3602: int i;
3603: int isNeg = 0;
3604: if( zArg[0]=='-' ){
3605: isNeg = 1;
3606: zArg++;
3607: }else if( zArg[0]=='+' ){
3608: zArg++;
3609: }
3610: if( zArg[0]=='0' && zArg[1]=='x' ){
3611: int x;
3612: zArg += 2;
3613: while( (x = hexDigitValue(zArg[0]))>=0 ){
3614: v = (v<<4) + x;
3615: zArg++;
3616: }
3617: }else{
3618: while( IsDigit(zArg[0]) ){
3619: v = v*10 + zArg[0] - '0';
3620: zArg++;
3621: }
3622: }
3623: for(i=0; i<ArraySize(aMult); i++){
3624: if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
3625: v *= aMult[i].iMult;
3626: break;
3627: }
3628: }
3629: return isNeg? -v : v;
1.2 misho 3630: }
3631:
3632: /*
1.4 misho 3633: ** Interpret zArg as either an integer or a boolean value. Return 1 or 0
3634: ** for TRUE and FALSE. Return the integer value if appropriate.
1.2 misho 3635: */
1.4.2.1 ! misho 3636: static int booleanValue(const char *zArg){
1.4 misho 3637: int i;
3638: if( zArg[0]=='0' && zArg[1]=='x' ){
3639: for(i=2; hexDigitValue(zArg[i])>=0; i++){}
3640: }else{
3641: for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1.2 misho 3642: }
1.4 misho 3643: if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
3644: if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
3645: return 1;
3646: }
3647: if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
3648: return 0;
3649: }
3650: utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
3651: zArg);
3652: return 0;
1.2 misho 3653: }
3654:
3655: /*
1.4.2.1 ! misho 3656: ** Set or clear a shell flag according to a boolean value.
! 3657: */
! 3658: static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){
! 3659: if( booleanValue(zArg) ){
! 3660: ShellSetFlag(p, mFlag);
! 3661: }else{
! 3662: ShellClearFlag(p, mFlag);
! 3663: }
! 3664: }
! 3665:
! 3666: /*
1.3 misho 3667: ** Close an output file, assuming it is not stderr or stdout
3668: */
3669: static void output_file_close(FILE *f){
3670: if( f && f!=stdout && f!=stderr ) fclose(f);
3671: }
3672:
3673: /*
3674: ** Try to open an output file. The names "stdout" and "stderr" are
1.4 misho 3675: ** recognized and do the right thing. NULL is returned if the output
1.3 misho 3676: ** filename is "off".
3677: */
3678: static FILE *output_file_open(const char *zFile){
3679: FILE *f;
3680: if( strcmp(zFile,"stdout")==0 ){
3681: f = stdout;
3682: }else if( strcmp(zFile, "stderr")==0 ){
3683: f = stderr;
3684: }else if( strcmp(zFile, "off")==0 ){
3685: f = 0;
3686: }else{
3687: f = fopen(zFile, "wb");
3688: if( f==0 ){
1.4 misho 3689: utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
1.3 misho 3690: }
3691: }
3692: return f;
3693: }
3694:
1.4.2.1 ! misho 3695: #if !defined(SQLITE_UNTESTABLE)
! 3696: #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
1.3 misho 3697: /*
3698: ** A routine for handling output from sqlite3_trace().
3699: */
1.4 misho 3700: static int sql_trace_callback(
3701: unsigned mType,
3702: void *pArg,
3703: void *pP,
3704: void *pX
3705: ){
1.3 misho 3706: FILE *f = (FILE*)pArg;
1.4 misho 3707: UNUSED_PARAMETER(mType);
3708: UNUSED_PARAMETER(pP);
3709: if( f ){
3710: const char *z = (const char*)pX;
3711: int i = (int)strlen(z);
3712: while( i>0 && z[i-1]==';' ){ i--; }
3713: utf8_printf(f, "%.*s;\n", i, z);
3714: }
3715: return 0;
1.3 misho 3716: }
1.4.2.1 ! misho 3717: #endif
! 3718: #endif
1.3 misho 3719:
3720: /*
3721: ** A no-op routine that runs with the ".breakpoint" doc-command. This is
3722: ** a useful spot to set a debugger breakpoint.
3723: */
3724: static void test_breakpoint(void){
3725: static int nCall = 0;
3726: nCall++;
3727: }
3728:
3729: /*
1.4 misho 3730: ** An object used to read a CSV and other files for import.
3731: */
3732: typedef struct ImportCtx ImportCtx;
3733: struct ImportCtx {
3734: const char *zFile; /* Name of the input file */
3735: FILE *in; /* Read the CSV text from this input stream */
3736: char *z; /* Accumulated text for a field */
3737: int n; /* Number of bytes in z */
3738: int nAlloc; /* Space allocated for z[] */
3739: int nLine; /* Current line number */
3740: int cTerm; /* Character that terminated the most recent field */
3741: int cColSep; /* The column separator character. (Usually ",") */
3742: int cRowSep; /* The row separator character. (Usually "\n") */
3743: };
3744:
3745: /* Append a single byte to z[] */
3746: static void import_append_char(ImportCtx *p, int c){
3747: if( p->n+1>=p->nAlloc ){
3748: p->nAlloc += p->nAlloc + 100;
3749: p->z = sqlite3_realloc64(p->z, p->nAlloc);
3750: if( p->z==0 ){
3751: raw_printf(stderr, "out of memory\n");
3752: exit(1);
3753: }
3754: }
3755: p->z[p->n++] = (char)c;
3756: }
3757:
3758: /* Read a single field of CSV text. Compatible with rfc4180 and extended
3759: ** with the option of having a separator other than ",".
3760: **
3761: ** + Input comes from p->in.
3762: ** + Store results in p->z of length p->n. Space to hold p->z comes
3763: ** from sqlite3_malloc64().
3764: ** + Use p->cSep as the column separator. The default is ",".
3765: ** + Use p->rSep as the row separator. The default is "\n".
3766: ** + Keep track of the line number in p->nLine.
3767: ** + Store the character that terminates the field in p->cTerm. Store
3768: ** EOF on end-of-file.
3769: ** + Report syntax errors on stderr
3770: */
3771: static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
3772: int c;
3773: int cSep = p->cColSep;
3774: int rSep = p->cRowSep;
3775: p->n = 0;
3776: c = fgetc(p->in);
3777: if( c==EOF || seenInterrupt ){
3778: p->cTerm = EOF;
3779: return 0;
3780: }
3781: if( c=='"' ){
3782: int pc, ppc;
3783: int startLine = p->nLine;
3784: int cQuote = c;
3785: pc = ppc = 0;
3786: while( 1 ){
3787: c = fgetc(p->in);
3788: if( c==rSep ) p->nLine++;
3789: if( c==cQuote ){
3790: if( pc==cQuote ){
3791: pc = 0;
3792: continue;
3793: }
3794: }
3795: if( (c==cSep && pc==cQuote)
3796: || (c==rSep && pc==cQuote)
3797: || (c==rSep && pc=='\r' && ppc==cQuote)
3798: || (c==EOF && pc==cQuote)
3799: ){
3800: do{ p->n--; }while( p->z[p->n]!=cQuote );
3801: p->cTerm = c;
3802: break;
3803: }
3804: if( pc==cQuote && c!='\r' ){
3805: utf8_printf(stderr, "%s:%d: unescaped %c character\n",
3806: p->zFile, p->nLine, cQuote);
3807: }
3808: if( c==EOF ){
3809: utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
3810: p->zFile, startLine, cQuote);
3811: p->cTerm = c;
3812: break;
3813: }
3814: import_append_char(p, c);
3815: ppc = pc;
3816: pc = c;
3817: }
3818: }else{
3819: while( c!=EOF && c!=cSep && c!=rSep ){
3820: import_append_char(p, c);
3821: c = fgetc(p->in);
3822: }
3823: if( c==rSep ){
3824: p->nLine++;
3825: if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
3826: }
3827: p->cTerm = c;
3828: }
3829: if( p->z ) p->z[p->n] = 0;
3830: return p->z;
3831: }
3832:
3833: /* Read a single field of ASCII delimited text.
3834: **
3835: ** + Input comes from p->in.
3836: ** + Store results in p->z of length p->n. Space to hold p->z comes
3837: ** from sqlite3_malloc64().
3838: ** + Use p->cSep as the column separator. The default is "\x1F".
3839: ** + Use p->rSep as the row separator. The default is "\x1E".
3840: ** + Keep track of the row number in p->nLine.
3841: ** + Store the character that terminates the field in p->cTerm. Store
3842: ** EOF on end-of-file.
3843: ** + Report syntax errors on stderr
3844: */
3845: static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
3846: int c;
3847: int cSep = p->cColSep;
3848: int rSep = p->cRowSep;
3849: p->n = 0;
3850: c = fgetc(p->in);
3851: if( c==EOF || seenInterrupt ){
3852: p->cTerm = EOF;
3853: return 0;
3854: }
3855: while( c!=EOF && c!=cSep && c!=rSep ){
3856: import_append_char(p, c);
3857: c = fgetc(p->in);
3858: }
3859: if( c==rSep ){
3860: p->nLine++;
3861: }
3862: p->cTerm = c;
3863: if( p->z ) p->z[p->n] = 0;
3864: return p->z;
3865: }
3866:
3867: /*
3868: ** Try to transfer data for table zTable. If an error is seen while
3869: ** moving forward, try to go backwards. The backwards movement won't
3870: ** work for WITHOUT ROWID tables.
3871: */
3872: static void tryToCloneData(
3873: ShellState *p,
3874: sqlite3 *newDb,
3875: const char *zTable
3876: ){
3877: sqlite3_stmt *pQuery = 0;
3878: sqlite3_stmt *pInsert = 0;
3879: char *zQuery = 0;
3880: char *zInsert = 0;
3881: int rc;
3882: int i, j, n;
3883: int nTable = (int)strlen(zTable);
3884: int k = 0;
3885: int cnt = 0;
3886: const int spinRate = 10000;
3887:
3888: zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
3889: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
3890: if( rc ){
3891: utf8_printf(stderr, "Error %d: %s on [%s]\n",
3892: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
3893: zQuery);
3894: goto end_data_xfer;
3895: }
3896: n = sqlite3_column_count(pQuery);
3897: zInsert = sqlite3_malloc64(200 + nTable + n*3);
3898: if( zInsert==0 ){
3899: raw_printf(stderr, "out of memory\n");
3900: goto end_data_xfer;
3901: }
3902: sqlite3_snprintf(200+nTable,zInsert,
3903: "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
3904: i = (int)strlen(zInsert);
3905: for(j=1; j<n; j++){
3906: memcpy(zInsert+i, ",?", 2);
3907: i += 2;
3908: }
3909: memcpy(zInsert+i, ");", 3);
3910: rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
3911: if( rc ){
3912: utf8_printf(stderr, "Error %d: %s on [%s]\n",
3913: sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
3914: zQuery);
3915: goto end_data_xfer;
3916: }
3917: for(k=0; k<2; k++){
3918: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
3919: for(i=0; i<n; i++){
3920: switch( sqlite3_column_type(pQuery, i) ){
3921: case SQLITE_NULL: {
3922: sqlite3_bind_null(pInsert, i+1);
3923: break;
3924: }
3925: case SQLITE_INTEGER: {
3926: sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
3927: break;
3928: }
3929: case SQLITE_FLOAT: {
3930: sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
3931: break;
3932: }
3933: case SQLITE_TEXT: {
3934: sqlite3_bind_text(pInsert, i+1,
3935: (const char*)sqlite3_column_text(pQuery,i),
3936: -1, SQLITE_STATIC);
3937: break;
3938: }
3939: case SQLITE_BLOB: {
3940: sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
3941: sqlite3_column_bytes(pQuery,i),
3942: SQLITE_STATIC);
3943: break;
3944: }
3945: }
3946: } /* End for */
3947: rc = sqlite3_step(pInsert);
3948: if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
3949: utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
3950: sqlite3_errmsg(newDb));
3951: }
3952: sqlite3_reset(pInsert);
3953: cnt++;
3954: if( (cnt%spinRate)==0 ){
3955: printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
3956: fflush(stdout);
3957: }
3958: } /* End while */
3959: if( rc==SQLITE_DONE ) break;
3960: sqlite3_finalize(pQuery);
3961: sqlite3_free(zQuery);
3962: zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
3963: zTable);
3964: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
3965: if( rc ){
3966: utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
3967: break;
3968: }
3969: } /* End for(k=0...) */
3970:
3971: end_data_xfer:
3972: sqlite3_finalize(pQuery);
3973: sqlite3_finalize(pInsert);
3974: sqlite3_free(zQuery);
3975: sqlite3_free(zInsert);
3976: }
3977:
3978:
3979: /*
3980: ** Try to transfer all rows of the schema that match zWhere. For
3981: ** each row, invoke xForEach() on the object defined by that row.
3982: ** If an error is encountered while moving forward through the
3983: ** sqlite_master table, try again moving backwards.
3984: */
3985: static void tryToCloneSchema(
3986: ShellState *p,
3987: sqlite3 *newDb,
3988: const char *zWhere,
3989: void (*xForEach)(ShellState*,sqlite3*,const char*)
3990: ){
3991: sqlite3_stmt *pQuery = 0;
3992: char *zQuery = 0;
3993: int rc;
3994: const unsigned char *zName;
3995: const unsigned char *zSql;
3996: char *zErrMsg = 0;
3997:
3998: zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
3999: " WHERE %s", zWhere);
4000: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
4001: if( rc ){
4002: utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
4003: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
4004: zQuery);
4005: goto end_schema_xfer;
4006: }
4007: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
4008: zName = sqlite3_column_text(pQuery, 0);
4009: zSql = sqlite3_column_text(pQuery, 1);
4010: printf("%s... ", zName); fflush(stdout);
4011: sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
4012: if( zErrMsg ){
4013: utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
4014: sqlite3_free(zErrMsg);
4015: zErrMsg = 0;
4016: }
4017: if( xForEach ){
4018: xForEach(p, newDb, (const char*)zName);
4019: }
4020: printf("done\n");
4021: }
4022: if( rc!=SQLITE_DONE ){
4023: sqlite3_finalize(pQuery);
4024: sqlite3_free(zQuery);
4025: zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
4026: " WHERE %s ORDER BY rowid DESC", zWhere);
4027: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
4028: if( rc ){
4029: utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
4030: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
4031: zQuery);
4032: goto end_schema_xfer;
4033: }
4034: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
4035: zName = sqlite3_column_text(pQuery, 0);
4036: zSql = sqlite3_column_text(pQuery, 1);
4037: printf("%s... ", zName); fflush(stdout);
4038: sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
4039: if( zErrMsg ){
4040: utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
4041: sqlite3_free(zErrMsg);
4042: zErrMsg = 0;
4043: }
4044: if( xForEach ){
4045: xForEach(p, newDb, (const char*)zName);
4046: }
4047: printf("done\n");
4048: }
4049: }
4050: end_schema_xfer:
4051: sqlite3_finalize(pQuery);
4052: sqlite3_free(zQuery);
4053: }
4054:
4055: /*
4056: ** Open a new database file named "zNewDb". Try to recover as much information
4057: ** as possible out of the main database (which might be corrupt) and write it
4058: ** into zNewDb.
4059: */
4060: static void tryToClone(ShellState *p, const char *zNewDb){
4061: int rc;
4062: sqlite3 *newDb = 0;
4063: if( access(zNewDb,0)==0 ){
4064: utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
4065: return;
4066: }
4067: rc = sqlite3_open(zNewDb, &newDb);
4068: if( rc ){
4069: utf8_printf(stderr, "Cannot create output database: %s\n",
4070: sqlite3_errmsg(newDb));
4071: }else{
4072: sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
4073: sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
4074: tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
4075: tryToCloneSchema(p, newDb, "type!='table'", 0);
4076: sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
4077: sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
4078: }
4079: sqlite3_close(newDb);
4080: }
4081:
4082: /*
4083: ** Change the output file back to stdout
4084: */
4085: static void output_reset(ShellState *p){
4086: if( p->outfile[0]=='|' ){
4087: #ifndef SQLITE_OMIT_POPEN
4088: pclose(p->out);
4089: #endif
4090: }else{
4091: output_file_close(p->out);
4092: }
4093: p->outfile[0] = 0;
4094: p->out = stdout;
4095: }
4096:
4097: /*
4098: ** Run an SQL command and return the single integer result.
4099: */
4100: static int db_int(ShellState *p, const char *zSql){
4101: sqlite3_stmt *pStmt;
4102: int res = 0;
4103: sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4104: if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
4105: res = sqlite3_column_int(pStmt,0);
4106: }
4107: sqlite3_finalize(pStmt);
4108: return res;
4109: }
4110:
4111: /*
4112: ** Convert a 2-byte or 4-byte big-endian integer into a native integer
4113: */
4114: static unsigned int get2byteInt(unsigned char *a){
4115: return (a[0]<<8) + a[1];
4116: }
4117: static unsigned int get4byteInt(unsigned char *a){
4118: return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
4119: }
4120:
4121: /*
4122: ** Implementation of the ".info" command.
4123: **
4124: ** Return 1 on error, 2 to exit, and 0 otherwise.
4125: */
4126: static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
4127: static const struct { const char *zName; int ofst; } aField[] = {
4128: { "file change counter:", 24 },
4129: { "database page count:", 28 },
4130: { "freelist page count:", 36 },
4131: { "schema cookie:", 40 },
4132: { "schema format:", 44 },
4133: { "default cache size:", 48 },
4134: { "autovacuum top root:", 52 },
4135: { "incremental vacuum:", 64 },
4136: { "text encoding:", 56 },
4137: { "user version:", 60 },
4138: { "application id:", 68 },
4139: { "software version:", 96 },
4140: };
4141: static const struct { const char *zName; const char *zSql; } aQuery[] = {
4142: { "number of tables:",
4143: "SELECT count(*) FROM %s WHERE type='table'" },
4144: { "number of indexes:",
4145: "SELECT count(*) FROM %s WHERE type='index'" },
4146: { "number of triggers:",
4147: "SELECT count(*) FROM %s WHERE type='trigger'" },
4148: { "number of views:",
4149: "SELECT count(*) FROM %s WHERE type='view'" },
4150: { "schema size:",
4151: "SELECT total(length(sql)) FROM %s" },
4152: };
4153: sqlite3_file *pFile = 0;
4154: int i;
4155: char *zSchemaTab;
4156: char *zDb = nArg>=2 ? azArg[1] : "main";
4157: unsigned char aHdr[100];
4158: open_db(p, 0);
4159: if( p->db==0 ) return 1;
4160: sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
4161: if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
4162: return 1;
4163: }
4164: i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
4165: if( i!=SQLITE_OK ){
4166: raw_printf(stderr, "unable to read database header\n");
4167: return 1;
4168: }
4169: i = get2byteInt(aHdr+16);
4170: if( i==1 ) i = 65536;
4171: utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
4172: utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
4173: utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
4174: utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
4175: for(i=0; i<ArraySize(aField); i++){
4176: int ofst = aField[i].ofst;
4177: unsigned int val = get4byteInt(aHdr + ofst);
4178: utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
4179: switch( ofst ){
4180: case 56: {
4181: if( val==1 ) raw_printf(p->out, " (utf8)");
4182: if( val==2 ) raw_printf(p->out, " (utf16le)");
4183: if( val==3 ) raw_printf(p->out, " (utf16be)");
4184: }
4185: }
4186: raw_printf(p->out, "\n");
4187: }
4188: if( zDb==0 ){
4189: zSchemaTab = sqlite3_mprintf("main.sqlite_master");
4190: }else if( strcmp(zDb,"temp")==0 ){
4191: zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
4192: }else{
4193: zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
4194: }
4195: for(i=0; i<ArraySize(aQuery); i++){
4196: char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
4197: int val = db_int(p, zSql);
4198: sqlite3_free(zSql);
4199: utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
4200: }
4201: sqlite3_free(zSchemaTab);
4202: return 0;
4203: }
4204:
4205: /*
4206: ** Print the current sqlite3_errmsg() value to stderr and return 1.
4207: */
4208: static int shellDatabaseError(sqlite3 *db){
4209: const char *zErr = sqlite3_errmsg(db);
4210: utf8_printf(stderr, "Error: %s\n", zErr);
4211: return 1;
4212: }
4213:
1.4.2.1 ! misho 4214: /*
! 4215: ** Print an out-of-memory message to stderr and return 1.
! 4216: */
! 4217: static int shellNomemError(void){
! 4218: raw_printf(stderr, "Error: out of memory\n");
! 4219: return 1;
! 4220: }
! 4221:
! 4222: /*
! 4223: ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
! 4224: ** if they match and FALSE (0) if they do not match.
! 4225: **
! 4226: ** Globbing rules:
! 4227: **
! 4228: ** '*' Matches any sequence of zero or more characters.
! 4229: **
! 4230: ** '?' Matches exactly one character.
! 4231: **
! 4232: ** [...] Matches one character from the enclosed list of
! 4233: ** characters.
! 4234: **
! 4235: ** [^...] Matches one character not in the enclosed list.
! 4236: **
! 4237: ** '#' Matches any sequence of one or more digits with an
! 4238: ** optional + or - sign in front
! 4239: **
! 4240: ** ' ' Any span of whitespace matches any other span of
! 4241: ** whitespace.
! 4242: **
! 4243: ** Extra whitespace at the end of z[] is ignored.
! 4244: */
! 4245: static int testcase_glob(const char *zGlob, const char *z){
! 4246: int c, c2;
! 4247: int invert;
! 4248: int seen;
! 4249:
! 4250: while( (c = (*(zGlob++)))!=0 ){
! 4251: if( IsSpace(c) ){
! 4252: if( !IsSpace(*z) ) return 0;
! 4253: while( IsSpace(*zGlob) ) zGlob++;
! 4254: while( IsSpace(*z) ) z++;
! 4255: }else if( c=='*' ){
! 4256: while( (c=(*(zGlob++))) == '*' || c=='?' ){
! 4257: if( c=='?' && (*(z++))==0 ) return 0;
! 4258: }
! 4259: if( c==0 ){
! 4260: return 1;
! 4261: }else if( c=='[' ){
! 4262: while( *z && testcase_glob(zGlob-1,z)==0 ){
! 4263: z++;
! 4264: }
! 4265: return (*z)!=0;
! 4266: }
! 4267: while( (c2 = (*(z++)))!=0 ){
! 4268: while( c2!=c ){
! 4269: c2 = *(z++);
! 4270: if( c2==0 ) return 0;
! 4271: }
! 4272: if( testcase_glob(zGlob,z) ) return 1;
! 4273: }
! 4274: return 0;
! 4275: }else if( c=='?' ){
! 4276: if( (*(z++))==0 ) return 0;
! 4277: }else if( c=='[' ){
! 4278: int prior_c = 0;
! 4279: seen = 0;
! 4280: invert = 0;
! 4281: c = *(z++);
! 4282: if( c==0 ) return 0;
! 4283: c2 = *(zGlob++);
! 4284: if( c2=='^' ){
! 4285: invert = 1;
! 4286: c2 = *(zGlob++);
! 4287: }
! 4288: if( c2==']' ){
! 4289: if( c==']' ) seen = 1;
! 4290: c2 = *(zGlob++);
! 4291: }
! 4292: while( c2 && c2!=']' ){
! 4293: if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
! 4294: c2 = *(zGlob++);
! 4295: if( c>=prior_c && c<=c2 ) seen = 1;
! 4296: prior_c = 0;
! 4297: }else{
! 4298: if( c==c2 ){
! 4299: seen = 1;
! 4300: }
! 4301: prior_c = c2;
! 4302: }
! 4303: c2 = *(zGlob++);
! 4304: }
! 4305: if( c2==0 || (seen ^ invert)==0 ) return 0;
! 4306: }else if( c=='#' ){
! 4307: if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
! 4308: if( !IsDigit(z[0]) ) return 0;
! 4309: z++;
! 4310: while( IsDigit(z[0]) ){ z++; }
! 4311: }else{
! 4312: if( c!=(*(z++)) ) return 0;
! 4313: }
! 4314: }
! 4315: while( IsSpace(*z) ){ z++; }
! 4316: return *z==0;
! 4317: }
! 4318:
1.4 misho 4319:
4320: /*
4321: ** Compare the string as a command-line option with either one or two
4322: ** initial "-" characters.
4323: */
4324: static int optionMatch(const char *zStr, const char *zOpt){
4325: if( zStr[0]!='-' ) return 0;
4326: zStr++;
4327: if( zStr[0]=='-' ) zStr++;
4328: return strcmp(zStr, zOpt)==0;
4329: }
4330:
4331: /*
1.4.2.1 ! misho 4332: ** Delete a file.
! 4333: */
! 4334: int shellDeleteFile(const char *zFilename){
! 4335: int rc;
! 4336: #ifdef _WIN32
! 4337: wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
! 4338: rc = _wunlink(z);
! 4339: sqlite3_free(z);
! 4340: #else
! 4341: rc = unlink(zFilename);
! 4342: #endif
! 4343: return rc;
! 4344: }
! 4345:
! 4346:
! 4347: /*
! 4348: ** The implementation of SQL scalar function fkey_collate_clause(), used
! 4349: ** by the ".lint fkey-indexes" command. This scalar function is always
! 4350: ** called with four arguments - the parent table name, the parent column name,
! 4351: ** the child table name and the child column name.
! 4352: **
! 4353: ** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
! 4354: **
! 4355: ** If either of the named tables or columns do not exist, this function
! 4356: ** returns an empty string. An empty string is also returned if both tables
! 4357: ** and columns exist but have the same default collation sequence. Or,
! 4358: ** if both exist but the default collation sequences are different, this
! 4359: ** function returns the string " COLLATE <parent-collation>", where
! 4360: ** <parent-collation> is the default collation sequence of the parent column.
! 4361: */
! 4362: static void shellFkeyCollateClause(
! 4363: sqlite3_context *pCtx,
! 4364: int nVal,
! 4365: sqlite3_value **apVal
! 4366: ){
! 4367: sqlite3 *db = sqlite3_context_db_handle(pCtx);
! 4368: const char *zParent;
! 4369: const char *zParentCol;
! 4370: const char *zParentSeq;
! 4371: const char *zChild;
! 4372: const char *zChildCol;
! 4373: const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
! 4374: int rc;
! 4375:
! 4376: assert( nVal==4 );
! 4377: zParent = (const char*)sqlite3_value_text(apVal[0]);
! 4378: zParentCol = (const char*)sqlite3_value_text(apVal[1]);
! 4379: zChild = (const char*)sqlite3_value_text(apVal[2]);
! 4380: zChildCol = (const char*)sqlite3_value_text(apVal[3]);
! 4381:
! 4382: sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
! 4383: rc = sqlite3_table_column_metadata(
! 4384: db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0
! 4385: );
! 4386: if( rc==SQLITE_OK ){
! 4387: rc = sqlite3_table_column_metadata(
! 4388: db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0
! 4389: );
! 4390: }
! 4391:
! 4392: if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){
! 4393: char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq);
! 4394: sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
! 4395: sqlite3_free(z);
! 4396: }
! 4397: }
! 4398:
! 4399:
! 4400: /*
! 4401: ** The implementation of dot-command ".lint fkey-indexes".
! 4402: */
! 4403: static int lintFkeyIndexes(
! 4404: ShellState *pState, /* Current shell tool state */
! 4405: char **azArg, /* Array of arguments passed to dot command */
! 4406: int nArg /* Number of entries in azArg[] */
! 4407: ){
! 4408: sqlite3 *db = pState->db; /* Database handle to query "main" db of */
! 4409: FILE *out = pState->out; /* Stream to write non-error output to */
! 4410: int bVerbose = 0; /* If -verbose is present */
! 4411: int bGroupByParent = 0; /* If -groupbyparent is present */
! 4412: int i; /* To iterate through azArg[] */
! 4413: const char *zIndent = ""; /* How much to indent CREATE INDEX by */
! 4414: int rc; /* Return code */
! 4415: sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
! 4416:
! 4417: /*
! 4418: ** This SELECT statement returns one row for each foreign key constraint
! 4419: ** in the schema of the main database. The column values are:
! 4420: **
! 4421: ** 0. The text of an SQL statement similar to:
! 4422: **
! 4423: ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?"
! 4424: **
! 4425: ** This is the same SELECT that the foreign keys implementation needs
! 4426: ** to run internally on child tables. If there is an index that can
! 4427: ** be used to optimize this query, then it can also be used by the FK
! 4428: ** implementation to optimize DELETE or UPDATE statements on the parent
! 4429: ** table.
! 4430: **
! 4431: ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by
! 4432: ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema
! 4433: ** contains an index that can be used to optimize the query.
! 4434: **
! 4435: ** 2. Human readable text that describes the child table and columns. e.g.
! 4436: **
! 4437: ** "child_table(child_key1, child_key2)"
! 4438: **
! 4439: ** 3. Human readable text that describes the parent table and columns. e.g.
! 4440: **
! 4441: ** "parent_table(parent_key1, parent_key2)"
! 4442: **
! 4443: ** 4. A full CREATE INDEX statement for an index that could be used to
! 4444: ** optimize DELETE or UPDATE statements on the parent table. e.g.
! 4445: **
! 4446: ** "CREATE INDEX child_table_child_key ON child_table(child_key)"
! 4447: **
! 4448: ** 5. The name of the parent table.
! 4449: **
! 4450: ** These six values are used by the C logic below to generate the report.
! 4451: */
! 4452: const char *zSql =
! 4453: "SELECT "
! 4454: " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '"
! 4455: " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
! 4456: " || fkey_collate_clause("
! 4457: " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')"
! 4458: ", "
! 4459: " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
! 4460: " || group_concat('*=?', ' AND ') || ')'"
! 4461: ", "
! 4462: " s.name || '(' || group_concat(f.[from], ', ') || ')'"
! 4463: ", "
! 4464: " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'"
! 4465: ", "
! 4466: " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
! 4467: " || ' ON ' || quote(s.name) || '('"
! 4468: " || group_concat(quote(f.[from]) ||"
! 4469: " fkey_collate_clause("
! 4470: " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')"
! 4471: " || ');'"
! 4472: ", "
! 4473: " f.[table] "
! 4474: "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f "
! 4475: "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
! 4476: "GROUP BY s.name, f.id "
! 4477: "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
! 4478: ;
! 4479: const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
! 4480:
! 4481: for(i=2; i<nArg; i++){
! 4482: int n = (int)strlen(azArg[i]);
! 4483: if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
! 4484: bVerbose = 1;
! 4485: }
! 4486: else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
! 4487: bGroupByParent = 1;
! 4488: zIndent = " ";
! 4489: }
! 4490: else{
! 4491: raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
! 4492: azArg[0], azArg[1]
! 4493: );
! 4494: return SQLITE_ERROR;
! 4495: }
! 4496: }
! 4497:
! 4498: /* Register the fkey_collate_clause() SQL function */
! 4499: rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
! 4500: 0, shellFkeyCollateClause, 0, 0
! 4501: );
! 4502:
! 4503:
! 4504: if( rc==SQLITE_OK ){
! 4505: rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
! 4506: }
! 4507: if( rc==SQLITE_OK ){
! 4508: sqlite3_bind_int(pSql, 1, bGroupByParent);
! 4509: }
! 4510:
! 4511: if( rc==SQLITE_OK ){
! 4512: int rc2;
! 4513: char *zPrev = 0;
! 4514: while( SQLITE_ROW==sqlite3_step(pSql) ){
! 4515: int res = -1;
! 4516: sqlite3_stmt *pExplain = 0;
! 4517: const char *zEQP = (const char*)sqlite3_column_text(pSql, 0);
! 4518: const char *zGlob = (const char*)sqlite3_column_text(pSql, 1);
! 4519: const char *zFrom = (const char*)sqlite3_column_text(pSql, 2);
! 4520: const char *zTarget = (const char*)sqlite3_column_text(pSql, 3);
! 4521: const char *zCI = (const char*)sqlite3_column_text(pSql, 4);
! 4522: const char *zParent = (const char*)sqlite3_column_text(pSql, 5);
! 4523:
! 4524: rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
! 4525: if( rc!=SQLITE_OK ) break;
! 4526: if( SQLITE_ROW==sqlite3_step(pExplain) ){
! 4527: const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
! 4528: res = (
! 4529: 0==sqlite3_strglob(zGlob, zPlan)
! 4530: || 0==sqlite3_strglob(zGlobIPK, zPlan)
! 4531: );
! 4532: }
! 4533: rc = sqlite3_finalize(pExplain);
! 4534: if( rc!=SQLITE_OK ) break;
! 4535:
! 4536: if( res<0 ){
! 4537: raw_printf(stderr, "Error: internal error");
! 4538: break;
! 4539: }else{
! 4540: if( bGroupByParent
! 4541: && (bVerbose || res==0)
! 4542: && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
! 4543: ){
! 4544: raw_printf(out, "-- Parent table %s\n", zParent);
! 4545: sqlite3_free(zPrev);
! 4546: zPrev = sqlite3_mprintf("%s", zParent);
! 4547: }
! 4548:
! 4549: if( res==0 ){
! 4550: raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
! 4551: }else if( bVerbose ){
! 4552: raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
! 4553: zIndent, zFrom, zTarget
! 4554: );
! 4555: }
! 4556: }
! 4557: }
! 4558: sqlite3_free(zPrev);
! 4559:
! 4560: if( rc!=SQLITE_OK ){
! 4561: raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
! 4562: }
! 4563:
! 4564: rc2 = sqlite3_finalize(pSql);
! 4565: if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
! 4566: rc = rc2;
! 4567: raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
! 4568: }
! 4569: }else{
! 4570: raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
! 4571: }
! 4572:
! 4573: return rc;
! 4574: }
! 4575:
! 4576: /*
! 4577: ** Implementation of ".lint" dot command.
! 4578: */
! 4579: static int lintDotCommand(
! 4580: ShellState *pState, /* Current shell tool state */
! 4581: char **azArg, /* Array of arguments passed to dot command */
! 4582: int nArg /* Number of entries in azArg[] */
! 4583: ){
! 4584: int n;
! 4585: n = (nArg>=2 ? (int)strlen(azArg[1]) : 0);
! 4586: if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
! 4587: return lintFkeyIndexes(pState, azArg, nArg);
! 4588:
! 4589: usage:
! 4590: raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
! 4591: raw_printf(stderr, "Where sub-commands are:\n");
! 4592: raw_printf(stderr, " fkey-indexes\n");
! 4593: return SQLITE_ERROR;
! 4594: }
! 4595:
! 4596:
! 4597: /*
1.2 misho 4598: ** If an input line begins with "." then invoke this routine to
4599: ** process that line.
4600: **
4601: ** Return 1 on error, 2 to exit, and 0 otherwise.
4602: */
1.4 misho 4603: static int do_meta_command(char *zLine, ShellState *p){
4604: int h = 1;
1.2 misho 4605: int nArg = 0;
4606: int n, c;
4607: int rc = 0;
4608: char *azArg[50];
4609:
4610: /* Parse the input line into tokens.
4611: */
1.4 misho 4612: while( zLine[h] && nArg<ArraySize(azArg) ){
4613: while( IsSpace(zLine[h]) ){ h++; }
4614: if( zLine[h]==0 ) break;
4615: if( zLine[h]=='\'' || zLine[h]=='"' ){
4616: int delim = zLine[h++];
4617: azArg[nArg++] = &zLine[h];
4618: while( zLine[h] && zLine[h]!=delim ){
4619: if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
4620: h++;
4621: }
4622: if( zLine[h]==delim ){
4623: zLine[h++] = 0;
1.2 misho 4624: }
4625: if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
4626: }else{
1.4 misho 4627: azArg[nArg++] = &zLine[h];
4628: while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
4629: if( zLine[h] ) zLine[h++] = 0;
1.2 misho 4630: resolve_backslashes(azArg[nArg-1]);
4631: }
4632: }
4633:
4634: /* Process the input line.
4635: */
4636: if( nArg==0 ) return 0; /* no tokens, no error */
4637: n = strlen30(azArg[0]);
4638: c = azArg[0][0];
1.4 misho 4639:
1.4.2.1 ! misho 4640: #ifndef SQLITE_OMIT_AUTHORIZATION
1.4 misho 4641: if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
4642: if( nArg!=2 ){
4643: raw_printf(stderr, "Usage: .auth ON|OFF\n");
4644: rc = 1;
4645: goto meta_command_exit;
4646: }
4647: open_db(p, 0);
4648: if( booleanValue(azArg[1]) ){
4649: sqlite3_set_authorizer(p->db, shellAuth, p);
4650: }else{
4651: sqlite3_set_authorizer(p->db, 0, 0);
4652: }
4653: }else
1.4.2.1 ! misho 4654: #endif
1.4 misho 4655:
4656: if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
4657: || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
4658: ){
4659: const char *zDestFile = 0;
4660: const char *zDb = 0;
1.2 misho 4661: sqlite3 *pDest;
4662: sqlite3_backup *pBackup;
1.4 misho 4663: int j;
4664: for(j=1; j<nArg; j++){
4665: const char *z = azArg[j];
4666: if( z[0]=='-' ){
4667: while( z[0]=='-' ) z++;
4668: /* No options to process at this time */
4669: {
4670: utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
4671: return 1;
4672: }
4673: }else if( zDestFile==0 ){
4674: zDestFile = azArg[j];
4675: }else if( zDb==0 ){
4676: zDb = zDestFile;
4677: zDestFile = azArg[j];
4678: }else{
4679: raw_printf(stderr, "too many arguments to .backup\n");
4680: return 1;
4681: }
4682: }
4683: if( zDestFile==0 ){
4684: raw_printf(stderr, "missing FILENAME argument on .backup\n");
4685: return 1;
1.2 misho 4686: }
1.4 misho 4687: if( zDb==0 ) zDb = "main";
1.2 misho 4688: rc = sqlite3_open(zDestFile, &pDest);
4689: if( rc!=SQLITE_OK ){
1.4 misho 4690: utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
1.2 misho 4691: sqlite3_close(pDest);
4692: return 1;
4693: }
1.4 misho 4694: open_db(p, 0);
1.2 misho 4695: pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
4696: if( pBackup==0 ){
1.4 misho 4697: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1.2 misho 4698: sqlite3_close(pDest);
4699: return 1;
4700: }
4701: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
4702: sqlite3_backup_finish(pBackup);
4703: if( rc==SQLITE_DONE ){
4704: rc = 0;
4705: }else{
1.4 misho 4706: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1.2 misho 4707: rc = 1;
4708: }
4709: sqlite3_close(pDest);
4710: }else
4711:
1.4 misho 4712: if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
4713: if( nArg==2 ){
4714: bail_on_error = booleanValue(azArg[1]);
4715: }else{
4716: raw_printf(stderr, "Usage: .bail on|off\n");
4717: rc = 1;
4718: }
4719: }else
4720:
4721: if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
4722: if( nArg==2 ){
4723: if( booleanValue(azArg[1]) ){
4724: setBinaryMode(p->out, 1);
4725: }else{
4726: setTextMode(p->out, 1);
4727: }
4728: }else{
4729: raw_printf(stderr, "Usage: .binary on|off\n");
4730: rc = 1;
4731: }
1.2 misho 4732: }else
4733:
1.3 misho 4734: /* The undocumented ".breakpoint" command causes a call to the no-op
4735: ** routine named test_breakpoint().
4736: */
4737: if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
4738: test_breakpoint();
4739: }else
4740:
1.4 misho 4741: if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
4742: if( nArg==2 ){
1.4.2.1 ! misho 4743: setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
1.4 misho 4744: }else{
4745: raw_printf(stderr, "Usage: .changes on|off\n");
4746: rc = 1;
4747: }
4748: }else
4749:
1.4.2.1 ! misho 4750: /* Cancel output redirection, if it is currently set (by .testcase)
! 4751: ** Then read the content of the testcase-out.txt file and compare against
! 4752: ** azArg[1]. If there are differences, report an error and exit.
! 4753: */
! 4754: if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
! 4755: char *zRes = 0;
! 4756: output_reset(p);
! 4757: if( nArg!=2 ){
! 4758: raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
! 4759: rc = 2;
! 4760: }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
! 4761: raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
! 4762: rc = 2;
! 4763: }else if( testcase_glob(azArg[1],zRes)==0 ){
! 4764: utf8_printf(stderr,
! 4765: "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
! 4766: p->zTestcase, azArg[1], zRes);
! 4767: rc = 2;
! 4768: }else{
! 4769: utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
! 4770: p->nCheck++;
! 4771: }
! 4772: sqlite3_free(zRes);
! 4773: }else
! 4774:
1.4 misho 4775: if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
4776: if( nArg==2 ){
4777: tryToClone(p, azArg[1]);
4778: }else{
4779: raw_printf(stderr, "Usage: .clone FILENAME\n");
4780: rc = 1;
4781: }
4782: }else
4783:
4784: if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
4785: ShellState data;
1.2 misho 4786: char *zErrMsg = 0;
1.4 misho 4787: open_db(p, 0);
1.2 misho 4788: memcpy(&data, p, sizeof(data));
1.4.2.1 ! misho 4789: data.showHeader = 0;
! 4790: data.cMode = data.mode = MODE_List;
! 4791: sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
1.2 misho 4792: data.cnt = 0;
1.4.2.1 ! misho 4793: sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
! 4794: callback, &data, &zErrMsg);
1.2 misho 4795: if( zErrMsg ){
1.4 misho 4796: utf8_printf(stderr,"Error: %s\n", zErrMsg);
1.2 misho 4797: sqlite3_free(zErrMsg);
4798: rc = 1;
4799: }
4800: }else
4801:
1.4 misho 4802: if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
4803: rc = shell_dbinfo_command(p, nArg, azArg);
4804: }else
4805:
4806: if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1.4.2.1 ! misho 4807: const char *zLike = 0;
! 4808: int i;
! 4809: int savedShowHeader = p->showHeader;
! 4810: ShellClearFlag(p, SHFLG_PreserveRowid);
! 4811: for(i=1; i<nArg; i++){
! 4812: if( azArg[i][0]=='-' ){
! 4813: const char *z = azArg[i]+1;
! 4814: if( z[0]=='-' ) z++;
! 4815: if( strcmp(z,"preserve-rowids")==0 ){
! 4816: #ifdef SQLITE_OMIT_VIRTUALTABLE
! 4817: raw_printf(stderr, "The --preserve-rowids option is not compatible"
! 4818: " with SQLITE_OMIT_VIRTUALTABLE\n");
! 4819: rc = 1;
! 4820: goto meta_command_exit;
! 4821: #else
! 4822: ShellSetFlag(p, SHFLG_PreserveRowid);
! 4823: #endif
! 4824: }else
! 4825: {
! 4826: raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
! 4827: rc = 1;
! 4828: goto meta_command_exit;
! 4829: }
! 4830: }else if( zLike ){
! 4831: raw_printf(stderr, "Usage: .dump ?--preserve-rowids? ?LIKE-PATTERN?\n");
! 4832: rc = 1;
! 4833: goto meta_command_exit;
! 4834: }else{
! 4835: zLike = azArg[i];
! 4836: }
! 4837: }
1.4 misho 4838: open_db(p, 0);
1.2 misho 4839: /* When playing back a "dump", the content might appear in an order
4840: ** which causes immediate foreign key constraints to be violated.
4841: ** So disable foreign-key constraint enforcement to prevent problems. */
1.4 misho 4842: raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
4843: raw_printf(p->out, "BEGIN TRANSACTION;\n");
1.2 misho 4844: p->writableSchema = 0;
1.4.2.1 ! misho 4845: p->showHeader = 0;
! 4846: /* Set writable_schema=ON since doing so forces SQLite to initialize
! 4847: ** as much of the schema as it can even if the sqlite_master table is
! 4848: ** corrupt. */
1.2 misho 4849: sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
4850: p->nErr = 0;
1.4.2.1 ! misho 4851: if( zLike==0 ){
1.4 misho 4852: run_schema_dump_query(p,
1.2 misho 4853: "SELECT name, type, sql FROM sqlite_master "
4854: "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
4855: );
1.4 misho 4856: run_schema_dump_query(p,
1.2 misho 4857: "SELECT name, type, sql FROM sqlite_master "
4858: "WHERE name=='sqlite_sequence'"
4859: );
4860: run_table_dump_query(p,
4861: "SELECT sql FROM sqlite_master "
4862: "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
4863: );
4864: }else{
1.4.2.1 ! misho 4865: char *zSql;
! 4866: zSql = sqlite3_mprintf(
! 4867: "SELECT name, type, sql FROM sqlite_master "
! 4868: "WHERE tbl_name LIKE %Q AND type=='table'"
! 4869: " AND sql NOT NULL", zLike);
! 4870: run_schema_dump_query(p,zSql);
! 4871: sqlite3_free(zSql);
! 4872: zSql = sqlite3_mprintf(
! 4873: "SELECT sql FROM sqlite_master "
! 4874: "WHERE sql NOT NULL"
! 4875: " AND type IN ('index','trigger','view')"
! 4876: " AND tbl_name LIKE %Q", zLike);
! 4877: run_table_dump_query(p, zSql, 0);
! 4878: sqlite3_free(zSql);
1.2 misho 4879: }
4880: if( p->writableSchema ){
1.4 misho 4881: raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
1.2 misho 4882: p->writableSchema = 0;
4883: }
4884: sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
4885: sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
1.4 misho 4886: raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
1.4.2.1 ! misho 4887: p->showHeader = savedShowHeader;
1.4 misho 4888: }else
4889:
4890: if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
4891: if( nArg==2 ){
1.4.2.1 ! misho 4892: setOrClearFlag(p, SHFLG_Echo, azArg[1]);
1.4 misho 4893: }else{
4894: raw_printf(stderr, "Usage: .echo on|off\n");
4895: rc = 1;
4896: }
1.2 misho 4897: }else
4898:
1.4 misho 4899: if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
4900: if( nArg==2 ){
4901: if( strcmp(azArg[1],"full")==0 ){
4902: p->autoEQP = 2;
4903: }else{
4904: p->autoEQP = booleanValue(azArg[1]);
4905: }
4906: }else{
4907: raw_printf(stderr, "Usage: .eqp on|off|full\n");
4908: rc = 1;
4909: }
1.2 misho 4910: }else
4911:
1.4 misho 4912: if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
4913: if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
1.2 misho 4914: rc = 2;
4915: }else
4916:
1.4 misho 4917: if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
4918: int val = 1;
4919: if( nArg>=2 ){
4920: if( strcmp(azArg[1],"auto")==0 ){
4921: val = 99;
4922: }else{
4923: val = booleanValue(azArg[1]);
4924: }
4925: }
4926: if( val==1 && p->mode!=MODE_Explain ){
4927: p->normalMode = p->mode;
1.2 misho 4928: p->mode = MODE_Explain;
1.4 misho 4929: p->autoExplain = 0;
4930: }else if( val==0 ){
4931: if( p->mode==MODE_Explain ) p->mode = p->normalMode;
4932: p->autoExplain = 0;
4933: }else if( val==99 ){
4934: if( p->mode==MODE_Explain ) p->mode = p->normalMode;
4935: p->autoExplain = 1;
4936: }
4937: }else
4938:
4939: if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
4940: ShellState data;
4941: char *zErrMsg = 0;
4942: int doStats = 0;
4943: memcpy(&data, p, sizeof(data));
4944: data.showHeader = 0;
4945: data.cMode = data.mode = MODE_Semi;
4946: if( nArg==2 && optionMatch(azArg[1], "indent") ){
4947: data.cMode = data.mode = MODE_Pretty;
4948: nArg = 1;
4949: }
4950: if( nArg!=1 ){
4951: raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
4952: rc = 1;
4953: goto meta_command_exit;
4954: }
4955: open_db(p, 0);
4956: rc = sqlite3_exec(p->db,
4957: "SELECT sql FROM"
4958: " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
4959: " FROM sqlite_master UNION ALL"
4960: " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
4961: "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
4962: "ORDER BY rowid",
4963: callback, &data, &zErrMsg
4964: );
4965: if( rc==SQLITE_OK ){
4966: sqlite3_stmt *pStmt;
4967: rc = sqlite3_prepare_v2(p->db,
4968: "SELECT rowid FROM sqlite_master"
4969: " WHERE name GLOB 'sqlite_stat[134]'",
4970: -1, &pStmt, 0);
4971: doStats = sqlite3_step(pStmt)==SQLITE_ROW;
4972: sqlite3_finalize(pStmt);
4973: }
4974: if( doStats==0 ){
4975: raw_printf(p->out, "/* No STAT tables available */\n");
4976: }else{
4977: raw_printf(p->out, "ANALYZE sqlite_master;\n");
4978: sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
4979: callback, &data, &zErrMsg);
4980: data.cMode = data.mode = MODE_Insert;
4981: data.zDestTable = "sqlite_stat1";
4982: shell_exec(p->db, "SELECT * FROM sqlite_stat1",
4983: shell_callback, &data,&zErrMsg);
4984: data.zDestTable = "sqlite_stat3";
4985: shell_exec(p->db, "SELECT * FROM sqlite_stat3",
4986: shell_callback, &data,&zErrMsg);
4987: data.zDestTable = "sqlite_stat4";
4988: shell_exec(p->db, "SELECT * FROM sqlite_stat4",
4989: shell_callback, &data, &zErrMsg);
4990: raw_printf(p->out, "ANALYZE sqlite_master;\n");
1.2 misho 4991: }
4992: }else
4993:
1.4 misho 4994: if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
4995: if( nArg==2 ){
4996: p->showHeader = booleanValue(azArg[1]);
4997: }else{
4998: raw_printf(stderr, "Usage: .headers on|off\n");
4999: rc = 1;
5000: }
1.2 misho 5001: }else
5002:
5003: if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1.4 misho 5004: utf8_printf(p->out, "%s", zHelp);
1.2 misho 5005: }else
5006:
1.4 misho 5007: if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
5008: char *zTable; /* Insert data into this table */
5009: char *zFile; /* Name of file to extra content from */
1.2 misho 5010: sqlite3_stmt *pStmt = NULL; /* A statement */
5011: int nCol; /* Number of columns in the table */
5012: int nByte; /* Number of bytes in an SQL string */
5013: int i, j; /* Loop counters */
1.4 misho 5014: int needCommit; /* True to COMMIT or ROLLBACK at end */
5015: int nSep; /* Number of bytes in p->colSeparator[] */
1.2 misho 5016: char *zSql; /* An SQL statement */
1.4 misho 5017: ImportCtx sCtx; /* Reader context */
5018: char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
5019: int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
5020:
5021: if( nArg!=3 ){
5022: raw_printf(stderr, "Usage: .import FILE TABLE\n");
5023: goto meta_command_exit;
5024: }
5025: zFile = azArg[1];
5026: zTable = azArg[2];
5027: seenInterrupt = 0;
5028: memset(&sCtx, 0, sizeof(sCtx));
5029: open_db(p, 0);
5030: nSep = strlen30(p->colSeparator);
5031: if( nSep==0 ){
5032: raw_printf(stderr,
5033: "Error: non-null column separator required for import\n");
5034: return 1;
5035: }
5036: if( nSep>1 ){
5037: raw_printf(stderr, "Error: multi-character column separators not allowed"
5038: " for import\n");
5039: return 1;
5040: }
5041: nSep = strlen30(p->rowSeparator);
1.2 misho 5042: if( nSep==0 ){
1.4 misho 5043: raw_printf(stderr, "Error: non-null row separator required for import\n");
1.2 misho 5044: return 1;
5045: }
1.4 misho 5046: if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
5047: /* When importing CSV (only), if the row separator is set to the
5048: ** default output row separator, change it to the default input
5049: ** row separator. This avoids having to maintain different input
5050: ** and output row separators. */
5051: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
5052: nSep = strlen30(p->rowSeparator);
5053: }
5054: if( nSep>1 ){
5055: raw_printf(stderr, "Error: multi-character row separators not allowed"
5056: " for import\n");
5057: return 1;
5058: }
5059: sCtx.zFile = zFile;
5060: sCtx.nLine = 1;
5061: if( sCtx.zFile[0]=='|' ){
5062: #ifdef SQLITE_OMIT_POPEN
5063: raw_printf(stderr, "Error: pipes are not supported in this OS\n");
5064: return 1;
5065: #else
5066: sCtx.in = popen(sCtx.zFile+1, "r");
5067: sCtx.zFile = "<pipe>";
5068: xCloser = pclose;
5069: #endif
5070: }else{
5071: sCtx.in = fopen(sCtx.zFile, "rb");
5072: xCloser = fclose;
5073: }
5074: if( p->mode==MODE_Ascii ){
5075: xRead = ascii_read_one_field;
5076: }else{
5077: xRead = csv_read_one_field;
5078: }
5079: if( sCtx.in==0 ){
5080: utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
5081: return 1;
5082: }
5083: sCtx.cColSep = p->colSeparator[0];
5084: sCtx.cRowSep = p->rowSeparator[0];
1.2 misho 5085: zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
5086: if( zSql==0 ){
1.4 misho 5087: raw_printf(stderr, "Error: out of memory\n");
5088: xCloser(sCtx.in);
1.2 misho 5089: return 1;
5090: }
5091: nByte = strlen30(zSql);
1.4 misho 5092: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
5093: import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
5094: if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
5095: char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
5096: char cSep = '(';
5097: while( xRead(&sCtx) ){
5098: zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
5099: cSep = ',';
5100: if( sCtx.cTerm!=sCtx.cColSep ) break;
5101: }
5102: if( cSep=='(' ){
5103: sqlite3_free(zCreate);
5104: sqlite3_free(sCtx.z);
5105: xCloser(sCtx.in);
5106: utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
5107: return 1;
5108: }
5109: zCreate = sqlite3_mprintf("%z\n)", zCreate);
5110: rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
5111: sqlite3_free(zCreate);
5112: if( rc ){
5113: utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
5114: sqlite3_errmsg(p->db));
5115: sqlite3_free(sCtx.z);
5116: xCloser(sCtx.in);
5117: return 1;
5118: }
5119: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
5120: }
1.2 misho 5121: sqlite3_free(zSql);
5122: if( rc ){
5123: if (pStmt) sqlite3_finalize(pStmt);
1.4 misho 5124: utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
5125: xCloser(sCtx.in);
1.2 misho 5126: return 1;
5127: }
5128: nCol = sqlite3_column_count(pStmt);
5129: sqlite3_finalize(pStmt);
5130: pStmt = 0;
5131: if( nCol==0 ) return 0; /* no columns, no error */
1.4 misho 5132: zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
1.2 misho 5133: if( zSql==0 ){
1.4 misho 5134: raw_printf(stderr, "Error: out of memory\n");
5135: xCloser(sCtx.in);
1.2 misho 5136: return 1;
5137: }
1.4 misho 5138: sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
1.2 misho 5139: j = strlen30(zSql);
5140: for(i=1; i<nCol; i++){
5141: zSql[j++] = ',';
5142: zSql[j++] = '?';
5143: }
5144: zSql[j++] = ')';
5145: zSql[j] = 0;
1.4 misho 5146: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
5147: sqlite3_free(zSql);
1.2 misho 5148: if( rc ){
1.4 misho 5149: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1.2 misho 5150: if (pStmt) sqlite3_finalize(pStmt);
1.4 misho 5151: xCloser(sCtx.in);
1.2 misho 5152: return 1;
5153: }
1.4 misho 5154: needCommit = sqlite3_get_autocommit(p->db);
5155: if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
5156: do{
5157: int startLine = sCtx.nLine;
5158: for(i=0; i<nCol; i++){
5159: char *z = xRead(&sCtx);
5160: /*
5161: ** Did we reach end-of-file before finding any columns?
5162: ** If so, stop instead of NULL filling the remaining columns.
5163: */
5164: if( z==0 && i==0 ) break;
5165: /*
5166: ** Did we reach end-of-file OR end-of-line before finding any
5167: ** columns in ASCII mode? If so, stop instead of NULL filling
5168: ** the remaining columns.
5169: */
5170: if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
5171: sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
5172: if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
5173: utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
5174: "filling the rest with NULL\n",
5175: sCtx.zFile, startLine, nCol, i+1);
5176: i += 2;
5177: while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
5178: }
5179: }
5180: if( sCtx.cTerm==sCtx.cColSep ){
5181: do{
5182: xRead(&sCtx);
1.2 misho 5183: i++;
1.4 misho 5184: }while( sCtx.cTerm==sCtx.cColSep );
5185: utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
5186: "extras ignored\n",
5187: sCtx.zFile, startLine, nCol, i);
5188: }
5189: if( i>=nCol ){
5190: sqlite3_step(pStmt);
5191: rc = sqlite3_reset(pStmt);
5192: if( rc!=SQLITE_OK ){
5193: utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
5194: startLine, sqlite3_errmsg(p->db));
1.2 misho 5195: }
5196: }
1.4 misho 5197: }while( sCtx.cTerm!=EOF );
5198:
5199: xCloser(sCtx.in);
5200: sqlite3_free(sCtx.z);
1.2 misho 5201: sqlite3_finalize(pStmt);
1.4 misho 5202: if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
1.2 misho 5203: }else
5204:
1.4.2.1 ! misho 5205: #ifndef SQLITE_UNTESTABLE
! 5206: if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
! 5207: char *zSql;
! 5208: char *zCollist = 0;
! 5209: sqlite3_stmt *pStmt;
! 5210: int tnum = 0;
! 5211: int i;
! 5212: if( nArg!=3 ){
! 5213: utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n");
1.4 misho 5214: rc = 1;
5215: goto meta_command_exit;
1.2 misho 5216: }
1.4.2.1 ! misho 5217: open_db(p, 0);
! 5218: zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
! 5219: " WHERE name='%q' AND type='index'", azArg[1]);
! 5220: sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
! 5221: sqlite3_free(zSql);
! 5222: if( sqlite3_step(pStmt)==SQLITE_ROW ){
! 5223: tnum = sqlite3_column_int(pStmt, 0);
! 5224: }
! 5225: sqlite3_finalize(pStmt);
! 5226: if( tnum==0 ){
! 5227: utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
1.2 misho 5228: rc = 1;
1.4.2.1 ! misho 5229: goto meta_command_exit;
! 5230: }
! 5231: zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
! 5232: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
! 5233: sqlite3_free(zSql);
! 5234: i = 0;
! 5235: while( sqlite3_step(pStmt)==SQLITE_ROW ){
! 5236: char zLabel[20];
! 5237: const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
! 5238: i++;
! 5239: if( zCol==0 ){
! 5240: if( sqlite3_column_int(pStmt,1)==-1 ){
! 5241: zCol = "_ROWID_";
! 5242: }else{
! 5243: sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
! 5244: zCol = zLabel;
! 5245: }
! 5246: }
! 5247: if( zCollist==0 ){
! 5248: zCollist = sqlite3_mprintf("\"%w\"", zCol);
! 5249: }else{
! 5250: zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
! 5251: }
! 5252: }
! 5253: sqlite3_finalize(pStmt);
! 5254: zSql = sqlite3_mprintf(
! 5255: "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
! 5256: azArg[2], zCollist, zCollist);
! 5257: sqlite3_free(zCollist);
! 5258: rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
! 5259: if( rc==SQLITE_OK ){
! 5260: rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
! 5261: sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
! 5262: if( rc ){
! 5263: utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
! 5264: }else{
! 5265: utf8_printf(stdout, "%s;\n", zSql);
! 5266: raw_printf(stdout,
! 5267: "WARNING: writing to an imposter table will corrupt the index!\n"
! 5268: );
! 5269: }
! 5270: }else{
! 5271: raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
1.2 misho 5272: rc = 1;
5273: }
1.4.2.1 ! misho 5274: sqlite3_free(zSql);
1.2 misho 5275: }else
1.4.2.1 ! misho 5276: #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
1.2 misho 5277:
5278: #ifdef SQLITE_ENABLE_IOTRACE
5279: if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
1.4 misho 5280: SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
1.2 misho 5281: if( iotrace && iotrace!=stdout ) fclose(iotrace);
5282: iotrace = 0;
5283: if( nArg<2 ){
5284: sqlite3IoTrace = 0;
5285: }else if( strcmp(azArg[1], "-")==0 ){
5286: sqlite3IoTrace = iotracePrintf;
5287: iotrace = stdout;
1.4 misho 5288: }else{
5289: iotrace = fopen(azArg[1], "w");
5290: if( iotrace==0 ){
5291: utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
5292: sqlite3IoTrace = 0;
5293: rc = 1;
5294: }else{
5295: sqlite3IoTrace = iotracePrintf;
5296: }
5297: }
5298: }else
5299: #endif
1.4.2.1 ! misho 5300:
1.4 misho 5301: if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
5302: static const struct {
5303: const char *zLimitName; /* Name of a limit */
5304: int limitCode; /* Integer code for that limit */
5305: } aLimit[] = {
5306: { "length", SQLITE_LIMIT_LENGTH },
5307: { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
5308: { "column", SQLITE_LIMIT_COLUMN },
5309: { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
5310: { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
5311: { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
5312: { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
5313: { "attached", SQLITE_LIMIT_ATTACHED },
5314: { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
5315: { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
5316: { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
5317: { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
5318: };
5319: int i, n2;
5320: open_db(p, 0);
5321: if( nArg==1 ){
5322: for(i=0; i<ArraySize(aLimit); i++){
5323: printf("%20s %d\n", aLimit[i].zLimitName,
5324: sqlite3_limit(p->db, aLimit[i].limitCode, -1));
5325: }
5326: }else if( nArg>3 ){
5327: raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
5328: rc = 1;
5329: goto meta_command_exit;
5330: }else{
5331: int iLimit = -1;
5332: n2 = strlen30(azArg[1]);
5333: for(i=0; i<ArraySize(aLimit); i++){
5334: if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
5335: if( iLimit<0 ){
5336: iLimit = i;
5337: }else{
5338: utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
5339: rc = 1;
5340: goto meta_command_exit;
5341: }
5342: }
5343: }
5344: if( iLimit<0 ){
5345: utf8_printf(stderr, "unknown limit: \"%s\"\n"
5346: "enter \".limits\" with no arguments for a list.\n",
5347: azArg[1]);
1.2 misho 5348: rc = 1;
1.4 misho 5349: goto meta_command_exit;
5350: }
5351: if( nArg==3 ){
5352: sqlite3_limit(p->db, aLimit[iLimit].limitCode,
5353: (int)integerValue(azArg[2]));
1.2 misho 5354: }
1.4 misho 5355: printf("%20s %d\n", aLimit[iLimit].zLimitName,
5356: sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
1.2 misho 5357: }
5358: }else
5359:
1.4.2.1 ! misho 5360: if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
! 5361: open_db(p, 0);
! 5362: lintDotCommand(p, azArg, nArg);
! 5363: }else
! 5364:
1.2 misho 5365: #ifndef SQLITE_OMIT_LOAD_EXTENSION
1.4 misho 5366: if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
1.2 misho 5367: const char *zFile, *zProc;
5368: char *zErrMsg = 0;
1.4 misho 5369: if( nArg<2 ){
5370: raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
5371: rc = 1;
5372: goto meta_command_exit;
5373: }
1.2 misho 5374: zFile = azArg[1];
5375: zProc = nArg>=3 ? azArg[2] : 0;
1.4 misho 5376: open_db(p, 0);
1.2 misho 5377: rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
5378: if( rc!=SQLITE_OK ){
1.4 misho 5379: utf8_printf(stderr, "Error: %s\n", zErrMsg);
1.2 misho 5380: sqlite3_free(zErrMsg);
5381: rc = 1;
5382: }
5383: }else
5384: #endif
5385:
1.4 misho 5386: if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
5387: if( nArg!=2 ){
5388: raw_printf(stderr, "Usage: .log FILENAME\n");
5389: rc = 1;
5390: }else{
5391: const char *zFile = azArg[1];
5392: output_file_close(p->pLog);
5393: p->pLog = output_file_open(zFile);
5394: }
1.2 misho 5395: }else
5396:
1.4 misho 5397: if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
5398: const char *zMode = nArg>=2 ? azArg[1] : "";
5399: int n2 = (int)strlen(zMode);
5400: int c2 = zMode[0];
5401: if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
1.2 misho 5402: p->mode = MODE_Line;
1.4.2.1 ! misho 5403: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 5404: }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
1.2 misho 5405: p->mode = MODE_Column;
1.4.2.1 ! misho 5406: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 5407: }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
1.2 misho 5408: p->mode = MODE_List;
1.4.2.1 ! misho 5409: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
! 5410: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 5411: }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
1.2 misho 5412: p->mode = MODE_Html;
1.4 misho 5413: }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
1.2 misho 5414: p->mode = MODE_Tcl;
1.4 misho 5415: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
1.4.2.1 ! misho 5416: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 5417: }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
1.2 misho 5418: p->mode = MODE_Csv;
1.4 misho 5419: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
5420: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
5421: }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
1.2 misho 5422: p->mode = MODE_List;
1.4 misho 5423: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
5424: }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
1.2 misho 5425: p->mode = MODE_Insert;
1.4 misho 5426: set_table_name(p, nArg>=3 ? azArg[2] : "table");
1.4.2.1 ! misho 5427: }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
! 5428: p->mode = MODE_Quote;
1.4 misho 5429: }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
5430: p->mode = MODE_Ascii;
5431: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
5432: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
1.2 misho 5433: }else {
1.4 misho 5434: raw_printf(stderr, "Error: mode should be one of: "
1.4.2.1 ! misho 5435: "ascii column csv html insert line list quote tabs tcl\n");
1.2 misho 5436: rc = 1;
5437: }
1.4 misho 5438: p->cMode = p->mode;
1.2 misho 5439: }else
5440:
1.4 misho 5441: if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
5442: if( nArg==2 ){
5443: sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
5444: "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
5445: }else{
5446: raw_printf(stderr, "Usage: .nullvalue STRING\n");
1.2 misho 5447: rc = 1;
5448: }
5449: }else
5450:
1.4 misho 5451: if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
1.4.2.1 ! misho 5452: char *zNewFilename; /* Name of the database file to open */
! 5453: int iName = 1; /* Index in azArg[] of the filename */
! 5454: int newFlag = 0; /* True to delete file before opening */
! 5455: /* Close the existing database */
! 5456: session_close_all(p);
! 5457: sqlite3_close(p->db);
1.4 misho 5458: p->db = 0;
1.4.2.1 ! misho 5459: p->zDbFilename = 0;
! 5460: sqlite3_free(p->zFreeOnClose);
! 5461: p->zFreeOnClose = 0;
! 5462: /* Check for command-line arguments */
! 5463: for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
! 5464: const char *z = azArg[iName];
! 5465: if( optionMatch(z,"new") ){
! 5466: newFlag = 1;
! 5467: }else if( z[0]=='-' ){
! 5468: utf8_printf(stderr, "unknown option: %s\n", z);
! 5469: rc = 1;
! 5470: goto meta_command_exit;
! 5471: }
! 5472: }
! 5473: /* If a filename is specified, try to open it first */
! 5474: zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
! 5475: if( zNewFilename ){
! 5476: if( newFlag ) shellDeleteFile(zNewFilename);
! 5477: p->zDbFilename = zNewFilename;
! 5478: open_db(p, 1);
! 5479: if( p->db==0 ){
! 5480: utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
! 5481: sqlite3_free(zNewFilename);
! 5482: }else{
! 5483: p->zFreeOnClose = zNewFilename;
! 5484: }
! 5485: }
! 5486: if( p->db==0 ){
! 5487: /* As a fall-back open a TEMP database */
! 5488: p->zDbFilename = 0;
! 5489: open_db(p, 0);
1.4 misho 5490: }
1.2 misho 5491: }else
5492:
1.4 misho 5493: if( c=='o'
5494: && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
5495: ){
5496: const char *zFile = nArg>=2 ? azArg[1] : "stdout";
5497: if( nArg>2 ){
5498: utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
5499: rc = 1;
5500: goto meta_command_exit;
5501: }
5502: if( n>1 && strncmp(azArg[0], "once", n)==0 ){
5503: if( nArg<2 ){
5504: raw_printf(stderr, "Usage: .once FILE\n");
5505: rc = 1;
5506: goto meta_command_exit;
5507: }
5508: p->outCount = 2;
1.3 misho 5509: }else{
1.4 misho 5510: p->outCount = 0;
1.2 misho 5511: }
1.4 misho 5512: output_reset(p);
5513: if( zFile[0]=='|' ){
5514: #ifdef SQLITE_OMIT_POPEN
5515: raw_printf(stderr, "Error: pipes are not supported in this OS\n");
5516: rc = 1;
5517: p->out = stdout;
5518: #else
5519: p->out = popen(zFile + 1, "w");
1.3 misho 5520: if( p->out==0 ){
1.4 misho 5521: utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
1.3 misho 5522: p->out = stdout;
5523: rc = 1;
5524: }else{
1.4 misho 5525: sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
1.3 misho 5526: }
1.4 misho 5527: #endif
1.2 misho 5528: }else{
1.4 misho 5529: p->out = output_file_open(zFile);
1.2 misho 5530: if( p->out==0 ){
1.4 misho 5531: if( strcmp(zFile,"off")!=0 ){
5532: utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
1.3 misho 5533: }
1.2 misho 5534: p->out = stdout;
5535: rc = 1;
5536: } else {
1.4 misho 5537: sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
1.2 misho 5538: }
5539: }
5540: }else
5541:
1.3 misho 5542: if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
5543: int i;
5544: for(i=1; i<nArg; i++){
1.4 misho 5545: if( i>1 ) raw_printf(p->out, " ");
5546: utf8_printf(p->out, "%s", azArg[i]);
1.3 misho 5547: }
1.4 misho 5548: raw_printf(p->out, "\n");
1.3 misho 5549: }else
5550:
1.4 misho 5551: if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
1.2 misho 5552: if( nArg >= 2) {
5553: strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
5554: }
5555: if( nArg >= 3) {
5556: strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
5557: }
5558: }else
5559:
1.4 misho 5560: if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
1.2 misho 5561: rc = 2;
5562: }else
5563:
1.4 misho 5564: if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
5565: FILE *alt;
5566: if( nArg!=2 ){
5567: raw_printf(stderr, "Usage: .read FILE\n");
5568: rc = 1;
5569: goto meta_command_exit;
5570: }
5571: alt = fopen(azArg[1], "rb");
1.2 misho 5572: if( alt==0 ){
1.4 misho 5573: utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1.2 misho 5574: rc = 1;
5575: }else{
5576: rc = process_input(p, alt);
5577: fclose(alt);
5578: }
5579: }else
5580:
1.4 misho 5581: if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
1.2 misho 5582: const char *zSrcFile;
5583: const char *zDb;
5584: sqlite3 *pSrc;
5585: sqlite3_backup *pBackup;
5586: int nTimeout = 0;
5587:
5588: if( nArg==2 ){
5589: zSrcFile = azArg[1];
5590: zDb = "main";
1.4 misho 5591: }else if( nArg==3 ){
1.2 misho 5592: zSrcFile = azArg[2];
5593: zDb = azArg[1];
1.4 misho 5594: }else{
5595: raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
5596: rc = 1;
5597: goto meta_command_exit;
1.2 misho 5598: }
5599: rc = sqlite3_open(zSrcFile, &pSrc);
5600: if( rc!=SQLITE_OK ){
1.4 misho 5601: utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
1.2 misho 5602: sqlite3_close(pSrc);
5603: return 1;
5604: }
1.4 misho 5605: open_db(p, 0);
1.2 misho 5606: pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
5607: if( pBackup==0 ){
1.4 misho 5608: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1.2 misho 5609: sqlite3_close(pSrc);
5610: return 1;
5611: }
5612: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
5613: || rc==SQLITE_BUSY ){
5614: if( rc==SQLITE_BUSY ){
5615: if( nTimeout++ >= 3 ) break;
5616: sqlite3_sleep(100);
5617: }
5618: }
5619: sqlite3_backup_finish(pBackup);
5620: if( rc==SQLITE_DONE ){
5621: rc = 0;
5622: }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
1.4 misho 5623: raw_printf(stderr, "Error: source database is busy\n");
1.2 misho 5624: rc = 1;
5625: }else{
1.4 misho 5626: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1.2 misho 5627: rc = 1;
5628: }
5629: sqlite3_close(pSrc);
5630: }else
5631:
1.4 misho 5632:
5633: if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
5634: if( nArg==2 ){
5635: p->scanstatsOn = booleanValue(azArg[1]);
5636: #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
5637: raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
5638: #endif
5639: }else{
5640: raw_printf(stderr, "Usage: .scanstats on|off\n");
5641: rc = 1;
5642: }
5643: }else
5644:
5645: if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
5646: ShellState data;
1.2 misho 5647: char *zErrMsg = 0;
1.4 misho 5648: open_db(p, 0);
1.2 misho 5649: memcpy(&data, p, sizeof(data));
5650: data.showHeader = 0;
1.4 misho 5651: data.cMode = data.mode = MODE_Semi;
5652: if( nArg>=2 && optionMatch(azArg[1], "indent") ){
5653: data.cMode = data.mode = MODE_Pretty;
5654: nArg--;
5655: if( nArg==2 ) azArg[1] = azArg[2];
5656: }
5657: if( nArg==2 && azArg[1][0]!='-' ){
1.2 misho 5658: int i;
5659: for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
5660: if( strcmp(azArg[1],"sqlite_master")==0 ){
5661: char *new_argv[2], *new_colv[2];
5662: new_argv[0] = "CREATE TABLE sqlite_master (\n"
5663: " type text,\n"
5664: " name text,\n"
5665: " tbl_name text,\n"
5666: " rootpage integer,\n"
5667: " sql text\n"
5668: ")";
5669: new_argv[1] = 0;
5670: new_colv[0] = "sql";
5671: new_colv[1] = 0;
5672: callback(&data, 1, new_argv, new_colv);
5673: rc = SQLITE_OK;
5674: }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
5675: char *new_argv[2], *new_colv[2];
5676: new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
5677: " type text,\n"
5678: " name text,\n"
5679: " tbl_name text,\n"
5680: " rootpage integer,\n"
5681: " sql text\n"
5682: ")";
5683: new_argv[1] = 0;
5684: new_colv[0] = "sql";
5685: new_colv[1] = 0;
5686: callback(&data, 1, new_argv, new_colv);
5687: rc = SQLITE_OK;
5688: }else{
1.4.2.1 ! misho 5689: char *zSql;
! 5690: zSql = sqlite3_mprintf(
1.2 misho 5691: "SELECT sql FROM "
1.3 misho 5692: " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
1.2 misho 5693: " FROM sqlite_master UNION ALL"
1.3 misho 5694: " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
1.4.2.1 ! misho 5695: "WHERE lower(tbl_name) LIKE %Q"
1.2 misho 5696: " AND type!='meta' AND sql NOTNULL "
1.4.2.1 ! misho 5697: "ORDER BY rowid", azArg[1]);
! 5698: rc = sqlite3_exec(p->db, zSql, callback, &data, &zErrMsg);
! 5699: sqlite3_free(zSql);
1.2 misho 5700: }
1.4 misho 5701: }else if( nArg==1 ){
1.2 misho 5702: rc = sqlite3_exec(p->db,
5703: "SELECT sql FROM "
1.3 misho 5704: " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
1.2 misho 5705: " FROM sqlite_master UNION ALL"
1.3 misho 5706: " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
1.4 misho 5707: "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
5708: "ORDER BY rowid",
1.2 misho 5709: callback, &data, &zErrMsg
5710: );
1.4 misho 5711: }else{
5712: raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
5713: rc = 1;
5714: goto meta_command_exit;
1.2 misho 5715: }
5716: if( zErrMsg ){
1.4 misho 5717: utf8_printf(stderr,"Error: %s\n", zErrMsg);
1.2 misho 5718: sqlite3_free(zErrMsg);
5719: rc = 1;
5720: }else if( rc != SQLITE_OK ){
1.4 misho 5721: raw_printf(stderr,"Error: querying schema information\n");
1.2 misho 5722: rc = 1;
5723: }else{
5724: rc = 0;
5725: }
5726: }else
5727:
1.4 misho 5728: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
5729: if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
1.4.2.1 ! misho 5730: sqlite3SelectTrace = (int)integerValue(azArg[1]);
1.4 misho 5731: }else
5732: #endif
5733:
5734: #if defined(SQLITE_ENABLE_SESSION)
5735: if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
5736: OpenSession *pSession = &p->aSession[0];
5737: char **azCmd = &azArg[1];
5738: int iSes = 0;
5739: int nCmd = nArg - 1;
5740: int i;
5741: if( nArg<=1 ) goto session_syntax_error;
5742: open_db(p, 0);
5743: if( nArg>=3 ){
5744: for(iSes=0; iSes<p->nSession; iSes++){
5745: if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
5746: }
5747: if( iSes<p->nSession ){
5748: pSession = &p->aSession[iSes];
5749: azCmd++;
5750: nCmd--;
5751: }else{
5752: pSession = &p->aSession[0];
5753: iSes = 0;
5754: }
5755: }
5756:
5757: /* .session attach TABLE
5758: ** Invoke the sqlite3session_attach() interface to attach a particular
5759: ** table so that it is never filtered.
5760: */
5761: if( strcmp(azCmd[0],"attach")==0 ){
5762: if( nCmd!=2 ) goto session_syntax_error;
5763: if( pSession->p==0 ){
5764: session_not_open:
5765: raw_printf(stderr, "ERROR: No sessions are open\n");
5766: }else{
5767: rc = sqlite3session_attach(pSession->p, azCmd[1]);
5768: if( rc ){
5769: raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
5770: rc = 0;
5771: }
5772: }
5773: }else
5774:
5775: /* .session changeset FILE
5776: ** .session patchset FILE
5777: ** Write a changeset or patchset into a file. The file is overwritten.
5778: */
5779: if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
5780: FILE *out = 0;
5781: if( nCmd!=2 ) goto session_syntax_error;
5782: if( pSession->p==0 ) goto session_not_open;
5783: out = fopen(azCmd[1], "wb");
5784: if( out==0 ){
5785: utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
5786: }else{
5787: int szChng;
5788: void *pChng;
5789: if( azCmd[0][0]=='c' ){
5790: rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
5791: }else{
5792: rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
5793: }
5794: if( rc ){
5795: printf("Error: error code %d\n", rc);
5796: rc = 0;
5797: }
5798: if( pChng
5799: && fwrite(pChng, szChng, 1, out)!=1 ){
5800: raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
5801: szChng);
5802: }
5803: sqlite3_free(pChng);
5804: fclose(out);
5805: }
5806: }else
5807:
5808: /* .session close
5809: ** Close the identified session
5810: */
5811: if( strcmp(azCmd[0], "close")==0 ){
5812: if( nCmd!=1 ) goto session_syntax_error;
5813: if( p->nSession ){
5814: session_close(pSession);
5815: p->aSession[iSes] = p->aSession[--p->nSession];
5816: }
5817: }else
5818:
5819: /* .session enable ?BOOLEAN?
5820: ** Query or set the enable flag
5821: */
5822: if( strcmp(azCmd[0], "enable")==0 ){
5823: int ii;
5824: if( nCmd>2 ) goto session_syntax_error;
5825: ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
5826: if( p->nSession ){
5827: ii = sqlite3session_enable(pSession->p, ii);
5828: utf8_printf(p->out, "session %s enable flag = %d\n",
5829: pSession->zName, ii);
5830: }
5831: }else
5832:
5833: /* .session filter GLOB ....
5834: ** Set a list of GLOB patterns of table names to be excluded.
5835: */
5836: if( strcmp(azCmd[0], "filter")==0 ){
5837: int ii, nByte;
5838: if( nCmd<2 ) goto session_syntax_error;
5839: if( p->nSession ){
5840: for(ii=0; ii<pSession->nFilter; ii++){
5841: sqlite3_free(pSession->azFilter[ii]);
5842: }
5843: sqlite3_free(pSession->azFilter);
5844: nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
5845: pSession->azFilter = sqlite3_malloc( nByte );
5846: if( pSession->azFilter==0 ){
5847: raw_printf(stderr, "Error: out or memory\n");
5848: exit(1);
5849: }
5850: for(ii=1; ii<nCmd; ii++){
5851: pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
5852: }
5853: pSession->nFilter = ii-1;
5854: }
5855: }else
5856:
5857: /* .session indirect ?BOOLEAN?
5858: ** Query or set the indirect flag
5859: */
5860: if( strcmp(azCmd[0], "indirect")==0 ){
5861: int ii;
5862: if( nCmd>2 ) goto session_syntax_error;
5863: ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
5864: if( p->nSession ){
5865: ii = sqlite3session_indirect(pSession->p, ii);
5866: utf8_printf(p->out, "session %s indirect flag = %d\n",
5867: pSession->zName, ii);
5868: }
5869: }else
5870:
5871: /* .session isempty
5872: ** Determine if the session is empty
5873: */
5874: if( strcmp(azCmd[0], "isempty")==0 ){
5875: int ii;
5876: if( nCmd!=1 ) goto session_syntax_error;
5877: if( p->nSession ){
5878: ii = sqlite3session_isempty(pSession->p);
5879: utf8_printf(p->out, "session %s isempty flag = %d\n",
5880: pSession->zName, ii);
5881: }
5882: }else
5883:
5884: /* .session list
5885: ** List all currently open sessions
5886: */
5887: if( strcmp(azCmd[0],"list")==0 ){
5888: for(i=0; i<p->nSession; i++){
5889: utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
5890: }
5891: }else
5892:
5893: /* .session open DB NAME
5894: ** Open a new session called NAME on the attached database DB.
5895: ** DB is normally "main".
5896: */
5897: if( strcmp(azCmd[0],"open")==0 ){
5898: char *zName;
5899: if( nCmd!=3 ) goto session_syntax_error;
5900: zName = azCmd[2];
5901: if( zName[0]==0 ) goto session_syntax_error;
5902: for(i=0; i<p->nSession; i++){
5903: if( strcmp(p->aSession[i].zName,zName)==0 ){
5904: utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
5905: goto meta_command_exit;
5906: }
5907: }
5908: if( p->nSession>=ArraySize(p->aSession) ){
5909: raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
5910: goto meta_command_exit;
5911: }
5912: pSession = &p->aSession[p->nSession];
5913: rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
5914: if( rc ){
5915: raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
5916: rc = 0;
5917: goto meta_command_exit;
5918: }
5919: pSession->nFilter = 0;
5920: sqlite3session_table_filter(pSession->p, session_filter, pSession);
5921: p->nSession++;
5922: pSession->zName = sqlite3_mprintf("%s", zName);
5923: }else
5924: /* If no command name matches, show a syntax error */
5925: session_syntax_error:
5926: session_help(p);
5927: }else
5928: #endif
5929:
5930: #ifdef SQLITE_DEBUG
5931: /* Undocumented commands for internal testing. Subject to change
5932: ** without notice. */
5933: if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
5934: if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
5935: int i, v;
5936: for(i=1; i<nArg; i++){
5937: v = booleanValue(azArg[i]);
5938: utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
5939: }
5940: }
5941: if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
5942: int i; sqlite3_int64 v;
5943: for(i=1; i<nArg; i++){
5944: char zBuf[200];
5945: v = integerValue(azArg[i]);
5946: sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
5947: utf8_printf(p->out, "%s", zBuf);
5948: }
5949: }
5950: }else
5951: #endif
5952:
1.4.2.1 ! misho 5953: if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){
! 5954: int bIsInit = 0; /* True to initialize the SELFTEST table */
! 5955: int bVerbose = 0; /* Verbose output */
! 5956: int bSelftestExists; /* True if SELFTEST already exists */
! 5957: char **azTest = 0; /* Content of the SELFTEST table */
! 5958: int nRow = 0; /* Number of rows in the SELFTEST table */
! 5959: int nCol = 4; /* Number of columns in the SELFTEST table */
! 5960: int i; /* Loop counter */
! 5961: int nTest = 0; /* Number of tests runs */
! 5962: int nErr = 0; /* Number of errors seen */
! 5963: ShellText str; /* Answer for a query */
! 5964: static char *azDefaultTest[] = {
! 5965: 0, 0, 0, 0,
! 5966: "0", "memo", "Missing SELFTEST table - default checks only", "",
! 5967: "1", "run", "PRAGMA integrity_check", "ok"
! 5968: };
! 5969: static const int nDefaultRow = 2;
! 5970:
! 5971: open_db(p,0);
! 5972: for(i=1; i<nArg; i++){
! 5973: const char *z = azArg[i];
! 5974: if( z[0]=='-' && z[1]=='-' ) z++;
! 5975: if( strcmp(z,"-init")==0 ){
! 5976: bIsInit = 1;
! 5977: }else
! 5978: if( strcmp(z,"-v")==0 ){
! 5979: bVerbose++;
! 5980: }else
! 5981: {
! 5982: utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
! 5983: azArg[i], azArg[0]);
! 5984: raw_printf(stderr, "Should be one of: --init -v\n");
! 5985: rc = 1;
! 5986: goto meta_command_exit;
! 5987: }
! 5988: }
! 5989: if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
! 5990: != SQLITE_OK ){
! 5991: bSelftestExists = 0;
! 5992: }else{
! 5993: bSelftestExists = 1;
! 5994: }
! 5995: if( bIsInit ){
! 5996: createSelftestTable(p);
! 5997: bSelftestExists = 1;
! 5998: }
! 5999: if( bSelftestExists ){
! 6000: rc = sqlite3_get_table(p->db,
! 6001: "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno",
! 6002: &azTest, &nRow, &nCol, 0);
! 6003: if( rc ){
! 6004: raw_printf(stderr, "Error querying the selftest table\n");
! 6005: rc = 1;
! 6006: sqlite3_free_table(azTest);
! 6007: goto meta_command_exit;
! 6008: }else if( nRow==0 ){
! 6009: sqlite3_free_table(azTest);
! 6010: azTest = azDefaultTest;
! 6011: nRow = nDefaultRow;
! 6012: }
! 6013: }else{
! 6014: azTest = azDefaultTest;
! 6015: nRow = nDefaultRow;
! 6016: }
! 6017: initText(&str);
! 6018: appendText(&str, "x", 0);
! 6019: for(i=1; i<=nRow; i++){
! 6020: int tno = atoi(azTest[i*nCol]);
! 6021: const char *zOp = azTest[i*nCol+1];
! 6022: const char *zSql = azTest[i*nCol+2];
! 6023: const char *zAns = azTest[i*nCol+3];
! 6024:
! 6025: if( bVerbose>0 ){
! 6026: char *zQuote = sqlite3_mprintf("%q", zSql);
! 6027: printf("%d: %s %s\n", tno, zOp, zSql);
! 6028: sqlite3_free(zQuote);
! 6029: }
! 6030: if( strcmp(zOp,"memo")==0 ){
! 6031: utf8_printf(p->out, "%s\n", zSql);
! 6032: }else
! 6033: if( strcmp(zOp,"run")==0 ){
! 6034: char *zErrMsg = 0;
! 6035: str.n = 0;
! 6036: str.z[0] = 0;
! 6037: rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
! 6038: nTest++;
! 6039: if( bVerbose ){
! 6040: utf8_printf(p->out, "Result: %s\n", str.z);
! 6041: }
! 6042: if( rc || zErrMsg ){
! 6043: nErr++;
! 6044: rc = 1;
! 6045: utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg);
! 6046: sqlite3_free(zErrMsg);
! 6047: }else if( strcmp(zAns,str.z)!=0 ){
! 6048: nErr++;
! 6049: rc = 1;
! 6050: utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
! 6051: utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z);
! 6052: }
! 6053: }else
! 6054: {
! 6055: utf8_printf(stderr,
! 6056: "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
! 6057: rc = 1;
! 6058: break;
! 6059: }
! 6060: }
! 6061: freeText(&str);
! 6062: if( azTest!=azDefaultTest ) sqlite3_free_table(azTest);
! 6063: utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
! 6064: }else
! 6065:
1.4 misho 6066: if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
6067: if( nArg<2 || nArg>3 ){
6068: raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
6069: rc = 1;
6070: }
6071: if( nArg>=2 ){
6072: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
6073: "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
6074: }
6075: if( nArg>=3 ){
6076: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
6077: "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
6078: }
6079: }else
6080:
1.4.2.1 ! misho 6081: if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){
! 6082: const char *zLike = 0; /* Which table to checksum. 0 means everything */
! 6083: int i; /* Loop counter */
! 6084: int bSchema = 0; /* Also hash the schema */
! 6085: int bSeparate = 0; /* Hash each table separately */
! 6086: int iSize = 224; /* Hash algorithm to use */
! 6087: int bDebug = 0; /* Only show the query that would have run */
! 6088: sqlite3_stmt *pStmt; /* For querying tables names */
! 6089: char *zSql; /* SQL to be run */
! 6090: char *zSep; /* Separator */
! 6091: ShellText sSql; /* Complete SQL for the query to run the hash */
! 6092: ShellText sQuery; /* Set of queries used to read all content */
! 6093: open_db(p, 0);
! 6094: for(i=1; i<nArg; i++){
! 6095: const char *z = azArg[i];
! 6096: if( z[0]=='-' ){
! 6097: z++;
! 6098: if( z[0]=='-' ) z++;
! 6099: if( strcmp(z,"schema")==0 ){
! 6100: bSchema = 1;
! 6101: }else
! 6102: if( strcmp(z,"sha3-224")==0 || strcmp(z,"sha3-256")==0
! 6103: || strcmp(z,"sha3-384")==0 || strcmp(z,"sha3-512")==0
! 6104: ){
! 6105: iSize = atoi(&z[5]);
! 6106: }else
! 6107: if( strcmp(z,"debug")==0 ){
! 6108: bDebug = 1;
! 6109: }else
! 6110: {
! 6111: utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
! 6112: azArg[i], azArg[0]);
! 6113: raw_printf(stderr, "Should be one of: --schema"
! 6114: " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n");
! 6115: rc = 1;
! 6116: goto meta_command_exit;
! 6117: }
! 6118: }else if( zLike ){
! 6119: raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
! 6120: rc = 1;
! 6121: goto meta_command_exit;
! 6122: }else{
! 6123: zLike = z;
! 6124: bSeparate = 1;
! 6125: if( sqlite3_strlike("sqlite_%", zLike, 0)==0 ) bSchema = 1;
! 6126: }
! 6127: }
! 6128: if( bSchema ){
! 6129: zSql = "SELECT lower(name) FROM sqlite_master"
! 6130: " WHERE type='table' AND coalesce(rootpage,0)>1"
! 6131: " UNION ALL SELECT 'sqlite_master'"
! 6132: " ORDER BY 1 collate nocase";
! 6133: }else{
! 6134: zSql = "SELECT lower(name) FROM sqlite_master"
! 6135: " WHERE type='table' AND coalesce(rootpage,0)>1"
! 6136: " AND name NOT LIKE 'sqlite_%'"
! 6137: " ORDER BY 1 collate nocase";
! 6138: }
! 6139: sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
! 6140: initText(&sQuery);
! 6141: initText(&sSql);
! 6142: appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0);
! 6143: zSep = "VALUES(";
! 6144: while( SQLITE_ROW==sqlite3_step(pStmt) ){
! 6145: const char *zTab = (const char*)sqlite3_column_text(pStmt,0);
! 6146: if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue;
! 6147: if( strncmp(zTab, "sqlite_",7)!=0 ){
! 6148: appendText(&sQuery,"SELECT * FROM ", 0);
! 6149: appendText(&sQuery,zTab,'"');
! 6150: appendText(&sQuery," NOT INDEXED;", 0);
! 6151: }else if( strcmp(zTab, "sqlite_master")==0 ){
! 6152: appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_master"
! 6153: " ORDER BY name;", 0);
! 6154: }else if( strcmp(zTab, "sqlite_sequence")==0 ){
! 6155: appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence"
! 6156: " ORDER BY name;", 0);
! 6157: }else if( strcmp(zTab, "sqlite_stat1")==0 ){
! 6158: appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
! 6159: " ORDER BY tbl,idx;", 0);
! 6160: }else if( strcmp(zTab, "sqlite_stat3")==0
! 6161: || strcmp(zTab, "sqlite_stat4")==0 ){
! 6162: appendText(&sQuery, "SELECT * FROM ", 0);
! 6163: appendText(&sQuery, zTab, 0);
! 6164: appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
! 6165: }
! 6166: appendText(&sSql, zSep, 0);
! 6167: appendText(&sSql, sQuery.z, '\'');
! 6168: sQuery.n = 0;
! 6169: appendText(&sSql, ",", 0);
! 6170: appendText(&sSql, zTab, '\'');
! 6171: zSep = "),(";
! 6172: }
! 6173: sqlite3_finalize(pStmt);
! 6174: if( bSeparate ){
! 6175: zSql = sqlite3_mprintf(
! 6176: "%s))"
! 6177: " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
! 6178: " FROM [sha3sum$query]",
! 6179: sSql.z, iSize);
! 6180: }else{
! 6181: zSql = sqlite3_mprintf(
! 6182: "%s))"
! 6183: " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
! 6184: " FROM [sha3sum$query]",
! 6185: sSql.z, iSize);
! 6186: }
! 6187: freeText(&sQuery);
! 6188: freeText(&sSql);
! 6189: if( bDebug ){
! 6190: utf8_printf(p->out, "%s\n", zSql);
! 6191: }else{
! 6192: shell_exec(p->db, zSql, shell_callback, p, 0);
! 6193: }
! 6194: sqlite3_free(zSql);
! 6195: }else
! 6196:
1.4 misho 6197: if( c=='s'
6198: && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
6199: ){
6200: char *zCmd;
6201: int i, x;
6202: if( nArg<2 ){
6203: raw_printf(stderr, "Usage: .system COMMAND\n");
6204: rc = 1;
6205: goto meta_command_exit;
6206: }
6207: zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
6208: for(i=2; i<nArg; i++){
6209: zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
6210: zCmd, azArg[i]);
6211: }
6212: x = system(zCmd);
6213: sqlite3_free(zCmd);
6214: if( x ) raw_printf(stderr, "System command returns %d\n", x);
1.2 misho 6215: }else
6216:
1.4 misho 6217: if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
6218: static const char *azBool[] = { "off", "on", "full", "unk" };
1.2 misho 6219: int i;
1.4 misho 6220: if( nArg!=1 ){
6221: raw_printf(stderr, "Usage: .show\n");
6222: rc = 1;
6223: goto meta_command_exit;
6224: }
1.4.2.1 ! misho 6225: utf8_printf(p->out, "%12.12s: %s\n","echo",
! 6226: azBool[ShellHasFlag(p, SHFLG_Echo)]);
1.4 misho 6227: utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
6228: utf8_printf(p->out, "%12.12s: %s\n","explain",
6229: p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
6230: utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
6231: utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
6232: utf8_printf(p->out, "%12.12s: ", "nullvalue");
6233: output_c_string(p->out, p->nullValue);
6234: raw_printf(p->out, "\n");
6235: utf8_printf(p->out,"%12.12s: %s\n","output",
1.2 misho 6236: strlen30(p->outfile) ? p->outfile : "stdout");
1.4 misho 6237: utf8_printf(p->out,"%12.12s: ", "colseparator");
6238: output_c_string(p->out, p->colSeparator);
6239: raw_printf(p->out, "\n");
6240: utf8_printf(p->out,"%12.12s: ", "rowseparator");
6241: output_c_string(p->out, p->rowSeparator);
6242: raw_printf(p->out, "\n");
6243: utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
6244: utf8_printf(p->out, "%12.12s: ", "width");
1.2 misho 6245: for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
1.4 misho 6246: raw_printf(p->out, "%d ", p->colWidth[i]);
1.2 misho 6247: }
1.4 misho 6248: raw_printf(p->out, "\n");
1.4.2.1 ! misho 6249: utf8_printf(p->out, "%12.12s: %s\n", "filename",
! 6250: p->zDbFilename ? p->zDbFilename : "");
1.2 misho 6251: }else
6252:
1.4 misho 6253: if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
6254: if( nArg==2 ){
6255: p->statsOn = booleanValue(azArg[1]);
6256: }else if( nArg==1 ){
6257: display_stats(p->db, p, 0);
6258: }else{
6259: raw_printf(stderr, "Usage: .stats ?on|off?\n");
6260: rc = 1;
6261: }
1.2 misho 6262: }else
6263:
1.4.2.1 ! misho 6264: if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
! 6265: || (c=='i' && (strncmp(azArg[0], "indices", n)==0
! 6266: || strncmp(azArg[0], "indexes", n)==0) )
! 6267: ){
1.3 misho 6268: sqlite3_stmt *pStmt;
1.2 misho 6269: char **azResult;
1.3 misho 6270: int nRow, nAlloc;
6271: char *zSql = 0;
6272: int ii;
1.4 misho 6273: open_db(p, 0);
1.3 misho 6274: rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
1.4 misho 6275: if( rc ) return shellDatabaseError(p->db);
6276:
6277: /* Create an SQL statement to query for the list of tables in the
6278: ** main and all attached databases where the table name matches the
6279: ** LIKE pattern bound to variable "?1". */
1.4.2.1 ! misho 6280: if( c=='t' ){
! 6281: zSql = sqlite3_mprintf(
! 6282: "SELECT name FROM sqlite_master"
! 6283: " WHERE type IN ('table','view')"
! 6284: " AND name NOT LIKE 'sqlite_%%'"
! 6285: " AND name LIKE ?1");
! 6286: }else if( nArg>2 ){
! 6287: /* It is an historical accident that the .indexes command shows an error
! 6288: ** when called with the wrong number of arguments whereas the .tables
! 6289: ** command does not. */
! 6290: raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
! 6291: rc = 1;
! 6292: goto meta_command_exit;
! 6293: }else{
! 6294: zSql = sqlite3_mprintf(
! 6295: "SELECT name FROM sqlite_master"
! 6296: " WHERE type='index'"
! 6297: " AND tbl_name LIKE ?1");
! 6298: }
! 6299: for(ii=0; zSql && sqlite3_step(pStmt)==SQLITE_ROW; ii++){
1.3 misho 6300: const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
1.4.2.1 ! misho 6301: if( zDbName==0 || ii==0 ) continue;
! 6302: if( c=='t' ){
1.3 misho 6303: zSql = sqlite3_mprintf(
6304: "%z UNION ALL "
1.4.2.1 ! misho 6305: "SELECT '%q.' || name FROM \"%w\".sqlite_master"
1.3 misho 6306: " WHERE type IN ('table','view')"
6307: " AND name NOT LIKE 'sqlite_%%'"
1.4.2.1 ! misho 6308: " AND name LIKE ?1", zSql, zDbName, zDbName);
1.3 misho 6309: }else{
6310: zSql = sqlite3_mprintf(
6311: "%z UNION ALL "
6312: "SELECT '%q.' || name FROM \"%w\".sqlite_master"
1.4.2.1 ! misho 6313: " WHERE type='index'"
! 6314: " AND tbl_name LIKE ?1", zSql, zDbName, zDbName);
1.3 misho 6315: }
6316: }
1.4 misho 6317: rc = sqlite3_finalize(pStmt);
6318: if( zSql && rc==SQLITE_OK ){
6319: zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
6320: if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
6321: }
1.3 misho 6322: sqlite3_free(zSql);
1.4 misho 6323: if( !zSql ) return shellNomemError();
6324: if( rc ) return shellDatabaseError(p->db);
6325:
6326: /* Run the SQL statement prepared by the above block. Store the results
6327: ** as an array of nul-terminated strings in azResult[]. */
1.3 misho 6328: nRow = nAlloc = 0;
6329: azResult = 0;
6330: if( nArg>1 ){
6331: sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
1.2 misho 6332: }else{
1.3 misho 6333: sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
6334: }
6335: while( sqlite3_step(pStmt)==SQLITE_ROW ){
6336: if( nRow>=nAlloc ){
6337: char **azNew;
1.4 misho 6338: int n2 = nAlloc*2 + 10;
6339: azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
1.3 misho 6340: if( azNew==0 ){
1.4 misho 6341: rc = shellNomemError();
1.3 misho 6342: break;
6343: }
1.4 misho 6344: nAlloc = n2;
1.3 misho 6345: azResult = azNew;
6346: }
6347: azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
1.4 misho 6348: if( 0==azResult[nRow] ){
6349: rc = shellNomemError();
6350: break;
6351: }
6352: nRow++;
1.2 misho 6353: }
1.4 misho 6354: if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
6355: rc = shellDatabaseError(p->db);
6356: }
6357:
6358: /* Pretty-print the contents of array azResult[] to the output */
6359: if( rc==0 && nRow>0 ){
1.2 misho 6360: int len, maxlen = 0;
6361: int i, j;
6362: int nPrintCol, nPrintRow;
1.3 misho 6363: for(i=0; i<nRow; i++){
1.2 misho 6364: len = strlen30(azResult[i]);
6365: if( len>maxlen ) maxlen = len;
6366: }
6367: nPrintCol = 80/(maxlen+2);
6368: if( nPrintCol<1 ) nPrintCol = 1;
6369: nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
6370: for(i=0; i<nPrintRow; i++){
1.3 misho 6371: for(j=i; j<nRow; j+=nPrintRow){
6372: char *zSp = j<nPrintRow ? "" : " ";
1.4 misho 6373: utf8_printf(p->out, "%s%-*s", zSp, maxlen,
6374: azResult[j] ? azResult[j]:"");
1.2 misho 6375: }
1.4 misho 6376: raw_printf(p->out, "\n");
1.2 misho 6377: }
6378: }
1.4 misho 6379:
1.3 misho 6380: for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
6381: sqlite3_free(azResult);
1.2 misho 6382: }else
6383:
1.4.2.1 ! misho 6384: /* Begin redirecting output to the file "testcase-out.txt" */
! 6385: if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
! 6386: output_reset(p);
! 6387: p->out = output_file_open("testcase-out.txt");
! 6388: if( p->out==0 ){
! 6389: raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
! 6390: }
! 6391: if( nArg>=2 ){
! 6392: sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
! 6393: }else{
! 6394: sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
! 6395: }
! 6396: }else
! 6397:
! 6398: #ifndef SQLITE_UNTESTABLE
1.2 misho 6399: if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
6400: static const struct {
6401: const char *zCtrlName; /* Name of a test-control option */
6402: int ctrlCode; /* Integer code for that option */
6403: } aCtrl[] = {
6404: { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
6405: { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
6406: { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
6407: { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
6408: { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
6409: { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
6410: { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
6411: { "assert", SQLITE_TESTCTRL_ASSERT },
6412: { "always", SQLITE_TESTCTRL_ALWAYS },
6413: { "reserve", SQLITE_TESTCTRL_RESERVE },
6414: { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
6415: { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
6416: { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
1.4 misho 6417: { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
6418: { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
6419: { "imposter", SQLITE_TESTCTRL_IMPOSTER },
1.2 misho 6420: };
6421: int testctrl = -1;
1.4 misho 6422: int rc2 = 0;
6423: int i, n2;
6424: open_db(p, 0);
1.2 misho 6425:
6426: /* convert testctrl text option to value. allow any unique prefix
6427: ** of the option name, or a numerical value. */
1.4 misho 6428: n2 = strlen30(azArg[1]);
6429: for(i=0; i<ArraySize(aCtrl); i++){
6430: if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
1.2 misho 6431: if( testctrl<0 ){
6432: testctrl = aCtrl[i].ctrlCode;
6433: }else{
1.4 misho 6434: utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
1.2 misho 6435: testctrl = -1;
6436: break;
6437: }
6438: }
6439: }
1.4 misho 6440: if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
1.2 misho 6441: if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
1.4 misho 6442: utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
1.2 misho 6443: }else{
6444: switch(testctrl){
6445:
6446: /* sqlite3_test_control(int, db, int) */
6447: case SQLITE_TESTCTRL_OPTIMIZATIONS:
1.4 misho 6448: case SQLITE_TESTCTRL_RESERVE:
1.2 misho 6449: if( nArg==3 ){
1.4 misho 6450: int opt = (int)strtol(azArg[2], 0, 0);
6451: rc2 = sqlite3_test_control(testctrl, p->db, opt);
6452: raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
1.2 misho 6453: } else {
1.4 misho 6454: utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
1.2 misho 6455: azArg[1]);
6456: }
6457: break;
6458:
6459: /* sqlite3_test_control(int) */
1.4 misho 6460: case SQLITE_TESTCTRL_PRNG_SAVE:
6461: case SQLITE_TESTCTRL_PRNG_RESTORE:
1.2 misho 6462: case SQLITE_TESTCTRL_PRNG_RESET:
1.4 misho 6463: case SQLITE_TESTCTRL_BYTEORDER:
1.2 misho 6464: if( nArg==2 ){
1.4 misho 6465: rc2 = sqlite3_test_control(testctrl);
6466: raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
1.2 misho 6467: } else {
1.4 misho 6468: utf8_printf(stderr,"Error: testctrl %s takes no options\n",
6469: azArg[1]);
1.2 misho 6470: }
6471: break;
6472:
6473: /* sqlite3_test_control(int, uint) */
1.4 misho 6474: case SQLITE_TESTCTRL_PENDING_BYTE:
1.2 misho 6475: if( nArg==3 ){
1.4 misho 6476: unsigned int opt = (unsigned int)integerValue(azArg[2]);
6477: rc2 = sqlite3_test_control(testctrl, opt);
6478: raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
1.2 misho 6479: } else {
1.4 misho 6480: utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
1.2 misho 6481: " int option\n", azArg[1]);
6482: }
6483: break;
1.4 misho 6484:
1.2 misho 6485: /* sqlite3_test_control(int, int) */
1.4 misho 6486: case SQLITE_TESTCTRL_ASSERT:
6487: case SQLITE_TESTCTRL_ALWAYS:
6488: case SQLITE_TESTCTRL_NEVER_CORRUPT:
1.2 misho 6489: if( nArg==3 ){
1.4 misho 6490: int opt = booleanValue(azArg[2]);
6491: rc2 = sqlite3_test_control(testctrl, opt);
6492: raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
1.2 misho 6493: } else {
1.4 misho 6494: utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
1.2 misho 6495: azArg[1]);
6496: }
6497: break;
6498:
6499: /* sqlite3_test_control(int, char *) */
6500: #ifdef SQLITE_N_KEYWORD
1.4 misho 6501: case SQLITE_TESTCTRL_ISKEYWORD:
1.2 misho 6502: if( nArg==3 ){
1.4 misho 6503: const char *opt = azArg[2];
6504: rc2 = sqlite3_test_control(testctrl, opt);
6505: raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
1.2 misho 6506: } else {
1.4 misho 6507: utf8_printf(stderr,
6508: "Error: testctrl %s takes a single char * option\n",
6509: azArg[1]);
1.2 misho 6510: }
6511: break;
6512: #endif
6513:
1.4 misho 6514: case SQLITE_TESTCTRL_IMPOSTER:
6515: if( nArg==5 ){
6516: rc2 = sqlite3_test_control(testctrl, p->db,
6517: azArg[2],
6518: integerValue(azArg[3]),
6519: integerValue(azArg[4]));
6520: raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
6521: }else{
6522: raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
6523: }
6524: break;
6525:
6526: case SQLITE_TESTCTRL_BITVEC_TEST:
6527: case SQLITE_TESTCTRL_FAULT_INSTALL:
6528: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
6529: case SQLITE_TESTCTRL_SCRATCHMALLOC:
1.2 misho 6530: default:
1.4 misho 6531: utf8_printf(stderr,
6532: "Error: CLI support for testctrl %s not implemented\n",
6533: azArg[1]);
1.2 misho 6534: break;
6535: }
6536: }
6537: }else
1.4.2.1 ! misho 6538: #endif /* !defined(SQLITE_UNTESTABLE) */
1.2 misho 6539:
1.4 misho 6540: if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
6541: open_db(p, 0);
6542: sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
6543: }else
6544:
6545: if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
6546: if( nArg==2 ){
6547: enableTimer = booleanValue(azArg[1]);
6548: if( enableTimer && !HAS_TIMER ){
6549: raw_printf(stderr, "Error: timer not available on this system.\n");
6550: enableTimer = 0;
6551: }
6552: }else{
6553: raw_printf(stderr, "Usage: .timer on|off\n");
6554: rc = 1;
6555: }
1.2 misho 6556: }else
1.4 misho 6557:
6558: if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
6559: open_db(p, 0);
6560: if( nArg!=2 ){
6561: raw_printf(stderr, "Usage: .trace FILE|off\n");
6562: rc = 1;
6563: goto meta_command_exit;
6564: }
1.3 misho 6565: output_file_close(p->traceOut);
6566: p->traceOut = output_file_open(azArg[1]);
6567: #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
6568: if( p->traceOut==0 ){
1.4 misho 6569: sqlite3_trace_v2(p->db, 0, 0, 0);
1.3 misho 6570: }else{
1.4 misho 6571: sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
1.3 misho 6572: }
6573: #endif
6574: }else
6575:
1.4 misho 6576: #if SQLITE_USER_AUTHENTICATION
6577: if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
6578: if( nArg<2 ){
6579: raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
6580: rc = 1;
6581: goto meta_command_exit;
6582: }
6583: open_db(p, 0);
6584: if( strcmp(azArg[1],"login")==0 ){
6585: if( nArg!=4 ){
6586: raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
6587: rc = 1;
6588: goto meta_command_exit;
6589: }
6590: rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
6591: (int)strlen(azArg[3]));
6592: if( rc ){
6593: utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
6594: rc = 1;
6595: }
6596: }else if( strcmp(azArg[1],"add")==0 ){
6597: if( nArg!=5 ){
6598: raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
6599: rc = 1;
6600: goto meta_command_exit;
6601: }
6602: rc = sqlite3_user_add(p->db, azArg[2],
6603: azArg[3], (int)strlen(azArg[3]),
6604: booleanValue(azArg[4]));
6605: if( rc ){
6606: raw_printf(stderr, "User-Add failed: %d\n", rc);
6607: rc = 1;
6608: }
6609: }else if( strcmp(azArg[1],"edit")==0 ){
6610: if( nArg!=5 ){
6611: raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
6612: rc = 1;
6613: goto meta_command_exit;
6614: }
6615: rc = sqlite3_user_change(p->db, azArg[2],
6616: azArg[3], (int)strlen(azArg[3]),
6617: booleanValue(azArg[4]));
6618: if( rc ){
6619: raw_printf(stderr, "User-Edit failed: %d\n", rc);
6620: rc = 1;
6621: }
6622: }else if( strcmp(azArg[1],"delete")==0 ){
6623: if( nArg!=3 ){
6624: raw_printf(stderr, "Usage: .user delete USER\n");
6625: rc = 1;
6626: goto meta_command_exit;
6627: }
6628: rc = sqlite3_user_delete(p->db, azArg[2]);
6629: if( rc ){
6630: raw_printf(stderr, "User-Delete failed: %d\n", rc);
6631: rc = 1;
6632: }
6633: }else{
6634: raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
6635: rc = 1;
6636: goto meta_command_exit;
6637: }
6638: }else
6639: #endif /* SQLITE_USER_AUTHENTICATION */
6640:
1.2 misho 6641: if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
1.4 misho 6642: utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
1.2 misho 6643: sqlite3_libversion(), sqlite3_sourceid());
6644: }else
6645:
1.4 misho 6646: if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
6647: const char *zDbName = nArg==2 ? azArg[1] : "main";
1.4.2.1 ! misho 6648: sqlite3_vfs *pVfs = 0;
1.4 misho 6649: if( p->db ){
6650: sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
6651: if( pVfs ){
6652: utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
6653: raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
6654: raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
6655: raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
6656: }
6657: }
6658: }else
6659:
6660: if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
6661: sqlite3_vfs *pVfs;
6662: sqlite3_vfs *pCurrent = 0;
6663: if( p->db ){
6664: sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
6665: }
6666: for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
6667: utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
6668: pVfs==pCurrent ? " <--- CURRENT" : "");
6669: raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
6670: raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
6671: raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
6672: if( pVfs->pNext ){
6673: raw_printf(p->out, "-----------------------------------\n");
6674: }
6675: }
6676: }else
6677:
1.2 misho 6678: if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
6679: const char *zDbName = nArg==2 ? azArg[1] : "main";
6680: char *zVfsName = 0;
6681: if( p->db ){
6682: sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
6683: if( zVfsName ){
1.4 misho 6684: utf8_printf(p->out, "%s\n", zVfsName);
1.2 misho 6685: sqlite3_free(zVfsName);
6686: }
6687: }
6688: }else
6689:
1.3 misho 6690: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
6691: if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
1.4 misho 6692: sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
1.3 misho 6693: }else
6694: #endif
6695:
1.4 misho 6696: if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1.2 misho 6697: int j;
6698: assert( nArg<=ArraySize(azArg) );
6699: for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
1.4 misho 6700: p->colWidth[j-1] = (int)integerValue(azArg[j]);
1.2 misho 6701: }
6702: }else
6703:
6704: {
1.4 misho 6705: utf8_printf(stderr, "Error: unknown command or invalid arguments: "
1.2 misho 6706: " \"%s\". Enter \".help\" for help\n", azArg[0]);
6707: rc = 1;
6708: }
6709:
1.4 misho 6710: meta_command_exit:
6711: if( p->outCount ){
6712: p->outCount--;
6713: if( p->outCount==0 ) output_reset(p);
6714: }
1.2 misho 6715: return rc;
6716: }
6717:
6718: /*
6719: ** Return TRUE if a semicolon occurs anywhere in the first N characters
6720: ** of string z[].
6721: */
1.4 misho 6722: static int line_contains_semicolon(const char *z, int N){
1.2 misho 6723: int i;
6724: for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
6725: return 0;
6726: }
6727:
6728: /*
6729: ** Test to see if a line consists entirely of whitespace.
6730: */
6731: static int _all_whitespace(const char *z){
6732: for(; *z; z++){
6733: if( IsSpace(z[0]) ) continue;
6734: if( *z=='/' && z[1]=='*' ){
6735: z += 2;
6736: while( *z && (*z!='*' || z[1]!='/') ){ z++; }
6737: if( *z==0 ) return 0;
6738: z++;
6739: continue;
6740: }
6741: if( *z=='-' && z[1]=='-' ){
6742: z += 2;
6743: while( *z && *z!='\n' ){ z++; }
6744: if( *z==0 ) return 1;
6745: continue;
6746: }
6747: return 0;
6748: }
6749: return 1;
6750: }
6751:
6752: /*
6753: ** Return TRUE if the line typed in is an SQL command terminator other
6754: ** than a semi-colon. The SQL Server style "go" command is understood
6755: ** as is the Oracle "/".
6756: */
1.4 misho 6757: static int line_is_command_terminator(const char *zLine){
1.2 misho 6758: while( IsSpace(zLine[0]) ){ zLine++; };
6759: if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
6760: return 1; /* Oracle */
6761: }
6762: if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
6763: && _all_whitespace(&zLine[2]) ){
6764: return 1; /* SQL Server */
6765: }
6766: return 0;
6767: }
6768:
6769: /*
6770: ** Return true if zSql is a complete SQL statement. Return false if it
6771: ** ends in the middle of a string literal or C-style comment.
6772: */
1.4 misho 6773: static int line_is_complete(char *zSql, int nSql){
1.2 misho 6774: int rc;
6775: if( zSql==0 ) return 1;
6776: zSql[nSql] = ';';
6777: zSql[nSql+1] = 0;
6778: rc = sqlite3_complete(zSql);
6779: zSql[nSql] = 0;
6780: return rc;
6781: }
6782:
6783: /*
1.4.2.1 ! misho 6784: ** Run a single line of SQL
! 6785: */
! 6786: static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
! 6787: int rc;
! 6788: char *zErrMsg = 0;
! 6789:
! 6790: open_db(p, 0);
! 6791: if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
! 6792: BEGIN_TIMER;
! 6793: rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
! 6794: END_TIMER;
! 6795: if( rc || zErrMsg ){
! 6796: char zPrefix[100];
! 6797: if( in!=0 || !stdin_is_interactive ){
! 6798: sqlite3_snprintf(sizeof(zPrefix), zPrefix,
! 6799: "Error: near line %d:", startline);
! 6800: }else{
! 6801: sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
! 6802: }
! 6803: if( zErrMsg!=0 ){
! 6804: utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
! 6805: sqlite3_free(zErrMsg);
! 6806: zErrMsg = 0;
! 6807: }else{
! 6808: utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
! 6809: }
! 6810: return 1;
! 6811: }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
! 6812: raw_printf(p->out, "changes: %3d total_changes: %d\n",
! 6813: sqlite3_changes(p->db), sqlite3_total_changes(p->db));
! 6814: }
! 6815: return 0;
! 6816: }
! 6817:
! 6818:
! 6819: /*
1.2 misho 6820: ** Read input from *in and process it. If *in==0 then input
6821: ** is interactive - the user is typing it it. Otherwise, input
6822: ** is coming from a file or device. A prompt is issued and history
6823: ** is saved only if input is interactive. An interrupt signal will
6824: ** cause this routine to exit immediately, unless input is interactive.
6825: **
6826: ** Return the number of errors.
6827: */
1.4 misho 6828: static int process_input(ShellState *p, FILE *in){
6829: char *zLine = 0; /* A single input line */
6830: char *zSql = 0; /* Accumulated SQL text */
6831: int nLine; /* Length of current line */
6832: int nSql = 0; /* Bytes of zSql[] used */
6833: int nAlloc = 0; /* Allocated zSql[] space */
6834: int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
6835: int rc; /* Error code */
6836: int errCnt = 0; /* Number of errors seen */
6837: int lineno = 0; /* Current line number */
6838: int startline = 0; /* Line number for start of current input */
1.2 misho 6839:
6840: while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
6841: fflush(p->out);
1.4 misho 6842: zLine = one_input_line(in, zLine, nSql>0);
1.2 misho 6843: if( zLine==0 ){
1.3 misho 6844: /* End of input */
1.4 misho 6845: if( in==0 && stdin_is_interactive ) printf("\n");
1.3 misho 6846: break;
1.2 misho 6847: }
6848: if( seenInterrupt ){
6849: if( in!=0 ) break;
6850: seenInterrupt = 0;
6851: }
6852: lineno++;
1.4 misho 6853: if( nSql==0 && _all_whitespace(zLine) ){
1.4.2.1 ! misho 6854: if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
1.4 misho 6855: continue;
6856: }
1.2 misho 6857: if( zLine && zLine[0]=='.' && nSql==0 ){
1.4.2.1 ! misho 6858: if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
1.2 misho 6859: rc = do_meta_command(zLine, p);
6860: if( rc==2 ){ /* exit requested */
6861: break;
6862: }else if( rc ){
6863: errCnt++;
6864: }
6865: continue;
6866: }
1.4 misho 6867: if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
1.2 misho 6868: memcpy(zLine,";",2);
6869: }
1.4 misho 6870: nLine = strlen30(zLine);
6871: if( nSql+nLine+2>=nAlloc ){
6872: nAlloc = nSql+nLine+100;
6873: zSql = realloc(zSql, nAlloc);
6874: if( zSql==0 ){
6875: raw_printf(stderr, "Error: out of memory\n");
6876: exit(1);
6877: }
6878: }
1.2 misho 6879: nSqlPrior = nSql;
1.4 misho 6880: if( nSql==0 ){
1.2 misho 6881: int i;
6882: for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
1.4 misho 6883: assert( nAlloc>0 && zSql!=0 );
6884: memcpy(zSql, zLine+i, nLine+1-i);
6885: startline = lineno;
6886: nSql = nLine-i;
1.2 misho 6887: }else{
6888: zSql[nSql++] = '\n';
1.4 misho 6889: memcpy(zSql+nSql, zLine, nLine+1);
6890: nSql += nLine;
1.2 misho 6891: }
1.4 misho 6892: if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1.2 misho 6893: && sqlite3_complete(zSql) ){
1.4.2.1 ! misho 6894: errCnt += runOneSqlLine(p, zSql, in, startline);
1.4 misho 6895: nSql = 0;
6896: if( p->outCount ){
6897: output_reset(p);
6898: p->outCount = 0;
6899: }
6900: }else if( nSql && _all_whitespace(zSql) ){
1.4.2.1 ! misho 6901: if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
1.2 misho 6902: nSql = 0;
6903: }
6904: }
1.4.2.1 ! misho 6905: if( nSql && !_all_whitespace(zSql) ){
! 6906: runOneSqlLine(p, zSql, in, startline);
1.2 misho 6907: }
1.4 misho 6908: free(zSql);
1.2 misho 6909: free(zLine);
1.3 misho 6910: return errCnt>0;
1.2 misho 6911: }
6912:
6913: /*
6914: ** Return a pathname which is the user's home directory. A
1.3 misho 6915: ** 0 return indicates an error of some kind.
1.2 misho 6916: */
1.4.2.1 ! misho 6917: static char *find_home_dir(int clearFlag){
1.3 misho 6918: static char *home_dir = NULL;
1.4.2.1 ! misho 6919: if( clearFlag ){
! 6920: free(home_dir);
! 6921: home_dir = 0;
! 6922: return 0;
! 6923: }
1.3 misho 6924: if( home_dir ) return home_dir;
1.2 misho 6925:
1.4 misho 6926: #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
6927: && !defined(__RTP__) && !defined(_WRS_KERNEL)
1.3 misho 6928: {
6929: struct passwd *pwent;
6930: uid_t uid = getuid();
6931: if( (pwent=getpwuid(uid)) != NULL) {
6932: home_dir = pwent->pw_dir;
6933: }
1.2 misho 6934: }
6935: #endif
6936:
6937: #if defined(_WIN32_WCE)
6938: /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
6939: */
1.3 misho 6940: home_dir = "/";
1.2 misho 6941: #else
6942:
1.3 misho 6943: #if defined(_WIN32) || defined(WIN32)
1.2 misho 6944: if (!home_dir) {
6945: home_dir = getenv("USERPROFILE");
6946: }
6947: #endif
6948:
6949: if (!home_dir) {
6950: home_dir = getenv("HOME");
6951: }
6952:
1.3 misho 6953: #if defined(_WIN32) || defined(WIN32)
1.2 misho 6954: if (!home_dir) {
6955: char *zDrive, *zPath;
6956: int n;
6957: zDrive = getenv("HOMEDRIVE");
6958: zPath = getenv("HOMEPATH");
6959: if( zDrive && zPath ){
6960: n = strlen30(zDrive) + strlen30(zPath) + 1;
6961: home_dir = malloc( n );
6962: if( home_dir==0 ) return 0;
6963: sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
6964: return home_dir;
6965: }
6966: home_dir = "c:\\";
6967: }
6968: #endif
6969:
6970: #endif /* !_WIN32_WCE */
6971:
6972: if( home_dir ){
6973: int n = strlen30(home_dir) + 1;
6974: char *z = malloc( n );
6975: if( z ) memcpy(z, home_dir, n);
6976: home_dir = z;
6977: }
6978:
6979: return home_dir;
6980: }
6981:
6982: /*
6983: ** Read input from the file given by sqliterc_override. Or if that
6984: ** parameter is NULL, take input from ~/.sqliterc
6985: **
6986: ** Returns the number of errors.
6987: */
1.4 misho 6988: static void process_sqliterc(
6989: ShellState *p, /* Configuration data */
1.2 misho 6990: const char *sqliterc_override /* Name of config file. NULL to use default */
6991: ){
6992: char *home_dir = NULL;
6993: const char *sqliterc = sqliterc_override;
6994: char *zBuf = 0;
6995: FILE *in = NULL;
6996:
6997: if (sqliterc == NULL) {
1.4.2.1 ! misho 6998: home_dir = find_home_dir(0);
1.2 misho 6999: if( home_dir==0 ){
1.4 misho 7000: raw_printf(stderr, "-- warning: cannot find home directory;"
7001: " cannot read ~/.sqliterc\n");
7002: return;
1.2 misho 7003: }
1.3 misho 7004: sqlite3_initialize();
7005: zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
7006: sqliterc = zBuf;
1.2 misho 7007: }
7008: in = fopen(sqliterc,"rb");
7009: if( in ){
7010: if( stdin_is_interactive ){
1.4 misho 7011: utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
1.2 misho 7012: }
1.4 misho 7013: process_input(p,in);
1.2 misho 7014: fclose(in);
7015: }
1.3 misho 7016: sqlite3_free(zBuf);
1.2 misho 7017: }
7018:
7019: /*
7020: ** Show available command line options
7021: */
1.4 misho 7022: static const char zOptions[] =
7023: " -ascii set output mode to 'ascii'\n"
1.2 misho 7024: " -bail stop after hitting an error\n"
7025: " -batch force batch I/O\n"
7026: " -column set output mode to 'column'\n"
1.3 misho 7027: " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
1.2 misho 7028: " -csv set output mode to 'csv'\n"
1.3 misho 7029: " -echo print commands before execution\n"
7030: " -init FILENAME read/process named file\n"
7031: " -[no]header turn headers on or off\n"
7032: #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
7033: " -heap SIZE Size of heap for memsys3 or memsys5\n"
7034: #endif
7035: " -help show this message\n"
1.2 misho 7036: " -html set output mode to HTML\n"
1.3 misho 7037: " -interactive force interactive I/O\n"
1.2 misho 7038: " -line set output mode to 'line'\n"
7039: " -list set output mode to 'list'\n"
1.4 misho 7040: " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
7041: " -mmap N default mmap size set to N\n"
1.3 misho 7042: #ifdef SQLITE_ENABLE_MULTIPLEX
7043: " -multiplex enable the multiplexor VFS\n"
7044: #endif
1.4 misho 7045: " -newline SEP set output row separator. Default: '\\n'\n"
1.3 misho 7046: " -nullvalue TEXT set text string for NULL values. Default ''\n"
1.4 misho 7047: " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
7048: " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
7049: " -separator SEP set output column separator. Default: '|'\n"
1.2 misho 7050: " -stats print memory stats before each finalize\n"
7051: " -version show SQLite version\n"
7052: " -vfs NAME use NAME as the default VFS\n"
7053: #ifdef SQLITE_ENABLE_VFSTRACE
7054: " -vfstrace enable tracing of all VFS calls\n"
7055: #endif
7056: ;
7057: static void usage(int showDetail){
1.4 misho 7058: utf8_printf(stderr,
7059: "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1.2 misho 7060: "FILENAME is the name of an SQLite database. A new database is created\n"
7061: "if the file does not previously exist.\n", Argv0);
7062: if( showDetail ){
1.4 misho 7063: utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
1.2 misho 7064: }else{
1.4 misho 7065: raw_printf(stderr, "Use the -help option for additional information\n");
1.2 misho 7066: }
7067: exit(1);
7068: }
7069:
7070: /*
7071: ** Initialize the state information in data
7072: */
1.4 misho 7073: static void main_init(ShellState *data) {
1.2 misho 7074: memset(data, 0, sizeof(*data));
1.4 misho 7075: data->normalMode = data->cMode = data->mode = MODE_List;
7076: data->autoExplain = 1;
7077: memcpy(data->colSeparator,SEP_Column, 2);
7078: memcpy(data->rowSeparator,SEP_Row, 2);
1.2 misho 7079: data->showHeader = 0;
1.4 misho 7080: data->shellFlgs = SHFLG_Lookaside;
1.2 misho 7081: sqlite3_config(SQLITE_CONFIG_URI, 1);
7082: sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
1.4 misho 7083: sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
1.2 misho 7084: sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
7085: sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
7086: }
7087:
1.3 misho 7088: /*
1.4 misho 7089: ** Output text to the console in a font that attracts extra attention.
7090: */
7091: #ifdef _WIN32
7092: static void printBold(const char *zText){
7093: HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
7094: CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
7095: GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
7096: SetConsoleTextAttribute(out,
7097: FOREGROUND_RED|FOREGROUND_INTENSITY
7098: );
7099: printf("%s", zText);
7100: SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
7101: }
7102: #else
7103: static void printBold(const char *zText){
7104: printf("\033[1m%s\033[0m", zText);
7105: }
7106: #endif
7107:
7108: /*
1.3 misho 7109: ** Get the argument to an --option. Throw an error and die if no argument
7110: ** is available.
7111: */
7112: static char *cmdline_option_value(int argc, char **argv, int i){
7113: if( i==argc ){
1.4 misho 7114: utf8_printf(stderr, "%s: Error: missing argument to %s\n",
1.3 misho 7115: argv[0], argv[argc-1]);
7116: exit(1);
7117: }
7118: return argv[i];
7119: }
7120:
1.4 misho 7121: #ifndef SQLITE_SHELL_IS_UTF8
7122: # if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
7123: # define SQLITE_SHELL_IS_UTF8 (0)
7124: # else
7125: # define SQLITE_SHELL_IS_UTF8 (1)
7126: # endif
7127: #endif
7128:
7129: #if SQLITE_SHELL_IS_UTF8
7130: int SQLITE_CDECL main(int argc, char **argv){
7131: #else
7132: int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
7133: char **argv;
7134: #endif
1.2 misho 7135: char *zErrMsg = 0;
1.4 misho 7136: ShellState data;
1.2 misho 7137: const char *zInitFile = 0;
7138: int i;
7139: int rc = 0;
1.4 misho 7140: int warnInmemoryDb = 0;
7141: int readStdin = 1;
7142: int nCmd = 0;
7143: char **azCmd = 0;
7144:
7145: setBinaryMode(stdin, 0);
7146: setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
7147: stdin_is_interactive = isatty(0);
7148: stdout_is_console = isatty(1);
1.2 misho 7149:
1.4 misho 7150: #if USE_SYSTEM_SQLITE+0!=1
1.2 misho 7151: if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
1.4 misho 7152: utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
1.2 misho 7153: sqlite3_sourceid(), SQLITE_SOURCE_ID);
7154: exit(1);
7155: }
1.4 misho 7156: #endif
7157: main_init(&data);
7158: #if !SQLITE_SHELL_IS_UTF8
7159: sqlite3_initialize();
7160: argv = sqlite3_malloc64(sizeof(argv[0])*argc);
7161: if( argv==0 ){
7162: raw_printf(stderr, "out of memory\n");
7163: exit(1);
7164: }
7165: for(i=0; i<argc; i++){
7166: argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
7167: if( argv[i]==0 ){
7168: raw_printf(stderr, "out of memory\n");
7169: exit(1);
7170: }
7171: }
7172: #endif
7173: assert( argc>=1 && argv && argv[0] );
1.2 misho 7174: Argv0 = argv[0];
7175:
7176: /* Make sure we have a valid signal handler early, before anything
7177: ** else is done.
7178: */
7179: #ifdef SIGINT
7180: signal(SIGINT, interrupt_handler);
7181: #endif
7182:
1.4 misho 7183: #ifdef SQLITE_SHELL_DBNAME_PROC
7184: {
7185: /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
7186: ** of a C-function that will provide the name of the database file. Use
7187: ** this compile-time option to embed this shell program in larger
7188: ** applications. */
7189: extern void SQLITE_SHELL_DBNAME_PROC(const char**);
7190: SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
7191: warnInmemoryDb = 0;
7192: }
7193: #endif
7194:
1.2 misho 7195: /* Do an initial pass through the command-line argument to locate
7196: ** the name of the database file, the name of the initialization file,
7197: ** the size of the alternative malloc heap,
7198: ** and the first command to execute.
7199: */
1.3 misho 7200: for(i=1; i<argc; i++){
1.2 misho 7201: char *z;
7202: z = argv[i];
1.3 misho 7203: if( z[0]!='-' ){
7204: if( data.zDbFilename==0 ){
7205: data.zDbFilename = z;
1.4 misho 7206: }else{
7207: /* Excesss arguments are interpreted as SQL (or dot-commands) and
7208: ** mean that nothing is read from stdin */
7209: readStdin = 0;
7210: nCmd++;
7211: azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
7212: if( azCmd==0 ){
7213: raw_printf(stderr, "out of memory\n");
7214: exit(1);
7215: }
7216: azCmd[nCmd-1] = z;
1.3 misho 7217: }
7218: }
7219: if( z[1]=='-' ) z++;
7220: if( strcmp(z,"-separator")==0
7221: || strcmp(z,"-nullvalue")==0
1.4 misho 7222: || strcmp(z,"-newline")==0
1.3 misho 7223: || strcmp(z,"-cmd")==0
7224: ){
7225: (void)cmdline_option_value(argc, argv, ++i);
7226: }else if( strcmp(z,"-init")==0 ){
7227: zInitFile = cmdline_option_value(argc, argv, ++i);
7228: }else if( strcmp(z,"-batch")==0 ){
7229: /* Need to check for batch mode here to so we can avoid printing
1.4 misho 7230: ** informational messages (like from process_sqliterc) before
1.3 misho 7231: ** we do the actual processing of arguments later in a second pass.
7232: */
1.2 misho 7233: stdin_is_interactive = 0;
1.3 misho 7234: }else if( strcmp(z,"-heap")==0 ){
1.2 misho 7235: #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
7236: const char *zSize;
7237: sqlite3_int64 szHeap;
7238:
1.3 misho 7239: zSize = cmdline_option_value(argc, argv, ++i);
1.4 misho 7240: szHeap = integerValue(zSize);
1.2 misho 7241: if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
7242: sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
1.4 misho 7243: #else
7244: (void)cmdline_option_value(argc, argv, ++i);
1.2 misho 7245: #endif
1.4 misho 7246: }else if( strcmp(z,"-scratch")==0 ){
7247: int n, sz;
7248: sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
7249: if( sz>400000 ) sz = 400000;
7250: if( sz<2500 ) sz = 2500;
7251: n = (int)integerValue(cmdline_option_value(argc,argv,++i));
7252: if( n>10 ) n = 10;
7253: if( n<1 ) n = 1;
7254: sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
7255: data.shellFlgs |= SHFLG_Scratch;
7256: }else if( strcmp(z,"-pagecache")==0 ){
7257: int n, sz;
7258: sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
7259: if( sz>70000 ) sz = 70000;
7260: if( sz<0 ) sz = 0;
7261: n = (int)integerValue(cmdline_option_value(argc,argv,++i));
7262: sqlite3_config(SQLITE_CONFIG_PAGECACHE,
7263: (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
7264: data.shellFlgs |= SHFLG_Pagecache;
7265: }else if( strcmp(z,"-lookaside")==0 ){
7266: int n, sz;
7267: sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
7268: if( sz<0 ) sz = 0;
7269: n = (int)integerValue(cmdline_option_value(argc,argv,++i));
7270: if( n<0 ) n = 0;
7271: sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
7272: if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
1.2 misho 7273: #ifdef SQLITE_ENABLE_VFSTRACE
1.3 misho 7274: }else if( strcmp(z,"-vfstrace")==0 ){
1.2 misho 7275: extern int vfstrace_register(
7276: const char *zTraceName,
7277: const char *zOldVfsName,
7278: int (*xOut)(const char*,void*),
7279: void *pOutArg,
7280: int makeDefault
7281: );
7282: vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
7283: #endif
7284: #ifdef SQLITE_ENABLE_MULTIPLEX
1.3 misho 7285: }else if( strcmp(z,"-multiplex")==0 ){
1.2 misho 7286: extern int sqlite3_multiple_initialize(const char*,int);
7287: sqlite3_multiplex_initialize(0, 1);
7288: #endif
1.4 misho 7289: }else if( strcmp(z,"-mmap")==0 ){
7290: sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
7291: sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
1.3 misho 7292: }else if( strcmp(z,"-vfs")==0 ){
7293: sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
1.2 misho 7294: if( pVfs ){
7295: sqlite3_vfs_register(pVfs, 1);
7296: }else{
1.4 misho 7297: utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
1.2 misho 7298: exit(1);
7299: }
7300: }
7301: }
1.3 misho 7302: if( data.zDbFilename==0 ){
1.2 misho 7303: #ifndef SQLITE_OMIT_MEMORYDB
7304: data.zDbFilename = ":memory:";
1.4 misho 7305: warnInmemoryDb = argc==1;
1.2 misho 7306: #else
1.4 misho 7307: utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
1.3 misho 7308: return 1;
1.2 misho 7309: #endif
7310: }
7311: data.out = stdout;
7312:
7313: /* Go ahead and open the database file if it already exists. If the
7314: ** file does not exist, delay opening it. This prevents empty database
7315: ** files from being created if a user mistypes the database name argument
7316: ** to the sqlite command-line tool.
7317: */
7318: if( access(data.zDbFilename, 0)==0 ){
1.4 misho 7319: open_db(&data, 0);
1.2 misho 7320: }
7321:
7322: /* Process the initialization file if there is one. If no -init option
7323: ** is given on the command line, look for a file named ~/.sqliterc and
7324: ** try to process it.
7325: */
1.4 misho 7326: process_sqliterc(&data,zInitFile);
1.2 misho 7327:
7328: /* Make a second pass through the command-line argument and set
7329: ** options. This second pass is delayed until after the initialization
7330: ** file is processed so that the command-line arguments will override
7331: ** settings in the initialization file.
7332: */
1.3 misho 7333: for(i=1; i<argc; i++){
1.2 misho 7334: char *z = argv[i];
1.3 misho 7335: if( z[0]!='-' ) continue;
1.2 misho 7336: if( z[1]=='-' ){ z++; }
7337: if( strcmp(z,"-init")==0 ){
7338: i++;
7339: }else if( strcmp(z,"-html")==0 ){
7340: data.mode = MODE_Html;
7341: }else if( strcmp(z,"-list")==0 ){
7342: data.mode = MODE_List;
7343: }else if( strcmp(z,"-line")==0 ){
7344: data.mode = MODE_Line;
7345: }else if( strcmp(z,"-column")==0 ){
7346: data.mode = MODE_Column;
7347: }else if( strcmp(z,"-csv")==0 ){
7348: data.mode = MODE_Csv;
1.4 misho 7349: memcpy(data.colSeparator,",",2);
7350: }else if( strcmp(z,"-ascii")==0 ){
7351: data.mode = MODE_Ascii;
7352: sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
7353: SEP_Unit);
7354: sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
7355: SEP_Record);
1.2 misho 7356: }else if( strcmp(z,"-separator")==0 ){
1.4 misho 7357: sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
7358: "%s",cmdline_option_value(argc,argv,++i));
7359: }else if( strcmp(z,"-newline")==0 ){
7360: sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
1.3 misho 7361: "%s",cmdline_option_value(argc,argv,++i));
1.2 misho 7362: }else if( strcmp(z,"-nullvalue")==0 ){
1.4 misho 7363: sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
1.3 misho 7364: "%s",cmdline_option_value(argc,argv,++i));
1.2 misho 7365: }else if( strcmp(z,"-header")==0 ){
7366: data.showHeader = 1;
7367: }else if( strcmp(z,"-noheader")==0 ){
7368: data.showHeader = 0;
7369: }else if( strcmp(z,"-echo")==0 ){
1.4.2.1 ! misho 7370: ShellSetFlag(&data, SHFLG_Echo);
1.4 misho 7371: }else if( strcmp(z,"-eqp")==0 ){
7372: data.autoEQP = 1;
7373: }else if( strcmp(z,"-eqpfull")==0 ){
7374: data.autoEQP = 2;
1.2 misho 7375: }else if( strcmp(z,"-stats")==0 ){
7376: data.statsOn = 1;
1.4 misho 7377: }else if( strcmp(z,"-scanstats")==0 ){
7378: data.scanstatsOn = 1;
7379: }else if( strcmp(z,"-backslash")==0 ){
7380: /* Undocumented command-line option: -backslash
7381: ** Causes C-style backslash escapes to be evaluated in SQL statements
7382: ** prior to sending the SQL into SQLite. Useful for injecting
7383: ** crazy bytes in the middle of SQL statements for testing and debugging.
7384: */
1.4.2.1 ! misho 7385: ShellSetFlag(&data, SHFLG_Backslash);
1.2 misho 7386: }else if( strcmp(z,"-bail")==0 ){
7387: bail_on_error = 1;
7388: }else if( strcmp(z,"-version")==0 ){
7389: printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
7390: return 0;
7391: }else if( strcmp(z,"-interactive")==0 ){
7392: stdin_is_interactive = 1;
7393: }else if( strcmp(z,"-batch")==0 ){
7394: stdin_is_interactive = 0;
7395: }else if( strcmp(z,"-heap")==0 ){
7396: i++;
1.4 misho 7397: }else if( strcmp(z,"-scratch")==0 ){
7398: i+=2;
7399: }else if( strcmp(z,"-pagecache")==0 ){
7400: i+=2;
7401: }else if( strcmp(z,"-lookaside")==0 ){
7402: i+=2;
7403: }else if( strcmp(z,"-mmap")==0 ){
7404: i++;
1.2 misho 7405: }else if( strcmp(z,"-vfs")==0 ){
7406: i++;
7407: #ifdef SQLITE_ENABLE_VFSTRACE
7408: }else if( strcmp(z,"-vfstrace")==0 ){
7409: i++;
7410: #endif
7411: #ifdef SQLITE_ENABLE_MULTIPLEX
7412: }else if( strcmp(z,"-multiplex")==0 ){
7413: i++;
7414: #endif
1.3 misho 7415: }else if( strcmp(z,"-help")==0 ){
1.2 misho 7416: usage(1);
1.3 misho 7417: }else if( strcmp(z,"-cmd")==0 ){
1.4 misho 7418: /* Run commands that follow -cmd first and separately from commands
7419: ** that simply appear on the command-line. This seems goofy. It would
7420: ** be better if all commands ran in the order that they appear. But
7421: ** we retain the goofy behavior for historical compatibility. */
1.3 misho 7422: if( i==argc-1 ) break;
7423: z = cmdline_option_value(argc,argv,++i);
7424: if( z[0]=='.' ){
7425: rc = do_meta_command(z, &data);
1.4 misho 7426: if( rc && bail_on_error ) return rc==2 ? 0 : rc;
1.3 misho 7427: }else{
1.4 misho 7428: open_db(&data, 0);
1.3 misho 7429: rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
7430: if( zErrMsg!=0 ){
1.4 misho 7431: utf8_printf(stderr,"Error: %s\n", zErrMsg);
1.3 misho 7432: if( bail_on_error ) return rc!=0 ? rc : 1;
7433: }else if( rc!=0 ){
1.4 misho 7434: utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
1.3 misho 7435: if( bail_on_error ) return rc;
7436: }
7437: }
1.2 misho 7438: }else{
1.4 misho 7439: utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
7440: raw_printf(stderr,"Use -help for a list of options.\n");
1.2 misho 7441: return 1;
7442: }
1.4 misho 7443: data.cMode = data.mode;
1.2 misho 7444: }
7445:
1.4 misho 7446: if( !readStdin ){
7447: /* Run all arguments that do not begin with '-' as if they were separate
7448: ** command-line inputs, except for the argToSkip argument which contains
7449: ** the database filename.
1.2 misho 7450: */
1.4 misho 7451: for(i=0; i<nCmd; i++){
7452: if( azCmd[i][0]=='.' ){
7453: rc = do_meta_command(azCmd[i], &data);
7454: if( rc ) return rc==2 ? 0 : rc;
7455: }else{
7456: open_db(&data, 0);
7457: rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
7458: if( zErrMsg!=0 ){
7459: utf8_printf(stderr,"Error: %s\n", zErrMsg);
7460: return rc!=0 ? rc : 1;
7461: }else if( rc!=0 ){
7462: utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
7463: return rc;
7464: }
1.2 misho 7465: }
7466: }
1.4 misho 7467: free(azCmd);
1.2 misho 7468: }else{
7469: /* Run commands received from standard input
7470: */
7471: if( stdin_is_interactive ){
7472: char *zHome;
7473: char *zHistory = 0;
7474: int nHistory;
7475: printf(
7476: "SQLite version %s %.19s\n" /*extra-version-info*/
1.4 misho 7477: "Enter \".help\" for usage hints.\n",
1.2 misho 7478: sqlite3_libversion(), sqlite3_sourceid()
7479: );
1.4 misho 7480: if( warnInmemoryDb ){
7481: printf("Connected to a ");
7482: printBold("transient in-memory database");
7483: printf(".\nUse \".open FILENAME\" to reopen on a "
7484: "persistent database.\n");
7485: }
1.4.2.1 ! misho 7486: zHome = find_home_dir(0);
1.2 misho 7487: if( zHome ){
7488: nHistory = strlen30(zHome) + 20;
7489: if( (zHistory = malloc(nHistory))!=0 ){
7490: sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
7491: }
7492: }
1.4 misho 7493: if( zHistory ){ shell_read_history(zHistory); }
1.2 misho 7494: rc = process_input(&data, 0);
7495: if( zHistory ){
1.4 misho 7496: shell_stifle_history(100);
7497: shell_write_history(zHistory);
1.2 misho 7498: free(zHistory);
7499: }
7500: }else{
7501: rc = process_input(&data, stdin);
7502: }
7503: }
7504: set_table_name(&data, 0);
7505: if( data.db ){
1.4 misho 7506: session_close_all(&data);
1.2 misho 7507: sqlite3_close(data.db);
7508: }
1.4 misho 7509: sqlite3_free(data.zFreeOnClose);
1.4.2.1 ! misho 7510: find_home_dir(1);
1.4 misho 7511: #if !SQLITE_SHELL_IS_UTF8
7512: for(i=0; i<argc; i++) sqlite3_free(argv[i]);
7513: sqlite3_free(argv);
7514: #endif
1.2 misho 7515: return rc;
7516: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>