Annotation of elwix/files/sqlite/dist/shell.c, revision 1.4.2.3
1.4.2.2 misho 1: /* DO NOT EDIT!
2: ** This file is automatically generated by the script in the canonical
3: ** SQLite source tree at tool/mkshellc.tcl. That script combines source
4: ** code from various constituent source files of SQLite into this single
5: ** "shell.c" file used to implement the SQLite command-line shell.
6: **
7: ** Most of the code found below comes from the "src/shell.c.in" file in
8: ** the canonical SQLite source tree. That main file contains "INCLUDE"
9: ** lines that specify other files in the canonical source tree that are
10: ** inserted to getnerate this complete program source file.
11: **
12: ** The code from multiple files is combined into this single "shell.c"
13: ** source file to help make the command-line program easier to compile.
14: **
15: ** To modify this program, get a copy of the canonical SQLite source tree,
16: ** edit the src/shell.c.in" and/or some of the other files that are included
17: ** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
18: */
1.2 misho 19: /*
20: ** 2001 September 15
21: **
22: ** The author disclaims copyright to this source code. In place of
23: ** a legal notice, here is a blessing:
24: **
25: ** May you do good and not evil.
26: ** May you find forgiveness for yourself and forgive others.
27: ** May you share freely, never taking more than you give.
28: **
29: *************************************************************************
30: ** This file contains code to implement the "sqlite" command line
31: ** utility for accessing SQLite databases.
32: */
33: #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
34: /* This needs to come before any includes for MSVC compiler */
35: #define _CRT_SECURE_NO_WARNINGS
36: #endif
37:
38: /*
1.4.2.3 ! misho 39: ** Determine if we are dealing with WinRT, which provides only a subset of
! 40: ** the full Win32 API.
! 41: */
! 42: #if !defined(SQLITE_OS_WINRT)
! 43: # define SQLITE_OS_WINRT 0
! 44: #endif
! 45:
! 46: /*
1.4.2.2 misho 47: ** Warning pragmas copied from msvc.h in the core.
1.4 misho 48: */
1.4.2.2 misho 49: #if defined(_MSC_VER)
50: #pragma warning(disable : 4054)
51: #pragma warning(disable : 4055)
52: #pragma warning(disable : 4100)
53: #pragma warning(disable : 4127)
54: #pragma warning(disable : 4130)
55: #pragma warning(disable : 4152)
56: #pragma warning(disable : 4189)
57: #pragma warning(disable : 4206)
58: #pragma warning(disable : 4210)
59: #pragma warning(disable : 4232)
60: #pragma warning(disable : 4244)
61: #pragma warning(disable : 4305)
62: #pragma warning(disable : 4306)
63: #pragma warning(disable : 4702)
64: #pragma warning(disable : 4706)
65: #endif /* defined(_MSC_VER) */
1.4 misho 66:
67: /*
68: ** No support for loadable extensions in VxWorks.
69: */
70: #if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
71: # define SQLITE_OMIT_LOAD_EXTENSION 1
72: #endif
73:
74: /*
1.2 misho 75: ** Enable large-file support for fopen() and friends on unix.
76: */
77: #ifndef SQLITE_DISABLE_LFS
78: # define _LARGE_FILE 1
79: # ifndef _FILE_OFFSET_BITS
80: # define _FILE_OFFSET_BITS 64
81: # endif
82: # define _LARGEFILE_SOURCE 1
83: #endif
84:
85: #include <stdlib.h>
86: #include <string.h>
87: #include <stdio.h>
88: #include <assert.h>
89: #include "sqlite3.h"
1.4.2.2 misho 90: typedef sqlite3_int64 i64;
91: typedef sqlite3_uint64 u64;
92: typedef unsigned char u8;
1.4 misho 93: #if SQLITE_USER_AUTHENTICATION
94: # include "sqlite3userauth.h"
95: #endif
1.2 misho 96: #include <ctype.h>
97: #include <stdarg.h>
98:
1.3 misho 99: #if !defined(_WIN32) && !defined(WIN32)
1.2 misho 100: # include <signal.h>
101: # if !defined(__RTP__) && !defined(_WRS_KERNEL)
102: # include <pwd.h>
103: # endif
1.4.2.2 misho 104: #endif
105: #if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
1.2 misho 106: # include <unistd.h>
1.4.2.2 misho 107: # include <dirent.h>
108: # define GETPID getpid
109: # if defined(__MINGW32__)
110: # define DIRENT dirent
111: # ifndef S_ISLNK
112: # define S_ISLNK(mode) (0)
113: # endif
114: # endif
115: #else
116: # define GETPID (int)GetCurrentProcessId
1.2 misho 117: #endif
1.4.2.2 misho 118: #include <sys/types.h>
119: #include <sys/stat.h>
1.2 misho 120:
1.4 misho 121: #if HAVE_READLINE
1.2 misho 122: # include <readline/readline.h>
123: # include <readline/history.h>
124: #endif
1.4 misho 125:
126: #if HAVE_EDITLINE
127: # include <editline/readline.h>
128: #endif
129:
130: #if HAVE_EDITLINE || HAVE_READLINE
131:
132: # define shell_add_history(X) add_history(X)
133: # define shell_read_history(X) read_history(X)
134: # define shell_write_history(X) write_history(X)
135: # define shell_stifle_history(X) stifle_history(X)
136: # define shell_readline(X) readline(X)
137:
138: #elif HAVE_LINENOISE
139:
140: # include "linenoise.h"
141: # define shell_add_history(X) linenoiseHistoryAdd(X)
142: # define shell_read_history(X) linenoiseHistoryLoad(X)
143: # define shell_write_history(X) linenoiseHistorySave(X)
144: # define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
145: # define shell_readline(X) linenoise(X)
146:
147: #else
148:
149: # define shell_read_history(X)
150: # define shell_write_history(X)
151: # define shell_stifle_history(X)
152:
153: # define SHELL_USE_LOCAL_GETLINE 1
1.2 misho 154: #endif
155:
1.4 misho 156:
1.2 misho 157: #if defined(_WIN32) || defined(WIN32)
1.4.2.3 ! misho 158: # if SQLITE_OS_WINRT
! 159: # define SQLITE_OMIT_POPEN 1
! 160: # else
! 161: # include <io.h>
! 162: # include <fcntl.h>
! 163: # define isatty(h) _isatty(h)
! 164: # ifndef access
! 165: # define access(f,m) _access((f),(m))
! 166: # endif
! 167: # ifndef unlink
! 168: # define unlink _unlink
! 169: # endif
! 170: # ifndef strdup
! 171: # define strdup _strdup
! 172: # endif
! 173: # undef popen
! 174: # define popen _popen
! 175: # undef pclose
! 176: # define pclose _pclose
1.4.2.2 misho 177: # endif
1.2 misho 178: #else
1.4 misho 179: /* Make sure isatty() has a prototype. */
180: extern int isatty(int);
181:
182: # if !defined(__RTP__) && !defined(_WRS_KERNEL)
183: /* popen and pclose are not C89 functions and so are
184: ** sometimes omitted from the <stdio.h> header */
185: extern FILE *popen(const char*,const char*);
186: extern int pclose(FILE*);
187: # else
188: # define SQLITE_OMIT_POPEN 1
189: # endif
1.2 misho 190: #endif
191:
192: #if defined(_WIN32_WCE)
193: /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
194: * thus we always assume that we have a console. That can be
195: * overridden with the -batch command line option.
196: */
197: #define isatty(x) 1
198: #endif
199:
200: /* ctype macros that work with signed characters */
201: #define IsSpace(X) isspace((unsigned char)X)
202: #define IsDigit(X) isdigit((unsigned char)X)
203: #define ToLower(X) (char)tolower((unsigned char)X)
204:
1.4 misho 205: #if defined(_WIN32) || defined(WIN32)
1.4.2.3 ! misho 206: #if SQLITE_OS_WINRT
! 207: #include <intrin.h>
! 208: #endif
1.4 misho 209: #include <windows.h>
210:
211: /* string conversion routines only needed on Win32 */
212: extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
213: extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
214: extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
1.4.2.1 misho 215: extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
1.4 misho 216: #endif
217:
218: /* On Windows, we normally run with output mode of TEXT so that \n characters
219: ** are automatically translated into \r\n. However, this behavior needs
220: ** to be disabled in some cases (ex: when generating CSV output and when
221: ** rendering quoted strings that contain \n characters). The following
222: ** routines take care of that.
223: */
1.4.2.3 ! misho 224: #if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
1.4 misho 225: static void setBinaryMode(FILE *file, int isOutput){
226: if( isOutput ) fflush(file);
227: _setmode(_fileno(file), _O_BINARY);
228: }
229: static void setTextMode(FILE *file, int isOutput){
230: if( isOutput ) fflush(file);
231: _setmode(_fileno(file), _O_TEXT);
232: }
233: #else
234: # define setBinaryMode(X,Y)
235: # define setTextMode(X,Y)
236: #endif
237:
238:
239: /* True if the timer is enabled */
240: static int enableTimer = 0;
241:
242: /* Return the current wall-clock time */
243: static sqlite3_int64 timeOfDay(void){
244: static sqlite3_vfs *clockVfs = 0;
245: sqlite3_int64 t;
246: if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
247: if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
248: clockVfs->xCurrentTimeInt64(clockVfs, &t);
249: }else{
250: double r;
251: clockVfs->xCurrentTime(clockVfs, &r);
252: t = (sqlite3_int64)(r*86400000.0);
253: }
254: return t;
255: }
256:
257: #if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
1.2 misho 258: #include <sys/time.h>
259: #include <sys/resource.h>
260:
1.4 misho 261: /* VxWorks does not support getrusage() as far as we can determine */
262: #if defined(_WRS_KERNEL) || defined(__RTP__)
263: struct rusage {
264: struct timeval ru_utime; /* user CPU time used */
265: struct timeval ru_stime; /* system CPU time used */
266: };
267: #define getrusage(A,B) memset(B,0,sizeof(*B))
268: #endif
269:
1.2 misho 270: /* Saved resource information for the beginning of an operation */
1.4 misho 271: static struct rusage sBegin; /* CPU time at start */
272: static sqlite3_int64 iBegin; /* Wall-clock time at start */
1.2 misho 273:
274: /*
275: ** Begin timing an operation
276: */
277: static void beginTimer(void){
278: if( enableTimer ){
279: getrusage(RUSAGE_SELF, &sBegin);
1.4 misho 280: iBegin = timeOfDay();
1.2 misho 281: }
282: }
283:
284: /* Return the difference of two time_structs in seconds */
285: static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
1.4 misho 286: return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
1.2 misho 287: (double)(pEnd->tv_sec - pStart->tv_sec);
288: }
289:
290: /*
291: ** Print the timing results.
292: */
293: static void endTimer(void){
294: if( enableTimer ){
1.4 misho 295: sqlite3_int64 iEnd = timeOfDay();
1.2 misho 296: struct rusage sEnd;
297: getrusage(RUSAGE_SELF, &sEnd);
1.4 misho 298: printf("Run Time: real %.3f user %f sys %f\n",
299: (iEnd - iBegin)*0.001,
1.2 misho 300: timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
301: timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
302: }
303: }
304:
305: #define BEGIN_TIMER beginTimer()
306: #define END_TIMER endTimer()
307: #define HAS_TIMER 1
308:
309: #elif (defined(_WIN32) || defined(WIN32))
310:
311: /* Saved resource information for the beginning of an operation */
312: static HANDLE hProcess;
313: static FILETIME ftKernelBegin;
314: static FILETIME ftUserBegin;
1.4 misho 315: static sqlite3_int64 ftWallBegin;
316: typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
317: LPFILETIME, LPFILETIME);
1.2 misho 318: static GETPROCTIMES getProcessTimesAddr = NULL;
319:
320: /*
321: ** Check to see if we have timer support. Return 1 if necessary
322: ** support found (or found previously).
323: */
324: static int hasTimer(void){
325: if( getProcessTimesAddr ){
326: return 1;
327: } else {
1.4.2.3 ! misho 328: #if !SQLITE_OS_WINRT
1.4 misho 329: /* GetProcessTimes() isn't supported in WIN95 and some other Windows
330: ** versions. See if the version we are running on has it, and if it
331: ** does, save off a pointer to it and the current process handle.
1.2 misho 332: */
333: hProcess = GetCurrentProcess();
334: if( hProcess ){
335: HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
336: if( NULL != hinstLib ){
1.4 misho 337: getProcessTimesAddr =
338: (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
1.2 misho 339: if( NULL != getProcessTimesAddr ){
340: return 1;
341: }
1.4 misho 342: FreeLibrary(hinstLib);
1.2 misho 343: }
344: }
1.4.2.3 ! misho 345: #endif
1.2 misho 346: }
347: return 0;
348: }
349:
350: /*
351: ** Begin timing an operation
352: */
353: static void beginTimer(void){
354: if( enableTimer && getProcessTimesAddr ){
355: FILETIME ftCreation, ftExit;
1.4 misho 356: getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
357: &ftKernelBegin,&ftUserBegin);
358: ftWallBegin = timeOfDay();
1.2 misho 359: }
360: }
361:
362: /* Return the difference of two FILETIME structs in seconds */
363: static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
364: sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
365: sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
366: return (double) ((i64End - i64Start) / 10000000.0);
367: }
368:
369: /*
370: ** Print the timing results.
371: */
372: static void endTimer(void){
373: if( enableTimer && getProcessTimesAddr){
374: FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
1.4 misho 375: sqlite3_int64 ftWallEnd = timeOfDay();
376: getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
377: printf("Run Time: real %.3f user %f sys %f\n",
378: (ftWallEnd - ftWallBegin)*0.001,
1.2 misho 379: timeDiff(&ftUserBegin, &ftUserEnd),
380: timeDiff(&ftKernelBegin, &ftKernelEnd));
381: }
382: }
383:
384: #define BEGIN_TIMER beginTimer()
385: #define END_TIMER endTimer()
386: #define HAS_TIMER hasTimer()
387:
388: #else
1.4 misho 389: #define BEGIN_TIMER
1.2 misho 390: #define END_TIMER
391: #define HAS_TIMER 0
392: #endif
393:
394: /*
395: ** Used to prevent warnings about unused parameters
396: */
397: #define UNUSED_PARAMETER(x) (void)(x)
398:
399: /*
1.4.2.2 misho 400: ** Number of elements in an array
401: */
402: #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
403:
404: /*
1.2 misho 405: ** If the following flag is set, then command execution stops
406: ** at an error if we are not interactive.
407: */
408: static int bail_on_error = 0;
409:
410: /*
411: ** Threat stdin as an interactive input if the following variable
412: ** is true. Otherwise, assume stdin is connected to a file or pipe.
413: */
414: static int stdin_is_interactive = 1;
415:
416: /*
1.4 misho 417: ** On Windows systems we have to know if standard output is a console
418: ** in order to translate UTF-8 into MBCS. The following variable is
419: ** true if translation is required.
420: */
421: static int stdout_is_console = 1;
422:
423: /*
1.2 misho 424: ** The following is the open SQLite database. We make a pointer
425: ** to this database a static variable so that it can be accessed
426: ** by the SIGINT handler to interrupt database processing.
427: */
1.4 misho 428: static sqlite3 *globalDb = 0;
1.2 misho 429:
430: /*
431: ** True if an interrupt (Control-C) has been received.
432: */
433: static volatile int seenInterrupt = 0;
434:
1.4.2.3 ! misho 435: #ifdef SQLITE_DEBUG
! 436: /*
! 437: ** Out-of-memory simulator variables
! 438: */
! 439: static unsigned int oomCounter = 0; /* Simulate OOM when equals 1 */
! 440: static unsigned int oomRepeat = 0; /* Number of OOMs in a row */
! 441: static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */
! 442: #endif /* SQLITE_DEBUG */
! 443:
1.2 misho 444: /*
445: ** This is the name of our program. It is set in main(), used
446: ** in a number of other places, mostly for error messages.
447: */
448: static char *Argv0;
449:
450: /*
451: ** Prompt strings. Initialized in main. Settable with
452: ** .prompt main continue
453: */
454: static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
455: static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
456:
457: /*
1.4 misho 458: ** Render output like fprintf(). Except, if the output is going to the
459: ** console and if this is running on a Windows machine, translate the
460: ** output from UTF-8 into MBCS.
461: */
462: #if defined(_WIN32) || defined(WIN32)
463: void utf8_printf(FILE *out, const char *zFormat, ...){
464: va_list ap;
465: va_start(ap, zFormat);
466: if( stdout_is_console && (out==stdout || out==stderr) ){
467: char *z1 = sqlite3_vmprintf(zFormat, ap);
468: char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
469: sqlite3_free(z1);
470: fputs(z2, out);
471: sqlite3_free(z2);
472: }else{
473: vfprintf(out, zFormat, ap);
474: }
475: va_end(ap);
476: }
477: #elif !defined(utf8_printf)
478: # define utf8_printf fprintf
479: #endif
480:
481: /*
482: ** Render output like fprintf(). This should not be used on anything that
483: ** includes string formatting (e.g. "%s").
484: */
485: #if !defined(raw_printf)
486: # define raw_printf fprintf
487: #endif
488:
1.4.2.2 misho 489: /* Indicate out-of-memory and exit. */
490: static void shell_out_of_memory(void){
491: raw_printf(stderr,"Error: out of memory\n");
492: exit(1);
493: }
494:
1.4.2.3 ! misho 495: #ifdef SQLITE_DEBUG
! 496: /* This routine is called when a simulated OOM occurs. It is broken
! 497: ** out as a separate routine to make it easy to set a breakpoint on
! 498: ** the OOM
! 499: */
! 500: void shellOomFault(void){
! 501: if( oomRepeat>0 ){
! 502: oomRepeat--;
! 503: }else{
! 504: oomCounter--;
! 505: }
! 506: }
! 507: #endif /* SQLITE_DEBUG */
! 508:
! 509: #ifdef SQLITE_DEBUG
! 510: /* This routine is a replacement malloc() that is used to simulate
! 511: ** Out-Of-Memory (OOM) errors for testing purposes.
! 512: */
! 513: static void *oomMalloc(int nByte){
! 514: if( oomCounter ){
! 515: if( oomCounter==1 ){
! 516: shellOomFault();
! 517: return 0;
! 518: }else{
! 519: oomCounter--;
! 520: }
! 521: }
! 522: return defaultMalloc(nByte);
! 523: }
! 524: #endif /* SQLITE_DEBUG */
! 525:
! 526: #ifdef SQLITE_DEBUG
! 527: /* Register the OOM simulator. This must occur before any memory
! 528: ** allocations */
! 529: static void registerOomSimulator(void){
! 530: sqlite3_mem_methods mem;
! 531: sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem);
! 532: defaultMalloc = mem.xMalloc;
! 533: mem.xMalloc = oomMalloc;
! 534: sqlite3_config(SQLITE_CONFIG_MALLOC, &mem);
! 535: }
! 536: #endif
! 537:
1.4 misho 538: /*
1.2 misho 539: ** Write I/O traces to the following stream.
540: */
541: #ifdef SQLITE_ENABLE_IOTRACE
542: static FILE *iotrace = 0;
543: #endif
544:
545: /*
546: ** This routine works like printf in that its first argument is a
547: ** format string and subsequent arguments are values to be substituted
548: ** in place of % fields. The result of formatting this string
549: ** is written to iotrace.
550: */
551: #ifdef SQLITE_ENABLE_IOTRACE
1.4 misho 552: static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
1.2 misho 553: va_list ap;
554: char *z;
555: if( iotrace==0 ) return;
556: va_start(ap, zFormat);
557: z = sqlite3_vmprintf(zFormat, ap);
558: va_end(ap);
1.4 misho 559: utf8_printf(iotrace, "%s", z);
1.2 misho 560: sqlite3_free(z);
561: }
562: #endif
563:
1.4.2.1 misho 564: /*
565: ** Output string zUtf to stream pOut as w characters. If w is negative,
566: ** then right-justify the text. W is the width in UTF-8 characters, not
567: ** in bytes. This is different from the %*.*s specification in printf
568: ** since with %*.*s the width is measured in bytes, not characters.
569: */
570: static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
571: int i;
572: int n;
573: int aw = w<0 ? -w : w;
574: char zBuf[1000];
575: if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
576: for(i=n=0; zUtf[i]; i++){
577: if( (zUtf[i]&0xc0)!=0x80 ){
578: n++;
579: if( n==aw ){
580: do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
581: break;
582: }
583: }
584: }
585: if( n>=aw ){
586: utf8_printf(pOut, "%.*s", i, zUtf);
587: }else if( w<0 ){
588: utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
589: }else{
590: utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
591: }
592: }
593:
1.2 misho 594:
595: /*
596: ** Determines if a string is a number of not.
597: */
598: static int isNumber(const char *z, int *realnum){
599: if( *z=='-' || *z=='+' ) z++;
600: if( !IsDigit(*z) ){
601: return 0;
602: }
603: z++;
604: if( realnum ) *realnum = 0;
605: while( IsDigit(*z) ){ z++; }
606: if( *z=='.' ){
607: z++;
608: if( !IsDigit(*z) ) return 0;
609: while( IsDigit(*z) ){ z++; }
610: if( realnum ) *realnum = 1;
611: }
612: if( *z=='e' || *z=='E' ){
613: z++;
614: if( *z=='+' || *z=='-' ) z++;
615: if( !IsDigit(*z) ) return 0;
616: while( IsDigit(*z) ){ z++; }
617: if( realnum ) *realnum = 1;
618: }
619: return *z==0;
620: }
621:
622: /*
1.4 misho 623: ** Compute a string length that is limited to what can be stored in
624: ** lower 30 bits of a 32-bit signed integer.
625: */
626: static int strlen30(const char *z){
627: const char *z2 = z;
628: while( *z2 ){ z2++; }
629: return 0x3fffffff & (int)(z2 - z);
630: }
631:
632: /*
1.4.2.2 misho 633: ** Return the length of a string in characters. Multibyte UTF8 characters
634: ** count as a single character.
635: */
636: static int strlenChar(const char *z){
637: int n = 0;
638: while( *z ){
639: if( (0xc0&*(z++))!=0x80 ) n++;
640: }
641: return n;
642: }
643:
644: /*
1.4.2.3 ! misho 645: ** Return true if zFile does not exist or if it is not an ordinary file.
! 646: */
! 647: #ifdef _WIN32
! 648: # define notNormalFile(X) 0
! 649: #else
! 650: static int notNormalFile(const char *zFile){
! 651: struct stat x;
! 652: int rc;
! 653: memset(&x, 0, sizeof(x));
! 654: rc = stat(zFile, &x);
! 655: return rc || !S_ISREG(x.st_mode);
! 656: }
! 657: #endif
! 658:
! 659: /*
1.2 misho 660: ** This routine reads a line of text from FILE in, stores
661: ** the text in memory obtained from malloc() and returns a pointer
662: ** to the text. NULL is returned at end of file, or if malloc()
663: ** fails.
664: **
1.4 misho 665: ** If zLine is not NULL then it is a malloced buffer returned from
666: ** a previous call to this routine that may be reused.
1.2 misho 667: */
1.4 misho 668: static char *local_getline(char *zLine, FILE *in){
669: int nLine = zLine==0 ? 0 : 100;
670: int n = 0;
1.2 misho 671:
672: while( 1 ){
673: if( n+100>nLine ){
674: nLine = nLine*2 + 100;
675: zLine = realloc(zLine, nLine);
1.4.2.2 misho 676: if( zLine==0 ) shell_out_of_memory();
1.2 misho 677: }
678: if( fgets(&zLine[n], nLine - n, in)==0 ){
679: if( n==0 ){
680: free(zLine);
681: return 0;
682: }
683: zLine[n] = 0;
684: break;
685: }
1.4 misho 686: while( zLine[n] ) n++;
687: if( n>0 && zLine[n-1]=='\n' ){
1.2 misho 688: n--;
689: if( n>0 && zLine[n-1]=='\r' ) n--;
690: zLine[n] = 0;
691: break;
692: }
693: }
1.4 misho 694: #if defined(_WIN32) || defined(WIN32)
695: /* For interactive input on Windows systems, translate the
696: ** multi-byte characterset characters into UTF-8. */
697: if( stdin_is_interactive && in==stdin ){
698: char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
699: if( zTrans ){
700: int nTrans = strlen30(zTrans)+1;
701: if( nTrans>nLine ){
702: zLine = realloc(zLine, nTrans);
1.4.2.2 misho 703: if( zLine==0 ) shell_out_of_memory();
1.4 misho 704: }
705: memcpy(zLine, zTrans, nTrans);
706: sqlite3_free(zTrans);
707: }
708: }
709: #endif /* defined(_WIN32) || defined(WIN32) */
1.2 misho 710: return zLine;
711: }
712:
713: /*
714: ** Retrieve a single line of input text.
715: **
1.4 misho 716: ** If in==0 then read from standard input and prompt before each line.
717: ** If isContinuation is true, then a continuation prompt is appropriate.
718: ** If isContinuation is zero, then the main prompt should be used.
719: **
720: ** If zPrior is not NULL then it is a buffer from a prior call to this
721: ** routine that can be reused.
722: **
723: ** The result is stored in space obtained from malloc() and must either
724: ** be freed by the caller or else passed back into this routine via the
725: ** zPrior argument for reuse.
1.2 misho 726: */
1.4 misho 727: static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
1.2 misho 728: char *zPrompt;
729: char *zResult;
730: if( in!=0 ){
1.4 misho 731: zResult = local_getline(zPrior, in);
1.2 misho 732: }else{
1.4 misho 733: zPrompt = isContinuation ? continuePrompt : mainPrompt;
734: #if SHELL_USE_LOCAL_GETLINE
735: printf("%s", zPrompt);
736: fflush(stdout);
737: zResult = local_getline(zPrior, stdin);
738: #else
739: free(zPrior);
740: zResult = shell_readline(zPrompt);
741: if( zResult && *zResult ) shell_add_history(zResult);
742: #endif
1.2 misho 743: }
744: return zResult;
745: }
1.4.2.2 misho 746:
747:
748: /*
749: ** Return the value of a hexadecimal digit. Return -1 if the input
750: ** is not a hex digit.
751: */
752: static int hexDigitValue(char c){
753: if( c>='0' && c<='9' ) return c - '0';
754: if( c>='a' && c<='f' ) return c - 'a' + 10;
755: if( c>='A' && c<='F' ) return c - 'A' + 10;
756: return -1;
757: }
758:
759: /*
760: ** Interpret zArg as an integer value, possibly with suffixes.
761: */
762: static sqlite3_int64 integerValue(const char *zArg){
763: sqlite3_int64 v = 0;
764: static const struct { char *zSuffix; int iMult; } aMult[] = {
765: { "KiB", 1024 },
766: { "MiB", 1024*1024 },
767: { "GiB", 1024*1024*1024 },
768: { "KB", 1000 },
769: { "MB", 1000000 },
770: { "GB", 1000000000 },
771: { "K", 1000 },
772: { "M", 1000000 },
773: { "G", 1000000000 },
774: };
775: int i;
776: int isNeg = 0;
777: if( zArg[0]=='-' ){
778: isNeg = 1;
779: zArg++;
780: }else if( zArg[0]=='+' ){
781: zArg++;
782: }
783: if( zArg[0]=='0' && zArg[1]=='x' ){
784: int x;
785: zArg += 2;
786: while( (x = hexDigitValue(zArg[0]))>=0 ){
787: v = (v<<4) + x;
788: zArg++;
789: }
790: }else{
791: while( IsDigit(zArg[0]) ){
792: v = v*10 + zArg[0] - '0';
793: zArg++;
794: }
795: }
796: for(i=0; i<ArraySize(aMult); i++){
797: if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
798: v *= aMult[i].iMult;
799: break;
800: }
801: }
802: return isNeg? -v : v;
803: }
804:
1.4.2.1 misho 805: /*
806: ** A variable length string to which one can append text.
807: */
808: typedef struct ShellText ShellText;
809: struct ShellText {
810: char *z;
811: int n;
812: int nAlloc;
813: };
814:
815: /*
816: ** Initialize and destroy a ShellText object
817: */
818: static void initText(ShellText *p){
819: memset(p, 0, sizeof(*p));
820: }
821: static void freeText(ShellText *p){
822: free(p->z);
823: initText(p);
824: }
825:
826: /* zIn is either a pointer to a NULL-terminated string in memory obtained
827: ** from malloc(), or a NULL pointer. The string pointed to by zAppend is
828: ** added to zIn, and the result returned in memory obtained from malloc().
829: ** zIn, if it was not NULL, is freed.
830: **
831: ** If the third argument, quote, is not '\0', then it is used as a
832: ** quote character for zAppend.
833: */
834: static void appendText(ShellText *p, char const *zAppend, char quote){
835: int len;
836: int i;
837: int nAppend = strlen30(zAppend);
838:
839: len = nAppend+p->n+1;
840: if( quote ){
841: len += 2;
842: for(i=0; i<nAppend; i++){
843: if( zAppend[i]==quote ) len++;
844: }
845: }
846:
847: if( p->n+len>=p->nAlloc ){
848: p->nAlloc = p->nAlloc*2 + len + 20;
849: p->z = realloc(p->z, p->nAlloc);
1.4.2.2 misho 850: if( p->z==0 ) shell_out_of_memory();
1.4.2.1 misho 851: }
852:
853: if( quote ){
854: char *zCsr = p->z+p->n;
855: *zCsr++ = quote;
856: for(i=0; i<nAppend; i++){
857: *zCsr++ = zAppend[i];
858: if( zAppend[i]==quote ) *zCsr++ = quote;
859: }
860: *zCsr++ = quote;
861: p->n = (int)(zCsr - p->z);
862: *zCsr = '\0';
863: }else{
864: memcpy(p->z+p->n, zAppend, nAppend);
865: p->n += nAppend;
866: p->z[p->n] = '\0';
867: }
868: }
869:
870: /*
871: ** Attempt to determine if identifier zName needs to be quoted, either
872: ** because it contains non-alphanumeric characters, or because it is an
873: ** SQLite keyword. Be conservative in this estimate: When in doubt assume
874: ** that quoting is required.
875: **
876: ** Return '"' if quoting is required. Return 0 if no quoting is required.
877: */
878: static char quoteChar(const char *zName){
1.4.2.2 misho 879: int i;
1.4.2.1 misho 880: if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
881: for(i=0; zName[i]; i++){
882: if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
883: }
1.4.2.2 misho 884: return sqlite3_keyword_check(zName, i) ? '"' : 0;
885: }
886:
887: /*
888: ** Construct a fake object name and column list to describe the structure
889: ** of the view, virtual table, or table valued function zSchema.zName.
890: */
891: static char *shellFakeSchema(
892: sqlite3 *db, /* The database connection containing the vtab */
893: const char *zSchema, /* Schema of the database holding the vtab */
894: const char *zName /* The name of the virtual table */
895: ){
896: sqlite3_stmt *pStmt = 0;
897: char *zSql;
898: ShellText s;
899: char cQuote;
900: char *zDiv = "(";
901: int nRow = 0;
902:
903: zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;",
904: zSchema ? zSchema : "main", zName);
905: sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
906: sqlite3_free(zSql);
907: initText(&s);
908: if( zSchema ){
909: cQuote = quoteChar(zSchema);
910: if( cQuote && sqlite3_stricmp(zSchema,"temp")==0 ) cQuote = 0;
911: appendText(&s, zSchema, cQuote);
912: appendText(&s, ".", 0);
913: }
914: cQuote = quoteChar(zName);
915: appendText(&s, zName, cQuote);
916: while( sqlite3_step(pStmt)==SQLITE_ROW ){
917: const char *zCol = (const char*)sqlite3_column_text(pStmt, 1);
918: nRow++;
919: appendText(&s, zDiv, 0);
920: zDiv = ",";
921: cQuote = quoteChar(zCol);
922: appendText(&s, zCol, cQuote);
923: }
924: appendText(&s, ")", 0);
925: sqlite3_finalize(pStmt);
926: if( nRow==0 ){
927: freeText(&s);
928: s.z = 0;
929: }
930: return s.z;
931: }
932:
933: /*
934: ** SQL function: shell_module_schema(X)
935: **
936: ** Return a fake schema for the table-valued function or eponymous virtual
937: ** table X.
938: */
939: static void shellModuleSchema(
940: sqlite3_context *pCtx,
941: int nVal,
942: sqlite3_value **apVal
943: ){
944: const char *zName = (const char*)sqlite3_value_text(apVal[0]);
945: char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName);
946: UNUSED_PARAMETER(nVal);
947: if( zFake ){
948: sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
949: -1, sqlite3_free);
950: free(zFake);
951: }
952: }
953:
954: /*
955: ** SQL function: shell_add_schema(S,X)
956: **
957: ** Add the schema name X to the CREATE statement in S and return the result.
958: ** Examples:
959: **
960: ** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x);
961: **
962: ** Also works on
963: **
964: ** CREATE INDEX
965: ** CREATE UNIQUE INDEX
966: ** CREATE VIEW
967: ** CREATE TRIGGER
968: ** CREATE VIRTUAL TABLE
969: **
970: ** This UDF is used by the .schema command to insert the schema name of
1.4.2.3 ! misho 971: ** attached databases into the middle of the sqlite_schema.sql field.
1.4.2.2 misho 972: */
973: static void shellAddSchemaName(
974: sqlite3_context *pCtx,
975: int nVal,
976: sqlite3_value **apVal
977: ){
978: static const char *aPrefix[] = {
979: "TABLE",
980: "INDEX",
981: "UNIQUE INDEX",
982: "VIEW",
983: "TRIGGER",
984: "VIRTUAL TABLE"
985: };
986: int i = 0;
987: const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
988: const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
989: const char *zName = (const char*)sqlite3_value_text(apVal[2]);
990: sqlite3 *db = sqlite3_context_db_handle(pCtx);
991: UNUSED_PARAMETER(nVal);
992: if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
993: for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
994: int n = strlen30(aPrefix[i]);
995: if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
996: char *z = 0;
997: char *zFake = 0;
998: if( zSchema ){
999: char cQuote = quoteChar(zSchema);
1000: if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){
1001: z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
1002: }else{
1003: z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
1004: }
1005: }
1006: if( zName
1007: && aPrefix[i][0]=='V'
1008: && (zFake = shellFakeSchema(db, zSchema, zName))!=0
1009: ){
1010: if( z==0 ){
1011: z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
1012: }else{
1013: z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
1014: }
1015: free(zFake);
1016: }
1017: if( z ){
1018: sqlite3_result_text(pCtx, z, -1, sqlite3_free);
1019: return;
1020: }
1021: }
1.4.2.1 misho 1022: }
1023: }
1.4.2.2 misho 1024: sqlite3_result_value(pCtx, apVal[0]);
1.4.2.1 misho 1025: }
1026:
1.4.2.2 misho 1027: /*
1028: ** The source code for several run-time loadable extensions is inserted
1029: ** below by the ../tool/mkshellc.tcl script. Before processing that included
1030: ** code, we need to override some macros to make the included program code
1031: ** work here in the middle of this regular program.
1.4.2.1 misho 1032: */
1.4.2.2 misho 1033: #define SQLITE_EXTENSION_INIT1
1034: #define SQLITE_EXTENSION_INIT2(X) (void)(X)
1035:
1036: #if defined(_WIN32) && defined(_MSC_VER)
1037: /************************* Begin test_windirent.h ******************/
1.4.2.1 misho 1038: /*
1.4.2.2 misho 1039: ** 2015 November 30
1.4.2.1 misho 1040: **
1.4.2.2 misho 1041: ** The author disclaims copyright to this source code. In place of
1042: ** a legal notice, here is a blessing:
1043: **
1044: ** May you do good and not evil.
1045: ** May you find forgiveness for yourself and forgive others.
1046: ** May you share freely, never taking more than you give.
1047: **
1048: *************************************************************************
1049: ** This file contains declarations for most of the opendir() family of
1050: ** POSIX functions on Win32 using the MSVCRT.
1.4.2.1 misho 1051: */
1.4.2.2 misho 1052:
1053: #if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H)
1054: #define SQLITE_WINDIRENT_H
1055:
1056: /*
1057: ** We need several data types from the Windows SDK header.
1058: */
1059:
1060: #ifndef WIN32_LEAN_AND_MEAN
1061: #define WIN32_LEAN_AND_MEAN
1.4.2.1 misho 1062: #endif
1063:
1.4.2.2 misho 1064: #include "windows.h"
1.4.2.1 misho 1065:
1066: /*
1.4.2.2 misho 1067: ** We need several support functions from the SQLite core.
1.4.2.1 misho 1068: */
1069:
1.4.2.2 misho 1070: /* #include "sqlite3.h" */
1.4.2.1 misho 1071:
1072: /*
1.4.2.2 misho 1073: ** We need several things from the ANSI and MSVCRT headers.
1.4.2.1 misho 1074: */
1075:
1.4.2.2 misho 1076: #include <stdio.h>
1077: #include <stdlib.h>
1078: #include <errno.h>
1079: #include <io.h>
1080: #include <limits.h>
1081: #include <sys/types.h>
1082: #include <sys/stat.h>
1.4.2.1 misho 1083:
1084: /*
1.4.2.2 misho 1085: ** We may need several defines that should have been in "sys/stat.h".
1.4.2.1 misho 1086: */
1.4.2.2 misho 1087:
1088: #ifndef S_ISREG
1089: #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
1090: #endif
1091:
1092: #ifndef S_ISDIR
1093: #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
1094: #endif
1095:
1096: #ifndef S_ISLNK
1097: #define S_ISLNK(mode) (0)
1.4.2.1 misho 1098: #endif
1099:
1100: /*
1.4.2.2 misho 1101: ** We may need to provide the "mode_t" type.
1.4.2.1 misho 1102: */
1.4.2.2 misho 1103:
1104: #ifndef MODE_T_DEFINED
1105: #define MODE_T_DEFINED
1106: typedef unsigned short mode_t;
1.4.2.1 misho 1107: #endif
1.4.2.2 misho 1108:
1109: /*
1110: ** We may need to provide the "ino_t" type.
1111: */
1112:
1113: #ifndef INO_T_DEFINED
1114: #define INO_T_DEFINED
1115: typedef unsigned short ino_t;
1.4.2.1 misho 1116: #endif
1.4.2.2 misho 1117:
1118: /*
1119: ** We need to define "NAME_MAX" if it was not present in "limits.h".
1120: */
1121:
1122: #ifndef NAME_MAX
1123: # ifdef FILENAME_MAX
1124: # define NAME_MAX (FILENAME_MAX)
1125: # else
1126: # define NAME_MAX (260)
1127: # endif
1128: #endif
1129:
1130: /*
1131: ** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T".
1132: */
1133:
1134: #ifndef NULL_INTPTR_T
1135: # define NULL_INTPTR_T ((intptr_t)(0))
1136: #endif
1137:
1138: #ifndef BAD_INTPTR_T
1139: # define BAD_INTPTR_T ((intptr_t)(-1))
1140: #endif
1141:
1142: /*
1143: ** We need to provide the necessary structures and related types.
1144: */
1145:
1146: #ifndef DIRENT_DEFINED
1147: #define DIRENT_DEFINED
1148: typedef struct DIRENT DIRENT;
1149: typedef DIRENT *LPDIRENT;
1150: struct DIRENT {
1151: ino_t d_ino; /* Sequence number, do not use. */
1152: unsigned d_attributes; /* Win32 file attributes. */
1153: char d_name[NAME_MAX + 1]; /* Name within the directory. */
1154: };
1155: #endif
1156:
1157: #ifndef DIR_DEFINED
1158: #define DIR_DEFINED
1159: typedef struct DIR DIR;
1160: typedef DIR *LPDIR;
1161: struct DIR {
1162: intptr_t d_handle; /* Value returned by "_findfirst". */
1163: DIRENT d_first; /* DIRENT constructed based on "_findfirst". */
1164: DIRENT d_next; /* DIRENT constructed based on "_findnext". */
1165: };
1166: #endif
1167:
1168: /*
1169: ** Provide a macro, for use by the implementation, to determine if a
1170: ** particular directory entry should be skipped over when searching for
1171: ** the next directory entry that should be returned by the readdir() or
1172: ** readdir_r() functions.
1173: */
1174:
1175: #ifndef is_filtered
1176: # define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM))
1177: #endif
1178:
1179: /*
1180: ** Provide the function prototype for the POSIX compatiable getenv()
1181: ** function. This function is not thread-safe.
1182: */
1183:
1184: extern const char *windirent_getenv(const char *name);
1185:
1186: /*
1187: ** Finally, we can provide the function prototypes for the opendir(),
1188: ** readdir(), readdir_r(), and closedir() POSIX functions.
1189: */
1190:
1191: extern LPDIR opendir(const char *dirname);
1192: extern LPDIRENT readdir(LPDIR dirp);
1193: extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result);
1194: extern INT closedir(LPDIR dirp);
1195:
1196: #endif /* defined(WIN32) && defined(_MSC_VER) */
1197:
1198: /************************* End test_windirent.h ********************/
1199: /************************* Begin test_windirent.c ******************/
1200: /*
1201: ** 2015 November 30
1202: **
1203: ** The author disclaims copyright to this source code. In place of
1204: ** a legal notice, here is a blessing:
1205: **
1206: ** May you do good and not evil.
1207: ** May you find forgiveness for yourself and forgive others.
1208: ** May you share freely, never taking more than you give.
1209: **
1210: *************************************************************************
1211: ** This file contains code to implement most of the opendir() family of
1212: ** POSIX functions on Win32 using the MSVCRT.
1213: */
1214:
1215: #if defined(_WIN32) && defined(_MSC_VER)
1216: /* #include "test_windirent.h" */
1217:
1218: /*
1219: ** Implementation of the POSIX getenv() function using the Win32 API.
1220: ** This function is not thread-safe.
1221: */
1222: const char *windirent_getenv(
1223: const char *name
1224: ){
1225: static char value[32768]; /* Maximum length, per MSDN */
1226: DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */
1227: DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */
1228:
1229: memset(value, 0, sizeof(value));
1230: dwRet = GetEnvironmentVariableA(name, value, dwSize);
1231: if( dwRet==0 || dwRet>dwSize ){
1232: /*
1233: ** The function call to GetEnvironmentVariableA() failed -OR-
1234: ** the buffer is not large enough. Either way, return NULL.
1235: */
1236: return 0;
1237: }else{
1238: /*
1239: ** The function call to GetEnvironmentVariableA() succeeded
1240: ** -AND- the buffer contains the entire value.
1241: */
1242: return value;
1.4.2.1 misho 1243: }
1244: }
1245:
1246: /*
1.4.2.2 misho 1247: ** Implementation of the POSIX opendir() function using the MSVCRT.
1.4.2.1 misho 1248: */
1.4.2.2 misho 1249: LPDIR opendir(
1250: const char *dirname
1251: ){
1252: struct _finddata_t data;
1253: LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
1254: SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
1255:
1256: if( dirp==NULL ) return NULL;
1257: memset(dirp, 0, sizeof(DIR));
1258:
1259: /* TODO: Remove this if Unix-style root paths are not used. */
1260: if( sqlite3_stricmp(dirname, "/")==0 ){
1261: dirname = windirent_getenv("SystemDrive");
1.4.2.1 misho 1262: }
1.4.2.2 misho 1263:
1264: memset(&data, 0, sizeof(struct _finddata_t));
1265: _snprintf(data.name, namesize, "%s\\*", dirname);
1266: dirp->d_handle = _findfirst(data.name, &data);
1267:
1268: if( dirp->d_handle==BAD_INTPTR_T ){
1269: closedir(dirp);
1270: return NULL;
1.4.2.1 misho 1271: }
1.4.2.2 misho 1272:
1273: /* TODO: Remove this block to allow hidden and/or system files. */
1274: if( is_filtered(data) ){
1275: next:
1276:
1277: memset(&data, 0, sizeof(struct _finddata_t));
1278: if( _findnext(dirp->d_handle, &data)==-1 ){
1279: closedir(dirp);
1280: return NULL;
1281: }
1282:
1283: /* TODO: Remove this block to allow hidden and/or system files. */
1284: if( is_filtered(data) ) goto next;
1285: }
1286:
1287: dirp->d_first.d_attributes = data.attrib;
1288: strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
1289: dirp->d_first.d_name[NAME_MAX] = '\0';
1290:
1291: return dirp;
1.4.2.1 misho 1292: }
1293:
1294: /*
1.4.2.2 misho 1295: ** Implementation of the POSIX readdir() function using the MSVCRT.
1.4.2.1 misho 1296: */
1.4.2.2 misho 1297: LPDIRENT readdir(
1298: LPDIR dirp
1.4.2.1 misho 1299: ){
1.4.2.2 misho 1300: struct _finddata_t data;
1301:
1302: if( dirp==NULL ) return NULL;
1303:
1304: if( dirp->d_first.d_ino==0 ){
1305: dirp->d_first.d_ino++;
1306: dirp->d_next.d_ino++;
1307:
1308: return &dirp->d_first;
1.4.2.1 misho 1309: }
1.4.2.2 misho 1310:
1311: next:
1312:
1313: memset(&data, 0, sizeof(struct _finddata_t));
1314: if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
1315:
1316: /* TODO: Remove this block to allow hidden and/or system files. */
1317: if( is_filtered(data) ) goto next;
1318:
1319: dirp->d_next.d_ino++;
1320: dirp->d_next.d_attributes = data.attrib;
1321: strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
1322: dirp->d_next.d_name[NAME_MAX] = '\0';
1323:
1324: return &dirp->d_next;
1325: }
1326:
1327: /*
1328: ** Implementation of the POSIX readdir_r() function using the MSVCRT.
1329: */
1330: INT readdir_r(
1331: LPDIR dirp,
1332: LPDIRENT entry,
1333: LPDIRENT *result
1334: ){
1335: struct _finddata_t data;
1336:
1337: if( dirp==NULL ) return EBADF;
1338:
1339: if( dirp->d_first.d_ino==0 ){
1340: dirp->d_first.d_ino++;
1341: dirp->d_next.d_ino++;
1342:
1343: entry->d_ino = dirp->d_first.d_ino;
1344: entry->d_attributes = dirp->d_first.d_attributes;
1345: strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
1346: entry->d_name[NAME_MAX] = '\0';
1347:
1348: *result = entry;
1349: return 0;
1.4.2.1 misho 1350: }
1.4.2.2 misho 1351:
1352: next:
1353:
1354: memset(&data, 0, sizeof(struct _finddata_t));
1355: if( _findnext(dirp->d_handle, &data)==-1 ){
1356: *result = NULL;
1357: return ENOENT;
1358: }
1359:
1360: /* TODO: Remove this block to allow hidden and/or system files. */
1361: if( is_filtered(data) ) goto next;
1362:
1363: entry->d_ino = (ino_t)-1; /* not available */
1364: entry->d_attributes = data.attrib;
1365: strncpy(entry->d_name, data.name, NAME_MAX);
1366: entry->d_name[NAME_MAX] = '\0';
1367:
1368: *result = entry;
1369: return 0;
1.4.2.1 misho 1370: }
1371:
1.4.2.2 misho 1372: /*
1373: ** Implementation of the POSIX closedir() function using the MSVCRT.
1.4.2.1 misho 1374: */
1.4.2.2 misho 1375: INT closedir(
1376: LPDIR dirp
1.4.2.1 misho 1377: ){
1.4.2.2 misho 1378: INT result = 0;
1379:
1380: if( dirp==NULL ) return EINVAL;
1381:
1382: if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
1383: result = _findclose(dirp->d_handle);
1384: }
1385:
1386: sqlite3_free(dirp);
1387: return result;
1.4.2.1 misho 1388: }
1389:
1.4.2.2 misho 1390: #endif /* defined(WIN32) && defined(_MSC_VER) */
1391:
1392: /************************* End test_windirent.c ********************/
1393: #define dirent DIRENT
1394: #endif
1395: /************************* Begin ../ext/misc/shathree.c ******************/
1.4.2.1 misho 1396: /*
1.4.2.2 misho 1397: ** 2017-03-08
1.4.2.1 misho 1398: **
1.4.2.2 misho 1399: ** The author disclaims copyright to this source code. In place of
1400: ** a legal notice, here is a blessing:
1.4.2.1 misho 1401: **
1.4.2.2 misho 1402: ** May you do good and not evil.
1403: ** May you find forgiveness for yourself and forgive others.
1404: ** May you share freely, never taking more than you give.
1.4.2.1 misho 1405: **
1.4.2.2 misho 1406: ******************************************************************************
1.4.2.1 misho 1407: **
1.4.2.2 misho 1408: ** This SQLite extension implements functions that compute SHA3 hashes.
1409: ** Two SQL functions are implemented:
1.4.2.1 misho 1410: **
1.4.2.2 misho 1411: ** sha3(X,SIZE)
1412: ** sha3_query(Y,SIZE)
1413: **
1414: ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
1415: ** X is NULL.
1416: **
1417: ** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
1418: ** and returns a hash of their results.
1419: **
1420: ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
1421: ** is used. If SIZE is included it must be one of the integers 224, 256,
1422: ** 384, or 512, to determine SHA3 hash variant that is computed.
1.4.2.1 misho 1423: */
1.4.2.2 misho 1424: /* #include "sqlite3ext.h" */
1425: SQLITE_EXTENSION_INIT1
1426: #include <assert.h>
1427: #include <string.h>
1428: #include <stdarg.h>
1429: /* typedef sqlite3_uint64 u64; */
1.4.2.1 misho 1430:
1.4.2.2 misho 1431: /******************************************************************************
1432: ** The Hash Engine
1433: */
1.4 misho 1434: /*
1.4.2.2 misho 1435: ** Macros to determine whether the machine is big or little endian,
1436: ** and whether or not that determination is run-time or compile-time.
1437: **
1438: ** For best performance, an attempt is made to guess at the byte-order
1439: ** using C-preprocessor macros. If that is unsuccessful, or if
1440: ** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
1441: ** at run-time.
1.4 misho 1442: */
1.4.2.2 misho 1443: #ifndef SHA3_BYTEORDER
1444: # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
1445: defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
1446: defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
1447: defined(__arm__)
1448: # define SHA3_BYTEORDER 1234
1449: # elif defined(sparc) || defined(__ppc__)
1450: # define SHA3_BYTEORDER 4321
1451: # else
1452: # define SHA3_BYTEORDER 0
1453: # endif
1.4 misho 1454: #endif
1455:
1.4.2.2 misho 1456:
1.4 misho 1457: /*
1.4.2.2 misho 1458: ** State structure for a SHA3 hash in progress
1.4 misho 1459: */
1.4.2.2 misho 1460: typedef struct SHA3Context SHA3Context;
1461: struct SHA3Context {
1462: union {
1463: u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */
1464: unsigned char x[1600]; /* ... or 1600 bytes */
1465: } u;
1466: unsigned nRate; /* Bytes of input accepted per Keccak iteration */
1467: unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
1468: unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
1.2 misho 1469: };
1470:
1471: /*
1.4.2.2 misho 1472: ** A single step of the Keccak mixing function for a 1600-bit state
1.2 misho 1473: */
1.4.2.2 misho 1474: static void KeccakF1600Step(SHA3Context *p){
1475: int i;
1476: u64 b0, b1, b2, b3, b4;
1477: u64 c0, c1, c2, c3, c4;
1478: u64 d0, d1, d2, d3, d4;
1479: static const u64 RC[] = {
1480: 0x0000000000000001ULL, 0x0000000000008082ULL,
1481: 0x800000000000808aULL, 0x8000000080008000ULL,
1482: 0x000000000000808bULL, 0x0000000080000001ULL,
1483: 0x8000000080008081ULL, 0x8000000000008009ULL,
1484: 0x000000000000008aULL, 0x0000000000000088ULL,
1485: 0x0000000080008009ULL, 0x000000008000000aULL,
1486: 0x000000008000808bULL, 0x800000000000008bULL,
1487: 0x8000000000008089ULL, 0x8000000000008003ULL,
1488: 0x8000000000008002ULL, 0x8000000000000080ULL,
1489: 0x000000000000800aULL, 0x800000008000000aULL,
1490: 0x8000000080008081ULL, 0x8000000000008080ULL,
1491: 0x0000000080000001ULL, 0x8000000080008008ULL
1492: };
1493: # define a00 (p->u.s[0])
1494: # define a01 (p->u.s[1])
1495: # define a02 (p->u.s[2])
1496: # define a03 (p->u.s[3])
1497: # define a04 (p->u.s[4])
1498: # define a10 (p->u.s[5])
1499: # define a11 (p->u.s[6])
1500: # define a12 (p->u.s[7])
1501: # define a13 (p->u.s[8])
1502: # define a14 (p->u.s[9])
1503: # define a20 (p->u.s[10])
1504: # define a21 (p->u.s[11])
1505: # define a22 (p->u.s[12])
1506: # define a23 (p->u.s[13])
1507: # define a24 (p->u.s[14])
1508: # define a30 (p->u.s[15])
1509: # define a31 (p->u.s[16])
1510: # define a32 (p->u.s[17])
1511: # define a33 (p->u.s[18])
1512: # define a34 (p->u.s[19])
1513: # define a40 (p->u.s[20])
1514: # define a41 (p->u.s[21])
1515: # define a42 (p->u.s[22])
1516: # define a43 (p->u.s[23])
1517: # define a44 (p->u.s[24])
1518: # define ROL64(a,x) ((a<<x)|(a>>(64-x)))
1519:
1520: for(i=0; i<24; i+=4){
1521: c0 = a00^a10^a20^a30^a40;
1522: c1 = a01^a11^a21^a31^a41;
1523: c2 = a02^a12^a22^a32^a42;
1524: c3 = a03^a13^a23^a33^a43;
1525: c4 = a04^a14^a24^a34^a44;
1526: d0 = c4^ROL64(c1, 1);
1527: d1 = c0^ROL64(c2, 1);
1528: d2 = c1^ROL64(c3, 1);
1529: d3 = c2^ROL64(c4, 1);
1530: d4 = c3^ROL64(c0, 1);
1531:
1532: b0 = (a00^d0);
1533: b1 = ROL64((a11^d1), 44);
1534: b2 = ROL64((a22^d2), 43);
1535: b3 = ROL64((a33^d3), 21);
1536: b4 = ROL64((a44^d4), 14);
1537: a00 = b0 ^((~b1)& b2 );
1538: a00 ^= RC[i];
1539: a11 = b1 ^((~b2)& b3 );
1540: a22 = b2 ^((~b3)& b4 );
1541: a33 = b3 ^((~b4)& b0 );
1542: a44 = b4 ^((~b0)& b1 );
1543:
1544: b2 = ROL64((a20^d0), 3);
1545: b3 = ROL64((a31^d1), 45);
1546: b4 = ROL64((a42^d2), 61);
1547: b0 = ROL64((a03^d3), 28);
1548: b1 = ROL64((a14^d4), 20);
1549: a20 = b0 ^((~b1)& b2 );
1550: a31 = b1 ^((~b2)& b3 );
1551: a42 = b2 ^((~b3)& b4 );
1552: a03 = b3 ^((~b4)& b0 );
1553: a14 = b4 ^((~b0)& b1 );
1554:
1555: b4 = ROL64((a40^d0), 18);
1556: b0 = ROL64((a01^d1), 1);
1557: b1 = ROL64((a12^d2), 6);
1558: b2 = ROL64((a23^d3), 25);
1559: b3 = ROL64((a34^d4), 8);
1560: a40 = b0 ^((~b1)& b2 );
1561: a01 = b1 ^((~b2)& b3 );
1562: a12 = b2 ^((~b3)& b4 );
1563: a23 = b3 ^((~b4)& b0 );
1564: a34 = b4 ^((~b0)& b1 );
1565:
1566: b1 = ROL64((a10^d0), 36);
1567: b2 = ROL64((a21^d1), 10);
1568: b3 = ROL64((a32^d2), 15);
1569: b4 = ROL64((a43^d3), 56);
1570: b0 = ROL64((a04^d4), 27);
1571: a10 = b0 ^((~b1)& b2 );
1572: a21 = b1 ^((~b2)& b3 );
1573: a32 = b2 ^((~b3)& b4 );
1574: a43 = b3 ^((~b4)& b0 );
1575: a04 = b4 ^((~b0)& b1 );
1576:
1577: b3 = ROL64((a30^d0), 41);
1578: b4 = ROL64((a41^d1), 2);
1579: b0 = ROL64((a02^d2), 62);
1580: b1 = ROL64((a13^d3), 55);
1581: b2 = ROL64((a24^d4), 39);
1582: a30 = b0 ^((~b1)& b2 );
1583: a41 = b1 ^((~b2)& b3 );
1584: a02 = b2 ^((~b3)& b4 );
1585: a13 = b3 ^((~b4)& b0 );
1586: a24 = b4 ^((~b0)& b1 );
1587:
1588: c0 = a00^a20^a40^a10^a30;
1589: c1 = a11^a31^a01^a21^a41;
1590: c2 = a22^a42^a12^a32^a02;
1591: c3 = a33^a03^a23^a43^a13;
1592: c4 = a44^a14^a34^a04^a24;
1593: d0 = c4^ROL64(c1, 1);
1594: d1 = c0^ROL64(c2, 1);
1595: d2 = c1^ROL64(c3, 1);
1596: d3 = c2^ROL64(c4, 1);
1597: d4 = c3^ROL64(c0, 1);
1598:
1599: b0 = (a00^d0);
1600: b1 = ROL64((a31^d1), 44);
1601: b2 = ROL64((a12^d2), 43);
1602: b3 = ROL64((a43^d3), 21);
1603: b4 = ROL64((a24^d4), 14);
1604: a00 = b0 ^((~b1)& b2 );
1605: a00 ^= RC[i+1];
1606: a31 = b1 ^((~b2)& b3 );
1607: a12 = b2 ^((~b3)& b4 );
1608: a43 = b3 ^((~b4)& b0 );
1609: a24 = b4 ^((~b0)& b1 );
1610:
1611: b2 = ROL64((a40^d0), 3);
1612: b3 = ROL64((a21^d1), 45);
1613: b4 = ROL64((a02^d2), 61);
1614: b0 = ROL64((a33^d3), 28);
1615: b1 = ROL64((a14^d4), 20);
1616: a40 = b0 ^((~b1)& b2 );
1617: a21 = b1 ^((~b2)& b3 );
1618: a02 = b2 ^((~b3)& b4 );
1619: a33 = b3 ^((~b4)& b0 );
1620: a14 = b4 ^((~b0)& b1 );
1621:
1622: b4 = ROL64((a30^d0), 18);
1623: b0 = ROL64((a11^d1), 1);
1624: b1 = ROL64((a42^d2), 6);
1625: b2 = ROL64((a23^d3), 25);
1626: b3 = ROL64((a04^d4), 8);
1627: a30 = b0 ^((~b1)& b2 );
1628: a11 = b1 ^((~b2)& b3 );
1629: a42 = b2 ^((~b3)& b4 );
1630: a23 = b3 ^((~b4)& b0 );
1631: a04 = b4 ^((~b0)& b1 );
1632:
1633: b1 = ROL64((a20^d0), 36);
1634: b2 = ROL64((a01^d1), 10);
1635: b3 = ROL64((a32^d2), 15);
1636: b4 = ROL64((a13^d3), 56);
1637: b0 = ROL64((a44^d4), 27);
1638: a20 = b0 ^((~b1)& b2 );
1639: a01 = b1 ^((~b2)& b3 );
1640: a32 = b2 ^((~b3)& b4 );
1641: a13 = b3 ^((~b4)& b0 );
1642: a44 = b4 ^((~b0)& b1 );
1643:
1644: b3 = ROL64((a10^d0), 41);
1645: b4 = ROL64((a41^d1), 2);
1646: b0 = ROL64((a22^d2), 62);
1647: b1 = ROL64((a03^d3), 55);
1648: b2 = ROL64((a34^d4), 39);
1649: a10 = b0 ^((~b1)& b2 );
1650: a41 = b1 ^((~b2)& b3 );
1651: a22 = b2 ^((~b3)& b4 );
1652: a03 = b3 ^((~b4)& b0 );
1653: a34 = b4 ^((~b0)& b1 );
1654:
1655: c0 = a00^a40^a30^a20^a10;
1656: c1 = a31^a21^a11^a01^a41;
1657: c2 = a12^a02^a42^a32^a22;
1658: c3 = a43^a33^a23^a13^a03;
1659: c4 = a24^a14^a04^a44^a34;
1660: d0 = c4^ROL64(c1, 1);
1661: d1 = c0^ROL64(c2, 1);
1662: d2 = c1^ROL64(c3, 1);
1663: d3 = c2^ROL64(c4, 1);
1664: d4 = c3^ROL64(c0, 1);
1665:
1666: b0 = (a00^d0);
1667: b1 = ROL64((a21^d1), 44);
1668: b2 = ROL64((a42^d2), 43);
1669: b3 = ROL64((a13^d3), 21);
1670: b4 = ROL64((a34^d4), 14);
1671: a00 = b0 ^((~b1)& b2 );
1672: a00 ^= RC[i+2];
1673: a21 = b1 ^((~b2)& b3 );
1674: a42 = b2 ^((~b3)& b4 );
1675: a13 = b3 ^((~b4)& b0 );
1676: a34 = b4 ^((~b0)& b1 );
1677:
1678: b2 = ROL64((a30^d0), 3);
1679: b3 = ROL64((a01^d1), 45);
1680: b4 = ROL64((a22^d2), 61);
1681: b0 = ROL64((a43^d3), 28);
1682: b1 = ROL64((a14^d4), 20);
1683: a30 = b0 ^((~b1)& b2 );
1684: a01 = b1 ^((~b2)& b3 );
1685: a22 = b2 ^((~b3)& b4 );
1686: a43 = b3 ^((~b4)& b0 );
1687: a14 = b4 ^((~b0)& b1 );
1688:
1689: b4 = ROL64((a10^d0), 18);
1690: b0 = ROL64((a31^d1), 1);
1691: b1 = ROL64((a02^d2), 6);
1692: b2 = ROL64((a23^d3), 25);
1693: b3 = ROL64((a44^d4), 8);
1694: a10 = b0 ^((~b1)& b2 );
1695: a31 = b1 ^((~b2)& b3 );
1696: a02 = b2 ^((~b3)& b4 );
1697: a23 = b3 ^((~b4)& b0 );
1698: a44 = b4 ^((~b0)& b1 );
1699:
1700: b1 = ROL64((a40^d0), 36);
1701: b2 = ROL64((a11^d1), 10);
1702: b3 = ROL64((a32^d2), 15);
1703: b4 = ROL64((a03^d3), 56);
1704: b0 = ROL64((a24^d4), 27);
1705: a40 = b0 ^((~b1)& b2 );
1706: a11 = b1 ^((~b2)& b3 );
1707: a32 = b2 ^((~b3)& b4 );
1708: a03 = b3 ^((~b4)& b0 );
1709: a24 = b4 ^((~b0)& b1 );
1710:
1711: b3 = ROL64((a20^d0), 41);
1712: b4 = ROL64((a41^d1), 2);
1713: b0 = ROL64((a12^d2), 62);
1714: b1 = ROL64((a33^d3), 55);
1715: b2 = ROL64((a04^d4), 39);
1716: a20 = b0 ^((~b1)& b2 );
1717: a41 = b1 ^((~b2)& b3 );
1718: a12 = b2 ^((~b3)& b4 );
1719: a33 = b3 ^((~b4)& b0 );
1720: a04 = b4 ^((~b0)& b1 );
1721:
1722: c0 = a00^a30^a10^a40^a20;
1723: c1 = a21^a01^a31^a11^a41;
1724: c2 = a42^a22^a02^a32^a12;
1725: c3 = a13^a43^a23^a03^a33;
1726: c4 = a34^a14^a44^a24^a04;
1727: d0 = c4^ROL64(c1, 1);
1728: d1 = c0^ROL64(c2, 1);
1729: d2 = c1^ROL64(c3, 1);
1730: d3 = c2^ROL64(c4, 1);
1731: d4 = c3^ROL64(c0, 1);
1732:
1733: b0 = (a00^d0);
1734: b1 = ROL64((a01^d1), 44);
1735: b2 = ROL64((a02^d2), 43);
1736: b3 = ROL64((a03^d3), 21);
1737: b4 = ROL64((a04^d4), 14);
1738: a00 = b0 ^((~b1)& b2 );
1739: a00 ^= RC[i+3];
1740: a01 = b1 ^((~b2)& b3 );
1741: a02 = b2 ^((~b3)& b4 );
1742: a03 = b3 ^((~b4)& b0 );
1743: a04 = b4 ^((~b0)& b1 );
1744:
1745: b2 = ROL64((a10^d0), 3);
1746: b3 = ROL64((a11^d1), 45);
1747: b4 = ROL64((a12^d2), 61);
1748: b0 = ROL64((a13^d3), 28);
1749: b1 = ROL64((a14^d4), 20);
1750: a10 = b0 ^((~b1)& b2 );
1751: a11 = b1 ^((~b2)& b3 );
1752: a12 = b2 ^((~b3)& b4 );
1753: a13 = b3 ^((~b4)& b0 );
1754: a14 = b4 ^((~b0)& b1 );
1755:
1756: b4 = ROL64((a20^d0), 18);
1757: b0 = ROL64((a21^d1), 1);
1758: b1 = ROL64((a22^d2), 6);
1759: b2 = ROL64((a23^d3), 25);
1760: b3 = ROL64((a24^d4), 8);
1761: a20 = b0 ^((~b1)& b2 );
1762: a21 = b1 ^((~b2)& b3 );
1763: a22 = b2 ^((~b3)& b4 );
1764: a23 = b3 ^((~b4)& b0 );
1765: a24 = b4 ^((~b0)& b1 );
1766:
1767: b1 = ROL64((a30^d0), 36);
1768: b2 = ROL64((a31^d1), 10);
1769: b3 = ROL64((a32^d2), 15);
1770: b4 = ROL64((a33^d3), 56);
1771: b0 = ROL64((a34^d4), 27);
1772: a30 = b0 ^((~b1)& b2 );
1773: a31 = b1 ^((~b2)& b3 );
1774: a32 = b2 ^((~b3)& b4 );
1775: a33 = b3 ^((~b4)& b0 );
1776: a34 = b4 ^((~b0)& b1 );
1777:
1778: b3 = ROL64((a40^d0), 41);
1779: b4 = ROL64((a41^d1), 2);
1780: b0 = ROL64((a42^d2), 62);
1781: b1 = ROL64((a43^d3), 55);
1782: b2 = ROL64((a44^d4), 39);
1783: a40 = b0 ^((~b1)& b2 );
1784: a41 = b1 ^((~b2)& b3 );
1785: a42 = b2 ^((~b3)& b4 );
1786: a43 = b3 ^((~b4)& b0 );
1787: a44 = b4 ^((~b0)& b1 );
1788: }
1789: }
1.2 misho 1790:
1791: /*
1.4.2.2 misho 1792: ** Initialize a new hash. iSize determines the size of the hash
1793: ** in bits and should be one of 224, 256, 384, or 512. Or iSize
1794: ** can be zero to use the default hash size of 256 bits.
1.4 misho 1795: */
1.4.2.2 misho 1796: static void SHA3Init(SHA3Context *p, int iSize){
1797: memset(p, 0, sizeof(*p));
1798: if( iSize>=128 && iSize<=512 ){
1799: p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
1800: }else{
1801: p->nRate = (1600 - 2*256)/8;
1802: }
1803: #if SHA3_BYTEORDER==1234
1804: /* Known to be little-endian at compile-time. No-op */
1805: #elif SHA3_BYTEORDER==4321
1806: p->ixMask = 7; /* Big-endian */
1807: #else
1808: {
1809: static unsigned int one = 1;
1810: if( 1==*(unsigned char*)&one ){
1811: /* Little endian. No byte swapping. */
1812: p->ixMask = 0;
1813: }else{
1814: /* Big endian. Byte swap. */
1815: p->ixMask = 7;
1816: }
1817: }
1818: #endif
1819: }
1.4.2.1 misho 1820:
1821: /*
1.4.2.2 misho 1822: ** Make consecutive calls to the SHA3Update function to add new content
1823: ** to the hash
1.4.2.1 misho 1824: */
1.4.2.2 misho 1825: static void SHA3Update(
1826: SHA3Context *p,
1827: const unsigned char *aData,
1828: unsigned int nData
1829: ){
1830: unsigned int i = 0;
1831: #if SHA3_BYTEORDER==1234
1832: if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
1833: for(; i+7<nData; i+=8){
1834: p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
1835: p->nLoaded += 8;
1836: if( p->nLoaded>=p->nRate ){
1837: KeccakF1600Step(p);
1838: p->nLoaded = 0;
1839: }
1840: }
1841: }
1842: #endif
1843: for(; i<nData; i++){
1844: #if SHA3_BYTEORDER==1234
1845: p->u.x[p->nLoaded] ^= aData[i];
1846: #elif SHA3_BYTEORDER==4321
1847: p->u.x[p->nLoaded^0x07] ^= aData[i];
1848: #else
1849: p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
1850: #endif
1851: p->nLoaded++;
1852: if( p->nLoaded==p->nRate ){
1853: KeccakF1600Step(p);
1854: p->nLoaded = 0;
1855: }
1856: }
1857: }
1.4 misho 1858:
1859: /*
1.4.2.2 misho 1860: ** After all content has been added, invoke SHA3Final() to compute
1861: ** the final hash. The function returns a pointer to the binary
1862: ** hash value.
1.2 misho 1863: */
1.4.2.2 misho 1864: static unsigned char *SHA3Final(SHA3Context *p){
1865: unsigned int i;
1866: if( p->nLoaded==p->nRate-1 ){
1867: const unsigned char c1 = 0x86;
1868: SHA3Update(p, &c1, 1);
1869: }else{
1870: const unsigned char c2 = 0x06;
1871: const unsigned char c3 = 0x80;
1872: SHA3Update(p, &c2, 1);
1873: p->nLoaded = p->nRate - 1;
1874: SHA3Update(p, &c3, 1);
1875: }
1876: for(i=0; i<p->nRate; i++){
1877: p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
1878: }
1879: return &p->u.x[p->nRate];
1.2 misho 1880: }
1.4.2.2 misho 1881: /* End of the hashing logic
1882: *****************************************************************************/
1.2 misho 1883:
1884: /*
1.4.2.2 misho 1885: ** Implementation of the sha3(X,SIZE) function.
1886: **
1887: ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default
1888: ** size is 256. If X is a BLOB, it is hashed as is.
1889: ** For all other non-NULL types of input, X is converted into a UTF-8 string
1890: ** and the string is hashed without the trailing 0x00 terminator. The hash
1891: ** of a NULL value is NULL.
1.2 misho 1892: */
1.4.2.2 misho 1893: static void sha3Func(
1894: sqlite3_context *context,
1895: int argc,
1896: sqlite3_value **argv
1897: ){
1898: SHA3Context cx;
1899: int eType = sqlite3_value_type(argv[0]);
1900: int nByte = sqlite3_value_bytes(argv[0]);
1901: int iSize;
1902: if( argc==1 ){
1903: iSize = 256;
1904: }else{
1905: iSize = sqlite3_value_int(argv[1]);
1906: if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
1907: sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
1908: "384 512", -1);
1909: return;
1910: }
1911: }
1912: if( eType==SQLITE_NULL ) return;
1913: SHA3Init(&cx, iSize);
1914: if( eType==SQLITE_BLOB ){
1915: SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte);
1916: }else{
1917: SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte);
1918: }
1919: sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
1.2 misho 1920: }
1921:
1.4.2.2 misho 1922: /* Compute a string using sqlite3_vsnprintf() with a maximum length
1923: ** of 50 bytes and add it to the hash.
1.4.2.1 misho 1924: */
1.4.2.2 misho 1925: static void hash_step_vformat(
1926: SHA3Context *p, /* Add content to this context */
1927: const char *zFormat,
1928: ...
1.4.2.1 misho 1929: ){
1.4.2.2 misho 1930: va_list ap;
1931: int n;
1932: char zBuf[50];
1933: va_start(ap, zFormat);
1934: sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
1935: va_end(ap);
1936: n = (int)strlen(zBuf);
1937: SHA3Update(p, (unsigned char*)zBuf, n);
1.4.2.1 misho 1938: }
1939:
1940: /*
1.4.2.2 misho 1941: ** Implementation of the sha3_query(SQL,SIZE) function.
1.4.2.1 misho 1942: **
1.4.2.2 misho 1943: ** This function compiles and runs the SQL statement(s) given in the
1944: ** argument. The results are hashed using a SIZE-bit SHA3. The default
1945: ** size is 256.
1946: **
1947: ** The format of the byte stream that is hashed is summarized as follows:
1948: **
1949: ** S<n>:<sql>
1950: ** R
1951: ** N
1952: ** I<int>
1953: ** F<ieee-float>
1954: ** B<size>:<bytes>
1955: ** T<size>:<text>
1956: **
1957: ** <sql> is the original SQL text for each statement run and <n> is
1958: ** the size of that text. The SQL text is UTF-8. A single R character
1959: ** occurs before the start of each row. N means a NULL value.
1960: ** I mean an 8-byte little-endian integer <int>. F is a floating point
1961: ** number with an 8-byte little-endian IEEE floating point value <ieee-float>.
1962: ** B means blobs of <size> bytes. T means text rendered as <size>
1963: ** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII
1964: ** text integers.
1965: **
1966: ** For each SQL statement in the X input, there is one S segment. Each
1967: ** S segment is followed by zero or more R segments, one for each row in the
1968: ** result set. After each R, there are one or more N, I, F, B, or T segments,
1969: ** one for each column in the result set. Segments are concatentated directly
1970: ** with no delimiters of any kind.
1.2 misho 1971: */
1.4.2.2 misho 1972: static void sha3QueryFunc(
1973: sqlite3_context *context,
1974: int argc,
1975: sqlite3_value **argv
1976: ){
1977: sqlite3 *db = sqlite3_context_db_handle(context);
1978: const char *zSql = (const char*)sqlite3_value_text(argv[0]);
1979: sqlite3_stmt *pStmt = 0;
1980: int nCol; /* Number of columns in the result set */
1981: int i; /* Loop counter */
1982: int rc;
1983: int n;
1984: const char *z;
1985: SHA3Context cx;
1986: int iSize;
1987:
1988: if( argc==1 ){
1989: iSize = 256;
1.4.2.1 misho 1990: }else{
1.4.2.2 misho 1991: iSize = sqlite3_value_int(argv[1]);
1992: if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
1993: sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
1994: "384 512", -1);
1995: return;
1.4.2.1 misho 1996: }
1.2 misho 1997: }
1.4.2.2 misho 1998: if( zSql==0 ) return;
1999: SHA3Init(&cx, iSize);
2000: while( zSql[0] ){
2001: rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
2002: if( rc ){
2003: char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
2004: zSql, sqlite3_errmsg(db));
2005: sqlite3_finalize(pStmt);
2006: sqlite3_result_error(context, zMsg, -1);
2007: sqlite3_free(zMsg);
2008: return;
2009: }
2010: if( !sqlite3_stmt_readonly(pStmt) ){
2011: char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
2012: sqlite3_finalize(pStmt);
2013: sqlite3_result_error(context, zMsg, -1);
2014: sqlite3_free(zMsg);
2015: return;
2016: }
2017: nCol = sqlite3_column_count(pStmt);
2018: z = sqlite3_sql(pStmt);
2019: n = (int)strlen(z);
2020: hash_step_vformat(&cx,"S%d:",n);
2021: SHA3Update(&cx,(unsigned char*)z,n);
1.4.2.1 misho 2022:
1.4.2.2 misho 2023: /* Compute a hash over the result of the query */
2024: while( SQLITE_ROW==sqlite3_step(pStmt) ){
2025: SHA3Update(&cx,(const unsigned char*)"R",1);
2026: for(i=0; i<nCol; i++){
2027: switch( sqlite3_column_type(pStmt,i) ){
2028: case SQLITE_NULL: {
2029: SHA3Update(&cx, (const unsigned char*)"N",1);
2030: break;
2031: }
2032: case SQLITE_INTEGER: {
2033: sqlite3_uint64 u;
2034: int j;
2035: unsigned char x[9];
2036: sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
2037: memcpy(&u, &v, 8);
2038: for(j=8; j>=1; j--){
2039: x[j] = u & 0xff;
2040: u >>= 8;
2041: }
2042: x[0] = 'I';
2043: SHA3Update(&cx, x, 9);
2044: break;
2045: }
2046: case SQLITE_FLOAT: {
2047: sqlite3_uint64 u;
2048: int j;
2049: unsigned char x[9];
2050: double r = sqlite3_column_double(pStmt,i);
2051: memcpy(&u, &r, 8);
2052: for(j=8; j>=1; j--){
2053: x[j] = u & 0xff;
2054: u >>= 8;
2055: }
2056: x[0] = 'F';
2057: SHA3Update(&cx,x,9);
2058: break;
2059: }
2060: case SQLITE_TEXT: {
2061: int n2 = sqlite3_column_bytes(pStmt, i);
2062: const unsigned char *z2 = sqlite3_column_text(pStmt, i);
2063: hash_step_vformat(&cx,"T%d:",n2);
2064: SHA3Update(&cx, z2, n2);
2065: break;
2066: }
2067: case SQLITE_BLOB: {
2068: int n2 = sqlite3_column_bytes(pStmt, i);
2069: const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
2070: hash_step_vformat(&cx,"B%d:",n2);
2071: SHA3Update(&cx, z2, n2);
2072: break;
2073: }
2074: }
1.4.2.1 misho 2075: }
1.2 misho 2076: }
1.4.2.2 misho 2077: sqlite3_finalize(pStmt);
1.2 misho 2078: }
1.4.2.2 misho 2079: sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
1.2 misho 2080: }
2081:
1.4.2.2 misho 2082:
2083: #ifdef _WIN32
2084:
2085: #endif
2086: int sqlite3_shathree_init(
2087: sqlite3 *db,
2088: char **pzErrMsg,
2089: const sqlite3_api_routines *pApi
2090: ){
2091: int rc = SQLITE_OK;
2092: SQLITE_EXTENSION_INIT2(pApi);
2093: (void)pzErrMsg; /* Unused parameter */
1.4.2.3 ! misho 2094: rc = sqlite3_create_function(db, "sha3", 1,
! 2095: SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
! 2096: 0, sha3Func, 0, 0);
1.4.2.2 misho 2097: if( rc==SQLITE_OK ){
1.4.2.3 ! misho 2098: rc = sqlite3_create_function(db, "sha3", 2,
! 2099: SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
! 2100: 0, sha3Func, 0, 0);
1.2 misho 2101: }
1.4.2.2 misho 2102: if( rc==SQLITE_OK ){
1.4.2.3 ! misho 2103: rc = sqlite3_create_function(db, "sha3_query", 1,
! 2104: SQLITE_UTF8 | SQLITE_DIRECTONLY,
! 2105: 0, sha3QueryFunc, 0, 0);
1.4.2.2 misho 2106: }
2107: if( rc==SQLITE_OK ){
1.4.2.3 ! misho 2108: rc = sqlite3_create_function(db, "sha3_query", 2,
! 2109: SQLITE_UTF8 | SQLITE_DIRECTONLY,
! 2110: 0, sha3QueryFunc, 0, 0);
1.4.2.2 misho 2111: }
2112: return rc;
1.2 misho 2113: }
2114:
1.4.2.2 misho 2115: /************************* End ../ext/misc/shathree.c ********************/
2116: /************************* Begin ../ext/misc/fileio.c ******************/
1.2 misho 2117: /*
1.4.2.2 misho 2118: ** 2014-06-13
2119: **
2120: ** The author disclaims copyright to this source code. In place of
2121: ** a legal notice, here is a blessing:
2122: **
2123: ** May you do good and not evil.
2124: ** May you find forgiveness for yourself and forgive others.
2125: ** May you share freely, never taking more than you give.
2126: **
2127: ******************************************************************************
2128: **
2129: ** This SQLite extension implements SQL functions readfile() and
2130: ** writefile(), and eponymous virtual type "fsdir".
2131: **
2132: ** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
2133: **
2134: ** If neither of the optional arguments is present, then this UDF
2135: ** function writes blob DATA to file FILE. If successful, the number
2136: ** of bytes written is returned. If an error occurs, NULL is returned.
2137: **
2138: ** If the first option argument - MODE - is present, then it must
2139: ** be passed an integer value that corresponds to a POSIX mode
2140: ** value (file type + permissions, as returned in the stat.st_mode
2141: ** field by the stat() system call). Three types of files may
2142: ** be written/created:
2143: **
2144: ** regular files: (mode & 0170000)==0100000
2145: ** symbolic links: (mode & 0170000)==0120000
2146: ** directories: (mode & 0170000)==0040000
2147: **
2148: ** For a directory, the DATA is ignored. For a symbolic link, it is
2149: ** interpreted as text and used as the target of the link. For a
2150: ** regular file, it is interpreted as a blob and written into the
2151: ** named file. Regardless of the type of file, its permissions are
2152: ** set to (mode & 0777) before returning.
2153: **
2154: ** If the optional MTIME argument is present, then it is interpreted
2155: ** as an integer - the number of seconds since the unix epoch. The
2156: ** modification-time of the target file is set to this value before
2157: ** returning.
2158: **
2159: ** If three or more arguments are passed to this function and an
2160: ** error is encountered, an exception is raised.
2161: **
2162: ** READFILE(FILE):
2163: **
2164: ** Read and return the contents of file FILE (type blob) from disk.
2165: **
2166: ** FSDIR:
2167: **
2168: ** Used as follows:
2169: **
2170: ** SELECT * FROM fsdir($path [, $dir]);
2171: **
2172: ** Parameter $path is an absolute or relative pathname. If the file that it
2173: ** refers to does not exist, it is an error. If the path refers to a regular
2174: ** file or symbolic link, it returns a single row. Or, if the path refers
2175: ** to a directory, it returns one row for the directory, and one row for each
2176: ** file within the hierarchy rooted at $path.
2177: **
2178: ** Each row has the following columns:
2179: **
2180: ** name: Path to file or directory (text value).
2181: ** mode: Value of stat.st_mode for directory entry (an integer).
2182: ** mtime: Value of stat.st_mtime for directory entry (an integer).
2183: ** data: For a regular file, a blob containing the file data. For a
2184: ** symlink, a text value containing the text of the link. For a
2185: ** directory, NULL.
2186: **
2187: ** If a non-NULL value is specified for the optional $dir parameter and
2188: ** $path is a relative path, then $path is interpreted relative to $dir.
2189: ** And the paths returned in the "name" column of the table are also
2190: ** relative to directory $dir.
1.2 misho 2191: */
1.4.2.2 misho 2192: /* #include "sqlite3ext.h" */
2193: SQLITE_EXTENSION_INIT1
2194: #include <stdio.h>
2195: #include <string.h>
2196: #include <assert.h>
2197:
2198: #include <sys/types.h>
2199: #include <sys/stat.h>
2200: #include <fcntl.h>
2201: #if !defined(_WIN32) && !defined(WIN32)
2202: # include <unistd.h>
2203: # include <dirent.h>
2204: # include <utime.h>
2205: # include <sys/time.h>
2206: #else
2207: # include "windows.h"
2208: # include <io.h>
2209: # include <direct.h>
2210: /* # include "test_windirent.h" */
2211: # define dirent DIRENT
2212: # ifndef chmod
2213: # define chmod _chmod
2214: # endif
2215: # ifndef stat
2216: # define stat _stat
2217: # endif
2218: # define mkdir(path,mode) _mkdir(path)
2219: # define lstat(path,buf) stat(path,buf)
2220: #endif
2221: #include <time.h>
2222: #include <errno.h>
2223:
1.2 misho 2224:
2225: /*
1.4.2.2 misho 2226: ** Structure of the fsdir() table-valued function
1.2 misho 2227: */
1.4.2.2 misho 2228: /* 0 1 2 3 4 5 */
2229: #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
2230: #define FSDIR_COLUMN_NAME 0 /* Name of the file */
2231: #define FSDIR_COLUMN_MODE 1 /* Access mode */
2232: #define FSDIR_COLUMN_MTIME 2 /* Last modification time */
2233: #define FSDIR_COLUMN_DATA 3 /* File content */
2234: #define FSDIR_COLUMN_PATH 4 /* Path to top of search */
2235: #define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
2236:
1.2 misho 2237:
2238: /*
1.4.2.2 misho 2239: ** Set the result stored by context ctx to a blob containing the
2240: ** contents of file zName. Or, leave the result unchanged (NULL)
2241: ** if the file does not exist or is unreadable.
2242: **
2243: ** If the file exceeds the SQLite blob size limit, through an
2244: ** SQLITE_TOOBIG error.
2245: **
2246: ** Throw an SQLITE_IOERR if there are difficulties pulling the file
2247: ** off of disk.
1.2 misho 2248: */
1.4.2.2 misho 2249: static void readFileContents(sqlite3_context *ctx, const char *zName){
2250: FILE *in;
2251: sqlite3_int64 nIn;
2252: void *pBuf;
2253: sqlite3 *db;
2254: int mxBlob;
2255:
2256: in = fopen(zName, "rb");
2257: if( in==0 ){
2258: /* File does not exist or is unreadable. Leave the result set to NULL. */
2259: return;
1.2 misho 2260: }
1.4.2.2 misho 2261: fseek(in, 0, SEEK_END);
2262: nIn = ftell(in);
2263: rewind(in);
2264: db = sqlite3_context_db_handle(ctx);
2265: mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
2266: if( nIn>mxBlob ){
2267: sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
2268: fclose(in);
2269: return;
2270: }
2271: pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
2272: if( pBuf==0 ){
2273: sqlite3_result_error_nomem(ctx);
2274: fclose(in);
2275: return;
2276: }
2277: if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
2278: sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
2279: }else{
2280: sqlite3_result_error_code(ctx, SQLITE_IOERR);
2281: sqlite3_free(pBuf);
1.2 misho 2282: }
1.4.2.2 misho 2283: fclose(in);
1.2 misho 2284: }
2285:
2286: /*
1.4.2.2 misho 2287: ** Implementation of the "readfile(X)" SQL function. The entire content
2288: ** of the file named X is read and returned as a BLOB. NULL is returned
2289: ** if the file does not exist or is unreadable.
1.2 misho 2290: */
1.4.2.2 misho 2291: static void readfileFunc(
2292: sqlite3_context *context,
2293: int argc,
2294: sqlite3_value **argv
2295: ){
2296: const char *zName;
2297: (void)(argc); /* Unused parameter */
2298: zName = (const char*)sqlite3_value_text(argv[0]);
2299: if( zName==0 ) return;
2300: readFileContents(context, zName);
1.2 misho 2301: }
2302:
2303: /*
1.4.2.2 misho 2304: ** Set the error message contained in context ctx to the results of
2305: ** vprintf(zFmt, ...).
1.4 misho 2306: */
1.4.2.2 misho 2307: static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
2308: char *zMsg = 0;
2309: va_list ap;
2310: va_start(ap, zFmt);
2311: zMsg = sqlite3_vmprintf(zFmt, ap);
2312: sqlite3_result_error(ctx, zMsg, -1);
2313: sqlite3_free(zMsg);
2314: va_end(ap);
2315: }
2316:
2317: #if defined(_WIN32)
2318: /*
2319: ** This function is designed to convert a Win32 FILETIME structure into the
2320: ** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
2321: */
2322: static sqlite3_uint64 fileTimeToUnixTime(
2323: LPFILETIME pFileTime
1.4 misho 2324: ){
1.4.2.2 misho 2325: SYSTEMTIME epochSystemTime;
2326: ULARGE_INTEGER epochIntervals;
2327: FILETIME epochFileTime;
2328: ULARGE_INTEGER fileIntervals;
2329:
2330: memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
2331: epochSystemTime.wYear = 1970;
2332: epochSystemTime.wMonth = 1;
2333: epochSystemTime.wDay = 1;
2334: SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
2335: epochIntervals.LowPart = epochFileTime.dwLowDateTime;
2336: epochIntervals.HighPart = epochFileTime.dwHighDateTime;
2337:
2338: fileIntervals.LowPart = pFileTime->dwLowDateTime;
2339: fileIntervals.HighPart = pFileTime->dwHighDateTime;
2340:
2341: return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
2342: }
2343:
2344: /*
2345: ** This function attempts to normalize the time values found in the stat()
2346: ** buffer to UTC. This is necessary on Win32, where the runtime library
2347: ** appears to return these values as local times.
2348: */
2349: static void statTimesToUtc(
2350: const char *zPath,
2351: struct stat *pStatBuf
2352: ){
2353: HANDLE hFindFile;
2354: WIN32_FIND_DATAW fd;
2355: LPWSTR zUnicodeName;
2356: extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
2357: zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
2358: if( zUnicodeName ){
2359: memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
2360: hFindFile = FindFirstFileW(zUnicodeName, &fd);
2361: if( hFindFile!=NULL ){
2362: pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
2363: pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
2364: pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
2365: FindClose(hFindFile);
1.4 misho 2366: }
1.4.2.2 misho 2367: sqlite3_free(zUnicodeName);
1.4 misho 2368: }
2369: }
1.4.2.1 misho 2370: #endif
2371:
2372: /*
1.4.2.2 misho 2373: ** This function is used in place of stat(). On Windows, special handling
2374: ** is required in order for the included time to be returned as UTC. On all
2375: ** other systems, this function simply calls stat().
1.4.2.1 misho 2376: */
1.4.2.2 misho 2377: static int fileStat(
2378: const char *zPath,
2379: struct stat *pStatBuf
2380: ){
2381: #if defined(_WIN32)
2382: int rc = stat(zPath, pStatBuf);
2383: if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
2384: return rc;
2385: #else
2386: return stat(zPath, pStatBuf);
2387: #endif
1.4.2.1 misho 2388: }
1.4.2.2 misho 2389:
2390: /*
2391: ** This function is used in place of lstat(). On Windows, special handling
2392: ** is required in order for the included time to be returned as UTC. On all
2393: ** other systems, this function simply calls lstat().
2394: */
2395: static int fileLinkStat(
2396: const char *zPath,
2397: struct stat *pStatBuf
2398: ){
2399: #if defined(_WIN32)
2400: int rc = lstat(zPath, pStatBuf);
2401: if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
2402: return rc;
2403: #else
2404: return lstat(zPath, pStatBuf);
2405: #endif
1.4.2.1 misho 2406: }
1.4 misho 2407:
2408: /*
1.4.2.2 misho 2409: ** Argument zFile is the name of a file that will be created and/or written
2410: ** by SQL function writefile(). This function ensures that the directory
2411: ** zFile will be written to exists, creating it if required. The permissions
2412: ** for any path components created by this function are set in accordance
2413: ** with the current umask.
2414: **
2415: ** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
2416: ** SQLITE_OK is returned if the directory is successfully created, or
2417: ** SQLITE_ERROR otherwise.
1.2 misho 2418: */
1.4.2.2 misho 2419: static int makeDirectory(
2420: const char *zFile
1.4 misho 2421: ){
1.4.2.2 misho 2422: char *zCopy = sqlite3_mprintf("%s", zFile);
2423: int rc = SQLITE_OK;
1.2 misho 2424:
1.4.2.2 misho 2425: if( zCopy==0 ){
2426: rc = SQLITE_NOMEM;
2427: }else{
2428: int nCopy = (int)strlen(zCopy);
2429: int i = 1;
2430:
2431: while( rc==SQLITE_OK ){
2432: struct stat sStat;
2433: int rc2;
2434:
2435: for(; zCopy[i]!='/' && i<nCopy; i++);
2436: if( i==nCopy ) break;
2437: zCopy[i] = '\0';
2438:
2439: rc2 = fileStat(zCopy, &sStat);
2440: if( rc2!=0 ){
2441: if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
1.4 misho 2442: }else{
1.4.2.2 misho 2443: if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
1.4 misho 2444: }
1.4.2.2 misho 2445: zCopy[i] = '/';
2446: i++;
2447: }
2448:
2449: sqlite3_free(zCopy);
2450: }
2451:
2452: return rc;
2453: }
2454:
2455: /*
2456: ** This function does the work for the writefile() UDF. Refer to
2457: ** header comments at the top of this file for details.
2458: */
2459: static int writeFile(
2460: sqlite3_context *pCtx, /* Context to return bytes written in */
2461: const char *zFile, /* File to write */
2462: sqlite3_value *pData, /* Data to write */
2463: mode_t mode, /* MODE parameter passed to writefile() */
2464: sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */
2465: ){
2466: #if !defined(_WIN32) && !defined(WIN32)
2467: if( S_ISLNK(mode) ){
2468: const char *zTo = (const char*)sqlite3_value_text(pData);
2469: if( symlink(zTo, zFile)<0 ) return 1;
2470: }else
2471: #endif
2472: {
2473: if( S_ISDIR(mode) ){
2474: if( mkdir(zFile, mode) ){
2475: /* The mkdir() call to create the directory failed. This might not
2476: ** be an error though - if there is already a directory at the same
2477: ** path and either the permissions already match or can be changed
2478: ** to do so using chmod(), it is not an error. */
2479: struct stat sStat;
2480: if( errno!=EEXIST
2481: || 0!=fileStat(zFile, &sStat)
2482: || !S_ISDIR(sStat.st_mode)
2483: || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
2484: ){
2485: return 1;
1.2 misho 2486: }
2487: }
1.4.2.2 misho 2488: }else{
2489: sqlite3_int64 nWrite = 0;
2490: const char *z;
2491: int rc = 0;
2492: FILE *out = fopen(zFile, "wb");
2493: if( out==0 ) return 1;
2494: z = (const char*)sqlite3_value_blob(pData);
2495: if( z ){
2496: sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
2497: nWrite = sqlite3_value_bytes(pData);
2498: if( nWrite!=n ){
2499: rc = 1;
1.4 misho 2500: }
2501: }
1.4.2.2 misho 2502: fclose(out);
2503: if( rc==0 && mode && chmod(zFile, mode & 0777) ){
2504: rc = 1;
2505: }
2506: if( rc ) return 2;
2507: sqlite3_result_int64(pCtx, nWrite);
1.4 misho 2508: }
1.4.2.2 misho 2509: }
2510:
2511: if( mtime>=0 ){
2512: #if defined(_WIN32)
1.4.2.3 ! misho 2513: #if !SQLITE_OS_WINRT
1.4.2.2 misho 2514: /* Windows */
2515: FILETIME lastAccess;
2516: FILETIME lastWrite;
2517: SYSTEMTIME currentTime;
2518: LONGLONG intervals;
2519: HANDLE hFile;
2520: LPWSTR zUnicodeName;
2521: extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
2522:
2523: GetSystemTime(¤tTime);
2524: SystemTimeToFileTime(¤tTime, &lastAccess);
2525: intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
2526: lastWrite.dwLowDateTime = (DWORD)intervals;
2527: lastWrite.dwHighDateTime = intervals >> 32;
2528: zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
2529: if( zUnicodeName==0 ){
2530: return 1;
1.4 misho 2531: }
1.4.2.2 misho 2532: hFile = CreateFileW(
2533: zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
2534: FILE_FLAG_BACKUP_SEMANTICS, NULL
2535: );
2536: sqlite3_free(zUnicodeName);
2537: if( hFile!=INVALID_HANDLE_VALUE ){
2538: BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
2539: CloseHandle(hFile);
2540: return !bResult;
2541: }else{
2542: return 1;
2543: }
1.4.2.3 ! misho 2544: #endif
1.4.2.2 misho 2545: #elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
2546: /* Recent unix */
2547: struct timespec times[2];
2548: times[0].tv_nsec = times[1].tv_nsec = 0;
2549: times[0].tv_sec = time(0);
2550: times[1].tv_sec = mtime;
2551: if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
2552: return 1;
2553: }
2554: #else
2555: /* Legacy unix */
2556: struct timeval times[2];
2557: times[0].tv_usec = times[1].tv_usec = 0;
2558: times[0].tv_sec = time(0);
2559: times[1].tv_sec = mtime;
2560: if( utimes(zFile, times) ){
2561: return 1;
2562: }
2563: #endif
2564: }
2565:
2566: return 0;
2567: }
2568:
2569: /*
2570: ** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.
2571: ** Refer to header comments at the top of this file for details.
2572: */
2573: static void writefileFunc(
2574: sqlite3_context *context,
2575: int argc,
2576: sqlite3_value **argv
2577: ){
2578: const char *zFile;
2579: mode_t mode = 0;
2580: int res;
2581: sqlite3_int64 mtime = -1;
2582:
2583: if( argc<2 || argc>4 ){
2584: sqlite3_result_error(context,
2585: "wrong number of arguments to function writefile()", -1
2586: );
2587: return;
2588: }
2589:
2590: zFile = (const char*)sqlite3_value_text(argv[0]);
2591: if( zFile==0 ) return;
2592: if( argc>=3 ){
2593: mode = (mode_t)sqlite3_value_int(argv[2]);
2594: }
2595: if( argc==4 ){
2596: mtime = sqlite3_value_int64(argv[3]);
2597: }
2598:
2599: res = writeFile(context, zFile, argv[1], mode, mtime);
2600: if( res==1 && errno==ENOENT ){
2601: if( makeDirectory(zFile)==SQLITE_OK ){
2602: res = writeFile(context, zFile, argv[1], mode, mtime);
2603: }
2604: }
2605:
2606: if( argc>2 && res!=0 ){
2607: if( S_ISLNK(mode) ){
2608: ctxErrorMsg(context, "failed to create symlink: %s", zFile);
2609: }else if( S_ISDIR(mode) ){
2610: ctxErrorMsg(context, "failed to create directory: %s", zFile);
2611: }else{
2612: ctxErrorMsg(context, "failed to write file: %s", zFile);
2613: }
2614: }
2615: }
2616:
2617: /*
2618: ** SQL function: lsmode(MODE)
2619: **
2620: ** Given a numberic st_mode from stat(), convert it into a human-readable
2621: ** text string in the style of "ls -l".
2622: */
2623: static void lsModeFunc(
2624: sqlite3_context *context,
2625: int argc,
2626: sqlite3_value **argv
2627: ){
2628: int i;
2629: int iMode = sqlite3_value_int(argv[0]);
2630: char z[16];
2631: (void)argc;
2632: if( S_ISLNK(iMode) ){
2633: z[0] = 'l';
2634: }else if( S_ISREG(iMode) ){
2635: z[0] = '-';
2636: }else if( S_ISDIR(iMode) ){
2637: z[0] = 'd';
2638: }else{
2639: z[0] = '?';
2640: }
2641: for(i=0; i<3; i++){
2642: int m = (iMode >> ((2-i)*3));
2643: char *a = &z[1 + i*3];
2644: a[0] = (m & 0x4) ? 'r' : '-';
2645: a[1] = (m & 0x2) ? 'w' : '-';
2646: a[2] = (m & 0x1) ? 'x' : '-';
2647: }
2648: z[10] = '\0';
2649: sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
2650: }
2651:
2652: #ifndef SQLITE_OMIT_VIRTUALTABLE
2653:
2654: /*
2655: ** Cursor type for recursively iterating through a directory structure.
2656: */
2657: typedef struct fsdir_cursor fsdir_cursor;
2658: typedef struct FsdirLevel FsdirLevel;
2659:
2660: struct FsdirLevel {
2661: DIR *pDir; /* From opendir() */
2662: char *zDir; /* Name of directory (nul-terminated) */
2663: };
2664:
2665: struct fsdir_cursor {
2666: sqlite3_vtab_cursor base; /* Base class - must be first */
2667:
2668: int nLvl; /* Number of entries in aLvl[] array */
2669: int iLvl; /* Index of current entry */
2670: FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
2671:
2672: const char *zBase;
2673: int nBase;
2674:
2675: struct stat sStat; /* Current lstat() results */
2676: char *zPath; /* Path to current entry */
2677: sqlite3_int64 iRowid; /* Current rowid */
2678: };
2679:
2680: typedef struct fsdir_tab fsdir_tab;
2681: struct fsdir_tab {
2682: sqlite3_vtab base; /* Base class - must be first */
2683: };
2684:
2685: /*
2686: ** Construct a new fsdir virtual table object.
2687: */
2688: static int fsdirConnect(
2689: sqlite3 *db,
2690: void *pAux,
2691: int argc, const char *const*argv,
2692: sqlite3_vtab **ppVtab,
2693: char **pzErr
2694: ){
2695: fsdir_tab *pNew = 0;
2696: int rc;
2697: (void)pAux;
2698: (void)argc;
2699: (void)argv;
2700: (void)pzErr;
2701: rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
2702: if( rc==SQLITE_OK ){
2703: pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
2704: if( pNew==0 ) return SQLITE_NOMEM;
2705: memset(pNew, 0, sizeof(*pNew));
1.4.2.3 ! misho 2706: sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
1.4.2.2 misho 2707: }
2708: *ppVtab = (sqlite3_vtab*)pNew;
2709: return rc;
2710: }
2711:
2712: /*
2713: ** This method is the destructor for fsdir vtab objects.
2714: */
2715: static int fsdirDisconnect(sqlite3_vtab *pVtab){
2716: sqlite3_free(pVtab);
2717: return SQLITE_OK;
2718: }
2719:
2720: /*
2721: ** Constructor for a new fsdir_cursor object.
2722: */
2723: static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
2724: fsdir_cursor *pCur;
2725: (void)p;
2726: pCur = sqlite3_malloc( sizeof(*pCur) );
2727: if( pCur==0 ) return SQLITE_NOMEM;
2728: memset(pCur, 0, sizeof(*pCur));
2729: pCur->iLvl = -1;
2730: *ppCursor = &pCur->base;
2731: return SQLITE_OK;
2732: }
2733:
2734: /*
2735: ** Reset a cursor back to the state it was in when first returned
2736: ** by fsdirOpen().
2737: */
2738: static void fsdirResetCursor(fsdir_cursor *pCur){
2739: int i;
2740: for(i=0; i<=pCur->iLvl; i++){
2741: FsdirLevel *pLvl = &pCur->aLvl[i];
2742: if( pLvl->pDir ) closedir(pLvl->pDir);
2743: sqlite3_free(pLvl->zDir);
2744: }
2745: sqlite3_free(pCur->zPath);
2746: sqlite3_free(pCur->aLvl);
2747: pCur->aLvl = 0;
2748: pCur->zPath = 0;
2749: pCur->zBase = 0;
2750: pCur->nBase = 0;
2751: pCur->nLvl = 0;
2752: pCur->iLvl = -1;
2753: pCur->iRowid = 1;
2754: }
2755:
2756: /*
2757: ** Destructor for an fsdir_cursor.
2758: */
2759: static int fsdirClose(sqlite3_vtab_cursor *cur){
2760: fsdir_cursor *pCur = (fsdir_cursor*)cur;
2761:
2762: fsdirResetCursor(pCur);
2763: sqlite3_free(pCur);
2764: return SQLITE_OK;
2765: }
2766:
2767: /*
2768: ** Set the error message for the virtual table associated with cursor
2769: ** pCur to the results of vprintf(zFmt, ...).
2770: */
2771: static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
2772: va_list ap;
2773: va_start(ap, zFmt);
2774: pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
2775: va_end(ap);
2776: }
2777:
2778:
2779: /*
2780: ** Advance an fsdir_cursor to its next row of output.
2781: */
2782: static int fsdirNext(sqlite3_vtab_cursor *cur){
2783: fsdir_cursor *pCur = (fsdir_cursor*)cur;
2784: mode_t m = pCur->sStat.st_mode;
2785:
2786: pCur->iRowid++;
2787: if( S_ISDIR(m) ){
2788: /* Descend into this directory */
2789: int iNew = pCur->iLvl + 1;
2790: FsdirLevel *pLvl;
2791: if( iNew>=pCur->nLvl ){
2792: int nNew = iNew+1;
2793: sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
2794: FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
2795: if( aNew==0 ) return SQLITE_NOMEM;
2796: memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
2797: pCur->aLvl = aNew;
2798: pCur->nLvl = nNew;
2799: }
2800: pCur->iLvl = iNew;
2801: pLvl = &pCur->aLvl[iNew];
2802:
2803: pLvl->zDir = pCur->zPath;
2804: pCur->zPath = 0;
2805: pLvl->pDir = opendir(pLvl->zDir);
2806: if( pLvl->pDir==0 ){
2807: fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
2808: return SQLITE_ERROR;
2809: }
2810: }
2811:
2812: while( pCur->iLvl>=0 ){
2813: FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
2814: struct dirent *pEntry = readdir(pLvl->pDir);
2815: if( pEntry ){
2816: if( pEntry->d_name[0]=='.' ){
2817: if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
2818: if( pEntry->d_name[1]=='\0' ) continue;
2819: }
2820: sqlite3_free(pCur->zPath);
2821: pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
2822: if( pCur->zPath==0 ) return SQLITE_NOMEM;
2823: if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
2824: fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
2825: return SQLITE_ERROR;
2826: }
2827: return SQLITE_OK;
2828: }
2829: closedir(pLvl->pDir);
2830: sqlite3_free(pLvl->zDir);
2831: pLvl->pDir = 0;
2832: pLvl->zDir = 0;
2833: pCur->iLvl--;
2834: }
2835:
2836: /* EOF */
2837: sqlite3_free(pCur->zPath);
2838: pCur->zPath = 0;
2839: return SQLITE_OK;
2840: }
2841:
2842: /*
2843: ** Return values of columns for the row at which the series_cursor
2844: ** is currently pointing.
2845: */
2846: static int fsdirColumn(
2847: sqlite3_vtab_cursor *cur, /* The cursor */
2848: sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
2849: int i /* Which column to return */
2850: ){
2851: fsdir_cursor *pCur = (fsdir_cursor*)cur;
2852: switch( i ){
2853: case FSDIR_COLUMN_NAME: {
2854: sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
2855: break;
2856: }
2857:
2858: case FSDIR_COLUMN_MODE:
2859: sqlite3_result_int64(ctx, pCur->sStat.st_mode);
2860: break;
2861:
2862: case FSDIR_COLUMN_MTIME:
2863: sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
2864: break;
2865:
2866: case FSDIR_COLUMN_DATA: {
2867: mode_t m = pCur->sStat.st_mode;
2868: if( S_ISDIR(m) ){
2869: sqlite3_result_null(ctx);
2870: #if !defined(_WIN32) && !defined(WIN32)
2871: }else if( S_ISLNK(m) ){
2872: char aStatic[64];
2873: char *aBuf = aStatic;
2874: sqlite3_int64 nBuf = 64;
2875: int n;
2876:
2877: while( 1 ){
2878: n = readlink(pCur->zPath, aBuf, nBuf);
2879: if( n<nBuf ) break;
2880: if( aBuf!=aStatic ) sqlite3_free(aBuf);
2881: nBuf = nBuf*2;
2882: aBuf = sqlite3_malloc64(nBuf);
2883: if( aBuf==0 ){
2884: sqlite3_result_error_nomem(ctx);
2885: return SQLITE_NOMEM;
2886: }
2887: }
2888:
2889: sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
2890: if( aBuf!=aStatic ) sqlite3_free(aBuf);
2891: #endif
2892: }else{
2893: readFileContents(ctx, pCur->zPath);
2894: }
2895: }
2896: case FSDIR_COLUMN_PATH:
2897: default: {
2898: /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
2899: ** always return their values as NULL */
2900: break;
2901: }
2902: }
2903: return SQLITE_OK;
2904: }
2905:
2906: /*
2907: ** Return the rowid for the current row. In this implementation, the
2908: ** first row returned is assigned rowid value 1, and each subsequent
2909: ** row a value 1 more than that of the previous.
2910: */
2911: static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
2912: fsdir_cursor *pCur = (fsdir_cursor*)cur;
2913: *pRowid = pCur->iRowid;
2914: return SQLITE_OK;
2915: }
2916:
2917: /*
2918: ** Return TRUE if the cursor has been moved off of the last
2919: ** row of output.
2920: */
2921: static int fsdirEof(sqlite3_vtab_cursor *cur){
2922: fsdir_cursor *pCur = (fsdir_cursor*)cur;
2923: return (pCur->zPath==0);
2924: }
2925:
2926: /*
2927: ** xFilter callback.
2928: **
2929: ** idxNum==1 PATH parameter only
2930: ** idxNum==2 Both PATH and DIR supplied
2931: */
2932: static int fsdirFilter(
2933: sqlite3_vtab_cursor *cur,
2934: int idxNum, const char *idxStr,
2935: int argc, sqlite3_value **argv
2936: ){
2937: const char *zDir = 0;
2938: fsdir_cursor *pCur = (fsdir_cursor*)cur;
2939: (void)idxStr;
2940: fsdirResetCursor(pCur);
2941:
2942: if( idxNum==0 ){
2943: fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
2944: return SQLITE_ERROR;
2945: }
2946:
2947: assert( argc==idxNum && (argc==1 || argc==2) );
2948: zDir = (const char*)sqlite3_value_text(argv[0]);
2949: if( zDir==0 ){
2950: fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
2951: return SQLITE_ERROR;
2952: }
2953: if( argc==2 ){
2954: pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
2955: }
2956: if( pCur->zBase ){
2957: pCur->nBase = (int)strlen(pCur->zBase)+1;
2958: pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
2959: }else{
2960: pCur->zPath = sqlite3_mprintf("%s", zDir);
2961: }
2962:
2963: if( pCur->zPath==0 ){
2964: return SQLITE_NOMEM;
2965: }
2966: if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
2967: fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
2968: return SQLITE_ERROR;
2969: }
2970:
2971: return SQLITE_OK;
2972: }
2973:
2974: /*
2975: ** SQLite will invoke this method one or more times while planning a query
2976: ** that uses the generate_series virtual table. This routine needs to create
2977: ** a query plan for each invocation and compute an estimated cost for that
2978: ** plan.
2979: **
2980: ** In this implementation idxNum is used to represent the
2981: ** query plan. idxStr is unused.
2982: **
2983: ** The query plan is represented by values of idxNum:
2984: **
2985: ** (1) The path value is supplied by argv[0]
2986: ** (2) Path is in argv[0] and dir is in argv[1]
2987: */
2988: static int fsdirBestIndex(
2989: sqlite3_vtab *tab,
2990: sqlite3_index_info *pIdxInfo
2991: ){
2992: int i; /* Loop over constraints */
2993: int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
2994: int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
2995: int seenPath = 0; /* True if an unusable PATH= constraint is seen */
2996: int seenDir = 0; /* True if an unusable DIR= constraint is seen */
2997: const struct sqlite3_index_constraint *pConstraint;
2998:
2999: (void)tab;
3000: pConstraint = pIdxInfo->aConstraint;
3001: for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
3002: if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
3003: switch( pConstraint->iColumn ){
3004: case FSDIR_COLUMN_PATH: {
3005: if( pConstraint->usable ){
3006: idxPath = i;
3007: seenPath = 0;
3008: }else if( idxPath<0 ){
3009: seenPath = 1;
3010: }
3011: break;
3012: }
3013: case FSDIR_COLUMN_DIR: {
3014: if( pConstraint->usable ){
3015: idxDir = i;
3016: seenDir = 0;
3017: }else if( idxDir<0 ){
3018: seenDir = 1;
3019: }
3020: break;
3021: }
3022: }
3023: }
3024: if( seenPath || seenDir ){
3025: /* If input parameters are unusable, disallow this plan */
3026: return SQLITE_CONSTRAINT;
3027: }
3028:
3029: if( idxPath<0 ){
3030: pIdxInfo->idxNum = 0;
3031: /* The pIdxInfo->estimatedCost should have been initialized to a huge
3032: ** number. Leave it unchanged. */
3033: pIdxInfo->estimatedRows = 0x7fffffff;
3034: }else{
3035: pIdxInfo->aConstraintUsage[idxPath].omit = 1;
3036: pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
3037: if( idxDir>=0 ){
3038: pIdxInfo->aConstraintUsage[idxDir].omit = 1;
3039: pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
3040: pIdxInfo->idxNum = 2;
3041: pIdxInfo->estimatedCost = 10.0;
3042: }else{
3043: pIdxInfo->idxNum = 1;
3044: pIdxInfo->estimatedCost = 100.0;
3045: }
3046: }
3047:
3048: return SQLITE_OK;
3049: }
3050:
3051: /*
3052: ** Register the "fsdir" virtual table.
3053: */
3054: static int fsdirRegister(sqlite3 *db){
3055: static sqlite3_module fsdirModule = {
3056: 0, /* iVersion */
3057: 0, /* xCreate */
3058: fsdirConnect, /* xConnect */
3059: fsdirBestIndex, /* xBestIndex */
3060: fsdirDisconnect, /* xDisconnect */
3061: 0, /* xDestroy */
3062: fsdirOpen, /* xOpen - open a cursor */
3063: fsdirClose, /* xClose - close a cursor */
3064: fsdirFilter, /* xFilter - configure scan constraints */
3065: fsdirNext, /* xNext - advance a cursor */
3066: fsdirEof, /* xEof - check for end of scan */
3067: fsdirColumn, /* xColumn - read data */
3068: fsdirRowid, /* xRowid - read data */
3069: 0, /* xUpdate */
3070: 0, /* xBegin */
3071: 0, /* xSync */
3072: 0, /* xCommit */
3073: 0, /* xRollback */
3074: 0, /* xFindMethod */
3075: 0, /* xRename */
3076: 0, /* xSavepoint */
3077: 0, /* xRelease */
3078: 0, /* xRollbackTo */
3079: 0, /* xShadowName */
3080: };
3081:
3082: int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
3083: return rc;
3084: }
3085: #else /* SQLITE_OMIT_VIRTUALTABLE */
3086: # define fsdirRegister(x) SQLITE_OK
3087: #endif
3088:
3089: #ifdef _WIN32
3090:
3091: #endif
3092: int sqlite3_fileio_init(
3093: sqlite3 *db,
3094: char **pzErrMsg,
3095: const sqlite3_api_routines *pApi
3096: ){
3097: int rc = SQLITE_OK;
3098: SQLITE_EXTENSION_INIT2(pApi);
3099: (void)pzErrMsg; /* Unused parameter */
1.4.2.3 ! misho 3100: rc = sqlite3_create_function(db, "readfile", 1,
! 3101: SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
1.4.2.2 misho 3102: readfileFunc, 0, 0);
3103: if( rc==SQLITE_OK ){
1.4.2.3 ! misho 3104: rc = sqlite3_create_function(db, "writefile", -1,
! 3105: SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
1.4.2.2 misho 3106: writefileFunc, 0, 0);
3107: }
3108: if( rc==SQLITE_OK ){
3109: rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
3110: lsModeFunc, 0, 0);
3111: }
3112: if( rc==SQLITE_OK ){
3113: rc = fsdirRegister(db);
3114: }
3115: return rc;
3116: }
3117:
3118: /************************* End ../ext/misc/fileio.c ********************/
3119: /************************* Begin ../ext/misc/completion.c ******************/
3120: /*
3121: ** 2017-07-10
3122: **
3123: ** The author disclaims copyright to this source code. In place of
3124: ** a legal notice, here is a blessing:
3125: **
3126: ** May you do good and not evil.
3127: ** May you find forgiveness for yourself and forgive others.
3128: ** May you share freely, never taking more than you give.
3129: **
3130: *************************************************************************
3131: **
3132: ** This file implements an eponymous virtual table that returns suggested
3133: ** completions for a partial SQL input.
3134: **
3135: ** Suggested usage:
3136: **
3137: ** SELECT DISTINCT candidate COLLATE nocase
3138: ** FROM completion($prefix,$wholeline)
3139: ** ORDER BY 1;
3140: **
3141: ** The two query parameters are optional. $prefix is the text of the
3142: ** current word being typed and that is to be completed. $wholeline is
3143: ** the complete input line, used for context.
3144: **
3145: ** The raw completion() table might return the same candidate multiple
3146: ** times, for example if the same column name is used to two or more
3147: ** tables. And the candidates are returned in an arbitrary order. Hence,
3148: ** the DISTINCT and ORDER BY are recommended.
3149: **
3150: ** This virtual table operates at the speed of human typing, and so there
3151: ** is no attempt to make it fast. Even a slow implementation will be much
3152: ** faster than any human can type.
3153: **
3154: */
3155: /* #include "sqlite3ext.h" */
3156: SQLITE_EXTENSION_INIT1
3157: #include <assert.h>
3158: #include <string.h>
3159: #include <ctype.h>
3160:
3161: #ifndef SQLITE_OMIT_VIRTUALTABLE
3162:
3163: /* completion_vtab is a subclass of sqlite3_vtab which will
3164: ** serve as the underlying representation of a completion virtual table
3165: */
3166: typedef struct completion_vtab completion_vtab;
3167: struct completion_vtab {
3168: sqlite3_vtab base; /* Base class - must be first */
3169: sqlite3 *db; /* Database connection for this completion vtab */
3170: };
3171:
3172: /* completion_cursor is a subclass of sqlite3_vtab_cursor which will
3173: ** serve as the underlying representation of a cursor that scans
3174: ** over rows of the result
3175: */
3176: typedef struct completion_cursor completion_cursor;
3177: struct completion_cursor {
3178: sqlite3_vtab_cursor base; /* Base class - must be first */
3179: sqlite3 *db; /* Database connection for this cursor */
3180: int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */
3181: char *zPrefix; /* The prefix for the word we want to complete */
3182: char *zLine; /* The whole that we want to complete */
3183: const char *zCurrentRow; /* Current output row */
3184: int szRow; /* Length of the zCurrentRow string */
3185: sqlite3_stmt *pStmt; /* Current statement */
3186: sqlite3_int64 iRowid; /* The rowid */
3187: int ePhase; /* Current phase */
3188: int j; /* inter-phase counter */
3189: };
3190:
3191: /* Values for ePhase:
3192: */
3193: #define COMPLETION_FIRST_PHASE 1
3194: #define COMPLETION_KEYWORDS 1
3195: #define COMPLETION_PRAGMAS 2
3196: #define COMPLETION_FUNCTIONS 3
3197: #define COMPLETION_COLLATIONS 4
3198: #define COMPLETION_INDEXES 5
3199: #define COMPLETION_TRIGGERS 6
3200: #define COMPLETION_DATABASES 7
3201: #define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */
3202: #define COMPLETION_COLUMNS 9
3203: #define COMPLETION_MODULES 10
3204: #define COMPLETION_EOF 11
3205:
3206: /*
3207: ** The completionConnect() method is invoked to create a new
3208: ** completion_vtab that describes the completion virtual table.
3209: **
3210: ** Think of this routine as the constructor for completion_vtab objects.
3211: **
3212: ** All this routine needs to do is:
3213: **
3214: ** (1) Allocate the completion_vtab object and initialize all fields.
3215: **
3216: ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
3217: ** result set of queries against completion will look like.
3218: */
3219: static int completionConnect(
3220: sqlite3 *db,
3221: void *pAux,
3222: int argc, const char *const*argv,
3223: sqlite3_vtab **ppVtab,
3224: char **pzErr
3225: ){
3226: completion_vtab *pNew;
3227: int rc;
3228:
3229: (void)(pAux); /* Unused parameter */
3230: (void)(argc); /* Unused parameter */
3231: (void)(argv); /* Unused parameter */
3232: (void)(pzErr); /* Unused parameter */
3233:
3234: /* Column numbers */
3235: #define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */
3236: #define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */
3237: #define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
3238: #define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
3239:
1.4.2.3 ! misho 3240: sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
1.4.2.2 misho 3241: rc = sqlite3_declare_vtab(db,
3242: "CREATE TABLE x("
3243: " candidate TEXT,"
3244: " prefix TEXT HIDDEN,"
3245: " wholeline TEXT HIDDEN,"
3246: " phase INT HIDDEN" /* Used for debugging only */
3247: ")");
3248: if( rc==SQLITE_OK ){
3249: pNew = sqlite3_malloc( sizeof(*pNew) );
3250: *ppVtab = (sqlite3_vtab*)pNew;
3251: if( pNew==0 ) return SQLITE_NOMEM;
3252: memset(pNew, 0, sizeof(*pNew));
3253: pNew->db = db;
3254: }
3255: return rc;
3256: }
3257:
3258: /*
3259: ** This method is the destructor for completion_cursor objects.
3260: */
3261: static int completionDisconnect(sqlite3_vtab *pVtab){
3262: sqlite3_free(pVtab);
3263: return SQLITE_OK;
3264: }
3265:
3266: /*
3267: ** Constructor for a new completion_cursor object.
3268: */
3269: static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
3270: completion_cursor *pCur;
3271: pCur = sqlite3_malloc( sizeof(*pCur) );
3272: if( pCur==0 ) return SQLITE_NOMEM;
3273: memset(pCur, 0, sizeof(*pCur));
3274: pCur->db = ((completion_vtab*)p)->db;
3275: *ppCursor = &pCur->base;
3276: return SQLITE_OK;
3277: }
3278:
3279: /*
3280: ** Reset the completion_cursor.
3281: */
3282: static void completionCursorReset(completion_cursor *pCur){
3283: sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0;
3284: sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0;
3285: sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
3286: pCur->j = 0;
3287: }
3288:
3289: /*
3290: ** Destructor for a completion_cursor.
3291: */
3292: static int completionClose(sqlite3_vtab_cursor *cur){
3293: completionCursorReset((completion_cursor*)cur);
3294: sqlite3_free(cur);
3295: return SQLITE_OK;
3296: }
3297:
3298: /*
3299: ** Advance a completion_cursor to its next row of output.
3300: **
3301: ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
3302: ** record the current state of the scan. This routine sets ->zCurrentRow
3303: ** to the current row of output and then returns. If no more rows remain,
3304: ** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
3305: ** table that has reached the end of its scan.
3306: **
3307: ** The current implementation just lists potential identifiers and
3308: ** keywords and filters them by zPrefix. Future enhancements should
3309: ** take zLine into account to try to restrict the set of identifiers and
3310: ** keywords based on what would be legal at the current point of input.
3311: */
3312: static int completionNext(sqlite3_vtab_cursor *cur){
3313: completion_cursor *pCur = (completion_cursor*)cur;
3314: int eNextPhase = 0; /* Next phase to try if current phase reaches end */
3315: int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */
3316: pCur->iRowid++;
3317: while( pCur->ePhase!=COMPLETION_EOF ){
3318: switch( pCur->ePhase ){
3319: case COMPLETION_KEYWORDS: {
3320: if( pCur->j >= sqlite3_keyword_count() ){
3321: pCur->zCurrentRow = 0;
3322: pCur->ePhase = COMPLETION_DATABASES;
3323: }else{
3324: sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
3325: }
3326: iCol = -1;
3327: break;
3328: }
3329: case COMPLETION_DATABASES: {
3330: if( pCur->pStmt==0 ){
3331: sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
3332: &pCur->pStmt, 0);
3333: }
3334: iCol = 1;
3335: eNextPhase = COMPLETION_TABLES;
3336: break;
3337: }
3338: case COMPLETION_TABLES: {
3339: if( pCur->pStmt==0 ){
3340: sqlite3_stmt *pS2;
3341: char *zSql = 0;
3342: const char *zSep = "";
3343: sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
3344: while( sqlite3_step(pS2)==SQLITE_ROW ){
3345: const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
3346: zSql = sqlite3_mprintf(
3347: "%z%s"
1.4.2.3 ! misho 3348: "SELECT name FROM \"%w\".sqlite_schema",
1.4.2.2 misho 3349: zSql, zSep, zDb
3350: );
3351: if( zSql==0 ) return SQLITE_NOMEM;
3352: zSep = " UNION ";
3353: }
3354: sqlite3_finalize(pS2);
3355: sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
3356: sqlite3_free(zSql);
3357: }
3358: iCol = 0;
3359: eNextPhase = COMPLETION_COLUMNS;
3360: break;
3361: }
3362: case COMPLETION_COLUMNS: {
3363: if( pCur->pStmt==0 ){
3364: sqlite3_stmt *pS2;
3365: char *zSql = 0;
3366: const char *zSep = "";
3367: sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
3368: while( sqlite3_step(pS2)==SQLITE_ROW ){
3369: const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
3370: zSql = sqlite3_mprintf(
3371: "%z%s"
1.4.2.3 ! misho 3372: "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
1.4.2.2 misho 3373: " JOIN pragma_table_info(sm.name,%Q) AS pti"
3374: " WHERE sm.type='table'",
3375: zSql, zSep, zDb, zDb
3376: );
3377: if( zSql==0 ) return SQLITE_NOMEM;
3378: zSep = " UNION ";
3379: }
3380: sqlite3_finalize(pS2);
3381: sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
3382: sqlite3_free(zSql);
3383: }
3384: iCol = 0;
3385: eNextPhase = COMPLETION_EOF;
3386: break;
3387: }
3388: }
3389: if( iCol<0 ){
3390: /* This case is when the phase presets zCurrentRow */
3391: if( pCur->zCurrentRow==0 ) continue;
3392: }else{
3393: if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
3394: /* Extract the next row of content */
3395: pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
3396: pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
3397: }else{
3398: /* When all rows are finished, advance to the next phase */
3399: sqlite3_finalize(pCur->pStmt);
3400: pCur->pStmt = 0;
3401: pCur->ePhase = eNextPhase;
3402: continue;
3403: }
3404: }
3405: if( pCur->nPrefix==0 ) break;
3406: if( pCur->nPrefix<=pCur->szRow
3407: && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
3408: ){
3409: break;
3410: }
3411: }
3412:
3413: return SQLITE_OK;
3414: }
3415:
3416: /*
3417: ** Return values of columns for the row at which the completion_cursor
3418: ** is currently pointing.
3419: */
3420: static int completionColumn(
3421: sqlite3_vtab_cursor *cur, /* The cursor */
3422: sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
3423: int i /* Which column to return */
3424: ){
3425: completion_cursor *pCur = (completion_cursor*)cur;
3426: switch( i ){
3427: case COMPLETION_COLUMN_CANDIDATE: {
3428: sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
3429: break;
3430: }
3431: case COMPLETION_COLUMN_PREFIX: {
3432: sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
3433: break;
3434: }
3435: case COMPLETION_COLUMN_WHOLELINE: {
3436: sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
3437: break;
3438: }
3439: case COMPLETION_COLUMN_PHASE: {
3440: sqlite3_result_int(ctx, pCur->ePhase);
3441: break;
3442: }
3443: }
3444: return SQLITE_OK;
3445: }
3446:
3447: /*
3448: ** Return the rowid for the current row. In this implementation, the
3449: ** rowid is the same as the output value.
3450: */
3451: static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
3452: completion_cursor *pCur = (completion_cursor*)cur;
3453: *pRowid = pCur->iRowid;
3454: return SQLITE_OK;
3455: }
3456:
3457: /*
3458: ** Return TRUE if the cursor has been moved off of the last
3459: ** row of output.
3460: */
3461: static int completionEof(sqlite3_vtab_cursor *cur){
3462: completion_cursor *pCur = (completion_cursor*)cur;
3463: return pCur->ePhase >= COMPLETION_EOF;
3464: }
3465:
3466: /*
3467: ** This method is called to "rewind" the completion_cursor object back
3468: ** to the first row of output. This method is always called at least
3469: ** once prior to any call to completionColumn() or completionRowid() or
3470: ** completionEof().
3471: */
3472: static int completionFilter(
3473: sqlite3_vtab_cursor *pVtabCursor,
3474: int idxNum, const char *idxStr,
3475: int argc, sqlite3_value **argv
3476: ){
3477: completion_cursor *pCur = (completion_cursor *)pVtabCursor;
3478: int iArg = 0;
3479: (void)(idxStr); /* Unused parameter */
3480: (void)(argc); /* Unused parameter */
3481: completionCursorReset(pCur);
3482: if( idxNum & 1 ){
3483: pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
3484: if( pCur->nPrefix>0 ){
3485: pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
3486: if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
3487: }
3488: iArg = 1;
3489: }
3490: if( idxNum & 2 ){
3491: pCur->nLine = sqlite3_value_bytes(argv[iArg]);
3492: if( pCur->nLine>0 ){
3493: pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
3494: if( pCur->zLine==0 ) return SQLITE_NOMEM;
3495: }
3496: }
3497: if( pCur->zLine!=0 && pCur->zPrefix==0 ){
3498: int i = pCur->nLine;
3499: while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
3500: i--;
3501: }
3502: pCur->nPrefix = pCur->nLine - i;
3503: if( pCur->nPrefix>0 ){
3504: pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
3505: if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
3506: }
3507: }
3508: pCur->iRowid = 0;
3509: pCur->ePhase = COMPLETION_FIRST_PHASE;
3510: return completionNext(pVtabCursor);
3511: }
3512:
3513: /*
3514: ** SQLite will invoke this method one or more times while planning a query
3515: ** that uses the completion virtual table. This routine needs to create
3516: ** a query plan for each invocation and compute an estimated cost for that
3517: ** plan.
3518: **
3519: ** There are two hidden parameters that act as arguments to the table-valued
3520: ** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix"
3521: ** is available and bit 1 is set if "wholeline" is available.
3522: */
3523: static int completionBestIndex(
3524: sqlite3_vtab *tab,
3525: sqlite3_index_info *pIdxInfo
3526: ){
3527: int i; /* Loop over constraints */
3528: int idxNum = 0; /* The query plan bitmask */
3529: int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */
3530: int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
3531: int nArg = 0; /* Number of arguments that completeFilter() expects */
3532: const struct sqlite3_index_constraint *pConstraint;
3533:
3534: (void)(tab); /* Unused parameter */
3535: pConstraint = pIdxInfo->aConstraint;
3536: for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
3537: if( pConstraint->usable==0 ) continue;
3538: if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
3539: switch( pConstraint->iColumn ){
3540: case COMPLETION_COLUMN_PREFIX:
3541: prefixIdx = i;
3542: idxNum |= 1;
3543: break;
3544: case COMPLETION_COLUMN_WHOLELINE:
3545: wholelineIdx = i;
3546: idxNum |= 2;
3547: break;
3548: }
3549: }
3550: if( prefixIdx>=0 ){
3551: pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
3552: pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
3553: }
3554: if( wholelineIdx>=0 ){
3555: pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
3556: pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
3557: }
3558: pIdxInfo->idxNum = idxNum;
3559: pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
3560: pIdxInfo->estimatedRows = 500 - 100*nArg;
3561: return SQLITE_OK;
3562: }
3563:
3564: /*
3565: ** This following structure defines all the methods for the
3566: ** completion virtual table.
3567: */
3568: static sqlite3_module completionModule = {
3569: 0, /* iVersion */
3570: 0, /* xCreate */
3571: completionConnect, /* xConnect */
3572: completionBestIndex, /* xBestIndex */
3573: completionDisconnect, /* xDisconnect */
3574: 0, /* xDestroy */
3575: completionOpen, /* xOpen - open a cursor */
3576: completionClose, /* xClose - close a cursor */
3577: completionFilter, /* xFilter - configure scan constraints */
3578: completionNext, /* xNext - advance a cursor */
3579: completionEof, /* xEof - check for end of scan */
3580: completionColumn, /* xColumn - read data */
3581: completionRowid, /* xRowid - read data */
3582: 0, /* xUpdate */
3583: 0, /* xBegin */
3584: 0, /* xSync */
3585: 0, /* xCommit */
3586: 0, /* xRollback */
3587: 0, /* xFindMethod */
3588: 0, /* xRename */
3589: 0, /* xSavepoint */
3590: 0, /* xRelease */
3591: 0, /* xRollbackTo */
3592: 0 /* xShadowName */
3593: };
3594:
3595: #endif /* SQLITE_OMIT_VIRTUALTABLE */
3596:
3597: int sqlite3CompletionVtabInit(sqlite3 *db){
3598: int rc = SQLITE_OK;
3599: #ifndef SQLITE_OMIT_VIRTUALTABLE
3600: rc = sqlite3_create_module(db, "completion", &completionModule, 0);
3601: #endif
3602: return rc;
3603: }
3604:
3605: #ifdef _WIN32
3606:
3607: #endif
3608: int sqlite3_completion_init(
3609: sqlite3 *db,
3610: char **pzErrMsg,
3611: const sqlite3_api_routines *pApi
3612: ){
3613: int rc = SQLITE_OK;
3614: SQLITE_EXTENSION_INIT2(pApi);
3615: (void)(pzErrMsg); /* Unused parameter */
3616: #ifndef SQLITE_OMIT_VIRTUALTABLE
3617: rc = sqlite3CompletionVtabInit(db);
3618: #endif
3619: return rc;
3620: }
3621:
3622: /************************* End ../ext/misc/completion.c ********************/
3623: /************************* Begin ../ext/misc/appendvfs.c ******************/
3624: /*
3625: ** 2017-10-20
3626: **
3627: ** The author disclaims copyright to this source code. In place of
3628: ** a legal notice, here is a blessing:
3629: **
3630: ** May you do good and not evil.
3631: ** May you find forgiveness for yourself and forgive others.
3632: ** May you share freely, never taking more than you give.
3633: **
3634: ******************************************************************************
3635: **
3636: ** This file implements a VFS shim that allows an SQLite database to be
3637: ** appended onto the end of some other file, such as an executable.
3638: **
3639: ** A special record must appear at the end of the file that identifies the
3640: ** file as an appended database and provides an offset to page 1. For
3641: ** best performance page 1 should be located at a disk page boundary, though
3642: ** that is not required.
3643: **
3644: ** When opening a database using this VFS, the connection might treat
3645: ** the file as an ordinary SQLite database, or it might treat is as a
3646: ** database appended onto some other file. Here are the rules:
3647: **
3648: ** (1) When opening a new empty file, that file is treated as an ordinary
3649: ** database.
3650: **
3651: ** (2) When opening a file that begins with the standard SQLite prefix
3652: ** string "SQLite format 3", that file is treated as an ordinary
3653: ** database.
3654: **
3655: ** (3) When opening a file that ends with the appendvfs trailer string
3656: ** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended
3657: ** database.
3658: **
3659: ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is
3660: ** set, then a new database is appended to the already existing file.
3661: **
3662: ** (5) Otherwise, SQLITE_CANTOPEN is returned.
3663: **
3664: ** To avoid unnecessary complications with the PENDING_BYTE, the size of
3665: ** the file containing the database is limited to 1GB. This VFS will refuse
3666: ** to read or write past the 1GB mark. This restriction might be lifted in
3667: ** future versions. For now, if you need a large database, then keep the
3668: ** database in a separate file.
3669: **
3670: ** If the file being opened is not an appended database, then this shim is
3671: ** a pass-through into the default underlying VFS.
3672: **/
3673: /* #include "sqlite3ext.h" */
3674: SQLITE_EXTENSION_INIT1
3675: #include <string.h>
3676: #include <assert.h>
3677:
3678: /* The append mark at the end of the database is:
3679: **
3680: ** Start-Of-SQLite3-NNNNNNNN
3681: ** 123456789 123456789 12345
3682: **
3683: ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
3684: ** the offset to page 1.
3685: */
3686: #define APND_MARK_PREFIX "Start-Of-SQLite3-"
3687: #define APND_MARK_PREFIX_SZ 17
3688: #define APND_MARK_SIZE 25
3689:
3690: /*
3691: ** Maximum size of the combined prefix + database + append-mark. This
3692: ** must be less than 0x40000000 to avoid locking issues on Windows.
3693: */
3694: #define APND_MAX_SIZE (65536*15259)
3695:
3696: /*
3697: ** Forward declaration of objects used by this utility
3698: */
3699: typedef struct sqlite3_vfs ApndVfs;
3700: typedef struct ApndFile ApndFile;
3701:
3702: /* Access to a lower-level VFS that (might) implement dynamic loading,
3703: ** access to randomness, etc.
3704: */
3705: #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
3706: #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
3707:
3708: /* An open file */
3709: struct ApndFile {
3710: sqlite3_file base; /* IO methods */
3711: sqlite3_int64 iPgOne; /* File offset to page 1 */
3712: sqlite3_int64 iMark; /* Start of the append-mark */
3713: };
3714:
3715: /*
3716: ** Methods for ApndFile
3717: */
3718: static int apndClose(sqlite3_file*);
3719: static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
3720: static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
3721: static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
3722: static int apndSync(sqlite3_file*, int flags);
3723: static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
3724: static int apndLock(sqlite3_file*, int);
3725: static int apndUnlock(sqlite3_file*, int);
3726: static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
3727: static int apndFileControl(sqlite3_file*, int op, void *pArg);
3728: static int apndSectorSize(sqlite3_file*);
3729: static int apndDeviceCharacteristics(sqlite3_file*);
3730: static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
3731: static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
3732: static void apndShmBarrier(sqlite3_file*);
3733: static int apndShmUnmap(sqlite3_file*, int deleteFlag);
3734: static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
3735: static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
3736:
3737: /*
3738: ** Methods for ApndVfs
3739: */
3740: static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
3741: static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
3742: static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
3743: static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
3744: static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
3745: static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
3746: static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
3747: static void apndDlClose(sqlite3_vfs*, void*);
3748: static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
3749: static int apndSleep(sqlite3_vfs*, int microseconds);
3750: static int apndCurrentTime(sqlite3_vfs*, double*);
3751: static int apndGetLastError(sqlite3_vfs*, int, char *);
3752: static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
3753: static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
3754: static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
3755: static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
3756:
3757: static sqlite3_vfs apnd_vfs = {
3758: 3, /* iVersion (set when registered) */
3759: 0, /* szOsFile (set when registered) */
3760: 1024, /* mxPathname */
3761: 0, /* pNext */
3762: "apndvfs", /* zName */
3763: 0, /* pAppData (set when registered) */
3764: apndOpen, /* xOpen */
3765: apndDelete, /* xDelete */
3766: apndAccess, /* xAccess */
3767: apndFullPathname, /* xFullPathname */
3768: apndDlOpen, /* xDlOpen */
3769: apndDlError, /* xDlError */
3770: apndDlSym, /* xDlSym */
3771: apndDlClose, /* xDlClose */
3772: apndRandomness, /* xRandomness */
3773: apndSleep, /* xSleep */
3774: apndCurrentTime, /* xCurrentTime */
3775: apndGetLastError, /* xGetLastError */
3776: apndCurrentTimeInt64, /* xCurrentTimeInt64 */
3777: apndSetSystemCall, /* xSetSystemCall */
3778: apndGetSystemCall, /* xGetSystemCall */
3779: apndNextSystemCall /* xNextSystemCall */
3780: };
3781:
3782: static const sqlite3_io_methods apnd_io_methods = {
3783: 3, /* iVersion */
3784: apndClose, /* xClose */
3785: apndRead, /* xRead */
3786: apndWrite, /* xWrite */
3787: apndTruncate, /* xTruncate */
3788: apndSync, /* xSync */
3789: apndFileSize, /* xFileSize */
3790: apndLock, /* xLock */
3791: apndUnlock, /* xUnlock */
3792: apndCheckReservedLock, /* xCheckReservedLock */
3793: apndFileControl, /* xFileControl */
3794: apndSectorSize, /* xSectorSize */
3795: apndDeviceCharacteristics, /* xDeviceCharacteristics */
3796: apndShmMap, /* xShmMap */
3797: apndShmLock, /* xShmLock */
3798: apndShmBarrier, /* xShmBarrier */
3799: apndShmUnmap, /* xShmUnmap */
3800: apndFetch, /* xFetch */
3801: apndUnfetch /* xUnfetch */
3802: };
3803:
3804:
3805:
3806: /*
3807: ** Close an apnd-file.
3808: */
3809: static int apndClose(sqlite3_file *pFile){
3810: pFile = ORIGFILE(pFile);
3811: return pFile->pMethods->xClose(pFile);
3812: }
3813:
3814: /*
3815: ** Read data from an apnd-file.
3816: */
3817: static int apndRead(
3818: sqlite3_file *pFile,
3819: void *zBuf,
3820: int iAmt,
3821: sqlite_int64 iOfst
3822: ){
3823: ApndFile *p = (ApndFile *)pFile;
3824: pFile = ORIGFILE(pFile);
3825: return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne);
3826: }
3827:
3828: /*
3829: ** Add the append-mark onto the end of the file.
3830: */
3831: static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){
3832: int i;
3833: unsigned char a[APND_MARK_SIZE];
3834: memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
3835: for(i=0; i<8; i++){
3836: a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff;
3837: }
3838: return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark);
3839: }
3840:
3841: /*
3842: ** Write data to an apnd-file.
3843: */
3844: static int apndWrite(
3845: sqlite3_file *pFile,
3846: const void *zBuf,
3847: int iAmt,
3848: sqlite_int64 iOfst
3849: ){
3850: int rc;
3851: ApndFile *p = (ApndFile *)pFile;
3852: pFile = ORIGFILE(pFile);
3853: if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL;
3854: rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne);
3855: if( rc==SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark ){
3856: sqlite3_int64 sz = 0;
3857: rc = pFile->pMethods->xFileSize(pFile, &sz);
3858: if( rc==SQLITE_OK ){
3859: p->iMark = sz - APND_MARK_SIZE;
3860: if( iOfst + iAmt + p->iPgOne > p->iMark ){
3861: p->iMark = p->iPgOne + iOfst + iAmt;
3862: rc = apndWriteMark(p, pFile);
3863: }
3864: }
3865: }
3866: return rc;
3867: }
3868:
3869: /*
3870: ** Truncate an apnd-file.
3871: */
3872: static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
3873: int rc;
3874: ApndFile *p = (ApndFile *)pFile;
3875: pFile = ORIGFILE(pFile);
3876: rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE);
3877: if( rc==SQLITE_OK ){
3878: p->iMark = p->iPgOne+size;
3879: rc = apndWriteMark(p, pFile);
3880: }
3881: return rc;
3882: }
3883:
3884: /*
3885: ** Sync an apnd-file.
3886: */
3887: static int apndSync(sqlite3_file *pFile, int flags){
3888: pFile = ORIGFILE(pFile);
3889: return pFile->pMethods->xSync(pFile, flags);
3890: }
3891:
3892: /*
3893: ** Return the current file-size of an apnd-file.
3894: */
3895: static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
3896: ApndFile *p = (ApndFile *)pFile;
3897: int rc;
3898: pFile = ORIGFILE(p);
3899: rc = pFile->pMethods->xFileSize(pFile, pSize);
3900: if( rc==SQLITE_OK && p->iPgOne ){
3901: *pSize -= p->iPgOne + APND_MARK_SIZE;
3902: }
3903: return rc;
3904: }
3905:
3906: /*
3907: ** Lock an apnd-file.
3908: */
3909: static int apndLock(sqlite3_file *pFile, int eLock){
3910: pFile = ORIGFILE(pFile);
3911: return pFile->pMethods->xLock(pFile, eLock);
3912: }
3913:
3914: /*
3915: ** Unlock an apnd-file.
3916: */
3917: static int apndUnlock(sqlite3_file *pFile, int eLock){
3918: pFile = ORIGFILE(pFile);
3919: return pFile->pMethods->xUnlock(pFile, eLock);
3920: }
3921:
3922: /*
3923: ** Check if another file-handle holds a RESERVED lock on an apnd-file.
3924: */
3925: static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
3926: pFile = ORIGFILE(pFile);
3927: return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
3928: }
3929:
3930: /*
3931: ** File control method. For custom operations on an apnd-file.
3932: */
3933: static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
3934: ApndFile *p = (ApndFile *)pFile;
3935: int rc;
3936: pFile = ORIGFILE(pFile);
3937: rc = pFile->pMethods->xFileControl(pFile, op, pArg);
3938: if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
3939: *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg);
3940: }
3941: return rc;
3942: }
3943:
3944: /*
3945: ** Return the sector-size in bytes for an apnd-file.
3946: */
3947: static int apndSectorSize(sqlite3_file *pFile){
3948: pFile = ORIGFILE(pFile);
3949: return pFile->pMethods->xSectorSize(pFile);
3950: }
3951:
3952: /*
3953: ** Return the device characteristic flags supported by an apnd-file.
3954: */
3955: static int apndDeviceCharacteristics(sqlite3_file *pFile){
3956: pFile = ORIGFILE(pFile);
3957: return pFile->pMethods->xDeviceCharacteristics(pFile);
3958: }
3959:
3960: /* Create a shared memory file mapping */
3961: static int apndShmMap(
3962: sqlite3_file *pFile,
3963: int iPg,
3964: int pgsz,
3965: int bExtend,
3966: void volatile **pp
3967: ){
3968: pFile = ORIGFILE(pFile);
3969: return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
3970: }
3971:
3972: /* Perform locking on a shared-memory segment */
3973: static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
3974: pFile = ORIGFILE(pFile);
3975: return pFile->pMethods->xShmLock(pFile,offset,n,flags);
3976: }
3977:
3978: /* Memory barrier operation on shared memory */
3979: static void apndShmBarrier(sqlite3_file *pFile){
3980: pFile = ORIGFILE(pFile);
3981: pFile->pMethods->xShmBarrier(pFile);
3982: }
3983:
3984: /* Unmap a shared memory segment */
3985: static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
3986: pFile = ORIGFILE(pFile);
3987: return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
3988: }
3989:
3990: /* Fetch a page of a memory-mapped file */
3991: static int apndFetch(
3992: sqlite3_file *pFile,
3993: sqlite3_int64 iOfst,
3994: int iAmt,
3995: void **pp
3996: ){
3997: ApndFile *p = (ApndFile *)pFile;
3998: pFile = ORIGFILE(pFile);
3999: return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
4000: }
4001:
4002: /* Release a memory-mapped page */
4003: static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
4004: ApndFile *p = (ApndFile *)pFile;
4005: pFile = ORIGFILE(pFile);
4006: return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
4007: }
4008:
4009: /*
4010: ** Check to see if the file is an ordinary SQLite database file.
4011: */
4012: static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
4013: int rc;
4014: char zHdr[16];
4015: static const char aSqliteHdr[] = "SQLite format 3";
4016: if( sz<512 ) return 0;
4017: rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0);
4018: if( rc ) return 0;
4019: return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0;
4020: }
4021:
4022: /*
4023: ** Try to read the append-mark off the end of a file. Return the
4024: ** start of the appended database if the append-mark is present. If
4025: ** there is no append-mark, return -1;
4026: */
4027: static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
4028: int rc, i;
4029: sqlite3_int64 iMark;
4030: unsigned char a[APND_MARK_SIZE];
4031:
4032: if( sz<=APND_MARK_SIZE ) return -1;
4033: rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
4034: if( rc ) return -1;
4035: if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
4036: iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56;
4037: for(i=1; i<8; i++){
4038: iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i);
4039: }
4040: return iMark;
4041: }
4042:
4043: /*
4044: ** Open an apnd file handle.
4045: */
4046: static int apndOpen(
4047: sqlite3_vfs *pVfs,
4048: const char *zName,
4049: sqlite3_file *pFile,
4050: int flags,
4051: int *pOutFlags
4052: ){
4053: ApndFile *p;
4054: sqlite3_file *pSubFile;
4055: sqlite3_vfs *pSubVfs;
4056: int rc;
4057: sqlite3_int64 sz;
4058: pSubVfs = ORIGVFS(pVfs);
4059: if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
4060: return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
4061: }
4062: p = (ApndFile*)pFile;
4063: memset(p, 0, sizeof(*p));
4064: pSubFile = ORIGFILE(pFile);
1.4.2.3 ! misho 4065: pFile->pMethods = &apnd_io_methods;
1.4.2.2 misho 4066: rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
4067: if( rc ) goto apnd_open_done;
4068: rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
4069: if( rc ){
4070: pSubFile->pMethods->xClose(pSubFile);
4071: goto apnd_open_done;
4072: }
4073: if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
4074: memmove(pFile, pSubFile, pSubVfs->szOsFile);
4075: return SQLITE_OK;
4076: }
4077: p->iMark = 0;
4078: p->iPgOne = apndReadMark(sz, pFile);
4079: if( p->iPgOne>0 ){
4080: return SQLITE_OK;
4081: }
4082: if( (flags & SQLITE_OPEN_CREATE)==0 ){
4083: pSubFile->pMethods->xClose(pSubFile);
4084: rc = SQLITE_CANTOPEN;
4085: }
4086: p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff;
4087: apnd_open_done:
4088: if( rc ) pFile->pMethods = 0;
4089: return rc;
4090: }
4091:
4092: /*
4093: ** All other VFS methods are pass-thrus.
4094: */
4095: static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
4096: return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
4097: }
4098: static int apndAccess(
4099: sqlite3_vfs *pVfs,
4100: const char *zPath,
4101: int flags,
4102: int *pResOut
4103: ){
4104: return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
4105: }
4106: static int apndFullPathname(
4107: sqlite3_vfs *pVfs,
4108: const char *zPath,
4109: int nOut,
4110: char *zOut
4111: ){
4112: return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
4113: }
4114: static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
4115: return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
4116: }
4117: static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
4118: ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
4119: }
4120: static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
4121: return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
4122: }
4123: static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
4124: ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
4125: }
4126: static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
4127: return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
4128: }
4129: static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
4130: return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
4131: }
4132: static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
4133: return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
4134: }
4135: static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
4136: return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
4137: }
4138: static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
4139: return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
4140: }
4141: static int apndSetSystemCall(
4142: sqlite3_vfs *pVfs,
4143: const char *zName,
4144: sqlite3_syscall_ptr pCall
4145: ){
4146: return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
4147: }
4148: static sqlite3_syscall_ptr apndGetSystemCall(
4149: sqlite3_vfs *pVfs,
4150: const char *zName
4151: ){
4152: return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
4153: }
4154: static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
4155: return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
4156: }
4157:
4158:
4159: #ifdef _WIN32
4160:
4161: #endif
4162: /*
4163: ** This routine is called when the extension is loaded.
4164: ** Register the new VFS.
4165: */
4166: int sqlite3_appendvfs_init(
4167: sqlite3 *db,
4168: char **pzErrMsg,
4169: const sqlite3_api_routines *pApi
4170: ){
4171: int rc = SQLITE_OK;
4172: sqlite3_vfs *pOrig;
4173: SQLITE_EXTENSION_INIT2(pApi);
4174: (void)pzErrMsg;
4175: (void)db;
4176: pOrig = sqlite3_vfs_find(0);
4177: apnd_vfs.iVersion = pOrig->iVersion;
4178: apnd_vfs.pAppData = pOrig;
4179: apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
4180: rc = sqlite3_vfs_register(&apnd_vfs, 0);
4181: #ifdef APPENDVFS_TEST
4182: if( rc==SQLITE_OK ){
4183: rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
4184: }
4185: #endif
4186: if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
4187: return rc;
4188: }
4189:
4190: /************************* End ../ext/misc/appendvfs.c ********************/
4191: /************************* Begin ../ext/misc/memtrace.c ******************/
4192: /*
4193: ** 2019-01-21
4194: **
4195: ** The author disclaims copyright to this source code. In place of
4196: ** a legal notice, here is a blessing:
4197: **
4198: ** May you do good and not evil.
4199: ** May you find forgiveness for yourself and forgive others.
4200: ** May you share freely, never taking more than you give.
4201: **
4202: *************************************************************************
4203: **
4204: ** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
4205: ** mechanism to add a tracing layer on top of SQLite. If this extension
4206: ** is registered prior to sqlite3_initialize(), it will cause all memory
4207: ** allocation activities to be logged on standard output, or to some other
4208: ** FILE specified by the initializer.
4209: **
4210: ** This file needs to be compiled into the application that uses it.
4211: **
4212: ** This extension is used to implement the --memtrace option of the
4213: ** command-line shell.
4214: */
4215: #include <assert.h>
4216: #include <string.h>
4217: #include <stdio.h>
4218:
4219: /* The original memory allocation routines */
4220: static sqlite3_mem_methods memtraceBase;
4221: static FILE *memtraceOut;
4222:
1.4.2.3 ! misho 4223: /* Methods that trace memory allocations */
! 4224: static void *memtraceMalloc(int n){
! 4225: if( memtraceOut ){
! 4226: fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n",
! 4227: memtraceBase.xRoundup(n));
! 4228: }
! 4229: return memtraceBase.xMalloc(n);
! 4230: }
! 4231: static void memtraceFree(void *p){
! 4232: if( p==0 ) return;
! 4233: if( memtraceOut ){
! 4234: fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
! 4235: }
! 4236: memtraceBase.xFree(p);
! 4237: }
! 4238: static void *memtraceRealloc(void *p, int n){
! 4239: if( p==0 ) return memtraceMalloc(n);
! 4240: if( n==0 ){
! 4241: memtraceFree(p);
! 4242: return 0;
! 4243: }
! 4244: if( memtraceOut ){
! 4245: fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
! 4246: memtraceBase.xSize(p), memtraceBase.xRoundup(n));
! 4247: }
! 4248: return memtraceBase.xRealloc(p, n);
! 4249: }
! 4250: static int memtraceSize(void *p){
! 4251: return memtraceBase.xSize(p);
! 4252: }
! 4253: static int memtraceRoundup(int n){
! 4254: return memtraceBase.xRoundup(n);
! 4255: }
! 4256: static int memtraceInit(void *p){
! 4257: return memtraceBase.xInit(p);
! 4258: }
! 4259: static void memtraceShutdown(void *p){
! 4260: memtraceBase.xShutdown(p);
! 4261: }
! 4262:
! 4263: /* The substitute memory allocator */
! 4264: static sqlite3_mem_methods ersaztMethods = {
! 4265: memtraceMalloc,
! 4266: memtraceFree,
! 4267: memtraceRealloc,
! 4268: memtraceSize,
! 4269: memtraceRoundup,
! 4270: memtraceInit,
! 4271: memtraceShutdown,
! 4272: 0
! 4273: };
! 4274:
! 4275: /* Begin tracing memory allocations to out. */
! 4276: int sqlite3MemTraceActivate(FILE *out){
! 4277: int rc = SQLITE_OK;
! 4278: if( memtraceBase.xMalloc==0 ){
! 4279: rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
! 4280: if( rc==SQLITE_OK ){
! 4281: rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
! 4282: }
! 4283: }
! 4284: memtraceOut = out;
! 4285: return rc;
! 4286: }
! 4287:
! 4288: /* Deactivate memory tracing */
! 4289: int sqlite3MemTraceDeactivate(void){
! 4290: int rc = SQLITE_OK;
! 4291: if( memtraceBase.xMalloc!=0 ){
! 4292: rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
! 4293: if( rc==SQLITE_OK ){
! 4294: memset(&memtraceBase, 0, sizeof(memtraceBase));
! 4295: }
! 4296: }
! 4297: memtraceOut = 0;
! 4298: return rc;
! 4299: }
! 4300:
! 4301: /************************* End ../ext/misc/memtrace.c ********************/
! 4302: /************************* Begin ../ext/misc/uint.c ******************/
! 4303: /*
! 4304: ** 2020-04-14
! 4305: **
! 4306: ** The author disclaims copyright to this source code. In place of
! 4307: ** a legal notice, here is a blessing:
! 4308: **
! 4309: ** May you do good and not evil.
! 4310: ** May you find forgiveness for yourself and forgive others.
! 4311: ** May you share freely, never taking more than you give.
! 4312: **
! 4313: ******************************************************************************
! 4314: **
! 4315: ** This SQLite extension implements the UINT collating sequence.
! 4316: **
! 4317: ** UINT works like BINARY for text, except that embedded strings
! 4318: ** of digits compare in numeric order.
! 4319: **
! 4320: ** * Leading zeros are handled properly, in the sense that
! 4321: ** they do not mess of the maginitude comparison of embedded
! 4322: ** strings of digits. "x00123y" is equal to "x123y".
! 4323: **
! 4324: ** * Only unsigned integers are recognized. Plus and minus
! 4325: ** signs are ignored. Decimal points and exponential notation
! 4326: ** are ignored.
! 4327: **
! 4328: ** * Embedded integers can be of arbitrary length. Comparison
! 4329: ** is *not* limited integers that can be expressed as a
! 4330: ** 64-bit machine integer.
! 4331: */
! 4332: /* #include "sqlite3ext.h" */
! 4333: SQLITE_EXTENSION_INIT1
! 4334: #include <assert.h>
! 4335: #include <string.h>
! 4336: #include <ctype.h>
! 4337:
! 4338: /*
! 4339: ** Compare text in lexicographic order, except strings of digits
! 4340: ** compare in numeric order.
! 4341: */
! 4342: static int uintCollFunc(
! 4343: void *notUsed,
! 4344: int nKey1, const void *pKey1,
! 4345: int nKey2, const void *pKey2
! 4346: ){
! 4347: const unsigned char *zA = (const unsigned char*)pKey1;
! 4348: const unsigned char *zB = (const unsigned char*)pKey2;
! 4349: int i=0, j=0, x;
! 4350: (void)notUsed;
! 4351: while( i<nKey1 && j<nKey2 ){
! 4352: x = zA[i] - zB[j];
! 4353: if( isdigit(zA[i]) ){
! 4354: int k;
! 4355: if( !isdigit(zB[j]) ) return x;
! 4356: while( i<nKey1 && zA[i]=='0' ){ i++; }
! 4357: while( j<nKey2 && zB[j]=='0' ){ j++; }
! 4358: k = 0;
! 4359: while( i+k<nKey1 && isdigit(zA[i+k])
! 4360: && j+k<nKey2 && isdigit(zB[j+k]) ){
! 4361: k++;
! 4362: }
! 4363: if( i+k<nKey1 && isdigit(zA[i+k]) ){
! 4364: return +1;
! 4365: }else if( j+k<nKey2 && isdigit(zB[j+k]) ){
! 4366: return -1;
! 4367: }else{
! 4368: x = memcmp(zA+i, zB+j, k);
! 4369: if( x ) return x;
! 4370: i += k;
! 4371: j += k;
! 4372: }
! 4373: }else if( x ){
! 4374: return x;
! 4375: }else{
! 4376: i++;
! 4377: j++;
! 4378: }
! 4379: }
! 4380: return (nKey1 - i) - (nKey2 - j);
! 4381: }
! 4382:
! 4383: #ifdef _WIN32
! 4384:
! 4385: #endif
! 4386: int sqlite3_uint_init(
! 4387: sqlite3 *db,
! 4388: char **pzErrMsg,
! 4389: const sqlite3_api_routines *pApi
! 4390: ){
! 4391: SQLITE_EXTENSION_INIT2(pApi);
! 4392: (void)pzErrMsg; /* Unused parameter */
! 4393: return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
! 4394: }
! 4395:
! 4396: /************************* End ../ext/misc/uint.c ********************/
! 4397: /************************* Begin ../ext/misc/decimal.c ******************/
! 4398: /*
! 4399: ** 2020-06-22
! 4400: **
! 4401: ** The author disclaims copyright to this source code. In place of
! 4402: ** a legal notice, here is a blessing:
! 4403: **
! 4404: ** May you do good and not evil.
! 4405: ** May you find forgiveness for yourself and forgive others.
! 4406: ** May you share freely, never taking more than you give.
! 4407: **
! 4408: ******************************************************************************
! 4409: **
! 4410: ** Routines to implement arbitrary-precision decimal math.
! 4411: **
! 4412: ** The focus here is on simplicity and correctness, not performance.
! 4413: */
! 4414: /* #include "sqlite3ext.h" */
! 4415: SQLITE_EXTENSION_INIT1
! 4416: #include <assert.h>
! 4417: #include <string.h>
! 4418: #include <ctype.h>
! 4419: #include <stdlib.h>
! 4420:
! 4421: /* Mark a function parameter as unused, to suppress nuisance compiler
! 4422: ** warnings. */
! 4423: #ifndef UNUSED_PARAMETER
! 4424: # define UNUSED_PARAMETER(X) (void)(X)
! 4425: #endif
! 4426:
! 4427:
! 4428: /* A decimal object */
! 4429: typedef struct Decimal Decimal;
! 4430: struct Decimal {
! 4431: char sign; /* 0 for positive, 1 for negative */
! 4432: char oom; /* True if an OOM is encountered */
! 4433: char isNull; /* True if holds a NULL rather than a number */
! 4434: char isInit; /* True upon initialization */
! 4435: int nDigit; /* Total number of digits */
! 4436: int nFrac; /* Number of digits to the right of the decimal point */
! 4437: signed char *a; /* Array of digits. Most significant first. */
! 4438: };
! 4439:
! 4440: /*
! 4441: ** Release memory held by a Decimal, but do not free the object itself.
! 4442: */
! 4443: static void decimal_clear(Decimal *p){
! 4444: sqlite3_free(p->a);
! 4445: }
! 4446:
! 4447: /*
! 4448: ** Destroy a Decimal object
! 4449: */
! 4450: static void decimal_free(Decimal *p){
! 4451: if( p ){
! 4452: decimal_clear(p);
! 4453: sqlite3_free(p);
! 4454: }
! 4455: }
! 4456:
! 4457: /*
! 4458: ** Allocate a new Decimal object. Initialize it to the number given
! 4459: ** by the input string.
! 4460: */
! 4461: static Decimal *decimal_new(
! 4462: sqlite3_context *pCtx,
! 4463: sqlite3_value *pIn,
! 4464: int nAlt,
! 4465: const unsigned char *zAlt
! 4466: ){
! 4467: Decimal *p;
! 4468: int n, i;
! 4469: const unsigned char *zIn;
! 4470: int iExp = 0;
! 4471: p = sqlite3_malloc( sizeof(*p) );
! 4472: if( p==0 ) goto new_no_mem;
! 4473: p->sign = 0;
! 4474: p->oom = 0;
! 4475: p->isInit = 1;
! 4476: p->isNull = 0;
! 4477: p->nDigit = 0;
! 4478: p->nFrac = 0;
! 4479: if( zAlt ){
! 4480: n = nAlt,
! 4481: zIn = zAlt;
! 4482: }else{
! 4483: if( sqlite3_value_type(pIn)==SQLITE_NULL ){
! 4484: p->a = 0;
! 4485: p->isNull = 1;
! 4486: return p;
! 4487: }
! 4488: n = sqlite3_value_bytes(pIn);
! 4489: zIn = sqlite3_value_text(pIn);
! 4490: }
! 4491: p->a = sqlite3_malloc64( n+1 );
! 4492: if( p->a==0 ) goto new_no_mem;
! 4493: for(i=0; isspace(zIn[i]); i++){}
! 4494: if( zIn[i]=='-' ){
! 4495: p->sign = 1;
! 4496: i++;
! 4497: }else if( zIn[i]=='+' ){
! 4498: i++;
! 4499: }
! 4500: while( i<n && zIn[i]=='0' ) i++;
! 4501: while( i<n ){
! 4502: char c = zIn[i];
! 4503: if( c>='0' && c<='9' ){
! 4504: p->a[p->nDigit++] = c - '0';
! 4505: }else if( c=='.' ){
! 4506: p->nFrac = p->nDigit + 1;
! 4507: }else if( c=='e' || c=='E' ){
! 4508: int j = i+1;
! 4509: int neg = 0;
! 4510: if( j>=n ) break;
! 4511: if( zIn[j]=='-' ){
! 4512: neg = 1;
! 4513: j++;
! 4514: }else if( zIn[j]=='+' ){
! 4515: j++;
! 4516: }
! 4517: while( j<n && iExp<1000000 ){
! 4518: if( zIn[j]>='0' && zIn[j]<='9' ){
! 4519: iExp = iExp*10 + zIn[j] - '0';
! 4520: }
! 4521: j++;
! 4522: }
! 4523: if( neg ) iExp = -iExp;
! 4524: break;
! 4525: }
! 4526: i++;
! 4527: }
! 4528: if( p->nFrac ){
! 4529: p->nFrac = p->nDigit - (p->nFrac - 1);
! 4530: }
! 4531: if( iExp>0 ){
! 4532: if( p->nFrac>0 ){
! 4533: if( iExp<=p->nFrac ){
! 4534: p->nFrac -= iExp;
! 4535: iExp = 0;
! 4536: }else{
! 4537: iExp -= p->nFrac;
! 4538: p->nFrac = 0;
! 4539: }
! 4540: }
! 4541: if( iExp>0 ){
! 4542: p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
! 4543: if( p->a==0 ) goto new_no_mem;
! 4544: memset(p->a+p->nDigit, 0, iExp);
! 4545: p->nDigit += iExp;
! 4546: }
! 4547: }else if( iExp<0 ){
! 4548: int nExtra;
! 4549: iExp = -iExp;
! 4550: nExtra = p->nDigit - p->nFrac - 1;
! 4551: if( nExtra ){
! 4552: if( nExtra>=iExp ){
! 4553: p->nFrac += iExp;
! 4554: iExp = 0;
! 4555: }else{
! 4556: iExp -= nExtra;
! 4557: p->nFrac = p->nDigit - 1;
! 4558: }
! 4559: }
! 4560: if( iExp>0 ){
! 4561: p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
! 4562: if( p->a==0 ) goto new_no_mem;
! 4563: memmove(p->a+iExp, p->a, p->nDigit);
! 4564: memset(p->a, 0, iExp);
! 4565: p->nDigit += iExp;
! 4566: p->nFrac += iExp;
! 4567: }
! 4568: }
! 4569: return p;
! 4570:
! 4571: new_no_mem:
! 4572: if( pCtx ) sqlite3_result_error_nomem(pCtx);
! 4573: sqlite3_free(p);
! 4574: return 0;
! 4575: }
! 4576:
! 4577: /*
! 4578: ** Make the given Decimal the result.
! 4579: */
! 4580: static void decimal_result(sqlite3_context *pCtx, Decimal *p){
! 4581: char *z;
! 4582: int i, j;
! 4583: int n;
! 4584: if( p==0 || p->oom ){
! 4585: sqlite3_result_error_nomem(pCtx);
! 4586: return;
! 4587: }
! 4588: if( p->isNull ){
! 4589: sqlite3_result_null(pCtx);
! 4590: return;
! 4591: }
! 4592: z = sqlite3_malloc( p->nDigit+4 );
! 4593: if( z==0 ){
! 4594: sqlite3_result_error_nomem(pCtx);
! 4595: return;
! 4596: }
! 4597: i = 0;
! 4598: if( p->nDigit==0 || (p->nDigit==1 && p->a[0]==0) ){
! 4599: p->sign = 0;
! 4600: }
! 4601: if( p->sign ){
! 4602: z[0] = '-';
! 4603: i = 1;
! 4604: }
! 4605: n = p->nDigit - p->nFrac;
! 4606: if( n<=0 ){
! 4607: z[i++] = '0';
! 4608: }
! 4609: j = 0;
! 4610: while( n>1 && p->a[j]==0 ){
! 4611: j++;
! 4612: n--;
! 4613: }
! 4614: while( n>0 ){
! 4615: z[i++] = p->a[j] + '0';
! 4616: j++;
! 4617: n--;
! 4618: }
! 4619: if( p->nFrac ){
! 4620: z[i++] = '.';
! 4621: do{
! 4622: z[i++] = p->a[j] + '0';
! 4623: j++;
! 4624: }while( j<p->nDigit );
! 4625: }
! 4626: z[i] = 0;
! 4627: sqlite3_result_text(pCtx, z, i, sqlite3_free);
! 4628: }
! 4629:
! 4630: /*
! 4631: ** SQL Function: decimal(X)
! 4632: **
! 4633: ** Convert input X into decimal and then back into text
! 4634: */
! 4635: static void decimalFunc(
! 4636: sqlite3_context *context,
! 4637: int argc,
! 4638: sqlite3_value **argv
! 4639: ){
! 4640: Decimal *p = decimal_new(context, argv[0], 0, 0);
! 4641: UNUSED_PARAMETER(argc);
! 4642: decimal_result(context, p);
! 4643: decimal_free(p);
! 4644: }
! 4645:
! 4646: /*
! 4647: ** Compare to Decimal objects. Return negative, 0, or positive if the
! 4648: ** first object is less than, equal to, or greater than the second.
! 4649: **
! 4650: ** Preconditions for this routine:
! 4651: **
! 4652: ** pA!=0
! 4653: ** pA->isNull==0
! 4654: ** pB!=0
! 4655: ** pB->isNull==0
! 4656: */
! 4657: static int decimal_cmp(const Decimal *pA, const Decimal *pB){
! 4658: int nASig, nBSig, rc, n;
! 4659: if( pA->sign!=pB->sign ){
! 4660: return pA->sign ? -1 : +1;
! 4661: }
! 4662: if( pA->sign ){
! 4663: const Decimal *pTemp = pA;
! 4664: pA = pB;
! 4665: pB = pTemp;
! 4666: }
! 4667: nASig = pA->nDigit - pA->nFrac;
! 4668: nBSig = pB->nDigit - pB->nFrac;
! 4669: if( nASig!=nBSig ){
! 4670: return nASig - nBSig;
! 4671: }
! 4672: n = pA->nDigit;
! 4673: if( n>pB->nDigit ) n = pB->nDigit;
! 4674: rc = memcmp(pA->a, pB->a, n);
! 4675: if( rc==0 ){
! 4676: rc = pA->nDigit - pB->nDigit;
! 4677: }
! 4678: return rc;
! 4679: }
! 4680:
! 4681: /*
! 4682: ** SQL Function: decimal_cmp(X, Y)
! 4683: **
! 4684: ** Return negative, zero, or positive if X is less then, equal to, or
! 4685: ** greater than Y.
! 4686: */
! 4687: static void decimalCmpFunc(
! 4688: sqlite3_context *context,
! 4689: int argc,
! 4690: sqlite3_value **argv
! 4691: ){
! 4692: Decimal *pA = 0, *pB = 0;
! 4693: int rc;
! 4694:
! 4695: UNUSED_PARAMETER(argc);
! 4696: pA = decimal_new(context, argv[0], 0, 0);
! 4697: if( pA==0 || pA->isNull ) goto cmp_done;
! 4698: pB = decimal_new(context, argv[1], 0, 0);
! 4699: if( pB==0 || pB->isNull ) goto cmp_done;
! 4700: rc = decimal_cmp(pA, pB);
! 4701: if( rc<0 ) rc = -1;
! 4702: else if( rc>0 ) rc = +1;
! 4703: sqlite3_result_int(context, rc);
! 4704: cmp_done:
! 4705: decimal_free(pA);
! 4706: decimal_free(pB);
! 4707: }
! 4708:
! 4709: /*
! 4710: ** Expand the Decimal so that it has a least nDigit digits and nFrac
! 4711: ** digits to the right of the decimal point.
! 4712: */
! 4713: static void decimal_expand(Decimal *p, int nDigit, int nFrac){
! 4714: int nAddSig;
! 4715: int nAddFrac;
! 4716: if( p==0 ) return;
! 4717: nAddFrac = nFrac - p->nFrac;
! 4718: nAddSig = (nDigit - p->nDigit) - nAddFrac;
! 4719: if( nAddFrac==0 && nAddSig==0 ) return;
! 4720: p->a = sqlite3_realloc64(p->a, nDigit+1);
! 4721: if( p->a==0 ){
! 4722: p->oom = 1;
! 4723: return;
! 4724: }
! 4725: if( nAddSig ){
! 4726: memmove(p->a+nAddSig, p->a, p->nDigit);
! 4727: memset(p->a, 0, nAddSig);
! 4728: p->nDigit += nAddSig;
! 4729: }
! 4730: if( nAddFrac ){
! 4731: memset(p->a+p->nDigit, 0, nAddFrac);
! 4732: p->nDigit += nAddFrac;
! 4733: p->nFrac += nAddFrac;
! 4734: }
! 4735: }
! 4736:
! 4737: /*
! 4738: ** Add the value pB into pA.
! 4739: **
! 4740: ** Both pA and pB might become denormalized by this routine.
! 4741: */
! 4742: static void decimal_add(Decimal *pA, Decimal *pB){
! 4743: int nSig, nFrac, nDigit;
! 4744: int i, rc;
! 4745: if( pA==0 ){
! 4746: return;
! 4747: }
! 4748: if( pA->oom || pB==0 || pB->oom ){
! 4749: pA->oom = 1;
! 4750: return;
! 4751: }
! 4752: if( pA->isNull || pB->isNull ){
! 4753: pA->isNull = 1;
! 4754: return;
! 4755: }
! 4756: nSig = pA->nDigit - pA->nFrac;
! 4757: if( nSig && pA->a[0]==0 ) nSig--;
! 4758: if( nSig<pB->nDigit-pB->nFrac ){
! 4759: nSig = pB->nDigit - pB->nFrac;
! 4760: }
! 4761: nFrac = pA->nFrac;
! 4762: if( nFrac<pB->nFrac ) nFrac = pB->nFrac;
! 4763: nDigit = nSig + nFrac + 1;
! 4764: decimal_expand(pA, nDigit, nFrac);
! 4765: decimal_expand(pB, nDigit, nFrac);
! 4766: if( pA->oom || pB->oom ){
! 4767: pA->oom = 1;
! 4768: }else{
! 4769: if( pA->sign==pB->sign ){
! 4770: int carry = 0;
! 4771: for(i=nDigit-1; i>=0; i--){
! 4772: int x = pA->a[i] + pB->a[i] + carry;
! 4773: if( x>=10 ){
! 4774: carry = 1;
! 4775: pA->a[i] = x - 10;
! 4776: }else{
! 4777: carry = 0;
! 4778: pA->a[i] = x;
! 4779: }
! 4780: }
! 4781: }else{
! 4782: signed char *aA, *aB;
! 4783: int borrow = 0;
! 4784: rc = memcmp(pA->a, pB->a, nDigit);
! 4785: if( rc<0 ){
! 4786: aA = pB->a;
! 4787: aB = pA->a;
! 4788: pA->sign = !pA->sign;
! 4789: }else{
! 4790: aA = pA->a;
! 4791: aB = pB->a;
! 4792: }
! 4793: for(i=nDigit-1; i>=0; i--){
! 4794: int x = aA[i] - aB[i] - borrow;
! 4795: if( x<0 ){
! 4796: pA->a[i] = x+10;
! 4797: borrow = 1;
! 4798: }else{
! 4799: pA->a[i] = x;
! 4800: borrow = 0;
! 4801: }
! 4802: }
! 4803: }
! 4804: }
! 4805: }
! 4806:
! 4807: /*
! 4808: ** Compare text in decimal order.
! 4809: */
! 4810: static int decimalCollFunc(
! 4811: void *notUsed,
! 4812: int nKey1, const void *pKey1,
! 4813: int nKey2, const void *pKey2
! 4814: ){
! 4815: const unsigned char *zA = (const unsigned char*)pKey1;
! 4816: const unsigned char *zB = (const unsigned char*)pKey2;
! 4817: Decimal *pA = decimal_new(0, 0, nKey1, zA);
! 4818: Decimal *pB = decimal_new(0, 0, nKey2, zB);
! 4819: int rc;
! 4820: UNUSED_PARAMETER(notUsed);
! 4821: if( pA==0 || pB==0 ){
! 4822: rc = 0;
! 4823: }else{
! 4824: rc = decimal_cmp(pA, pB);
! 4825: }
! 4826: decimal_free(pA);
! 4827: decimal_free(pB);
! 4828: return rc;
! 4829: }
! 4830:
! 4831:
! 4832: /*
! 4833: ** SQL Function: decimal_add(X, Y)
! 4834: ** decimal_sub(X, Y)
! 4835: **
! 4836: ** Return the sum or difference of X and Y.
! 4837: */
! 4838: static void decimalAddFunc(
! 4839: sqlite3_context *context,
! 4840: int argc,
! 4841: sqlite3_value **argv
! 4842: ){
! 4843: Decimal *pA = decimal_new(context, argv[0], 0, 0);
! 4844: Decimal *pB = decimal_new(context, argv[1], 0, 0);
! 4845: UNUSED_PARAMETER(argc);
! 4846: decimal_add(pA, pB);
! 4847: decimal_result(context, pA);
! 4848: decimal_free(pA);
! 4849: decimal_free(pB);
! 4850: }
! 4851: static void decimalSubFunc(
! 4852: sqlite3_context *context,
! 4853: int argc,
! 4854: sqlite3_value **argv
! 4855: ){
! 4856: Decimal *pA = decimal_new(context, argv[0], 0, 0);
! 4857: Decimal *pB = decimal_new(context, argv[1], 0, 0);
! 4858: UNUSED_PARAMETER(argc);
! 4859: if( pB==0 ) return;
! 4860: pB->sign = !pB->sign;
! 4861: decimal_add(pA, pB);
! 4862: decimal_result(context, pA);
! 4863: decimal_free(pA);
! 4864: decimal_free(pB);
! 4865: }
! 4866:
! 4867: /* Aggregate funcion: decimal_sum(X)
! 4868: **
! 4869: ** Works like sum() except that it uses decimal arithmetic for unlimited
! 4870: ** precision.
! 4871: */
! 4872: static void decimalSumStep(
! 4873: sqlite3_context *context,
! 4874: int argc,
! 4875: sqlite3_value **argv
! 4876: ){
! 4877: Decimal *p;
! 4878: Decimal *pArg;
! 4879: UNUSED_PARAMETER(argc);
! 4880: p = sqlite3_aggregate_context(context, sizeof(*p));
! 4881: if( p==0 ) return;
! 4882: if( !p->isInit ){
! 4883: p->isInit = 1;
! 4884: p->a = sqlite3_malloc(2);
! 4885: if( p->a==0 ){
! 4886: p->oom = 1;
! 4887: }else{
! 4888: p->a[0] = 0;
! 4889: }
! 4890: p->nDigit = 1;
! 4891: p->nFrac = 0;
! 4892: }
! 4893: if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
! 4894: pArg = decimal_new(context, argv[0], 0, 0);
! 4895: decimal_add(p, pArg);
! 4896: decimal_free(pArg);
! 4897: }
! 4898: static void decimalSumInverse(
! 4899: sqlite3_context *context,
! 4900: int argc,
! 4901: sqlite3_value **argv
! 4902: ){
! 4903: Decimal *p;
! 4904: Decimal *pArg;
! 4905: UNUSED_PARAMETER(argc);
! 4906: p = sqlite3_aggregate_context(context, sizeof(*p));
! 4907: if( p==0 ) return;
! 4908: if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
! 4909: pArg = decimal_new(context, argv[0], 0, 0);
! 4910: if( pArg ) pArg->sign = !pArg->sign;
! 4911: decimal_add(p, pArg);
! 4912: decimal_free(pArg);
! 4913: }
! 4914: static void decimalSumValue(sqlite3_context *context){
! 4915: Decimal *p = sqlite3_aggregate_context(context, 0);
! 4916: if( p==0 ) return;
! 4917: decimal_result(context, p);
! 4918: }
! 4919: static void decimalSumFinalize(sqlite3_context *context){
! 4920: Decimal *p = sqlite3_aggregate_context(context, 0);
! 4921: if( p==0 ) return;
! 4922: decimal_result(context, p);
! 4923: decimal_clear(p);
! 4924: }
! 4925:
! 4926: /*
! 4927: ** SQL Function: decimal_mul(X, Y)
! 4928: **
! 4929: ** Return the product of X and Y.
! 4930: **
! 4931: ** All significant digits after the decimal point are retained.
! 4932: ** Trailing zeros after the decimal point are omitted as long as
! 4933: ** the number of digits after the decimal point is no less than
! 4934: ** either the number of digits in either input.
! 4935: */
! 4936: static void decimalMulFunc(
! 4937: sqlite3_context *context,
! 4938: int argc,
! 4939: sqlite3_value **argv
! 4940: ){
! 4941: Decimal *pA = decimal_new(context, argv[0], 0, 0);
! 4942: Decimal *pB = decimal_new(context, argv[1], 0, 0);
! 4943: signed char *acc = 0;
! 4944: int i, j, k;
! 4945: int minFrac;
! 4946: UNUSED_PARAMETER(argc);
! 4947: if( pA==0 || pA->oom || pA->isNull
! 4948: || pB==0 || pB->oom || pB->isNull
! 4949: ){
! 4950: goto mul_end;
! 4951: }
! 4952: acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
! 4953: if( acc==0 ){
! 4954: sqlite3_result_error_nomem(context);
! 4955: goto mul_end;
! 4956: }
! 4957: memset(acc, 0, pA->nDigit + pB->nDigit + 2);
! 4958: minFrac = pA->nFrac;
! 4959: if( pB->nFrac<minFrac ) minFrac = pB->nFrac;
! 4960: for(i=pA->nDigit-1; i>=0; i--){
! 4961: signed char f = pA->a[i];
! 4962: int carry = 0, x;
! 4963: for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){
! 4964: x = acc[k] + f*pB->a[j] + carry;
! 4965: acc[k] = x%10;
! 4966: carry = x/10;
! 4967: }
! 4968: x = acc[k] + carry;
! 4969: acc[k] = x%10;
! 4970: acc[k-1] += x/10;
! 4971: }
! 4972: sqlite3_free(pA->a);
! 4973: pA->a = acc;
! 4974: acc = 0;
! 4975: pA->nDigit += pB->nDigit + 2;
! 4976: pA->nFrac += pB->nFrac;
! 4977: pA->sign ^= pB->sign;
! 4978: while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){
! 4979: pA->nFrac--;
! 4980: pA->nDigit--;
! 4981: }
! 4982: decimal_result(context, pA);
! 4983:
! 4984: mul_end:
! 4985: sqlite3_free(acc);
! 4986: decimal_free(pA);
! 4987: decimal_free(pB);
! 4988: }
! 4989:
! 4990: #ifdef _WIN32
! 4991:
! 4992: #endif
! 4993: int sqlite3_decimal_init(
! 4994: sqlite3 *db,
! 4995: char **pzErrMsg,
! 4996: const sqlite3_api_routines *pApi
! 4997: ){
! 4998: int rc = SQLITE_OK;
! 4999: static const struct {
! 5000: const char *zFuncName;
! 5001: int nArg;
! 5002: void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
! 5003: } aFunc[] = {
! 5004: { "decimal", 1, decimalFunc },
! 5005: { "decimal_cmp", 2, decimalCmpFunc },
! 5006: { "decimal_add", 2, decimalAddFunc },
! 5007: { "decimal_sub", 2, decimalSubFunc },
! 5008: { "decimal_mul", 2, decimalMulFunc },
! 5009: };
! 5010: unsigned int i;
! 5011: (void)pzErrMsg; /* Unused parameter */
! 5012:
! 5013: SQLITE_EXTENSION_INIT2(pApi);
! 5014:
! 5015: for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
! 5016: rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg,
! 5017: SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
! 5018: 0, aFunc[i].xFunc, 0, 0);
! 5019: }
! 5020: if( rc==SQLITE_OK ){
! 5021: rc = sqlite3_create_window_function(db, "decimal_sum", 1,
! 5022: SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0,
! 5023: decimalSumStep, decimalSumFinalize,
! 5024: decimalSumValue, decimalSumInverse, 0);
! 5025: }
! 5026: if( rc==SQLITE_OK ){
! 5027: rc = sqlite3_create_collation(db, "decimal", SQLITE_UTF8,
! 5028: 0, decimalCollFunc);
! 5029: }
! 5030: return rc;
! 5031: }
! 5032:
! 5033: /************************* End ../ext/misc/decimal.c ********************/
! 5034: /************************* Begin ../ext/misc/ieee754.c ******************/
! 5035: /*
! 5036: ** 2013-04-17
! 5037: **
! 5038: ** The author disclaims copyright to this source code. In place of
! 5039: ** a legal notice, here is a blessing:
! 5040: **
! 5041: ** May you do good and not evil.
! 5042: ** May you find forgiveness for yourself and forgive others.
! 5043: ** May you share freely, never taking more than you give.
! 5044: **
! 5045: ******************************************************************************
! 5046: **
! 5047: ** This SQLite extension implements functions for the exact display
! 5048: ** and input of IEEE754 Binary64 floating-point numbers.
! 5049: **
! 5050: ** ieee754(X)
! 5051: ** ieee754(Y,Z)
! 5052: **
! 5053: ** In the first form, the value X should be a floating-point number.
! 5054: ** The function will return a string of the form 'ieee754(Y,Z)' where
! 5055: ** Y and Z are integers such that X==Y*pow(2,Z).
! 5056: **
! 5057: ** In the second form, Y and Z are integers which are the mantissa and
! 5058: ** base-2 exponent of a new floating point number. The function returns
! 5059: ** a floating-point value equal to Y*pow(2,Z).
! 5060: **
! 5061: ** Examples:
! 5062: **
! 5063: ** ieee754(2.0) -> 'ieee754(2,0)'
! 5064: ** ieee754(45.25) -> 'ieee754(181,-2)'
! 5065: ** ieee754(2, 0) -> 2.0
! 5066: ** ieee754(181, -2) -> 45.25
! 5067: **
! 5068: ** Two additional functions break apart the one-argument ieee754()
! 5069: ** result into separate integer values:
! 5070: **
! 5071: ** ieee754_mantissa(45.25) -> 181
! 5072: ** ieee754_exponent(45.25) -> -2
! 5073: **
! 5074: ** These functions convert binary64 numbers into blobs and back again.
! 5075: **
! 5076: ** ieee754_from_blob(x'3ff0000000000000') -> 1.0
! 5077: ** ieee754_to_blob(1.0) -> x'3ff0000000000000'
! 5078: **
! 5079: ** In all single-argument functions, if the argument is an 8-byte blob
! 5080: ** then that blob is interpreted as a big-endian binary64 value.
! 5081: **
! 5082: **
! 5083: ** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES
! 5084: ** -----------------------------------------------
! 5085: **
! 5086: ** This extension in combination with the separate 'decimal' extension
! 5087: ** can be used to compute the exact decimal representation of binary64
! 5088: ** values. To begin, first compute a table of exponent values:
! 5089: **
! 5090: ** CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
! 5091: ** WITH RECURSIVE c(x,v) AS (
! 5092: ** VALUES(0,'1')
! 5093: ** UNION ALL
! 5094: ** SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971
! 5095: ** ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
! 5096: ** WITH RECURSIVE c(x,v) AS (
! 5097: ** VALUES(-1,'0.5')
! 5098: ** UNION ALL
! 5099: ** SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075
! 5100: ** ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
! 5101: **
! 5102: ** Then, to compute the exact decimal representation of a floating
! 5103: ** point value (the value 47.49 is used in the example) do:
! 5104: **
! 5105: ** WITH c(n) AS (VALUES(47.49))
! 5106: ** ---------------^^^^^---- Replace with whatever you want
! 5107: ** SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
! 5108: ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
! 5109: **
! 5110: ** Here is a query to show various boundry values for the binary64
! 5111: ** number format:
! 5112: **
! 5113: ** WITH c(name,bin) AS (VALUES
! 5114: ** ('minimum positive value', x'0000000000000001'),
! 5115: ** ('maximum subnormal value', x'000fffffffffffff'),
! 5116: ** ('mininum positive nornal value', x'0010000000000000'),
! 5117: ** ('maximum value', x'7fefffffffffffff'))
! 5118: ** SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
! 5119: ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
! 5120: **
! 5121: */
! 5122: /* #include "sqlite3ext.h" */
! 5123: SQLITE_EXTENSION_INIT1
! 5124: #include <assert.h>
! 5125: #include <string.h>
! 5126:
! 5127: /* Mark a function parameter as unused, to suppress nuisance compiler
! 5128: ** warnings. */
! 5129: #ifndef UNUSED_PARAMETER
! 5130: # define UNUSED_PARAMETER(X) (void)(X)
! 5131: #endif
! 5132:
! 5133: /*
! 5134: ** Implementation of the ieee754() function
! 5135: */
! 5136: static void ieee754func(
! 5137: sqlite3_context *context,
! 5138: int argc,
! 5139: sqlite3_value **argv
! 5140: ){
! 5141: if( argc==1 ){
! 5142: sqlite3_int64 m, a;
! 5143: double r;
! 5144: int e;
! 5145: int isNeg;
! 5146: char zResult[100];
! 5147: assert( sizeof(m)==sizeof(r) );
! 5148: if( sqlite3_value_type(argv[0])==SQLITE_BLOB
! 5149: && sqlite3_value_bytes(argv[0])==sizeof(r)
! 5150: ){
! 5151: const unsigned char *x = sqlite3_value_blob(argv[0]);
! 5152: unsigned int i;
! 5153: sqlite3_uint64 v = 0;
! 5154: for(i=0; i<sizeof(r); i++){
! 5155: v = (v<<8) | x[i];
! 5156: }
! 5157: memcpy(&r, &v, sizeof(r));
! 5158: }else{
! 5159: r = sqlite3_value_double(argv[0]);
! 5160: }
! 5161: if( r<0.0 ){
! 5162: isNeg = 1;
! 5163: r = -r;
! 5164: }else{
! 5165: isNeg = 0;
! 5166: }
! 5167: memcpy(&a,&r,sizeof(a));
! 5168: if( a==0 ){
! 5169: e = 0;
! 5170: m = 0;
! 5171: }else{
! 5172: e = a>>52;
! 5173: m = a & ((((sqlite3_int64)1)<<52)-1);
! 5174: if( e==0 ){
! 5175: m <<= 1;
! 5176: }else{
! 5177: m |= ((sqlite3_int64)1)<<52;
! 5178: }
! 5179: while( e<1075 && m>0 && (m&1)==0 ){
! 5180: m >>= 1;
! 5181: e++;
! 5182: }
! 5183: if( isNeg ) m = -m;
! 5184: }
! 5185: switch( *(int*)sqlite3_user_data(context) ){
! 5186: case 0:
! 5187: sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)",
! 5188: m, e-1075);
! 5189: sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT);
! 5190: break;
! 5191: case 1:
! 5192: sqlite3_result_int64(context, m);
! 5193: break;
! 5194: case 2:
! 5195: sqlite3_result_int(context, e-1075);
! 5196: break;
! 5197: }
! 5198: }else{
! 5199: sqlite3_int64 m, e, a;
! 5200: double r;
! 5201: int isNeg = 0;
! 5202: m = sqlite3_value_int64(argv[0]);
! 5203: e = sqlite3_value_int64(argv[1]);
! 5204: if( m<0 ){
! 5205: isNeg = 1;
! 5206: m = -m;
! 5207: if( m<0 ) return;
! 5208: }else if( m==0 && e>-1000 && e<1000 ){
! 5209: sqlite3_result_double(context, 0.0);
! 5210: return;
! 5211: }
! 5212: while( (m>>32)&0xffe00000 ){
! 5213: m >>= 1;
! 5214: e++;
! 5215: }
! 5216: while( m!=0 && ((m>>32)&0xfff00000)==0 ){
! 5217: m <<= 1;
! 5218: e--;
! 5219: }
! 5220: e += 1075;
! 5221: if( e<=0 ){
! 5222: /* Subnormal */
! 5223: m >>= 1-e;
! 5224: e = 0;
! 5225: }else if( e>0x7ff ){
! 5226: e = 0x7ff;
! 5227: }
! 5228: a = m & ((((sqlite3_int64)1)<<52)-1);
! 5229: a |= e<<52;
! 5230: if( isNeg ) a |= ((sqlite3_uint64)1)<<63;
! 5231: memcpy(&r, &a, sizeof(r));
! 5232: sqlite3_result_double(context, r);
1.4.2.2 misho 5233: }
5234: }
1.4.2.3 ! misho 5235:
! 5236: /*
! 5237: ** Functions to convert between blobs and floats.
! 5238: */
! 5239: static void ieee754func_from_blob(
! 5240: sqlite3_context *context,
! 5241: int argc,
! 5242: sqlite3_value **argv
! 5243: ){
! 5244: UNUSED_PARAMETER(argc);
! 5245: if( sqlite3_value_type(argv[0])==SQLITE_BLOB
! 5246: && sqlite3_value_bytes(argv[0])==sizeof(double)
! 5247: ){
! 5248: double r;
! 5249: const unsigned char *x = sqlite3_value_blob(argv[0]);
! 5250: unsigned int i;
! 5251: sqlite3_uint64 v = 0;
! 5252: for(i=0; i<sizeof(r); i++){
! 5253: v = (v<<8) | x[i];
! 5254: }
! 5255: memcpy(&r, &v, sizeof(r));
! 5256: sqlite3_result_double(context, r);
1.4.2.2 misho 5257: }
5258: }
1.4.2.3 ! misho 5259: static void ieee754func_to_blob(
! 5260: sqlite3_context *context,
! 5261: int argc,
! 5262: sqlite3_value **argv
! 5263: ){
! 5264: UNUSED_PARAMETER(argc);
! 5265: if( sqlite3_value_type(argv[0])==SQLITE_FLOAT
! 5266: || sqlite3_value_type(argv[0])==SQLITE_INTEGER
! 5267: ){
! 5268: double r = sqlite3_value_double(argv[0]);
! 5269: sqlite3_uint64 v;
! 5270: unsigned char a[sizeof(r)];
! 5271: unsigned int i;
! 5272: memcpy(&v, &r, sizeof(r));
! 5273: for(i=1; i<=sizeof(r); i++){
! 5274: a[sizeof(r)-i] = v&0xff;
! 5275: v >>= 8;
! 5276: }
! 5277: sqlite3_result_blob(context, a, sizeof(r), SQLITE_TRANSIENT);
1.4.2.2 misho 5278: }
5279: }
5280:
5281:
1.4.2.3 ! misho 5282: #ifdef _WIN32
1.4.2.2 misho 5283:
1.4.2.3 ! misho 5284: #endif
! 5285: int sqlite3_ieee_init(
! 5286: sqlite3 *db,
! 5287: char **pzErrMsg,
! 5288: const sqlite3_api_routines *pApi
! 5289: ){
! 5290: static const struct {
! 5291: char *zFName;
! 5292: int nArg;
! 5293: int iAux;
! 5294: void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
! 5295: } aFunc[] = {
! 5296: { "ieee754", 1, 0, ieee754func },
! 5297: { "ieee754", 2, 0, ieee754func },
! 5298: { "ieee754_mantissa", 1, 1, ieee754func },
! 5299: { "ieee754_exponent", 1, 2, ieee754func },
! 5300: { "ieee754_to_blob", 1, 0, ieee754func_to_blob },
! 5301: { "ieee754_from_blob", 1, 0, ieee754func_from_blob },
! 5302:
! 5303: };
! 5304: unsigned int i;
1.4.2.2 misho 5305: int rc = SQLITE_OK;
1.4.2.3 ! misho 5306: SQLITE_EXTENSION_INIT2(pApi);
! 5307: (void)pzErrMsg; /* Unused parameter */
! 5308: for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
! 5309: rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
! 5310: SQLITE_UTF8|SQLITE_INNOCUOUS,
! 5311: (void*)&aFunc[i].iAux,
! 5312: aFunc[i].xFunc, 0, 0);
1.4.2.2 misho 5313: }
5314: return rc;
5315: }
5316:
1.4.2.3 ! misho 5317: /************************* End ../ext/misc/ieee754.c ********************/
1.4.2.2 misho 5318: #ifdef SQLITE_HAVE_ZLIB
5319: /************************* Begin ../ext/misc/zipfile.c ******************/
5320: /*
5321: ** 2017-12-26
5322: **
5323: ** The author disclaims copyright to this source code. In place of
5324: ** a legal notice, here is a blessing:
5325: **
5326: ** May you do good and not evil.
5327: ** May you find forgiveness for yourself and forgive others.
5328: ** May you share freely, never taking more than you give.
5329: **
5330: ******************************************************************************
5331: **
5332: ** This file implements a virtual table for reading and writing ZIP archive
5333: ** files.
5334: **
5335: ** Usage example:
5336: **
5337: ** SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename);
5338: **
5339: ** Current limitations:
5340: **
5341: ** * No support for encryption
5342: ** * No support for ZIP archives spanning multiple files
5343: ** * No support for zip64 extensions
5344: ** * Only the "inflate/deflate" (zlib) compression method is supported
5345: */
5346: /* #include "sqlite3ext.h" */
5347: SQLITE_EXTENSION_INIT1
5348: #include <stdio.h>
5349: #include <string.h>
5350: #include <assert.h>
5351:
5352: #include <zlib.h>
5353:
5354: #ifndef SQLITE_OMIT_VIRTUALTABLE
5355:
5356: #ifndef SQLITE_AMALGAMATION
5357:
5358: /* typedef sqlite3_int64 i64; */
5359: /* typedef unsigned char u8; */
5360: typedef unsigned short u16;
5361: typedef unsigned long u32;
5362: #define MIN(a,b) ((a)<(b) ? (a) : (b))
5363:
5364: #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
5365: # define ALWAYS(X) (1)
5366: # define NEVER(X) (0)
5367: #elif !defined(NDEBUG)
5368: # define ALWAYS(X) ((X)?1:(assert(0),0))
5369: # define NEVER(X) ((X)?(assert(0),1):0)
5370: #else
5371: # define ALWAYS(X) (X)
5372: # define NEVER(X) (X)
5373: #endif
5374:
5375: #endif /* SQLITE_AMALGAMATION */
5376:
5377: /*
5378: ** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK.
5379: **
5380: ** In some ways it would be better to obtain these values from system
5381: ** header files. But, the dependency is undesirable and (a) these
5382: ** have been stable for decades, (b) the values are part of POSIX and
5383: ** are also made explicit in [man stat], and (c) are part of the
5384: ** file format for zip archives.
5385: */
5386: #ifndef S_IFDIR
5387: # define S_IFDIR 0040000
5388: #endif
5389: #ifndef S_IFREG
5390: # define S_IFREG 0100000
5391: #endif
5392: #ifndef S_IFLNK
5393: # define S_IFLNK 0120000
5394: #endif
5395:
5396: static const char ZIPFILE_SCHEMA[] =
5397: "CREATE TABLE y("
5398: "name PRIMARY KEY," /* 0: Name of file in zip archive */
5399: "mode," /* 1: POSIX mode for file */
5400: "mtime," /* 2: Last modification time (secs since 1970)*/
5401: "sz," /* 3: Size of object */
5402: "rawdata," /* 4: Raw data */
5403: "data," /* 5: Uncompressed data */
5404: "method," /* 6: Compression method (integer) */
5405: "z HIDDEN" /* 7: Name of zip file */
5406: ") WITHOUT ROWID;";
5407:
5408: #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
5409: #define ZIPFILE_BUFFER_SIZE (64*1024)
5410:
5411:
5412: /*
5413: ** Magic numbers used to read and write zip files.
5414: **
5415: ** ZIPFILE_NEWENTRY_MADEBY:
5416: ** Use this value for the "version-made-by" field in new zip file
5417: ** entries. The upper byte indicates "unix", and the lower byte
5418: ** indicates that the zip file matches pkzip specification 3.0.
5419: ** This is what info-zip seems to do.
5420: **
5421: ** ZIPFILE_NEWENTRY_REQUIRED:
5422: ** Value for "version-required-to-extract" field of new entries.
5423: ** Version 2.0 is required to support folders and deflate compression.
5424: **
5425: ** ZIPFILE_NEWENTRY_FLAGS:
5426: ** Value for "general-purpose-bit-flags" field of new entries. Bit
5427: ** 11 means "utf-8 filename and comment".
5428: **
5429: ** ZIPFILE_SIGNATURE_CDS:
5430: ** First 4 bytes of a valid CDS record.
5431: **
5432: ** ZIPFILE_SIGNATURE_LFH:
5433: ** First 4 bytes of a valid LFH record.
5434: **
5435: ** ZIPFILE_SIGNATURE_EOCD
5436: ** First 4 bytes of a valid EOCD record.
5437: */
5438: #define ZIPFILE_EXTRA_TIMESTAMP 0x5455
5439: #define ZIPFILE_NEWENTRY_MADEBY ((3<<8) + 30)
5440: #define ZIPFILE_NEWENTRY_REQUIRED 20
5441: #define ZIPFILE_NEWENTRY_FLAGS 0x800
5442: #define ZIPFILE_SIGNATURE_CDS 0x02014b50
5443: #define ZIPFILE_SIGNATURE_LFH 0x04034b50
5444: #define ZIPFILE_SIGNATURE_EOCD 0x06054b50
5445:
5446: /*
5447: ** The sizes of the fixed-size part of each of the three main data
5448: ** structures in a zip archive.
5449: */
5450: #define ZIPFILE_LFH_FIXED_SZ 30
5451: #define ZIPFILE_EOCD_FIXED_SZ 22
5452: #define ZIPFILE_CDS_FIXED_SZ 46
5453:
5454: /*
5455: *** 4.3.16 End of central directory record:
5456: ***
5457: *** end of central dir signature 4 bytes (0x06054b50)
5458: *** number of this disk 2 bytes
5459: *** number of the disk with the
5460: *** start of the central directory 2 bytes
5461: *** total number of entries in the
5462: *** central directory on this disk 2 bytes
5463: *** total number of entries in
5464: *** the central directory 2 bytes
5465: *** size of the central directory 4 bytes
5466: *** offset of start of central
5467: *** directory with respect to
5468: *** the starting disk number 4 bytes
5469: *** .ZIP file comment length 2 bytes
5470: *** .ZIP file comment (variable size)
5471: */
5472: typedef struct ZipfileEOCD ZipfileEOCD;
5473: struct ZipfileEOCD {
5474: u16 iDisk;
5475: u16 iFirstDisk;
5476: u16 nEntry;
5477: u16 nEntryTotal;
5478: u32 nSize;
5479: u32 iOffset;
5480: };
5481:
5482: /*
5483: *** 4.3.12 Central directory structure:
5484: ***
5485: *** ...
5486: ***
5487: *** central file header signature 4 bytes (0x02014b50)
5488: *** version made by 2 bytes
5489: *** version needed to extract 2 bytes
5490: *** general purpose bit flag 2 bytes
5491: *** compression method 2 bytes
5492: *** last mod file time 2 bytes
5493: *** last mod file date 2 bytes
5494: *** crc-32 4 bytes
5495: *** compressed size 4 bytes
5496: *** uncompressed size 4 bytes
5497: *** file name length 2 bytes
5498: *** extra field length 2 bytes
5499: *** file comment length 2 bytes
5500: *** disk number start 2 bytes
5501: *** internal file attributes 2 bytes
5502: *** external file attributes 4 bytes
5503: *** relative offset of local header 4 bytes
5504: */
5505: typedef struct ZipfileCDS ZipfileCDS;
5506: struct ZipfileCDS {
5507: u16 iVersionMadeBy;
5508: u16 iVersionExtract;
5509: u16 flags;
5510: u16 iCompression;
5511: u16 mTime;
5512: u16 mDate;
5513: u32 crc32;
5514: u32 szCompressed;
5515: u32 szUncompressed;
5516: u16 nFile;
5517: u16 nExtra;
5518: u16 nComment;
5519: u16 iDiskStart;
5520: u16 iInternalAttr;
5521: u32 iExternalAttr;
5522: u32 iOffset;
5523: char *zFile; /* Filename (sqlite3_malloc()) */
5524: };
5525:
5526: /*
5527: *** 4.3.7 Local file header:
5528: ***
5529: *** local file header signature 4 bytes (0x04034b50)
5530: *** version needed to extract 2 bytes
5531: *** general purpose bit flag 2 bytes
5532: *** compression method 2 bytes
5533: *** last mod file time 2 bytes
5534: *** last mod file date 2 bytes
5535: *** crc-32 4 bytes
5536: *** compressed size 4 bytes
5537: *** uncompressed size 4 bytes
5538: *** file name length 2 bytes
5539: *** extra field length 2 bytes
5540: ***
5541: */
5542: typedef struct ZipfileLFH ZipfileLFH;
5543: struct ZipfileLFH {
5544: u16 iVersionExtract;
5545: u16 flags;
5546: u16 iCompression;
5547: u16 mTime;
5548: u16 mDate;
5549: u32 crc32;
5550: u32 szCompressed;
5551: u32 szUncompressed;
5552: u16 nFile;
5553: u16 nExtra;
5554: };
5555:
5556: typedef struct ZipfileEntry ZipfileEntry;
5557: struct ZipfileEntry {
5558: ZipfileCDS cds; /* Parsed CDS record */
5559: u32 mUnixTime; /* Modification time, in UNIX format */
5560: u8 *aExtra; /* cds.nExtra+cds.nComment bytes of extra data */
5561: i64 iDataOff; /* Offset to data in file (if aData==0) */
5562: u8 *aData; /* cds.szCompressed bytes of compressed data */
5563: ZipfileEntry *pNext; /* Next element in in-memory CDS */
5564: };
5565:
5566: /*
5567: ** Cursor type for zipfile tables.
5568: */
5569: typedef struct ZipfileCsr ZipfileCsr;
5570: struct ZipfileCsr {
5571: sqlite3_vtab_cursor base; /* Base class - must be first */
5572: i64 iId; /* Cursor ID */
5573: u8 bEof; /* True when at EOF */
5574: u8 bNoop; /* If next xNext() call is no-op */
5575:
5576: /* Used outside of write transactions */
5577: FILE *pFile; /* Zip file */
5578: i64 iNextOff; /* Offset of next record in central directory */
5579: ZipfileEOCD eocd; /* Parse of central directory record */
5580:
5581: ZipfileEntry *pFreeEntry; /* Free this list when cursor is closed or reset */
5582: ZipfileEntry *pCurrent; /* Current entry */
5583: ZipfileCsr *pCsrNext; /* Next cursor on same virtual table */
5584: };
5585:
5586: typedef struct ZipfileTab ZipfileTab;
5587: struct ZipfileTab {
5588: sqlite3_vtab base; /* Base class - must be first */
5589: char *zFile; /* Zip file this table accesses (may be NULL) */
5590: sqlite3 *db; /* Host database connection */
5591: u8 *aBuffer; /* Temporary buffer used for various tasks */
5592:
5593: ZipfileCsr *pCsrList; /* List of cursors */
5594: i64 iNextCsrid;
5595:
5596: /* The following are used by write transactions only */
5597: ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */
5598: ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */
5599: FILE *pWriteFd; /* File handle open on zip archive */
5600: i64 szCurrent; /* Current size of zip archive */
5601: i64 szOrig; /* Size of archive at start of transaction */
5602: };
5603:
5604: /*
5605: ** Set the error message contained in context ctx to the results of
5606: ** vprintf(zFmt, ...).
5607: */
5608: static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
5609: char *zMsg = 0;
5610: va_list ap;
5611: va_start(ap, zFmt);
5612: zMsg = sqlite3_vmprintf(zFmt, ap);
5613: sqlite3_result_error(ctx, zMsg, -1);
5614: sqlite3_free(zMsg);
5615: va_end(ap);
5616: }
5617:
5618: /*
5619: ** If string zIn is quoted, dequote it in place. Otherwise, if the string
5620: ** is not quoted, do nothing.
5621: */
5622: static void zipfileDequote(char *zIn){
5623: char q = zIn[0];
5624: if( q=='"' || q=='\'' || q=='`' || q=='[' ){
5625: int iIn = 1;
5626: int iOut = 0;
5627: if( q=='[' ) q = ']';
5628: while( ALWAYS(zIn[iIn]) ){
5629: char c = zIn[iIn++];
5630: if( c==q && zIn[iIn++]!=q ) break;
5631: zIn[iOut++] = c;
5632: }
5633: zIn[iOut] = '\0';
5634: }
5635: }
5636:
5637: /*
5638: ** Construct a new ZipfileTab virtual table object.
5639: **
5640: ** argv[0] -> module name ("zipfile")
5641: ** argv[1] -> database name
5642: ** argv[2] -> table name
5643: ** argv[...] -> "column name" and other module argument fields.
5644: */
5645: static int zipfileConnect(
5646: sqlite3 *db,
5647: void *pAux,
5648: int argc, const char *const*argv,
5649: sqlite3_vtab **ppVtab,
5650: char **pzErr
5651: ){
5652: int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE;
5653: int nFile = 0;
5654: const char *zFile = 0;
5655: ZipfileTab *pNew = 0;
5656: int rc;
5657:
5658: /* If the table name is not "zipfile", require that the argument be
5659: ** specified. This stops zipfile tables from being created as:
5660: **
5661: ** CREATE VIRTUAL TABLE zzz USING zipfile();
5662: **
5663: ** It does not prevent:
5664: **
5665: ** CREATE VIRTUAL TABLE zipfile USING zipfile();
5666: */
5667: assert( 0==sqlite3_stricmp(argv[0], "zipfile") );
5668: if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){
5669: *pzErr = sqlite3_mprintf("zipfile constructor requires one argument");
5670: return SQLITE_ERROR;
5671: }
5672:
5673: if( argc>3 ){
5674: zFile = argv[3];
5675: nFile = (int)strlen(zFile)+1;
5676: }
5677:
5678: rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
5679: if( rc==SQLITE_OK ){
5680: pNew = (ZipfileTab*)sqlite3_malloc64((sqlite3_int64)nByte+nFile);
5681: if( pNew==0 ) return SQLITE_NOMEM;
5682: memset(pNew, 0, nByte+nFile);
5683: pNew->db = db;
5684: pNew->aBuffer = (u8*)&pNew[1];
5685: if( zFile ){
5686: pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
5687: memcpy(pNew->zFile, zFile, nFile);
5688: zipfileDequote(pNew->zFile);
5689: }
5690: }
1.4.2.3 ! misho 5691: sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
1.4.2.2 misho 5692: *ppVtab = (sqlite3_vtab*)pNew;
5693: return rc;
5694: }
5695:
5696: /*
5697: ** Free the ZipfileEntry structure indicated by the only argument.
5698: */
5699: static void zipfileEntryFree(ZipfileEntry *p){
5700: if( p ){
5701: sqlite3_free(p->cds.zFile);
5702: sqlite3_free(p);
5703: }
5704: }
5705:
5706: /*
5707: ** Release resources that should be freed at the end of a write
5708: ** transaction.
5709: */
5710: static void zipfileCleanupTransaction(ZipfileTab *pTab){
5711: ZipfileEntry *pEntry;
5712: ZipfileEntry *pNext;
5713:
5714: if( pTab->pWriteFd ){
5715: fclose(pTab->pWriteFd);
5716: pTab->pWriteFd = 0;
5717: }
5718: for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){
5719: pNext = pEntry->pNext;
5720: zipfileEntryFree(pEntry);
5721: }
5722: pTab->pFirstEntry = 0;
5723: pTab->pLastEntry = 0;
5724: pTab->szCurrent = 0;
5725: pTab->szOrig = 0;
5726: }
5727:
5728: /*
5729: ** This method is the destructor for zipfile vtab objects.
5730: */
5731: static int zipfileDisconnect(sqlite3_vtab *pVtab){
5732: zipfileCleanupTransaction((ZipfileTab*)pVtab);
5733: sqlite3_free(pVtab);
5734: return SQLITE_OK;
5735: }
5736:
5737: /*
5738: ** Constructor for a new ZipfileCsr object.
5739: */
5740: static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
5741: ZipfileTab *pTab = (ZipfileTab*)p;
5742: ZipfileCsr *pCsr;
5743: pCsr = sqlite3_malloc(sizeof(*pCsr));
5744: *ppCsr = (sqlite3_vtab_cursor*)pCsr;
5745: if( pCsr==0 ){
5746: return SQLITE_NOMEM;
5747: }
5748: memset(pCsr, 0, sizeof(*pCsr));
5749: pCsr->iId = ++pTab->iNextCsrid;
5750: pCsr->pCsrNext = pTab->pCsrList;
5751: pTab->pCsrList = pCsr;
5752: return SQLITE_OK;
5753: }
5754:
5755: /*
5756: ** Reset a cursor back to the state it was in when first returned
5757: ** by zipfileOpen().
5758: */
5759: static void zipfileResetCursor(ZipfileCsr *pCsr){
5760: ZipfileEntry *p;
5761: ZipfileEntry *pNext;
5762:
5763: pCsr->bEof = 0;
5764: if( pCsr->pFile ){
5765: fclose(pCsr->pFile);
5766: pCsr->pFile = 0;
5767: zipfileEntryFree(pCsr->pCurrent);
5768: pCsr->pCurrent = 0;
5769: }
5770:
5771: for(p=pCsr->pFreeEntry; p; p=pNext){
5772: pNext = p->pNext;
5773: zipfileEntryFree(p);
5774: }
5775: }
5776:
5777: /*
5778: ** Destructor for an ZipfileCsr.
5779: */
5780: static int zipfileClose(sqlite3_vtab_cursor *cur){
5781: ZipfileCsr *pCsr = (ZipfileCsr*)cur;
5782: ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
5783: ZipfileCsr **pp;
5784: zipfileResetCursor(pCsr);
5785:
5786: /* Remove this cursor from the ZipfileTab.pCsrList list. */
5787: for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext));
5788: *pp = pCsr->pCsrNext;
5789:
5790: sqlite3_free(pCsr);
5791: return SQLITE_OK;
5792: }
5793:
5794: /*
5795: ** Set the error message for the virtual table associated with cursor
5796: ** pCsr to the results of vprintf(zFmt, ...).
5797: */
5798: static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){
5799: va_list ap;
5800: va_start(ap, zFmt);
5801: sqlite3_free(pTab->base.zErrMsg);
5802: pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap);
5803: va_end(ap);
5804: }
5805: static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){
5806: va_list ap;
5807: va_start(ap, zFmt);
5808: sqlite3_free(pCsr->base.pVtab->zErrMsg);
5809: pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
5810: va_end(ap);
5811: }
5812:
5813: /*
5814: ** Read nRead bytes of data from offset iOff of file pFile into buffer
5815: ** aRead[]. Return SQLITE_OK if successful, or an SQLite error code
5816: ** otherwise.
5817: **
5818: ** If an error does occur, output variable (*pzErrmsg) may be set to point
5819: ** to an English language error message. It is the responsibility of the
5820: ** caller to eventually free this buffer using
5821: ** sqlite3_free().
5822: */
5823: static int zipfileReadData(
5824: FILE *pFile, /* Read from this file */
5825: u8 *aRead, /* Read into this buffer */
5826: int nRead, /* Number of bytes to read */
5827: i64 iOff, /* Offset to read from */
5828: char **pzErrmsg /* OUT: Error message (from sqlite3_malloc) */
5829: ){
5830: size_t n;
5831: fseek(pFile, (long)iOff, SEEK_SET);
5832: n = fread(aRead, 1, nRead, pFile);
5833: if( (int)n!=nRead ){
5834: *pzErrmsg = sqlite3_mprintf("error in fread()");
5835: return SQLITE_ERROR;
5836: }
5837: return SQLITE_OK;
5838: }
5839:
5840: static int zipfileAppendData(
5841: ZipfileTab *pTab,
5842: const u8 *aWrite,
5843: int nWrite
5844: ){
5845: size_t n;
5846: fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
5847: n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
5848: if( (int)n!=nWrite ){
5849: pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
5850: return SQLITE_ERROR;
5851: }
5852: pTab->szCurrent += nWrite;
5853: return SQLITE_OK;
5854: }
5855:
5856: /*
5857: ** Read and return a 16-bit little-endian unsigned integer from buffer aBuf.
5858: */
5859: static u16 zipfileGetU16(const u8 *aBuf){
5860: return (aBuf[1] << 8) + aBuf[0];
5861: }
5862:
5863: /*
5864: ** Read and return a 32-bit little-endian unsigned integer from buffer aBuf.
5865: */
5866: static u32 zipfileGetU32(const u8 *aBuf){
5867: return ((u32)(aBuf[3]) << 24)
5868: + ((u32)(aBuf[2]) << 16)
5869: + ((u32)(aBuf[1]) << 8)
5870: + ((u32)(aBuf[0]) << 0);
5871: }
5872:
5873: /*
5874: ** Write a 16-bit little endiate integer into buffer aBuf.
5875: */
5876: static void zipfilePutU16(u8 *aBuf, u16 val){
5877: aBuf[0] = val & 0xFF;
5878: aBuf[1] = (val>>8) & 0xFF;
5879: }
5880:
5881: /*
5882: ** Write a 32-bit little endiate integer into buffer aBuf.
5883: */
5884: static void zipfilePutU32(u8 *aBuf, u32 val){
5885: aBuf[0] = val & 0xFF;
5886: aBuf[1] = (val>>8) & 0xFF;
5887: aBuf[2] = (val>>16) & 0xFF;
5888: aBuf[3] = (val>>24) & 0xFF;
5889: }
5890:
5891: #define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) )
5892: #define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) )
5893:
5894: #define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; }
5895: #define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; }
5896:
5897: /*
5898: ** Magic numbers used to read CDS records.
5899: */
5900: #define ZIPFILE_CDS_NFILE_OFF 28
5901: #define ZIPFILE_CDS_SZCOMPRESSED_OFF 20
5902:
5903: /*
5904: ** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR
5905: ** if the record is not well-formed, or SQLITE_OK otherwise.
5906: */
5907: static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){
5908: u8 *aRead = aBuf;
5909: u32 sig = zipfileRead32(aRead);
5910: int rc = SQLITE_OK;
5911: if( sig!=ZIPFILE_SIGNATURE_CDS ){
5912: rc = SQLITE_ERROR;
5913: }else{
5914: pCDS->iVersionMadeBy = zipfileRead16(aRead);
5915: pCDS->iVersionExtract = zipfileRead16(aRead);
5916: pCDS->flags = zipfileRead16(aRead);
5917: pCDS->iCompression = zipfileRead16(aRead);
5918: pCDS->mTime = zipfileRead16(aRead);
5919: pCDS->mDate = zipfileRead16(aRead);
5920: pCDS->crc32 = zipfileRead32(aRead);
5921: pCDS->szCompressed = zipfileRead32(aRead);
5922: pCDS->szUncompressed = zipfileRead32(aRead);
5923: assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
5924: pCDS->nFile = zipfileRead16(aRead);
5925: pCDS->nExtra = zipfileRead16(aRead);
5926: pCDS->nComment = zipfileRead16(aRead);
5927: pCDS->iDiskStart = zipfileRead16(aRead);
5928: pCDS->iInternalAttr = zipfileRead16(aRead);
5929: pCDS->iExternalAttr = zipfileRead32(aRead);
5930: pCDS->iOffset = zipfileRead32(aRead);
5931: assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] );
5932: }
5933:
5934: return rc;
5935: }
5936:
5937: /*
5938: ** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR
5939: ** if the record is not well-formed, or SQLITE_OK otherwise.
5940: */
5941: static int zipfileReadLFH(
5942: u8 *aBuffer,
5943: ZipfileLFH *pLFH
5944: ){
5945: u8 *aRead = aBuffer;
5946: int rc = SQLITE_OK;
5947:
5948: u32 sig = zipfileRead32(aRead);
5949: if( sig!=ZIPFILE_SIGNATURE_LFH ){
5950: rc = SQLITE_ERROR;
5951: }else{
5952: pLFH->iVersionExtract = zipfileRead16(aRead);
5953: pLFH->flags = zipfileRead16(aRead);
5954: pLFH->iCompression = zipfileRead16(aRead);
5955: pLFH->mTime = zipfileRead16(aRead);
5956: pLFH->mDate = zipfileRead16(aRead);
5957: pLFH->crc32 = zipfileRead32(aRead);
5958: pLFH->szCompressed = zipfileRead32(aRead);
5959: pLFH->szUncompressed = zipfileRead32(aRead);
5960: pLFH->nFile = zipfileRead16(aRead);
5961: pLFH->nExtra = zipfileRead16(aRead);
5962: }
5963: return rc;
5964: }
5965:
5966:
5967: /*
5968: ** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields.
5969: ** Scan through this buffer to find an "extra-timestamp" field. If one
5970: ** exists, extract the 32-bit modification-timestamp from it and store
5971: ** the value in output parameter *pmTime.
5972: **
5973: ** Zero is returned if no extra-timestamp record could be found (and so
5974: ** *pmTime is left unchanged), or non-zero otherwise.
5975: **
5976: ** The general format of an extra field is:
5977: **
5978: ** Header ID 2 bytes
5979: ** Data Size 2 bytes
5980: ** Data N bytes
5981: */
5982: static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
5983: int ret = 0;
5984: u8 *p = aExtra;
5985: u8 *pEnd = &aExtra[nExtra];
5986:
5987: while( p<pEnd ){
5988: u16 id = zipfileRead16(p);
5989: u16 nByte = zipfileRead16(p);
5990:
5991: switch( id ){
5992: case ZIPFILE_EXTRA_TIMESTAMP: {
5993: u8 b = p[0];
5994: if( b & 0x01 ){ /* 0x01 -> modtime is present */
5995: *pmTime = zipfileGetU32(&p[1]);
5996: ret = 1;
5997: }
5998: break;
5999: }
6000: }
6001:
6002: p += nByte;
6003: }
6004: return ret;
6005: }
6006:
6007: /*
6008: ** Convert the standard MS-DOS timestamp stored in the mTime and mDate
6009: ** fields of the CDS structure passed as the only argument to a 32-bit
6010: ** UNIX seconds-since-the-epoch timestamp. Return the result.
6011: **
6012: ** "Standard" MS-DOS time format:
6013: **
6014: ** File modification time:
6015: ** Bits 00-04: seconds divided by 2
6016: ** Bits 05-10: minute
6017: ** Bits 11-15: hour
6018: ** File modification date:
6019: ** Bits 00-04: day
6020: ** Bits 05-08: month (1-12)
6021: ** Bits 09-15: years from 1980
6022: **
6023: ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
6024: */
6025: static u32 zipfileMtime(ZipfileCDS *pCDS){
6026: int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
6027: int M = ((pCDS->mDate >> 5) & 0x0F);
6028: int D = (pCDS->mDate & 0x1F);
6029: int B = -13;
6030:
6031: int sec = (pCDS->mTime & 0x1F)*2;
6032: int min = (pCDS->mTime >> 5) & 0x3F;
6033: int hr = (pCDS->mTime >> 11) & 0x1F;
6034: i64 JD;
6035:
6036: /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */
6037:
6038: /* Calculate the JD in seconds for noon on the day in question */
6039: if( M<3 ){
6040: Y = Y-1;
6041: M = M+12;
6042: }
6043: JD = (i64)(24*60*60) * (
6044: (int)(365.25 * (Y + 4716))
6045: + (int)(30.6001 * (M + 1))
6046: + D + B - 1524
6047: );
6048:
6049: /* Correct the JD for the time within the day */
6050: JD += (hr-12) * 3600 + min * 60 + sec;
6051:
6052: /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */
6053: return (u32)(JD - (i64)(24405875) * 24*60*6);
6054: }
6055:
6056: /*
6057: ** The opposite of zipfileMtime(). This function populates the mTime and
6058: ** mDate fields of the CDS structure passed as the first argument according
6059: ** to the UNIX timestamp value passed as the second.
6060: */
6061: static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
6062: /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */
6063: i64 JD = (i64)2440588 + mUnixTime / (24*60*60);
6064:
6065: int A, B, C, D, E;
6066: int yr, mon, day;
6067: int hr, min, sec;
6068:
6069: A = (int)((JD - 1867216.25)/36524.25);
6070: A = (int)(JD + 1 + A - (A/4));
6071: B = A + 1524;
6072: C = (int)((B - 122.1)/365.25);
6073: D = (36525*(C&32767))/100;
6074: E = (int)((B-D)/30.6001);
6075:
6076: day = B - D - (int)(30.6001*E);
6077: mon = (E<14 ? E-1 : E-13);
6078: yr = mon>2 ? C-4716 : C-4715;
6079:
6080: hr = (mUnixTime % (24*60*60)) / (60*60);
6081: min = (mUnixTime % (60*60)) / 60;
6082: sec = (mUnixTime % 60);
6083:
6084: if( yr>=1980 ){
6085: pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9));
6086: pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11));
6087: }else{
6088: pCds->mDate = pCds->mTime = 0;
6089: }
6090:
6091: assert( mUnixTime<315507600
6092: || mUnixTime==zipfileMtime(pCds)
6093: || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds))
6094: /* || (mUnixTime % 2) */
6095: );
6096: }
6097:
6098: /*
6099: ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in
6100: ** size) containing an entire zip archive image. Or, if aBlob is NULL,
6101: ** then pFile is a file-handle open on a zip file. In either case, this
6102: ** function creates a ZipfileEntry object based on the zip archive entry
6103: ** for which the CDS record is at offset iOff.
6104: **
6105: ** If successful, SQLITE_OK is returned and (*ppEntry) set to point to
6106: ** the new object. Otherwise, an SQLite error code is returned and the
6107: ** final value of (*ppEntry) undefined.
6108: */
6109: static int zipfileGetEntry(
6110: ZipfileTab *pTab, /* Store any error message here */
6111: const u8 *aBlob, /* Pointer to in-memory file image */
6112: int nBlob, /* Size of aBlob[] in bytes */
6113: FILE *pFile, /* If aBlob==0, read from this file */
6114: i64 iOff, /* Offset of CDS record */
6115: ZipfileEntry **ppEntry /* OUT: Pointer to new object */
6116: ){
6117: u8 *aRead;
6118: char **pzErr = &pTab->base.zErrMsg;
6119: int rc = SQLITE_OK;
6120:
6121: if( aBlob==0 ){
6122: aRead = pTab->aBuffer;
6123: rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr);
6124: }else{
6125: aRead = (u8*)&aBlob[iOff];
6126: }
6127:
6128: if( rc==SQLITE_OK ){
6129: sqlite3_int64 nAlloc;
6130: ZipfileEntry *pNew;
6131:
6132: int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]);
6133: int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]);
6134: nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]);
6135:
6136: nAlloc = sizeof(ZipfileEntry) + nExtra;
6137: if( aBlob ){
6138: nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]);
6139: }
6140:
6141: pNew = (ZipfileEntry*)sqlite3_malloc64(nAlloc);
6142: if( pNew==0 ){
6143: rc = SQLITE_NOMEM;
6144: }else{
6145: memset(pNew, 0, sizeof(ZipfileEntry));
6146: rc = zipfileReadCDS(aRead, &pNew->cds);
6147: if( rc!=SQLITE_OK ){
6148: *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff);
6149: }else if( aBlob==0 ){
6150: rc = zipfileReadData(
6151: pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr
6152: );
6153: }else{
6154: aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ];
6155: }
6156: }
6157:
6158: if( rc==SQLITE_OK ){
6159: u32 *pt = &pNew->mUnixTime;
6160: pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead);
6161: pNew->aExtra = (u8*)&pNew[1];
6162: memcpy(pNew->aExtra, &aRead[nFile], nExtra);
6163: if( pNew->cds.zFile==0 ){
6164: rc = SQLITE_NOMEM;
6165: }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
6166: pNew->mUnixTime = zipfileMtime(&pNew->cds);
6167: }
6168: }
6169:
6170: if( rc==SQLITE_OK ){
6171: static const int szFix = ZIPFILE_LFH_FIXED_SZ;
6172: ZipfileLFH lfh;
6173: if( pFile ){
6174: rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
6175: }else{
6176: aRead = (u8*)&aBlob[pNew->cds.iOffset];
6177: }
6178:
6179: rc = zipfileReadLFH(aRead, &lfh);
6180: if( rc==SQLITE_OK ){
6181: pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
6182: pNew->iDataOff += lfh.nFile + lfh.nExtra;
6183: if( aBlob && pNew->cds.szCompressed ){
6184: pNew->aData = &pNew->aExtra[nExtra];
6185: memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
6186: }
6187: }else{
6188: *pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
6189: (int)pNew->cds.iOffset
6190: );
6191: }
6192: }
6193:
6194: if( rc!=SQLITE_OK ){
6195: zipfileEntryFree(pNew);
6196: }else{
6197: *ppEntry = pNew;
6198: }
6199: }
6200:
6201: return rc;
6202: }
6203:
6204: /*
6205: ** Advance an ZipfileCsr to its next row of output.
6206: */
6207: static int zipfileNext(sqlite3_vtab_cursor *cur){
6208: ZipfileCsr *pCsr = (ZipfileCsr*)cur;
6209: int rc = SQLITE_OK;
6210:
6211: if( pCsr->pFile ){
6212: i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize;
6213: zipfileEntryFree(pCsr->pCurrent);
6214: pCsr->pCurrent = 0;
6215: if( pCsr->iNextOff>=iEof ){
6216: pCsr->bEof = 1;
6217: }else{
6218: ZipfileEntry *p = 0;
6219: ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab);
6220: rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p);
6221: if( rc==SQLITE_OK ){
6222: pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ;
6223: pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment;
6224: }
6225: pCsr->pCurrent = p;
6226: }
6227: }else{
6228: if( !pCsr->bNoop ){
6229: pCsr->pCurrent = pCsr->pCurrent->pNext;
6230: }
6231: if( pCsr->pCurrent==0 ){
6232: pCsr->bEof = 1;
6233: }
6234: }
6235:
6236: pCsr->bNoop = 0;
6237: return rc;
6238: }
6239:
6240: static void zipfileFree(void *p) {
6241: sqlite3_free(p);
6242: }
6243:
6244: /*
6245: ** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the
6246: ** size is nOut bytes. This function uncompresses the data and sets the
6247: ** return value in context pCtx to the result (a blob).
6248: **
6249: ** If an error occurs, an error code is left in pCtx instead.
6250: */
6251: static void zipfileInflate(
6252: sqlite3_context *pCtx, /* Store result here */
6253: const u8 *aIn, /* Compressed data */
6254: int nIn, /* Size of buffer aIn[] in bytes */
6255: int nOut /* Expected output size */
6256: ){
6257: u8 *aRes = sqlite3_malloc(nOut);
6258: if( aRes==0 ){
6259: sqlite3_result_error_nomem(pCtx);
6260: }else{
6261: int err;
6262: z_stream str;
6263: memset(&str, 0, sizeof(str));
6264:
6265: str.next_in = (Byte*)aIn;
6266: str.avail_in = nIn;
6267: str.next_out = (Byte*)aRes;
6268: str.avail_out = nOut;
6269:
6270: err = inflateInit2(&str, -15);
6271: if( err!=Z_OK ){
6272: zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err);
6273: }else{
6274: err = inflate(&str, Z_NO_FLUSH);
6275: if( err!=Z_STREAM_END ){
6276: zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
6277: }else{
6278: sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree);
6279: aRes = 0;
6280: }
6281: }
6282: sqlite3_free(aRes);
6283: inflateEnd(&str);
6284: }
6285: }
6286:
6287: /*
6288: ** Buffer aIn (size nIn bytes) contains uncompressed data. This function
6289: ** compresses it and sets (*ppOut) to point to a buffer containing the
6290: ** compressed data. The caller is responsible for eventually calling
6291: ** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut)
6292: ** is set to the size of buffer (*ppOut) in bytes.
6293: **
6294: ** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error
6295: ** code is returned and an error message left in virtual-table handle
6296: ** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this
6297: ** case.
6298: */
6299: static int zipfileDeflate(
6300: const u8 *aIn, int nIn, /* Input */
6301: u8 **ppOut, int *pnOut, /* Output */
6302: char **pzErr /* OUT: Error message */
6303: ){
6304: int rc = SQLITE_OK;
1.4.2.3 ! misho 6305: sqlite3_int64 nAlloc;
! 6306: z_stream str;
! 6307: u8 *aOut;
1.4.2.2 misho 6308:
1.4.2.3 ! misho 6309: memset(&str, 0, sizeof(str));
! 6310: str.next_in = (Bytef*)aIn;
! 6311: str.avail_in = nIn;
! 6312: deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
! 6313:
! 6314: nAlloc = deflateBound(&str, nIn);
1.4.2.2 misho 6315: aOut = (u8*)sqlite3_malloc64(nAlloc);
6316: if( aOut==0 ){
6317: rc = SQLITE_NOMEM;
6318: }else{
6319: int res;
6320: str.next_out = aOut;
6321: str.avail_out = nAlloc;
6322: res = deflate(&str, Z_FINISH);
6323: if( res==Z_STREAM_END ){
6324: *ppOut = aOut;
6325: *pnOut = (int)str.total_out;
6326: }else{
6327: sqlite3_free(aOut);
6328: *pzErr = sqlite3_mprintf("zipfile: deflate() error");
6329: rc = SQLITE_ERROR;
6330: }
6331: deflateEnd(&str);
6332: }
6333:
6334: return rc;
6335: }
6336:
6337:
6338: /*
6339: ** Return values of columns for the row at which the series_cursor
6340: ** is currently pointing.
6341: */
6342: static int zipfileColumn(
6343: sqlite3_vtab_cursor *cur, /* The cursor */
6344: sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
6345: int i /* Which column to return */
6346: ){
6347: ZipfileCsr *pCsr = (ZipfileCsr*)cur;
6348: ZipfileCDS *pCDS = &pCsr->pCurrent->cds;
6349: int rc = SQLITE_OK;
6350: switch( i ){
6351: case 0: /* name */
6352: sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT);
6353: break;
6354: case 1: /* mode */
6355: /* TODO: Whether or not the following is correct surely depends on
6356: ** the platform on which the archive was created. */
6357: sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16);
6358: break;
6359: case 2: { /* mtime */
6360: sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime);
6361: break;
6362: }
6363: case 3: { /* sz */
6364: if( sqlite3_vtab_nochange(ctx)==0 ){
6365: sqlite3_result_int64(ctx, pCDS->szUncompressed);
6366: }
6367: break;
6368: }
6369: case 4: /* rawdata */
6370: if( sqlite3_vtab_nochange(ctx) ) break;
6371: case 5: { /* data */
6372: if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){
6373: int sz = pCDS->szCompressed;
6374: int szFinal = pCDS->szUncompressed;
6375: if( szFinal>0 ){
6376: u8 *aBuf;
6377: u8 *aFree = 0;
6378: if( pCsr->pCurrent->aData ){
6379: aBuf = pCsr->pCurrent->aData;
6380: }else{
6381: aBuf = aFree = sqlite3_malloc64(sz);
6382: if( aBuf==0 ){
6383: rc = SQLITE_NOMEM;
6384: }else{
6385: FILE *pFile = pCsr->pFile;
6386: if( pFile==0 ){
6387: pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd;
6388: }
6389: rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff,
6390: &pCsr->base.pVtab->zErrMsg
6391: );
6392: }
6393: }
6394: if( rc==SQLITE_OK ){
6395: if( i==5 && pCDS->iCompression ){
6396: zipfileInflate(ctx, aBuf, sz, szFinal);
6397: }else{
6398: sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
6399: }
6400: }
6401: sqlite3_free(aFree);
6402: }else{
6403: /* Figure out if this is a directory or a zero-sized file. Consider
6404: ** it to be a directory either if the mode suggests so, or if
6405: ** the final character in the name is '/'. */
6406: u32 mode = pCDS->iExternalAttr >> 16;
6407: if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){
6408: sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
6409: }
6410: }
6411: }
6412: break;
6413: }
6414: case 6: /* method */
6415: sqlite3_result_int(ctx, pCDS->iCompression);
6416: break;
6417: default: /* z */
6418: assert( i==7 );
6419: sqlite3_result_int64(ctx, pCsr->iId);
6420: break;
6421: }
6422:
6423: return rc;
6424: }
6425:
6426: /*
6427: ** Return TRUE if the cursor is at EOF.
6428: */
6429: static int zipfileEof(sqlite3_vtab_cursor *cur){
6430: ZipfileCsr *pCsr = (ZipfileCsr*)cur;
6431: return pCsr->bEof;
6432: }
6433:
6434: /*
6435: ** If aBlob is not NULL, then it points to a buffer nBlob bytes in size
6436: ** containing an entire zip archive image. Or, if aBlob is NULL, then pFile
6437: ** is guaranteed to be a file-handle open on a zip file.
6438: **
6439: ** This function attempts to locate the EOCD record within the zip archive
6440: ** and populate *pEOCD with the results of decoding it. SQLITE_OK is
6441: ** returned if successful. Otherwise, an SQLite error code is returned and
6442: ** an English language error message may be left in virtual-table pTab.
6443: */
6444: static int zipfileReadEOCD(
6445: ZipfileTab *pTab, /* Return errors here */
6446: const u8 *aBlob, /* Pointer to in-memory file image */
6447: int nBlob, /* Size of aBlob[] in bytes */
6448: FILE *pFile, /* Read from this file if aBlob==0 */
6449: ZipfileEOCD *pEOCD /* Object to populate */
6450: ){
6451: u8 *aRead = pTab->aBuffer; /* Temporary buffer */
6452: int nRead; /* Bytes to read from file */
6453: int rc = SQLITE_OK;
6454:
6455: if( aBlob==0 ){
6456: i64 iOff; /* Offset to read from */
6457: i64 szFile; /* Total size of file in bytes */
6458: fseek(pFile, 0, SEEK_END);
6459: szFile = (i64)ftell(pFile);
6460: if( szFile==0 ){
6461: memset(pEOCD, 0, sizeof(ZipfileEOCD));
6462: return SQLITE_OK;
6463: }
6464: nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
6465: iOff = szFile - nRead;
6466: rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
6467: }else{
6468: nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE));
6469: aRead = (u8*)&aBlob[nBlob-nRead];
6470: }
6471:
6472: if( rc==SQLITE_OK ){
6473: int i;
6474:
6475: /* Scan backwards looking for the signature bytes */
6476: for(i=nRead-20; i>=0; i--){
6477: if( aRead[i]==0x50 && aRead[i+1]==0x4b
6478: && aRead[i+2]==0x05 && aRead[i+3]==0x06
6479: ){
6480: break;
6481: }
6482: }
6483: if( i<0 ){
6484: pTab->base.zErrMsg = sqlite3_mprintf(
6485: "cannot find end of central directory record"
6486: );
6487: return SQLITE_ERROR;
6488: }
6489:
6490: aRead += i+4;
6491: pEOCD->iDisk = zipfileRead16(aRead);
6492: pEOCD->iFirstDisk = zipfileRead16(aRead);
6493: pEOCD->nEntry = zipfileRead16(aRead);
6494: pEOCD->nEntryTotal = zipfileRead16(aRead);
6495: pEOCD->nSize = zipfileRead32(aRead);
6496: pEOCD->iOffset = zipfileRead32(aRead);
6497: }
6498:
6499: return rc;
6500: }
6501:
6502: /*
6503: ** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry
6504: ** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added
6505: ** to the end of the list. Otherwise, it is added to the list immediately
6506: ** before pBefore (which is guaranteed to be a part of said list).
6507: */
6508: static void zipfileAddEntry(
6509: ZipfileTab *pTab,
6510: ZipfileEntry *pBefore,
6511: ZipfileEntry *pNew
6512: ){
6513: assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
6514: assert( pNew->pNext==0 );
6515: if( pBefore==0 ){
6516: if( pTab->pFirstEntry==0 ){
6517: pTab->pFirstEntry = pTab->pLastEntry = pNew;
6518: }else{
6519: assert( pTab->pLastEntry->pNext==0 );
6520: pTab->pLastEntry->pNext = pNew;
6521: pTab->pLastEntry = pNew;
6522: }
6523: }else{
6524: ZipfileEntry **pp;
6525: for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext));
6526: pNew->pNext = pBefore;
6527: *pp = pNew;
6528: }
6529: }
6530:
6531: static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){
6532: ZipfileEOCD eocd;
6533: int rc;
6534: int i;
6535: i64 iOff;
6536:
6537: rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd);
6538: iOff = eocd.iOffset;
6539: for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){
6540: ZipfileEntry *pNew = 0;
6541: rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew);
6542:
6543: if( rc==SQLITE_OK ){
6544: zipfileAddEntry(pTab, 0, pNew);
6545: iOff += ZIPFILE_CDS_FIXED_SZ;
6546: iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment;
6547: }
6548: }
6549: return rc;
6550: }
6551:
6552: /*
6553: ** xFilter callback.
6554: */
6555: static int zipfileFilter(
6556: sqlite3_vtab_cursor *cur,
6557: int idxNum, const char *idxStr,
6558: int argc, sqlite3_value **argv
6559: ){
6560: ZipfileTab *pTab = (ZipfileTab*)cur->pVtab;
6561: ZipfileCsr *pCsr = (ZipfileCsr*)cur;
6562: const char *zFile = 0; /* Zip file to scan */
6563: int rc = SQLITE_OK; /* Return Code */
6564: int bInMemory = 0; /* True for an in-memory zipfile */
6565:
6566: zipfileResetCursor(pCsr);
6567:
6568: if( pTab->zFile ){
6569: zFile = pTab->zFile;
6570: }else if( idxNum==0 ){
6571: zipfileCursorErr(pCsr, "zipfile() function requires an argument");
6572: return SQLITE_ERROR;
6573: }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
6574: const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
6575: int nBlob = sqlite3_value_bytes(argv[0]);
6576: assert( pTab->pFirstEntry==0 );
6577: rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
6578: pCsr->pFreeEntry = pTab->pFirstEntry;
6579: pTab->pFirstEntry = pTab->pLastEntry = 0;
6580: if( rc!=SQLITE_OK ) return rc;
6581: bInMemory = 1;
6582: }else{
6583: zFile = (const char*)sqlite3_value_text(argv[0]);
6584: }
6585:
6586: if( 0==pTab->pWriteFd && 0==bInMemory ){
6587: pCsr->pFile = fopen(zFile, "rb");
6588: if( pCsr->pFile==0 ){
6589: zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
6590: rc = SQLITE_ERROR;
6591: }else{
6592: rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd);
6593: if( rc==SQLITE_OK ){
6594: if( pCsr->eocd.nEntry==0 ){
6595: pCsr->bEof = 1;
6596: }else{
6597: pCsr->iNextOff = pCsr->eocd.iOffset;
6598: rc = zipfileNext(cur);
6599: }
6600: }
6601: }
6602: }else{
6603: pCsr->bNoop = 1;
6604: pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry;
6605: rc = zipfileNext(cur);
6606: }
6607:
6608: return rc;
6609: }
6610:
6611: /*
6612: ** xBestIndex callback.
6613: */
6614: static int zipfileBestIndex(
6615: sqlite3_vtab *tab,
6616: sqlite3_index_info *pIdxInfo
6617: ){
6618: int i;
6619: int idx = -1;
6620: int unusable = 0;
6621:
6622: for(i=0; i<pIdxInfo->nConstraint; i++){
6623: const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
6624: if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
6625: if( pCons->usable==0 ){
6626: unusable = 1;
6627: }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
6628: idx = i;
6629: }
6630: }
1.4.2.3 ! misho 6631: pIdxInfo->estimatedCost = 1000.0;
1.4.2.2 misho 6632: if( idx>=0 ){
6633: pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
6634: pIdxInfo->aConstraintUsage[idx].omit = 1;
6635: pIdxInfo->idxNum = 1;
6636: }else if( unusable ){
6637: return SQLITE_CONSTRAINT;
6638: }
6639: return SQLITE_OK;
6640: }
6641:
6642: static ZipfileEntry *zipfileNewEntry(const char *zPath){
6643: ZipfileEntry *pNew;
6644: pNew = sqlite3_malloc(sizeof(ZipfileEntry));
6645: if( pNew ){
6646: memset(pNew, 0, sizeof(ZipfileEntry));
6647: pNew->cds.zFile = sqlite3_mprintf("%s", zPath);
6648: if( pNew->cds.zFile==0 ){
6649: sqlite3_free(pNew);
6650: pNew = 0;
6651: }
6652: }
6653: return pNew;
6654: }
6655:
6656: static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){
6657: ZipfileCDS *pCds = &pEntry->cds;
6658: u8 *a = aBuf;
6659:
6660: pCds->nExtra = 9;
6661:
6662: /* Write the LFH itself */
6663: zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH);
6664: zipfileWrite16(a, pCds->iVersionExtract);
6665: zipfileWrite16(a, pCds->flags);
6666: zipfileWrite16(a, pCds->iCompression);
6667: zipfileWrite16(a, pCds->mTime);
6668: zipfileWrite16(a, pCds->mDate);
6669: zipfileWrite32(a, pCds->crc32);
6670: zipfileWrite32(a, pCds->szCompressed);
6671: zipfileWrite32(a, pCds->szUncompressed);
6672: zipfileWrite16(a, (u16)pCds->nFile);
6673: zipfileWrite16(a, pCds->nExtra);
6674: assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] );
6675:
6676: /* Add the file name */
6677: memcpy(a, pCds->zFile, (int)pCds->nFile);
6678: a += (int)pCds->nFile;
6679:
6680: /* The "extra" data */
6681: zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
6682: zipfileWrite16(a, 5);
6683: *a++ = 0x01;
6684: zipfileWrite32(a, pEntry->mUnixTime);
6685:
6686: return a-aBuf;
6687: }
6688:
6689: static int zipfileAppendEntry(
6690: ZipfileTab *pTab,
6691: ZipfileEntry *pEntry,
6692: const u8 *pData,
6693: int nData
6694: ){
6695: u8 *aBuf = pTab->aBuffer;
6696: int nBuf;
6697: int rc;
6698:
6699: nBuf = zipfileSerializeLFH(pEntry, aBuf);
6700: rc = zipfileAppendData(pTab, aBuf, nBuf);
6701: if( rc==SQLITE_OK ){
6702: pEntry->iDataOff = pTab->szCurrent;
6703: rc = zipfileAppendData(pTab, pData, nData);
6704: }
6705:
6706: return rc;
6707: }
6708:
6709: static int zipfileGetMode(
6710: sqlite3_value *pVal,
6711: int bIsDir, /* If true, default to directory */
6712: u32 *pMode, /* OUT: Mode value */
6713: char **pzErr /* OUT: Error message */
6714: ){
6715: const char *z = (const char*)sqlite3_value_text(pVal);
6716: u32 mode = 0;
6717: if( z==0 ){
6718: mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644));
6719: }else if( z[0]>='0' && z[0]<='9' ){
6720: mode = (unsigned int)sqlite3_value_int(pVal);
6721: }else{
6722: const char zTemplate[11] = "-rwxrwxrwx";
6723: int i;
6724: if( strlen(z)!=10 ) goto parse_error;
6725: switch( z[0] ){
6726: case '-': mode |= S_IFREG; break;
6727: case 'd': mode |= S_IFDIR; break;
6728: case 'l': mode |= S_IFLNK; break;
6729: default: goto parse_error;
6730: }
6731: for(i=1; i<10; i++){
6732: if( z[i]==zTemplate[i] ) mode |= 1 << (9-i);
6733: else if( z[i]!='-' ) goto parse_error;
6734: }
6735: }
6736: if( ((mode & S_IFDIR)==0)==bIsDir ){
6737: /* The "mode" attribute is a directory, but data has been specified.
6738: ** Or vice-versa - no data but "mode" is a file or symlink. */
6739: *pzErr = sqlite3_mprintf("zipfile: mode does not match data");
6740: return SQLITE_CONSTRAINT;
6741: }
6742: *pMode = mode;
6743: return SQLITE_OK;
6744:
6745: parse_error:
6746: *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z);
6747: return SQLITE_ERROR;
6748: }
6749:
6750: /*
6751: ** Both (const char*) arguments point to nul-terminated strings. Argument
6752: ** nB is the value of strlen(zB). This function returns 0 if the strings are
6753: ** identical, ignoring any trailing '/' character in either path. */
6754: static int zipfileComparePath(const char *zA, const char *zB, int nB){
6755: int nA = (int)strlen(zA);
1.4.2.3 ! misho 6756: if( nA>0 && zA[nA-1]=='/' ) nA--;
! 6757: if( nB>0 && zB[nB-1]=='/' ) nB--;
1.4.2.2 misho 6758: if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
6759: return 1;
6760: }
6761:
6762: static int zipfileBegin(sqlite3_vtab *pVtab){
6763: ZipfileTab *pTab = (ZipfileTab*)pVtab;
6764: int rc = SQLITE_OK;
6765:
6766: assert( pTab->pWriteFd==0 );
1.4.2.3 ! misho 6767: if( pTab->zFile==0 || pTab->zFile[0]==0 ){
! 6768: pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
! 6769: return SQLITE_ERROR;
! 6770: }
1.4.2.2 misho 6771:
6772: /* Open a write fd on the file. Also load the entire central directory
6773: ** structure into memory. During the transaction any new file data is
6774: ** appended to the archive file, but the central directory is accumulated
6775: ** in main-memory until the transaction is committed. */
6776: pTab->pWriteFd = fopen(pTab->zFile, "ab+");
6777: if( pTab->pWriteFd==0 ){
6778: pTab->base.zErrMsg = sqlite3_mprintf(
6779: "zipfile: failed to open file %s for writing", pTab->zFile
6780: );
6781: rc = SQLITE_ERROR;
6782: }else{
6783: fseek(pTab->pWriteFd, 0, SEEK_END);
6784: pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd);
6785: rc = zipfileLoadDirectory(pTab, 0, 0);
6786: }
6787:
6788: if( rc!=SQLITE_OK ){
6789: zipfileCleanupTransaction(pTab);
6790: }
6791:
6792: return rc;
6793: }
6794:
6795: /*
6796: ** Return the current time as a 32-bit timestamp in UNIX epoch format (like
6797: ** time(2)).
6798: */
6799: static u32 zipfileTime(void){
6800: sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
6801: u32 ret;
6802: if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
6803: i64 ms;
6804: pVfs->xCurrentTimeInt64(pVfs, &ms);
6805: ret = (u32)((ms/1000) - ((i64)24405875 * 8640));
6806: }else{
6807: double day;
6808: pVfs->xCurrentTime(pVfs, &day);
6809: ret = (u32)((day - 2440587.5) * 86400);
6810: }
6811: return ret;
6812: }
6813:
6814: /*
6815: ** Return a 32-bit timestamp in UNIX epoch format.
6816: **
6817: ** If the value passed as the only argument is either NULL or an SQL NULL,
6818: ** return the current time. Otherwise, return the value stored in (*pVal)
6819: ** cast to a 32-bit unsigned integer.
6820: */
6821: static u32 zipfileGetTime(sqlite3_value *pVal){
6822: if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
6823: return zipfileTime();
6824: }
6825: return (u32)sqlite3_value_int64(pVal);
6826: }
6827:
6828: /*
6829: ** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry
6830: ** linked list. Remove it from the list and free the object.
6831: */
6832: static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
6833: if( pOld ){
6834: ZipfileEntry **pp;
6835: for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
6836: *pp = (*pp)->pNext;
6837: zipfileEntryFree(pOld);
6838: }
6839: }
6840:
6841: /*
6842: ** xUpdate method.
6843: */
6844: static int zipfileUpdate(
6845: sqlite3_vtab *pVtab,
6846: int nVal,
6847: sqlite3_value **apVal,
6848: sqlite_int64 *pRowid
6849: ){
6850: ZipfileTab *pTab = (ZipfileTab*)pVtab;
6851: int rc = SQLITE_OK; /* Return Code */
6852: ZipfileEntry *pNew = 0; /* New in-memory CDS entry */
6853:
6854: u32 mode = 0; /* Mode for new entry */
6855: u32 mTime = 0; /* Modification time for new entry */
6856: i64 sz = 0; /* Uncompressed size */
6857: const char *zPath = 0; /* Path for new entry */
6858: int nPath = 0; /* strlen(zPath) */
6859: const u8 *pData = 0; /* Pointer to buffer containing content */
6860: int nData = 0; /* Size of pData buffer in bytes */
6861: int iMethod = 0; /* Compression method for new entry */
6862: u8 *pFree = 0; /* Free this */
6863: char *zFree = 0; /* Also free this */
6864: ZipfileEntry *pOld = 0;
6865: ZipfileEntry *pOld2 = 0;
6866: int bUpdate = 0; /* True for an update that modifies "name" */
6867: int bIsDir = 0;
6868: u32 iCrc32 = 0;
6869:
6870: if( pTab->pWriteFd==0 ){
6871: rc = zipfileBegin(pVtab);
6872: if( rc!=SQLITE_OK ) return rc;
6873: }
6874:
6875: /* If this is a DELETE or UPDATE, find the archive entry to delete. */
6876: if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
6877: const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
6878: int nDelete = (int)strlen(zDelete);
6879: if( nVal>1 ){
6880: const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]);
6881: if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
6882: bUpdate = 1;
6883: }
6884: }
6885: for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
6886: if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
6887: break;
6888: }
6889: assert( pOld->pNext );
6890: }
6891: }
6892:
6893: if( nVal>1 ){
6894: /* Check that "sz" and "rawdata" are both NULL: */
6895: if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){
6896: zipfileTableErr(pTab, "sz must be NULL");
6897: rc = SQLITE_CONSTRAINT;
6898: }
6899: if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){
6900: zipfileTableErr(pTab, "rawdata must be NULL");
6901: rc = SQLITE_CONSTRAINT;
6902: }
6903:
6904: if( rc==SQLITE_OK ){
6905: if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){
6906: /* data=NULL. A directory */
6907: bIsDir = 1;
6908: }else{
6909: /* Value specified for "data", and possibly "method". This must be
6910: ** a regular file or a symlink. */
6911: const u8 *aIn = sqlite3_value_blob(apVal[7]);
6912: int nIn = sqlite3_value_bytes(apVal[7]);
6913: int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
6914:
6915: iMethod = sqlite3_value_int(apVal[8]);
6916: sz = nIn;
6917: pData = aIn;
6918: nData = nIn;
6919: if( iMethod!=0 && iMethod!=8 ){
6920: zipfileTableErr(pTab, "unknown compression method: %d", iMethod);
6921: rc = SQLITE_CONSTRAINT;
6922: }else{
6923: if( bAuto || iMethod ){
6924: int nCmp;
6925: rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg);
6926: if( rc==SQLITE_OK ){
6927: if( iMethod || nCmp<nIn ){
6928: iMethod = 8;
6929: pData = pFree;
6930: nData = nCmp;
6931: }
6932: }
6933: }
6934: iCrc32 = crc32(0, aIn, nIn);
6935: }
6936: }
6937: }
6938:
6939: if( rc==SQLITE_OK ){
6940: rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
6941: }
6942:
6943: if( rc==SQLITE_OK ){
6944: zPath = (const char*)sqlite3_value_text(apVal[2]);
1.4.2.3 ! misho 6945: if( zPath==0 ) zPath = "";
1.4.2.2 misho 6946: nPath = (int)strlen(zPath);
6947: mTime = zipfileGetTime(apVal[4]);
6948: }
6949:
6950: if( rc==SQLITE_OK && bIsDir ){
6951: /* For a directory, check that the last character in the path is a
6952: ** '/'. This appears to be required for compatibility with info-zip
6953: ** (the unzip command on unix). It does not create directories
6954: ** otherwise. */
1.4.2.3 ! misho 6955: if( nPath<=0 || zPath[nPath-1]!='/' ){
1.4.2.2 misho 6956: zFree = sqlite3_mprintf("%s/", zPath);
6957: zPath = (const char*)zFree;
1.4.2.3 ! misho 6958: if( zFree==0 ){
! 6959: rc = SQLITE_NOMEM;
! 6960: nPath = 0;
! 6961: }else{
! 6962: nPath = (int)strlen(zPath);
! 6963: }
1.4.2.2 misho 6964: }
6965: }
6966:
6967: /* Check that we're not inserting a duplicate entry -OR- updating an
6968: ** entry with a path, thereby making it into a duplicate. */
6969: if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
6970: ZipfileEntry *p;
6971: for(p=pTab->pFirstEntry; p; p=p->pNext){
6972: if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
6973: switch( sqlite3_vtab_on_conflict(pTab->db) ){
6974: case SQLITE_IGNORE: {
6975: goto zipfile_update_done;
6976: }
6977: case SQLITE_REPLACE: {
6978: pOld2 = p;
6979: break;
6980: }
6981: default: {
6982: zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath);
6983: rc = SQLITE_CONSTRAINT;
6984: break;
6985: }
6986: }
6987: break;
6988: }
6989: }
6990: }
6991:
6992: if( rc==SQLITE_OK ){
6993: /* Create the new CDS record. */
6994: pNew = zipfileNewEntry(zPath);
6995: if( pNew==0 ){
6996: rc = SQLITE_NOMEM;
6997: }else{
6998: pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
6999: pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
7000: pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS;
7001: pNew->cds.iCompression = (u16)iMethod;
7002: zipfileMtimeToDos(&pNew->cds, mTime);
7003: pNew->cds.crc32 = iCrc32;
7004: pNew->cds.szCompressed = nData;
7005: pNew->cds.szUncompressed = (u32)sz;
7006: pNew->cds.iExternalAttr = (mode<<16);
7007: pNew->cds.iOffset = (u32)pTab->szCurrent;
7008: pNew->cds.nFile = (u16)nPath;
7009: pNew->mUnixTime = (u32)mTime;
7010: rc = zipfileAppendEntry(pTab, pNew, pData, nData);
7011: zipfileAddEntry(pTab, pOld, pNew);
7012: }
7013: }
7014: }
7015:
7016: if( rc==SQLITE_OK && (pOld || pOld2) ){
7017: ZipfileCsr *pCsr;
7018: for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
7019: if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){
7020: pCsr->pCurrent = pCsr->pCurrent->pNext;
7021: pCsr->bNoop = 1;
7022: }
7023: }
7024:
7025: zipfileRemoveEntryFromList(pTab, pOld);
7026: zipfileRemoveEntryFromList(pTab, pOld2);
7027: }
7028:
7029: zipfile_update_done:
7030: sqlite3_free(pFree);
7031: sqlite3_free(zFree);
7032: return rc;
7033: }
7034:
7035: static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){
7036: u8 *a = aBuf;
7037: zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD);
7038: zipfileWrite16(a, p->iDisk);
7039: zipfileWrite16(a, p->iFirstDisk);
7040: zipfileWrite16(a, p->nEntry);
7041: zipfileWrite16(a, p->nEntryTotal);
7042: zipfileWrite32(a, p->nSize);
7043: zipfileWrite32(a, p->iOffset);
7044: zipfileWrite16(a, 0); /* Size of trailing comment in bytes*/
7045:
7046: return a-aBuf;
7047: }
7048:
7049: static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){
7050: int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer);
7051: assert( nBuf==ZIPFILE_EOCD_FIXED_SZ );
7052: return zipfileAppendData(pTab, pTab->aBuffer, nBuf);
7053: }
7054:
7055: /*
7056: ** Serialize the CDS structure into buffer aBuf[]. Return the number
7057: ** of bytes written.
7058: */
7059: static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){
7060: u8 *a = aBuf;
7061: ZipfileCDS *pCDS = &pEntry->cds;
7062:
7063: if( pEntry->aExtra==0 ){
7064: pCDS->nExtra = 9;
7065: }
7066:
7067: zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS);
7068: zipfileWrite16(a, pCDS->iVersionMadeBy);
7069: zipfileWrite16(a, pCDS->iVersionExtract);
7070: zipfileWrite16(a, pCDS->flags);
7071: zipfileWrite16(a, pCDS->iCompression);
7072: zipfileWrite16(a, pCDS->mTime);
7073: zipfileWrite16(a, pCDS->mDate);
7074: zipfileWrite32(a, pCDS->crc32);
7075: zipfileWrite32(a, pCDS->szCompressed);
7076: zipfileWrite32(a, pCDS->szUncompressed);
7077: assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
7078: zipfileWrite16(a, pCDS->nFile);
7079: zipfileWrite16(a, pCDS->nExtra);
7080: zipfileWrite16(a, pCDS->nComment);
7081: zipfileWrite16(a, pCDS->iDiskStart);
7082: zipfileWrite16(a, pCDS->iInternalAttr);
7083: zipfileWrite32(a, pCDS->iExternalAttr);
7084: zipfileWrite32(a, pCDS->iOffset);
7085:
7086: memcpy(a, pCDS->zFile, pCDS->nFile);
7087: a += pCDS->nFile;
7088:
7089: if( pEntry->aExtra ){
7090: int n = (int)pCDS->nExtra + (int)pCDS->nComment;
7091: memcpy(a, pEntry->aExtra, n);
7092: a += n;
7093: }else{
7094: assert( pCDS->nExtra==9 );
7095: zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
7096: zipfileWrite16(a, 5);
7097: *a++ = 0x01;
7098: zipfileWrite32(a, pEntry->mUnixTime);
7099: }
7100:
7101: return a-aBuf;
7102: }
7103:
7104: static int zipfileCommit(sqlite3_vtab *pVtab){
7105: ZipfileTab *pTab = (ZipfileTab*)pVtab;
7106: int rc = SQLITE_OK;
7107: if( pTab->pWriteFd ){
7108: i64 iOffset = pTab->szCurrent;
7109: ZipfileEntry *p;
7110: ZipfileEOCD eocd;
7111: int nEntry = 0;
7112:
7113: /* Write out all entries */
7114: for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){
7115: int n = zipfileSerializeCDS(p, pTab->aBuffer);
7116: rc = zipfileAppendData(pTab, pTab->aBuffer, n);
7117: nEntry++;
7118: }
7119:
7120: /* Write out the EOCD record */
7121: eocd.iDisk = 0;
7122: eocd.iFirstDisk = 0;
7123: eocd.nEntry = (u16)nEntry;
7124: eocd.nEntryTotal = (u16)nEntry;
7125: eocd.nSize = (u32)(pTab->szCurrent - iOffset);
7126: eocd.iOffset = (u32)iOffset;
7127: rc = zipfileAppendEOCD(pTab, &eocd);
7128:
7129: zipfileCleanupTransaction(pTab);
7130: }
7131: return rc;
7132: }
7133:
7134: static int zipfileRollback(sqlite3_vtab *pVtab){
7135: return zipfileCommit(pVtab);
7136: }
7137:
7138: static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
7139: ZipfileCsr *pCsr;
7140: for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
7141: if( iId==pCsr->iId ) break;
7142: }
7143: return pCsr;
7144: }
7145:
7146: static void zipfileFunctionCds(
7147: sqlite3_context *context,
7148: int argc,
7149: sqlite3_value **argv
7150: ){
7151: ZipfileCsr *pCsr;
7152: ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
7153: assert( argc>0 );
7154:
7155: pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
7156: if( pCsr ){
7157: ZipfileCDS *p = &pCsr->pCurrent->cds;
7158: char *zRes = sqlite3_mprintf("{"
7159: "\"version-made-by\" : %u, "
7160: "\"version-to-extract\" : %u, "
7161: "\"flags\" : %u, "
7162: "\"compression\" : %u, "
7163: "\"time\" : %u, "
7164: "\"date\" : %u, "
7165: "\"crc32\" : %u, "
7166: "\"compressed-size\" : %u, "
7167: "\"uncompressed-size\" : %u, "
7168: "\"file-name-length\" : %u, "
7169: "\"extra-field-length\" : %u, "
7170: "\"file-comment-length\" : %u, "
7171: "\"disk-number-start\" : %u, "
7172: "\"internal-attr\" : %u, "
7173: "\"external-attr\" : %u, "
7174: "\"offset\" : %u }",
7175: (u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
7176: (u32)p->flags, (u32)p->iCompression,
7177: (u32)p->mTime, (u32)p->mDate,
7178: (u32)p->crc32, (u32)p->szCompressed,
7179: (u32)p->szUncompressed, (u32)p->nFile,
7180: (u32)p->nExtra, (u32)p->nComment,
7181: (u32)p->iDiskStart, (u32)p->iInternalAttr,
7182: (u32)p->iExternalAttr, (u32)p->iOffset
7183: );
7184:
7185: if( zRes==0 ){
7186: sqlite3_result_error_nomem(context);
7187: }else{
7188: sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
7189: sqlite3_free(zRes);
7190: }
7191: }
7192: }
7193:
7194: /*
7195: ** xFindFunction method.
7196: */
7197: static int zipfileFindFunction(
7198: sqlite3_vtab *pVtab, /* Virtual table handle */
7199: int nArg, /* Number of SQL function arguments */
7200: const char *zName, /* Name of SQL function */
7201: void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
7202: void **ppArg /* OUT: User data for *pxFunc */
7203: ){
7204: if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
7205: *pxFunc = zipfileFunctionCds;
7206: *ppArg = (void*)pVtab;
7207: return 1;
7208: }
7209: return 0;
7210: }
7211:
7212: typedef struct ZipfileBuffer ZipfileBuffer;
7213: struct ZipfileBuffer {
7214: u8 *a; /* Pointer to buffer */
7215: int n; /* Size of buffer in bytes */
7216: int nAlloc; /* Byte allocated at a[] */
7217: };
7218:
7219: typedef struct ZipfileCtx ZipfileCtx;
7220: struct ZipfileCtx {
7221: int nEntry;
7222: ZipfileBuffer body;
7223: ZipfileBuffer cds;
7224: };
7225:
7226: static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
7227: if( pBuf->n+nByte>pBuf->nAlloc ){
7228: u8 *aNew;
7229: sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
7230: int nReq = pBuf->n + nByte;
7231:
7232: while( nNew<nReq ) nNew = nNew*2;
7233: aNew = sqlite3_realloc64(pBuf->a, nNew);
7234: if( aNew==0 ) return SQLITE_NOMEM;
7235: pBuf->a = aNew;
7236: pBuf->nAlloc = (int)nNew;
7237: }
7238: return SQLITE_OK;
7239: }
7240:
7241: /*
7242: ** xStep() callback for the zipfile() aggregate. This can be called in
7243: ** any of the following ways:
7244: **
7245: ** SELECT zipfile(name,data) ...
7246: ** SELECT zipfile(name,mode,mtime,data) ...
7247: ** SELECT zipfile(name,mode,mtime,data,method) ...
7248: */
7249: void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
7250: ZipfileCtx *p; /* Aggregate function context */
7251: ZipfileEntry e; /* New entry to add to zip archive */
7252:
7253: sqlite3_value *pName = 0;
7254: sqlite3_value *pMode = 0;
7255: sqlite3_value *pMtime = 0;
7256: sqlite3_value *pData = 0;
7257: sqlite3_value *pMethod = 0;
7258:
7259: int bIsDir = 0;
7260: u32 mode;
7261: int rc = SQLITE_OK;
7262: char *zErr = 0;
7263:
7264: int iMethod = -1; /* Compression method to use (0 or 8) */
7265:
7266: const u8 *aData = 0; /* Possibly compressed data for new entry */
7267: int nData = 0; /* Size of aData[] in bytes */
7268: int szUncompressed = 0; /* Size of data before compression */
7269: u8 *aFree = 0; /* Free this before returning */
7270: u32 iCrc32 = 0; /* crc32 of uncompressed data */
7271:
7272: char *zName = 0; /* Path (name) of new entry */
7273: int nName = 0; /* Size of zName in bytes */
7274: char *zFree = 0; /* Free this before returning */
7275: int nByte;
7276:
7277: memset(&e, 0, sizeof(e));
7278: p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
7279: if( p==0 ) return;
7280:
7281: /* Martial the arguments into stack variables */
7282: if( nVal!=2 && nVal!=4 && nVal!=5 ){
7283: zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()");
7284: rc = SQLITE_ERROR;
7285: goto zipfile_step_out;
7286: }
7287: pName = apVal[0];
7288: if( nVal==2 ){
7289: pData = apVal[1];
7290: }else{
7291: pMode = apVal[1];
7292: pMtime = apVal[2];
7293: pData = apVal[3];
7294: if( nVal==5 ){
7295: pMethod = apVal[4];
7296: }
7297: }
7298:
7299: /* Check that the 'name' parameter looks ok. */
7300: zName = (char*)sqlite3_value_text(pName);
7301: nName = sqlite3_value_bytes(pName);
7302: if( zName==0 ){
7303: zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
7304: rc = SQLITE_ERROR;
7305: goto zipfile_step_out;
7306: }
7307:
7308: /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
7309: ** deflate compression) or NULL (choose automatically). */
7310: if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
7311: iMethod = (int)sqlite3_value_int64(pMethod);
7312: if( iMethod!=0 && iMethod!=8 ){
7313: zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
7314: rc = SQLITE_ERROR;
7315: goto zipfile_step_out;
7316: }
7317: }
7318:
7319: /* Now inspect the data. If this is NULL, then the new entry must be a
7320: ** directory. Otherwise, figure out whether or not the data should
7321: ** be deflated or simply stored in the zip archive. */
7322: if( sqlite3_value_type(pData)==SQLITE_NULL ){
7323: bIsDir = 1;
7324: iMethod = 0;
7325: }else{
7326: aData = sqlite3_value_blob(pData);
7327: szUncompressed = nData = sqlite3_value_bytes(pData);
7328: iCrc32 = crc32(0, aData, nData);
7329: if( iMethod<0 || iMethod==8 ){
7330: int nOut = 0;
7331: rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr);
7332: if( rc!=SQLITE_OK ){
7333: goto zipfile_step_out;
7334: }
7335: if( iMethod==8 || nOut<nData ){
7336: aData = aFree;
7337: nData = nOut;
7338: iMethod = 8;
7339: }else{
7340: iMethod = 0;
7341: }
7342: }
7343: }
7344:
7345: /* Decode the "mode" argument. */
7346: rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr);
7347: if( rc ) goto zipfile_step_out;
7348:
7349: /* Decode the "mtime" argument. */
7350: e.mUnixTime = zipfileGetTime(pMtime);
7351:
7352: /* If this is a directory entry, ensure that there is exactly one '/'
7353: ** at the end of the path. Or, if this is not a directory and the path
7354: ** ends in '/' it is an error. */
7355: if( bIsDir==0 ){
1.4.2.3 ! misho 7356: if( nName>0 && zName[nName-1]=='/' ){
1.4.2.2 misho 7357: zErr = sqlite3_mprintf("non-directory name must not end with /");
7358: rc = SQLITE_ERROR;
7359: goto zipfile_step_out;
7360: }
7361: }else{
1.4.2.3 ! misho 7362: if( nName==0 || zName[nName-1]!='/' ){
1.4.2.2 misho 7363: zName = zFree = sqlite3_mprintf("%s/", zName);
7364: if( zName==0 ){
7365: rc = SQLITE_NOMEM;
7366: goto zipfile_step_out;
7367: }
1.4.2.3 ! misho 7368: nName = (int)strlen(zName);
1.4.2.2 misho 7369: }else{
7370: while( nName>1 && zName[nName-2]=='/' ) nName--;
7371: }
7372: }
7373:
7374: /* Assemble the ZipfileEntry object for the new zip archive entry */
7375: e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
7376: e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
7377: e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
7378: e.cds.iCompression = (u16)iMethod;
7379: zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
7380: e.cds.crc32 = iCrc32;
7381: e.cds.szCompressed = nData;
7382: e.cds.szUncompressed = szUncompressed;
7383: e.cds.iExternalAttr = (mode<<16);
7384: e.cds.iOffset = p->body.n;
7385: e.cds.nFile = (u16)nName;
7386: e.cds.zFile = zName;
7387:
7388: /* Append the LFH to the body of the new archive */
7389: nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
7390: if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
7391: p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);
7392:
7393: /* Append the data to the body of the new archive */
7394: if( nData>0 ){
7395: if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
7396: memcpy(&p->body.a[p->body.n], aData, nData);
7397: p->body.n += nData;
7398: }
7399:
7400: /* Append the CDS record to the directory of the new archive */
7401: nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9;
7402: if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out;
7403: p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]);
7404:
7405: /* Increment the count of entries in the archive */
7406: p->nEntry++;
7407:
7408: zipfile_step_out:
7409: sqlite3_free(aFree);
7410: sqlite3_free(zFree);
7411: if( rc ){
7412: if( zErr ){
7413: sqlite3_result_error(pCtx, zErr, -1);
7414: }else{
7415: sqlite3_result_error_code(pCtx, rc);
7416: }
7417: }
7418: sqlite3_free(zErr);
7419: }
7420:
7421: /*
7422: ** xFinalize() callback for zipfile aggregate function.
7423: */
7424: void zipfileFinal(sqlite3_context *pCtx){
7425: ZipfileCtx *p;
7426: ZipfileEOCD eocd;
7427: sqlite3_int64 nZip;
7428: u8 *aZip;
7429:
7430: p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
7431: if( p==0 ) return;
7432: if( p->nEntry>0 ){
7433: memset(&eocd, 0, sizeof(eocd));
7434: eocd.nEntry = (u16)p->nEntry;
7435: eocd.nEntryTotal = (u16)p->nEntry;
7436: eocd.nSize = p->cds.n;
7437: eocd.iOffset = p->body.n;
7438:
7439: nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
7440: aZip = (u8*)sqlite3_malloc64(nZip);
7441: if( aZip==0 ){
7442: sqlite3_result_error_nomem(pCtx);
7443: }else{
7444: memcpy(aZip, p->body.a, p->body.n);
7445: memcpy(&aZip[p->body.n], p->cds.a, p->cds.n);
7446: zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]);
7447: sqlite3_result_blob(pCtx, aZip, (int)nZip, zipfileFree);
7448: }
7449: }
7450:
7451: sqlite3_free(p->body.a);
7452: sqlite3_free(p->cds.a);
7453: }
7454:
7455:
7456: /*
7457: ** Register the "zipfile" virtual table.
7458: */
7459: static int zipfileRegister(sqlite3 *db){
7460: static sqlite3_module zipfileModule = {
7461: 1, /* iVersion */
7462: zipfileConnect, /* xCreate */
7463: zipfileConnect, /* xConnect */
7464: zipfileBestIndex, /* xBestIndex */
7465: zipfileDisconnect, /* xDisconnect */
7466: zipfileDisconnect, /* xDestroy */
7467: zipfileOpen, /* xOpen - open a cursor */
7468: zipfileClose, /* xClose - close a cursor */
7469: zipfileFilter, /* xFilter - configure scan constraints */
7470: zipfileNext, /* xNext - advance a cursor */
7471: zipfileEof, /* xEof - check for end of scan */
7472: zipfileColumn, /* xColumn - read data */
7473: 0, /* xRowid - read data */
7474: zipfileUpdate, /* xUpdate */
7475: zipfileBegin, /* xBegin */
7476: 0, /* xSync */
7477: zipfileCommit, /* xCommit */
7478: zipfileRollback, /* xRollback */
7479: zipfileFindFunction, /* xFindMethod */
7480: 0, /* xRename */
7481: };
7482:
7483: int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
7484: if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
7485: if( rc==SQLITE_OK ){
7486: rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0,
7487: zipfileStep, zipfileFinal
7488: );
7489: }
7490: return rc;
7491: }
7492: #else /* SQLITE_OMIT_VIRTUALTABLE */
7493: # define zipfileRegister(x) SQLITE_OK
7494: #endif
7495:
7496: #ifdef _WIN32
7497:
7498: #endif
7499: int sqlite3_zipfile_init(
7500: sqlite3 *db,
7501: char **pzErrMsg,
7502: const sqlite3_api_routines *pApi
7503: ){
7504: SQLITE_EXTENSION_INIT2(pApi);
7505: (void)pzErrMsg; /* Unused parameter */
7506: return zipfileRegister(db);
7507: }
7508:
7509: /************************* End ../ext/misc/zipfile.c ********************/
7510: /************************* Begin ../ext/misc/sqlar.c ******************/
7511: /*
7512: ** 2017-12-17
7513: **
7514: ** The author disclaims copyright to this source code. In place of
7515: ** a legal notice, here is a blessing:
7516: **
7517: ** May you do good and not evil.
7518: ** May you find forgiveness for yourself and forgive others.
7519: ** May you share freely, never taking more than you give.
7520: **
7521: ******************************************************************************
7522: **
7523: ** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
7524: ** for working with sqlar archives and used by the shell tool's built-in
7525: ** sqlar support.
7526: */
7527: /* #include "sqlite3ext.h" */
7528: SQLITE_EXTENSION_INIT1
7529: #include <zlib.h>
1.4.2.3 ! misho 7530: #include <assert.h>
1.4.2.2 misho 7531:
7532: /*
7533: ** Implementation of the "sqlar_compress(X)" SQL function.
7534: **
7535: ** If the type of X is SQLITE_BLOB, and compressing that blob using
7536: ** zlib utility function compress() yields a smaller blob, return the
7537: ** compressed blob. Otherwise, return a copy of X.
7538: **
7539: ** SQLar uses the "zlib format" for compressed content. The zlib format
7540: ** contains a two-byte identification header and a four-byte checksum at
7541: ** the end. This is different from ZIP which uses the raw deflate format.
7542: **
7543: ** Future enhancements to SQLar might add support for new compression formats.
7544: ** If so, those new formats will be identified by alternative headers in the
7545: ** compressed data.
7546: */
7547: static void sqlarCompressFunc(
7548: sqlite3_context *context,
7549: int argc,
7550: sqlite3_value **argv
7551: ){
7552: assert( argc==1 );
7553: if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
7554: const Bytef *pData = sqlite3_value_blob(argv[0]);
7555: uLong nData = sqlite3_value_bytes(argv[0]);
7556: uLongf nOut = compressBound(nData);
7557: Bytef *pOut;
7558:
7559: pOut = (Bytef*)sqlite3_malloc(nOut);
7560: if( pOut==0 ){
7561: sqlite3_result_error_nomem(context);
7562: return;
7563: }else{
7564: if( Z_OK!=compress(pOut, &nOut, pData, nData) ){
7565: sqlite3_result_error(context, "error in compress()", -1);
7566: }else if( nOut<nData ){
7567: sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT);
7568: }else{
7569: sqlite3_result_value(context, argv[0]);
7570: }
7571: sqlite3_free(pOut);
7572: }
7573: }else{
7574: sqlite3_result_value(context, argv[0]);
7575: }
7576: }
7577:
7578: /*
7579: ** Implementation of the "sqlar_uncompress(X,SZ)" SQL function
7580: **
7581: ** Parameter SZ is interpreted as an integer. If it is less than or
7582: ** equal to zero, then this function returns a copy of X. Or, if
7583: ** SZ is equal to the size of X when interpreted as a blob, also
7584: ** return a copy of X. Otherwise, decompress blob X using zlib
7585: ** utility function uncompress() and return the results (another
7586: ** blob).
7587: */
7588: static void sqlarUncompressFunc(
7589: sqlite3_context *context,
7590: int argc,
7591: sqlite3_value **argv
7592: ){
7593: uLong nData;
7594: uLongf sz;
7595:
7596: assert( argc==2 );
7597: sz = sqlite3_value_int(argv[1]);
7598:
7599: if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
7600: sqlite3_result_value(context, argv[0]);
7601: }else{
7602: const Bytef *pData= sqlite3_value_blob(argv[0]);
7603: Bytef *pOut = sqlite3_malloc(sz);
7604: if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){
7605: sqlite3_result_error(context, "error in uncompress()", -1);
7606: }else{
7607: sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT);
7608: }
7609: sqlite3_free(pOut);
7610: }
7611: }
7612:
7613:
7614: #ifdef _WIN32
7615:
7616: #endif
7617: int sqlite3_sqlar_init(
7618: sqlite3 *db,
7619: char **pzErrMsg,
7620: const sqlite3_api_routines *pApi
7621: ){
7622: int rc = SQLITE_OK;
7623: SQLITE_EXTENSION_INIT2(pApi);
7624: (void)pzErrMsg; /* Unused parameter */
1.4.2.3 ! misho 7625: rc = sqlite3_create_function(db, "sqlar_compress", 1,
! 7626: SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
1.4.2.2 misho 7627: sqlarCompressFunc, 0, 0);
7628: if( rc==SQLITE_OK ){
1.4.2.3 ! misho 7629: rc = sqlite3_create_function(db, "sqlar_uncompress", 2,
! 7630: SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
1.4.2.2 misho 7631: sqlarUncompressFunc, 0, 0);
7632: }
7633: return rc;
7634: }
7635:
7636: /************************* End ../ext/misc/sqlar.c ********************/
7637: #endif
7638: /************************* Begin ../ext/expert/sqlite3expert.h ******************/
7639: /*
7640: ** 2017 April 07
7641: **
7642: ** The author disclaims copyright to this source code. In place of
7643: ** a legal notice, here is a blessing:
7644: **
7645: ** May you do good and not evil.
7646: ** May you find forgiveness for yourself and forgive others.
7647: ** May you share freely, never taking more than you give.
7648: **
7649: *************************************************************************
7650: */
1.4.2.3 ! misho 7651: #if !defined(SQLITEEXPERT_H)
! 7652: #define SQLITEEXPERT_H 1
1.4.2.2 misho 7653: /* #include "sqlite3.h" */
7654:
7655: typedef struct sqlite3expert sqlite3expert;
7656:
7657: /*
7658: ** Create a new sqlite3expert object.
7659: **
7660: ** If successful, a pointer to the new object is returned and (*pzErr) set
7661: ** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to
7662: ** an English-language error message. In this case it is the responsibility
7663: ** of the caller to eventually free the error message buffer using
7664: ** sqlite3_free().
7665: */
7666: sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr);
7667:
7668: /*
7669: ** Configure an sqlite3expert object.
7670: **
7671: ** EXPERT_CONFIG_SAMPLE:
7672: ** By default, sqlite3_expert_analyze() generates sqlite_stat1 data for
7673: ** each candidate index. This involves scanning and sorting the entire
7674: ** contents of each user database table once for each candidate index
7675: ** associated with the table. For large databases, this can be
7676: ** prohibitively slow. This option allows the sqlite3expert object to
7677: ** be configured so that sqlite_stat1 data is instead generated based on a
7678: ** subset of each table, or so that no sqlite_stat1 data is used at all.
7679: **
7680: ** A single integer argument is passed to this option. If the value is less
7681: ** than or equal to zero, then no sqlite_stat1 data is generated or used by
7682: ** the analysis - indexes are recommended based on the database schema only.
7683: ** Or, if the value is 100 or greater, complete sqlite_stat1 data is
7684: ** generated for each candidate index (this is the default). Finally, if the
7685: ** value falls between 0 and 100, then it represents the percentage of user
7686: ** table rows that should be considered when generating sqlite_stat1 data.
7687: **
7688: ** Examples:
7689: **
7690: ** // Do not generate any sqlite_stat1 data
7691: ** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0);
7692: **
7693: ** // Generate sqlite_stat1 data based on 10% of the rows in each table.
7694: ** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10);
7695: */
7696: int sqlite3_expert_config(sqlite3expert *p, int op, ...);
7697:
7698: #define EXPERT_CONFIG_SAMPLE 1 /* int */
7699:
7700: /*
7701: ** Specify zero or more SQL statements to be included in the analysis.
7702: **
7703: ** Buffer zSql must contain zero or more complete SQL statements. This
7704: ** function parses all statements contained in the buffer and adds them
7705: ** to the internal list of statements to analyze. If successful, SQLITE_OK
7706: ** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example
7707: ** due to a error in the SQL - an SQLite error code is returned and (*pzErr)
7708: ** may be set to point to an English language error message. In this case
7709: ** the caller is responsible for eventually freeing the error message buffer
7710: ** using sqlite3_free().
7711: **
7712: ** If an error does occur while processing one of the statements in the
7713: ** buffer passed as the second argument, none of the statements in the
7714: ** buffer are added to the analysis.
7715: **
7716: ** This function must be called before sqlite3_expert_analyze(). If a call
7717: ** to this function is made on an sqlite3expert object that has already
7718: ** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned
7719: ** immediately and no statements are added to the analysis.
7720: */
7721: int sqlite3_expert_sql(
7722: sqlite3expert *p, /* From a successful sqlite3_expert_new() */
7723: const char *zSql, /* SQL statement(s) to add */
7724: char **pzErr /* OUT: Error message (if any) */
7725: );
7726:
7727:
7728: /*
7729: ** This function is called after the sqlite3expert object has been configured
7730: ** with all SQL statements using sqlite3_expert_sql() to actually perform
7731: ** the analysis. Once this function has been called, it is not possible to
7732: ** add further SQL statements to the analysis.
7733: **
7734: ** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if
7735: ** an error occurs, an SQLite error code is returned and (*pzErr) set to
7736: ** point to a buffer containing an English language error message. In this
7737: ** case it is the responsibility of the caller to eventually free the buffer
7738: ** using sqlite3_free().
7739: **
7740: ** If an error does occur within this function, the sqlite3expert object
7741: ** is no longer useful for any purpose. At that point it is no longer
7742: ** possible to add further SQL statements to the object or to re-attempt
7743: ** the analysis. The sqlite3expert object must still be freed using a call
7744: ** sqlite3_expert_destroy().
7745: */
7746: int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr);
7747:
7748: /*
7749: ** Return the total number of statements loaded using sqlite3_expert_sql().
7750: ** The total number of SQL statements may be different from the total number
7751: ** to calls to sqlite3_expert_sql().
7752: */
7753: int sqlite3_expert_count(sqlite3expert*);
7754:
7755: /*
7756: ** Return a component of the report.
7757: **
7758: ** This function is called after sqlite3_expert_analyze() to extract the
7759: ** results of the analysis. Each call to this function returns either a
7760: ** NULL pointer or a pointer to a buffer containing a nul-terminated string.
7761: ** The value passed as the third argument must be one of the EXPERT_REPORT_*
7762: ** #define constants defined below.
7763: **
7764: ** For some EXPERT_REPORT_* parameters, the buffer returned contains
7765: ** information relating to a specific SQL statement. In these cases that
7766: ** SQL statement is identified by the value passed as the second argument.
7767: ** SQL statements are numbered from 0 in the order in which they are parsed.
7768: ** If an out-of-range value (less than zero or equal to or greater than the
7769: ** value returned by sqlite3_expert_count()) is passed as the second argument
7770: ** along with such an EXPERT_REPORT_* parameter, NULL is always returned.
7771: **
7772: ** EXPERT_REPORT_SQL:
7773: ** Return the text of SQL statement iStmt.
7774: **
7775: ** EXPERT_REPORT_INDEXES:
7776: ** Return a buffer containing the CREATE INDEX statements for all recommended
7777: ** indexes for statement iStmt. If there are no new recommeded indexes, NULL
7778: ** is returned.
7779: **
7780: ** EXPERT_REPORT_PLAN:
7781: ** Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query
7782: ** iStmt after the proposed indexes have been added to the database schema.
7783: **
7784: ** EXPERT_REPORT_CANDIDATES:
7785: ** Return a pointer to a buffer containing the CREATE INDEX statements
7786: ** for all indexes that were tested (for all SQL statements). The iStmt
7787: ** parameter is ignored for EXPERT_REPORT_CANDIDATES calls.
7788: */
7789: const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport);
7790:
7791: /*
7792: ** Values for the third argument passed to sqlite3_expert_report().
7793: */
7794: #define EXPERT_REPORT_SQL 1
7795: #define EXPERT_REPORT_INDEXES 2
7796: #define EXPERT_REPORT_PLAN 3
7797: #define EXPERT_REPORT_CANDIDATES 4
7798:
7799: /*
7800: ** Free an (sqlite3expert*) handle and all associated resources. There
7801: ** should be one call to this function for each successful call to
7802: ** sqlite3-expert_new().
7803: */
7804: void sqlite3_expert_destroy(sqlite3expert*);
7805:
1.4.2.3 ! misho 7806: #endif /* !defined(SQLITEEXPERT_H) */
1.4.2.2 misho 7807:
7808: /************************* End ../ext/expert/sqlite3expert.h ********************/
7809: /************************* Begin ../ext/expert/sqlite3expert.c ******************/
7810: /*
7811: ** 2017 April 09
7812: **
7813: ** The author disclaims copyright to this source code. In place of
7814: ** a legal notice, here is a blessing:
7815: **
7816: ** May you do good and not evil.
7817: ** May you find forgiveness for yourself and forgive others.
7818: ** May you share freely, never taking more than you give.
7819: **
7820: *************************************************************************
7821: */
7822: /* #include "sqlite3expert.h" */
7823: #include <assert.h>
7824: #include <string.h>
7825: #include <stdio.h>
7826:
7827: #ifndef SQLITE_OMIT_VIRTUALTABLE
7828:
7829: /* typedef sqlite3_int64 i64; */
7830: /* typedef sqlite3_uint64 u64; */
7831:
7832: typedef struct IdxColumn IdxColumn;
7833: typedef struct IdxConstraint IdxConstraint;
7834: typedef struct IdxScan IdxScan;
7835: typedef struct IdxStatement IdxStatement;
7836: typedef struct IdxTable IdxTable;
7837: typedef struct IdxWrite IdxWrite;
7838:
7839: #define STRLEN (int)strlen
7840:
7841: /*
7842: ** A temp table name that we assume no user database will actually use.
7843: ** If this assumption proves incorrect triggers on the table with the
7844: ** conflicting name will be ignored.
7845: */
7846: #define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776"
7847:
7848: /*
7849: ** A single constraint. Equivalent to either "col = ?" or "col < ?" (or
7850: ** any other type of single-ended range constraint on a column).
7851: **
7852: ** pLink:
7853: ** Used to temporarily link IdxConstraint objects into lists while
7854: ** creating candidate indexes.
7855: */
7856: struct IdxConstraint {
7857: char *zColl; /* Collation sequence */
7858: int bRange; /* True for range, false for eq */
7859: int iCol; /* Constrained table column */
7860: int bFlag; /* Used by idxFindCompatible() */
7861: int bDesc; /* True if ORDER BY <expr> DESC */
7862: IdxConstraint *pNext; /* Next constraint in pEq or pRange list */
7863: IdxConstraint *pLink; /* See above */
7864: };
7865:
7866: /*
7867: ** A single scan of a single table.
7868: */
7869: struct IdxScan {
7870: IdxTable *pTab; /* Associated table object */
7871: int iDb; /* Database containing table zTable */
7872: i64 covering; /* Mask of columns required for cov. index */
7873: IdxConstraint *pOrder; /* ORDER BY columns */
7874: IdxConstraint *pEq; /* List of == constraints */
7875: IdxConstraint *pRange; /* List of < constraints */
7876: IdxScan *pNextScan; /* Next IdxScan object for same analysis */
7877: };
7878:
7879: /*
7880: ** Information regarding a single database table. Extracted from
7881: ** "PRAGMA table_info" by function idxGetTableInfo().
7882: */
7883: struct IdxColumn {
7884: char *zName;
7885: char *zColl;
7886: int iPk;
7887: };
7888: struct IdxTable {
7889: int nCol;
7890: char *zName; /* Table name */
7891: IdxColumn *aCol;
7892: IdxTable *pNext; /* Next table in linked list of all tables */
7893: };
7894:
7895: /*
7896: ** An object of the following type is created for each unique table/write-op
7897: ** seen. The objects are stored in a singly-linked list beginning at
7898: ** sqlite3expert.pWrite.
7899: */
7900: struct IdxWrite {
7901: IdxTable *pTab;
7902: int eOp; /* SQLITE_UPDATE, DELETE or INSERT */
7903: IdxWrite *pNext;
7904: };
7905:
7906: /*
7907: ** Each statement being analyzed is represented by an instance of this
7908: ** structure.
7909: */
7910: struct IdxStatement {
7911: int iId; /* Statement number */
7912: char *zSql; /* SQL statement */
7913: char *zIdx; /* Indexes */
7914: char *zEQP; /* Plan */
7915: IdxStatement *pNext;
7916: };
7917:
7918:
7919: /*
7920: ** A hash table for storing strings. With space for a payload string
7921: ** with each entry. Methods are:
7922: **
7923: ** idxHashInit()
7924: ** idxHashClear()
7925: ** idxHashAdd()
7926: ** idxHashSearch()
7927: */
7928: #define IDX_HASH_SIZE 1023
7929: typedef struct IdxHashEntry IdxHashEntry;
7930: typedef struct IdxHash IdxHash;
7931: struct IdxHashEntry {
7932: char *zKey; /* nul-terminated key */
7933: char *zVal; /* nul-terminated value string */
7934: char *zVal2; /* nul-terminated value string 2 */
7935: IdxHashEntry *pHashNext; /* Next entry in same hash bucket */
7936: IdxHashEntry *pNext; /* Next entry in hash */
7937: };
7938: struct IdxHash {
7939: IdxHashEntry *pFirst;
7940: IdxHashEntry *aHash[IDX_HASH_SIZE];
7941: };
7942:
7943: /*
7944: ** sqlite3expert object.
7945: */
7946: struct sqlite3expert {
7947: int iSample; /* Percentage of tables to sample for stat1 */
7948: sqlite3 *db; /* User database */
7949: sqlite3 *dbm; /* In-memory db for this analysis */
7950: sqlite3 *dbv; /* Vtab schema for this analysis */
7951: IdxTable *pTable; /* List of all IdxTable objects */
7952: IdxScan *pScan; /* List of scan objects */
7953: IdxWrite *pWrite; /* List of write objects */
7954: IdxStatement *pStatement; /* List of IdxStatement objects */
7955: int bRun; /* True once analysis has run */
7956: char **pzErrmsg;
7957: int rc; /* Error code from whereinfo hook */
7958: IdxHash hIdx; /* Hash containing all candidate indexes */
7959: char *zCandidates; /* For EXPERT_REPORT_CANDIDATES */
7960: };
7961:
7962:
7963: /*
7964: ** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc().
7965: ** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
7966: */
7967: static void *idxMalloc(int *pRc, int nByte){
7968: void *pRet;
7969: assert( *pRc==SQLITE_OK );
7970: assert( nByte>0 );
7971: pRet = sqlite3_malloc(nByte);
7972: if( pRet ){
7973: memset(pRet, 0, nByte);
7974: }else{
7975: *pRc = SQLITE_NOMEM;
7976: }
7977: return pRet;
7978: }
7979:
7980: /*
7981: ** Initialize an IdxHash hash table.
7982: */
7983: static void idxHashInit(IdxHash *pHash){
7984: memset(pHash, 0, sizeof(IdxHash));
7985: }
7986:
7987: /*
7988: ** Reset an IdxHash hash table.
7989: */
7990: static void idxHashClear(IdxHash *pHash){
7991: int i;
7992: for(i=0; i<IDX_HASH_SIZE; i++){
7993: IdxHashEntry *pEntry;
7994: IdxHashEntry *pNext;
7995: for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){
7996: pNext = pEntry->pHashNext;
7997: sqlite3_free(pEntry->zVal2);
7998: sqlite3_free(pEntry);
7999: }
8000: }
8001: memset(pHash, 0, sizeof(IdxHash));
8002: }
8003:
8004: /*
8005: ** Return the index of the hash bucket that the string specified by the
8006: ** arguments to this function belongs.
8007: */
8008: static int idxHashString(const char *z, int n){
8009: unsigned int ret = 0;
8010: int i;
8011: for(i=0; i<n; i++){
8012: ret += (ret<<3) + (unsigned char)(z[i]);
8013: }
8014: return (int)(ret % IDX_HASH_SIZE);
8015: }
8016:
8017: /*
8018: ** If zKey is already present in the hash table, return non-zero and do
8019: ** nothing. Otherwise, add an entry with key zKey and payload string zVal to
8020: ** the hash table passed as the second argument.
8021: */
8022: static int idxHashAdd(
8023: int *pRc,
8024: IdxHash *pHash,
8025: const char *zKey,
8026: const char *zVal
8027: ){
8028: int nKey = STRLEN(zKey);
8029: int iHash = idxHashString(zKey, nKey);
8030: int nVal = (zVal ? STRLEN(zVal) : 0);
8031: IdxHashEntry *pEntry;
8032: assert( iHash>=0 );
8033: for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
8034: if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
8035: return 1;
8036: }
8037: }
8038: pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
8039: if( pEntry ){
8040: pEntry->zKey = (char*)&pEntry[1];
8041: memcpy(pEntry->zKey, zKey, nKey);
8042: if( zVal ){
8043: pEntry->zVal = &pEntry->zKey[nKey+1];
8044: memcpy(pEntry->zVal, zVal, nVal);
8045: }
8046: pEntry->pHashNext = pHash->aHash[iHash];
8047: pHash->aHash[iHash] = pEntry;
8048:
8049: pEntry->pNext = pHash->pFirst;
8050: pHash->pFirst = pEntry;
8051: }
8052: return 0;
8053: }
8054:
8055: /*
8056: ** If zKey/nKey is present in the hash table, return a pointer to the
8057: ** hash-entry object.
8058: */
8059: static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){
8060: int iHash;
8061: IdxHashEntry *pEntry;
8062: if( nKey<0 ) nKey = STRLEN(zKey);
8063: iHash = idxHashString(zKey, nKey);
8064: assert( iHash>=0 );
8065: for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
8066: if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
8067: return pEntry;
8068: }
8069: }
8070: return 0;
8071: }
8072:
8073: /*
8074: ** If the hash table contains an entry with a key equal to the string
8075: ** passed as the final two arguments to this function, return a pointer
8076: ** to the payload string. Otherwise, if zKey/nKey is not present in the
8077: ** hash table, return NULL.
8078: */
8079: static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){
8080: IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey);
8081: if( pEntry ) return pEntry->zVal;
8082: return 0;
8083: }
8084:
8085: /*
8086: ** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl
8087: ** variable to point to a copy of nul-terminated string zColl.
8088: */
8089: static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){
8090: IdxConstraint *pNew;
8091: int nColl = STRLEN(zColl);
8092:
8093: assert( *pRc==SQLITE_OK );
8094: pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1);
8095: if( pNew ){
8096: pNew->zColl = (char*)&pNew[1];
8097: memcpy(pNew->zColl, zColl, nColl+1);
8098: }
8099: return pNew;
8100: }
8101:
8102: /*
8103: ** An error associated with database handle db has just occurred. Pass
8104: ** the error message to callback function xOut.
8105: */
8106: static void idxDatabaseError(
8107: sqlite3 *db, /* Database handle */
8108: char **pzErrmsg /* Write error here */
8109: ){
8110: *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
8111: }
8112:
8113: /*
8114: ** Prepare an SQL statement.
8115: */
8116: static int idxPrepareStmt(
8117: sqlite3 *db, /* Database handle to compile against */
8118: sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */
8119: char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */
8120: const char *zSql /* SQL statement to compile */
8121: ){
8122: int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
8123: if( rc!=SQLITE_OK ){
8124: *ppStmt = 0;
8125: idxDatabaseError(db, pzErrmsg);
8126: }
8127: return rc;
8128: }
8129:
8130: /*
8131: ** Prepare an SQL statement using the results of a printf() formatting.
8132: */
8133: static int idxPrintfPrepareStmt(
8134: sqlite3 *db, /* Database handle to compile against */
8135: sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */
8136: char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */
8137: const char *zFmt, /* printf() format of SQL statement */
8138: ... /* Trailing printf() arguments */
8139: ){
8140: va_list ap;
8141: int rc;
8142: char *zSql;
8143: va_start(ap, zFmt);
8144: zSql = sqlite3_vmprintf(zFmt, ap);
8145: if( zSql==0 ){
8146: rc = SQLITE_NOMEM;
8147: }else{
8148: rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql);
8149: sqlite3_free(zSql);
8150: }
8151: va_end(ap);
8152: return rc;
8153: }
8154:
8155:
8156: /*************************************************************************
8157: ** Beginning of virtual table implementation.
8158: */
8159: typedef struct ExpertVtab ExpertVtab;
8160: struct ExpertVtab {
8161: sqlite3_vtab base;
8162: IdxTable *pTab;
8163: sqlite3expert *pExpert;
8164: };
8165:
8166: typedef struct ExpertCsr ExpertCsr;
8167: struct ExpertCsr {
8168: sqlite3_vtab_cursor base;
8169: sqlite3_stmt *pData;
8170: };
8171:
8172: static char *expertDequote(const char *zIn){
8173: int n = STRLEN(zIn);
8174: char *zRet = sqlite3_malloc(n);
8175:
8176: assert( zIn[0]=='\'' );
8177: assert( zIn[n-1]=='\'' );
8178:
8179: if( zRet ){
8180: int iOut = 0;
8181: int iIn = 0;
8182: for(iIn=1; iIn<(n-1); iIn++){
8183: if( zIn[iIn]=='\'' ){
8184: assert( zIn[iIn+1]=='\'' );
8185: iIn++;
8186: }
8187: zRet[iOut++] = zIn[iIn];
8188: }
8189: zRet[iOut] = '\0';
8190: }
8191:
8192: return zRet;
8193: }
8194:
8195: /*
8196: ** This function is the implementation of both the xConnect and xCreate
8197: ** methods of the r-tree virtual table.
8198: **
8199: ** argv[0] -> module name
8200: ** argv[1] -> database name
8201: ** argv[2] -> table name
8202: ** argv[...] -> column names...
8203: */
8204: static int expertConnect(
8205: sqlite3 *db,
8206: void *pAux,
8207: int argc, const char *const*argv,
8208: sqlite3_vtab **ppVtab,
8209: char **pzErr
8210: ){
8211: sqlite3expert *pExpert = (sqlite3expert*)pAux;
8212: ExpertVtab *p = 0;
8213: int rc;
8214:
8215: if( argc!=4 ){
8216: *pzErr = sqlite3_mprintf("internal error!");
8217: rc = SQLITE_ERROR;
8218: }else{
8219: char *zCreateTable = expertDequote(argv[3]);
8220: if( zCreateTable ){
8221: rc = sqlite3_declare_vtab(db, zCreateTable);
8222: if( rc==SQLITE_OK ){
8223: p = idxMalloc(&rc, sizeof(ExpertVtab));
8224: }
8225: if( rc==SQLITE_OK ){
8226: p->pExpert = pExpert;
8227: p->pTab = pExpert->pTable;
8228: assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 );
8229: }
8230: sqlite3_free(zCreateTable);
8231: }else{
8232: rc = SQLITE_NOMEM;
8233: }
8234: }
8235:
8236: *ppVtab = (sqlite3_vtab*)p;
8237: return rc;
8238: }
8239:
8240: static int expertDisconnect(sqlite3_vtab *pVtab){
8241: ExpertVtab *p = (ExpertVtab*)pVtab;
8242: sqlite3_free(p);
8243: return SQLITE_OK;
8244: }
8245:
8246: static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){
8247: ExpertVtab *p = (ExpertVtab*)pVtab;
8248: int rc = SQLITE_OK;
8249: int n = 0;
8250: IdxScan *pScan;
8251: const int opmask =
8252: SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT |
8253: SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE |
8254: SQLITE_INDEX_CONSTRAINT_LE;
8255:
8256: pScan = idxMalloc(&rc, sizeof(IdxScan));
8257: if( pScan ){
8258: int i;
8259:
8260: /* Link the new scan object into the list */
8261: pScan->pTab = p->pTab;
8262: pScan->pNextScan = p->pExpert->pScan;
8263: p->pExpert->pScan = pScan;
8264:
8265: /* Add the constraints to the IdxScan object */
8266: for(i=0; i<pIdxInfo->nConstraint; i++){
8267: struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
8268: if( pCons->usable
8269: && pCons->iColumn>=0
8270: && p->pTab->aCol[pCons->iColumn].iPk==0
8271: && (pCons->op & opmask)
8272: ){
8273: IdxConstraint *pNew;
8274: const char *zColl = sqlite3_vtab_collation(pIdxInfo, i);
8275: pNew = idxNewConstraint(&rc, zColl);
8276: if( pNew ){
8277: pNew->iCol = pCons->iColumn;
8278: if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
8279: pNew->pNext = pScan->pEq;
8280: pScan->pEq = pNew;
8281: }else{
8282: pNew->bRange = 1;
8283: pNew->pNext = pScan->pRange;
8284: pScan->pRange = pNew;
8285: }
8286: }
8287: n++;
8288: pIdxInfo->aConstraintUsage[i].argvIndex = n;
8289: }
8290: }
8291:
8292: /* Add the ORDER BY to the IdxScan object */
8293: for(i=pIdxInfo->nOrderBy-1; i>=0; i--){
8294: int iCol = pIdxInfo->aOrderBy[i].iColumn;
8295: if( iCol>=0 ){
8296: IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl);
8297: if( pNew ){
8298: pNew->iCol = iCol;
8299: pNew->bDesc = pIdxInfo->aOrderBy[i].desc;
8300: pNew->pNext = pScan->pOrder;
8301: pNew->pLink = pScan->pOrder;
8302: pScan->pOrder = pNew;
8303: n++;
8304: }
8305: }
8306: }
8307: }
8308:
8309: pIdxInfo->estimatedCost = 1000000.0 / (n+1);
8310: return rc;
8311: }
8312:
8313: static int expertUpdate(
8314: sqlite3_vtab *pVtab,
8315: int nData,
8316: sqlite3_value **azData,
8317: sqlite_int64 *pRowid
8318: ){
8319: (void)pVtab;
8320: (void)nData;
8321: (void)azData;
8322: (void)pRowid;
8323: return SQLITE_OK;
8324: }
8325:
8326: /*
8327: ** Virtual table module xOpen method.
8328: */
8329: static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
8330: int rc = SQLITE_OK;
8331: ExpertCsr *pCsr;
8332: (void)pVTab;
8333: pCsr = idxMalloc(&rc, sizeof(ExpertCsr));
8334: *ppCursor = (sqlite3_vtab_cursor*)pCsr;
8335: return rc;
8336: }
8337:
8338: /*
8339: ** Virtual table module xClose method.
8340: */
8341: static int expertClose(sqlite3_vtab_cursor *cur){
8342: ExpertCsr *pCsr = (ExpertCsr*)cur;
8343: sqlite3_finalize(pCsr->pData);
8344: sqlite3_free(pCsr);
8345: return SQLITE_OK;
8346: }
8347:
8348: /*
8349: ** Virtual table module xEof method.
8350: **
8351: ** Return non-zero if the cursor does not currently point to a valid
8352: ** record (i.e if the scan has finished), or zero otherwise.
8353: */
8354: static int expertEof(sqlite3_vtab_cursor *cur){
8355: ExpertCsr *pCsr = (ExpertCsr*)cur;
8356: return pCsr->pData==0;
8357: }
8358:
8359: /*
8360: ** Virtual table module xNext method.
8361: */
8362: static int expertNext(sqlite3_vtab_cursor *cur){
8363: ExpertCsr *pCsr = (ExpertCsr*)cur;
8364: int rc = SQLITE_OK;
8365:
8366: assert( pCsr->pData );
8367: rc = sqlite3_step(pCsr->pData);
8368: if( rc!=SQLITE_ROW ){
8369: rc = sqlite3_finalize(pCsr->pData);
8370: pCsr->pData = 0;
8371: }else{
8372: rc = SQLITE_OK;
8373: }
8374:
8375: return rc;
8376: }
8377:
8378: /*
8379: ** Virtual table module xRowid method.
8380: */
8381: static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
8382: (void)cur;
8383: *pRowid = 0;
8384: return SQLITE_OK;
8385: }
8386:
8387: /*
8388: ** Virtual table module xColumn method.
8389: */
8390: static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
8391: ExpertCsr *pCsr = (ExpertCsr*)cur;
8392: sqlite3_value *pVal;
8393: pVal = sqlite3_column_value(pCsr->pData, i);
8394: if( pVal ){
8395: sqlite3_result_value(ctx, pVal);
8396: }
8397: return SQLITE_OK;
8398: }
8399:
8400: /*
8401: ** Virtual table module xFilter method.
8402: */
8403: static int expertFilter(
8404: sqlite3_vtab_cursor *cur,
8405: int idxNum, const char *idxStr,
8406: int argc, sqlite3_value **argv
8407: ){
8408: ExpertCsr *pCsr = (ExpertCsr*)cur;
8409: ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab);
8410: sqlite3expert *pExpert = pVtab->pExpert;
8411: int rc;
8412:
8413: (void)idxNum;
8414: (void)idxStr;
8415: (void)argc;
8416: (void)argv;
8417: rc = sqlite3_finalize(pCsr->pData);
8418: pCsr->pData = 0;
8419: if( rc==SQLITE_OK ){
8420: rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
8421: "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
8422: );
8423: }
8424:
8425: if( rc==SQLITE_OK ){
8426: rc = expertNext(cur);
8427: }
8428: return rc;
8429: }
8430:
8431: static int idxRegisterVtab(sqlite3expert *p){
8432: static sqlite3_module expertModule = {
8433: 2, /* iVersion */
8434: expertConnect, /* xCreate - create a table */
8435: expertConnect, /* xConnect - connect to an existing table */
8436: expertBestIndex, /* xBestIndex - Determine search strategy */
8437: expertDisconnect, /* xDisconnect - Disconnect from a table */
8438: expertDisconnect, /* xDestroy - Drop a table */
8439: expertOpen, /* xOpen - open a cursor */
8440: expertClose, /* xClose - close a cursor */
8441: expertFilter, /* xFilter - configure scan constraints */
8442: expertNext, /* xNext - advance a cursor */
8443: expertEof, /* xEof */
8444: expertColumn, /* xColumn - read data */
8445: expertRowid, /* xRowid - read data */
8446: expertUpdate, /* xUpdate - write data */
8447: 0, /* xBegin - begin transaction */
8448: 0, /* xSync - sync transaction */
8449: 0, /* xCommit - commit transaction */
8450: 0, /* xRollback - rollback transaction */
8451: 0, /* xFindFunction - function overloading */
8452: 0, /* xRename - rename the table */
8453: 0, /* xSavepoint */
8454: 0, /* xRelease */
8455: 0, /* xRollbackTo */
8456: 0, /* xShadowName */
8457: };
8458:
8459: return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
8460: }
8461: /*
8462: ** End of virtual table implementation.
8463: *************************************************************************/
8464: /*
8465: ** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function
8466: ** is called, set it to the return value of sqlite3_finalize() before
8467: ** returning. Otherwise, discard the sqlite3_finalize() return value.
8468: */
8469: static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){
8470: int rc = sqlite3_finalize(pStmt);
8471: if( *pRc==SQLITE_OK ) *pRc = rc;
8472: }
8473:
8474: /*
8475: ** Attempt to allocate an IdxTable structure corresponding to table zTab
8476: ** in the main database of connection db. If successful, set (*ppOut) to
8477: ** point to the new object and return SQLITE_OK. Otherwise, return an
8478: ** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be
8479: ** set to point to an error string.
8480: **
8481: ** It is the responsibility of the caller to eventually free either the
8482: ** IdxTable object or error message using sqlite3_free().
8483: */
8484: static int idxGetTableInfo(
8485: sqlite3 *db, /* Database connection to read details from */
8486: const char *zTab, /* Table name */
8487: IdxTable **ppOut, /* OUT: New object (if successful) */
8488: char **pzErrmsg /* OUT: Error message (if not) */
8489: ){
8490: sqlite3_stmt *p1 = 0;
8491: int nCol = 0;
8492: int nTab = STRLEN(zTab);
8493: int nByte = sizeof(IdxTable) + nTab + 1;
8494: IdxTable *pNew = 0;
8495: int rc, rc2;
8496: char *pCsr = 0;
8497:
8498: rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
8499: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
8500: const char *zCol = (const char*)sqlite3_column_text(p1, 1);
8501: nByte += 1 + STRLEN(zCol);
8502: rc = sqlite3_table_column_metadata(
8503: db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
8504: );
8505: nByte += 1 + STRLEN(zCol);
8506: nCol++;
8507: }
8508: rc2 = sqlite3_reset(p1);
8509: if( rc==SQLITE_OK ) rc = rc2;
8510:
8511: nByte += sizeof(IdxColumn) * nCol;
8512: if( rc==SQLITE_OK ){
8513: pNew = idxMalloc(&rc, nByte);
8514: }
8515: if( rc==SQLITE_OK ){
8516: pNew->aCol = (IdxColumn*)&pNew[1];
8517: pNew->nCol = nCol;
8518: pCsr = (char*)&pNew->aCol[nCol];
8519: }
8520:
8521: nCol = 0;
8522: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
8523: const char *zCol = (const char*)sqlite3_column_text(p1, 1);
8524: int nCopy = STRLEN(zCol) + 1;
8525: pNew->aCol[nCol].zName = pCsr;
8526: pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
8527: memcpy(pCsr, zCol, nCopy);
8528: pCsr += nCopy;
8529:
8530: rc = sqlite3_table_column_metadata(
8531: db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
8532: );
8533: if( rc==SQLITE_OK ){
8534: nCopy = STRLEN(zCol) + 1;
8535: pNew->aCol[nCol].zColl = pCsr;
8536: memcpy(pCsr, zCol, nCopy);
8537: pCsr += nCopy;
8538: }
8539:
8540: nCol++;
8541: }
8542: idxFinalize(&rc, p1);
8543:
8544: if( rc!=SQLITE_OK ){
8545: sqlite3_free(pNew);
8546: pNew = 0;
8547: }else{
8548: pNew->zName = pCsr;
8549: memcpy(pNew->zName, zTab, nTab+1);
8550: }
8551:
8552: *ppOut = pNew;
8553: return rc;
8554: }
8555:
8556: /*
8557: ** This function is a no-op if *pRc is set to anything other than
8558: ** SQLITE_OK when it is called.
8559: **
8560: ** If *pRc is initially set to SQLITE_OK, then the text specified by
8561: ** the printf() style arguments is appended to zIn and the result returned
8562: ** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on
8563: ** zIn before returning.
8564: */
8565: static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
8566: va_list ap;
8567: char *zAppend = 0;
8568: char *zRet = 0;
8569: int nIn = zIn ? STRLEN(zIn) : 0;
8570: int nAppend = 0;
8571: va_start(ap, zFmt);
8572: if( *pRc==SQLITE_OK ){
8573: zAppend = sqlite3_vmprintf(zFmt, ap);
8574: if( zAppend ){
8575: nAppend = STRLEN(zAppend);
8576: zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
8577: }
8578: if( zAppend && zRet ){
8579: if( nIn ) memcpy(zRet, zIn, nIn);
8580: memcpy(&zRet[nIn], zAppend, nAppend+1);
8581: }else{
8582: sqlite3_free(zRet);
8583: zRet = 0;
8584: *pRc = SQLITE_NOMEM;
8585: }
8586: sqlite3_free(zAppend);
8587: sqlite3_free(zIn);
8588: }
8589: va_end(ap);
8590: return zRet;
8591: }
8592:
8593: /*
8594: ** Return true if zId must be quoted in order to use it as an SQL
8595: ** identifier, or false otherwise.
8596: */
8597: static int idxIdentifierRequiresQuotes(const char *zId){
8598: int i;
8599: for(i=0; zId[i]; i++){
8600: if( !(zId[i]=='_')
8601: && !(zId[i]>='0' && zId[i]<='9')
8602: && !(zId[i]>='a' && zId[i]<='z')
8603: && !(zId[i]>='A' && zId[i]<='Z')
8604: ){
8605: return 1;
8606: }
8607: }
8608: return 0;
8609: }
8610:
8611: /*
8612: ** This function appends an index column definition suitable for constraint
8613: ** pCons to the string passed as zIn and returns the result.
8614: */
8615: static char *idxAppendColDefn(
8616: int *pRc, /* IN/OUT: Error code */
8617: char *zIn, /* Column defn accumulated so far */
8618: IdxTable *pTab, /* Table index will be created on */
8619: IdxConstraint *pCons
8620: ){
8621: char *zRet = zIn;
8622: IdxColumn *p = &pTab->aCol[pCons->iCol];
8623: if( zRet ) zRet = idxAppendText(pRc, zRet, ", ");
8624:
8625: if( idxIdentifierRequiresQuotes(p->zName) ){
8626: zRet = idxAppendText(pRc, zRet, "%Q", p->zName);
8627: }else{
8628: zRet = idxAppendText(pRc, zRet, "%s", p->zName);
8629: }
8630:
8631: if( sqlite3_stricmp(p->zColl, pCons->zColl) ){
8632: if( idxIdentifierRequiresQuotes(pCons->zColl) ){
8633: zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl);
8634: }else{
8635: zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl);
8636: }
8637: }
8638:
8639: if( pCons->bDesc ){
8640: zRet = idxAppendText(pRc, zRet, " DESC");
8641: }
8642: return zRet;
8643: }
8644:
8645: /*
8646: ** Search database dbm for an index compatible with the one idxCreateFromCons()
8647: ** would create from arguments pScan, pEq and pTail. If no error occurs and
8648: ** such an index is found, return non-zero. Or, if no such index is found,
8649: ** return zero.
8650: **
8651: ** If an error occurs, set *pRc to an SQLite error code and return zero.
8652: */
8653: static int idxFindCompatible(
8654: int *pRc, /* OUT: Error code */
8655: sqlite3* dbm, /* Database to search */
8656: IdxScan *pScan, /* Scan for table to search for index on */
8657: IdxConstraint *pEq, /* List of == constraints */
8658: IdxConstraint *pTail /* List of range constraints */
8659: ){
8660: const char *zTbl = pScan->pTab->zName;
8661: sqlite3_stmt *pIdxList = 0;
8662: IdxConstraint *pIter;
8663: int nEq = 0; /* Number of elements in pEq */
8664: int rc;
8665:
8666: /* Count the elements in list pEq */
8667: for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++;
8668:
8669: rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl);
8670: while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){
8671: int bMatch = 1;
8672: IdxConstraint *pT = pTail;
8673: sqlite3_stmt *pInfo = 0;
8674: const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
8675:
8676: /* Zero the IdxConstraint.bFlag values in the pEq list */
8677: for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
8678:
8679: rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx);
8680: while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){
8681: int iIdx = sqlite3_column_int(pInfo, 0);
8682: int iCol = sqlite3_column_int(pInfo, 1);
8683: const char *zColl = (const char*)sqlite3_column_text(pInfo, 4);
8684:
8685: if( iIdx<nEq ){
8686: for(pIter=pEq; pIter; pIter=pIter->pLink){
8687: if( pIter->bFlag ) continue;
8688: if( pIter->iCol!=iCol ) continue;
8689: if( sqlite3_stricmp(pIter->zColl, zColl) ) continue;
8690: pIter->bFlag = 1;
8691: break;
8692: }
8693: if( pIter==0 ){
8694: bMatch = 0;
8695: break;
8696: }
8697: }else{
8698: if( pT ){
8699: if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){
8700: bMatch = 0;
8701: break;
8702: }
8703: pT = pT->pLink;
8704: }
8705: }
8706: }
8707: idxFinalize(&rc, pInfo);
8708:
8709: if( rc==SQLITE_OK && bMatch ){
8710: sqlite3_finalize(pIdxList);
8711: return 1;
8712: }
8713: }
8714: idxFinalize(&rc, pIdxList);
8715:
8716: *pRc = rc;
8717: return 0;
8718: }
8719:
8720: static int idxCreateFromCons(
8721: sqlite3expert *p,
8722: IdxScan *pScan,
8723: IdxConstraint *pEq,
8724: IdxConstraint *pTail
8725: ){
8726: sqlite3 *dbm = p->dbm;
8727: int rc = SQLITE_OK;
8728: if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){
8729: IdxTable *pTab = pScan->pTab;
8730: char *zCols = 0;
8731: char *zIdx = 0;
8732: IdxConstraint *pCons;
8733: unsigned int h = 0;
8734: const char *zFmt;
8735:
8736: for(pCons=pEq; pCons; pCons=pCons->pLink){
8737: zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
8738: }
8739: for(pCons=pTail; pCons; pCons=pCons->pLink){
8740: zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
8741: }
8742:
8743: if( rc==SQLITE_OK ){
8744: /* Hash the list of columns to come up with a name for the index */
8745: const char *zTable = pScan->pTab->zName;
8746: char *zName; /* Index name */
8747: int i;
8748: for(i=0; zCols[i]; i++){
8749: h += ((h<<3) + zCols[i]);
8750: }
8751: zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
8752: if( zName==0 ){
8753: rc = SQLITE_NOMEM;
8754: }else{
8755: if( idxIdentifierRequiresQuotes(zTable) ){
8756: zFmt = "CREATE INDEX '%q' ON %Q(%s)";
8757: }else{
8758: zFmt = "CREATE INDEX %s ON %s(%s)";
8759: }
8760: zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols);
8761: if( !zIdx ){
8762: rc = SQLITE_NOMEM;
8763: }else{
8764: rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
8765: idxHashAdd(&rc, &p->hIdx, zName, zIdx);
8766: }
8767: sqlite3_free(zName);
8768: sqlite3_free(zIdx);
8769: }
8770: }
8771:
8772: sqlite3_free(zCols);
8773: }
8774: return rc;
8775: }
8776:
8777: /*
8778: ** Return true if list pList (linked by IdxConstraint.pLink) contains
8779: ** a constraint compatible with *p. Otherwise return false.
8780: */
8781: static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){
8782: IdxConstraint *pCmp;
8783: for(pCmp=pList; pCmp; pCmp=pCmp->pLink){
8784: if( p->iCol==pCmp->iCol ) return 1;
8785: }
8786: return 0;
8787: }
8788:
8789: static int idxCreateFromWhere(
8790: sqlite3expert *p,
8791: IdxScan *pScan, /* Create indexes for this scan */
8792: IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */
8793: ){
8794: IdxConstraint *p1 = 0;
8795: IdxConstraint *pCon;
8796: int rc;
8797:
8798: /* Gather up all the == constraints. */
8799: for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){
8800: if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
8801: pCon->pLink = p1;
8802: p1 = pCon;
8803: }
8804: }
8805:
8806: /* Create an index using the == constraints collected above. And the
8807: ** range constraint/ORDER BY terms passed in by the caller, if any. */
8808: rc = idxCreateFromCons(p, pScan, p1, pTail);
8809:
8810: /* If no range/ORDER BY passed by the caller, create a version of the
8811: ** index for each range constraint. */
8812: if( pTail==0 ){
8813: for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
8814: assert( pCon->pLink==0 );
8815: if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
8816: rc = idxCreateFromCons(p, pScan, p1, pCon);
8817: }
8818: }
8819: }
8820:
8821: return rc;
8822: }
8823:
8824: /*
8825: ** Create candidate indexes in database [dbm] based on the data in
8826: ** linked-list pScan.
8827: */
8828: static int idxCreateCandidates(sqlite3expert *p){
8829: int rc = SQLITE_OK;
8830: IdxScan *pIter;
8831:
8832: for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
8833: rc = idxCreateFromWhere(p, pIter, 0);
8834: if( rc==SQLITE_OK && pIter->pOrder ){
8835: rc = idxCreateFromWhere(p, pIter, pIter->pOrder);
8836: }
8837: }
8838:
8839: return rc;
8840: }
8841:
8842: /*
8843: ** Free all elements of the linked list starting at pConstraint.
8844: */
8845: static void idxConstraintFree(IdxConstraint *pConstraint){
8846: IdxConstraint *pNext;
8847: IdxConstraint *p;
8848:
8849: for(p=pConstraint; p; p=pNext){
8850: pNext = p->pNext;
8851: sqlite3_free(p);
8852: }
8853: }
8854:
8855: /*
8856: ** Free all elements of the linked list starting from pScan up until pLast
8857: ** (pLast is not freed).
8858: */
8859: static void idxScanFree(IdxScan *pScan, IdxScan *pLast){
8860: IdxScan *p;
8861: IdxScan *pNext;
8862: for(p=pScan; p!=pLast; p=pNext){
8863: pNext = p->pNextScan;
8864: idxConstraintFree(p->pOrder);
8865: idxConstraintFree(p->pEq);
8866: idxConstraintFree(p->pRange);
8867: sqlite3_free(p);
8868: }
8869: }
8870:
8871: /*
8872: ** Free all elements of the linked list starting from pStatement up
8873: ** until pLast (pLast is not freed).
8874: */
8875: static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){
8876: IdxStatement *p;
8877: IdxStatement *pNext;
8878: for(p=pStatement; p!=pLast; p=pNext){
8879: pNext = p->pNext;
8880: sqlite3_free(p->zEQP);
8881: sqlite3_free(p->zIdx);
8882: sqlite3_free(p);
8883: }
8884: }
8885:
8886: /*
8887: ** Free the linked list of IdxTable objects starting at pTab.
8888: */
8889: static void idxTableFree(IdxTable *pTab){
8890: IdxTable *pIter;
8891: IdxTable *pNext;
8892: for(pIter=pTab; pIter; pIter=pNext){
8893: pNext = pIter->pNext;
8894: sqlite3_free(pIter);
8895: }
8896: }
8897:
8898: /*
8899: ** Free the linked list of IdxWrite objects starting at pTab.
8900: */
8901: static void idxWriteFree(IdxWrite *pTab){
8902: IdxWrite *pIter;
8903: IdxWrite *pNext;
8904: for(pIter=pTab; pIter; pIter=pNext){
8905: pNext = pIter->pNext;
8906: sqlite3_free(pIter);
8907: }
8908: }
8909:
8910:
8911:
8912: /*
8913: ** This function is called after candidate indexes have been created. It
8914: ** runs all the queries to see which indexes they prefer, and populates
8915: ** IdxStatement.zIdx and IdxStatement.zEQP with the results.
8916: */
8917: int idxFindIndexes(
8918: sqlite3expert *p,
8919: char **pzErr /* OUT: Error message (sqlite3_malloc) */
8920: ){
8921: IdxStatement *pStmt;
8922: sqlite3 *dbm = p->dbm;
8923: int rc = SQLITE_OK;
8924:
8925: IdxHash hIdx;
8926: idxHashInit(&hIdx);
8927:
8928: for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){
8929: IdxHashEntry *pEntry;
8930: sqlite3_stmt *pExplain = 0;
8931: idxHashClear(&hIdx);
8932: rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,
8933: "EXPLAIN QUERY PLAN %s", pStmt->zSql
8934: );
8935: while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
8936: /* int iId = sqlite3_column_int(pExplain, 0); */
8937: /* int iParent = sqlite3_column_int(pExplain, 1); */
8938: /* int iNotUsed = sqlite3_column_int(pExplain, 2); */
8939: const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
1.4.2.3 ! misho 8940: int nDetail;
1.4.2.2 misho 8941: int i;
8942:
1.4.2.3 ! misho 8943: if( !zDetail ) continue;
! 8944: nDetail = STRLEN(zDetail);
! 8945:
1.4.2.2 misho 8946: for(i=0; i<nDetail; i++){
8947: const char *zIdx = 0;
1.4.2.3 ! misho 8948: if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
1.4.2.2 misho 8949: zIdx = &zDetail[i+13];
1.4.2.3 ! misho 8950: }else if( i+22<nDetail
! 8951: && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0
! 8952: ){
1.4.2.2 misho 8953: zIdx = &zDetail[i+22];
8954: }
8955: if( zIdx ){
8956: const char *zSql;
8957: int nIdx = 0;
8958: while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){
8959: nIdx++;
8960: }
8961: zSql = idxHashSearch(&p->hIdx, zIdx, nIdx);
8962: if( zSql ){
8963: idxHashAdd(&rc, &hIdx, zSql, 0);
8964: if( rc ) goto find_indexes_out;
8965: }
8966: break;
8967: }
8968: }
8969:
8970: if( zDetail[0]!='-' ){
8971: pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
8972: }
8973: }
8974:
8975: for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
8976: pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey);
8977: }
8978:
8979: idxFinalize(&rc, pExplain);
8980: }
8981:
8982: find_indexes_out:
8983: idxHashClear(&hIdx);
8984: return rc;
8985: }
8986:
8987: static int idxAuthCallback(
8988: void *pCtx,
8989: int eOp,
8990: const char *z3,
8991: const char *z4,
8992: const char *zDb,
8993: const char *zTrigger
8994: ){
8995: int rc = SQLITE_OK;
8996: (void)z4;
8997: (void)zTrigger;
8998: if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){
8999: if( sqlite3_stricmp(zDb, "main")==0 ){
9000: sqlite3expert *p = (sqlite3expert*)pCtx;
9001: IdxTable *pTab;
9002: for(pTab=p->pTable; pTab; pTab=pTab->pNext){
9003: if( 0==sqlite3_stricmp(z3, pTab->zName) ) break;
9004: }
9005: if( pTab ){
9006: IdxWrite *pWrite;
9007: for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){
9008: if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break;
9009: }
9010: if( pWrite==0 ){
9011: pWrite = idxMalloc(&rc, sizeof(IdxWrite));
9012: if( rc==SQLITE_OK ){
9013: pWrite->pTab = pTab;
9014: pWrite->eOp = eOp;
9015: pWrite->pNext = p->pWrite;
9016: p->pWrite = pWrite;
9017: }
9018: }
9019: }
9020: }
9021: }
9022: return rc;
9023: }
9024:
9025: static int idxProcessOneTrigger(
9026: sqlite3expert *p,
9027: IdxWrite *pWrite,
9028: char **pzErr
9029: ){
9030: static const char *zInt = UNIQUE_TABLE_NAME;
9031: static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME;
9032: IdxTable *pTab = pWrite->pTab;
9033: const char *zTab = pTab->zName;
9034: const char *zSql =
1.4.2.3 ! misho 9035: "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_schema "
1.4.2.2 misho 9036: "WHERE tbl_name = %Q AND type IN ('table', 'trigger') "
9037: "ORDER BY type;";
9038: sqlite3_stmt *pSelect = 0;
9039: int rc = SQLITE_OK;
9040: char *zWrite = 0;
9041:
9042: /* Create the table and its triggers in the temp schema */
9043: rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab);
9044: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){
9045: const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0);
9046: rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr);
9047: }
9048: idxFinalize(&rc, pSelect);
9049:
9050: /* Rename the table in the temp schema to zInt */
9051: if( rc==SQLITE_OK ){
9052: char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt);
9053: if( z==0 ){
9054: rc = SQLITE_NOMEM;
9055: }else{
9056: rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr);
9057: sqlite3_free(z);
9058: }
9059: }
9060:
9061: switch( pWrite->eOp ){
9062: case SQLITE_INSERT: {
9063: int i;
9064: zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt);
9065: for(i=0; i<pTab->nCol; i++){
9066: zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", ");
9067: }
9068: zWrite = idxAppendText(&rc, zWrite, ")");
9069: break;
9070: }
9071: case SQLITE_UPDATE: {
9072: int i;
9073: zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt);
9074: for(i=0; i<pTab->nCol; i++){
9075: zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ",
9076: pTab->aCol[i].zName
9077: );
9078: }
9079: break;
9080: }
9081: default: {
9082: assert( pWrite->eOp==SQLITE_DELETE );
9083: if( rc==SQLITE_OK ){
9084: zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt);
9085: if( zWrite==0 ) rc = SQLITE_NOMEM;
9086: }
9087: }
9088: }
9089:
9090: if( rc==SQLITE_OK ){
9091: sqlite3_stmt *pX = 0;
9092: rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0);
9093: idxFinalize(&rc, pX);
9094: if( rc!=SQLITE_OK ){
9095: idxDatabaseError(p->dbv, pzErr);
9096: }
9097: }
9098: sqlite3_free(zWrite);
9099:
9100: if( rc==SQLITE_OK ){
9101: rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr);
9102: }
9103:
9104: return rc;
9105: }
9106:
9107: static int idxProcessTriggers(sqlite3expert *p, char **pzErr){
9108: int rc = SQLITE_OK;
9109: IdxWrite *pEnd = 0;
9110: IdxWrite *pFirst = p->pWrite;
9111:
9112: while( rc==SQLITE_OK && pFirst!=pEnd ){
9113: IdxWrite *pIter;
9114: for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){
9115: rc = idxProcessOneTrigger(p, pIter, pzErr);
9116: }
9117: pEnd = pFirst;
9118: pFirst = p->pWrite;
9119: }
9120:
9121: return rc;
9122: }
9123:
9124:
9125: static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
9126: int rc = idxRegisterVtab(p);
9127: sqlite3_stmt *pSchema = 0;
9128:
9129: /* For each table in the main db schema:
9130: **
9131: ** 1) Add an entry to the p->pTable list, and
9132: ** 2) Create the equivalent virtual table in dbv.
9133: */
9134: rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
1.4.2.3 ! misho 9135: "SELECT type, name, sql, 1 FROM sqlite_schema "
1.4.2.2 misho 9136: "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
9137: " UNION ALL "
1.4.2.3 ! misho 9138: "SELECT type, name, sql, 2 FROM sqlite_schema "
1.4.2.2 misho 9139: "WHERE type = 'trigger'"
1.4.2.3 ! misho 9140: " AND tbl_name IN(SELECT name FROM sqlite_schema WHERE type = 'view') "
1.4.2.2 misho 9141: "ORDER BY 4, 1"
9142: );
9143: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
9144: const char *zType = (const char*)sqlite3_column_text(pSchema, 0);
9145: const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
9146: const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
9147:
9148: if( zType[0]=='v' || zType[1]=='r' ){
9149: rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
9150: }else{
9151: IdxTable *pTab;
9152: rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
9153: if( rc==SQLITE_OK ){
9154: int i;
9155: char *zInner = 0;
9156: char *zOuter = 0;
9157: pTab->pNext = p->pTable;
9158: p->pTable = pTab;
9159:
9160: /* The statement the vtab will pass to sqlite3_declare_vtab() */
9161: zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
9162: for(i=0; i<pTab->nCol; i++){
9163: zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s",
9164: (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
9165: );
9166: }
9167: zInner = idxAppendText(&rc, zInner, ")");
9168:
9169: /* The CVT statement to create the vtab */
9170: zOuter = idxAppendText(&rc, 0,
9171: "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner
9172: );
9173: if( rc==SQLITE_OK ){
9174: rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg);
9175: }
9176: sqlite3_free(zInner);
9177: sqlite3_free(zOuter);
9178: }
9179: }
9180: }
9181: idxFinalize(&rc, pSchema);
9182: return rc;
9183: }
9184:
9185: struct IdxSampleCtx {
9186: int iTarget;
9187: double target; /* Target nRet/nRow value */
9188: double nRow; /* Number of rows seen */
9189: double nRet; /* Number of rows returned */
9190: };
9191:
9192: static void idxSampleFunc(
9193: sqlite3_context *pCtx,
9194: int argc,
9195: sqlite3_value **argv
9196: ){
9197: struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx);
9198: int bRet;
9199:
9200: (void)argv;
9201: assert( argc==0 );
9202: if( p->nRow==0.0 ){
9203: bRet = 1;
9204: }else{
9205: bRet = (p->nRet / p->nRow) <= p->target;
9206: if( bRet==0 ){
9207: unsigned short rnd;
9208: sqlite3_randomness(2, (void*)&rnd);
9209: bRet = ((int)rnd % 100) <= p->iTarget;
9210: }
9211: }
9212:
9213: sqlite3_result_int(pCtx, bRet);
9214: p->nRow += 1.0;
9215: p->nRet += (double)bRet;
9216: }
9217:
9218: struct IdxRemCtx {
9219: int nSlot;
9220: struct IdxRemSlot {
9221: int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
9222: i64 iVal; /* SQLITE_INTEGER value */
9223: double rVal; /* SQLITE_FLOAT value */
9224: int nByte; /* Bytes of space allocated at z */
9225: int n; /* Size of buffer z */
9226: char *z; /* SQLITE_TEXT/BLOB value */
9227: } aSlot[1];
9228: };
9229:
9230: /*
9231: ** Implementation of scalar function rem().
9232: */
9233: static void idxRemFunc(
9234: sqlite3_context *pCtx,
9235: int argc,
9236: sqlite3_value **argv
9237: ){
9238: struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx);
9239: struct IdxRemSlot *pSlot;
9240: int iSlot;
9241: assert( argc==2 );
9242:
9243: iSlot = sqlite3_value_int(argv[0]);
9244: assert( iSlot<=p->nSlot );
9245: pSlot = &p->aSlot[iSlot];
9246:
9247: switch( pSlot->eType ){
9248: case SQLITE_NULL:
9249: /* no-op */
9250: break;
9251:
9252: case SQLITE_INTEGER:
9253: sqlite3_result_int64(pCtx, pSlot->iVal);
9254: break;
9255:
9256: case SQLITE_FLOAT:
9257: sqlite3_result_double(pCtx, pSlot->rVal);
9258: break;
9259:
9260: case SQLITE_BLOB:
9261: sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
9262: break;
9263:
9264: case SQLITE_TEXT:
9265: sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
9266: break;
9267: }
9268:
9269: pSlot->eType = sqlite3_value_type(argv[1]);
9270: switch( pSlot->eType ){
9271: case SQLITE_NULL:
9272: /* no-op */
9273: break;
9274:
9275: case SQLITE_INTEGER:
9276: pSlot->iVal = sqlite3_value_int64(argv[1]);
9277: break;
9278:
9279: case SQLITE_FLOAT:
9280: pSlot->rVal = sqlite3_value_double(argv[1]);
9281: break;
9282:
9283: case SQLITE_BLOB:
9284: case SQLITE_TEXT: {
9285: int nByte = sqlite3_value_bytes(argv[1]);
9286: if( nByte>pSlot->nByte ){
9287: char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
9288: if( zNew==0 ){
9289: sqlite3_result_error_nomem(pCtx);
9290: return;
9291: }
9292: pSlot->nByte = nByte*2;
9293: pSlot->z = zNew;
9294: }
9295: pSlot->n = nByte;
9296: if( pSlot->eType==SQLITE_BLOB ){
9297: memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte);
9298: }else{
9299: memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte);
9300: }
9301: break;
9302: }
9303: }
9304: }
9305:
9306: static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){
9307: int rc = SQLITE_OK;
9308: const char *zMax =
9309: "SELECT max(i.seqno) FROM "
1.4.2.3 ! misho 9310: " sqlite_schema AS s, "
1.4.2.2 misho 9311: " pragma_index_list(s.name) AS l, "
9312: " pragma_index_info(l.name) AS i "
9313: "WHERE s.type = 'table'";
9314: sqlite3_stmt *pMax = 0;
9315:
9316: *pnMax = 0;
9317: rc = idxPrepareStmt(db, &pMax, pzErr, zMax);
9318: if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
9319: *pnMax = sqlite3_column_int(pMax, 0) + 1;
9320: }
9321: idxFinalize(&rc, pMax);
9322:
9323: return rc;
9324: }
9325:
9326: static int idxPopulateOneStat1(
9327: sqlite3expert *p,
9328: sqlite3_stmt *pIndexXInfo,
9329: sqlite3_stmt *pWriteStat,
9330: const char *zTab,
9331: const char *zIdx,
9332: char **pzErr
9333: ){
9334: char *zCols = 0;
9335: char *zOrder = 0;
9336: char *zQuery = 0;
9337: int nCol = 0;
9338: int i;
9339: sqlite3_stmt *pQuery = 0;
9340: int *aStat = 0;
9341: int rc = SQLITE_OK;
9342:
9343: assert( p->iSample>0 );
9344:
9345: /* Formulate the query text */
9346: sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC);
9347: while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){
9348: const char *zComma = zCols==0 ? "" : ", ";
9349: const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
9350: const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
9351: zCols = idxAppendText(&rc, zCols,
9352: "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
9353: );
9354: zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
9355: }
9356: sqlite3_reset(pIndexXInfo);
9357: if( rc==SQLITE_OK ){
9358: if( p->iSample==100 ){
9359: zQuery = sqlite3_mprintf(
9360: "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder
9361: );
9362: }else{
9363: zQuery = sqlite3_mprintf(
9364: "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder
9365: );
9366: }
9367: }
9368: sqlite3_free(zCols);
9369: sqlite3_free(zOrder);
9370:
9371: /* Formulate the query text */
9372: if( rc==SQLITE_OK ){
9373: sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
9374: rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
9375: }
9376: sqlite3_free(zQuery);
9377:
9378: if( rc==SQLITE_OK ){
9379: aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
9380: }
9381: if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
9382: IdxHashEntry *pEntry;
9383: char *zStat = 0;
9384: for(i=0; i<=nCol; i++) aStat[i] = 1;
9385: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
9386: aStat[0]++;
9387: for(i=0; i<nCol; i++){
9388: if( sqlite3_column_int(pQuery, i)==0 ) break;
9389: }
9390: for(/*no-op*/; i<nCol; i++){
9391: aStat[i+1]++;
9392: }
9393: }
9394:
9395: if( rc==SQLITE_OK ){
9396: int s0 = aStat[0];
9397: zStat = sqlite3_mprintf("%d", s0);
9398: if( zStat==0 ) rc = SQLITE_NOMEM;
9399: for(i=1; rc==SQLITE_OK && i<=nCol; i++){
9400: zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
9401: }
9402: }
9403:
9404: if( rc==SQLITE_OK ){
9405: sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
9406: sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC);
9407: sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC);
9408: sqlite3_step(pWriteStat);
9409: rc = sqlite3_reset(pWriteStat);
9410: }
9411:
9412: pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx));
9413: if( pEntry ){
9414: assert( pEntry->zVal2==0 );
9415: pEntry->zVal2 = zStat;
9416: }else{
9417: sqlite3_free(zStat);
9418: }
9419: }
9420: sqlite3_free(aStat);
9421: idxFinalize(&rc, pQuery);
9422:
9423: return rc;
9424: }
9425:
9426: static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){
9427: int rc;
9428: char *zSql;
9429:
9430: rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
9431: if( rc!=SQLITE_OK ) return rc;
9432:
9433: zSql = sqlite3_mprintf(
9434: "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab
9435: );
9436: if( zSql==0 ) return SQLITE_NOMEM;
9437: rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0);
9438: sqlite3_free(zSql);
9439:
9440: return rc;
9441: }
9442:
9443: /*
9444: ** This function is called as part of sqlite3_expert_analyze(). Candidate
9445: ** indexes have already been created in database sqlite3expert.dbm, this
9446: ** function populates sqlite_stat1 table in the same database.
9447: **
9448: ** The stat1 data is generated by querying the
9449: */
9450: static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
9451: int rc = SQLITE_OK;
9452: int nMax =0;
9453: struct IdxRemCtx *pCtx = 0;
9454: struct IdxSampleCtx samplectx;
9455: int i;
9456: i64 iPrev = -100000;
9457: sqlite3_stmt *pAllIndex = 0;
9458: sqlite3_stmt *pIndexXInfo = 0;
9459: sqlite3_stmt *pWrite = 0;
9460:
9461: const char *zAllIndex =
9462: "SELECT s.rowid, s.name, l.name FROM "
1.4.2.3 ! misho 9463: " sqlite_schema AS s, "
1.4.2.2 misho 9464: " pragma_index_list(s.name) AS l "
9465: "WHERE s.type = 'table'";
9466: const char *zIndexXInfo =
9467: "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key";
9468: const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)";
9469:
9470: /* If iSample==0, no sqlite_stat1 data is required. */
9471: if( p->iSample==0 ) return SQLITE_OK;
9472:
9473: rc = idxLargestIndex(p->dbm, &nMax, pzErr);
9474: if( nMax<=0 || rc!=SQLITE_OK ) return rc;
9475:
9476: rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
9477:
9478: if( rc==SQLITE_OK ){
9479: int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
9480: pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
9481: }
9482:
9483: if( rc==SQLITE_OK ){
9484: sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
9485: rc = sqlite3_create_function(
9486: dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
9487: );
9488: }
9489: if( rc==SQLITE_OK ){
9490: rc = sqlite3_create_function(
9491: p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
9492: );
9493: }
9494:
9495: if( rc==SQLITE_OK ){
9496: pCtx->nSlot = nMax+1;
9497: rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
9498: }
9499: if( rc==SQLITE_OK ){
9500: rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
9501: }
9502: if( rc==SQLITE_OK ){
9503: rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite);
9504: }
9505:
9506: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){
9507: i64 iRowid = sqlite3_column_int64(pAllIndex, 0);
9508: const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1);
9509: const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2);
9510: if( p->iSample<100 && iPrev!=iRowid ){
9511: samplectx.target = (double)p->iSample / 100.0;
9512: samplectx.iTarget = p->iSample;
9513: samplectx.nRow = 0.0;
9514: samplectx.nRet = 0.0;
9515: rc = idxBuildSampleTable(p, zTab);
9516: if( rc!=SQLITE_OK ) break;
9517: }
9518: rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr);
9519: iPrev = iRowid;
9520: }
9521: if( rc==SQLITE_OK && p->iSample<100 ){
9522: rc = sqlite3_exec(p->dbv,
9523: "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0
9524: );
9525: }
9526:
9527: idxFinalize(&rc, pAllIndex);
9528: idxFinalize(&rc, pIndexXInfo);
9529: idxFinalize(&rc, pWrite);
9530:
9531: for(i=0; i<pCtx->nSlot; i++){
9532: sqlite3_free(pCtx->aSlot[i].z);
9533: }
9534: sqlite3_free(pCtx);
9535:
9536: if( rc==SQLITE_OK ){
1.4.2.3 ! misho 9537: rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
1.4.2.2 misho 9538: }
9539:
9540: sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
9541: return rc;
9542: }
9543:
9544: /*
9545: ** Allocate a new sqlite3expert object.
9546: */
9547: sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
9548: int rc = SQLITE_OK;
9549: sqlite3expert *pNew;
9550:
9551: pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert));
9552:
9553: /* Open two in-memory databases to work with. The "vtab database" (dbv)
9554: ** will contain a virtual table corresponding to each real table in
9555: ** the user database schema, and a copy of each view. It is used to
9556: ** collect information regarding the WHERE, ORDER BY and other clauses
9557: ** of the user's query.
9558: */
9559: if( rc==SQLITE_OK ){
9560: pNew->db = db;
9561: pNew->iSample = 100;
9562: rc = sqlite3_open(":memory:", &pNew->dbv);
9563: }
9564: if( rc==SQLITE_OK ){
9565: rc = sqlite3_open(":memory:", &pNew->dbm);
9566: if( rc==SQLITE_OK ){
9567: sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0);
9568: }
9569: }
9570:
9571:
9572: /* Copy the entire schema of database [db] into [dbm]. */
9573: if( rc==SQLITE_OK ){
9574: sqlite3_stmt *pSql;
9575: rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg,
1.4.2.3 ! misho 9576: "SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'"
1.4.2.2 misho 9577: " AND sql NOT LIKE 'CREATE VIRTUAL %%'"
9578: );
9579: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
9580: const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
9581: rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
9582: }
9583: idxFinalize(&rc, pSql);
9584: }
9585:
9586: /* Create the vtab schema */
9587: if( rc==SQLITE_OK ){
9588: rc = idxCreateVtabSchema(pNew, pzErrmsg);
9589: }
9590:
9591: /* Register the auth callback with dbv */
9592: if( rc==SQLITE_OK ){
9593: sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
9594: }
9595:
9596: /* If an error has occurred, free the new object and reutrn NULL. Otherwise,
9597: ** return the new sqlite3expert handle. */
9598: if( rc!=SQLITE_OK ){
9599: sqlite3_expert_destroy(pNew);
9600: pNew = 0;
9601: }
9602: return pNew;
9603: }
9604:
9605: /*
9606: ** Configure an sqlite3expert object.
9607: */
9608: int sqlite3_expert_config(sqlite3expert *p, int op, ...){
9609: int rc = SQLITE_OK;
9610: va_list ap;
9611: va_start(ap, op);
9612: switch( op ){
9613: case EXPERT_CONFIG_SAMPLE: {
9614: int iVal = va_arg(ap, int);
9615: if( iVal<0 ) iVal = 0;
9616: if( iVal>100 ) iVal = 100;
9617: p->iSample = iVal;
9618: break;
9619: }
9620: default:
9621: rc = SQLITE_NOTFOUND;
9622: break;
9623: }
9624:
9625: va_end(ap);
9626: return rc;
9627: }
9628:
9629: /*
9630: ** Add an SQL statement to the analysis.
9631: */
9632: int sqlite3_expert_sql(
9633: sqlite3expert *p, /* From sqlite3_expert_new() */
9634: const char *zSql, /* SQL statement to add */
9635: char **pzErr /* OUT: Error message (if any) */
9636: ){
9637: IdxScan *pScanOrig = p->pScan;
9638: IdxStatement *pStmtOrig = p->pStatement;
9639: int rc = SQLITE_OK;
9640: const char *zStmt = zSql;
9641:
9642: if( p->bRun ) return SQLITE_MISUSE;
9643:
9644: while( rc==SQLITE_OK && zStmt && zStmt[0] ){
9645: sqlite3_stmt *pStmt = 0;
9646: rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
9647: if( rc==SQLITE_OK ){
9648: if( pStmt ){
9649: IdxStatement *pNew;
9650: const char *z = sqlite3_sql(pStmt);
9651: int n = STRLEN(z);
9652: pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
9653: if( rc==SQLITE_OK ){
9654: pNew->zSql = (char*)&pNew[1];
9655: memcpy(pNew->zSql, z, n+1);
9656: pNew->pNext = p->pStatement;
9657: if( p->pStatement ) pNew->iId = p->pStatement->iId+1;
9658: p->pStatement = pNew;
9659: }
9660: sqlite3_finalize(pStmt);
9661: }
9662: }else{
9663: idxDatabaseError(p->dbv, pzErr);
9664: }
9665: }
9666:
9667: if( rc!=SQLITE_OK ){
9668: idxScanFree(p->pScan, pScanOrig);
9669: idxStatementFree(p->pStatement, pStmtOrig);
9670: p->pScan = pScanOrig;
9671: p->pStatement = pStmtOrig;
9672: }
9673:
9674: return rc;
9675: }
9676:
9677: int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
9678: int rc;
9679: IdxHashEntry *pEntry;
9680:
9681: /* Do trigger processing to collect any extra IdxScan structures */
9682: rc = idxProcessTriggers(p, pzErr);
9683:
9684: /* Create candidate indexes within the in-memory database file */
9685: if( rc==SQLITE_OK ){
9686: rc = idxCreateCandidates(p);
9687: }
9688:
9689: /* Generate the stat1 data */
9690: if( rc==SQLITE_OK ){
9691: rc = idxPopulateStat1(p, pzErr);
9692: }
9693:
9694: /* Formulate the EXPERT_REPORT_CANDIDATES text */
9695: for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
9696: p->zCandidates = idxAppendText(&rc, p->zCandidates,
9697: "%s;%s%s\n", pEntry->zVal,
9698: pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2
9699: );
9700: }
9701:
9702: /* Figure out which of the candidate indexes are preferred by the query
9703: ** planner and report the results to the user. */
9704: if( rc==SQLITE_OK ){
9705: rc = idxFindIndexes(p, pzErr);
9706: }
9707:
9708: if( rc==SQLITE_OK ){
9709: p->bRun = 1;
9710: }
9711: return rc;
9712: }
9713:
9714: /*
9715: ** Return the total number of statements that have been added to this
9716: ** sqlite3expert using sqlite3_expert_sql().
9717: */
9718: int sqlite3_expert_count(sqlite3expert *p){
9719: int nRet = 0;
9720: if( p->pStatement ) nRet = p->pStatement->iId+1;
9721: return nRet;
9722: }
9723:
9724: /*
9725: ** Return a component of the report.
9726: */
9727: const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){
9728: const char *zRet = 0;
9729: IdxStatement *pStmt;
9730:
9731: if( p->bRun==0 ) return 0;
9732: for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext);
9733: switch( eReport ){
9734: case EXPERT_REPORT_SQL:
9735: if( pStmt ) zRet = pStmt->zSql;
9736: break;
9737: case EXPERT_REPORT_INDEXES:
9738: if( pStmt ) zRet = pStmt->zIdx;
9739: break;
9740: case EXPERT_REPORT_PLAN:
9741: if( pStmt ) zRet = pStmt->zEQP;
9742: break;
9743: case EXPERT_REPORT_CANDIDATES:
9744: zRet = p->zCandidates;
9745: break;
9746: }
9747: return zRet;
9748: }
9749:
9750: /*
9751: ** Free an sqlite3expert object.
9752: */
9753: void sqlite3_expert_destroy(sqlite3expert *p){
9754: if( p ){
9755: sqlite3_close(p->dbm);
9756: sqlite3_close(p->dbv);
9757: idxScanFree(p->pScan, 0);
9758: idxStatementFree(p->pStatement, 0);
9759: idxTableFree(p->pTable);
9760: idxWriteFree(p->pWrite);
9761: idxHashClear(&p->hIdx);
9762: sqlite3_free(p->zCandidates);
9763: sqlite3_free(p);
9764: }
9765: }
9766:
1.4.2.3 ! misho 9767: #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
1.4.2.2 misho 9768:
9769: /************************* End ../ext/expert/sqlite3expert.c ********************/
9770:
9771: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
9772: /************************* Begin ../ext/misc/dbdata.c ******************/
9773: /*
9774: ** 2019-04-17
9775: **
9776: ** The author disclaims copyright to this source code. In place of
9777: ** a legal notice, here is a blessing:
9778: **
9779: ** May you do good and not evil.
9780: ** May you find forgiveness for yourself and forgive others.
9781: ** May you share freely, never taking more than you give.
9782: **
9783: ******************************************************************************
9784: **
9785: ** This file contains an implementation of two eponymous virtual tables,
9786: ** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
9787: ** "sqlite_dbpage" eponymous virtual table be available.
9788: **
9789: ** SQLITE_DBDATA:
9790: ** sqlite_dbdata is used to extract data directly from a database b-tree
9791: ** page and its associated overflow pages, bypassing the b-tree layer.
9792: ** The table schema is equivalent to:
9793: **
9794: ** CREATE TABLE sqlite_dbdata(
9795: ** pgno INTEGER,
9796: ** cell INTEGER,
9797: ** field INTEGER,
9798: ** value ANY,
9799: ** schema TEXT HIDDEN
9800: ** );
9801: **
9802: ** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
9803: ** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
9804: ** "schema".
9805: **
9806: ** Each page of the database is inspected. If it cannot be interpreted as
9807: ** a b-tree page, or if it is a b-tree page containing 0 entries, the
9808: ** sqlite_dbdata table contains no rows for that page. Otherwise, the
9809: ** table contains one row for each field in the record associated with
9810: ** each cell on the page. For intkey b-trees, the key value is stored in
9811: ** field -1.
9812: **
9813: ** For example, for the database:
9814: **
9815: ** CREATE TABLE t1(a, b); -- root page is page 2
9816: ** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
9817: ** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
9818: **
9819: ** the sqlite_dbdata table contains, as well as from entries related to
9820: ** page 1, content equivalent to:
9821: **
9822: ** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
9823: ** (2, 0, -1, 5 ),
9824: ** (2, 0, 0, 'v' ),
9825: ** (2, 0, 1, 'five'),
9826: ** (2, 1, -1, 10 ),
9827: ** (2, 1, 0, 'x' ),
9828: ** (2, 1, 1, 'ten' );
9829: **
9830: ** If database corruption is encountered, this module does not report an
9831: ** error. Instead, it attempts to extract as much data as possible and
9832: ** ignores the corruption.
9833: **
9834: ** SQLITE_DBPTR:
9835: ** The sqlite_dbptr table has the following schema:
9836: **
9837: ** CREATE TABLE sqlite_dbptr(
9838: ** pgno INTEGER,
9839: ** child INTEGER,
9840: ** schema TEXT HIDDEN
9841: ** );
9842: **
9843: ** It contains one entry for each b-tree pointer between a parent and
9844: ** child page in the database.
9845: */
9846: #if !defined(SQLITEINT_H)
9847: /* #include "sqlite3ext.h" */
9848:
9849: /* typedef unsigned char u8; */
9850:
9851: #endif
9852: SQLITE_EXTENSION_INIT1
9853: #include <string.h>
9854: #include <assert.h>
9855:
9856: #define DBDATA_PADDING_BYTES 100
9857:
9858: typedef struct DbdataTable DbdataTable;
9859: typedef struct DbdataCursor DbdataCursor;
9860:
9861: /* Cursor object */
9862: struct DbdataCursor {
9863: sqlite3_vtab_cursor base; /* Base class. Must be first */
9864: sqlite3_stmt *pStmt; /* For fetching database pages */
9865:
9866: int iPgno; /* Current page number */
9867: u8 *aPage; /* Buffer containing page */
9868: int nPage; /* Size of aPage[] in bytes */
9869: int nCell; /* Number of cells on aPage[] */
9870: int iCell; /* Current cell number */
9871: int bOnePage; /* True to stop after one page */
9872: int szDb;
9873: sqlite3_int64 iRowid;
9874:
9875: /* Only for the sqlite_dbdata table */
9876: u8 *pRec; /* Buffer containing current record */
9877: int nRec; /* Size of pRec[] in bytes */
9878: int nHdr; /* Size of header in bytes */
9879: int iField; /* Current field number */
9880: u8 *pHdrPtr;
9881: u8 *pPtr;
9882:
9883: sqlite3_int64 iIntkey; /* Integer key value */
9884: };
9885:
9886: /* Table object */
9887: struct DbdataTable {
9888: sqlite3_vtab base; /* Base class. Must be first */
9889: sqlite3 *db; /* The database connection */
9890: sqlite3_stmt *pStmt; /* For fetching database pages */
9891: int bPtr; /* True for sqlite3_dbptr table */
9892: };
9893:
9894: /* Column and schema definitions for sqlite_dbdata */
9895: #define DBDATA_COLUMN_PGNO 0
9896: #define DBDATA_COLUMN_CELL 1
9897: #define DBDATA_COLUMN_FIELD 2
9898: #define DBDATA_COLUMN_VALUE 3
9899: #define DBDATA_COLUMN_SCHEMA 4
9900: #define DBDATA_SCHEMA \
9901: "CREATE TABLE x(" \
9902: " pgno INTEGER," \
9903: " cell INTEGER," \
9904: " field INTEGER," \
9905: " value ANY," \
9906: " schema TEXT HIDDEN" \
9907: ")"
9908:
9909: /* Column and schema definitions for sqlite_dbptr */
9910: #define DBPTR_COLUMN_PGNO 0
9911: #define DBPTR_COLUMN_CHILD 1
9912: #define DBPTR_COLUMN_SCHEMA 2
9913: #define DBPTR_SCHEMA \
9914: "CREATE TABLE x(" \
9915: " pgno INTEGER," \
9916: " child INTEGER," \
9917: " schema TEXT HIDDEN" \
9918: ")"
9919:
9920: /*
9921: ** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual
9922: ** table.
9923: */
9924: static int dbdataConnect(
9925: sqlite3 *db,
9926: void *pAux,
9927: int argc, const char *const*argv,
9928: sqlite3_vtab **ppVtab,
9929: char **pzErr
9930: ){
9931: DbdataTable *pTab = 0;
9932: int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
9933:
9934: if( rc==SQLITE_OK ){
9935: pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
9936: if( pTab==0 ){
9937: rc = SQLITE_NOMEM;
9938: }else{
9939: memset(pTab, 0, sizeof(DbdataTable));
9940: pTab->db = db;
9941: pTab->bPtr = (pAux!=0);
9942: }
9943: }
9944:
9945: *ppVtab = (sqlite3_vtab*)pTab;
9946: return rc;
9947: }
9948:
9949: /*
9950: ** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
9951: */
9952: static int dbdataDisconnect(sqlite3_vtab *pVtab){
9953: DbdataTable *pTab = (DbdataTable*)pVtab;
9954: if( pTab ){
9955: sqlite3_finalize(pTab->pStmt);
9956: sqlite3_free(pVtab);
9957: }
9958: return SQLITE_OK;
9959: }
9960:
9961: /*
9962: ** This function interprets two types of constraints:
9963: **
9964: ** schema=?
9965: ** pgno=?
9966: **
9967: ** If neither are present, idxNum is set to 0. If schema=? is present,
9968: ** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
9969: ** in idxNum is set.
9970: **
9971: ** If both parameters are present, schema is in position 0 and pgno in
9972: ** position 1.
9973: */
9974: static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
9975: DbdataTable *pTab = (DbdataTable*)tab;
9976: int i;
9977: int iSchema = -1;
9978: int iPgno = -1;
9979: int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);
9980:
9981: for(i=0; i<pIdx->nConstraint; i++){
9982: struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
9983: if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
9984: if( p->iColumn==colSchema ){
9985: if( p->usable==0 ) return SQLITE_CONSTRAINT;
9986: iSchema = i;
9987: }
9988: if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
9989: iPgno = i;
9990: }
9991: }
9992: }
9993:
9994: if( iSchema>=0 ){
9995: pIdx->aConstraintUsage[iSchema].argvIndex = 1;
9996: pIdx->aConstraintUsage[iSchema].omit = 1;
9997: }
9998: if( iPgno>=0 ){
9999: pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
10000: pIdx->aConstraintUsage[iPgno].omit = 1;
10001: pIdx->estimatedCost = 100;
10002: pIdx->estimatedRows = 50;
10003:
10004: if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
10005: int iCol = pIdx->aOrderBy[0].iColumn;
10006: if( pIdx->nOrderBy==1 ){
10007: pIdx->orderByConsumed = (iCol==0 || iCol==1);
10008: }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
10009: pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
10010: }
10011: }
10012:
10013: }else{
10014: pIdx->estimatedCost = 100000000;
10015: pIdx->estimatedRows = 1000000000;
10016: }
10017: pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
10018: return SQLITE_OK;
10019: }
10020:
10021: /*
10022: ** Open a new sqlite_dbdata or sqlite_dbptr cursor.
10023: */
10024: static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
10025: DbdataCursor *pCsr;
10026:
10027: pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
10028: if( pCsr==0 ){
10029: return SQLITE_NOMEM;
10030: }else{
10031: memset(pCsr, 0, sizeof(DbdataCursor));
10032: pCsr->base.pVtab = pVTab;
10033: }
10034:
10035: *ppCursor = (sqlite3_vtab_cursor *)pCsr;
10036: return SQLITE_OK;
10037: }
10038:
10039: /*
10040: ** Restore a cursor object to the state it was in when first allocated
10041: ** by dbdataOpen().
10042: */
10043: static void dbdataResetCursor(DbdataCursor *pCsr){
10044: DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
10045: if( pTab->pStmt==0 ){
10046: pTab->pStmt = pCsr->pStmt;
10047: }else{
10048: sqlite3_finalize(pCsr->pStmt);
10049: }
10050: pCsr->pStmt = 0;
10051: pCsr->iPgno = 1;
10052: pCsr->iCell = 0;
10053: pCsr->iField = 0;
10054: pCsr->bOnePage = 0;
10055: sqlite3_free(pCsr->aPage);
10056: sqlite3_free(pCsr->pRec);
10057: pCsr->pRec = 0;
10058: pCsr->aPage = 0;
10059: }
10060:
10061: /*
10062: ** Close an sqlite_dbdata or sqlite_dbptr cursor.
10063: */
10064: static int dbdataClose(sqlite3_vtab_cursor *pCursor){
10065: DbdataCursor *pCsr = (DbdataCursor*)pCursor;
10066: dbdataResetCursor(pCsr);
10067: sqlite3_free(pCsr);
10068: return SQLITE_OK;
10069: }
10070:
10071: /*
10072: ** Utility methods to decode 16 and 32-bit big-endian unsigned integers.
10073: */
10074: static unsigned int get_uint16(unsigned char *a){
10075: return (a[0]<<8)|a[1];
10076: }
10077: static unsigned int get_uint32(unsigned char *a){
10078: return ((unsigned int)a[0]<<24)
10079: | ((unsigned int)a[1]<<16)
10080: | ((unsigned int)a[2]<<8)
10081: | ((unsigned int)a[3]);
10082: }
10083:
10084: /*
10085: ** Load page pgno from the database via the sqlite_dbpage virtual table.
10086: ** If successful, set (*ppPage) to point to a buffer containing the page
10087: ** data, (*pnPage) to the size of that buffer in bytes and return
10088: ** SQLITE_OK. In this case it is the responsibility of the caller to
10089: ** eventually free the buffer using sqlite3_free().
10090: **
10091: ** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
10092: ** return an SQLite error code.
10093: */
10094: static int dbdataLoadPage(
10095: DbdataCursor *pCsr, /* Cursor object */
10096: unsigned int pgno, /* Page number of page to load */
10097: u8 **ppPage, /* OUT: pointer to page buffer */
10098: int *pnPage /* OUT: Size of (*ppPage) in bytes */
10099: ){
10100: int rc2;
10101: int rc = SQLITE_OK;
10102: sqlite3_stmt *pStmt = pCsr->pStmt;
10103:
10104: *ppPage = 0;
10105: *pnPage = 0;
10106: sqlite3_bind_int64(pStmt, 2, pgno);
10107: if( SQLITE_ROW==sqlite3_step(pStmt) ){
10108: int nCopy = sqlite3_column_bytes(pStmt, 0);
10109: if( nCopy>0 ){
10110: u8 *pPage;
10111: pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
10112: if( pPage==0 ){
10113: rc = SQLITE_NOMEM;
10114: }else{
10115: const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
10116: memcpy(pPage, pCopy, nCopy);
10117: memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
10118: }
10119: *ppPage = pPage;
10120: *pnPage = nCopy;
10121: }
10122: }
10123: rc2 = sqlite3_reset(pStmt);
10124: if( rc==SQLITE_OK ) rc = rc2;
10125:
10126: return rc;
10127: }
10128:
10129: /*
10130: ** Read a varint. Put the value in *pVal and return the number of bytes.
10131: */
10132: static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
10133: sqlite3_int64 v = 0;
10134: int i;
10135: for(i=0; i<8; i++){
10136: v = (v<<7) + (z[i]&0x7f);
10137: if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
10138: }
10139: v = (v<<8) + (z[i]&0xff);
10140: *pVal = v;
10141: return 9;
10142: }
10143:
10144: /*
10145: ** Return the number of bytes of space used by an SQLite value of type
10146: ** eType.
10147: */
10148: static int dbdataValueBytes(int eType){
10149: switch( eType ){
10150: case 0: case 8: case 9:
10151: case 10: case 11:
10152: return 0;
10153: case 1:
10154: return 1;
10155: case 2:
10156: return 2;
10157: case 3:
10158: return 3;
10159: case 4:
10160: return 4;
10161: case 5:
10162: return 6;
10163: case 6:
10164: case 7:
10165: return 8;
10166: default:
10167: if( eType>0 ){
10168: return ((eType-12) / 2);
10169: }
10170: return 0;
10171: }
10172: }
10173:
10174: /*
10175: ** Load a value of type eType from buffer pData and use it to set the
10176: ** result of context object pCtx.
10177: */
10178: static void dbdataValue(
10179: sqlite3_context *pCtx,
10180: int eType,
10181: u8 *pData,
10182: int nData
10183: ){
10184: if( eType>=0 && dbdataValueBytes(eType)<=nData ){
10185: switch( eType ){
10186: case 0:
10187: case 10:
10188: case 11:
10189: sqlite3_result_null(pCtx);
10190: break;
10191:
10192: case 8:
10193: sqlite3_result_int(pCtx, 0);
10194: break;
10195: case 9:
10196: sqlite3_result_int(pCtx, 1);
10197: break;
10198:
10199: case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
10200: sqlite3_uint64 v = (signed char)pData[0];
10201: pData++;
10202: switch( eType ){
10203: case 7:
10204: case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
10205: case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2;
10206: case 4: v = (v<<8) + pData[0]; pData++;
10207: case 3: v = (v<<8) + pData[0]; pData++;
10208: case 2: v = (v<<8) + pData[0]; pData++;
10209: }
10210:
10211: if( eType==7 ){
10212: double r;
10213: memcpy(&r, &v, sizeof(r));
10214: sqlite3_result_double(pCtx, r);
10215: }else{
10216: sqlite3_result_int64(pCtx, (sqlite3_int64)v);
10217: }
10218: break;
10219: }
10220:
10221: default: {
10222: int n = ((eType-12) / 2);
10223: if( eType % 2 ){
10224: sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
10225: }else{
10226: sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
10227: }
10228: }
10229: }
10230: }
10231: }
10232:
10233: /*
10234: ** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
10235: */
10236: static int dbdataNext(sqlite3_vtab_cursor *pCursor){
10237: DbdataCursor *pCsr = (DbdataCursor*)pCursor;
10238: DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
10239:
10240: pCsr->iRowid++;
10241: while( 1 ){
10242: int rc;
10243: int iOff = (pCsr->iPgno==1 ? 100 : 0);
10244: int bNextPage = 0;
10245:
10246: if( pCsr->aPage==0 ){
10247: while( 1 ){
10248: if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
10249: rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
10250: if( rc!=SQLITE_OK ) return rc;
10251: if( pCsr->aPage ) break;
10252: pCsr->iPgno++;
10253: }
10254: pCsr->iCell = pTab->bPtr ? -2 : 0;
10255: pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
10256: }
10257:
10258: if( pTab->bPtr ){
10259: if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
10260: pCsr->iCell = pCsr->nCell;
10261: }
10262: pCsr->iCell++;
10263: if( pCsr->iCell>=pCsr->nCell ){
10264: sqlite3_free(pCsr->aPage);
10265: pCsr->aPage = 0;
10266: if( pCsr->bOnePage ) return SQLITE_OK;
10267: pCsr->iPgno++;
10268: }else{
10269: return SQLITE_OK;
10270: }
10271: }else{
10272: /* If there is no record loaded, load it now. */
10273: if( pCsr->pRec==0 ){
10274: int bHasRowid = 0;
10275: int nPointer = 0;
10276: sqlite3_int64 nPayload = 0;
10277: sqlite3_int64 nHdr = 0;
10278: int iHdr;
10279: int U, X;
10280: int nLocal;
10281:
10282: switch( pCsr->aPage[iOff] ){
10283: case 0x02:
10284: nPointer = 4;
10285: break;
10286: case 0x0a:
10287: break;
10288: case 0x0d:
10289: bHasRowid = 1;
10290: break;
10291: default:
10292: /* This is not a b-tree page with records on it. Continue. */
10293: pCsr->iCell = pCsr->nCell;
10294: break;
10295: }
10296:
10297: if( pCsr->iCell>=pCsr->nCell ){
10298: bNextPage = 1;
10299: }else{
10300:
10301: iOff += 8 + nPointer + pCsr->iCell*2;
10302: if( iOff>pCsr->nPage ){
10303: bNextPage = 1;
10304: }else{
10305: iOff = get_uint16(&pCsr->aPage[iOff]);
10306: }
10307:
10308: /* For an interior node cell, skip past the child-page number */
10309: iOff += nPointer;
10310:
10311: /* Load the "byte of payload including overflow" field */
10312: if( bNextPage || iOff>pCsr->nPage ){
10313: bNextPage = 1;
10314: }else{
10315: iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
10316: }
10317:
10318: /* If this is a leaf intkey cell, load the rowid */
10319: if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
10320: iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
10321: }
10322:
10323: /* Figure out how much data to read from the local page */
10324: U = pCsr->nPage;
10325: if( bHasRowid ){
10326: X = U-35;
10327: }else{
10328: X = ((U-12)*64/255)-23;
10329: }
10330: if( nPayload<=X ){
10331: nLocal = nPayload;
10332: }else{
10333: int M, K;
10334: M = ((U-12)*32/255)-23;
10335: K = M+((nPayload-M)%(U-4));
10336: if( K<=X ){
10337: nLocal = K;
10338: }else{
10339: nLocal = M;
10340: }
10341: }
10342:
10343: if( bNextPage || nLocal+iOff>pCsr->nPage ){
10344: bNextPage = 1;
10345: }else{
10346:
10347: /* Allocate space for payload. And a bit more to catch small buffer
10348: ** overruns caused by attempting to read a varint or similar from
10349: ** near the end of a corrupt record. */
10350: pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
10351: if( pCsr->pRec==0 ) return SQLITE_NOMEM;
10352: memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
10353: pCsr->nRec = nPayload;
10354:
10355: /* Load the nLocal bytes of payload */
10356: memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
10357: iOff += nLocal;
10358:
10359: /* Load content from overflow pages */
10360: if( nPayload>nLocal ){
10361: sqlite3_int64 nRem = nPayload - nLocal;
10362: unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
10363: while( nRem>0 ){
10364: u8 *aOvfl = 0;
10365: int nOvfl = 0;
10366: int nCopy;
10367: rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
10368: assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
10369: if( rc!=SQLITE_OK ) return rc;
10370: if( aOvfl==0 ) break;
10371:
10372: nCopy = U-4;
10373: if( nCopy>nRem ) nCopy = nRem;
10374: memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
10375: nRem -= nCopy;
10376:
10377: pgnoOvfl = get_uint32(aOvfl);
10378: sqlite3_free(aOvfl);
10379: }
10380: }
10381:
10382: iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
10383: pCsr->nHdr = nHdr;
10384: pCsr->pHdrPtr = &pCsr->pRec[iHdr];
10385: pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
10386: pCsr->iField = (bHasRowid ? -1 : 0);
10387: }
10388: }
10389: }else{
10390: pCsr->iField++;
10391: if( pCsr->iField>0 ){
10392: sqlite3_int64 iType;
10393: if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
10394: bNextPage = 1;
10395: }else{
10396: pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
10397: pCsr->pPtr += dbdataValueBytes(iType);
10398: }
10399: }
10400: }
10401:
10402: if( bNextPage ){
10403: sqlite3_free(pCsr->aPage);
10404: sqlite3_free(pCsr->pRec);
10405: pCsr->aPage = 0;
10406: pCsr->pRec = 0;
10407: if( pCsr->bOnePage ) return SQLITE_OK;
10408: pCsr->iPgno++;
10409: }else{
10410: if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
10411: return SQLITE_OK;
10412: }
10413:
10414: /* Advance to the next cell. The next iteration of the loop will load
10415: ** the record and so on. */
10416: sqlite3_free(pCsr->pRec);
10417: pCsr->pRec = 0;
10418: pCsr->iCell++;
10419: }
10420: }
10421: }
10422:
10423: assert( !"can't get here" );
10424: return SQLITE_OK;
10425: }
10426:
10427: /*
10428: ** Return true if the cursor is at EOF.
10429: */
10430: static int dbdataEof(sqlite3_vtab_cursor *pCursor){
10431: DbdataCursor *pCsr = (DbdataCursor*)pCursor;
10432: return pCsr->aPage==0;
10433: }
10434:
10435: /*
10436: ** Determine the size in pages of database zSchema (where zSchema is
10437: ** "main", "temp" or the name of an attached database) and set
10438: ** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
10439: ** an SQLite error code.
10440: */
10441: static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
10442: DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
10443: char *zSql = 0;
10444: int rc, rc2;
10445: sqlite3_stmt *pStmt = 0;
10446:
10447: zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
10448: if( zSql==0 ) return SQLITE_NOMEM;
10449: rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
10450: sqlite3_free(zSql);
10451: if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
10452: pCsr->szDb = sqlite3_column_int(pStmt, 0);
10453: }
10454: rc2 = sqlite3_finalize(pStmt);
10455: if( rc==SQLITE_OK ) rc = rc2;
10456: return rc;
10457: }
10458:
10459: /*
10460: ** xFilter method for sqlite_dbdata and sqlite_dbptr.
10461: */
10462: static int dbdataFilter(
10463: sqlite3_vtab_cursor *pCursor,
10464: int idxNum, const char *idxStr,
10465: int argc, sqlite3_value **argv
10466: ){
10467: DbdataCursor *pCsr = (DbdataCursor*)pCursor;
10468: DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
10469: int rc = SQLITE_OK;
10470: const char *zSchema = "main";
10471:
10472: dbdataResetCursor(pCsr);
10473: assert( pCsr->iPgno==1 );
10474: if( idxNum & 0x01 ){
10475: zSchema = (const char*)sqlite3_value_text(argv[0]);
10476: }
10477: if( idxNum & 0x02 ){
10478: pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
10479: pCsr->bOnePage = 1;
10480: }else{
10481: pCsr->nPage = dbdataDbsize(pCsr, zSchema);
10482: rc = dbdataDbsize(pCsr, zSchema);
10483: }
10484:
10485: if( rc==SQLITE_OK ){
10486: if( pTab->pStmt ){
10487: pCsr->pStmt = pTab->pStmt;
10488: pTab->pStmt = 0;
10489: }else{
10490: rc = sqlite3_prepare_v2(pTab->db,
10491: "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
10492: &pCsr->pStmt, 0
10493: );
10494: }
10495: }
10496: if( rc==SQLITE_OK ){
10497: rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
10498: }else{
10499: pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
10500: }
10501: if( rc==SQLITE_OK ){
10502: rc = dbdataNext(pCursor);
10503: }
10504: return rc;
10505: }
10506:
10507: /*
10508: ** Return a column for the sqlite_dbdata or sqlite_dbptr table.
10509: */
10510: static int dbdataColumn(
10511: sqlite3_vtab_cursor *pCursor,
10512: sqlite3_context *ctx,
10513: int i
10514: ){
10515: DbdataCursor *pCsr = (DbdataCursor*)pCursor;
10516: DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
10517: if( pTab->bPtr ){
10518: switch( i ){
10519: case DBPTR_COLUMN_PGNO:
10520: sqlite3_result_int64(ctx, pCsr->iPgno);
10521: break;
10522: case DBPTR_COLUMN_CHILD: {
10523: int iOff = pCsr->iPgno==1 ? 100 : 0;
10524: if( pCsr->iCell<0 ){
10525: iOff += 8;
10526: }else{
10527: iOff += 12 + pCsr->iCell*2;
10528: if( iOff>pCsr->nPage ) return SQLITE_OK;
10529: iOff = get_uint16(&pCsr->aPage[iOff]);
10530: }
10531: if( iOff<=pCsr->nPage ){
10532: sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
10533: }
10534: break;
10535: }
10536: }
10537: }else{
10538: switch( i ){
10539: case DBDATA_COLUMN_PGNO:
10540: sqlite3_result_int64(ctx, pCsr->iPgno);
10541: break;
10542: case DBDATA_COLUMN_CELL:
10543: sqlite3_result_int(ctx, pCsr->iCell);
10544: break;
10545: case DBDATA_COLUMN_FIELD:
10546: sqlite3_result_int(ctx, pCsr->iField);
10547: break;
10548: case DBDATA_COLUMN_VALUE: {
10549: if( pCsr->iField<0 ){
10550: sqlite3_result_int64(ctx, pCsr->iIntkey);
10551: }else{
10552: sqlite3_int64 iType;
10553: dbdataGetVarint(pCsr->pHdrPtr, &iType);
10554: dbdataValue(
10555: ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
10556: );
10557: }
10558: break;
10559: }
10560: }
10561: }
10562: return SQLITE_OK;
10563: }
10564:
10565: /*
10566: ** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
10567: */
10568: static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
10569: DbdataCursor *pCsr = (DbdataCursor*)pCursor;
10570: *pRowid = pCsr->iRowid;
10571: return SQLITE_OK;
10572: }
10573:
10574:
10575: /*
10576: ** Invoke this routine to register the "sqlite_dbdata" virtual table module
10577: */
10578: static int sqlite3DbdataRegister(sqlite3 *db){
10579: static sqlite3_module dbdata_module = {
10580: 0, /* iVersion */
10581: 0, /* xCreate */
10582: dbdataConnect, /* xConnect */
10583: dbdataBestIndex, /* xBestIndex */
10584: dbdataDisconnect, /* xDisconnect */
10585: 0, /* xDestroy */
10586: dbdataOpen, /* xOpen - open a cursor */
10587: dbdataClose, /* xClose - close a cursor */
10588: dbdataFilter, /* xFilter - configure scan constraints */
10589: dbdataNext, /* xNext - advance a cursor */
10590: dbdataEof, /* xEof - check for end of scan */
10591: dbdataColumn, /* xColumn - read data */
10592: dbdataRowid, /* xRowid - read data */
10593: 0, /* xUpdate */
10594: 0, /* xBegin */
10595: 0, /* xSync */
10596: 0, /* xCommit */
10597: 0, /* xRollback */
10598: 0, /* xFindMethod */
10599: 0, /* xRename */
10600: 0, /* xSavepoint */
10601: 0, /* xRelease */
10602: 0, /* xRollbackTo */
10603: 0 /* xShadowName */
10604: };
10605:
10606: int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
10607: if( rc==SQLITE_OK ){
10608: rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
10609: }
10610: return rc;
10611: }
10612:
10613: #ifdef _WIN32
10614:
10615: #endif
10616: int sqlite3_dbdata_init(
10617: sqlite3 *db,
10618: char **pzErrMsg,
10619: const sqlite3_api_routines *pApi
10620: ){
10621: SQLITE_EXTENSION_INIT2(pApi);
10622: return sqlite3DbdataRegister(db);
10623: }
10624:
10625: /************************* End ../ext/misc/dbdata.c ********************/
10626: #endif
10627:
10628: #if defined(SQLITE_ENABLE_SESSION)
10629: /*
10630: ** State information for a single open session
10631: */
10632: typedef struct OpenSession OpenSession;
10633: struct OpenSession {
10634: char *zName; /* Symbolic name for this session */
10635: int nFilter; /* Number of xFilter rejection GLOB patterns */
10636: char **azFilter; /* Array of xFilter rejection GLOB patterns */
10637: sqlite3_session *p; /* The open session */
10638: };
10639: #endif
10640:
10641: typedef struct ExpertInfo ExpertInfo;
10642: struct ExpertInfo {
10643: sqlite3expert *pExpert;
10644: int bVerbose;
10645: };
10646:
10647: /* A single line in the EQP output */
10648: typedef struct EQPGraphRow EQPGraphRow;
10649: struct EQPGraphRow {
10650: int iEqpId; /* ID for this row */
10651: int iParentId; /* ID of the parent row */
10652: EQPGraphRow *pNext; /* Next row in sequence */
10653: char zText[1]; /* Text to display for this row */
10654: };
10655:
10656: /* All EQP output is collected into an instance of the following */
10657: typedef struct EQPGraph EQPGraph;
10658: struct EQPGraph {
10659: EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
10660: EQPGraphRow *pLast; /* Last element of the pRow list */
10661: char zPrefix[100]; /* Graph prefix */
10662: };
10663:
10664: /*
10665: ** State information about the database connection is contained in an
10666: ** instance of the following structure.
10667: */
10668: typedef struct ShellState ShellState;
10669: struct ShellState {
10670: sqlite3 *db; /* The database */
10671: u8 autoExplain; /* Automatically turn on .explain mode */
10672: u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
10673: u8 autoEQPtest; /* autoEQP is in test mode */
10674: u8 autoEQPtrace; /* autoEQP is in trace mode */
10675: u8 statsOn; /* True to display memory stats before each finalize */
10676: u8 scanstatsOn; /* True to display scan stats before each finalize */
10677: u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
10678: u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
10679: u8 nEqpLevel; /* Depth of the EQP output graph */
10680: u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
10681: unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
10682: int outCount; /* Revert to stdout when reaching zero */
10683: int cnt; /* Number of records displayed so far */
10684: int lineno; /* Line number of last line read from in */
1.4.2.3 ! misho 10685: int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
1.4.2.2 misho 10686: FILE *in; /* Read commands from this stream */
10687: FILE *out; /* Write results here */
10688: FILE *traceOut; /* Output for sqlite3_trace() */
10689: int nErr; /* Number of errors seen */
10690: int mode; /* An output mode setting */
10691: int modePrior; /* Saved mode */
10692: int cMode; /* temporary output mode for the current query */
10693: int normalMode; /* Output mode before ".explain on" */
10694: int writableSchema; /* True if PRAGMA writable_schema=ON */
10695: int showHeader; /* True to show column names in List or Column mode */
10696: int nCheck; /* Number of ".check" commands run */
10697: unsigned nProgress; /* Number of progress callbacks encountered */
10698: unsigned mxProgress; /* Maximum progress callbacks before failing */
10699: unsigned flgProgress; /* Flags for the progress callback */
10700: unsigned shellFlgs; /* Various flags */
1.4.2.3 ! misho 10701: unsigned priorShFlgs; /* Saved copy of flags */
1.4.2.2 misho 10702: sqlite3_int64 szMax; /* --maxsize argument to .open */
10703: char *zDestTable; /* Name of destination table when MODE_Insert */
10704: char *zTempFile; /* Temporary file that might need deleting */
10705: char zTestcase[30]; /* Name of current test case */
10706: char colSeparator[20]; /* Column separator character for several modes */
10707: char rowSeparator[20]; /* Row separator character for MODE_Ascii */
10708: char colSepPrior[20]; /* Saved column separator */
10709: char rowSepPrior[20]; /* Saved row separator */
1.4.2.3 ! misho 10710: int *colWidth; /* Requested width of each column in columnar modes */
! 10711: int *actualWidth; /* Actual width of each column */
! 10712: int nWidth; /* Number of slots in colWidth[] and actualWidth[] */
1.4.2.2 misho 10713: char nullValue[20]; /* The text to print when a NULL comes back from
10714: ** the database */
10715: char outfile[FILENAME_MAX]; /* Filename for *out */
10716: const char *zDbFilename; /* name of the database file */
10717: char *zFreeOnClose; /* Filename to free when closing */
10718: const char *zVfs; /* Name of VFS to use */
10719: sqlite3_stmt *pStmt; /* Current statement if any. */
10720: FILE *pLog; /* Write log output here */
10721: int *aiIndent; /* Array of indents used in MODE_Explain */
10722: int nIndent; /* Size of array aiIndent[] */
10723: int iIndent; /* Index of current op in aiIndent[] */
10724: EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
10725: #if defined(SQLITE_ENABLE_SESSION)
10726: int nSession; /* Number of active sessions */
10727: OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
10728: #endif
10729: ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
10730: };
10731:
10732:
10733: /* Allowed values for ShellState.autoEQP
10734: */
10735: #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
10736: #define AUTOEQP_on 1 /* Automatic EQP is on */
10737: #define AUTOEQP_trigger 2 /* On and also show plans for triggers */
10738: #define AUTOEQP_full 3 /* Show full EXPLAIN */
10739:
10740: /* Allowed values for ShellState.openMode
10741: */
10742: #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
10743: #define SHELL_OPEN_NORMAL 1 /* Normal database file */
10744: #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
10745: #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
10746: #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
10747: #define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
10748: #define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */
10749:
10750: /* Allowed values for ShellState.eTraceType
10751: */
10752: #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */
10753: #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */
10754: #define SHELL_TRACE_NORMALIZED 2 /* Show normalized SQL text */
10755:
10756: /* Bits in the ShellState.flgProgress variable */
10757: #define SHELL_PROGRESS_QUIET 0x01 /* Omit announcing every progress callback */
10758: #define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progres
10759: ** callback limit is reached, and for each
10760: ** top-level SQL statement */
10761: #define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */
10762:
10763: /*
10764: ** These are the allowed shellFlgs values
10765: */
10766: #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
10767: #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
10768: #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
10769: #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
10770: #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
10771: #define SHFLG_CountChanges 0x00000020 /* .changes setting */
10772: #define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
1.4.2.3 ! misho 10773: #define SHFLG_HeaderSet 0x00000080 /* .header has been used */
1.4.2.2 misho 10774:
10775: /*
10776: ** Macros for testing and setting shellFlgs
10777: */
10778: #define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
10779: #define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
10780: #define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
10781:
10782: /*
10783: ** These are the allowed modes.
10784: */
10785: #define MODE_Line 0 /* One column per line. Blank line between records */
10786: #define MODE_Column 1 /* One record per line in neat columns */
10787: #define MODE_List 2 /* One record per line with a separator */
10788: #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
10789: #define MODE_Html 4 /* Generate an XHTML table */
10790: #define MODE_Insert 5 /* Generate SQL "insert" statements */
10791: #define MODE_Quote 6 /* Quote values as for SQL */
10792: #define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
10793: #define MODE_Csv 8 /* Quote strings, numbers are plain */
10794: #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
10795: #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
10796: #define MODE_Pretty 11 /* Pretty-print schemas */
10797: #define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
1.4.2.3 ! misho 10798: #define MODE_Json 13 /* Output JSON */
! 10799: #define MODE_Markdown 14 /* Markdown formatting */
! 10800: #define MODE_Table 15 /* MySQL-style table formatting */
! 10801: #define MODE_Box 16 /* Unicode box-drawing characters */
1.4.2.2 misho 10802:
10803: static const char *modeDescr[] = {
10804: "line",
10805: "column",
10806: "list",
10807: "semi",
10808: "html",
10809: "insert",
10810: "quote",
10811: "tcl",
10812: "csv",
10813: "explain",
10814: "ascii",
10815: "prettyprint",
1.4.2.3 ! misho 10816: "eqp",
! 10817: "json",
! 10818: "markdown",
! 10819: "table",
! 10820: "box"
1.4.2.2 misho 10821: };
10822:
10823: /*
10824: ** These are the column/row/line separators used by the various
10825: ** import/export modes.
10826: */
10827: #define SEP_Column "|"
10828: #define SEP_Row "\n"
10829: #define SEP_Tab "\t"
10830: #define SEP_Space " "
10831: #define SEP_Comma ","
10832: #define SEP_CrLf "\r\n"
10833: #define SEP_Unit "\x1F"
10834: #define SEP_Record "\x1E"
10835:
10836: /*
10837: ** A callback for the sqlite3_log() interface.
10838: */
10839: static void shellLog(void *pArg, int iErrCode, const char *zMsg){
10840: ShellState *p = (ShellState*)pArg;
10841: if( p->pLog==0 ) return;
10842: utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
10843: fflush(p->pLog);
10844: }
10845:
10846: /*
10847: ** SQL function: shell_putsnl(X)
10848: **
10849: ** Write the text X to the screen (or whatever output is being directed)
10850: ** adding a newline at the end, and then return X.
10851: */
10852: static void shellPutsFunc(
10853: sqlite3_context *pCtx,
10854: int nVal,
10855: sqlite3_value **apVal
10856: ){
10857: ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
10858: (void)nVal;
10859: utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
10860: sqlite3_result_value(pCtx, apVal[0]);
10861: }
10862:
10863: /*
10864: ** SQL function: edit(VALUE)
10865: ** edit(VALUE,EDITOR)
10866: **
10867: ** These steps:
10868: **
10869: ** (1) Write VALUE into a temporary file.
10870: ** (2) Run program EDITOR on that temporary file.
10871: ** (3) Read the temporary file back and return its content as the result.
10872: ** (4) Delete the temporary file
10873: **
10874: ** If the EDITOR argument is omitted, use the value in the VISUAL
10875: ** environment variable. If still there is no EDITOR, through an error.
10876: **
10877: ** Also throw an error if the EDITOR program returns a non-zero exit code.
10878: */
10879: #ifndef SQLITE_NOHAVE_SYSTEM
10880: static void editFunc(
10881: sqlite3_context *context,
10882: int argc,
10883: sqlite3_value **argv
10884: ){
10885: const char *zEditor;
10886: char *zTempFile = 0;
10887: sqlite3 *db;
10888: char *zCmd = 0;
10889: int bBin;
10890: int rc;
10891: int hasCRNL = 0;
10892: FILE *f = 0;
10893: sqlite3_int64 sz;
10894: sqlite3_int64 x;
10895: unsigned char *p = 0;
10896:
10897: if( argc==2 ){
10898: zEditor = (const char*)sqlite3_value_text(argv[1]);
10899: }else{
10900: zEditor = getenv("VISUAL");
10901: }
10902: if( zEditor==0 ){
10903: sqlite3_result_error(context, "no editor for edit()", -1);
10904: return;
10905: }
10906: if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
10907: sqlite3_result_error(context, "NULL input to edit()", -1);
10908: return;
10909: }
10910: db = sqlite3_context_db_handle(context);
10911: zTempFile = 0;
10912: sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile);
10913: if( zTempFile==0 ){
10914: sqlite3_uint64 r = 0;
10915: sqlite3_randomness(sizeof(r), &r);
10916: zTempFile = sqlite3_mprintf("temp%llx", r);
10917: if( zTempFile==0 ){
10918: sqlite3_result_error_nomem(context);
10919: return;
10920: }
10921: }
10922: bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB;
10923: /* When writing the file to be edited, do \n to \r\n conversions on systems
10924: ** that want \r\n line endings */
10925: f = fopen(zTempFile, bBin ? "wb" : "w");
10926: if( f==0 ){
10927: sqlite3_result_error(context, "edit() cannot open temp file", -1);
10928: goto edit_func_end;
10929: }
10930: sz = sqlite3_value_bytes(argv[0]);
10931: if( bBin ){
1.4.2.3 ! misho 10932: x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f);
1.4.2.2 misho 10933: }else{
10934: const char *z = (const char*)sqlite3_value_text(argv[0]);
10935: /* Remember whether or not the value originally contained \r\n */
10936: if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
1.4.2.3 ! misho 10937: x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f);
1.4.2.2 misho 10938: }
10939: fclose(f);
10940: f = 0;
10941: if( x!=sz ){
10942: sqlite3_result_error(context, "edit() could not write the whole file", -1);
10943: goto edit_func_end;
10944: }
10945: zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile);
10946: if( zCmd==0 ){
10947: sqlite3_result_error_nomem(context);
10948: goto edit_func_end;
10949: }
10950: rc = system(zCmd);
10951: sqlite3_free(zCmd);
10952: if( rc ){
10953: sqlite3_result_error(context, "EDITOR returned non-zero", -1);
10954: goto edit_func_end;
10955: }
10956: f = fopen(zTempFile, "rb");
10957: if( f==0 ){
10958: sqlite3_result_error(context,
10959: "edit() cannot reopen temp file after edit", -1);
10960: goto edit_func_end;
10961: }
10962: fseek(f, 0, SEEK_END);
10963: sz = ftell(f);
10964: rewind(f);
1.4.2.3 ! misho 10965: p = sqlite3_malloc64( sz+1 );
1.4.2.2 misho 10966: if( p==0 ){
10967: sqlite3_result_error_nomem(context);
10968: goto edit_func_end;
10969: }
1.4.2.3 ! misho 10970: x = fread(p, 1, (size_t)sz, f);
1.4.2.2 misho 10971: fclose(f);
10972: f = 0;
10973: if( x!=sz ){
10974: sqlite3_result_error(context, "could not read back the whole file", -1);
10975: goto edit_func_end;
10976: }
10977: if( bBin ){
10978: sqlite3_result_blob64(context, p, sz, sqlite3_free);
10979: }else{
10980: sqlite3_int64 i, j;
10981: if( hasCRNL ){
10982: /* If the original contains \r\n then do no conversions back to \n */
10983: j = sz;
10984: }else{
10985: /* If the file did not originally contain \r\n then convert any new
10986: ** \r\n back into \n */
10987: for(i=j=0; i<sz; i++){
10988: if( p[i]=='\r' && p[i+1]=='\n' ) i++;
10989: p[j++] = p[i];
10990: }
10991: sz = j;
10992: p[sz] = 0;
10993: }
10994: sqlite3_result_text64(context, (const char*)p, sz,
10995: sqlite3_free, SQLITE_UTF8);
10996: }
10997: p = 0;
10998:
10999: edit_func_end:
11000: if( f ) fclose(f);
11001: unlink(zTempFile);
11002: sqlite3_free(zTempFile);
11003: sqlite3_free(p);
11004: }
11005: #endif /* SQLITE_NOHAVE_SYSTEM */
11006:
11007: /*
11008: ** Save or restore the current output mode
11009: */
11010: static void outputModePush(ShellState *p){
11011: p->modePrior = p->mode;
1.4.2.3 ! misho 11012: p->priorShFlgs = p->shellFlgs;
1.4.2.2 misho 11013: memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
11014: memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
11015: }
11016: static void outputModePop(ShellState *p){
11017: p->mode = p->modePrior;
1.4.2.3 ! misho 11018: p->shellFlgs = p->priorShFlgs;
1.4.2.2 misho 11019: memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
11020: memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
11021: }
11022:
11023: /*
11024: ** Output the given string as a hex-encoded blob (eg. X'1234' )
11025: */
11026: static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
11027: int i;
11028: char *zBlob = (char *)pBlob;
11029: raw_printf(out,"X'");
11030: for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
11031: raw_printf(out,"'");
11032: }
11033:
11034: /*
11035: ** Find a string that is not found anywhere in z[]. Return a pointer
11036: ** to that string.
11037: **
11038: ** Try to use zA and zB first. If both of those are already found in z[]
11039: ** then make up some string and store it in the buffer zBuf.
11040: */
11041: static const char *unused_string(
11042: const char *z, /* Result must not appear anywhere in z */
11043: const char *zA, const char *zB, /* Try these first */
11044: char *zBuf /* Space to store a generated string */
11045: ){
11046: unsigned i = 0;
11047: if( strstr(z, zA)==0 ) return zA;
11048: if( strstr(z, zB)==0 ) return zB;
11049: do{
11050: sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
11051: }while( strstr(z,zBuf)!=0 );
11052: return zBuf;
11053: }
11054:
11055: /*
11056: ** Output the given string as a quoted string using SQL quoting conventions.
11057: **
11058: ** See also: output_quoted_escaped_string()
11059: */
11060: static void output_quoted_string(FILE *out, const char *z){
11061: int i;
11062: char c;
11063: setBinaryMode(out, 1);
11064: for(i=0; (c = z[i])!=0 && c!='\''; i++){}
11065: if( c==0 ){
11066: utf8_printf(out,"'%s'",z);
11067: }else{
11068: raw_printf(out, "'");
11069: while( *z ){
11070: for(i=0; (c = z[i])!=0 && c!='\''; i++){}
11071: if( c=='\'' ) i++;
11072: if( i ){
11073: utf8_printf(out, "%.*s", i, z);
11074: z += i;
11075: }
11076: if( c=='\'' ){
11077: raw_printf(out, "'");
11078: continue;
11079: }
11080: if( c==0 ){
11081: break;
11082: }
11083: z++;
11084: }
11085: raw_printf(out, "'");
11086: }
11087: setTextMode(out, 1);
11088: }
11089:
11090: /*
11091: ** Output the given string as a quoted string using SQL quoting conventions.
11092: ** Additionallly , escape the "\n" and "\r" characters so that they do not
11093: ** get corrupted by end-of-line translation facilities in some operating
11094: ** systems.
11095: **
11096: ** This is like output_quoted_string() but with the addition of the \r\n
11097: ** escape mechanism.
11098: */
11099: static void output_quoted_escaped_string(FILE *out, const char *z){
11100: int i;
11101: char c;
11102: setBinaryMode(out, 1);
11103: for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
11104: if( c==0 ){
11105: utf8_printf(out,"'%s'",z);
11106: }else{
11107: const char *zNL = 0;
11108: const char *zCR = 0;
11109: int nNL = 0;
11110: int nCR = 0;
11111: char zBuf1[20], zBuf2[20];
11112: for(i=0; z[i]; i++){
11113: if( z[i]=='\n' ) nNL++;
11114: if( z[i]=='\r' ) nCR++;
11115: }
11116: if( nNL ){
11117: raw_printf(out, "replace(");
11118: zNL = unused_string(z, "\\n", "\\012", zBuf1);
11119: }
11120: if( nCR ){
11121: raw_printf(out, "replace(");
11122: zCR = unused_string(z, "\\r", "\\015", zBuf2);
11123: }
11124: raw_printf(out, "'");
11125: while( *z ){
11126: for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
11127: if( c=='\'' ) i++;
11128: if( i ){
11129: utf8_printf(out, "%.*s", i, z);
11130: z += i;
11131: }
11132: if( c=='\'' ){
11133: raw_printf(out, "'");
11134: continue;
11135: }
11136: if( c==0 ){
11137: break;
11138: }
11139: z++;
11140: if( c=='\n' ){
11141: raw_printf(out, "%s", zNL);
11142: continue;
11143: }
11144: raw_printf(out, "%s", zCR);
11145: }
11146: raw_printf(out, "'");
11147: if( nCR ){
11148: raw_printf(out, ",'%s',char(13))", zCR);
11149: }
11150: if( nNL ){
11151: raw_printf(out, ",'%s',char(10))", zNL);
11152: }
11153: }
11154: setTextMode(out, 1);
11155: }
11156:
11157: /*
11158: ** Output the given string as a quoted according to C or TCL quoting rules.
11159: */
11160: static void output_c_string(FILE *out, const char *z){
11161: unsigned int c;
11162: fputc('"', out);
11163: while( (c = *(z++))!=0 ){
11164: if( c=='\\' ){
11165: fputc(c, out);
11166: fputc(c, out);
11167: }else if( c=='"' ){
11168: fputc('\\', out);
11169: fputc('"', out);
11170: }else if( c=='\t' ){
11171: fputc('\\', out);
11172: fputc('t', out);
11173: }else if( c=='\n' ){
11174: fputc('\\', out);
11175: fputc('n', out);
11176: }else if( c=='\r' ){
11177: fputc('\\', out);
11178: fputc('r', out);
11179: }else if( !isprint(c&0xff) ){
11180: raw_printf(out, "\\%03o", c&0xff);
11181: }else{
11182: fputc(c, out);
11183: }
11184: }
11185: fputc('"', out);
11186: }
11187:
11188: /*
1.4.2.3 ! misho 11189: ** Output the given string as a quoted according to JSON quoting rules.
! 11190: */
! 11191: static void output_json_string(FILE *out, const char *z, int n){
! 11192: unsigned int c;
! 11193: if( n<0 ) n = (int)strlen(z);
! 11194: fputc('"', out);
! 11195: while( n-- ){
! 11196: c = *(z++);
! 11197: if( c=='\\' || c=='"' ){
! 11198: fputc('\\', out);
! 11199: fputc(c, out);
! 11200: }else if( c<=0x1f ){
! 11201: fputc('\\', out);
! 11202: if( c=='\b' ){
! 11203: fputc('b', out);
! 11204: }else if( c=='\f' ){
! 11205: fputc('f', out);
! 11206: }else if( c=='\n' ){
! 11207: fputc('n', out);
! 11208: }else if( c=='\r' ){
! 11209: fputc('r', out);
! 11210: }else if( c=='\t' ){
! 11211: fputc('t', out);
! 11212: }else{
! 11213: raw_printf(out, "u%04x",c);
! 11214: }
! 11215: }else{
! 11216: fputc(c, out);
! 11217: }
! 11218: }
! 11219: fputc('"', out);
! 11220: }
! 11221:
! 11222: /*
1.4.2.2 misho 11223: ** Output the given string with characters that are special to
11224: ** HTML escaped.
11225: */
11226: static void output_html_string(FILE *out, const char *z){
11227: int i;
11228: if( z==0 ) z = "";
11229: while( *z ){
11230: for(i=0; z[i]
11231: && z[i]!='<'
11232: && z[i]!='&'
11233: && z[i]!='>'
11234: && z[i]!='\"'
11235: && z[i]!='\'';
11236: i++){}
11237: if( i>0 ){
11238: utf8_printf(out,"%.*s",i,z);
11239: }
11240: if( z[i]=='<' ){
11241: raw_printf(out,"<");
11242: }else if( z[i]=='&' ){
11243: raw_printf(out,"&");
11244: }else if( z[i]=='>' ){
11245: raw_printf(out,">");
11246: }else if( z[i]=='\"' ){
11247: raw_printf(out,""");
11248: }else if( z[i]=='\'' ){
11249: raw_printf(out,"'");
11250: }else{
11251: break;
11252: }
11253: z += i + 1;
11254: }
11255: }
11256:
11257: /*
11258: ** If a field contains any character identified by a 1 in the following
11259: ** array, then the string must be quoted for CSV.
11260: */
11261: static const char needCsvQuote[] = {
11262: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11263: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11264: 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
11265: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11266: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11267: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11268: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11269: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
11270: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11271: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11272: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11273: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11274: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11275: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11276: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11277: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
11278: };
11279:
11280: /*
11281: ** Output a single term of CSV. Actually, p->colSeparator is used for
11282: ** the separator, which may or may not be a comma. p->nullValue is
11283: ** the null value. Strings are quoted if necessary. The separator
11284: ** is only issued if bSep is true.
11285: */
11286: static void output_csv(ShellState *p, const char *z, int bSep){
11287: FILE *out = p->out;
11288: if( z==0 ){
11289: utf8_printf(out,"%s",p->nullValue);
11290: }else{
11291: int i;
11292: int nSep = strlen30(p->colSeparator);
11293: for(i=0; z[i]; i++){
11294: if( needCsvQuote[((unsigned char*)z)[i]]
11295: || (z[i]==p->colSeparator[0] &&
11296: (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
11297: i = 0;
11298: break;
11299: }
11300: }
11301: if( i==0 ){
11302: char *zQuoted = sqlite3_mprintf("\"%w\"", z);
11303: utf8_printf(out, "%s", zQuoted);
11304: sqlite3_free(zQuoted);
11305: }else{
11306: utf8_printf(out, "%s", z);
11307: }
11308: }
11309: if( bSep ){
11310: utf8_printf(p->out, "%s", p->colSeparator);
11311: }
11312: }
11313:
11314: /*
11315: ** This routine runs when the user presses Ctrl-C
11316: */
11317: static void interrupt_handler(int NotUsed){
11318: UNUSED_PARAMETER(NotUsed);
11319: seenInterrupt++;
11320: if( seenInterrupt>2 ) exit(1);
11321: if( globalDb ) sqlite3_interrupt(globalDb);
11322: }
11323:
11324: #if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
11325: /*
11326: ** This routine runs for console events (e.g. Ctrl-C) on Win32
11327: */
11328: static BOOL WINAPI ConsoleCtrlHandler(
11329: DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */
11330: ){
11331: if( dwCtrlType==CTRL_C_EVENT ){
11332: interrupt_handler(0);
11333: return TRUE;
11334: }
11335: return FALSE;
11336: }
11337: #endif
11338:
11339: #ifndef SQLITE_OMIT_AUTHORIZATION
11340: /*
11341: ** When the ".auth ON" is set, the following authorizer callback is
11342: ** invoked. It always returns SQLITE_OK.
11343: */
11344: static int shellAuth(
11345: void *pClientData,
11346: int op,
11347: const char *zA1,
11348: const char *zA2,
11349: const char *zA3,
11350: const char *zA4
11351: ){
11352: ShellState *p = (ShellState*)pClientData;
11353: static const char *azAction[] = { 0,
11354: "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
11355: "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
11356: "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
11357: "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
11358: "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
11359: "DROP_TRIGGER", "DROP_VIEW", "INSERT",
11360: "PRAGMA", "READ", "SELECT",
11361: "TRANSACTION", "UPDATE", "ATTACH",
11362: "DETACH", "ALTER_TABLE", "REINDEX",
11363: "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
11364: "FUNCTION", "SAVEPOINT", "RECURSIVE"
11365: };
11366: int i;
11367: const char *az[4];
11368: az[0] = zA1;
11369: az[1] = zA2;
11370: az[2] = zA3;
11371: az[3] = zA4;
11372: utf8_printf(p->out, "authorizer: %s", azAction[op]);
11373: for(i=0; i<4; i++){
11374: raw_printf(p->out, " ");
11375: if( az[i] ){
11376: output_c_string(p->out, az[i]);
11377: }else{
11378: raw_printf(p->out, "NULL");
11379: }
11380: }
11381: raw_printf(p->out, "\n");
11382: return SQLITE_OK;
11383: }
11384: #endif
11385:
11386: /*
11387: ** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
11388: **
11389: ** This routine converts some CREATE TABLE statements for shadow tables
11390: ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
11391: */
11392: static void printSchemaLine(FILE *out, const char *z, const char *zTail){
11393: if( z==0 ) return;
11394: if( zTail==0 ) return;
11395: if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
11396: utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
11397: }else{
11398: utf8_printf(out, "%s%s", z, zTail);
11399: }
11400: }
11401: static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
11402: char c = z[n];
11403: z[n] = 0;
11404: printSchemaLine(out, z, zTail);
11405: z[n] = c;
11406: }
11407:
11408: /*
11409: ** Return true if string z[] has nothing but whitespace and comments to the
11410: ** end of the first line.
11411: */
11412: static int wsToEol(const char *z){
11413: int i;
11414: for(i=0; z[i]; i++){
11415: if( z[i]=='\n' ) return 1;
11416: if( IsSpace(z[i]) ) continue;
11417: if( z[i]=='-' && z[i+1]=='-' ) return 1;
11418: return 0;
11419: }
11420: return 1;
11421: }
11422:
11423: /*
11424: ** Add a new entry to the EXPLAIN QUERY PLAN data
11425: */
11426: static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
11427: EQPGraphRow *pNew;
11428: int nText = strlen30(zText);
11429: if( p->autoEQPtest ){
11430: utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
11431: }
11432: pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
11433: if( pNew==0 ) shell_out_of_memory();
11434: pNew->iEqpId = iEqpId;
11435: pNew->iParentId = p2;
11436: memcpy(pNew->zText, zText, nText+1);
11437: pNew->pNext = 0;
11438: if( p->sGraph.pLast ){
11439: p->sGraph.pLast->pNext = pNew;
11440: }else{
11441: p->sGraph.pRow = pNew;
11442: }
11443: p->sGraph.pLast = pNew;
11444: }
11445:
11446: /*
11447: ** Free and reset the EXPLAIN QUERY PLAN data that has been collected
11448: ** in p->sGraph.
11449: */
11450: static void eqp_reset(ShellState *p){
11451: EQPGraphRow *pRow, *pNext;
11452: for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
11453: pNext = pRow->pNext;
11454: sqlite3_free(pRow);
11455: }
11456: memset(&p->sGraph, 0, sizeof(p->sGraph));
11457: }
11458:
11459: /* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
11460: ** pOld, or return the first such line if pOld is NULL
11461: */
11462: static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
11463: EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
11464: while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
11465: return pRow;
11466: }
11467:
11468: /* Render a single level of the graph that has iEqpId as its parent. Called
11469: ** recursively to render sublevels.
11470: */
11471: static void eqp_render_level(ShellState *p, int iEqpId){
11472: EQPGraphRow *pRow, *pNext;
11473: int n = strlen30(p->sGraph.zPrefix);
11474: char *z;
11475: for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
11476: pNext = eqp_next_row(p, iEqpId, pRow);
11477: z = pRow->zText;
1.4.2.3 ! misho 11478: utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix,
! 11479: pNext ? "|--" : "`--", z);
1.4.2.2 misho 11480: if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
11481: memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
11482: eqp_render_level(p, pRow->iEqpId);
11483: p->sGraph.zPrefix[n] = 0;
11484: }
11485: }
11486: }
11487:
11488: /*
11489: ** Display and reset the EXPLAIN QUERY PLAN data
11490: */
11491: static void eqp_render(ShellState *p){
11492: EQPGraphRow *pRow = p->sGraph.pRow;
11493: if( pRow ){
11494: if( pRow->zText[0]=='-' ){
11495: if( pRow->pNext==0 ){
11496: eqp_reset(p);
11497: return;
11498: }
11499: utf8_printf(p->out, "%s\n", pRow->zText+3);
11500: p->sGraph.pRow = pRow->pNext;
11501: sqlite3_free(pRow);
11502: }else{
11503: utf8_printf(p->out, "QUERY PLAN\n");
11504: }
11505: p->sGraph.zPrefix[0] = 0;
11506: eqp_render_level(p, 0);
11507: eqp_reset(p);
11508: }
11509: }
11510:
11511: #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
11512: /*
11513: ** Progress handler callback.
11514: */
11515: static int progress_handler(void *pClientData) {
11516: ShellState *p = (ShellState*)pClientData;
11517: p->nProgress++;
11518: if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
11519: raw_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
11520: if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
11521: if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0;
11522: return 1;
11523: }
11524: if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
11525: raw_printf(p->out, "Progress %u\n", p->nProgress);
11526: }
11527: return 0;
11528: }
11529: #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
11530:
11531: /*
1.4.2.3 ! misho 11532: ** Print N dashes
! 11533: */
! 11534: static void print_dashes(FILE *out, int N){
! 11535: const char zDash[] = "--------------------------------------------------";
! 11536: const int nDash = sizeof(zDash) - 1;
! 11537: while( N>nDash ){
! 11538: fputs(zDash, out);
! 11539: N -= nDash;
! 11540: }
! 11541: raw_printf(out, "%.*s", N, zDash);
! 11542: }
! 11543:
! 11544: /*
! 11545: ** Print a markdown or table-style row separator using ascii-art
! 11546: */
! 11547: static void print_row_separator(
! 11548: ShellState *p,
! 11549: int nArg,
! 11550: const char *zSep
! 11551: ){
! 11552: int i;
! 11553: if( nArg>0 ){
! 11554: fputs(zSep, p->out);
! 11555: print_dashes(p->out, p->actualWidth[0]+2);
! 11556: for(i=1; i<nArg; i++){
! 11557: fputs(zSep, p->out);
! 11558: print_dashes(p->out, p->actualWidth[i]+2);
! 11559: }
! 11560: fputs(zSep, p->out);
! 11561: }
! 11562: fputs("\n", p->out);
! 11563: }
! 11564:
! 11565: /*
1.4.2.2 misho 11566: ** This is the callback routine that the shell
11567: ** invokes for each row of a query result.
11568: */
11569: static int shell_callback(
11570: void *pArg,
11571: int nArg, /* Number of result columns */
11572: char **azArg, /* Text of each result column */
11573: char **azCol, /* Column names */
1.4.2.3 ! misho 11574: int *aiType /* Column types. Might be NULL */
1.4.2.2 misho 11575: ){
11576: int i;
11577: ShellState *p = (ShellState*)pArg;
11578:
11579: if( azArg==0 ) return 0;
11580: switch( p->cMode ){
11581: case MODE_Line: {
11582: int w = 5;
11583: if( azArg==0 ) break;
11584: for(i=0; i<nArg; i++){
11585: int len = strlen30(azCol[i] ? azCol[i] : "");
11586: if( len>w ) w = len;
11587: }
11588: if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
11589: for(i=0; i<nArg; i++){
11590: utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
11591: azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
11592: }
11593: break;
11594: }
1.4.2.3 ! misho 11595: case MODE_Explain: {
! 11596: static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
! 11597: if( nArg>ArraySize(aExplainWidth) ){
! 11598: nArg = ArraySize(aExplainWidth);
1.4.2.2 misho 11599: }
11600: if( p->cnt++==0 ){
11601: for(i=0; i<nArg; i++){
1.4.2.3 ! misho 11602: int w = aExplainWidth[i];
! 11603: utf8_width_print(p->out, w, azCol[i]);
! 11604: fputs(i==nArg-1 ? "\n" : " ", p->out);
1.4.2.2 misho 11605: }
1.4.2.3 ! misho 11606: for(i=0; i<nArg; i++){
! 11607: int w = aExplainWidth[i];
! 11608: print_dashes(p->out, w);
! 11609: fputs(i==nArg-1 ? "\n" : " ", p->out);
1.4.2.2 misho 11610: }
11611: }
11612: if( azArg==0 ) break;
11613: for(i=0; i<nArg; i++){
1.4.2.3 ! misho 11614: int w = aExplainWidth[i];
! 11615: if( azArg[i] && strlenChar(azArg[i])>w ){
1.4.2.2 misho 11616: w = strlenChar(azArg[i]);
11617: }
11618: if( i==1 && p->aiIndent && p->pStmt ){
11619: if( p->iIndent<p->nIndent ){
11620: utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
11621: }
11622: p->iIndent++;
11623: }
11624: utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
1.4.2.3 ! misho 11625: fputs(i==nArg-1 ? "\n" : " ", p->out);
1.4.2.2 misho 11626: }
11627: break;
11628: }
11629: case MODE_Semi: { /* .schema and .fullschema output */
11630: printSchemaLine(p->out, azArg[0], ";\n");
11631: break;
11632: }
11633: case MODE_Pretty: { /* .schema and .fullschema with --indent */
11634: char *z;
11635: int j;
11636: int nParen = 0;
11637: char cEnd = 0;
11638: char c;
11639: int nLine = 0;
11640: assert( nArg==1 );
11641: if( azArg[0]==0 ) break;
11642: if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
11643: || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
11644: ){
11645: utf8_printf(p->out, "%s;\n", azArg[0]);
11646: break;
11647: }
11648: z = sqlite3_mprintf("%s", azArg[0]);
11649: j = 0;
1.4 misho 11650: for(i=0; IsSpace(z[i]); i++){}
11651: for(; (c = z[i])!=0; i++){
11652: if( IsSpace(c) ){
1.4.2.2 misho 11653: if( z[j-1]=='\r' ) z[j-1] = '\n';
1.4 misho 11654: if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
11655: }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
11656: j--;
11657: }
1.4.2.2 misho 11658: z[j++] = c;
11659: }
11660: while( j>0 && IsSpace(z[j-1]) ){ j--; }
11661: z[j] = 0;
11662: if( strlen30(z)>=79 ){
1.4.2.3 ! misho 11663: for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
1.4.2.2 misho 11664: if( c==cEnd ){
11665: cEnd = 0;
11666: }else if( c=='"' || c=='\'' || c=='`' ){
11667: cEnd = c;
11668: }else if( c=='[' ){
11669: cEnd = ']';
11670: }else if( c=='-' && z[i+1]=='-' ){
11671: cEnd = '\n';
11672: }else if( c=='(' ){
11673: nParen++;
11674: }else if( c==')' ){
11675: nParen--;
11676: if( nLine>0 && nParen==0 && j>0 ){
11677: printSchemaLineN(p->out, z, j, "\n");
11678: j = 0;
11679: }
11680: }
11681: z[j++] = c;
11682: if( nParen==1 && cEnd==0
11683: && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
11684: ){
11685: if( c=='\n' ) j--;
11686: printSchemaLineN(p->out, z, j, "\n ");
11687: j = 0;
11688: nLine++;
11689: while( IsSpace(z[i+1]) ){ i++; }
11690: }
11691: }
11692: z[j] = 0;
11693: }
11694: printSchemaLine(p->out, z, ";\n");
11695: sqlite3_free(z);
11696: break;
11697: }
11698: case MODE_List: {
11699: if( p->cnt++==0 && p->showHeader ){
11700: for(i=0; i<nArg; i++){
11701: utf8_printf(p->out,"%s%s",azCol[i],
11702: i==nArg-1 ? p->rowSeparator : p->colSeparator);
11703: }
11704: }
11705: if( azArg==0 ) break;
11706: for(i=0; i<nArg; i++){
11707: char *z = azArg[i];
11708: if( z==0 ) z = p->nullValue;
11709: utf8_printf(p->out, "%s", z);
11710: if( i<nArg-1 ){
11711: utf8_printf(p->out, "%s", p->colSeparator);
11712: }else{
11713: utf8_printf(p->out, "%s", p->rowSeparator);
11714: }
11715: }
11716: break;
11717: }
11718: case MODE_Html: {
11719: if( p->cnt++==0 && p->showHeader ){
11720: raw_printf(p->out,"<TR>");
11721: for(i=0; i<nArg; i++){
11722: raw_printf(p->out,"<TH>");
11723: output_html_string(p->out, azCol[i]);
11724: raw_printf(p->out,"</TH>\n");
11725: }
11726: raw_printf(p->out,"</TR>\n");
11727: }
11728: if( azArg==0 ) break;
11729: raw_printf(p->out,"<TR>");
11730: for(i=0; i<nArg; i++){
11731: raw_printf(p->out,"<TD>");
11732: output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
11733: raw_printf(p->out,"</TD>\n");
11734: }
11735: raw_printf(p->out,"</TR>\n");
11736: break;
11737: }
11738: case MODE_Tcl: {
11739: if( p->cnt++==0 && p->showHeader ){
11740: for(i=0; i<nArg; i++){
11741: output_c_string(p->out,azCol[i] ? azCol[i] : "");
11742: if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
11743: }
11744: utf8_printf(p->out, "%s", p->rowSeparator);
11745: }
11746: if( azArg==0 ) break;
11747: for(i=0; i<nArg; i++){
11748: output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
11749: if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
11750: }
11751: utf8_printf(p->out, "%s", p->rowSeparator);
11752: break;
11753: }
11754: case MODE_Csv: {
11755: setBinaryMode(p->out, 1);
11756: if( p->cnt++==0 && p->showHeader ){
11757: for(i=0; i<nArg; i++){
11758: output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
11759: }
11760: utf8_printf(p->out, "%s", p->rowSeparator);
11761: }
11762: if( nArg>0 ){
11763: for(i=0; i<nArg; i++){
11764: output_csv(p, azArg[i], i<nArg-1);
11765: }
11766: utf8_printf(p->out, "%s", p->rowSeparator);
11767: }
11768: setTextMode(p->out, 1);
11769: break;
11770: }
11771: case MODE_Insert: {
11772: if( azArg==0 ) break;
11773: utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
11774: if( p->showHeader ){
11775: raw_printf(p->out,"(");
11776: for(i=0; i<nArg; i++){
11777: if( i>0 ) raw_printf(p->out, ",");
11778: if( quoteChar(azCol[i]) ){
11779: char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
11780: utf8_printf(p->out, "%s", z);
11781: sqlite3_free(z);
11782: }else{
11783: raw_printf(p->out, "%s", azCol[i]);
11784: }
11785: }
11786: raw_printf(p->out,")");
11787: }
11788: p->cnt++;
11789: for(i=0; i<nArg; i++){
11790: raw_printf(p->out, i>0 ? "," : " VALUES(");
11791: if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
11792: utf8_printf(p->out,"NULL");
11793: }else if( aiType && aiType[i]==SQLITE_TEXT ){
11794: if( ShellHasFlag(p, SHFLG_Newlines) ){
11795: output_quoted_string(p->out, azArg[i]);
11796: }else{
11797: output_quoted_escaped_string(p->out, azArg[i]);
11798: }
11799: }else if( aiType && aiType[i]==SQLITE_INTEGER ){
11800: utf8_printf(p->out,"%s", azArg[i]);
11801: }else if( aiType && aiType[i]==SQLITE_FLOAT ){
11802: char z[50];
11803: double r = sqlite3_column_double(p->pStmt, i);
11804: sqlite3_uint64 ur;
11805: memcpy(&ur,&r,sizeof(r));
11806: if( ur==0x7ff0000000000000LL ){
11807: raw_printf(p->out, "1e999");
11808: }else if( ur==0xfff0000000000000LL ){
11809: raw_printf(p->out, "-1e999");
11810: }else{
11811: sqlite3_snprintf(50,z,"%!.20g", r);
11812: raw_printf(p->out, "%s", z);
11813: }
11814: }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
11815: const void *pBlob = sqlite3_column_blob(p->pStmt, i);
11816: int nBlob = sqlite3_column_bytes(p->pStmt, i);
11817: output_hex_blob(p->out, pBlob, nBlob);
11818: }else if( isNumber(azArg[i], 0) ){
11819: utf8_printf(p->out,"%s", azArg[i]);
11820: }else if( ShellHasFlag(p, SHFLG_Newlines) ){
11821: output_quoted_string(p->out, azArg[i]);
11822: }else{
11823: output_quoted_escaped_string(p->out, azArg[i]);
11824: }
11825: }
11826: raw_printf(p->out,");\n");
11827: break;
11828: }
1.4.2.3 ! misho 11829: case MODE_Json: {
! 11830: if( azArg==0 ) break;
! 11831: if( p->cnt==0 ){
! 11832: fputs("[{", p->out);
! 11833: }else{
! 11834: fputs(",\n{", p->out);
! 11835: }
! 11836: p->cnt++;
! 11837: for(i=0; i<nArg; i++){
! 11838: output_json_string(p->out, azCol[i], -1);
! 11839: putc(':', p->out);
! 11840: if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
! 11841: fputs("null",p->out);
! 11842: }else if( aiType && aiType[i]==SQLITE_FLOAT ){
! 11843: char z[50];
! 11844: double r = sqlite3_column_double(p->pStmt, i);
! 11845: sqlite3_uint64 ur;
! 11846: memcpy(&ur,&r,sizeof(r));
! 11847: if( ur==0x7ff0000000000000LL ){
! 11848: raw_printf(p->out, "1e999");
! 11849: }else if( ur==0xfff0000000000000LL ){
! 11850: raw_printf(p->out, "-1e999");
! 11851: }else{
! 11852: sqlite3_snprintf(50,z,"%!.20g", r);
! 11853: raw_printf(p->out, "%s", z);
! 11854: }
! 11855: }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
! 11856: const void *pBlob = sqlite3_column_blob(p->pStmt, i);
! 11857: int nBlob = sqlite3_column_bytes(p->pStmt, i);
! 11858: output_json_string(p->out, pBlob, nBlob);
! 11859: }else if( aiType && aiType[i]==SQLITE_TEXT ){
! 11860: output_json_string(p->out, azArg[i], -1);
! 11861: }else{
! 11862: utf8_printf(p->out,"%s", azArg[i]);
! 11863: }
! 11864: if( i<nArg-1 ){
! 11865: putc(',', p->out);
! 11866: }
! 11867: }
! 11868: putc('}', p->out);
! 11869: break;
! 11870: }
1.4.2.2 misho 11871: case MODE_Quote: {
11872: if( azArg==0 ) break;
11873: if( p->cnt==0 && p->showHeader ){
11874: for(i=0; i<nArg; i++){
1.4.2.3 ! misho 11875: if( i>0 ) fputs(p->colSeparator, p->out);
1.4.2.2 misho 11876: output_quoted_string(p->out, azCol[i]);
11877: }
1.4.2.3 ! misho 11878: fputs(p->rowSeparator, p->out);
1.4.2.2 misho 11879: }
11880: p->cnt++;
11881: for(i=0; i<nArg; i++){
1.4.2.3 ! misho 11882: if( i>0 ) fputs(p->colSeparator, p->out);
1.4.2.2 misho 11883: if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
11884: utf8_printf(p->out,"NULL");
11885: }else if( aiType && aiType[i]==SQLITE_TEXT ){
11886: output_quoted_string(p->out, azArg[i]);
11887: }else if( aiType && aiType[i]==SQLITE_INTEGER ){
11888: utf8_printf(p->out,"%s", azArg[i]);
11889: }else if( aiType && aiType[i]==SQLITE_FLOAT ){
11890: char z[50];
11891: double r = sqlite3_column_double(p->pStmt, i);
11892: sqlite3_snprintf(50,z,"%!.20g", r);
11893: raw_printf(p->out, "%s", z);
11894: }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
11895: const void *pBlob = sqlite3_column_blob(p->pStmt, i);
11896: int nBlob = sqlite3_column_bytes(p->pStmt, i);
11897: output_hex_blob(p->out, pBlob, nBlob);
11898: }else if( isNumber(azArg[i], 0) ){
11899: utf8_printf(p->out,"%s", azArg[i]);
11900: }else{
11901: output_quoted_string(p->out, azArg[i]);
11902: }
11903: }
1.4.2.3 ! misho 11904: fputs(p->rowSeparator, p->out);
1.4.2.2 misho 11905: break;
11906: }
11907: case MODE_Ascii: {
11908: if( p->cnt++==0 && p->showHeader ){
11909: for(i=0; i<nArg; i++){
11910: if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
11911: utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
11912: }
11913: utf8_printf(p->out, "%s", p->rowSeparator);
11914: }
11915: if( azArg==0 ) break;
11916: for(i=0; i<nArg; i++){
11917: if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
11918: utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
11919: }
11920: utf8_printf(p->out, "%s", p->rowSeparator);
11921: break;
11922: }
11923: case MODE_EQP: {
11924: eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
11925: break;
11926: }
11927: }
11928: return 0;
11929: }
11930:
11931: /*
11932: ** This is the callback routine that the SQLite library
11933: ** invokes for each row of a query result.
11934: */
11935: static int callback(void *pArg, int nArg, char **azArg, char **azCol){
11936: /* since we don't have type info, call the shell_callback with a NULL value */
11937: return shell_callback(pArg, nArg, azArg, azCol, NULL);
11938: }
11939:
11940: /*
11941: ** This is the callback routine from sqlite3_exec() that appends all
11942: ** output onto the end of a ShellText object.
11943: */
11944: static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
11945: ShellText *p = (ShellText*)pArg;
11946: int i;
11947: UNUSED_PARAMETER(az);
11948: if( azArg==0 ) return 0;
11949: if( p->n ) appendText(p, "|", 0);
11950: for(i=0; i<nArg; i++){
11951: if( i ) appendText(p, ",", 0);
11952: if( azArg[i] ) appendText(p, azArg[i], 0);
11953: }
11954: return 0;
11955: }
11956:
11957: /*
11958: ** Generate an appropriate SELFTEST table in the main database.
11959: */
11960: static void createSelftestTable(ShellState *p){
11961: char *zErrMsg = 0;
11962: sqlite3_exec(p->db,
11963: "SAVEPOINT selftest_init;\n"
11964: "CREATE TABLE IF NOT EXISTS selftest(\n"
11965: " tno INTEGER PRIMARY KEY,\n" /* Test number */
11966: " op TEXT,\n" /* Operator: memo run */
11967: " cmd TEXT,\n" /* Command text */
11968: " ans TEXT\n" /* Desired answer */
11969: ");"
11970: "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n"
11971: "INSERT INTO [_shell$self](rowid,op,cmd)\n"
11972: " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n"
11973: " 'memo','Tests generated by --init');\n"
11974: "INSERT INTO [_shell$self]\n"
11975: " SELECT 'run',\n"
11976: " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql "
1.4.2.3 ! misho 11977: "FROM sqlite_schema ORDER BY 2'',224))',\n"
1.4.2.2 misho 11978: " hex(sha3_query('SELECT type,name,tbl_name,sql "
1.4.2.3 ! misho 11979: "FROM sqlite_schema ORDER BY 2',224));\n"
1.4.2.2 misho 11980: "INSERT INTO [_shell$self]\n"
11981: " SELECT 'run',"
11982: " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||"
11983: " printf('%w',name) || '\" NOT INDEXED'',224))',\n"
11984: " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n"
11985: " FROM (\n"
1.4.2.3 ! misho 11986: " SELECT name FROM sqlite_schema\n"
1.4.2.2 misho 11987: " WHERE type='table'\n"
11988: " AND name<>'selftest'\n"
11989: " AND coalesce(rootpage,0)>0\n"
11990: " )\n"
11991: " ORDER BY name;\n"
11992: "INSERT INTO [_shell$self]\n"
11993: " VALUES('run','PRAGMA integrity_check','ok');\n"
11994: "INSERT INTO selftest(tno,op,cmd,ans)"
11995: " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
11996: "DROP TABLE [_shell$self];"
11997: ,0,0,&zErrMsg);
11998: if( zErrMsg ){
11999: utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
12000: sqlite3_free(zErrMsg);
12001: }
12002: sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
12003: }
12004:
12005:
12006: /*
12007: ** Set the destination table field of the ShellState structure to
12008: ** the name of the table given. Escape any quote characters in the
12009: ** table name.
12010: */
12011: static void set_table_name(ShellState *p, const char *zName){
12012: int i, n;
12013: char cQuote;
12014: char *z;
12015:
12016: if( p->zDestTable ){
12017: free(p->zDestTable);
12018: p->zDestTable = 0;
12019: }
12020: if( zName==0 ) return;
12021: cQuote = quoteChar(zName);
12022: n = strlen30(zName);
12023: if( cQuote ) n += n+2;
12024: z = p->zDestTable = malloc( n+1 );
12025: if( z==0 ) shell_out_of_memory();
12026: n = 0;
12027: if( cQuote ) z[n++] = cQuote;
12028: for(i=0; zName[i]; i++){
12029: z[n++] = zName[i];
12030: if( zName[i]==cQuote ) z[n++] = cQuote;
12031: }
12032: if( cQuote ) z[n++] = cQuote;
12033: z[n] = 0;
12034: }
12035:
12036:
12037: /*
12038: ** Execute a query statement that will generate SQL output. Print
12039: ** the result columns, comma-separated, on a line and then add a
12040: ** semicolon terminator to the end of that line.
12041: **
12042: ** If the number of columns is 1 and that column contains text "--"
12043: ** then write the semicolon on a separate line. That way, if a
12044: ** "--" comment occurs at the end of the statement, the comment
12045: ** won't consume the semicolon terminator.
12046: */
12047: static int run_table_dump_query(
12048: ShellState *p, /* Query context */
1.4.2.3 ! misho 12049: const char *zSelect /* SELECT statement to extract content */
1.4.2.2 misho 12050: ){
12051: sqlite3_stmt *pSelect;
12052: int rc;
12053: int nResult;
12054: int i;
12055: const char *z;
12056: rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
12057: if( rc!=SQLITE_OK || !pSelect ){
12058: utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
12059: sqlite3_errmsg(p->db));
12060: if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
12061: return rc;
12062: }
12063: rc = sqlite3_step(pSelect);
12064: nResult = sqlite3_column_count(pSelect);
12065: while( rc==SQLITE_ROW ){
12066: z = (const char*)sqlite3_column_text(pSelect, 0);
12067: utf8_printf(p->out, "%s", z);
12068: for(i=1; i<nResult; i++){
12069: utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
12070: }
12071: if( z==0 ) z = "";
12072: while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
12073: if( z[0] ){
12074: raw_printf(p->out, "\n;\n");
12075: }else{
12076: raw_printf(p->out, ";\n");
12077: }
12078: rc = sqlite3_step(pSelect);
12079: }
12080: rc = sqlite3_finalize(pSelect);
12081: if( rc!=SQLITE_OK ){
12082: utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
12083: sqlite3_errmsg(p->db));
12084: if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
12085: }
12086: return rc;
12087: }
12088:
12089: /*
12090: ** Allocate space and save off current error string.
12091: */
12092: static char *save_err_msg(
12093: sqlite3 *db /* Database to query */
12094: ){
12095: int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
12096: char *zErrMsg = sqlite3_malloc64(nErrMsg);
12097: if( zErrMsg ){
12098: memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
12099: }
12100: return zErrMsg;
12101: }
12102:
12103: #ifdef __linux__
12104: /*
12105: ** Attempt to display I/O stats on Linux using /proc/PID/io
12106: */
12107: static void displayLinuxIoStats(FILE *out){
12108: FILE *in;
12109: char z[200];
12110: sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
12111: in = fopen(z, "rb");
12112: if( in==0 ) return;
12113: while( fgets(z, sizeof(z), in)!=0 ){
12114: static const struct {
12115: const char *zPattern;
12116: const char *zDesc;
12117: } aTrans[] = {
12118: { "rchar: ", "Bytes received by read():" },
12119: { "wchar: ", "Bytes sent to write():" },
12120: { "syscr: ", "Read() system calls:" },
12121: { "syscw: ", "Write() system calls:" },
12122: { "read_bytes: ", "Bytes read from storage:" },
12123: { "write_bytes: ", "Bytes written to storage:" },
12124: { "cancelled_write_bytes: ", "Cancelled write bytes:" },
12125: };
12126: int i;
12127: for(i=0; i<ArraySize(aTrans); i++){
12128: int n = strlen30(aTrans[i].zPattern);
12129: if( strncmp(aTrans[i].zPattern, z, n)==0 ){
12130: utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
12131: break;
12132: }
12133: }
12134: }
12135: fclose(in);
12136: }
12137: #endif
12138:
12139: /*
12140: ** Display a single line of status using 64-bit values.
12141: */
12142: static void displayStatLine(
12143: ShellState *p, /* The shell context */
12144: char *zLabel, /* Label for this one line */
12145: char *zFormat, /* Format for the result */
12146: int iStatusCtrl, /* Which status to display */
12147: int bReset /* True to reset the stats */
12148: ){
12149: sqlite3_int64 iCur = -1;
12150: sqlite3_int64 iHiwtr = -1;
12151: int i, nPercent;
12152: char zLine[200];
12153: sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset);
12154: for(i=0, nPercent=0; zFormat[i]; i++){
12155: if( zFormat[i]=='%' ) nPercent++;
12156: }
12157: if( nPercent>1 ){
12158: sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
12159: }else{
12160: sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
12161: }
12162: raw_printf(p->out, "%-36s %s\n", zLabel, zLine);
12163: }
12164:
12165: /*
12166: ** Display memory stats.
12167: */
12168: static int display_stats(
12169: sqlite3 *db, /* Database to query */
12170: ShellState *pArg, /* Pointer to ShellState */
12171: int bReset /* True to reset the stats */
12172: ){
12173: int iCur;
12174: int iHiwtr;
12175: FILE *out;
12176: if( pArg==0 || pArg->out==0 ) return 0;
12177: out = pArg->out;
12178:
12179: if( pArg->pStmt && (pArg->statsOn & 2) ){
12180: int nCol, i, x;
12181: sqlite3_stmt *pStmt = pArg->pStmt;
12182: char z[100];
12183: nCol = sqlite3_column_count(pStmt);
12184: raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
12185: for(i=0; i<nCol; i++){
12186: sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
12187: utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
12188: #ifndef SQLITE_OMIT_DECLTYPE
12189: sqlite3_snprintf(30, z+x, "declared type:");
12190: utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
12191: #endif
12192: #ifdef SQLITE_ENABLE_COLUMN_METADATA
12193: sqlite3_snprintf(30, z+x, "database name:");
12194: utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
12195: sqlite3_snprintf(30, z+x, "table name:");
12196: utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
12197: sqlite3_snprintf(30, z+x, "origin name:");
12198: utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
12199: #endif
12200: }
12201: }
12202:
12203: displayStatLine(pArg, "Memory Used:",
12204: "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
12205: displayStatLine(pArg, "Number of Outstanding Allocations:",
12206: "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
12207: if( pArg->shellFlgs & SHFLG_Pagecache ){
12208: displayStatLine(pArg, "Number of Pcache Pages Used:",
12209: "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
12210: }
12211: displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
12212: "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
12213: displayStatLine(pArg, "Largest Allocation:",
12214: "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
12215: displayStatLine(pArg, "Largest Pcache Allocation:",
12216: "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
12217: #ifdef YYTRACKMAXSTACKDEPTH
12218: displayStatLine(pArg, "Deepest Parser Stack:",
12219: "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
12220: #endif
12221:
12222: if( db ){
12223: if( pArg->shellFlgs & SHFLG_Lookaside ){
12224: iHiwtr = iCur = -1;
12225: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
12226: &iCur, &iHiwtr, bReset);
12227: raw_printf(pArg->out,
12228: "Lookaside Slots Used: %d (max %d)\n",
12229: iCur, iHiwtr);
12230: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
12231: &iCur, &iHiwtr, bReset);
12232: raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
12233: iHiwtr);
12234: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
12235: &iCur, &iHiwtr, bReset);
12236: raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
12237: iHiwtr);
12238: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
12239: &iCur, &iHiwtr, bReset);
12240: raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
12241: iHiwtr);
12242: }
12243: iHiwtr = iCur = -1;
12244: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
12245: raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
12246: iCur);
12247: iHiwtr = iCur = -1;
12248: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
12249: raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
12250: iHiwtr = iCur = -1;
12251: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
12252: raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
12253: iHiwtr = iCur = -1;
12254: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
12255: raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
12256: iHiwtr = iCur = -1;
12257: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
12258: raw_printf(pArg->out, "Page cache spills: %d\n", iCur);
12259: iHiwtr = iCur = -1;
12260: sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
12261: raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
12262: iCur);
12263: iHiwtr = iCur = -1;
12264: sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
12265: raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
12266: iCur);
12267: }
12268:
12269: if( pArg->pStmt ){
12270: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
12271: bReset);
12272: raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
12273: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
12274: raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
12275: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
12276: raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
12277: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
12278: raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
1.4.2.3 ! misho 12279: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
1.4.2.2 misho 12280: raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
12281: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
12282: raw_printf(pArg->out, "Number of times run: %d\n", iCur);
12283: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
12284: raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur);
12285: }
12286:
12287: #ifdef __linux__
12288: displayLinuxIoStats(pArg->out);
12289: #endif
12290:
12291: /* Do not remove this machine readable comment: extra-stats-output-here */
12292:
12293: return 0;
12294: }
12295:
12296: /*
12297: ** Display scan stats.
12298: */
12299: static void display_scanstats(
12300: sqlite3 *db, /* Database to query */
12301: ShellState *pArg /* Pointer to ShellState */
12302: ){
12303: #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
12304: UNUSED_PARAMETER(db);
12305: UNUSED_PARAMETER(pArg);
12306: #else
12307: int i, k, n, mx;
12308: raw_printf(pArg->out, "-------- scanstats --------\n");
12309: mx = 0;
12310: for(k=0; k<=mx; k++){
12311: double rEstLoop = 1.0;
12312: for(i=n=0; 1; i++){
12313: sqlite3_stmt *p = pArg->pStmt;
12314: sqlite3_int64 nLoop, nVisit;
12315: double rEst;
12316: int iSid;
12317: const char *zExplain;
12318: if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
12319: break;
12320: }
12321: sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
12322: if( iSid>mx ) mx = iSid;
12323: if( iSid!=k ) continue;
12324: if( n==0 ){
12325: rEstLoop = (double)nLoop;
12326: if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
12327: }
12328: n++;
12329: sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
12330: sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
12331: sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
12332: utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
12333: rEstLoop *= rEst;
12334: raw_printf(pArg->out,
12335: " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
12336: nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
12337: );
12338: }
12339: }
12340: raw_printf(pArg->out, "---------------------------\n");
12341: #endif
12342: }
12343:
12344: /*
12345: ** Parameter azArray points to a zero-terminated array of strings. zStr
12346: ** points to a single nul-terminated string. Return non-zero if zStr
12347: ** is equal, according to strcmp(), to any of the strings in the array.
12348: ** Otherwise, return zero.
12349: */
12350: static int str_in_array(const char *zStr, const char **azArray){
12351: int i;
12352: for(i=0; azArray[i]; i++){
12353: if( 0==strcmp(zStr, azArray[i]) ) return 1;
12354: }
12355: return 0;
12356: }
12357:
12358: /*
12359: ** If compiled statement pSql appears to be an EXPLAIN statement, allocate
12360: ** and populate the ShellState.aiIndent[] array with the number of
12361: ** spaces each opcode should be indented before it is output.
12362: **
12363: ** The indenting rules are:
12364: **
12365: ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
12366: ** all opcodes that occur between the p2 jump destination and the opcode
12367: ** itself by 2 spaces.
12368: **
12369: ** * For each "Goto", if the jump destination is earlier in the program
12370: ** and ends on one of:
12371: ** Yield SeekGt SeekLt RowSetRead Rewind
12372: ** or if the P1 parameter is one instead of zero,
12373: ** then indent all opcodes between the earlier instruction
12374: ** and "Goto" by 2 spaces.
12375: */
12376: static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
12377: const char *zSql; /* The text of the SQL statement */
12378: const char *z; /* Used to check if this is an EXPLAIN */
12379: int *abYield = 0; /* True if op is an OP_Yield */
12380: int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
12381: int iOp; /* Index of operation in p->aiIndent[] */
12382:
12383: const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
12384: const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
12385: "Rewind", 0 };
12386: const char *azGoto[] = { "Goto", 0 };
12387:
12388: /* Try to figure out if this is really an EXPLAIN statement. If this
12389: ** cannot be verified, return early. */
12390: if( sqlite3_column_count(pSql)!=8 ){
12391: p->cMode = p->mode;
12392: return;
12393: }
12394: zSql = sqlite3_sql(pSql);
12395: if( zSql==0 ) return;
12396: for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
12397: if( sqlite3_strnicmp(z, "explain", 7) ){
12398: p->cMode = p->mode;
12399: return;
12400: }
12401:
12402: for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
12403: int i;
12404: int iAddr = sqlite3_column_int(pSql, 0);
12405: const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
12406:
12407: /* Set p2 to the P2 field of the current opcode. Then, assuming that
12408: ** p2 is an instruction address, set variable p2op to the index of that
12409: ** instruction in the aiIndent[] array. p2 and p2op may be different if
12410: ** the current instruction is part of a sub-program generated by an
12411: ** SQL trigger or foreign key. */
12412: int p2 = sqlite3_column_int(pSql, 3);
12413: int p2op = (p2 + (iOp-iAddr));
12414:
12415: /* Grow the p->aiIndent array as required */
12416: if( iOp>=nAlloc ){
12417: if( iOp==0 ){
12418: /* Do further verfication that this is explain output. Abort if
12419: ** it is not */
12420: static const char *explainCols[] = {
12421: "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
12422: int jj;
12423: for(jj=0; jj<ArraySize(explainCols); jj++){
12424: if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
12425: p->cMode = p->mode;
12426: sqlite3_reset(pSql);
12427: return;
12428: }
12429: }
12430: }
12431: nAlloc += 100;
12432: p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
12433: if( p->aiIndent==0 ) shell_out_of_memory();
12434: abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
12435: if( abYield==0 ) shell_out_of_memory();
12436: }
12437: abYield[iOp] = str_in_array(zOp, azYield);
12438: p->aiIndent[iOp] = 0;
12439: p->nIndent = iOp+1;
12440:
12441: if( str_in_array(zOp, azNext) ){
12442: for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
12443: }
12444: if( str_in_array(zOp, azGoto) && p2op<p->nIndent
12445: && (abYield[p2op] || sqlite3_column_int(pSql, 2))
12446: ){
12447: for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
12448: }
12449: }
12450:
12451: p->iIndent = 0;
12452: sqlite3_free(abYield);
12453: sqlite3_reset(pSql);
12454: }
12455:
12456: /*
12457: ** Free the array allocated by explain_data_prepare().
12458: */
12459: static void explain_data_delete(ShellState *p){
12460: sqlite3_free(p->aiIndent);
12461: p->aiIndent = 0;
12462: p->nIndent = 0;
12463: p->iIndent = 0;
12464: }
12465:
12466: /*
12467: ** Disable and restore .wheretrace and .selecttrace settings.
12468: */
12469: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1.4.2.3 ! misho 12470: extern unsigned int sqlite3_unsupported_selecttrace;
1.4.2.2 misho 12471: static int savedSelectTrace;
12472: #endif
12473: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
12474: extern int sqlite3WhereTrace;
12475: static int savedWhereTrace;
12476: #endif
12477: static void disable_debug_trace_modes(void){
12478: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1.4.2.3 ! misho 12479: savedSelectTrace = sqlite3_unsupported_selecttrace;
! 12480: sqlite3_unsupported_selecttrace = 0;
1.4.2.2 misho 12481: #endif
12482: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
12483: savedWhereTrace = sqlite3WhereTrace;
12484: sqlite3WhereTrace = 0;
12485: #endif
12486: }
12487: static void restore_debug_trace_modes(void){
12488: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1.4.2.3 ! misho 12489: sqlite3_unsupported_selecttrace = savedSelectTrace;
1.4.2.2 misho 12490: #endif
12491: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
12492: sqlite3WhereTrace = savedWhereTrace;
12493: #endif
12494: }
12495:
12496: /* Create the TEMP table used to store parameter bindings */
12497: static void bind_table_init(ShellState *p){
12498: int wrSchema = 0;
1.4.2.3 ! misho 12499: int defensiveMode = 0;
! 12500: sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode);
! 12501: sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0);
1.4.2.2 misho 12502: sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
12503: sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
12504: sqlite3_exec(p->db,
12505: "CREATE TABLE IF NOT EXISTS temp.sqlite_parameters(\n"
12506: " key TEXT PRIMARY KEY,\n"
12507: " value ANY\n"
12508: ") WITHOUT ROWID;",
12509: 0, 0, 0);
12510: sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
1.4.2.3 ! misho 12511: sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, defensiveMode, 0);
1.4.2.2 misho 12512: }
12513:
12514: /*
12515: ** Bind parameters on a prepared statement.
12516: **
12517: ** Parameter bindings are taken from a TEMP table of the form:
12518: **
12519: ** CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value)
12520: ** WITHOUT ROWID;
12521: **
1.4.2.3 ! misho 12522: ** No bindings occur if this table does not exist. The name of the table
! 12523: ** begins with "sqlite_" so that it will not collide with ordinary application
! 12524: ** tables. The table must be in the TEMP schema.
1.4.2.2 misho 12525: */
12526: static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
12527: int nVar;
12528: int i;
12529: int rc;
12530: sqlite3_stmt *pQ = 0;
12531:
12532: nVar = sqlite3_bind_parameter_count(pStmt);
12533: if( nVar==0 ) return; /* Nothing to do */
12534: if( sqlite3_table_column_metadata(pArg->db, "TEMP", "sqlite_parameters",
12535: "key", 0, 0, 0, 0, 0)!=SQLITE_OK ){
12536: return; /* Parameter table does not exist */
12537: }
12538: rc = sqlite3_prepare_v2(pArg->db,
12539: "SELECT value FROM temp.sqlite_parameters"
12540: " WHERE key=?1", -1, &pQ, 0);
12541: if( rc || pQ==0 ) return;
12542: for(i=1; i<=nVar; i++){
12543: char zNum[30];
12544: const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
12545: if( zVar==0 ){
12546: sqlite3_snprintf(sizeof(zNum),zNum,"?%d",i);
12547: zVar = zNum;
12548: }
1.4.2.3 ! misho 12549: sqlite3_bind_text(pQ, 1, zVar, -1, SQLITE_STATIC);
! 12550: if( sqlite3_step(pQ)==SQLITE_ROW ){
! 12551: sqlite3_bind_value(pStmt, i, sqlite3_column_value(pQ, 0));
! 12552: }else{
! 12553: sqlite3_bind_null(pStmt, i);
! 12554: }
! 12555: sqlite3_reset(pQ);
! 12556: }
! 12557: sqlite3_finalize(pQ);
! 12558: }
! 12559:
! 12560: /*
! 12561: ** UTF8 box-drawing characters. Imagine box lines like this:
! 12562: **
! 12563: ** 1
! 12564: ** |
! 12565: ** 4 --+-- 2
! 12566: ** |
! 12567: ** 3
! 12568: **
! 12569: ** Each box characters has between 2 and 4 of the lines leading from
! 12570: ** the center. The characters are here identified by the numbers of
! 12571: ** their corresponding lines.
! 12572: */
! 12573: #define BOX_24 "\342\224\200" /* U+2500 --- */
! 12574: #define BOX_13 "\342\224\202" /* U+2502 | */
! 12575: #define BOX_23 "\342\224\214" /* U+250c ,- */
! 12576: #define BOX_34 "\342\224\220" /* U+2510 -, */
! 12577: #define BOX_12 "\342\224\224" /* U+2514 '- */
! 12578: #define BOX_14 "\342\224\230" /* U+2518 -' */
! 12579: #define BOX_123 "\342\224\234" /* U+251c |- */
! 12580: #define BOX_134 "\342\224\244" /* U+2524 -| */
! 12581: #define BOX_234 "\342\224\254" /* U+252c -,- */
! 12582: #define BOX_124 "\342\224\264" /* U+2534 -'- */
! 12583: #define BOX_1234 "\342\224\274" /* U+253c -|- */
! 12584:
! 12585: /* Draw horizontal line N characters long using unicode box
! 12586: ** characters
! 12587: */
! 12588: static void print_box_line(FILE *out, int N){
! 12589: const char zDash[] =
! 12590: BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
! 12591: BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
! 12592: const int nDash = sizeof(zDash) - 1;
! 12593: N *= 3;
! 12594: while( N>nDash ){
! 12595: utf8_printf(out, zDash);
! 12596: N -= nDash;
! 12597: }
! 12598: utf8_printf(out, "%.*s", N, zDash);
! 12599: }
! 12600:
! 12601: /*
! 12602: ** Draw a horizontal separator for a MODE_Box table.
! 12603: */
! 12604: static void print_box_row_separator(
! 12605: ShellState *p,
! 12606: int nArg,
! 12607: const char *zSep1,
! 12608: const char *zSep2,
! 12609: const char *zSep3
! 12610: ){
! 12611: int i;
! 12612: if( nArg>0 ){
! 12613: utf8_printf(p->out, "%s", zSep1);
! 12614: print_box_line(p->out, p->actualWidth[0]+2);
! 12615: for(i=1; i<nArg; i++){
! 12616: utf8_printf(p->out, "%s", zSep2);
! 12617: print_box_line(p->out, p->actualWidth[i]+2);
! 12618: }
! 12619: utf8_printf(p->out, "%s", zSep3);
! 12620: }
! 12621: fputs("\n", p->out);
! 12622: }
! 12623:
! 12624:
! 12625:
! 12626: /*
! 12627: ** Run a prepared statement and output the result in one of the
! 12628: ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
! 12629: ** or MODE_Box.
! 12630: **
! 12631: ** This is different from ordinary exec_prepared_stmt() in that
! 12632: ** it has to run the entire query and gather the results into memory
! 12633: ** first, in order to determine column widths, before providing
! 12634: ** any output.
! 12635: */
! 12636: static void exec_prepared_stmt_columnar(
! 12637: ShellState *p, /* Pointer to ShellState */
! 12638: sqlite3_stmt *pStmt /* Statment to run */
! 12639: ){
! 12640: sqlite3_int64 nRow = 0;
! 12641: int nColumn = 0;
! 12642: char **azData = 0;
! 12643: sqlite3_int64 nAlloc = 0;
! 12644: const char *z;
! 12645: int rc;
! 12646: sqlite3_int64 i, nData;
! 12647: int j, nTotal, w, n;
! 12648: const char *colSep = 0;
! 12649: const char *rowSep = 0;
! 12650:
! 12651: rc = sqlite3_step(pStmt);
! 12652: if( rc!=SQLITE_ROW ) return;
! 12653: nColumn = sqlite3_column_count(pStmt);
! 12654: nAlloc = nColumn*4;
! 12655: azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
! 12656: if( azData==0 ) shell_out_of_memory();
! 12657: for(i=0; i<nColumn; i++){
! 12658: azData[i] = strdup(sqlite3_column_name(pStmt,i));
! 12659: }
! 12660: do{
! 12661: if( (nRow+2)*nColumn >= nAlloc ){
! 12662: nAlloc *= 2;
! 12663: azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
! 12664: if( azData==0 ) shell_out_of_memory();
! 12665: }
! 12666: nRow++;
! 12667: for(i=0; i<nColumn; i++){
! 12668: z = (const char*)sqlite3_column_text(pStmt,i);
! 12669: azData[nRow*nColumn + i] = z ? strdup(z) : 0;
! 12670: }
! 12671: }while( (rc = sqlite3_step(pStmt))==SQLITE_ROW );
! 12672: if( nColumn>p->nWidth ){
! 12673: p->colWidth = realloc(p->colWidth, nColumn*2*sizeof(int));
! 12674: if( p->colWidth==0 ) shell_out_of_memory();
! 12675: for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
! 12676: p->nWidth = nColumn;
! 12677: p->actualWidth = &p->colWidth[nColumn];
! 12678: }
! 12679: memset(p->actualWidth, 0, nColumn*sizeof(int));
! 12680: for(i=0; i<nColumn; i++){
! 12681: w = p->colWidth[i];
! 12682: if( w<0 ) w = -w;
! 12683: p->actualWidth[i] = w;
! 12684: }
! 12685: nTotal = nColumn*(nRow+1);
! 12686: for(i=0; i<nTotal; i++){
! 12687: z = azData[i];
! 12688: if( z==0 ) z = p->nullValue;
! 12689: n = strlenChar(z);
! 12690: j = i%nColumn;
! 12691: if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
! 12692: }
! 12693: if( seenInterrupt ) goto columnar_end;
! 12694: switch( p->cMode ){
! 12695: case MODE_Column: {
! 12696: colSep = " ";
! 12697: rowSep = "\n";
! 12698: if( p->showHeader ){
! 12699: for(i=0; i<nColumn; i++){
! 12700: w = p->actualWidth[i];
! 12701: if( p->colWidth[i]<0 ) w = -w;
! 12702: utf8_width_print(p->out, w, azData[i]);
! 12703: fputs(i==nColumn-1?"\n":" ", p->out);
! 12704: }
! 12705: for(i=0; i<nColumn; i++){
! 12706: print_dashes(p->out, p->actualWidth[i]);
! 12707: fputs(i==nColumn-1?"\n":" ", p->out);
! 12708: }
! 12709: }
! 12710: break;
! 12711: }
! 12712: case MODE_Table: {
! 12713: colSep = " | ";
! 12714: rowSep = " |\n";
! 12715: print_row_separator(p, nColumn, "+");
! 12716: fputs("| ", p->out);
! 12717: for(i=0; i<nColumn; i++){
! 12718: w = p->actualWidth[i];
! 12719: n = strlenChar(azData[i]);
! 12720: utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
! 12721: fputs(i==nColumn-1?" |\n":" | ", p->out);
! 12722: }
! 12723: print_row_separator(p, nColumn, "+");
! 12724: break;
! 12725: }
! 12726: case MODE_Markdown: {
! 12727: colSep = " | ";
! 12728: rowSep = " |\n";
! 12729: fputs("| ", p->out);
! 12730: for(i=0; i<nColumn; i++){
! 12731: w = p->actualWidth[i];
! 12732: n = strlenChar(azData[i]);
! 12733: utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
! 12734: fputs(i==nColumn-1?" |\n":" | ", p->out);
! 12735: }
! 12736: print_row_separator(p, nColumn, "|");
! 12737: break;
! 12738: }
! 12739: case MODE_Box: {
! 12740: colSep = " " BOX_13 " ";
! 12741: rowSep = " " BOX_13 "\n";
! 12742: print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34);
! 12743: utf8_printf(p->out, BOX_13 " ");
! 12744: for(i=0; i<nColumn; i++){
! 12745: w = p->actualWidth[i];
! 12746: n = strlenChar(azData[i]);
! 12747: utf8_printf(p->out, "%*s%s%*s%s",
! 12748: (w-n)/2, "", azData[i], (w-n+1)/2, "",
! 12749: i==nColumn-1?" "BOX_13"\n":" "BOX_13" ");
! 12750: }
! 12751: print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
! 12752: break;
1.4.2.2 misho 12753: }
12754: }
1.4.2.3 ! misho 12755: for(i=nColumn, j=0; i<nTotal; i++, j++){
! 12756: if( j==0 && p->cMode!=MODE_Column ){
! 12757: utf8_printf(p->out, "%s", p->cMode==MODE_Box?BOX_13" ":"| ");
! 12758: }
! 12759: z = azData[i];
! 12760: if( z==0 ) z = p->nullValue;
! 12761: w = p->actualWidth[j];
! 12762: if( p->colWidth[j]<0 ) w = -w;
! 12763: utf8_width_print(p->out, w, z);
! 12764: if( j==nColumn-1 ){
! 12765: utf8_printf(p->out, "%s", rowSep);
! 12766: j = -1;
! 12767: if( seenInterrupt ) goto columnar_end;
! 12768: }else{
! 12769: utf8_printf(p->out, "%s", colSep);
! 12770: }
! 12771: }
! 12772: if( p->cMode==MODE_Table ){
! 12773: print_row_separator(p, nColumn, "+");
! 12774: }else if( p->cMode==MODE_Box ){
! 12775: print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14);
! 12776: }
! 12777: columnar_end:
! 12778: if( seenInterrupt ){
! 12779: utf8_printf(p->out, "Interrupt\n");
! 12780: }
! 12781: nData = (nRow+1)*nColumn;
! 12782: for(i=0; i<nData; i++) free(azData[i]);
! 12783: sqlite3_free(azData);
1.4.2.2 misho 12784: }
12785:
12786: /*
12787: ** Run a prepared statement
12788: */
12789: static void exec_prepared_stmt(
12790: ShellState *pArg, /* Pointer to ShellState */
12791: sqlite3_stmt *pStmt /* Statment to run */
12792: ){
12793: int rc;
12794:
1.4.2.3 ! misho 12795: if( pArg->cMode==MODE_Column
! 12796: || pArg->cMode==MODE_Table
! 12797: || pArg->cMode==MODE_Box
! 12798: || pArg->cMode==MODE_Markdown
! 12799: ){
! 12800: exec_prepared_stmt_columnar(pArg, pStmt);
! 12801: return;
! 12802: }
! 12803:
1.4.2.2 misho 12804: /* perform the first step. this will tell us if we
12805: ** have a result set or not and how wide it is.
12806: */
12807: rc = sqlite3_step(pStmt);
12808: /* if we have a result set... */
12809: if( SQLITE_ROW == rc ){
12810: /* allocate space for col name ptr, value ptr, and type */
12811: int nCol = sqlite3_column_count(pStmt);
12812: void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
12813: if( !pData ){
12814: rc = SQLITE_NOMEM;
12815: }else{
12816: char **azCols = (char **)pData; /* Names of result columns */
12817: char **azVals = &azCols[nCol]; /* Results */
12818: int *aiTypes = (int *)&azVals[nCol]; /* Result types */
12819: int i, x;
12820: assert(sizeof(int) <= sizeof(char *));
12821: /* save off ptrs to column names */
12822: for(i=0; i<nCol; i++){
12823: azCols[i] = (char *)sqlite3_column_name(pStmt, i);
12824: }
12825: do{
12826: /* extract the data and data types */
12827: for(i=0; i<nCol; i++){
12828: aiTypes[i] = x = sqlite3_column_type(pStmt, i);
12829: if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
12830: azVals[i] = "";
12831: }else{
12832: azVals[i] = (char*)sqlite3_column_text(pStmt, i);
12833: }
12834: if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
12835: rc = SQLITE_NOMEM;
12836: break; /* from for */
12837: }
12838: } /* end for */
12839:
12840: /* if data and types extracted successfully... */
12841: if( SQLITE_ROW == rc ){
12842: /* call the supplied callback with the result row data */
12843: if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
12844: rc = SQLITE_ABORT;
12845: }else{
12846: rc = sqlite3_step(pStmt);
12847: }
12848: }
12849: } while( SQLITE_ROW == rc );
12850: sqlite3_free(pData);
1.4.2.3 ! misho 12851: if( pArg->cMode==MODE_Json ){
! 12852: fputs("]\n", pArg->out);
! 12853: }
1.4.2.2 misho 12854: }
12855: }
12856: }
12857:
12858: #ifndef SQLITE_OMIT_VIRTUALTABLE
12859: /*
12860: ** This function is called to process SQL if the previous shell command
12861: ** was ".expert". It passes the SQL in the second argument directly to
12862: ** the sqlite3expert object.
12863: **
12864: ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
12865: ** code. In this case, (*pzErr) may be set to point to a buffer containing
12866: ** an English language error message. It is the responsibility of the
12867: ** caller to eventually free this buffer using sqlite3_free().
12868: */
12869: static int expertHandleSQL(
12870: ShellState *pState,
12871: const char *zSql,
12872: char **pzErr
12873: ){
12874: assert( pState->expert.pExpert );
12875: assert( pzErr==0 || *pzErr==0 );
12876: return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr);
12877: }
12878:
12879: /*
12880: ** This function is called either to silently clean up the object
12881: ** created by the ".expert" command (if bCancel==1), or to generate a
12882: ** report from it and then clean it up (if bCancel==0).
12883: **
12884: ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
12885: ** code. In this case, (*pzErr) may be set to point to a buffer containing
12886: ** an English language error message. It is the responsibility of the
12887: ** caller to eventually free this buffer using sqlite3_free().
12888: */
12889: static int expertFinish(
12890: ShellState *pState,
12891: int bCancel,
12892: char **pzErr
12893: ){
12894: int rc = SQLITE_OK;
12895: sqlite3expert *p = pState->expert.pExpert;
12896: assert( p );
12897: assert( bCancel || pzErr==0 || *pzErr==0 );
12898: if( bCancel==0 ){
12899: FILE *out = pState->out;
12900: int bVerbose = pState->expert.bVerbose;
12901:
12902: rc = sqlite3_expert_analyze(p, pzErr);
12903: if( rc==SQLITE_OK ){
12904: int nQuery = sqlite3_expert_count(p);
12905: int i;
12906:
12907: if( bVerbose ){
12908: const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
12909: raw_printf(out, "-- Candidates -----------------------------\n");
12910: raw_printf(out, "%s\n", zCand);
12911: }
12912: for(i=0; i<nQuery; i++){
12913: const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
12914: const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
12915: const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
12916: if( zIdx==0 ) zIdx = "(no new indexes)\n";
12917: if( bVerbose ){
12918: raw_printf(out, "-- Query %d --------------------------------\n",i+1);
12919: raw_printf(out, "%s\n\n", zSql);
12920: }
12921: raw_printf(out, "%s\n", zIdx);
12922: raw_printf(out, "%s\n", zEQP);
12923: }
12924: }
12925: }
12926: sqlite3_expert_destroy(p);
12927: pState->expert.pExpert = 0;
12928: return rc;
12929: }
12930:
12931: /*
12932: ** Implementation of ".expert" dot command.
12933: */
12934: static int expertDotCommand(
12935: ShellState *pState, /* Current shell tool state */
12936: char **azArg, /* Array of arguments passed to dot command */
12937: int nArg /* Number of entries in azArg[] */
12938: ){
12939: int rc = SQLITE_OK;
12940: char *zErr = 0;
12941: int i;
12942: int iSample = 0;
12943:
12944: assert( pState->expert.pExpert==0 );
12945: memset(&pState->expert, 0, sizeof(ExpertInfo));
12946:
12947: for(i=1; rc==SQLITE_OK && i<nArg; i++){
12948: char *z = azArg[i];
12949: int n;
12950: if( z[0]=='-' && z[1]=='-' ) z++;
12951: n = strlen30(z);
12952: if( n>=2 && 0==strncmp(z, "-verbose", n) ){
12953: pState->expert.bVerbose = 1;
12954: }
12955: else if( n>=2 && 0==strncmp(z, "-sample", n) ){
12956: if( i==(nArg-1) ){
12957: raw_printf(stderr, "option requires an argument: %s\n", z);
12958: rc = SQLITE_ERROR;
12959: }else{
12960: iSample = (int)integerValue(azArg[++i]);
12961: if( iSample<0 || iSample>100 ){
12962: raw_printf(stderr, "value out of range: %s\n", azArg[i]);
12963: rc = SQLITE_ERROR;
12964: }
12965: }
12966: }
12967: else{
12968: raw_printf(stderr, "unknown option: %s\n", z);
12969: rc = SQLITE_ERROR;
12970: }
12971: }
12972:
12973: if( rc==SQLITE_OK ){
12974: pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
12975: if( pState->expert.pExpert==0 ){
12976: raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr);
12977: rc = SQLITE_ERROR;
12978: }else{
12979: sqlite3_expert_config(
12980: pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
12981: );
12982: }
12983: }
12984:
12985: return rc;
12986: }
12987: #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
12988:
12989: /*
12990: ** Execute a statement or set of statements. Print
12991: ** any result rows/columns depending on the current mode
12992: ** set via the supplied callback.
12993: **
12994: ** This is very similar to SQLite's built-in sqlite3_exec()
12995: ** function except it takes a slightly different callback
12996: ** and callback data argument.
12997: */
12998: static int shell_exec(
12999: ShellState *pArg, /* Pointer to ShellState */
13000: const char *zSql, /* SQL to be evaluated */
13001: char **pzErrMsg /* Error msg written here */
13002: ){
13003: sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
13004: int rc = SQLITE_OK; /* Return Code */
13005: int rc2;
13006: const char *zLeftover; /* Tail of unprocessed SQL */
13007: sqlite3 *db = pArg->db;
13008:
13009: if( pzErrMsg ){
13010: *pzErrMsg = NULL;
13011: }
13012:
13013: #ifndef SQLITE_OMIT_VIRTUALTABLE
13014: if( pArg->expert.pExpert ){
13015: rc = expertHandleSQL(pArg, zSql, pzErrMsg);
13016: return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
13017: }
13018: #endif
13019:
13020: while( zSql[0] && (SQLITE_OK == rc) ){
13021: static const char *zStmtSql;
13022: rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
13023: if( SQLITE_OK != rc ){
13024: if( pzErrMsg ){
13025: *pzErrMsg = save_err_msg(db);
13026: }
13027: }else{
13028: if( !pStmt ){
13029: /* this happens for a comment or white-space */
13030: zSql = zLeftover;
13031: while( IsSpace(zSql[0]) ) zSql++;
13032: continue;
1.4 misho 13033: }
1.4.2.2 misho 13034: zStmtSql = sqlite3_sql(pStmt);
13035: if( zStmtSql==0 ) zStmtSql = "";
13036: while( IsSpace(zStmtSql[0]) ) zStmtSql++;
13037:
13038: /* save off the prepared statment handle and reset row count */
13039: if( pArg ){
13040: pArg->pStmt = pStmt;
13041: pArg->cnt = 0;
13042: }
13043:
13044: /* echo the sql statement if echo on */
13045: if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
13046: utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
13047: }
13048:
13049: /* Show the EXPLAIN QUERY PLAN if .eqp is on */
13050: if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
13051: sqlite3_stmt *pExplain;
13052: char *zEQP;
13053: int triggerEQP = 0;
13054: disable_debug_trace_modes();
13055: sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
13056: if( pArg->autoEQP>=AUTOEQP_trigger ){
13057: sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
13058: }
13059: zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
13060: rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
13061: if( rc==SQLITE_OK ){
13062: while( sqlite3_step(pExplain)==SQLITE_ROW ){
13063: const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
13064: int iEqpId = sqlite3_column_int(pExplain, 0);
13065: int iParentId = sqlite3_column_int(pExplain, 1);
1.4.2.3 ! misho 13066: if( zEQPLine==0 ) zEQPLine = "";
1.4.2.2 misho 13067: if( zEQPLine[0]=='-' ) eqp_render(pArg);
13068: eqp_append(pArg, iEqpId, iParentId, zEQPLine);
1.4 misho 13069: }
1.4.2.2 misho 13070: eqp_render(pArg);
13071: }
13072: sqlite3_finalize(pExplain);
13073: sqlite3_free(zEQP);
13074: if( pArg->autoEQP>=AUTOEQP_full ){
13075: /* Also do an EXPLAIN for ".eqp full" mode */
13076: zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
13077: rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
13078: if( rc==SQLITE_OK ){
13079: pArg->cMode = MODE_Explain;
13080: explain_data_prepare(pArg, pExplain);
13081: exec_prepared_stmt(pArg, pExplain);
13082: explain_data_delete(pArg);
1.4 misho 13083: }
1.4.2.2 misho 13084: sqlite3_finalize(pExplain);
13085: sqlite3_free(zEQP);
1.3 misho 13086: }
1.4.2.2 misho 13087: if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
13088: sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
13089: /* Reprepare pStmt before reactiving trace modes */
13090: sqlite3_finalize(pStmt);
13091: sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
13092: if( pArg ) pArg->pStmt = pStmt;
1.2 misho 13093: }
1.4.2.2 misho 13094: restore_debug_trace_modes();
1.2 misho 13095: }
1.4.2.2 misho 13096:
13097: if( pArg ){
13098: pArg->cMode = pArg->mode;
13099: if( pArg->autoExplain ){
13100: if( sqlite3_stmt_isexplain(pStmt)==1 ){
13101: pArg->cMode = MODE_Explain;
13102: }
13103: if( sqlite3_stmt_isexplain(pStmt)==2 ){
13104: pArg->cMode = MODE_EQP;
13105: }
1.2 misho 13106: }
1.4.2.2 misho 13107:
13108: /* If the shell is currently in ".explain" mode, gather the extra
13109: ** data required to add indents to the output.*/
13110: if( pArg->cMode==MODE_Explain ){
13111: explain_data_prepare(pArg, pStmt);
1.2 misho 13112: }
13113: }
1.4.2.2 misho 13114:
13115: bind_prepared_stmt(pArg, pStmt);
13116: exec_prepared_stmt(pArg, pStmt);
13117: explain_data_delete(pArg);
13118: eqp_render(pArg);
13119:
13120: /* print usage stats if stats on */
13121: if( pArg && pArg->statsOn ){
13122: display_stats(db, pArg, 0);
1.2 misho 13123: }
1.4.2.2 misho 13124:
13125: /* print loop-counters if required */
13126: if( pArg && pArg->scanstatsOn ){
13127: display_scanstats(db, pArg);
1.2 misho 13128: }
1.4.2.2 misho 13129:
13130: /* Finalize the statement just executed. If this fails, save a
13131: ** copy of the error message. Otherwise, set zSql to point to the
13132: ** next statement to execute. */
13133: rc2 = sqlite3_finalize(pStmt);
13134: if( rc!=SQLITE_NOMEM ) rc = rc2;
13135: if( rc==SQLITE_OK ){
13136: zSql = zLeftover;
13137: while( IsSpace(zSql[0]) ) zSql++;
13138: }else if( pzErrMsg ){
13139: *pzErrMsg = save_err_msg(db);
1.2 misho 13140: }
1.4.2.2 misho 13141:
13142: /* clear saved stmt handle */
13143: if( pArg ){
13144: pArg->pStmt = NULL;
1.2 misho 13145: }
13146: }
1.4.2.2 misho 13147: } /* end while */
13148:
13149: return rc;
13150: }
13151:
13152: /*
13153: ** Release memory previously allocated by tableColumnList().
13154: */
13155: static void freeColumnList(char **azCol){
13156: int i;
13157: for(i=1; azCol[i]; i++){
13158: sqlite3_free(azCol[i]);
13159: }
13160: /* azCol[0] is a static string */
13161: sqlite3_free(azCol);
13162: }
13163:
13164: /*
13165: ** Return a list of pointers to strings which are the names of all
13166: ** columns in table zTab. The memory to hold the names is dynamically
13167: ** allocated and must be released by the caller using a subsequent call
13168: ** to freeColumnList().
13169: **
13170: ** The azCol[0] entry is usually NULL. However, if zTab contains a rowid
13171: ** value that needs to be preserved, then azCol[0] is filled in with the
13172: ** name of the rowid column.
13173: **
13174: ** The first regular column in the table is azCol[1]. The list is terminated
13175: ** by an entry with azCol[i]==0.
13176: */
13177: static char **tableColumnList(ShellState *p, const char *zTab){
13178: char **azCol = 0;
13179: sqlite3_stmt *pStmt;
13180: char *zSql;
13181: int nCol = 0;
13182: int nAlloc = 0;
13183: int nPK = 0; /* Number of PRIMARY KEY columns seen */
13184: int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */
13185: int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid);
13186: int rc;
13187:
13188: zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab);
13189: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
13190: sqlite3_free(zSql);
13191: if( rc ) return 0;
13192: while( sqlite3_step(pStmt)==SQLITE_ROW ){
13193: if( nCol>=nAlloc-2 ){
13194: nAlloc = nAlloc*2 + nCol + 10;
13195: azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
13196: if( azCol==0 ) shell_out_of_memory();
1.4.2.1 misho 13197: }
1.4.2.2 misho 13198: azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
13199: if( sqlite3_column_int(pStmt, 5) ){
13200: nPK++;
13201: if( nPK==1
13202: && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
13203: "INTEGER")==0
13204: ){
13205: isIPK = 1;
13206: }else{
13207: isIPK = 0;
1.2 misho 13208: }
1.4 misho 13209: }
1.4.2.2 misho 13210: }
13211: sqlite3_finalize(pStmt);
13212: if( azCol==0 ) return 0;
13213: azCol[0] = 0;
13214: azCol[nCol+1] = 0;
13215:
13216: /* The decision of whether or not a rowid really needs to be preserved
13217: ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table
13218: ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve
13219: ** rowids on tables where the rowid is inaccessible because there are other
13220: ** columns in the table named "rowid", "_rowid_", and "oid".
13221: */
13222: if( preserveRowid && isIPK ){
13223: /* If a single PRIMARY KEY column with type INTEGER was seen, then it
13224: ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID
13225: ** table or a INTEGER PRIMARY KEY DESC column, neither of which are
13226: ** ROWID aliases. To distinguish these cases, check to see if
13227: ** there is a "pk" entry in "PRAGMA index_list". There will be
13228: ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID.
13229: */
13230: zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)"
13231: " WHERE origin='pk'", zTab);
13232: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
13233: sqlite3_free(zSql);
13234: if( rc ){
13235: freeColumnList(azCol);
13236: return 0;
13237: }
13238: rc = sqlite3_step(pStmt);
13239: sqlite3_finalize(pStmt);
13240: preserveRowid = rc==SQLITE_ROW;
13241: }
13242: if( preserveRowid ){
13243: /* Only preserve the rowid if we can find a name to use for the
13244: ** rowid */
13245: static char *azRowid[] = { "rowid", "_rowid_", "oid" };
13246: int i, j;
13247: for(j=0; j<3; j++){
13248: for(i=1; i<=nCol; i++){
13249: if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break;
1.4 misho 13250: }
1.4.2.2 misho 13251: if( i>nCol ){
13252: /* At this point, we know that azRowid[j] is not the name of any
13253: ** ordinary column in the table. Verify that azRowid[j] is a valid
13254: ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
13255: ** tables will fail this last check */
13256: rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
13257: if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
13258: break;
1.4 misho 13259: }
1.2 misho 13260: }
13261: }
1.4.2.2 misho 13262: return azCol;
1.2 misho 13263: }
13264:
13265: /*
1.4.2.2 misho 13266: ** Toggle the reverse_unordered_selects setting.
1.2 misho 13267: */
1.4.2.2 misho 13268: static void toggleSelectOrder(sqlite3 *db){
13269: sqlite3_stmt *pStmt = 0;
13270: int iSetting = 0;
13271: char zStmt[100];
13272: sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0);
13273: if( sqlite3_step(pStmt)==SQLITE_ROW ){
13274: iSetting = sqlite3_column_int(pStmt, 0);
13275: }
13276: sqlite3_finalize(pStmt);
13277: sqlite3_snprintf(sizeof(zStmt), zStmt,
13278: "PRAGMA reverse_unordered_selects(%d)", !iSetting);
13279: sqlite3_exec(db, zStmt, 0, 0, 0);
1.2 misho 13280: }
13281:
13282: /*
1.4.2.2 misho 13283: ** This is a different callback routine used for dumping the database.
13284: ** Each row received by this callback consists of a table name,
13285: ** the table type ("index" or "table") and SQL to create the table.
13286: ** This routine should print text sufficient to recreate the table.
1.4.2.1 misho 13287: */
1.4.2.2 misho 13288: static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
13289: int rc;
13290: const char *zTable;
13291: const char *zType;
13292: const char *zSql;
13293: ShellState *p = (ShellState *)pArg;
13294:
13295: UNUSED_PARAMETER(azNotUsed);
13296: if( nArg!=3 || azArg==0 ) return 0;
13297: zTable = azArg[0];
13298: zType = azArg[1];
13299: zSql = azArg[2];
13300:
13301: if( strcmp(zTable, "sqlite_sequence")==0 ){
13302: raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
13303: }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
1.4.2.3 ! misho 13304: raw_printf(p->out, "ANALYZE sqlite_schema;\n");
1.4.2.2 misho 13305: }else if( strncmp(zTable, "sqlite_", 7)==0 ){
13306: return 0;
13307: }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
13308: char *zIns;
13309: if( !p->writableSchema ){
13310: raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
13311: p->writableSchema = 1;
13312: }
13313: zIns = sqlite3_mprintf(
1.4.2.3 ! misho 13314: "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
1.4.2.2 misho 13315: "VALUES('table','%q','%q',0,'%q');",
13316: zTable, zTable, zSql);
13317: utf8_printf(p->out, "%s\n", zIns);
13318: sqlite3_free(zIns);
13319: return 0;
13320: }else{
13321: printSchemaLine(p->out, zSql, ";\n");
1.4.2.1 misho 13322: }
13323:
1.4.2.2 misho 13324: if( strcmp(zType, "table")==0 ){
13325: ShellText sSelect;
13326: ShellText sTable;
13327: char **azCol;
13328: int i;
13329: char *savedDestTable;
13330: int savedMode;
13331:
13332: azCol = tableColumnList(p, zTable);
13333: if( azCol==0 ){
13334: p->nErr++;
13335: return 0;
13336: }
13337:
13338: /* Always quote the table name, even if it appears to be pure ascii,
13339: ** in case it is a keyword. Ex: INSERT INTO "table" ... */
13340: initText(&sTable);
13341: appendText(&sTable, zTable, quoteChar(zTable));
13342: /* If preserving the rowid, add a column list after the table name.
13343: ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
13344: ** instead of the usual "INSERT INTO tab VALUES(...)".
13345: */
13346: if( azCol[0] ){
13347: appendText(&sTable, "(", 0);
13348: appendText(&sTable, azCol[0], 0);
13349: for(i=1; azCol[i]; i++){
13350: appendText(&sTable, ",", 0);
13351: appendText(&sTable, azCol[i], quoteChar(azCol[i]));
13352: }
13353: appendText(&sTable, ")", 0);
13354: }
13355:
13356: /* Build an appropriate SELECT statement */
13357: initText(&sSelect);
13358: appendText(&sSelect, "SELECT ", 0);
13359: if( azCol[0] ){
13360: appendText(&sSelect, azCol[0], 0);
13361: appendText(&sSelect, ",", 0);
13362: }
13363: for(i=1; azCol[i]; i++){
13364: appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
13365: if( azCol[i+1] ){
13366: appendText(&sSelect, ",", 0);
13367: }
13368: }
13369: freeColumnList(azCol);
13370: appendText(&sSelect, " FROM ", 0);
13371: appendText(&sSelect, zTable, quoteChar(zTable));
13372:
13373: savedDestTable = p->zDestTable;
13374: savedMode = p->mode;
13375: p->zDestTable = sTable.z;
13376: p->mode = p->cMode = MODE_Insert;
13377: rc = shell_exec(p, sSelect.z, 0);
13378: if( (rc&0xff)==SQLITE_CORRUPT ){
13379: raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
13380: toggleSelectOrder(p->db);
13381: shell_exec(p, sSelect.z, 0);
13382: toggleSelectOrder(p->db);
13383: }
13384: p->zDestTable = savedDestTable;
13385: p->mode = savedMode;
13386: freeText(&sTable);
13387: freeText(&sSelect);
13388: if( rc ) p->nErr++;
1.4.2.1 misho 13389: }
1.4.2.2 misho 13390: return 0;
1.4.2.1 misho 13391: }
13392:
13393: /*
1.4.2.2 misho 13394: ** Run zQuery. Use dump_callback() as the callback routine so that
13395: ** the contents of the query are output as SQL statements.
13396: **
13397: ** If we get a SQLITE_CORRUPT error, rerun the query after appending
13398: ** "ORDER BY rowid DESC" to the end.
1.2 misho 13399: */
1.4.2.2 misho 13400: static int run_schema_dump_query(
13401: ShellState *p,
13402: const char *zQuery
13403: ){
13404: int rc;
13405: char *zErr = 0;
13406: rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
13407: if( rc==SQLITE_CORRUPT ){
13408: char *zQ2;
13409: int len = strlen30(zQuery);
13410: raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
13411: if( zErr ){
13412: utf8_printf(p->out, "/****** %s ******/\n", zErr);
13413: sqlite3_free(zErr);
13414: zErr = 0;
13415: }
13416: zQ2 = malloc( len+100 );
13417: if( zQ2==0 ) return rc;
13418: sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
13419: rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
13420: if( rc ){
13421: utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
13422: }else{
13423: rc = SQLITE_CORRUPT;
13424: }
13425: sqlite3_free(zErr);
13426: free(zQ2);
1.2 misho 13427: }
1.4.2.2 misho 13428: return rc;
1.2 misho 13429: }
13430:
1.4.2.2 misho 13431: /*
13432: ** Text of help messages.
13433: **
13434: ** The help text for each individual command begins with a line that starts
13435: ** with ".". Subsequent lines are supplimental information.
13436: **
13437: ** There must be two or more spaces between the end of the command and the
13438: ** start of the description of what that command does.
13439: */
13440: static const char *(azHelp[]) = {
13441: #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
13442: ".archive ... Manage SQL archives",
13443: " Each command must have exactly one of the following options:",
13444: " -c, --create Create a new archive",
1.4.2.3 ! misho 13445: " -u, --update Add or update files with changed mtime",
! 13446: " -i, --insert Like -u but always add even if unchanged",
1.4.2.2 misho 13447: " -t, --list List contents of archive",
13448: " -x, --extract Extract files from archive",
13449: " Optional arguments:",
13450: " -v, --verbose Print each filename as it is processed",
1.4.2.3 ! misho 13451: " -f FILE, --file FILE Use archive FILE (default is current db)",
! 13452: " -a FILE, --append FILE Open FILE using the apndvfs VFS",
! 13453: " -C DIR, --directory DIR Read/extract files from directory DIR",
1.4.2.2 misho 13454: " -n, --dryrun Show the SQL that would have occurred",
13455: " Examples:",
1.4.2.3 ! misho 13456: " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
! 13457: " .ar -tf ARCHIVE # List members of ARCHIVE",
! 13458: " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
1.4.2.2 misho 13459: " See also:",
13460: " http://sqlite.org/cli.html#sqlar_archive_support",
13461: #endif
13462: #ifndef SQLITE_OMIT_AUTHORIZATION
13463: ".auth ON|OFF Show authorizer callbacks",
13464: #endif
13465: ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
13466: " --append Use the appendvfs",
1.4.2.3 ! misho 13467: " --async Write to FILE without journal and fsync()",
1.4.2.2 misho 13468: ".bail on|off Stop after hitting an error. Default OFF",
13469: ".binary on|off Turn binary output on or off. Default OFF",
13470: ".cd DIRECTORY Change the working directory to DIRECTORY",
13471: ".changes on|off Show number of rows changed by SQL",
13472: ".check GLOB Fail if output since .testcase does not match",
13473: ".clone NEWDB Clone data into NEWDB from the existing database",
13474: ".databases List names and files of attached databases",
13475: ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
13476: ".dbinfo ?DB? Show status information about the database",
1.4.2.3 ! misho 13477: ".dump ?TABLE? Render database content as SQL",
1.4.2.2 misho 13478: " Options:",
13479: " --preserve-rowids Include ROWID values in the output",
13480: " --newlines Allow unescaped newline characters in output",
13481: " TABLE is a LIKE pattern for the tables to dump",
1.4.2.3 ! misho 13482: " Additional LIKE patterns can be given in subsequent arguments",
1.4.2.2 misho 13483: ".echo on|off Turn command echo on or off",
13484: ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
13485: " Other Modes:",
13486: #ifdef SQLITE_DEBUG
13487: " test Show raw EXPLAIN QUERY PLAN output",
1.4.2.3 ! misho 13488: " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
1.4.2.2 misho 13489: #endif
13490: " trigger Like \"full\" but also show trigger bytecode",
1.4.2.3 ! misho 13491: ".excel Display the output of next command in spreadsheet",
! 13492: " --bom Put a UTF8 byte-order mark on intermediate file",
1.4.2.2 misho 13493: ".exit ?CODE? Exit this program with return-code CODE",
1.4.2.3 ! misho 13494: ".expert EXPERIMENTAL. Suggest indexes for queries",
! 13495: ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
1.4.2.2 misho 13496: ".filectrl CMD ... Run various sqlite3_file_control() operations",
1.4.2.3 ! misho 13497: " --schema SCHEMA Use SCHEMA instead of \"main\"",
! 13498: " --help Show CMD details",
1.4.2.2 misho 13499: ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
13500: ".headers on|off Turn display of headers on or off",
13501: ".help ?-all? ?PATTERN? Show help text for PATTERN",
13502: ".import FILE TABLE Import data from FILE into TABLE",
1.4.2.3 ! misho 13503: " Options:",
! 13504: " --ascii Use \\037 and \\036 as column and row separators",
! 13505: " --csv Use , and \\n as column and row separators",
! 13506: " --skip N Skip the first N rows of input",
! 13507: " -v \"Verbose\" - increase auxiliary output",
! 13508: " Notes:",
! 13509: " * If TABLE does not exist, it is created. The first row of input",
! 13510: " determines the column names.",
! 13511: " * If neither --csv or --ascii are used, the input mode is derived",
! 13512: " from the \".mode\" output mode",
! 13513: " * If FILE begins with \"|\" then it is a command that generates the",
! 13514: " input text.",
1.4.2.2 misho 13515: #ifndef SQLITE_OMIT_TEST_CONTROL
13516: ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
13517: #endif
13518: ".indexes ?TABLE? Show names of indexes",
13519: " If TABLE is specified, only show indexes for",
13520: " tables matching TABLE using the LIKE operator.",
13521: #ifdef SQLITE_ENABLE_IOTRACE
13522: ".iotrace FILE Enable I/O diagnostic logging to FILE",
13523: #endif
13524: ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
13525: ".lint OPTIONS Report potential schema issues.",
13526: " Options:",
13527: " fkey-indexes Find missing foreign key indexes",
13528: #ifndef SQLITE_OMIT_LOAD_EXTENSION
13529: ".load FILE ?ENTRY? Load an extension library",
13530: #endif
13531: ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
13532: ".mode MODE ?TABLE? Set output mode",
13533: " MODE is one of:",
1.4.2.3 ! misho 13534: " ascii Columns/rows delimited by 0x1F and 0x1E",
! 13535: " box Tables using unicode box-drawing characters",
! 13536: " csv Comma-separated values",
! 13537: " column Output in columns. (See .width)",
! 13538: " html HTML <table> code",
! 13539: " insert SQL insert statements for TABLE",
! 13540: " json Results in a JSON array",
! 13541: " line One value per line",
! 13542: " list Values delimited by \"|\"",
! 13543: " markdown Markdown table format",
! 13544: " quote Escape answers as for SQL",
! 13545: " table ASCII-art table",
! 13546: " tabs Tab-separated values",
! 13547: " tcl TCL list elements",
1.4.2.2 misho 13548: ".nullvalue STRING Use STRING in place of NULL values",
1.4.2.3 ! misho 13549: ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
1.4.2.2 misho 13550: " If FILE begins with '|' then open as a pipe",
1.4.2.3 ! misho 13551: " --bom Put a UTF8 byte-order mark at the beginning",
! 13552: " -e Send output to the system text editor",
! 13553: " -x Send output as CSV to a spreadsheet (same as \".excel\")",
! 13554: #ifdef SQLITE_DEBUG
! 13555: ".oom ?--repeat M? ?N? Simulate an OOM error on the N-th allocation",
! 13556: #endif
1.4.2.2 misho 13557: ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
13558: " Options:",
13559: " --append Use appendvfs to append database to the end of FILE",
13560: #ifdef SQLITE_ENABLE_DESERIALIZE
13561: " --deserialize Load into memory useing sqlite3_deserialize()",
1.4.2.3 ! misho 13562: " --hexdb Load the output of \"dbtotxt\" as an in-memory db",
1.4.2.2 misho 13563: " --maxsize N Maximum size for --hexdb or --deserialized database",
13564: #endif
13565: " --new Initialize FILE to an empty database",
1.4.2.3 ! misho 13566: " --nofollow Do not follow symbolic links",
1.4.2.2 misho 13567: " --readonly Open FILE readonly",
13568: " --zip FILE is a ZIP archive",
13569: ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
1.4.2.3 ! misho 13570: " If FILE begins with '|' then open it as a pipe.",
! 13571: " Options:",
! 13572: " --bom Prefix output with a UTF8 byte-order mark",
! 13573: " -e Send output to the system text editor",
! 13574: " -x Send output as CSV to a spreadsheet",
1.4.2.2 misho 13575: ".parameter CMD ... Manage SQL parameter bindings",
13576: " clear Erase all bindings",
13577: " init Initialize the TEMP table that holds bindings",
13578: " list List the current parameter bindings",
13579: " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
1.4.2.3 ! misho 13580: " PARAMETER should start with one of: $ : @ ?",
1.4.2.2 misho 13581: " unset PARAMETER Remove PARAMETER from the binding table",
13582: ".print STRING... Print literal STRING",
13583: #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
13584: ".progress N Invoke progress handler after every N opcodes",
13585: " --limit N Interrupt after N progress callbacks",
13586: " --once Do no more than one progress interrupt",
13587: " --quiet|-q No output except at interrupts",
13588: " --reset Reset the count for each input and interrupt",
13589: #endif
13590: ".prompt MAIN CONTINUE Replace the standard prompts",
13591: ".quit Exit this program",
13592: ".read FILE Read input from FILE",
13593: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
13594: ".recover Recover as much data as possible from corrupt db.",
1.4.2.3 ! misho 13595: " --freelist-corrupt Assume the freelist is corrupt",
! 13596: " --recovery-db NAME Store recovery metadata in database file NAME",
! 13597: " --lost-and-found TABLE Alternative name for the lost-and-found table",
! 13598: " --no-rowids Do not attempt to recover rowid values",
! 13599: " that are not also INTEGER PRIMARY KEYs",
1.4.2.2 misho 13600: #endif
13601: ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
13602: ".save FILE Write in-memory database into FILE",
13603: ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
13604: ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
13605: " Options:",
13606: " --indent Try to pretty-print the schema",
13607: ".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
13608: " Options:",
13609: " --init Create a new SELFTEST table",
13610: " -v Verbose output",
13611: ".separator COL ?ROW? Change the column and row separators",
13612: #if defined(SQLITE_ENABLE_SESSION)
13613: ".session ?NAME? CMD ... Create or control sessions",
13614: " Subcommands:",
13615: " attach TABLE Attach TABLE",
13616: " changeset FILE Write a changeset into FILE",
13617: " close Close one session",
13618: " enable ?BOOLEAN? Set or query the enable bit",
13619: " filter GLOB... Reject tables matching GLOBs",
13620: " indirect ?BOOLEAN? Mark or query the indirect status",
13621: " isempty Query whether the session is empty",
13622: " list List currently open session names",
13623: " open DB NAME Open a new session on DB",
13624: " patchset FILE Write a patchset into FILE",
13625: " If ?NAME? is omitted, the first defined session is used.",
13626: #endif
13627: ".sha3sum ... Compute a SHA3 hash of database content",
13628: " Options:",
1.4.2.3 ! misho 13629: " --schema Also hash the sqlite_schema table",
1.4.2.2 misho 13630: " --sha3-224 Use the sha3-224 algorithm",
1.4.2.3 ! misho 13631: " --sha3-256 Use the sha3-256 algorithm (default)",
1.4.2.2 misho 13632: " --sha3-384 Use the sha3-384 algorithm",
13633: " --sha3-512 Use the sha3-512 algorithm",
13634: " Any other argument is a LIKE pattern for tables to hash",
13635: #ifndef SQLITE_NOHAVE_SYSTEM
13636: ".shell CMD ARGS... Run CMD ARGS... in a system shell",
13637: #endif
13638: ".show Show the current values for various settings",
13639: ".stats ?on|off? Show stats or turn stats on or off",
13640: #ifndef SQLITE_NOHAVE_SYSTEM
13641: ".system CMD ARGS... Run CMD ARGS... in a system shell",
13642: #endif
13643: ".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
13644: ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
13645: ".testctrl CMD ... Run various sqlite3_test_control() operations",
13646: " Run \".testctrl\" with no arguments for details",
13647: ".timeout MS Try opening locked tables for MS milliseconds",
13648: ".timer on|off Turn SQL timer on or off",
13649: #ifndef SQLITE_OMIT_TRACE
13650: ".trace ?OPTIONS? Output each SQL statement as it is run",
13651: " FILE Send output to FILE",
13652: " stdout Send output to stdout",
13653: " stderr Send output to stderr",
13654: " off Disable tracing",
13655: " --expanded Expand query parameters",
13656: #ifdef SQLITE_ENABLE_NORMALIZE
13657: " --normalized Normal the SQL statements",
13658: #endif
13659: " --plain Show SQL as it is input",
13660: " --stmt Trace statement execution (SQLITE_TRACE_STMT)",
13661: " --profile Profile statements (SQLITE_TRACE_PROFILE)",
13662: " --row Trace each row (SQLITE_TRACE_ROW)",
13663: " --close Trace connection close (SQLITE_TRACE_CLOSE)",
13664: #endif /* SQLITE_OMIT_TRACE */
1.4.2.3 ! misho 13665: #ifdef SQLITE_DEBUG
! 13666: ".unmodule NAME ... Unregister virtual table modules",
! 13667: " --allexcept Unregister everything except those named",
! 13668: #endif
1.4.2.2 misho 13669: ".vfsinfo ?AUX? Information about the top-level VFS",
13670: ".vfslist List all available VFSes",
13671: ".vfsname ?AUX? Print the name of the VFS stack",
1.4.2.3 ! misho 13672: ".width NUM1 NUM2 ... Set minimum column widths for columnar output",
1.4.2.2 misho 13673: " Negative values right-justify",
13674: };
1.2 misho 13675:
13676: /*
1.4.2.2 misho 13677: ** Output help text.
1.2 misho 13678: **
1.4.2.2 misho 13679: ** zPattern describes the set of commands for which help text is provided.
13680: ** If zPattern is NULL, then show all commands, but only give a one-line
13681: ** description of each.
13682: **
13683: ** Return the number of matches.
1.2 misho 13684: */
1.4.2.2 misho 13685: static int showHelp(FILE *out, const char *zPattern){
13686: int i = 0;
13687: int j = 0;
13688: int n = 0;
13689: char *zPat;
13690: if( zPattern==0
13691: || zPattern[0]=='0'
13692: || strcmp(zPattern,"-a")==0
13693: || strcmp(zPattern,"-all")==0
1.4.2.3 ! misho 13694: || strcmp(zPattern,"--all")==0
1.4.2.2 misho 13695: ){
13696: /* Show all commands, but only one line per command */
13697: if( zPattern==0 ) zPattern = "";
13698: for(i=0; i<ArraySize(azHelp); i++){
13699: if( azHelp[i][0]=='.' || zPattern[0] ){
13700: utf8_printf(out, "%s\n", azHelp[i]);
13701: n++;
13702: }
1.2 misho 13703: }
1.4.2.2 misho 13704: }else{
13705: /* Look for commands that for which zPattern is an exact prefix */
13706: zPat = sqlite3_mprintf(".%s*", zPattern);
13707: for(i=0; i<ArraySize(azHelp); i++){
13708: if( sqlite3_strglob(zPat, azHelp[i])==0 ){
13709: utf8_printf(out, "%s\n", azHelp[i]);
13710: j = i+1;
13711: n++;
13712: }
13713: }
13714: sqlite3_free(zPat);
13715: if( n ){
13716: if( n==1 ){
13717: /* when zPattern is a prefix of exactly one command, then include the
13718: ** details of that command, which should begin at offset j */
13719: while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
13720: utf8_printf(out, "%s\n", azHelp[j]);
13721: j++;
13722: }
13723: }
13724: return n;
1.3 misho 13725: }
1.4.2.2 misho 13726: /* Look for commands that contain zPattern anywhere. Show the complete
13727: ** text of all commands that match. */
13728: zPat = sqlite3_mprintf("%%%s%%", zPattern);
13729: for(i=0; i<ArraySize(azHelp); i++){
13730: if( azHelp[i][0]=='.' ) j = i;
13731: if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
13732: utf8_printf(out, "%s\n", azHelp[j]);
13733: while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
13734: j++;
13735: utf8_printf(out, "%s\n", azHelp[j]);
13736: }
13737: i = j;
13738: n++;
13739: }
1.4 misho 13740: }
1.4.2.2 misho 13741: sqlite3_free(zPat);
1.2 misho 13742: }
1.4.2.2 misho 13743: return n;
13744: }
13745:
13746: /* Forward reference */
13747: static int process_input(ShellState *p);
13748:
13749: /*
13750: ** Read the content of file zName into memory obtained from sqlite3_malloc64()
13751: ** and return a pointer to the buffer. The caller is responsible for freeing
13752: ** the memory.
13753: **
13754: ** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
13755: ** read.
13756: **
13757: ** For convenience, a nul-terminator byte is always appended to the data read
13758: ** from the file before the buffer is returned. This byte is not included in
13759: ** the final value of (*pnByte), if applicable.
13760: **
13761: ** NULL is returned if any error is encountered. The final value of *pnByte
13762: ** is undefined in this case.
13763: */
13764: static char *readFile(const char *zName, int *pnByte){
13765: FILE *in = fopen(zName, "rb");
13766: long nIn;
13767: size_t nRead;
13768: char *pBuf;
13769: if( in==0 ) return 0;
13770: fseek(in, 0, SEEK_END);
13771: nIn = ftell(in);
13772: rewind(in);
13773: pBuf = sqlite3_malloc64( nIn+1 );
13774: if( pBuf==0 ){ fclose(in); return 0; }
13775: nRead = fread(pBuf, nIn, 1, in);
13776: fclose(in);
13777: if( nRead!=1 ){
13778: sqlite3_free(pBuf);
13779: return 0;
1.2 misho 13780: }
1.4.2.2 misho 13781: pBuf[nIn] = 0;
13782: if( pnByte ) *pnByte = nIn;
13783: return pBuf;
1.2 misho 13784: }
13785:
1.4.2.2 misho 13786: #if defined(SQLITE_ENABLE_SESSION)
1.2 misho 13787: /*
1.4.2.2 misho 13788: ** Close a single OpenSession object and release all of its associated
13789: ** resources.
1.2 misho 13790: */
1.4.2.2 misho 13791: static void session_close(OpenSession *pSession){
13792: int i;
13793: sqlite3session_delete(pSession->p);
13794: sqlite3_free(pSession->zName);
13795: for(i=0; i<pSession->nFilter; i++){
13796: sqlite3_free(pSession->azFilter[i]);
1.2 misho 13797: }
1.4.2.2 misho 13798: sqlite3_free(pSession->azFilter);
13799: memset(pSession, 0, sizeof(OpenSession));
1.2 misho 13800: }
1.4.2.2 misho 13801: #endif
1.2 misho 13802:
1.4 misho 13803: /*
1.4.2.2 misho 13804: ** Close all OpenSession objects and release all associated resources.
1.4 misho 13805: */
1.4.2.2 misho 13806: #if defined(SQLITE_ENABLE_SESSION)
13807: static void session_close_all(ShellState *p){
13808: int i;
13809: for(i=0; i<p->nSession; i++){
13810: session_close(&p->aSession[i]);
13811: }
13812: p->nSession = 0;
13813: }
13814: #else
13815: # define session_close_all(X)
13816: #endif
13817:
13818: /*
13819: ** Implementation of the xFilter function for an open session. Omit
13820: ** any tables named by ".session filter" but let all other table through.
13821: */
13822: #if defined(SQLITE_ENABLE_SESSION)
13823: static int session_filter(void *pCtx, const char *zTab){
13824: OpenSession *pSession = (OpenSession*)pCtx;
13825: int i;
13826: for(i=0; i<pSession->nFilter; i++){
13827: if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
1.4 misho 13828: }
1.4.2.2 misho 13829: return 1;
1.4 misho 13830: }
13831: #endif
13832:
1.4.2.1 misho 13833: /*
1.4.2.2 misho 13834: ** Try to deduce the type of file for zName based on its content. Return
13835: ** one of the SHELL_OPEN_* constants.
13836: **
13837: ** If the file does not exist or is empty but its name looks like a ZIP
13838: ** archive and the dfltZip flag is true, then assume it is a ZIP archive.
13839: ** Otherwise, assume an ordinary database regardless of the filename if
13840: ** the type cannot be determined from content.
13841: */
13842: int deduceDatabaseType(const char *zName, int dfltZip){
13843: FILE *f = fopen(zName, "rb");
13844: size_t n;
13845: int rc = SHELL_OPEN_UNSPEC;
13846: char zBuf[100];
13847: if( f==0 ){
13848: if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
13849: return SHELL_OPEN_ZIPFILE;
13850: }else{
13851: return SHELL_OPEN_NORMAL;
13852: }
1.4.2.1 misho 13853: }
1.4.2.2 misho 13854: n = fread(zBuf, 16, 1, f);
13855: if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
13856: fclose(f);
13857: return SHELL_OPEN_NORMAL;
13858: }
13859: fseek(f, -25, SEEK_END);
13860: n = fread(zBuf, 25, 1, f);
13861: if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
13862: rc = SHELL_OPEN_APPENDVFS;
1.4.2.1 misho 13863: }else{
1.4.2.2 misho 13864: fseek(f, -22, SEEK_END);
13865: n = fread(zBuf, 22, 1, f);
13866: if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
13867: && zBuf[3]==0x06 ){
13868: rc = SHELL_OPEN_ZIPFILE;
13869: }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
13870: rc = SHELL_OPEN_ZIPFILE;
13871: }
1.4.2.1 misho 13872: }
1.4.2.2 misho 13873: fclose(f);
13874: return rc;
1.4.2.1 misho 13875: }
1.4 misho 13876:
1.4.2.2 misho 13877: #ifdef SQLITE_ENABLE_DESERIALIZE
1.2 misho 13878: /*
1.4.2.2 misho 13879: ** Reconstruct an in-memory database using the output from the "dbtotxt"
13880: ** program. Read content from the file in p->zDbFilename. If p->zDbFilename
13881: ** is 0, then read from standard input.
1.2 misho 13882: */
1.4.2.2 misho 13883: static unsigned char *readHexDb(ShellState *p, int *pnData){
13884: unsigned char *a = 0;
13885: int nLine;
13886: int n = 0;
13887: int pgsz = 0;
13888: int iOffset = 0;
13889: int j, k;
13890: int rc;
13891: FILE *in;
13892: unsigned int x[16];
13893: char zLine[1000];
13894: if( p->zDbFilename ){
13895: in = fopen(p->zDbFilename, "r");
13896: if( in==0 ){
13897: utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
13898: return 0;
13899: }
13900: nLine = 0;
13901: }else{
13902: in = p->in;
13903: nLine = p->lineno;
13904: if( in==0 ) in = stdin;
13905: }
13906: *pnData = 0;
13907: nLine++;
13908: if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
13909: rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
13910: if( rc!=2 ) goto readHexDb_error;
13911: if( n<0 ) goto readHexDb_error;
1.4.2.3 ! misho 13912: if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
! 13913: n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */
1.4.2.2 misho 13914: a = sqlite3_malloc( n ? n : 1 );
13915: if( a==0 ){
13916: utf8_printf(stderr, "Out of memory!\n");
13917: goto readHexDb_error;
13918: }
13919: memset(a, 0, n);
13920: if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
13921: utf8_printf(stderr, "invalid pagesize\n");
13922: goto readHexDb_error;
13923: }
13924: for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){
13925: rc = sscanf(zLine, "| page %d offset %d", &j, &k);
13926: if( rc==2 ){
13927: iOffset = k;
13928: continue;
13929: }
13930: if( strncmp(zLine, "| end ", 6)==0 ){
13931: break;
13932: }
13933: rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
13934: &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
13935: &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
13936: if( rc==17 ){
13937: k = iOffset+j;
13938: if( k+16<=n ){
13939: int ii;
13940: for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
13941: }
1.4 misho 13942: }
1.2 misho 13943: }
1.4.2.2 misho 13944: *pnData = n;
13945: if( in!=p->in ){
13946: fclose(in);
13947: }else{
13948: p->lineno = nLine;
1.2 misho 13949: }
1.4.2.2 misho 13950: return a;
1.2 misho 13951:
1.4.2.2 misho 13952: readHexDb_error:
13953: if( in!=p->in ){
13954: fclose(in);
13955: }else{
13956: while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
13957: nLine++;
13958: if(strncmp(zLine, "| end ", 6)==0 ) break;
13959: }
13960: p->lineno = nLine;
13961: }
13962: sqlite3_free(a);
13963: utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
1.2 misho 13964: return 0;
13965: }
1.4.2.2 misho 13966: #endif /* SQLITE_ENABLE_DESERIALIZE */
1.2 misho 13967:
13968: /*
1.4.2.2 misho 13969: ** Scalar function "shell_int32". The first argument to this function
13970: ** must be a blob. The second a non-negative integer. This function
13971: ** reads and returns a 32-bit big-endian integer from byte
13972: ** offset (4*<arg2>) of the blob.
1.2 misho 13973: */
1.4.2.2 misho 13974: static void shellInt32(
13975: sqlite3_context *context,
13976: int argc,
13977: sqlite3_value **argv
1.2 misho 13978: ){
1.4.2.2 misho 13979: const unsigned char *pBlob;
13980: int nBlob;
13981: int iInt;
1.2 misho 13982:
1.4.2.2 misho 13983: UNUSED_PARAMETER(argc);
13984: nBlob = sqlite3_value_bytes(argv[0]);
13985: pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
13986: iInt = sqlite3_value_int(argv[1]);
13987:
13988: if( iInt>=0 && (iInt+1)*4<=nBlob ){
13989: const unsigned char *a = &pBlob[iInt*4];
13990: sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24)
13991: + ((sqlite3_int64)a[1]<<16)
13992: + ((sqlite3_int64)a[2]<< 8)
13993: + ((sqlite3_int64)a[3]<< 0);
13994: sqlite3_result_int64(context, iVal);
1.4 misho 13995: }
13996: }
1.2 misho 13997:
1.4 misho 13998: /*
1.4.2.3 ! misho 13999: ** Scalar function "shell_idquote(X)" returns string X quoted as an identifier,
! 14000: ** using "..." with internal double-quote characters doubled.
! 14001: */
! 14002: static void shellIdQuote(
! 14003: sqlite3_context *context,
! 14004: int argc,
! 14005: sqlite3_value **argv
! 14006: ){
! 14007: const char *zName = (const char*)sqlite3_value_text(argv[0]);
! 14008: UNUSED_PARAMETER(argc);
! 14009: if( zName ){
! 14010: char *z = sqlite3_mprintf("\"%w\"", zName);
! 14011: sqlite3_result_text(context, z, -1, sqlite3_free);
! 14012: }
! 14013: }
! 14014:
! 14015: /*
1.4.2.2 misho 14016: ** Scalar function "shell_escape_crnl" used by the .recover command.
14017: ** The argument passed to this function is the output of built-in
14018: ** function quote(). If the first character of the input is "'",
14019: ** indicating that the value passed to quote() was a text value,
14020: ** then this function searches the input for "\n" and "\r" characters
14021: ** and adds a wrapper similar to the following:
1.4 misho 14022: **
1.4.2.2 misho 14023: ** replace(replace(<input>, '\n', char(10), '\r', char(13));
1.4 misho 14024: **
1.4.2.2 misho 14025: ** Or, if the first character of the input is not "'", then a copy
14026: ** of the input is returned.
1.4 misho 14027: */
1.4.2.2 misho 14028: static void shellEscapeCrnl(
14029: sqlite3_context *context,
14030: int argc,
14031: sqlite3_value **argv
14032: ){
14033: const char *zText = (const char*)sqlite3_value_text(argv[0]);
14034: UNUSED_PARAMETER(argc);
14035: if( zText[0]=='\'' ){
14036: int nText = sqlite3_value_bytes(argv[0]);
1.4 misho 14037: int i;
1.4.2.2 misho 14038: char zBuf1[20];
14039: char zBuf2[20];
14040: const char *zNL = 0;
14041: const char *zCR = 0;
14042: int nCR = 0;
14043: int nNL = 0;
1.2 misho 14044:
1.4.2.2 misho 14045: for(i=0; zText[i]; i++){
14046: if( zNL==0 && zText[i]=='\n' ){
14047: zNL = unused_string(zText, "\\n", "\\012", zBuf1);
14048: nNL = (int)strlen(zNL);
14049: }
14050: if( zCR==0 && zText[i]=='\r' ){
14051: zCR = unused_string(zText, "\\r", "\\015", zBuf2);
14052: nCR = (int)strlen(zCR);
14053: }
14054: }
1.4 misho 14055:
1.4.2.2 misho 14056: if( zNL || zCR ){
14057: int iOut = 0;
14058: i64 nMax = (nNL > nCR) ? nNL : nCR;
14059: i64 nAlloc = nMax * nText + (nMax+64)*2;
14060: char *zOut = (char*)sqlite3_malloc64(nAlloc);
14061: if( zOut==0 ){
14062: sqlite3_result_error_nomem(context);
14063: return;
14064: }
14065:
14066: if( zNL && zCR ){
14067: memcpy(&zOut[iOut], "replace(replace(", 16);
14068: iOut += 16;
14069: }else{
14070: memcpy(&zOut[iOut], "replace(", 8);
14071: iOut += 8;
14072: }
14073: for(i=0; zText[i]; i++){
14074: if( zText[i]=='\n' ){
14075: memcpy(&zOut[iOut], zNL, nNL);
14076: iOut += nNL;
14077: }else if( zText[i]=='\r' ){
14078: memcpy(&zOut[iOut], zCR, nCR);
14079: iOut += nCR;
14080: }else{
14081: zOut[iOut] = zText[i];
14082: iOut++;
1.2 misho 14083: }
14084: }
1.4 misho 14085:
1.4.2.2 misho 14086: if( zNL ){
14087: memcpy(&zOut[iOut], ",'", 2); iOut += 2;
14088: memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
14089: memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
14090: }
14091: if( zCR ){
14092: memcpy(&zOut[iOut], ",'", 2); iOut += 2;
14093: memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
14094: memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
14095: }
14096:
14097: sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
14098: sqlite3_free(zOut);
14099: return;
1.4 misho 14100: }
14101: }
14102:
1.4.2.2 misho 14103: sqlite3_result_value(context, argv[0]);
1.4 misho 14104: }
14105:
1.4.2.2 misho 14106: /* Flags for open_db().
14107: **
14108: ** The default behavior of open_db() is to exit(1) if the database fails to
14109: ** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
14110: ** but still returns without calling exit.
14111: **
14112: ** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a
14113: ** ZIP archive if the file does not exist or is empty and its name matches
14114: ** the *.zip pattern.
1.4 misho 14115: */
1.4.2.2 misho 14116: #define OPEN_DB_KEEPALIVE 0x001 /* Return after error if true */
14117: #define OPEN_DB_ZIPFILE 0x002 /* Open as ZIP if name matches *.zip */
1.4 misho 14118:
14119: /*
1.4.2.2 misho 14120: ** Make sure the database is open. If it is not, then open it. If
14121: ** the database fails to open, print an error message and exit.
1.4 misho 14122: */
1.4.2.2 misho 14123: static void open_db(ShellState *p, int openFlags){
14124: if( p->db==0 ){
14125: if( p->openMode==SHELL_OPEN_UNSPEC ){
14126: if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){
14127: p->openMode = SHELL_OPEN_NORMAL;
14128: }else{
14129: p->openMode = (u8)deduceDatabaseType(p->zDbFilename,
14130: (openFlags & OPEN_DB_ZIPFILE)!=0);
14131: }
14132: }
14133: switch( p->openMode ){
14134: case SHELL_OPEN_APPENDVFS: {
14135: sqlite3_open_v2(p->zDbFilename, &p->db,
1.4.2.3 ! misho 14136: SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs");
1.4.2.2 misho 14137: break;
14138: }
14139: case SHELL_OPEN_HEXDB:
14140: case SHELL_OPEN_DESERIALIZE: {
14141: sqlite3_open(0, &p->db);
14142: break;
14143: }
14144: case SHELL_OPEN_ZIPFILE: {
14145: sqlite3_open(":memory:", &p->db);
14146: break;
14147: }
14148: case SHELL_OPEN_READONLY: {
1.4.2.3 ! misho 14149: sqlite3_open_v2(p->zDbFilename, &p->db,
! 14150: SQLITE_OPEN_READONLY|p->openFlags, 0);
1.4.2.2 misho 14151: break;
14152: }
14153: case SHELL_OPEN_UNSPEC:
14154: case SHELL_OPEN_NORMAL: {
1.4.2.3 ! misho 14155: sqlite3_open_v2(p->zDbFilename, &p->db,
! 14156: SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
1.4.2.2 misho 14157: break;
14158: }
14159: }
14160: globalDb = p->db;
14161: if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
14162: utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
14163: p->zDbFilename, sqlite3_errmsg(p->db));
14164: if( openFlags & OPEN_DB_KEEPALIVE ){
14165: sqlite3_open(":memory:", &p->db);
14166: return;
14167: }
14168: exit(1);
14169: }
14170: #ifndef SQLITE_OMIT_LOAD_EXTENSION
14171: sqlite3_enable_load_extension(p->db, 1);
1.4 misho 14172: #endif
1.4.2.2 misho 14173: sqlite3_fileio_init(p->db, 0, 0);
14174: sqlite3_shathree_init(p->db, 0, 0);
14175: sqlite3_completion_init(p->db, 0, 0);
1.4.2.3 ! misho 14176: sqlite3_uint_init(p->db, 0, 0);
! 14177: sqlite3_decimal_init(p->db, 0, 0);
! 14178: sqlite3_ieee_init(p->db, 0, 0);
1.4.2.2 misho 14179: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
14180: sqlite3_dbdata_init(p->db, 0, 0);
14181: #endif
14182: #ifdef SQLITE_HAVE_ZLIB
14183: sqlite3_zipfile_init(p->db, 0, 0);
14184: sqlite3_sqlar_init(p->db, 0, 0);
14185: #endif
14186: sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
14187: shellAddSchemaName, 0, 0);
14188: sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
14189: shellModuleSchema, 0, 0);
14190: sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
14191: shellPutsFunc, 0, 0);
14192: sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0,
14193: shellEscapeCrnl, 0, 0);
14194: sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
14195: shellInt32, 0, 0);
1.4.2.3 ! misho 14196: sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
! 14197: shellIdQuote, 0, 0);
1.4.2.2 misho 14198: #ifndef SQLITE_NOHAVE_SYSTEM
14199: sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
14200: editFunc, 0, 0);
14201: sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
14202: editFunc, 0, 0);
14203: #endif
14204: if( p->openMode==SHELL_OPEN_ZIPFILE ){
14205: char *zSql = sqlite3_mprintf(
14206: "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
14207: sqlite3_exec(p->db, zSql, 0, 0, 0);
14208: sqlite3_free(zSql);
14209: }
14210: #ifdef SQLITE_ENABLE_DESERIALIZE
14211: else
14212: if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){
14213: int rc;
14214: int nData = 0;
14215: unsigned char *aData;
14216: if( p->openMode==SHELL_OPEN_DESERIALIZE ){
14217: aData = (unsigned char*)readFile(p->zDbFilename, &nData);
14218: }else{
14219: aData = readHexDb(p, &nData);
14220: if( aData==0 ){
14221: return;
14222: }
14223: }
14224: rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
14225: SQLITE_DESERIALIZE_RESIZEABLE |
14226: SQLITE_DESERIALIZE_FREEONCLOSE);
14227: if( rc ){
14228: utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
14229: }
14230: if( p->szMax>0 ){
14231: sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
14232: }
14233: }
1.4 misho 14234: #endif
1.4.2.2 misho 14235: }
1.4 misho 14236: }
1.4.2.2 misho 14237:
14238: /*
14239: ** Attempt to close the databaes connection. Report errors.
14240: */
14241: void close_db(sqlite3 *db){
14242: int rc = sqlite3_close(db);
14243: if( rc ){
14244: utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
14245: rc, sqlite3_errmsg(db));
14246: }
1.4 misho 14247: }
14248:
1.4.2.2 misho 14249: #if HAVE_READLINE || HAVE_EDITLINE
1.4 misho 14250: /*
1.4.2.2 misho 14251: ** Readline completion callbacks
1.4 misho 14252: */
1.4.2.2 misho 14253: static char *readline_completion_generator(const char *text, int state){
14254: static sqlite3_stmt *pStmt = 0;
14255: char *zRet;
14256: if( state==0 ){
14257: char *zSql;
14258: sqlite3_finalize(pStmt);
14259: zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
14260: " FROM completion(%Q) ORDER BY 1", text);
14261: sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
14262: sqlite3_free(zSql);
14263: }
14264: if( sqlite3_step(pStmt)==SQLITE_ROW ){
14265: zRet = strdup((const char*)sqlite3_column_text(pStmt, 0));
14266: }else{
14267: sqlite3_finalize(pStmt);
14268: pStmt = 0;
14269: zRet = 0;
14270: }
14271: return zRet;
14272: }
14273: static char **readline_completion(const char *zText, int iStart, int iEnd){
14274: rl_attempted_completion_over = 1;
14275: return rl_completion_matches(zText, readline_completion_generator);
14276: }
1.4 misho 14277:
1.4.2.2 misho 14278: #elif HAVE_LINENOISE
14279: /*
14280: ** Linenoise completion callback
14281: */
14282: static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
14283: int nLine = strlen30(zLine);
14284: int i, iStart;
14285: sqlite3_stmt *pStmt = 0;
14286: char *zSql;
14287: char zBuf[1000];
1.4 misho 14288:
1.4.2.2 misho 14289: if( nLine>sizeof(zBuf)-30 ) return;
14290: if( zLine[0]=='.' || zLine[0]=='#') return;
14291: for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
14292: if( i==nLine-1 ) return;
14293: iStart = i+1;
14294: memcpy(zBuf, zLine, iStart);
14295: zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
14296: " FROM completion(%Q,%Q) ORDER BY 1",
14297: &zLine[iStart], zLine);
14298: sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
14299: sqlite3_free(zSql);
14300: sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */
14301: while( sqlite3_step(pStmt)==SQLITE_ROW ){
14302: const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0);
14303: int nCompletion = sqlite3_column_bytes(pStmt, 0);
14304: if( iStart+nCompletion < sizeof(zBuf)-1 ){
14305: memcpy(zBuf+iStart, zCompletion, nCompletion+1);
14306: linenoiseAddCompletion(lc, zBuf);
1.4 misho 14307: }
14308: }
1.4.2.2 misho 14309: sqlite3_finalize(pStmt);
1.4 misho 14310: }
1.4.2.2 misho 14311: #endif
1.4 misho 14312:
14313: /*
1.4.2.2 misho 14314: ** Do C-language style dequoting.
1.4 misho 14315: **
1.4.2.2 misho 14316: ** \a -> alarm
14317: ** \b -> backspace
14318: ** \t -> tab
14319: ** \n -> newline
14320: ** \v -> vertical tab
14321: ** \f -> form feed
14322: ** \r -> carriage return
14323: ** \s -> space
14324: ** \" -> "
14325: ** \' -> '
14326: ** \\ -> backslash
14327: ** \NNN -> ascii character NNN in octal
1.4 misho 14328: */
1.4.2.2 misho 14329: static void resolve_backslashes(char *z){
14330: int i, j;
14331: char c;
14332: while( *z && *z!='\\' ) z++;
14333: for(i=j=0; (c = z[i])!=0; i++, j++){
14334: if( c=='\\' && z[i+1]!=0 ){
14335: c = z[++i];
14336: if( c=='a' ){
14337: c = '\a';
14338: }else if( c=='b' ){
14339: c = '\b';
14340: }else if( c=='t' ){
14341: c = '\t';
14342: }else if( c=='n' ){
14343: c = '\n';
14344: }else if( c=='v' ){
14345: c = '\v';
14346: }else if( c=='f' ){
14347: c = '\f';
14348: }else if( c=='r' ){
14349: c = '\r';
14350: }else if( c=='"' ){
14351: c = '"';
14352: }else if( c=='\'' ){
14353: c = '\'';
14354: }else if( c=='\\' ){
14355: c = '\\';
14356: }else if( c>='0' && c<='7' ){
14357: c -= '0';
14358: if( z[i+1]>='0' && z[i+1]<='7' ){
14359: i++;
14360: c = (c<<3) + z[i] - '0';
14361: if( z[i+1]>='0' && z[i+1]<='7' ){
14362: i++;
14363: c = (c<<3) + z[i] - '0';
1.4 misho 14364: }
14365: }
14366: }
1.4.2.2 misho 14367: }
14368: z[j] = c;
14369: }
14370: if( j<i ) z[j] = 0;
14371: }
1.4 misho 14372:
1.4.2.2 misho 14373: /*
14374: ** Interpret zArg as either an integer or a boolean value. Return 1 or 0
14375: ** for TRUE and FALSE. Return the integer value if appropriate.
14376: */
14377: static int booleanValue(const char *zArg){
14378: int i;
14379: if( zArg[0]=='0' && zArg[1]=='x' ){
14380: for(i=2; hexDigitValue(zArg[i])>=0; i++){}
14381: }else{
14382: for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
14383: }
14384: if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
14385: if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
14386: return 1;
14387: }
14388: if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
14389: return 0;
14390: }
14391: utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
14392: zArg);
14393: return 0;
14394: }
1.4 misho 14395:
1.4.2.2 misho 14396: /*
14397: ** Set or clear a shell flag according to a boolean value.
14398: */
14399: static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){
14400: if( booleanValue(zArg) ){
14401: ShellSetFlag(p, mFlag);
14402: }else{
14403: ShellClearFlag(p, mFlag);
14404: }
14405: }
1.4 misho 14406:
1.4.2.2 misho 14407: /*
14408: ** Close an output file, assuming it is not stderr or stdout
14409: */
14410: static void output_file_close(FILE *f){
14411: if( f && f!=stdout && f!=stderr ) fclose(f);
14412: }
1.2 misho 14413:
1.4.2.2 misho 14414: /*
14415: ** Try to open an output file. The names "stdout" and "stderr" are
14416: ** recognized and do the right thing. NULL is returned if the output
14417: ** filename is "off".
14418: */
14419: static FILE *output_file_open(const char *zFile, int bTextMode){
14420: FILE *f;
14421: if( strcmp(zFile,"stdout")==0 ){
14422: f = stdout;
14423: }else if( strcmp(zFile, "stderr")==0 ){
14424: f = stderr;
14425: }else if( strcmp(zFile, "off")==0 ){
14426: f = 0;
14427: }else{
14428: f = fopen(zFile, bTextMode ? "w" : "wb");
14429: if( f==0 ){
14430: utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
14431: }
14432: }
14433: return f;
14434: }
1.2 misho 14435:
1.4.2.2 misho 14436: #ifndef SQLITE_OMIT_TRACE
14437: /*
14438: ** A routine for handling output from sqlite3_trace().
14439: */
14440: static int sql_trace_callback(
14441: unsigned mType, /* The trace type */
14442: void *pArg, /* The ShellState pointer */
14443: void *pP, /* Usually a pointer to sqlite_stmt */
14444: void *pX /* Auxiliary output */
14445: ){
14446: ShellState *p = (ShellState*)pArg;
14447: sqlite3_stmt *pStmt;
14448: const char *zSql;
14449: int nSql;
14450: if( p->traceOut==0 ) return 0;
14451: if( mType==SQLITE_TRACE_CLOSE ){
14452: utf8_printf(p->traceOut, "-- closing database connection\n");
14453: return 0;
14454: }
14455: if( mType!=SQLITE_TRACE_ROW && ((const char*)pX)[0]=='-' ){
14456: zSql = (const char*)pX;
14457: }else{
14458: pStmt = (sqlite3_stmt*)pP;
14459: switch( p->eTraceType ){
14460: case SHELL_TRACE_EXPANDED: {
14461: zSql = sqlite3_expanded_sql(pStmt);
14462: break;
1.4 misho 14463: }
1.4.2.2 misho 14464: #ifdef SQLITE_ENABLE_NORMALIZE
14465: case SHELL_TRACE_NORMALIZED: {
14466: zSql = sqlite3_normalized_sql(pStmt);
14467: break;
1.2 misho 14468: }
1.4.2.2 misho 14469: #endif
14470: default: {
14471: zSql = sqlite3_sql(pStmt);
14472: break;
1.2 misho 14473: }
14474: }
1.4.2.2 misho 14475: }
14476: if( zSql==0 ) return 0;
14477: nSql = strlen30(zSql);
14478: while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; }
14479: switch( mType ){
14480: case SQLITE_TRACE_ROW:
14481: case SQLITE_TRACE_STMT: {
14482: utf8_printf(p->traceOut, "%.*s;\n", nSql, zSql);
14483: break;
14484: }
14485: case SQLITE_TRACE_PROFILE: {
14486: sqlite3_int64 nNanosec = *(sqlite3_int64*)pX;
14487: utf8_printf(p->traceOut, "%.*s; -- %lld ns\n", nSql, zSql, nNanosec);
14488: break;
14489: }
14490: }
14491: return 0;
1.2 misho 14492: }
1.4.2.2 misho 14493: #endif
1.2 misho 14494:
1.4.2.1 misho 14495: /*
1.4.2.2 misho 14496: ** A no-op routine that runs with the ".breakpoint" doc-command. This is
14497: ** a useful spot to set a debugger breakpoint.
1.4.2.1 misho 14498: */
1.4.2.2 misho 14499: static void test_breakpoint(void){
14500: static int nCall = 0;
14501: nCall++;
1.4.2.1 misho 14502: }
14503:
14504: /*
1.4.2.2 misho 14505: ** An object used to read a CSV and other files for import.
1.4.2.1 misho 14506: */
1.4.2.2 misho 14507: typedef struct ImportCtx ImportCtx;
14508: struct ImportCtx {
14509: const char *zFile; /* Name of the input file */
14510: FILE *in; /* Read the CSV text from this input stream */
1.4.2.3 ! misho 14511: int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */
1.4.2.2 misho 14512: char *z; /* Accumulated text for a field */
14513: int n; /* Number of bytes in z */
14514: int nAlloc; /* Space allocated for z[] */
14515: int nLine; /* Current line number */
1.4.2.3 ! misho 14516: int nRow; /* Number of rows imported */
! 14517: int nErr; /* Number of errors encountered */
1.4.2.2 misho 14518: int bNotFirst; /* True if one or more bytes already read */
14519: int cTerm; /* Character that terminated the most recent field */
14520: int cColSep; /* The column separator character. (Usually ",") */
14521: int cRowSep; /* The row separator character. (Usually "\n") */
14522: };
1.4.2.1 misho 14523:
1.4.2.3 ! misho 14524: /* Clean up resourced used by an ImportCtx */
! 14525: static void import_cleanup(ImportCtx *p){
! 14526: if( p->in!=0 && p->xCloser!=0 ){
! 14527: p->xCloser(p->in);
! 14528: p->in = 0;
! 14529: }
! 14530: sqlite3_free(p->z);
! 14531: p->z = 0;
! 14532: }
! 14533:
1.4.2.2 misho 14534: /* Append a single byte to z[] */
14535: static void import_append_char(ImportCtx *p, int c){
14536: if( p->n+1>=p->nAlloc ){
14537: p->nAlloc += p->nAlloc + 100;
14538: p->z = sqlite3_realloc64(p->z, p->nAlloc);
14539: if( p->z==0 ) shell_out_of_memory();
1.4.2.1 misho 14540: }
1.4.2.2 misho 14541: p->z[p->n++] = (char)c;
14542: }
1.4.2.1 misho 14543:
1.4.2.2 misho 14544: /* Read a single field of CSV text. Compatible with rfc4180 and extended
14545: ** with the option of having a separator other than ",".
14546: **
14547: ** + Input comes from p->in.
14548: ** + Store results in p->z of length p->n. Space to hold p->z comes
14549: ** from sqlite3_malloc64().
14550: ** + Use p->cSep as the column separator. The default is ",".
14551: ** + Use p->rSep as the row separator. The default is "\n".
14552: ** + Keep track of the line number in p->nLine.
14553: ** + Store the character that terminates the field in p->cTerm. Store
14554: ** EOF on end-of-file.
14555: ** + Report syntax errors on stderr
14556: */
14557: static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
14558: int c;
14559: int cSep = p->cColSep;
14560: int rSep = p->cRowSep;
14561: p->n = 0;
14562: c = fgetc(p->in);
14563: if( c==EOF || seenInterrupt ){
14564: p->cTerm = EOF;
14565: return 0;
14566: }
14567: if( c=='"' ){
14568: int pc, ppc;
14569: int startLine = p->nLine;
14570: int cQuote = c;
14571: pc = ppc = 0;
14572: while( 1 ){
14573: c = fgetc(p->in);
14574: if( c==rSep ) p->nLine++;
14575: if( c==cQuote ){
14576: if( pc==cQuote ){
14577: pc = 0;
14578: continue;
14579: }
1.4.2.1 misho 14580: }
1.4.2.2 misho 14581: if( (c==cSep && pc==cQuote)
14582: || (c==rSep && pc==cQuote)
14583: || (c==rSep && pc=='\r' && ppc==cQuote)
14584: || (c==EOF && pc==cQuote)
14585: ){
14586: do{ p->n--; }while( p->z[p->n]!=cQuote );
14587: p->cTerm = c;
14588: break;
14589: }
14590: if( pc==cQuote && c!='\r' ){
14591: utf8_printf(stderr, "%s:%d: unescaped %c character\n",
14592: p->zFile, p->nLine, cQuote);
14593: }
14594: if( c==EOF ){
14595: utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
14596: p->zFile, startLine, cQuote);
14597: p->cTerm = c;
1.4.2.1 misho 14598: break;
14599: }
1.4.2.2 misho 14600: import_append_char(p, c);
14601: ppc = pc;
14602: pc = c;
14603: }
14604: }else{
14605: /* If this is the first field being parsed and it begins with the
14606: ** UTF-8 BOM (0xEF BB BF) then skip the BOM */
14607: if( (c&0xff)==0xef && p->bNotFirst==0 ){
14608: import_append_char(p, c);
14609: c = fgetc(p->in);
14610: if( (c&0xff)==0xbb ){
14611: import_append_char(p, c);
14612: c = fgetc(p->in);
14613: if( (c&0xff)==0xbf ){
14614: p->bNotFirst = 1;
14615: p->n = 0;
14616: return csv_read_one_field(p);
14617: }
14618: }
14619: }
14620: while( c!=EOF && c!=cSep && c!=rSep ){
14621: import_append_char(p, c);
14622: c = fgetc(p->in);
14623: }
14624: if( c==rSep ){
14625: p->nLine++;
14626: if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
1.4.2.1 misho 14627: }
1.4.2.2 misho 14628: p->cTerm = c;
1.4.2.1 misho 14629: }
1.4.2.2 misho 14630: if( p->z ) p->z[p->n] = 0;
14631: p->bNotFirst = 1;
14632: return p->z;
1.4.2.1 misho 14633: }
14634:
1.4.2.2 misho 14635: /* Read a single field of ASCII delimited text.
14636: **
14637: ** + Input comes from p->in.
14638: ** + Store results in p->z of length p->n. Space to hold p->z comes
14639: ** from sqlite3_malloc64().
14640: ** + Use p->cSep as the column separator. The default is "\x1F".
14641: ** + Use p->rSep as the row separator. The default is "\x1E".
14642: ** + Keep track of the row number in p->nLine.
14643: ** + Store the character that terminates the field in p->cTerm. Store
14644: ** EOF on end-of-file.
14645: ** + Report syntax errors on stderr
1.4.2.1 misho 14646: */
1.4.2.2 misho 14647: static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
14648: int c;
14649: int cSep = p->cColSep;
14650: int rSep = p->cRowSep;
14651: p->n = 0;
14652: c = fgetc(p->in);
14653: if( c==EOF || seenInterrupt ){
14654: p->cTerm = EOF;
14655: return 0;
1.4.2.1 misho 14656: }
1.4.2.2 misho 14657: while( c!=EOF && c!=cSep && c!=rSep ){
14658: import_append_char(p, c);
14659: c = fgetc(p->in);
14660: }
14661: if( c==rSep ){
14662: p->nLine++;
14663: }
14664: p->cTerm = c;
14665: if( p->z ) p->z[p->n] = 0;
14666: return p->z;
1.4.2.1 misho 14667: }
1.2 misho 14668:
14669: /*
1.4.2.2 misho 14670: ** Try to transfer data for table zTable. If an error is seen while
14671: ** moving forward, try to go backwards. The backwards movement won't
14672: ** work for WITHOUT ROWID tables.
1.2 misho 14673: */
1.4.2.2 misho 14674: static void tryToCloneData(
14675: ShellState *p,
14676: sqlite3 *newDb,
14677: const char *zTable
14678: ){
14679: sqlite3_stmt *pQuery = 0;
14680: sqlite3_stmt *pInsert = 0;
14681: char *zQuery = 0;
14682: char *zInsert = 0;
1.2 misho 14683: int rc;
1.4.2.2 misho 14684: int i, j, n;
14685: int nTable = strlen30(zTable);
14686: int k = 0;
14687: int cnt = 0;
14688: const int spinRate = 10000;
1.4 misho 14689:
1.4.2.2 misho 14690: zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
14691: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
14692: if( rc ){
14693: utf8_printf(stderr, "Error %d: %s on [%s]\n",
14694: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
14695: zQuery);
14696: goto end_data_xfer;
1.2 misho 14697: }
1.4.2.2 misho 14698: n = sqlite3_column_count(pQuery);
14699: zInsert = sqlite3_malloc64(200 + nTable + n*3);
14700: if( zInsert==0 ) shell_out_of_memory();
14701: sqlite3_snprintf(200+nTable,zInsert,
14702: "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
14703: i = strlen30(zInsert);
14704: for(j=1; j<n; j++){
14705: memcpy(zInsert+i, ",?", 2);
14706: i += 2;
14707: }
14708: memcpy(zInsert+i, ");", 3);
14709: rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
14710: if( rc ){
14711: utf8_printf(stderr, "Error %d: %s on [%s]\n",
14712: sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
14713: zQuery);
14714: goto end_data_xfer;
14715: }
14716: for(k=0; k<2; k++){
14717: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
14718: for(i=0; i<n; i++){
14719: switch( sqlite3_column_type(pQuery, i) ){
14720: case SQLITE_NULL: {
14721: sqlite3_bind_null(pInsert, i+1);
14722: break;
14723: }
14724: case SQLITE_INTEGER: {
14725: sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
14726: break;
14727: }
14728: case SQLITE_FLOAT: {
14729: sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
14730: break;
14731: }
14732: case SQLITE_TEXT: {
14733: sqlite3_bind_text(pInsert, i+1,
14734: (const char*)sqlite3_column_text(pQuery,i),
14735: -1, SQLITE_STATIC);
14736: break;
14737: }
14738: case SQLITE_BLOB: {
14739: sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
14740: sqlite3_column_bytes(pQuery,i),
14741: SQLITE_STATIC);
14742: break;
14743: }
14744: }
14745: } /* End for */
14746: rc = sqlite3_step(pInsert);
14747: if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
14748: utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
14749: sqlite3_errmsg(newDb));
1.4.2.1 misho 14750: }
1.4.2.2 misho 14751: sqlite3_reset(pInsert);
14752: cnt++;
14753: if( (cnt%spinRate)==0 ){
14754: printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
14755: fflush(stdout);
1.4.2.1 misho 14756: }
1.4.2.2 misho 14757: } /* End while */
14758: if( rc==SQLITE_DONE ) break;
14759: sqlite3_finalize(pQuery);
14760: sqlite3_free(zQuery);
14761: zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
14762: zTable);
14763: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
14764: if( rc ){
14765: utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
14766: break;
1.4.2.1 misho 14767: }
1.4.2.2 misho 14768: } /* End for(k=0...) */
1.4.2.1 misho 14769:
1.4.2.2 misho 14770: end_data_xfer:
14771: sqlite3_finalize(pQuery);
14772: sqlite3_finalize(pInsert);
14773: sqlite3_free(zQuery);
14774: sqlite3_free(zInsert);
1.2 misho 14775: }
14776:
1.4.2.2 misho 14777:
1.2 misho 14778: /*
1.4.2.2 misho 14779: ** Try to transfer all rows of the schema that match zWhere. For
14780: ** each row, invoke xForEach() on the object defined by that row.
14781: ** If an error is encountered while moving forward through the
1.4.2.3 ! misho 14782: ** sqlite_schema table, try again moving backwards.
1.2 misho 14783: */
1.4.2.2 misho 14784: static void tryToCloneSchema(
1.4 misho 14785: ShellState *p,
1.4.2.2 misho 14786: sqlite3 *newDb,
14787: const char *zWhere,
14788: void (*xForEach)(ShellState*,sqlite3*,const char*)
1.2 misho 14789: ){
1.4.2.2 misho 14790: sqlite3_stmt *pQuery = 0;
14791: char *zQuery = 0;
1.2 misho 14792: int rc;
1.4.2.2 misho 14793: const unsigned char *zName;
14794: const unsigned char *zSql;
14795: char *zErrMsg = 0;
14796:
1.4.2.3 ! misho 14797: zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
1.4.2.2 misho 14798: " WHERE %s", zWhere);
14799: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
14800: if( rc ){
14801: utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
14802: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
14803: zQuery);
14804: goto end_schema_xfer;
14805: }
14806: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
14807: zName = sqlite3_column_text(pQuery, 0);
14808: zSql = sqlite3_column_text(pQuery, 1);
14809: printf("%s... ", zName); fflush(stdout);
14810: sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
14811: if( zErrMsg ){
14812: utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
14813: sqlite3_free(zErrMsg);
14814: zErrMsg = 0;
1.2 misho 14815: }
1.4.2.2 misho 14816: if( xForEach ){
14817: xForEach(p, newDb, (const char*)zName);
14818: }
14819: printf("done\n");
14820: }
14821: if( rc!=SQLITE_DONE ){
14822: sqlite3_finalize(pQuery);
14823: sqlite3_free(zQuery);
1.4.2.3 ! misho 14824: zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
1.4.2.2 misho 14825: " WHERE %s ORDER BY rowid DESC", zWhere);
14826: rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
1.2 misho 14827: if( rc ){
1.4.2.2 misho 14828: utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
14829: sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
14830: zQuery);
14831: goto end_schema_xfer;
14832: }
14833: while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
14834: zName = sqlite3_column_text(pQuery, 0);
14835: zSql = sqlite3_column_text(pQuery, 1);
14836: printf("%s... ", zName); fflush(stdout);
14837: sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
14838: if( zErrMsg ){
14839: utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
14840: sqlite3_free(zErrMsg);
14841: zErrMsg = 0;
14842: }
14843: if( xForEach ){
14844: xForEach(p, newDb, (const char*)zName);
14845: }
14846: printf("done\n");
1.2 misho 14847: }
14848: }
1.4.2.2 misho 14849: end_schema_xfer:
14850: sqlite3_finalize(pQuery);
14851: sqlite3_free(zQuery);
1.4 misho 14852: }
1.4.2.1 misho 14853:
14854: /*
1.4.2.2 misho 14855: ** Open a new database file named "zNewDb". Try to recover as much information
14856: ** as possible out of the main database (which might be corrupt) and write it
14857: ** into zNewDb.
1.4.2.1 misho 14858: */
1.4.2.2 misho 14859: static void tryToClone(ShellState *p, const char *zNewDb){
14860: int rc;
14861: sqlite3 *newDb = 0;
14862: if( access(zNewDb,0)==0 ){
14863: utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
14864: return;
1.4.2.1 misho 14865: }
1.4.2.2 misho 14866: rc = sqlite3_open(zNewDb, &newDb);
14867: if( rc ){
14868: utf8_printf(stderr, "Cannot create output database: %s\n",
14869: sqlite3_errmsg(newDb));
1.4 misho 14870: }else{
1.4.2.2 misho 14871: sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
14872: sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
14873: tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
14874: tryToCloneSchema(p, newDb, "type!='table'", 0);
14875: sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
14876: sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1.4 misho 14877: }
1.4.2.2 misho 14878: close_db(newDb);
1.4 misho 14879: }
14880:
14881: /*
1.4.2.2 misho 14882: ** Change the output file back to stdout.
14883: **
14884: ** If the p->doXdgOpen flag is set, that means the output was being
14885: ** redirected to a temporary file named by p->zTempFile. In that case,
14886: ** launch start/open/xdg-open on that temporary file.
1.4 misho 14887: */
1.4.2.2 misho 14888: static void output_reset(ShellState *p){
14889: if( p->outfile[0]=='|' ){
14890: #ifndef SQLITE_OMIT_POPEN
14891: pclose(p->out);
14892: #endif
14893: }else{
14894: output_file_close(p->out);
14895: #ifndef SQLITE_NOHAVE_SYSTEM
14896: if( p->doXdgOpen ){
14897: const char *zXdgOpenCmd =
14898: #if defined(_WIN32)
14899: "start";
14900: #elif defined(__APPLE__)
14901: "open";
14902: #else
14903: "xdg-open";
14904: #endif
14905: char *zCmd;
14906: zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
14907: if( system(zCmd) ){
14908: utf8_printf(stderr, "Failed: [%s]\n", zCmd);
1.4.2.3 ! misho 14909: }else{
! 14910: /* Give the start/open/xdg-open command some time to get
! 14911: ** going before we continue, and potential delete the
! 14912: ** p->zTempFile data file out from under it */
! 14913: sqlite3_sleep(2000);
1.4.2.2 misho 14914: }
14915: sqlite3_free(zCmd);
14916: outputModePop(p);
14917: p->doXdgOpen = 0;
14918: }
14919: #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
1.4 misho 14920: }
1.4.2.2 misho 14921: p->outfile[0] = 0;
14922: p->out = stdout;
1.4 misho 14923: }
14924:
14925: /*
1.4.2.2 misho 14926: ** Run an SQL command and return the single integer result.
1.4 misho 14927: */
1.4.2.2 misho 14928: static int db_int(ShellState *p, const char *zSql){
14929: sqlite3_stmt *pStmt;
14930: int res = 0;
14931: sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
14932: if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
14933: res = sqlite3_column_int(pStmt,0);
1.4 misho 14934: }
1.4.2.2 misho 14935: sqlite3_finalize(pStmt);
14936: return res;
1.4 misho 14937: }
14938:
14939: /*
1.4.2.2 misho 14940: ** Convert a 2-byte or 4-byte big-endian integer into a native integer
1.4 misho 14941: */
1.4.2.2 misho 14942: static unsigned int get2byteInt(unsigned char *a){
14943: return (a[0]<<8) + a[1];
14944: }
14945: static unsigned int get4byteInt(unsigned char *a){
14946: return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
1.4 misho 14947: }
1.2 misho 14948:
14949: /*
1.4.2.3 ! misho 14950: ** Implementation of the ".dbinfo" command.
1.4.2.2 misho 14951: **
14952: ** Return 1 on error, 2 to exit, and 0 otherwise.
1.2 misho 14953: */
1.4.2.2 misho 14954: static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
14955: static const struct { const char *zName; int ofst; } aField[] = {
14956: { "file change counter:", 24 },
14957: { "database page count:", 28 },
14958: { "freelist page count:", 36 },
14959: { "schema cookie:", 40 },
14960: { "schema format:", 44 },
14961: { "default cache size:", 48 },
14962: { "autovacuum top root:", 52 },
14963: { "incremental vacuum:", 64 },
14964: { "text encoding:", 56 },
14965: { "user version:", 60 },
14966: { "application id:", 68 },
14967: { "software version:", 96 },
14968: };
14969: static const struct { const char *zName; const char *zSql; } aQuery[] = {
14970: { "number of tables:",
14971: "SELECT count(*) FROM %s WHERE type='table'" },
14972: { "number of indexes:",
14973: "SELECT count(*) FROM %s WHERE type='index'" },
14974: { "number of triggers:",
14975: "SELECT count(*) FROM %s WHERE type='trigger'" },
14976: { "number of views:",
14977: "SELECT count(*) FROM %s WHERE type='view'" },
14978: { "schema size:",
14979: "SELECT total(length(sql)) FROM %s" },
14980: };
14981: int i, rc;
14982: unsigned iDataVersion;
14983: char *zSchemaTab;
14984: char *zDb = nArg>=2 ? azArg[1] : "main";
14985: sqlite3_stmt *pStmt = 0;
14986: unsigned char aHdr[100];
14987: open_db(p, 0);
14988: if( p->db==0 ) return 1;
14989: rc = sqlite3_prepare_v2(p->db,
14990: "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
14991: -1, &pStmt, 0);
14992: if( rc ){
1.4.2.3 ! misho 14993: utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
1.4.2.2 misho 14994: sqlite3_finalize(pStmt);
14995: return 1;
14996: }
14997: sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
14998: if( sqlite3_step(pStmt)==SQLITE_ROW
14999: && sqlite3_column_bytes(pStmt,0)>100
15000: ){
15001: memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
15002: sqlite3_finalize(pStmt);
15003: }else{
15004: raw_printf(stderr, "unable to read database header\n");
15005: sqlite3_finalize(pStmt);
15006: return 1;
15007: }
15008: i = get2byteInt(aHdr+16);
15009: if( i==1 ) i = 65536;
15010: utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
15011: utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
15012: utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
15013: utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
15014: for(i=0; i<ArraySize(aField); i++){
15015: int ofst = aField[i].ofst;
15016: unsigned int val = get4byteInt(aHdr + ofst);
15017: utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
15018: switch( ofst ){
15019: case 56: {
15020: if( val==1 ) raw_printf(p->out, " (utf8)");
15021: if( val==2 ) raw_printf(p->out, " (utf16le)");
15022: if( val==3 ) raw_printf(p->out, " (utf16be)");
15023: }
15024: }
15025: raw_printf(p->out, "\n");
15026: }
15027: if( zDb==0 ){
1.4.2.3 ! misho 15028: zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
1.4.2.2 misho 15029: }else if( strcmp(zDb,"temp")==0 ){
1.4.2.3 ! misho 15030: zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
1.4.2.2 misho 15031: }else{
1.4.2.3 ! misho 15032: zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
1.4.2.2 misho 15033: }
15034: for(i=0; i<ArraySize(aQuery); i++){
15035: char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
15036: int val = db_int(p, zSql);
15037: sqlite3_free(zSql);
15038: utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
1.2 misho 15039: }
1.4.2.2 misho 15040: sqlite3_free(zSchemaTab);
15041: sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
15042: utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
15043: return 0;
1.2 misho 15044: }
15045:
15046: /*
1.4.2.2 misho 15047: ** Print the current sqlite3_errmsg() value to stderr and return 1.
15048: */
15049: static int shellDatabaseError(sqlite3 *db){
15050: const char *zErr = sqlite3_errmsg(db);
15051: utf8_printf(stderr, "Error: %s\n", zErr);
15052: return 1;
15053: }
15054:
15055: /*
15056: ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
15057: ** if they match and FALSE (0) if they do not match.
1.2 misho 15058: **
1.4.2.2 misho 15059: ** Globbing rules:
15060: **
15061: ** '*' Matches any sequence of zero or more characters.
15062: **
15063: ** '?' Matches exactly one character.
15064: **
15065: ** [...] Matches one character from the enclosed list of
15066: ** characters.
15067: **
15068: ** [^...] Matches one character not in the enclosed list.
15069: **
15070: ** '#' Matches any sequence of one or more digits with an
15071: ** optional + or - sign in front
15072: **
15073: ** ' ' Any span of whitespace matches any other span of
15074: ** whitespace.
15075: **
15076: ** Extra whitespace at the end of z[] is ignored.
1.2 misho 15077: */
1.4.2.2 misho 15078: static int testcase_glob(const char *zGlob, const char *z){
15079: int c, c2;
15080: int invert;
15081: int seen;
15082:
15083: while( (c = (*(zGlob++)))!=0 ){
15084: if( IsSpace(c) ){
15085: if( !IsSpace(*z) ) return 0;
15086: while( IsSpace(*zGlob) ) zGlob++;
15087: while( IsSpace(*z) ) z++;
15088: }else if( c=='*' ){
15089: while( (c=(*(zGlob++))) == '*' || c=='?' ){
15090: if( c=='?' && (*(z++))==0 ) return 0;
15091: }
15092: if( c==0 ){
15093: return 1;
15094: }else if( c=='[' ){
15095: while( *z && testcase_glob(zGlob-1,z)==0 ){
15096: z++;
15097: }
15098: return (*z)!=0;
15099: }
15100: while( (c2 = (*(z++)))!=0 ){
15101: while( c2!=c ){
15102: c2 = *(z++);
15103: if( c2==0 ) return 0;
15104: }
15105: if( testcase_glob(zGlob,z) ) return 1;
15106: }
15107: return 0;
15108: }else if( c=='?' ){
15109: if( (*(z++))==0 ) return 0;
15110: }else if( c=='[' ){
15111: int prior_c = 0;
15112: seen = 0;
15113: invert = 0;
15114: c = *(z++);
15115: if( c==0 ) return 0;
15116: c2 = *(zGlob++);
15117: if( c2=='^' ){
15118: invert = 1;
15119: c2 = *(zGlob++);
15120: }
15121: if( c2==']' ){
15122: if( c==']' ) seen = 1;
15123: c2 = *(zGlob++);
15124: }
15125: while( c2 && c2!=']' ){
15126: if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
15127: c2 = *(zGlob++);
15128: if( c>=prior_c && c<=c2 ) seen = 1;
15129: prior_c = 0;
15130: }else{
15131: if( c==c2 ){
15132: seen = 1;
1.2 misho 15133: }
1.4.2.2 misho 15134: prior_c = c2;
1.2 misho 15135: }
1.4.2.2 misho 15136: c2 = *(zGlob++);
1.2 misho 15137: }
1.4.2.2 misho 15138: if( c2==0 || (seen ^ invert)==0 ) return 0;
15139: }else if( c=='#' ){
15140: if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
15141: if( !IsDigit(z[0]) ) return 0;
15142: z++;
15143: while( IsDigit(z[0]) ){ z++; }
15144: }else{
15145: if( c!=(*(z++)) ) return 0;
1.2 misho 15146: }
15147: }
1.4.2.2 misho 15148: while( IsSpace(*z) ){ z++; }
15149: return *z==0;
1.4 misho 15150: }
15151:
1.4.2.2 misho 15152:
1.4 misho 15153: /*
1.4.2.2 misho 15154: ** Compare the string as a command-line option with either one or two
15155: ** initial "-" characters.
1.4 misho 15156: */
1.4.2.2 misho 15157: static int optionMatch(const char *zStr, const char *zOpt){
15158: if( zStr[0]!='-' ) return 0;
15159: zStr++;
15160: if( zStr[0]=='-' ) zStr++;
15161: return strcmp(zStr, zOpt)==0;
1.4 misho 15162: }
15163:
15164: /*
1.4.2.2 misho 15165: ** Delete a file.
1.4 misho 15166: */
1.4.2.2 misho 15167: int shellDeleteFile(const char *zFilename){
15168: int rc;
15169: #ifdef _WIN32
15170: wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
15171: rc = _wunlink(z);
15172: sqlite3_free(z);
15173: #else
15174: rc = unlink(zFilename);
15175: #endif
15176: return rc;
15177: }
15178:
15179: /*
15180: ** Try to delete the temporary file (if there is one) and free the
15181: ** memory used to hold the name of the temp file.
15182: */
15183: static void clearTempFile(ShellState *p){
15184: if( p->zTempFile==0 ) return;
15185: if( p->doXdgOpen ) return;
15186: if( shellDeleteFile(p->zTempFile) ) return;
15187: sqlite3_free(p->zTempFile);
15188: p->zTempFile = 0;
15189: }
15190:
15191: /*
15192: ** Create a new temp file name with the given suffix.
15193: */
15194: static void newTempFile(ShellState *p, const char *zSuffix){
15195: clearTempFile(p);
15196: sqlite3_free(p->zTempFile);
15197: p->zTempFile = 0;
15198: if( p->db ){
15199: sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
15200: }
15201: if( p->zTempFile==0 ){
1.4.2.3 ! misho 15202: /* If p->db is an in-memory database then the TEMPFILENAME file-control
! 15203: ** will not work and we will need to fallback to guessing */
! 15204: char *zTemp;
1.4.2.2 misho 15205: sqlite3_uint64 r;
15206: sqlite3_randomness(sizeof(r), &r);
1.4.2.3 ! misho 15207: zTemp = getenv("TEMP");
! 15208: if( zTemp==0 ) zTemp = getenv("TMP");
! 15209: if( zTemp==0 ){
! 15210: #ifdef _WIN32
! 15211: zTemp = "\\tmp";
! 15212: #else
! 15213: zTemp = "/tmp";
! 15214: #endif
! 15215: }
! 15216: p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
1.4 misho 15217: }else{
1.4.2.2 misho 15218: p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
1.4 misho 15219: }
1.4.2.2 misho 15220: if( p->zTempFile==0 ){
15221: raw_printf(stderr, "out of memory\n");
15222: exit(1);
1.4 misho 15223: }
1.2 misho 15224: }
15225:
1.4.2.2 misho 15226:
1.2 misho 15227: /*
1.4.2.2 misho 15228: ** The implementation of SQL scalar function fkey_collate_clause(), used
15229: ** by the ".lint fkey-indexes" command. This scalar function is always
15230: ** called with four arguments - the parent table name, the parent column name,
15231: ** the child table name and the child column name.
15232: **
15233: ** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
15234: **
15235: ** If either of the named tables or columns do not exist, this function
15236: ** returns an empty string. An empty string is also returned if both tables
15237: ** and columns exist but have the same default collation sequence. Or,
15238: ** if both exist but the default collation sequences are different, this
15239: ** function returns the string " COLLATE <parent-collation>", where
15240: ** <parent-collation> is the default collation sequence of the parent column.
1.2 misho 15241: */
1.4.2.2 misho 15242: static void shellFkeyCollateClause(
15243: sqlite3_context *pCtx,
15244: int nVal,
15245: sqlite3_value **apVal
15246: ){
15247: sqlite3 *db = sqlite3_context_db_handle(pCtx);
15248: const char *zParent;
15249: const char *zParentCol;
15250: const char *zParentSeq;
15251: const char *zChild;
15252: const char *zChildCol;
15253: const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
15254: int rc;
15255:
15256: assert( nVal==4 );
15257: zParent = (const char*)sqlite3_value_text(apVal[0]);
15258: zParentCol = (const char*)sqlite3_value_text(apVal[1]);
15259: zChild = (const char*)sqlite3_value_text(apVal[2]);
15260: zChildCol = (const char*)sqlite3_value_text(apVal[3]);
15261:
15262: sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
15263: rc = sqlite3_table_column_metadata(
15264: db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0
15265: );
15266: if( rc==SQLITE_OK ){
15267: rc = sqlite3_table_column_metadata(
15268: db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0
15269: );
1.2 misho 15270: }
1.4.2.2 misho 15271:
15272: if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){
15273: char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq);
15274: sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
15275: sqlite3_free(z);
15276: }
15277: }
15278:
15279:
15280: /*
15281: ** The implementation of dot-command ".lint fkey-indexes".
15282: */
15283: static int lintFkeyIndexes(
15284: ShellState *pState, /* Current shell tool state */
15285: char **azArg, /* Array of arguments passed to dot command */
15286: int nArg /* Number of entries in azArg[] */
15287: ){
15288: sqlite3 *db = pState->db; /* Database handle to query "main" db of */
15289: FILE *out = pState->out; /* Stream to write non-error output to */
15290: int bVerbose = 0; /* If -verbose is present */
15291: int bGroupByParent = 0; /* If -groupbyparent is present */
15292: int i; /* To iterate through azArg[] */
15293: const char *zIndent = ""; /* How much to indent CREATE INDEX by */
15294: int rc; /* Return code */
15295: sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
15296:
15297: /*
15298: ** This SELECT statement returns one row for each foreign key constraint
15299: ** in the schema of the main database. The column values are:
15300: **
15301: ** 0. The text of an SQL statement similar to:
15302: **
15303: ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?"
15304: **
15305: ** This SELECT is similar to the one that the foreign keys implementation
15306: ** needs to run internally on child tables. If there is an index that can
15307: ** be used to optimize this query, then it can also be used by the FK
15308: ** implementation to optimize DELETE or UPDATE statements on the parent
15309: ** table.
15310: **
15311: ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by
15312: ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema
15313: ** contains an index that can be used to optimize the query.
15314: **
15315: ** 2. Human readable text that describes the child table and columns. e.g.
15316: **
15317: ** "child_table(child_key1, child_key2)"
15318: **
15319: ** 3. Human readable text that describes the parent table and columns. e.g.
15320: **
15321: ** "parent_table(parent_key1, parent_key2)"
15322: **
15323: ** 4. A full CREATE INDEX statement for an index that could be used to
15324: ** optimize DELETE or UPDATE statements on the parent table. e.g.
15325: **
15326: ** "CREATE INDEX child_table_child_key ON child_table(child_key)"
15327: **
15328: ** 5. The name of the parent table.
15329: **
15330: ** These six values are used by the C logic below to generate the report.
15331: */
15332: const char *zSql =
15333: "SELECT "
15334: " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '"
15335: " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
15336: " || fkey_collate_clause("
15337: " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')"
15338: ", "
15339: " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
15340: " || group_concat('*=?', ' AND ') || ')'"
15341: ", "
15342: " s.name || '(' || group_concat(f.[from], ', ') || ')'"
15343: ", "
15344: " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'"
15345: ", "
15346: " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
15347: " || ' ON ' || quote(s.name) || '('"
15348: " || group_concat(quote(f.[from]) ||"
15349: " fkey_collate_clause("
15350: " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')"
15351: " || ');'"
15352: ", "
15353: " f.[table] "
1.4.2.3 ! misho 15354: "FROM sqlite_schema AS s, pragma_foreign_key_list(s.name) AS f "
1.4.2.2 misho 15355: "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
15356: "GROUP BY s.name, f.id "
15357: "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
15358: ;
15359: const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
15360:
15361: for(i=2; i<nArg; i++){
15362: int n = strlen30(azArg[i]);
15363: if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
15364: bVerbose = 1;
15365: }
15366: else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
15367: bGroupByParent = 1;
15368: zIndent = " ";
15369: }
15370: else{
15371: raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
15372: azArg[0], azArg[1]
15373: );
15374: return SQLITE_ERROR;
15375: }
15376: }
15377:
15378: /* Register the fkey_collate_clause() SQL function */
15379: rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
15380: 0, shellFkeyCollateClause, 0, 0
15381: );
15382:
15383:
15384: if( rc==SQLITE_OK ){
15385: rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
1.4 misho 15386: }
1.4.2.2 misho 15387: if( rc==SQLITE_OK ){
15388: sqlite3_bind_int(pSql, 1, bGroupByParent);
1.4 misho 15389: }
1.2 misho 15390:
1.4.2.2 misho 15391: if( rc==SQLITE_OK ){
15392: int rc2;
15393: char *zPrev = 0;
15394: while( SQLITE_ROW==sqlite3_step(pSql) ){
15395: int res = -1;
15396: sqlite3_stmt *pExplain = 0;
15397: const char *zEQP = (const char*)sqlite3_column_text(pSql, 0);
15398: const char *zGlob = (const char*)sqlite3_column_text(pSql, 1);
15399: const char *zFrom = (const char*)sqlite3_column_text(pSql, 2);
15400: const char *zTarget = (const char*)sqlite3_column_text(pSql, 3);
15401: const char *zCI = (const char*)sqlite3_column_text(pSql, 4);
15402: const char *zParent = (const char*)sqlite3_column_text(pSql, 5);
1.4.2.1 misho 15403:
1.4.2.2 misho 15404: rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
15405: if( rc!=SQLITE_OK ) break;
15406: if( SQLITE_ROW==sqlite3_step(pExplain) ){
15407: const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
15408: res = (
15409: 0==sqlite3_strglob(zGlob, zPlan)
15410: || 0==sqlite3_strglob(zGlobIPK, zPlan)
15411: );
15412: }
15413: rc = sqlite3_finalize(pExplain);
15414: if( rc!=SQLITE_OK ) break;
1.3 misho 15415:
1.4.2.2 misho 15416: if( res<0 ){
15417: raw_printf(stderr, "Error: internal error");
15418: break;
15419: }else{
15420: if( bGroupByParent
15421: && (bVerbose || res==0)
15422: && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
15423: ){
15424: raw_printf(out, "-- Parent table %s\n", zParent);
15425: sqlite3_free(zPrev);
15426: zPrev = sqlite3_mprintf("%s", zParent);
15427: }
15428:
15429: if( res==0 ){
15430: raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
15431: }else if( bVerbose ){
15432: raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
15433: zIndent, zFrom, zTarget
15434: );
15435: }
15436: }
15437: }
15438: sqlite3_free(zPrev);
15439:
15440: if( rc!=SQLITE_OK ){
15441: raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
15442: }
15443:
15444: rc2 = sqlite3_finalize(pSql);
15445: if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
15446: rc = rc2;
15447: raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
1.3 misho 15448: }
1.4.2.2 misho 15449: }else{
15450: raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
1.3 misho 15451: }
1.4.2.2 misho 15452:
15453: return rc;
1.3 misho 15454: }
15455:
15456: /*
1.4.2.2 misho 15457: ** Implementation of ".lint" dot command.
1.3 misho 15458: */
1.4.2.2 misho 15459: static int lintDotCommand(
15460: ShellState *pState, /* Current shell tool state */
15461: char **azArg, /* Array of arguments passed to dot command */
15462: int nArg /* Number of entries in azArg[] */
1.4 misho 15463: ){
1.4.2.2 misho 15464: int n;
15465: n = (nArg>=2 ? strlen30(azArg[1]) : 0);
15466: if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
15467: return lintFkeyIndexes(pState, azArg, nArg);
1.3 misho 15468:
1.4.2.2 misho 15469: usage:
15470: raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
15471: raw_printf(stderr, "Where sub-commands are:\n");
15472: raw_printf(stderr, " fkey-indexes\n");
15473: return SQLITE_ERROR;
1.3 misho 15474: }
15475:
1.4.2.2 misho 15476: #if !defined SQLITE_OMIT_VIRTUALTABLE
15477: static void shellPrepare(
15478: sqlite3 *db,
15479: int *pRc,
15480: const char *zSql,
15481: sqlite3_stmt **ppStmt
15482: ){
15483: *ppStmt = 0;
15484: if( *pRc==SQLITE_OK ){
15485: int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
15486: if( rc!=SQLITE_OK ){
15487: raw_printf(stderr, "sql error: %s (%d)\n",
15488: sqlite3_errmsg(db), sqlite3_errcode(db)
15489: );
15490: *pRc = rc;
1.4 misho 15491: }
15492: }
15493: }
15494:
1.4.2.2 misho 15495: /*
15496: ** Create a prepared statement using printf-style arguments for the SQL.
1.4 misho 15497: **
1.4.2.2 misho 15498: ** This routine is could be marked "static". But it is not always used,
15499: ** depending on compile-time options. By omitting the "static", we avoid
15500: ** nuisance compiler warnings about "defined but not used".
15501: */
15502: void shellPreparePrintf(
15503: sqlite3 *db,
15504: int *pRc,
15505: sqlite3_stmt **ppStmt,
15506: const char *zFmt,
15507: ...
15508: ){
15509: *ppStmt = 0;
15510: if( *pRc==SQLITE_OK ){
15511: va_list ap;
15512: char *z;
15513: va_start(ap, zFmt);
15514: z = sqlite3_vmprintf(zFmt, ap);
15515: va_end(ap);
15516: if( z==0 ){
15517: *pRc = SQLITE_NOMEM;
15518: }else{
15519: shellPrepare(db, pRc, z, ppStmt);
15520: sqlite3_free(z);
1.4 misho 15521: }
15522: }
15523: }
15524:
1.4.2.2 misho 15525: /* Finalize the prepared statement created using shellPreparePrintf().
1.4 misho 15526: **
1.4.2.2 misho 15527: ** This routine is could be marked "static". But it is not always used,
15528: ** depending on compile-time options. By omitting the "static", we avoid
15529: ** nuisance compiler warnings about "defined but not used".
15530: */
15531: void shellFinalize(
15532: int *pRc,
15533: sqlite3_stmt *pStmt
15534: ){
15535: if( pStmt ){
15536: sqlite3 *db = sqlite3_db_handle(pStmt);
15537: int rc = sqlite3_finalize(pStmt);
15538: if( *pRc==SQLITE_OK ){
15539: if( rc!=SQLITE_OK ){
15540: raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
15541: }
15542: *pRc = rc;
15543: }
1.4 misho 15544: }
1.4.2.2 misho 15545: }
15546:
15547: /* Reset the prepared statement created using shellPreparePrintf().
15548: **
15549: ** This routine is could be marked "static". But it is not always used,
15550: ** depending on compile-time options. By omitting the "static", we avoid
15551: ** nuisance compiler warnings about "defined but not used".
15552: */
15553: void shellReset(
15554: int *pRc,
15555: sqlite3_stmt *pStmt
15556: ){
15557: int rc = sqlite3_reset(pStmt);
15558: if( *pRc==SQLITE_OK ){
15559: if( rc!=SQLITE_OK ){
15560: sqlite3 *db = sqlite3_db_handle(pStmt);
15561: raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
15562: }
15563: *pRc = rc;
1.4 misho 15564: }
15565: }
1.4.2.2 misho 15566: #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
15567:
15568: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
1.4.2.3 ! misho 15569: /******************************************************************************
1.4.2.2 misho 15570: ** The ".archive" or ".ar" command.
15571: */
15572: /*
15573: ** Structure representing a single ".ar" command.
15574: */
15575: typedef struct ArCommand ArCommand;
15576: struct ArCommand {
15577: u8 eCmd; /* An AR_CMD_* value */
15578: u8 bVerbose; /* True if --verbose */
15579: u8 bZip; /* True if the archive is a ZIP */
15580: u8 bDryRun; /* True if --dry-run */
15581: u8 bAppend; /* True if --append */
15582: u8 fromCmdLine; /* Run from -A instead of .archive */
15583: int nArg; /* Number of command arguments */
15584: char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
15585: const char *zFile; /* --file argument, or NULL */
15586: const char *zDir; /* --directory argument, or NULL */
15587: char **azArg; /* Array of command arguments */
15588: ShellState *p; /* Shell state */
15589: sqlite3 *db; /* Database containing the archive */
15590: };
1.4 misho 15591:
15592: /*
1.4.2.2 misho 15593: ** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
1.4 misho 15594: */
1.4.2.2 misho 15595: static int arUsage(FILE *f){
15596: showHelp(f,"archive");
15597: return SQLITE_ERROR;
15598: }
1.4 misho 15599:
1.4.2.2 misho 15600: /*
15601: ** Print an error message for the .ar command to stderr and return
15602: ** SQLITE_ERROR.
15603: */
15604: static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
15605: va_list ap;
15606: char *z;
15607: va_start(ap, zFmt);
15608: z = sqlite3_vmprintf(zFmt, ap);
15609: va_end(ap);
15610: utf8_printf(stderr, "Error: %s\n", z);
15611: if( pAr->fromCmdLine ){
15612: utf8_printf(stderr, "Use \"-A\" for more help\n");
15613: }else{
15614: utf8_printf(stderr, "Use \".archive --help\" for more help\n");
1.4 misho 15615: }
1.4.2.2 misho 15616: sqlite3_free(z);
15617: return SQLITE_ERROR;
15618: }
15619:
15620: /*
15621: ** Values for ArCommand.eCmd.
15622: */
15623: #define AR_CMD_CREATE 1
15624: #define AR_CMD_UPDATE 2
15625: #define AR_CMD_INSERT 3
15626: #define AR_CMD_EXTRACT 4
15627: #define AR_CMD_LIST 5
15628: #define AR_CMD_HELP 6
15629:
15630: /*
15631: ** Other (non-command) switches.
15632: */
15633: #define AR_SWITCH_VERBOSE 7
15634: #define AR_SWITCH_FILE 8
15635: #define AR_SWITCH_DIRECTORY 9
15636: #define AR_SWITCH_APPEND 10
15637: #define AR_SWITCH_DRYRUN 11
15638:
15639: static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
15640: switch( eSwitch ){
15641: case AR_CMD_CREATE:
15642: case AR_CMD_EXTRACT:
15643: case AR_CMD_LIST:
15644: case AR_CMD_UPDATE:
15645: case AR_CMD_INSERT:
15646: case AR_CMD_HELP:
15647: if( pAr->eCmd ){
15648: return arErrorMsg(pAr, "multiple command options");
1.4 misho 15649: }
1.4.2.2 misho 15650: pAr->eCmd = eSwitch;
1.4 misho 15651: break;
15652:
1.4.2.2 misho 15653: case AR_SWITCH_DRYRUN:
15654: pAr->bDryRun = 1;
15655: break;
15656: case AR_SWITCH_VERBOSE:
15657: pAr->bVerbose = 1;
15658: break;
15659: case AR_SWITCH_APPEND:
15660: pAr->bAppend = 1;
15661: /* Fall thru into --file */
15662: case AR_SWITCH_FILE:
15663: pAr->zFile = zArg;
15664: break;
15665: case AR_SWITCH_DIRECTORY:
15666: pAr->zDir = zArg;
15667: break;
15668: }
1.4 misho 15669:
1.4.2.2 misho 15670: return SQLITE_OK;
15671: }
1.4 misho 15672:
15673: /*
1.4.2.2 misho 15674: ** Parse the command line for an ".ar" command. The results are written into
15675: ** structure (*pAr). SQLITE_OK is returned if the command line is parsed
15676: ** successfully, otherwise an error message is written to stderr and
15677: ** SQLITE_ERROR returned.
1.4 misho 15678: */
1.4.2.2 misho 15679: static int arParseCommand(
15680: char **azArg, /* Array of arguments passed to dot command */
15681: int nArg, /* Number of entries in azArg[] */
15682: ArCommand *pAr /* Populate this object */
1.4 misho 15683: ){
1.4.2.2 misho 15684: struct ArSwitch {
15685: const char *zLong;
15686: char cShort;
15687: u8 eSwitch;
15688: u8 bArg;
15689: } aSwitch[] = {
15690: { "create", 'c', AR_CMD_CREATE, 0 },
15691: { "extract", 'x', AR_CMD_EXTRACT, 0 },
15692: { "insert", 'i', AR_CMD_INSERT, 0 },
15693: { "list", 't', AR_CMD_LIST, 0 },
15694: { "update", 'u', AR_CMD_UPDATE, 0 },
15695: { "help", 'h', AR_CMD_HELP, 0 },
15696: { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
15697: { "file", 'f', AR_SWITCH_FILE, 1 },
15698: { "append", 'a', AR_SWITCH_APPEND, 1 },
15699: { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
15700: { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
15701: };
15702: int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
15703: struct ArSwitch *pEnd = &aSwitch[nSwitch];
1.4 misho 15704:
1.4.2.2 misho 15705: if( nArg<=1 ){
15706: utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
15707: return arUsage(stderr);
15708: }else{
15709: char *z = azArg[1];
15710: if( z[0]!='-' ){
15711: /* Traditional style [tar] invocation */
15712: int i;
15713: int iArg = 2;
15714: for(i=0; z[i]; i++){
15715: const char *zArg = 0;
15716: struct ArSwitch *pOpt;
15717: for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
15718: if( z[i]==pOpt->cShort ) break;
15719: }
15720: if( pOpt==pEnd ){
15721: return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
15722: }
15723: if( pOpt->bArg ){
15724: if( iArg>=nArg ){
15725: return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
15726: }
15727: zArg = azArg[iArg++];
15728: }
15729: if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
1.4 misho 15730: }
1.4.2.2 misho 15731: pAr->nArg = nArg-iArg;
15732: if( pAr->nArg>0 ){
15733: pAr->azArg = &azArg[iArg];
15734: }
15735: }else{
15736: /* Non-traditional invocation */
15737: int iArg;
15738: for(iArg=1; iArg<nArg; iArg++){
15739: int n;
15740: z = azArg[iArg];
15741: if( z[0]!='-' ){
15742: /* All remaining command line words are command arguments. */
15743: pAr->azArg = &azArg[iArg];
15744: pAr->nArg = nArg-iArg;
15745: break;
15746: }
15747: n = strlen30(z);
15748:
15749: if( z[1]!='-' ){
15750: int i;
15751: /* One or more short options */
15752: for(i=1; i<n; i++){
15753: const char *zArg = 0;
15754: struct ArSwitch *pOpt;
15755: for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
15756: if( z[i]==pOpt->cShort ) break;
15757: }
15758: if( pOpt==pEnd ){
15759: return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
15760: }
15761: if( pOpt->bArg ){
15762: if( i<(n-1) ){
15763: zArg = &z[i+1];
15764: i = n;
15765: }else{
15766: if( iArg>=(nArg-1) ){
1.4.2.3 ! misho 15767: return arErrorMsg(pAr, "option requires an argument: %c",
! 15768: z[i]);
1.4.2.2 misho 15769: }
15770: zArg = azArg[++iArg];
15771: }
15772: }
15773: if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
15774: }
15775: }else if( z[2]=='\0' ){
15776: /* A -- option, indicating that all remaining command line words
15777: ** are command arguments. */
15778: pAr->azArg = &azArg[iArg+1];
15779: pAr->nArg = nArg-iArg-1;
15780: break;
15781: }else{
15782: /* A long option */
15783: const char *zArg = 0; /* Argument for option, if any */
15784: struct ArSwitch *pMatch = 0; /* Matching option */
15785: struct ArSwitch *pOpt; /* Iterator */
15786: for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
15787: const char *zLong = pOpt->zLong;
15788: if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){
15789: if( pMatch ){
15790: return arErrorMsg(pAr, "ambiguous option: %s",z);
15791: }else{
15792: pMatch = pOpt;
15793: }
15794: }
15795: }
15796:
15797: if( pMatch==0 ){
15798: return arErrorMsg(pAr, "unrecognized option: %s", z);
15799: }
15800: if( pMatch->bArg ){
15801: if( iArg>=(nArg-1) ){
15802: return arErrorMsg(pAr, "option requires an argument: %s", z);
15803: }
15804: zArg = azArg[++iArg];
15805: }
15806: if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR;
15807: }
1.4 misho 15808: }
15809: }
15810: }
1.4.2.2 misho 15811:
15812: return SQLITE_OK;
1.4 misho 15813: }
15814:
15815: /*
1.4.2.2 misho 15816: ** This function assumes that all arguments within the ArCommand.azArg[]
15817: ** array refer to archive members, as for the --extract or --list commands.
15818: ** It checks that each of them are present. If any specified file is not
15819: ** present in the archive, an error is printed to stderr and an error
15820: ** code returned. Otherwise, if all specified arguments are present in
15821: ** the archive, SQLITE_OK is returned.
15822: **
15823: ** This function strips any trailing '/' characters from each argument.
15824: ** This is consistent with the way the [tar] command seems to work on
15825: ** Linux.
15826: */
15827: static int arCheckEntries(ArCommand *pAr){
15828: int rc = SQLITE_OK;
15829: if( pAr->nArg ){
15830: int i, j;
15831: sqlite3_stmt *pTest = 0;
15832:
15833: shellPreparePrintf(pAr->db, &rc, &pTest,
15834: "SELECT name FROM %s WHERE name=$name",
15835: pAr->zSrcTable
15836: );
15837: j = sqlite3_bind_parameter_index(pTest, "$name");
15838: for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
15839: char *z = pAr->azArg[i];
15840: int n = strlen30(z);
15841: int bOk = 0;
15842: while( n>0 && z[n-1]=='/' ) n--;
15843: z[n] = '\0';
15844: sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC);
15845: if( SQLITE_ROW==sqlite3_step(pTest) ){
15846: bOk = 1;
15847: }
15848: shellReset(&rc, pTest);
15849: if( rc==SQLITE_OK && bOk==0 ){
15850: utf8_printf(stderr, "not found in archive: %s\n", z);
15851: rc = SQLITE_ERROR;
15852: }
15853: }
15854: shellFinalize(&rc, pTest);
1.4 misho 15855: }
1.4.2.2 misho 15856: return rc;
1.4 misho 15857: }
15858:
15859: /*
1.4.2.2 misho 15860: ** Format a WHERE clause that can be used against the "sqlar" table to
15861: ** identify all archive members that match the command arguments held
15862: ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
15863: ** The caller is responsible for eventually calling sqlite3_free() on
15864: ** any non-NULL (*pzWhere) value.
15865: */
15866: static void arWhereClause(
15867: int *pRc,
15868: ArCommand *pAr,
15869: char **pzWhere /* OUT: New WHERE clause */
15870: ){
15871: char *zWhere = 0;
15872: if( *pRc==SQLITE_OK ){
15873: if( pAr->nArg==0 ){
15874: zWhere = sqlite3_mprintf("1");
15875: }else{
15876: int i;
15877: const char *zSep = "";
15878: for(i=0; i<pAr->nArg; i++){
15879: const char *z = pAr->azArg[i];
15880: zWhere = sqlite3_mprintf(
15881: "%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
15882: zWhere, zSep, z, strlen30(z)+1, z
15883: );
15884: if( zWhere==0 ){
15885: *pRc = SQLITE_NOMEM;
15886: break;
15887: }
15888: zSep = " OR ";
15889: }
15890: }
1.4 misho 15891: }
1.4.2.2 misho 15892: *pzWhere = zWhere;
1.4 misho 15893: }
15894:
15895: /*
1.4.2.2 misho 15896: ** Implementation of .ar "lisT" command.
1.4 misho 15897: */
1.4.2.2 misho 15898: static int arListCommand(ArCommand *pAr){
15899: const char *zSql = "SELECT %s FROM %s WHERE %s";
15900: const char *azCols[] = {
15901: "name",
15902: "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
15903: };
15904:
15905: char *zWhere = 0;
15906: sqlite3_stmt *pSql = 0;
15907: int rc;
15908:
15909: rc = arCheckEntries(pAr);
15910: arWhereClause(&rc, pAr, &zWhere);
15911:
15912: shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
15913: pAr->zSrcTable, zWhere);
15914: if( pAr->bDryRun ){
15915: utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
15916: }else{
15917: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
15918: if( pAr->bVerbose ){
15919: utf8_printf(pAr->p->out, "%s % 10d %s %s\n",
15920: sqlite3_column_text(pSql, 0),
15921: sqlite3_column_int(pSql, 1),
15922: sqlite3_column_text(pSql, 2),
15923: sqlite3_column_text(pSql, 3)
15924: );
15925: }else{
15926: utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
15927: }
15928: }
1.4 misho 15929: }
1.4.2.2 misho 15930: shellFinalize(&rc, pSql);
15931: sqlite3_free(zWhere);
15932: return rc;
1.4 misho 15933: }
15934:
15935:
15936: /*
1.4.2.2 misho 15937: ** Implementation of .ar "eXtract" command.
1.4 misho 15938: */
1.4.2.2 misho 15939: static int arExtractCommand(ArCommand *pAr){
15940: const char *zSql1 =
15941: "SELECT "
15942: " ($dir || name),"
15943: " writefile(($dir || name), %s, mode, mtime) "
15944: "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
15945: " AND name NOT GLOB '*..[/\\]*'";
15946:
15947: const char *azExtraArg[] = {
15948: "sqlar_uncompress(data, sz)",
15949: "data"
1.4 misho 15950: };
1.4.2.2 misho 15951:
15952: sqlite3_stmt *pSql = 0;
15953: int rc = SQLITE_OK;
15954: char *zDir = 0;
15955: char *zWhere = 0;
15956: int i, j;
15957:
15958: /* If arguments are specified, check that they actually exist within
15959: ** the archive before proceeding. And formulate a WHERE clause to
15960: ** match them. */
15961: rc = arCheckEntries(pAr);
15962: arWhereClause(&rc, pAr, &zWhere);
15963:
15964: if( rc==SQLITE_OK ){
15965: if( pAr->zDir ){
15966: zDir = sqlite3_mprintf("%s/", pAr->zDir);
15967: }else{
15968: zDir = sqlite3_mprintf("");
15969: }
15970: if( zDir==0 ) rc = SQLITE_NOMEM;
1.4 misho 15971: }
1.4.2.2 misho 15972:
15973: shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
15974: azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
15975: );
15976:
15977: if( rc==SQLITE_OK ){
15978: j = sqlite3_bind_parameter_index(pSql, "$dir");
15979: sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
15980:
15981: /* Run the SELECT statement twice. The first time, writefile() is called
15982: ** for all archive members that should be extracted. The second time,
15983: ** only for the directories. This is because the timestamps for
15984: ** extracted directories must be reset after they are populated (as
15985: ** populating them changes the timestamp). */
15986: for(i=0; i<2; i++){
15987: j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
15988: sqlite3_bind_int(pSql, j, i);
15989: if( pAr->bDryRun ){
15990: utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
15991: }else{
15992: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
15993: if( i==0 && pAr->bVerbose ){
15994: utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
15995: }
15996: }
1.4 misho 15997: }
1.4.2.2 misho 15998: shellReset(&rc, pSql);
1.4 misho 15999: }
1.4.2.2 misho 16000: shellFinalize(&rc, pSql);
1.4 misho 16001: }
16002:
1.4.2.2 misho 16003: sqlite3_free(zDir);
16004: sqlite3_free(zWhere);
16005: return rc;
1.4 misho 16006: }
16007:
1.4.2.1 misho 16008: /*
1.4.2.2 misho 16009: ** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out.
1.4.2.1 misho 16010: */
1.4.2.2 misho 16011: static int arExecSql(ArCommand *pAr, const char *zSql){
16012: int rc;
16013: if( pAr->bDryRun ){
16014: utf8_printf(pAr->p->out, "%s\n", zSql);
16015: rc = SQLITE_OK;
16016: }else{
16017: char *zErr = 0;
16018: rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
16019: if( zErr ){
16020: utf8_printf(stdout, "ERROR: %s\n", zErr);
16021: sqlite3_free(zErr);
16022: }
16023: }
16024: return rc;
1.4.2.1 misho 16025: }
16026:
1.4.2.2 misho 16027:
1.4.2.1 misho 16028: /*
1.4.2.2 misho 16029: ** Implementation of .ar "create", "insert", and "update" commands.
1.4.2.1 misho 16030: **
1.4.2.2 misho 16031: ** create -> Create a new SQL archive
16032: ** insert -> Insert or reinsert all files listed
16033: ** update -> Insert files that have changed or that were not
16034: ** previously in the archive
1.4.2.1 misho 16035: **
1.4.2.2 misho 16036: ** Create the "sqlar" table in the database if it does not already exist.
16037: ** Then add each file in the azFile[] array to the archive. Directories
16038: ** are added recursively. If argument bVerbose is non-zero, a message is
16039: ** printed on stdout for each file archived.
1.4.2.1 misho 16040: **
1.4.2.2 misho 16041: ** The create command is the same as update, except that it drops
16042: ** any existing "sqlar" table before beginning. The "insert" command
16043: ** always overwrites every file named on the command-line, where as
16044: ** "update" only overwrites if the size or mtime or mode has changed.
16045: */
16046: static int arCreateOrUpdateCommand(
16047: ArCommand *pAr, /* Command arguments and options */
16048: int bUpdate, /* true for a --create. */
16049: int bOnlyIfChanged /* Only update if file has changed */
16050: ){
16051: const char *zCreate =
16052: "CREATE TABLE IF NOT EXISTS sqlar(\n"
16053: " name TEXT PRIMARY KEY, -- name of the file\n"
16054: " mode INT, -- access permissions\n"
16055: " mtime INT, -- last modification time\n"
16056: " sz INT, -- original file size\n"
16057: " data BLOB -- compressed content\n"
16058: ")";
16059: const char *zDrop = "DROP TABLE IF EXISTS sqlar";
16060: const char *zInsertFmt[2] = {
16061: "REPLACE INTO %s(name,mode,mtime,sz,data)\n"
16062: " SELECT\n"
16063: " %s,\n"
16064: " mode,\n"
16065: " mtime,\n"
16066: " CASE substr(lsmode(mode),1,1)\n"
16067: " WHEN '-' THEN length(data)\n"
16068: " WHEN 'd' THEN 0\n"
16069: " ELSE -1 END,\n"
16070: " sqlar_compress(data)\n"
16071: " FROM fsdir(%Q,%Q) AS disk\n"
16072: " WHERE lsmode(mode) NOT LIKE '?%%'%s;"
16073: ,
16074: "REPLACE INTO %s(name,mode,mtime,data)\n"
16075: " SELECT\n"
16076: " %s,\n"
16077: " mode,\n"
16078: " mtime,\n"
16079: " data\n"
16080: " FROM fsdir(%Q,%Q) AS disk\n"
16081: " WHERE lsmode(mode) NOT LIKE '?%%'%s;"
16082: };
16083: int i; /* For iterating through azFile[] */
16084: int rc; /* Return code */
16085: const char *zTab = 0; /* SQL table into which to insert */
16086: char *zSql;
16087: char zTemp[50];
16088: char *zExists = 0;
1.4.2.1 misho 16089:
1.4.2.2 misho 16090: arExecSql(pAr, "PRAGMA page_size=512");
16091: rc = arExecSql(pAr, "SAVEPOINT ar;");
16092: if( rc!=SQLITE_OK ) return rc;
16093: zTemp[0] = 0;
16094: if( pAr->bZip ){
16095: /* Initialize the zipfile virtual table, if necessary */
16096: if( pAr->zFile ){
16097: sqlite3_uint64 r;
16098: sqlite3_randomness(sizeof(r),&r);
16099: sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r);
16100: zTab = zTemp;
16101: zSql = sqlite3_mprintf(
16102: "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)",
16103: zTab, pAr->zFile
16104: );
16105: rc = arExecSql(pAr, zSql);
16106: sqlite3_free(zSql);
16107: }else{
16108: zTab = "zip";
16109: }
16110: }else{
16111: /* Initialize the table for an SQLAR */
16112: zTab = "sqlar";
16113: if( bUpdate==0 ){
16114: rc = arExecSql(pAr, zDrop);
16115: if( rc!=SQLITE_OK ) goto end_ar_transaction;
16116: }
16117: rc = arExecSql(pAr, zCreate);
16118: }
16119: if( bOnlyIfChanged ){
16120: zExists = sqlite3_mprintf(
16121: " AND NOT EXISTS("
16122: "SELECT 1 FROM %s AS mem"
16123: " WHERE mem.name=disk.name"
16124: " AND mem.mtime=disk.mtime"
16125: " AND mem.mode=disk.mode)", zTab);
16126: }else{
16127: zExists = sqlite3_mprintf("");
16128: }
16129: if( zExists==0 ) rc = SQLITE_NOMEM;
16130: for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
16131: char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
16132: pAr->bVerbose ? "shell_putsnl(name)" : "name",
16133: pAr->azArg[i], pAr->zDir, zExists);
16134: rc = arExecSql(pAr, zSql2);
16135: sqlite3_free(zSql2);
16136: }
16137: end_ar_transaction:
16138: if( rc!=SQLITE_OK ){
16139: sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
16140: }else{
16141: rc = arExecSql(pAr, "RELEASE ar;");
16142: if( pAr->bZip && pAr->zFile ){
16143: zSql = sqlite3_mprintf("DROP TABLE %s", zTemp);
16144: arExecSql(pAr, zSql);
16145: sqlite3_free(zSql);
16146: }
16147: }
16148: sqlite3_free(zExists);
16149: return rc;
16150: }
16151:
16152: /*
16153: ** Implementation of ".ar" dot command.
16154: */
16155: static int arDotCommand(
1.4.2.3 ! misho 16156: ShellState *pState, /* Current shell tool state */
! 16157: int fromCmdLine, /* True if -A command-line option, not .ar cmd */
! 16158: char **azArg, /* Array of arguments passed to dot command */
! 16159: int nArg /* Number of entries in azArg[] */
1.4.2.2 misho 16160: ){
16161: ArCommand cmd;
16162: int rc;
16163: memset(&cmd, 0, sizeof(cmd));
16164: cmd.fromCmdLine = fromCmdLine;
16165: rc = arParseCommand(azArg, nArg, &cmd);
16166: if( rc==SQLITE_OK ){
16167: int eDbType = SHELL_OPEN_UNSPEC;
16168: cmd.p = pState;
16169: cmd.db = pState->db;
16170: if( cmd.zFile ){
16171: eDbType = deduceDatabaseType(cmd.zFile, 1);
16172: }else{
16173: eDbType = pState->openMode;
16174: }
16175: if( eDbType==SHELL_OPEN_ZIPFILE ){
16176: if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
16177: if( cmd.zFile==0 ){
16178: cmd.zSrcTable = sqlite3_mprintf("zip");
1.4.2.1 misho 16179: }else{
1.4.2.2 misho 16180: cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
1.4.2.1 misho 16181: }
16182: }
1.4.2.2 misho 16183: cmd.bZip = 1;
16184: }else if( cmd.zFile ){
16185: int flags;
16186: if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
16187: if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
16188: || cmd.eCmd==AR_CMD_UPDATE ){
16189: flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
16190: }else{
16191: flags = SQLITE_OPEN_READONLY;
16192: }
16193: cmd.db = 0;
16194: if( cmd.bDryRun ){
16195: utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
16196: eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
16197: }
16198: rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
16199: eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
16200: if( rc!=SQLITE_OK ){
16201: utf8_printf(stderr, "cannot open file: %s (%s)\n",
16202: cmd.zFile, sqlite3_errmsg(cmd.db)
16203: );
16204: goto end_ar_command;
16205: }
16206: sqlite3_fileio_init(cmd.db, 0, 0);
16207: sqlite3_sqlar_init(cmd.db, 0, 0);
16208: sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
16209: shellPutsFunc, 0, 0);
16210:
16211: }
16212: if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
16213: if( cmd.eCmd!=AR_CMD_CREATE
16214: && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
16215: ){
16216: utf8_printf(stderr, "database does not contain an 'sqlar' table\n");
16217: rc = SQLITE_ERROR;
16218: goto end_ar_command;
16219: }
16220: cmd.zSrcTable = sqlite3_mprintf("sqlar");
16221: }
16222:
16223: switch( cmd.eCmd ){
16224: case AR_CMD_CREATE:
16225: rc = arCreateOrUpdateCommand(&cmd, 0, 0);
16226: break;
16227:
16228: case AR_CMD_EXTRACT:
16229: rc = arExtractCommand(&cmd);
16230: break;
16231:
16232: case AR_CMD_LIST:
16233: rc = arListCommand(&cmd);
16234: break;
16235:
16236: case AR_CMD_HELP:
16237: arUsage(pState->out);
16238: break;
16239:
16240: case AR_CMD_INSERT:
16241: rc = arCreateOrUpdateCommand(&cmd, 1, 0);
16242: break;
16243:
16244: default:
16245: assert( cmd.eCmd==AR_CMD_UPDATE );
16246: rc = arCreateOrUpdateCommand(&cmd, 1, 1);
16247: break;
16248: }
16249: }
16250: end_ar_command:
16251: if( cmd.db!=pState->db ){
16252: close_db(cmd.db);
16253: }
16254: sqlite3_free(cmd.zSrcTable);
16255:
16256: return rc;
16257: }
16258: /* End of the ".archive" or ".ar" command logic
1.4.2.3 ! misho 16259: *******************************************************************************/
1.4.2.2 misho 16260: #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
16261:
16262: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
16263: /*
16264: ** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op.
16265: ** Otherwise, the SQL statement or statements in zSql are executed using
16266: ** database connection db and the error code written to *pRc before
16267: ** this function returns.
16268: */
16269: static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
16270: int rc = *pRc;
16271: if( rc==SQLITE_OK ){
16272: char *zErr = 0;
16273: rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
16274: if( rc!=SQLITE_OK ){
16275: raw_printf(stderr, "SQL error: %s\n", zErr);
16276: }
16277: *pRc = rc;
16278: }
16279: }
16280:
16281: /*
16282: ** Like shellExec(), except that zFmt is a printf() style format string.
16283: */
16284: static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){
16285: char *z = 0;
16286: if( *pRc==SQLITE_OK ){
16287: va_list ap;
16288: va_start(ap, zFmt);
16289: z = sqlite3_vmprintf(zFmt, ap);
16290: va_end(ap);
16291: if( z==0 ){
16292: *pRc = SQLITE_NOMEM;
1.4.2.1 misho 16293: }else{
1.4.2.2 misho 16294: shellExec(db, pRc, z);
1.4.2.1 misho 16295: }
1.4.2.2 misho 16296: sqlite3_free(z);
1.4.2.1 misho 16297: }
16298: }
16299:
1.4.2.2 misho 16300: /*
16301: ** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
16302: ** Otherwise, an attempt is made to allocate, zero and return a pointer
16303: ** to a buffer nByte bytes in size. If an OOM error occurs, *pRc is set
16304: ** to SQLITE_NOMEM and NULL returned.
16305: */
16306: static void *shellMalloc(int *pRc, sqlite3_int64 nByte){
16307: void *pRet = 0;
16308: if( *pRc==SQLITE_OK ){
16309: pRet = sqlite3_malloc64(nByte);
16310: if( pRet==0 ){
16311: *pRc = SQLITE_NOMEM;
16312: }else{
16313: memset(pRet, 0, nByte);
16314: }
16315: }
16316: return pRet;
16317: }
1.4 misho 16318:
16319: /*
1.4.2.2 misho 16320: ** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
16321: ** Otherwise, zFmt is treated as a printf() style string. The result of
16322: ** formatting it along with any trailing arguments is written into a
16323: ** buffer obtained from sqlite3_malloc(), and pointer to which is returned.
16324: ** It is the responsibility of the caller to eventually free this buffer
16325: ** using a call to sqlite3_free().
16326: **
16327: ** If an OOM error occurs, (*pRc) is set to SQLITE_NOMEM and a NULL
16328: ** pointer returned.
16329: */
16330: static char *shellMPrintf(int *pRc, const char *zFmt, ...){
16331: char *z = 0;
16332: if( *pRc==SQLITE_OK ){
16333: va_list ap;
16334: va_start(ap, zFmt);
16335: z = sqlite3_vmprintf(zFmt, ap);
16336: va_end(ap);
16337: if( z==0 ){
16338: *pRc = SQLITE_NOMEM;
16339: }
16340: }
16341: return z;
1.4 misho 16342: }
16343:
16344: /*
1.4.2.2 misho 16345: ** When running the ".recover" command, each output table, and the special
16346: ** orphaned row table if it is required, is represented by an instance
16347: ** of the following struct.
1.4.2.1 misho 16348: */
1.4.2.2 misho 16349: typedef struct RecoverTable RecoverTable;
16350: struct RecoverTable {
16351: char *zQuoted; /* Quoted version of table name */
16352: int nCol; /* Number of columns in table */
16353: char **azlCol; /* Array of column lists */
16354: int iPk; /* Index of IPK column */
16355: };
1.4.2.1 misho 16356:
1.4.2.2 misho 16357: /*
16358: ** Free a RecoverTable object allocated by recoverFindTable() or
16359: ** recoverOrphanTable().
16360: */
16361: static void recoverFreeTable(RecoverTable *pTab){
16362: if( pTab ){
16363: sqlite3_free(pTab->zQuoted);
16364: if( pTab->azlCol ){
16365: int i;
16366: for(i=0; i<=pTab->nCol; i++){
16367: sqlite3_free(pTab->azlCol[i]);
16368: }
16369: sqlite3_free(pTab->azlCol);
16370: }
16371: sqlite3_free(pTab);
16372: }
16373: }
1.4.2.1 misho 16374:
16375: /*
1.4.2.2 misho 16376: ** This function is a no-op if (*pRc) is not SQLITE_OK when it is called.
16377: ** Otherwise, it allocates and returns a RecoverTable object based on the
16378: ** final four arguments passed to this function. It is the responsibility
16379: ** of the caller to eventually free the returned object using
16380: ** recoverFreeTable().
1.4.2.1 misho 16381: */
1.4.2.2 misho 16382: static RecoverTable *recoverNewTable(
16383: int *pRc, /* IN/OUT: Error code */
16384: const char *zName, /* Name of table */
16385: const char *zSql, /* CREATE TABLE statement */
16386: int bIntkey,
16387: int nCol
1.4.2.1 misho 16388: ){
1.4.2.2 misho 16389: sqlite3 *dbtmp = 0; /* sqlite3 handle for testing CREATE TABLE */
16390: int rc = *pRc;
16391: RecoverTable *pTab = 0;
1.4.2.1 misho 16392:
1.4.2.2 misho 16393: pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable));
1.4.2.1 misho 16394: if( rc==SQLITE_OK ){
1.4.2.2 misho 16395: int nSqlCol = 0;
16396: int bSqlIntkey = 0;
16397: sqlite3_stmt *pStmt = 0;
16398:
16399: rc = sqlite3_open("", &dbtmp);
16400: if( rc==SQLITE_OK ){
1.4.2.3 ! misho 16401: sqlite3_create_function(dbtmp, "shell_idquote", 1, SQLITE_UTF8, 0,
! 16402: shellIdQuote, 0, 0);
! 16403: }
! 16404: if( rc==SQLITE_OK ){
1.4.2.2 misho 16405: rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
16406: }
16407: if( rc==SQLITE_OK ){
16408: rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0);
16409: if( rc==SQLITE_ERROR ){
16410: rc = SQLITE_OK;
16411: goto finished;
16412: }
16413: }
16414: shellPreparePrintf(dbtmp, &rc, &pStmt,
16415: "SELECT count(*) FROM pragma_table_info(%Q)", zName
16416: );
16417: if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
16418: nSqlCol = sqlite3_column_int(pStmt, 0);
16419: }
16420: shellFinalize(&rc, pStmt);
16421:
16422: if( rc!=SQLITE_OK || nSqlCol<nCol ){
16423: goto finished;
16424: }
16425:
16426: shellPreparePrintf(dbtmp, &rc, &pStmt,
16427: "SELECT ("
16428: " SELECT substr(data,1,1)==X'0D' FROM sqlite_dbpage WHERE pgno=rootpage"
1.4.2.3 ! misho 16429: ") FROM sqlite_schema WHERE name = %Q", zName
1.4.2.1 misho 16430: );
1.4.2.2 misho 16431: if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
16432: bSqlIntkey = sqlite3_column_int(pStmt, 0);
16433: }
16434: shellFinalize(&rc, pStmt);
16435:
16436: if( bIntkey==bSqlIntkey ){
16437: int i;
16438: const char *zPk = "_rowid_";
16439: sqlite3_stmt *pPkFinder = 0;
16440:
16441: /* If this is an intkey table and there is an INTEGER PRIMARY KEY,
16442: ** set zPk to the name of the PK column, and pTab->iPk to the index
16443: ** of the column, where columns are 0-numbered from left to right.
16444: ** Or, if this is a WITHOUT ROWID table or if there is no IPK column,
16445: ** leave zPk as "_rowid_" and pTab->iPk at -2. */
16446: pTab->iPk = -2;
16447: if( bIntkey ){
16448: shellPreparePrintf(dbtmp, &rc, &pPkFinder,
16449: "SELECT cid, name FROM pragma_table_info(%Q) "
16450: " WHERE pk=1 AND type='integer' COLLATE nocase"
16451: " AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)"
16452: , zName, zName
16453: );
16454: if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){
16455: pTab->iPk = sqlite3_column_int(pPkFinder, 0);
16456: zPk = (const char*)sqlite3_column_text(pPkFinder, 1);
16457: }
16458: }
16459:
1.4.2.3 ! misho 16460: pTab->zQuoted = shellMPrintf(&rc, "\"%w\"", zName);
1.4.2.2 misho 16461: pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
16462: pTab->nCol = nSqlCol;
16463:
16464: if( bIntkey ){
1.4.2.3 ! misho 16465: pTab->azlCol[0] = shellMPrintf(&rc, "\"%w\"", zPk);
1.4.2.2 misho 16466: }else{
16467: pTab->azlCol[0] = shellMPrintf(&rc, "");
16468: }
16469: i = 1;
16470: shellPreparePrintf(dbtmp, &rc, &pStmt,
1.4.2.3 ! misho 16471: "SELECT %Q || group_concat(shell_idquote(name), ', ') "
1.4.2.2 misho 16472: " FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
16473: "FROM pragma_table_info(%Q)",
16474: bIntkey ? ", " : "", pTab->iPk,
16475: bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ",
16476: zName
16477: );
16478: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
16479: const char *zText = (const char*)sqlite3_column_text(pStmt, 0);
16480: pTab->azlCol[i] = shellMPrintf(&rc, "%s%s", pTab->azlCol[0], zText);
16481: i++;
16482: }
16483: shellFinalize(&rc, pStmt);
16484:
16485: shellFinalize(&rc, pPkFinder);
16486: }
1.4.2.1 misho 16487: }
16488:
1.4.2.2 misho 16489: finished:
16490: sqlite3_close(dbtmp);
16491: *pRc = rc;
16492: if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){
16493: recoverFreeTable(pTab);
16494: pTab = 0;
1.4.2.1 misho 16495: }
1.4.2.2 misho 16496: return pTab;
1.4.2.1 misho 16497: }
16498:
1.4.2.2 misho 16499: /*
16500: ** This function is called to search the schema recovered from the
1.4.2.3 ! misho 16501: ** sqlite_schema table of the (possibly) corrupt database as part
1.4.2.2 misho 16502: ** of a ".recover" command. Specifically, for a table with root page
16503: ** iRoot and at least nCol columns. Additionally, if bIntkey is 0, the
16504: ** table must be a WITHOUT ROWID table, or if non-zero, not one of
16505: ** those.
16506: **
16507: ** If a table is found, a (RecoverTable*) object is returned. Or, if
16508: ** no such table is found, but bIntkey is false and iRoot is the
16509: ** root page of an index in the recovered schema, then (*pbNoop) is
16510: ** set to true and NULL returned. Or, if there is no such table or
16511: ** index, NULL is returned and (*pbNoop) set to 0, indicating that
16512: ** the caller should write data to the orphans table.
16513: */
16514: static RecoverTable *recoverFindTable(
16515: ShellState *pState, /* Shell state object */
16516: int *pRc, /* IN/OUT: Error code */
16517: int iRoot, /* Root page of table */
16518: int bIntkey, /* True for an intkey table */
16519: int nCol, /* Number of columns in table */
16520: int *pbNoop /* OUT: True if iRoot is root of index */
16521: ){
16522: sqlite3_stmt *pStmt = 0;
16523: RecoverTable *pRet = 0;
16524: int bNoop = 0;
16525: const char *zSql = 0;
16526: const char *zName = 0;
16527:
16528: /* Search the recovered schema for an object with root page iRoot. */
16529: shellPreparePrintf(pState->db, pRc, &pStmt,
16530: "SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot
16531: );
16532: while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
16533: const char *zType = (const char*)sqlite3_column_text(pStmt, 0);
16534: if( bIntkey==0 && sqlite3_stricmp(zType, "index")==0 ){
16535: bNoop = 1;
16536: break;
16537: }
16538: if( sqlite3_stricmp(zType, "table")==0 ){
16539: zName = (const char*)sqlite3_column_text(pStmt, 1);
16540: zSql = (const char*)sqlite3_column_text(pStmt, 2);
16541: pRet = recoverNewTable(pRc, zName, zSql, bIntkey, nCol);
16542: break;
16543: }
16544: }
16545:
16546: shellFinalize(pRc, pStmt);
16547: *pbNoop = bNoop;
16548: return pRet;
16549: }
1.4.2.1 misho 16550:
16551: /*
1.4.2.2 misho 16552: ** Return a RecoverTable object representing the orphans table.
1.4.2.1 misho 16553: */
1.4.2.2 misho 16554: static RecoverTable *recoverOrphanTable(
16555: ShellState *pState, /* Shell state object */
16556: int *pRc, /* IN/OUT: Error code */
16557: const char *zLostAndFound, /* Base name for orphans table */
16558: int nCol /* Number of user data columns */
1.4.2.1 misho 16559: ){
1.4.2.2 misho 16560: RecoverTable *pTab = 0;
16561: if( nCol>=0 && *pRc==SQLITE_OK ){
16562: int i;
1.4.2.1 misho 16563:
1.4.2.2 misho 16564: /* This block determines the name of the orphan table. The prefered
16565: ** name is zLostAndFound. But if that clashes with another name
16566: ** in the recovered schema, try zLostAndFound_0, zLostAndFound_1
16567: ** and so on until a non-clashing name is found. */
16568: int iTab = 0;
16569: char *zTab = shellMPrintf(pRc, "%s", zLostAndFound);
16570: sqlite3_stmt *pTest = 0;
16571: shellPrepare(pState->db, pRc,
16572: "SELECT 1 FROM recovery.schema WHERE name=?", &pTest
16573: );
16574: if( pTest ) sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
16575: while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pTest) ){
16576: shellReset(pRc, pTest);
16577: sqlite3_free(zTab);
16578: zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++);
16579: sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
16580: }
16581: shellFinalize(pRc, pTest);
16582:
16583: pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
16584: if( pTab ){
1.4.2.3 ! misho 16585: pTab->zQuoted = shellMPrintf(pRc, "\"%w\"", zTab);
1.4.2.2 misho 16586: pTab->nCol = nCol;
16587: pTab->iPk = -2;
16588: if( nCol>0 ){
16589: pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1));
16590: if( pTab->azlCol ){
16591: pTab->azlCol[nCol] = shellMPrintf(pRc, "");
16592: for(i=nCol-1; i>=0; i--){
16593: pTab->azlCol[i] = shellMPrintf(pRc, "%s, NULL", pTab->azlCol[i+1]);
16594: }
16595: }
16596: }
16597:
16598: if( *pRc!=SQLITE_OK ){
16599: recoverFreeTable(pTab);
16600: pTab = 0;
16601: }else{
16602: raw_printf(pState->out,
16603: "CREATE TABLE %s(rootpgno INTEGER, "
16604: "pgno INTEGER, nfield INTEGER, id INTEGER", pTab->zQuoted
16605: );
16606: for(i=0; i<nCol; i++){
16607: raw_printf(pState->out, ", c%d", i);
16608: }
16609: raw_printf(pState->out, ");\n");
16610: }
16611: }
16612: sqlite3_free(zTab);
16613: }
16614: return pTab;
16615: }
16616:
16617: /*
16618: ** This function is called to recover data from the database. A script
16619: ** to construct a new database containing all recovered data is output
16620: ** on stream pState->out.
16621: */
16622: static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
16623: int rc = SQLITE_OK;
16624: sqlite3_stmt *pLoop = 0; /* Loop through all root pages */
16625: sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */
16626: sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */
16627: const char *zRecoveryDb = ""; /* Name of "recovery" database */
16628: const char *zLostAndFound = "lost_and_found";
16629: int i;
16630: int nOrphan = -1;
16631: RecoverTable *pOrphan = 0;
1.4.2.1 misho 16632:
1.4.2.2 misho 16633: int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
1.4.2.3 ! misho 16634: int bRowids = 1; /* 0 if --no-rowids */
1.4.2.2 misho 16635: for(i=1; i<nArg; i++){
16636: char *z = azArg[i];
16637: int n;
16638: if( z[0]=='-' && z[1]=='-' ) z++;
16639: n = strlen30(z);
16640: if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
16641: bFreelist = 0;
16642: }else
16643: if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
16644: i++;
16645: zRecoveryDb = azArg[i];
16646: }else
16647: if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
16648: i++;
16649: zLostAndFound = azArg[i];
1.4.2.3 ! misho 16650: }else
! 16651: if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
! 16652: bRowids = 0;
1.4.2.1 misho 16653: }
16654: else{
1.4.2.3 ! misho 16655: utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
! 16656: showHelp(pState->out, azArg[0]);
1.4.2.2 misho 16657: return 1;
1.4.2.1 misho 16658: }
16659: }
16660:
1.4.2.2 misho 16661: shellExecPrintf(pState->db, &rc,
16662: /* Attach an in-memory database named 'recovery'. Create an indexed
16663: ** cache of the sqlite_dbptr virtual table. */
1.4.2.3 ! misho 16664: "PRAGMA writable_schema = on;"
1.4.2.2 misho 16665: "ATTACH %Q AS recovery;"
16666: "DROP TABLE IF EXISTS recovery.dbptr;"
16667: "DROP TABLE IF EXISTS recovery.freelist;"
16668: "DROP TABLE IF EXISTS recovery.map;"
16669: "DROP TABLE IF EXISTS recovery.schema;"
16670: "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb
16671: );
1.4.2.1 misho 16672:
1.4.2.2 misho 16673: if( bFreelist ){
16674: shellExec(pState->db, &rc,
16675: "WITH trunk(pgno) AS ("
16676: " SELECT shell_int32("
16677: " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x "
16678: " WHERE x>0"
16679: " UNION"
16680: " SELECT shell_int32("
16681: " (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x "
16682: " FROM trunk WHERE x>0"
16683: "),"
16684: "freelist(data, n, freepgno) AS ("
16685: " SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno "
16686: " FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno"
16687: " UNION ALL"
16688: " SELECT data, n-1, shell_int32(data, 2+n) "
16689: " FROM freelist WHERE n>=0"
16690: ")"
16691: "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;"
16692: );
1.4.2.1 misho 16693: }
16694:
1.4.2.3 ! misho 16695: /* If this is an auto-vacuum database, add all pointer-map pages to
! 16696: ** the freelist table. Do this regardless of whether or not
! 16697: ** --freelist-corrupt was specified. */
! 16698: shellExec(pState->db, &rc,
! 16699: "WITH ptrmap(pgno) AS ("
! 16700: " SELECT 2 WHERE shell_int32("
! 16701: " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 13"
! 16702: " )"
! 16703: " UNION ALL "
! 16704: " SELECT pgno+1+(SELECT page_size FROM pragma_page_size)/5 AS pp "
! 16705: " FROM ptrmap WHERE pp<=(SELECT page_count FROM pragma_page_count)"
! 16706: ")"
! 16707: "REPLACE INTO recovery.freelist SELECT pgno FROM ptrmap"
! 16708: );
! 16709:
1.4.2.2 misho 16710: shellExec(pState->db, &rc,
16711: "CREATE TABLE recovery.dbptr("
16712: " pgno, child, PRIMARY KEY(child, pgno)"
16713: ") WITHOUT ROWID;"
16714: "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) "
16715: " SELECT * FROM sqlite_dbptr"
16716: " WHERE pgno NOT IN freelist AND child NOT IN freelist;"
16717:
16718: /* Delete any pointer to page 1. This ensures that page 1 is considered
16719: ** a root page, regardless of how corrupt the db is. */
16720: "DELETE FROM recovery.dbptr WHERE child = 1;"
16721:
16722: /* Delete all pointers to any pages that have more than one pointer
16723: ** to them. Such pages will be treated as root pages when recovering
16724: ** data. */
16725: "DELETE FROM recovery.dbptr WHERE child IN ("
16726: " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1"
16727: ");"
16728:
16729: /* Create the "map" table that will (eventually) contain instructions
16730: ** for dealing with each page in the db that contains one or more
16731: ** records. */
16732: "CREATE TABLE recovery.map("
16733: "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT"
16734: ");"
16735:
16736: /* Populate table [map]. If there are circular loops of pages in the
16737: ** database, the following adds all pages in such a loop to the map
16738: ** as individual root pages. This could be handled better. */
16739: "WITH pages(i, maxlen) AS ("
16740: " SELECT page_count, ("
16741: " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count"
16742: " ) FROM pragma_page_count WHERE page_count>0"
16743: " UNION ALL"
16744: " SELECT i-1, ("
16745: " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
16746: " ) FROM pages WHERE i>=2"
16747: ")"
16748: "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
16749: " SELECT i, maxlen, NULL, ("
16750: " WITH p(orig, pgno, parent) AS ("
16751: " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
16752: " UNION "
16753: " SELECT i, p.parent, "
16754: " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
16755: " )"
16756: " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
16757: ") "
1.4.2.3 ! misho 16758: "FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;"
1.4.2.2 misho 16759: "UPDATE recovery.map AS o SET intkey = ("
16760: " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
16761: ");"
16762:
16763: /* Extract data from page 1 and any linked pages into table
1.4.2.3 ! misho 16764: ** recovery.schema. With the same schema as an sqlite_schema table. */
1.4.2.2 misho 16765: "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
16766: "INSERT INTO recovery.schema SELECT "
16767: " max(CASE WHEN field=0 THEN value ELSE NULL END),"
16768: " max(CASE WHEN field=1 THEN value ELSE NULL END),"
16769: " max(CASE WHEN field=2 THEN value ELSE NULL END),"
16770: " max(CASE WHEN field=3 THEN value ELSE NULL END),"
16771: " max(CASE WHEN field=4 THEN value ELSE NULL END)"
16772: "FROM sqlite_dbdata WHERE pgno IN ("
16773: " SELECT pgno FROM recovery.map WHERE root=1"
16774: ")"
16775: "GROUP BY pgno, cell;"
16776: "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);"
16777: );
16778:
16779: /* Open a transaction, then print out all non-virtual, non-"sqlite_%"
16780: ** CREATE TABLE statements that extracted from the existing schema. */
1.4.2.1 misho 16781: if( rc==SQLITE_OK ){
1.4.2.2 misho 16782: sqlite3_stmt *pStmt = 0;
1.4.2.3 ! misho 16783: /* ".recover" might output content in an order which causes immediate
! 16784: ** foreign key constraints to be violated. So disable foreign-key
! 16785: ** constraint enforcement to prevent problems when running the output
! 16786: ** script. */
! 16787: raw_printf(pState->out, "PRAGMA foreign_keys=OFF;\n");
1.4.2.2 misho 16788: raw_printf(pState->out, "BEGIN;\n");
16789: raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
16790: shellPrepare(pState->db, &rc,
16791: "SELECT sql FROM recovery.schema "
16792: "WHERE type='table' AND sql LIKE 'create table%'", &pStmt
16793: );
16794: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
16795: const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0);
16796: raw_printf(pState->out, "CREATE TABLE IF NOT EXISTS %s;\n",
16797: &zCreateTable[12]
16798: );
16799: }
16800: shellFinalize(&rc, pStmt);
16801: }
1.4.2.1 misho 16802:
1.4.2.2 misho 16803: /* Figure out if an orphan table will be required. And if so, how many
16804: ** user columns it should contain */
16805: shellPrepare(pState->db, &rc,
16806: "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"
16807: , &pLoop
16808: );
16809: if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
16810: nOrphan = sqlite3_column_int(pLoop, 0);
16811: }
16812: shellFinalize(&rc, pLoop);
16813: pLoop = 0;
1.4.2.1 misho 16814:
1.4.2.2 misho 16815: shellPrepare(pState->db, &rc,
16816: "SELECT pgno FROM recovery.map WHERE root=?", &pPages
16817: );
1.4.2.3 ! misho 16818:
1.4.2.2 misho 16819: shellPrepare(pState->db, &rc,
1.4.2.3 ! misho 16820: "SELECT max(field), group_concat(shell_escape_crnl(quote"
! 16821: "(case when (? AND field<0) then NULL else value end)"
! 16822: "), ', ')"
! 16823: ", min(field) "
1.4.2.2 misho 16824: "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
16825: "GROUP BY cell", &pCells
16826: );
1.4.2.1 misho 16827:
1.4.2.2 misho 16828: /* Loop through each root page. */
16829: shellPrepare(pState->db, &rc,
16830: "SELECT root, intkey, max(maxlen) FROM recovery.map"
16831: " WHERE root>1 GROUP BY root, intkey ORDER BY root=("
16832: " SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'"
16833: ")", &pLoop
16834: );
16835: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
16836: int iRoot = sqlite3_column_int(pLoop, 0);
16837: int bIntkey = sqlite3_column_int(pLoop, 1);
16838: int nCol = sqlite3_column_int(pLoop, 2);
16839: int bNoop = 0;
16840: RecoverTable *pTab;
16841:
1.4.2.3 ! misho 16842: assert( bIntkey==0 || bIntkey==1 );
1.4.2.2 misho 16843: pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
16844: if( bNoop || rc ) continue;
16845: if( pTab==0 ){
16846: if( pOrphan==0 ){
16847: pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
16848: }
16849: pTab = pOrphan;
16850: if( pTab==0 ) break;
16851: }
16852:
1.4.2.3 ! misho 16853: if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
1.4.2.2 misho 16854: raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
16855: }
16856: sqlite3_bind_int(pPages, 1, iRoot);
1.4.2.3 ! misho 16857: if( bRowids==0 && pTab->iPk<0 ){
! 16858: sqlite3_bind_int(pCells, 1, 1);
! 16859: }else{
! 16860: sqlite3_bind_int(pCells, 1, 0);
! 16861: }
! 16862: sqlite3_bind_int(pCells, 3, pTab->iPk);
1.4.2.2 misho 16863:
16864: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
16865: int iPgno = sqlite3_column_int(pPages, 0);
1.4.2.3 ! misho 16866: sqlite3_bind_int(pCells, 2, iPgno);
1.4.2.2 misho 16867: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
16868: int nField = sqlite3_column_int(pCells, 0);
1.4.2.3 ! misho 16869: int iMin = sqlite3_column_int(pCells, 2);
1.4.2.2 misho 16870: const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
16871:
1.4.2.3 ! misho 16872: RecoverTable *pTab2 = pTab;
! 16873: if( pTab!=pOrphan && (iMin<0)!=bIntkey ){
! 16874: if( pOrphan==0 ){
! 16875: pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
! 16876: }
! 16877: pTab2 = pOrphan;
! 16878: if( pTab2==0 ) break;
! 16879: }
! 16880:
1.4.2.2 misho 16881: nField = nField+1;
1.4.2.3 ! misho 16882: if( pTab2==pOrphan ){
1.4.2.2 misho 16883: raw_printf(pState->out,
16884: "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
1.4.2.3 ! misho 16885: pTab2->zQuoted, iRoot, iPgno, nField,
! 16886: iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField]
1.4.2.2 misho 16887: );
16888: }else{
16889: raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n",
1.4.2.3 ! misho 16890: pTab2->zQuoted, pTab2->azlCol[nField], zVal
1.4.2.1 misho 16891: );
16892: }
16893: }
1.4.2.2 misho 16894: shellReset(&rc, pCells);
1.4.2.1 misho 16895: }
1.4.2.2 misho 16896: shellReset(&rc, pPages);
16897: if( pTab!=pOrphan ) recoverFreeTable(pTab);
16898: }
16899: shellFinalize(&rc, pLoop);
16900: shellFinalize(&rc, pPages);
16901: shellFinalize(&rc, pCells);
16902: recoverFreeTable(pOrphan);
1.4.2.1 misho 16903:
1.4.2.2 misho 16904: /* The rest of the schema */
16905: if( rc==SQLITE_OK ){
16906: sqlite3_stmt *pStmt = 0;
16907: shellPrepare(pState->db, &rc,
16908: "SELECT sql, name FROM recovery.schema "
16909: "WHERE sql NOT LIKE 'create table%'", &pStmt
16910: );
16911: while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
16912: const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
16913: if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){
16914: const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
16915: char *zPrint = shellMPrintf(&rc,
1.4.2.3 ! misho 16916: "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
1.4.2.2 misho 16917: zName, zName, zSql
16918: );
16919: raw_printf(pState->out, "%s;\n", zPrint);
16920: sqlite3_free(zPrint);
16921: }else{
16922: raw_printf(pState->out, "%s;\n", zSql);
16923: }
1.4.2.1 misho 16924: }
1.4.2.2 misho 16925: shellFinalize(&rc, pStmt);
1.4.2.1 misho 16926: }
16927:
1.4.2.2 misho 16928: if( rc==SQLITE_OK ){
16929: raw_printf(pState->out, "PRAGMA writable_schema = off;\n");
16930: raw_printf(pState->out, "COMMIT;\n");
16931: }
16932: sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
1.4.2.1 misho 16933: return rc;
16934: }
1.4.2.2 misho 16935: #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
1.4.2.1 misho 16936:
16937:
16938: /*
1.2 misho 16939: ** If an input line begins with "." then invoke this routine to
16940: ** process that line.
16941: **
16942: ** Return 1 on error, 2 to exit, and 0 otherwise.
16943: */
1.4 misho 16944: static int do_meta_command(char *zLine, ShellState *p){
16945: int h = 1;
1.2 misho 16946: int nArg = 0;
16947: int n, c;
16948: int rc = 0;
1.4.2.3 ! misho 16949: char *azArg[52];
1.2 misho 16950:
1.4.2.2 misho 16951: #ifndef SQLITE_OMIT_VIRTUALTABLE
16952: if( p->expert.pExpert ){
16953: expertFinish(p, 1, 0);
16954: }
16955: #endif
16956:
1.2 misho 16957: /* Parse the input line into tokens.
16958: */
1.4.2.3 ! misho 16959: while( zLine[h] && nArg<ArraySize(azArg)-1 ){
1.4 misho 16960: while( IsSpace(zLine[h]) ){ h++; }
16961: if( zLine[h]==0 ) break;
16962: if( zLine[h]=='\'' || zLine[h]=='"' ){
16963: int delim = zLine[h++];
16964: azArg[nArg++] = &zLine[h];
16965: while( zLine[h] && zLine[h]!=delim ){
16966: if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
16967: h++;
16968: }
16969: if( zLine[h]==delim ){
16970: zLine[h++] = 0;
1.2 misho 16971: }
16972: if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
16973: }else{
1.4 misho 16974: azArg[nArg++] = &zLine[h];
16975: while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
16976: if( zLine[h] ) zLine[h++] = 0;
1.2 misho 16977: resolve_backslashes(azArg[nArg-1]);
16978: }
16979: }
1.4.2.3 ! misho 16980: azArg[nArg] = 0;
1.2 misho 16981:
16982: /* Process the input line.
16983: */
16984: if( nArg==0 ) return 0; /* no tokens, no error */
16985: n = strlen30(azArg[0]);
16986: c = azArg[0][0];
1.4.2.2 misho 16987: clearTempFile(p);
1.4 misho 16988:
1.4.2.1 misho 16989: #ifndef SQLITE_OMIT_AUTHORIZATION
1.4 misho 16990: if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
16991: if( nArg!=2 ){
16992: raw_printf(stderr, "Usage: .auth ON|OFF\n");
16993: rc = 1;
16994: goto meta_command_exit;
16995: }
16996: open_db(p, 0);
16997: if( booleanValue(azArg[1]) ){
16998: sqlite3_set_authorizer(p->db, shellAuth, p);
16999: }else{
17000: sqlite3_set_authorizer(p->db, 0, 0);
17001: }
17002: }else
1.4.2.1 misho 17003: #endif
1.4 misho 17004:
1.4.2.2 misho 17005: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
17006: if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
17007: open_db(p, 0);
17008: rc = arDotCommand(p, 0, azArg, nArg);
17009: }else
17010: #endif
17011:
1.4 misho 17012: if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
17013: || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
17014: ){
17015: const char *zDestFile = 0;
17016: const char *zDb = 0;
1.2 misho 17017: sqlite3 *pDest;
17018: sqlite3_backup *pBackup;
1.4 misho 17019: int j;
1.4.2.2 misho 17020: int bAsync = 0;
17021: const char *zVfs = 0;
1.4 misho 17022: for(j=1; j<nArg; j++){
17023: const char *z = azArg[j];
17024: if( z[0]=='-' ){
1.4.2.2 misho 17025: if( z[1]=='-' ) z++;
17026: if( strcmp(z, "-append")==0 ){
17027: zVfs = "apndvfs";
17028: }else
17029: if( strcmp(z, "-async")==0 ){
17030: bAsync = 1;
17031: }else
1.4 misho 17032: {
17033: utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
17034: return 1;
17035: }
17036: }else if( zDestFile==0 ){
17037: zDestFile = azArg[j];
17038: }else if( zDb==0 ){
17039: zDb = zDestFile;
17040: zDestFile = azArg[j];
17041: }else{
1.4.2.2 misho 17042: raw_printf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
1.4 misho 17043: return 1;
17044: }
17045: }
17046: if( zDestFile==0 ){
17047: raw_printf(stderr, "missing FILENAME argument on .backup\n");
17048: return 1;
1.2 misho 17049: }
1.4 misho 17050: if( zDb==0 ) zDb = "main";
1.4.2.2 misho 17051: rc = sqlite3_open_v2(zDestFile, &pDest,
17052: SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
1.2 misho 17053: if( rc!=SQLITE_OK ){
1.4 misho 17054: utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
1.4.2.2 misho 17055: close_db(pDest);
1.2 misho 17056: return 1;
17057: }
1.4.2.2 misho 17058: if( bAsync ){
17059: sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;",
17060: 0, 0, 0);
17061: }
1.4 misho 17062: open_db(p, 0);
1.2 misho 17063: pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
17064: if( pBackup==0 ){
1.4 misho 17065: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1.4.2.2 misho 17066: close_db(pDest);
1.2 misho 17067: return 1;
17068: }
17069: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
17070: sqlite3_backup_finish(pBackup);
17071: if( rc==SQLITE_DONE ){
17072: rc = 0;
17073: }else{
1.4 misho 17074: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1.2 misho 17075: rc = 1;
17076: }
1.4.2.2 misho 17077: close_db(pDest);
1.2 misho 17078: }else
17079:
1.4 misho 17080: if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
17081: if( nArg==2 ){
17082: bail_on_error = booleanValue(azArg[1]);
17083: }else{
17084: raw_printf(stderr, "Usage: .bail on|off\n");
17085: rc = 1;
17086: }
17087: }else
17088:
17089: if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
17090: if( nArg==2 ){
17091: if( booleanValue(azArg[1]) ){
17092: setBinaryMode(p->out, 1);
17093: }else{
17094: setTextMode(p->out, 1);
17095: }
17096: }else{
17097: raw_printf(stderr, "Usage: .binary on|off\n");
17098: rc = 1;
17099: }
1.2 misho 17100: }else
17101:
1.4.2.2 misho 17102: if( c=='c' && strcmp(azArg[0],"cd")==0 ){
17103: if( nArg==2 ){
17104: #if defined(_WIN32) || defined(WIN32)
17105: wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
17106: rc = !SetCurrentDirectoryW(z);
17107: sqlite3_free(z);
17108: #else
17109: rc = chdir(azArg[1]);
17110: #endif
17111: if( rc ){
17112: utf8_printf(stderr, "Cannot change to directory \"%s\"\n", azArg[1]);
17113: rc = 1;
17114: }
17115: }else{
17116: raw_printf(stderr, "Usage: .cd DIRECTORY\n");
17117: rc = 1;
17118: }
17119: }else
17120:
1.3 misho 17121: /* The undocumented ".breakpoint" command causes a call to the no-op
17122: ** routine named test_breakpoint().
17123: */
17124: if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
17125: test_breakpoint();
17126: }else
17127:
1.4 misho 17128: if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
17129: if( nArg==2 ){
1.4.2.1 misho 17130: setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
1.4 misho 17131: }else{
17132: raw_printf(stderr, "Usage: .changes on|off\n");
17133: rc = 1;
17134: }
17135: }else
17136:
1.4.2.1 misho 17137: /* Cancel output redirection, if it is currently set (by .testcase)
17138: ** Then read the content of the testcase-out.txt file and compare against
17139: ** azArg[1]. If there are differences, report an error and exit.
17140: */
17141: if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
17142: char *zRes = 0;
17143: output_reset(p);
17144: if( nArg!=2 ){
17145: raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
17146: rc = 2;
17147: }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
17148: raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
17149: rc = 2;
17150: }else if( testcase_glob(azArg[1],zRes)==0 ){
17151: utf8_printf(stderr,
17152: "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
17153: p->zTestcase, azArg[1], zRes);
1.4.2.2 misho 17154: rc = 1;
1.4.2.1 misho 17155: }else{
17156: utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
17157: p->nCheck++;
17158: }
17159: sqlite3_free(zRes);
17160: }else
17161:
1.4 misho 17162: if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
17163: if( nArg==2 ){
17164: tryToClone(p, azArg[1]);
17165: }else{
17166: raw_printf(stderr, "Usage: .clone FILENAME\n");
17167: rc = 1;
17168: }
17169: }else
17170:
17171: if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
17172: ShellState data;
1.2 misho 17173: char *zErrMsg = 0;
1.4 misho 17174: open_db(p, 0);
1.2 misho 17175: memcpy(&data, p, sizeof(data));
1.4.2.1 misho 17176: data.showHeader = 0;
17177: data.cMode = data.mode = MODE_List;
17178: sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
1.2 misho 17179: data.cnt = 0;
1.4.2.1 misho 17180: sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
17181: callback, &data, &zErrMsg);
1.2 misho 17182: if( zErrMsg ){
1.4 misho 17183: utf8_printf(stderr,"Error: %s\n", zErrMsg);
1.2 misho 17184: sqlite3_free(zErrMsg);
17185: rc = 1;
17186: }
17187: }else
17188:
1.4.2.2 misho 17189: if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
17190: static const struct DbConfigChoices {
17191: const char *zName;
17192: int op;
17193: } aDbConfig[] = {
1.4.2.3 ! misho 17194: { "defensive", SQLITE_DBCONFIG_DEFENSIVE },
! 17195: { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
! 17196: { "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
1.4.2.2 misho 17197: { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
1.4.2.3 ! misho 17198: { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
1.4.2.2 misho 17199: { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
1.4.2.3 ! misho 17200: { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
1.4.2.2 misho 17201: { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
1.4.2.3 ! misho 17202: { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
! 17203: { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT },
1.4.2.2 misho 17204: { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
17205: { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
17206: { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
1.4.2.3 ! misho 17207: { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
! 17208: { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA },
1.4.2.2 misho 17209: { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
17210: };
17211: int ii, v;
17212: open_db(p, 0);
17213: for(ii=0; ii<ArraySize(aDbConfig); ii++){
17214: if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
17215: if( nArg>=3 ){
17216: sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
17217: }
17218: sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
1.4.2.3 ! misho 17219: utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
1.4.2.2 misho 17220: if( nArg>1 ) break;
17221: }
17222: if( nArg>1 && ii==ArraySize(aDbConfig) ){
17223: utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
17224: utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
17225: }
17226: }else
17227:
17228: if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
1.4 misho 17229: rc = shell_dbinfo_command(p, nArg, azArg);
17230: }else
17231:
1.4.2.2 misho 17232: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
17233: if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
17234: open_db(p, 0);
17235: rc = recoverDatabaseCmd(p, nArg, azArg);
17236: }else
17237: #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
17238:
1.4 misho 17239: if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
1.4.2.3 ! misho 17240: char *zLike = 0;
! 17241: char *zSql;
1.4.2.1 misho 17242: int i;
17243: int savedShowHeader = p->showHeader;
1.4.2.2 misho 17244: int savedShellFlags = p->shellFlgs;
17245: ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);
1.4.2.1 misho 17246: for(i=1; i<nArg; i++){
17247: if( azArg[i][0]=='-' ){
17248: const char *z = azArg[i]+1;
17249: if( z[0]=='-' ) z++;
17250: if( strcmp(z,"preserve-rowids")==0 ){
17251: #ifdef SQLITE_OMIT_VIRTUALTABLE
17252: raw_printf(stderr, "The --preserve-rowids option is not compatible"
17253: " with SQLITE_OMIT_VIRTUALTABLE\n");
17254: rc = 1;
1.4.2.3 ! misho 17255: sqlite3_free(zLike);
1.4.2.1 misho 17256: goto meta_command_exit;
17257: #else
17258: ShellSetFlag(p, SHFLG_PreserveRowid);
17259: #endif
17260: }else
1.4.2.2 misho 17261: if( strcmp(z,"newlines")==0 ){
17262: ShellSetFlag(p, SHFLG_Newlines);
17263: }else
1.4.2.1 misho 17264: {
17265: raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
17266: rc = 1;
1.4.2.3 ! misho 17267: sqlite3_free(zLike);
1.4.2.1 misho 17268: goto meta_command_exit;
17269: }
17270: }else if( zLike ){
1.4.2.3 ! misho 17271: zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
! 17272: zLike, azArg[i]);
1.4.2.1 misho 17273: }else{
1.4.2.3 ! misho 17274: zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
1.4.2.1 misho 17275: }
17276: }
1.4.2.2 misho 17277:
1.4 misho 17278: open_db(p, 0);
1.4.2.2 misho 17279:
1.2 misho 17280: /* When playing back a "dump", the content might appear in an order
17281: ** which causes immediate foreign key constraints to be violated.
17282: ** So disable foreign-key constraint enforcement to prevent problems. */
1.4 misho 17283: raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
17284: raw_printf(p->out, "BEGIN TRANSACTION;\n");
1.2 misho 17285: p->writableSchema = 0;
1.4.2.1 misho 17286: p->showHeader = 0;
17287: /* Set writable_schema=ON since doing so forces SQLite to initialize
1.4.2.3 ! misho 17288: ** as much of the schema as it can even if the sqlite_schema table is
1.4.2.1 misho 17289: ** corrupt. */
1.2 misho 17290: sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
17291: p->nErr = 0;
1.4.2.3 ! misho 17292: if( zLike==0 ) zLike = sqlite3_mprintf("true");
! 17293: zSql = sqlite3_mprintf(
! 17294: "SELECT name, type, sql FROM sqlite_schema "
! 17295: "WHERE (%s) AND type=='table'"
! 17296: " AND sql NOT NULL"
! 17297: " ORDER BY tbl_name='sqlite_sequence', rowid",
! 17298: zLike
! 17299: );
! 17300: run_schema_dump_query(p,zSql);
! 17301: sqlite3_free(zSql);
! 17302: zSql = sqlite3_mprintf(
! 17303: "SELECT sql FROM sqlite_schema "
! 17304: "WHERE (%s) AND sql NOT NULL"
! 17305: " AND type IN ('index','trigger','view')",
! 17306: zLike
! 17307: );
! 17308: run_table_dump_query(p, zSql);
! 17309: sqlite3_free(zSql);
! 17310: sqlite3_free(zLike);
1.2 misho 17311: if( p->writableSchema ){
1.4 misho 17312: raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
1.2 misho 17313: p->writableSchema = 0;
17314: }
17315: sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
17316: sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
1.4.2.2 misho 17317: raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
1.4.2.1 misho 17318: p->showHeader = savedShowHeader;
1.4.2.2 misho 17319: p->shellFlgs = savedShellFlags;
1.4 misho 17320: }else
17321:
17322: if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
17323: if( nArg==2 ){
1.4.2.1 misho 17324: setOrClearFlag(p, SHFLG_Echo, azArg[1]);
1.4 misho 17325: }else{
17326: raw_printf(stderr, "Usage: .echo on|off\n");
17327: rc = 1;
17328: }
1.2 misho 17329: }else
17330:
1.4 misho 17331: if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
17332: if( nArg==2 ){
1.4.2.2 misho 17333: p->autoEQPtest = 0;
17334: if( p->autoEQPtrace ){
17335: if( p->db ) sqlite3_exec(p->db, "PRAGMA vdbe_trace=OFF;", 0, 0, 0);
17336: p->autoEQPtrace = 0;
17337: }
1.4 misho 17338: if( strcmp(azArg[1],"full")==0 ){
1.4.2.2 misho 17339: p->autoEQP = AUTOEQP_full;
17340: }else if( strcmp(azArg[1],"trigger")==0 ){
17341: p->autoEQP = AUTOEQP_trigger;
17342: #ifdef SQLITE_DEBUG
17343: }else if( strcmp(azArg[1],"test")==0 ){
17344: p->autoEQP = AUTOEQP_on;
17345: p->autoEQPtest = 1;
17346: }else if( strcmp(azArg[1],"trace")==0 ){
17347: p->autoEQP = AUTOEQP_full;
17348: p->autoEQPtrace = 1;
17349: open_db(p, 0);
1.4.2.3 ! misho 17350: sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
1.4.2.2 misho 17351: sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
17352: #endif
1.4 misho 17353: }else{
1.4.2.2 misho 17354: p->autoEQP = (u8)booleanValue(azArg[1]);
1.4 misho 17355: }
17356: }else{
1.4.2.2 misho 17357: raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
1.4 misho 17358: rc = 1;
17359: }
1.2 misho 17360: }else
17361:
1.4 misho 17362: if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
17363: if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
1.2 misho 17364: rc = 2;
17365: }else
17366:
1.4.2.2 misho 17367: /* The ".explain" command is automatic now. It is largely pointless. It
17368: ** retained purely for backwards compatibility */
1.4 misho 17369: if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
17370: int val = 1;
17371: if( nArg>=2 ){
17372: if( strcmp(azArg[1],"auto")==0 ){
17373: val = 99;
17374: }else{
17375: val = booleanValue(azArg[1]);
17376: }
17377: }
17378: if( val==1 && p->mode!=MODE_Explain ){
17379: p->normalMode = p->mode;
1.2 misho 17380: p->mode = MODE_Explain;
1.4 misho 17381: p->autoExplain = 0;
17382: }else if( val==0 ){
17383: if( p->mode==MODE_Explain ) p->mode = p->normalMode;
17384: p->autoExplain = 0;
17385: }else if( val==99 ){
17386: if( p->mode==MODE_Explain ) p->mode = p->normalMode;
17387: p->autoExplain = 1;
17388: }
17389: }else
17390:
1.4.2.2 misho 17391: #ifndef SQLITE_OMIT_VIRTUALTABLE
17392: if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){
17393: open_db(p, 0);
17394: expertDotCommand(p, azArg, nArg);
17395: }else
17396: #endif
17397:
17398: if( c=='f' && strncmp(azArg[0], "filectrl", n)==0 ){
17399: static const struct {
17400: const char *zCtrlName; /* Name of a test-control option */
17401: int ctrlCode; /* Integer code for that option */
17402: const char *zUsage; /* Usage notes */
17403: } aCtrl[] = {
17404: { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" },
17405: { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" },
17406: /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/
17407: { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" },
17408: { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" },
17409: /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/
17410: { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" },
17411: { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" },
17412: { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" },
1.4.2.3 ! misho 17413: { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" },
1.4.2.2 misho 17414: };
17415: int filectrl = -1;
17416: int iCtrl = -1;
17417: sqlite3_int64 iRes = 0; /* Integer result to display if rc2==1 */
17418: int isOk = 0; /* 0: usage 1: %lld 2: no-result */
17419: int n2, i;
17420: const char *zCmd = 0;
1.4.2.3 ! misho 17421: const char *zSchema = 0;
1.4.2.2 misho 17422:
17423: open_db(p, 0);
17424: zCmd = nArg>=2 ? azArg[1] : "help";
17425:
1.4.2.3 ! misho 17426: if( zCmd[0]=='-'
! 17427: && (strcmp(zCmd,"--schema")==0 || strcmp(zCmd,"-schema")==0)
! 17428: && nArg>=4
! 17429: ){
! 17430: zSchema = azArg[2];
! 17431: for(i=3; i<nArg; i++) azArg[i-2] = azArg[i];
! 17432: nArg -= 2;
! 17433: zCmd = azArg[1];
! 17434: }
! 17435:
1.4.2.2 misho 17436: /* The argument can optionally begin with "-" or "--" */
17437: if( zCmd[0]=='-' && zCmd[1] ){
17438: zCmd++;
17439: if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
17440: }
17441:
17442: /* --help lists all file-controls */
17443: if( strcmp(zCmd,"help")==0 ){
17444: utf8_printf(p->out, "Available file-controls:\n");
17445: for(i=0; i<ArraySize(aCtrl); i++){
17446: utf8_printf(p->out, " .filectrl %s %s\n",
17447: aCtrl[i].zCtrlName, aCtrl[i].zUsage);
17448: }
17449: rc = 1;
17450: goto meta_command_exit;
17451: }
17452:
17453: /* convert filectrl text option to value. allow any unique prefix
17454: ** of the option name, or a numerical value. */
17455: n2 = strlen30(zCmd);
17456: for(i=0; i<ArraySize(aCtrl); i++){
17457: if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
17458: if( filectrl<0 ){
17459: filectrl = aCtrl[i].ctrlCode;
17460: iCtrl = i;
17461: }else{
17462: utf8_printf(stderr, "Error: ambiguous file-control: \"%s\"\n"
17463: "Use \".filectrl --help\" for help\n", zCmd);
17464: rc = 1;
17465: goto meta_command_exit;
17466: }
17467: }
17468: }
17469: if( filectrl<0 ){
17470: utf8_printf(stderr,"Error: unknown file-control: %s\n"
17471: "Use \".filectrl --help\" for help\n", zCmd);
17472: }else{
17473: switch(filectrl){
17474: case SQLITE_FCNTL_SIZE_LIMIT: {
17475: if( nArg!=2 && nArg!=3 ) break;
17476: iRes = nArg==3 ? integerValue(azArg[2]) : -1;
1.4.2.3 ! misho 17477: sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
1.4.2.2 misho 17478: isOk = 1;
17479: break;
17480: }
17481: case SQLITE_FCNTL_LOCK_TIMEOUT:
17482: case SQLITE_FCNTL_CHUNK_SIZE: {
17483: int x;
17484: if( nArg!=3 ) break;
17485: x = (int)integerValue(azArg[2]);
1.4.2.3 ! misho 17486: sqlite3_file_control(p->db, zSchema, filectrl, &x);
1.4.2.2 misho 17487: isOk = 2;
17488: break;
17489: }
17490: case SQLITE_FCNTL_PERSIST_WAL:
17491: case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
17492: int x;
17493: if( nArg!=2 && nArg!=3 ) break;
17494: x = nArg==3 ? booleanValue(azArg[2]) : -1;
1.4.2.3 ! misho 17495: sqlite3_file_control(p->db, zSchema, filectrl, &x);
1.4.2.2 misho 17496: iRes = x;
17497: isOk = 1;
17498: break;
17499: }
17500: case SQLITE_FCNTL_HAS_MOVED: {
17501: int x;
17502: if( nArg!=2 ) break;
1.4.2.3 ! misho 17503: sqlite3_file_control(p->db, zSchema, filectrl, &x);
1.4.2.2 misho 17504: iRes = x;
17505: isOk = 1;
17506: break;
17507: }
17508: case SQLITE_FCNTL_TEMPFILENAME: {
17509: char *z = 0;
17510: if( nArg!=2 ) break;
1.4.2.3 ! misho 17511: sqlite3_file_control(p->db, zSchema, filectrl, &z);
1.4.2.2 misho 17512: if( z ){
17513: utf8_printf(p->out, "%s\n", z);
17514: sqlite3_free(z);
17515: }
17516: isOk = 2;
17517: break;
17518: }
1.4.2.3 ! misho 17519: case SQLITE_FCNTL_RESERVE_BYTES: {
! 17520: int x;
! 17521: if( nArg>=3 ){
! 17522: x = atoi(azArg[2]);
! 17523: sqlite3_file_control(p->db, zSchema, filectrl, &x);
! 17524: }
! 17525: x = -1;
! 17526: sqlite3_file_control(p->db, zSchema, filectrl, &x);
! 17527: utf8_printf(p->out,"%d\n", x);
! 17528: isOk = 2;
! 17529: break;
! 17530: }
1.4.2.2 misho 17531: }
17532: }
17533: if( isOk==0 && iCtrl>=0 ){
17534: utf8_printf(p->out, "Usage: .filectrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
17535: rc = 1;
17536: }else if( isOk==1 ){
17537: char zBuf[100];
17538: sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
17539: raw_printf(p->out, "%s\n", zBuf);
17540: }
17541: }else
17542:
1.4 misho 17543: if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
17544: ShellState data;
17545: char *zErrMsg = 0;
17546: int doStats = 0;
17547: memcpy(&data, p, sizeof(data));
17548: data.showHeader = 0;
17549: data.cMode = data.mode = MODE_Semi;
17550: if( nArg==2 && optionMatch(azArg[1], "indent") ){
17551: data.cMode = data.mode = MODE_Pretty;
17552: nArg = 1;
17553: }
17554: if( nArg!=1 ){
17555: raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
17556: rc = 1;
17557: goto meta_command_exit;
17558: }
17559: open_db(p, 0);
17560: rc = sqlite3_exec(p->db,
17561: "SELECT sql FROM"
17562: " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
1.4.2.3 ! misho 17563: " FROM sqlite_schema UNION ALL"
! 17564: " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
1.4 misho 17565: "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
17566: "ORDER BY rowid",
17567: callback, &data, &zErrMsg
17568: );
17569: if( rc==SQLITE_OK ){
17570: sqlite3_stmt *pStmt;
17571: rc = sqlite3_prepare_v2(p->db,
1.4.2.3 ! misho 17572: "SELECT rowid FROM sqlite_schema"
1.4 misho 17573: " WHERE name GLOB 'sqlite_stat[134]'",
17574: -1, &pStmt, 0);
17575: doStats = sqlite3_step(pStmt)==SQLITE_ROW;
17576: sqlite3_finalize(pStmt);
17577: }
17578: if( doStats==0 ){
17579: raw_printf(p->out, "/* No STAT tables available */\n");
17580: }else{
1.4.2.3 ! misho 17581: raw_printf(p->out, "ANALYZE sqlite_schema;\n");
! 17582: sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_schema'",
1.4 misho 17583: callback, &data, &zErrMsg);
17584: data.cMode = data.mode = MODE_Insert;
17585: data.zDestTable = "sqlite_stat1";
1.4.2.2 misho 17586: shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
1.4 misho 17587: data.zDestTable = "sqlite_stat4";
1.4.2.2 misho 17588: shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
1.4.2.3 ! misho 17589: raw_printf(p->out, "ANALYZE sqlite_schema;\n");
1.2 misho 17590: }
17591: }else
17592:
1.4 misho 17593: if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
17594: if( nArg==2 ){
17595: p->showHeader = booleanValue(azArg[1]);
1.4.2.3 ! misho 17596: p->shellFlgs |= SHFLG_HeaderSet;
1.4 misho 17597: }else{
17598: raw_printf(stderr, "Usage: .headers on|off\n");
17599: rc = 1;
17600: }
1.2 misho 17601: }else
17602:
17603: if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
1.4.2.2 misho 17604: if( nArg>=2 ){
17605: n = showHelp(p->out, azArg[1]);
17606: if( n==0 ){
17607: utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
17608: }
17609: }else{
17610: showHelp(p->out, 0);
17611: }
1.2 misho 17612: }else
17613:
1.4 misho 17614: if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
1.4.2.3 ! misho 17615: char *zTable = 0; /* Insert data into this table */
! 17616: char *zFile = 0; /* Name of file to extra content from */
1.2 misho 17617: sqlite3_stmt *pStmt = NULL; /* A statement */
17618: int nCol; /* Number of columns in the table */
17619: int nByte; /* Number of bytes in an SQL string */
17620: int i, j; /* Loop counters */
1.4 misho 17621: int needCommit; /* True to COMMIT or ROLLBACK at end */
17622: int nSep; /* Number of bytes in p->colSeparator[] */
1.2 misho 17623: char *zSql; /* An SQL statement */
1.4 misho 17624: ImportCtx sCtx; /* Reader context */
17625: char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
1.4.2.3 ! misho 17626: int eVerbose = 0; /* Larger for more console output */
! 17627: int nSkip = 0; /* Initial lines to skip */
! 17628: int useOutputMode = 1; /* Use output mode to determine separators */
1.4 misho 17629:
17630: memset(&sCtx, 0, sizeof(sCtx));
1.4.2.3 ! misho 17631: if( p->mode==MODE_Ascii ){
! 17632: xRead = ascii_read_one_field;
! 17633: }else{
! 17634: xRead = csv_read_one_field;
1.4 misho 17635: }
1.4.2.3 ! misho 17636: for(i=1; i<nArg; i++){
! 17637: char *z = azArg[i];
! 17638: if( z[0]=='-' && z[1]=='-' ) z++;
! 17639: if( z[0]!='-' ){
! 17640: if( zFile==0 ){
! 17641: zFile = z;
! 17642: }else if( zTable==0 ){
! 17643: zTable = z;
! 17644: }else{
! 17645: utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n", z);
! 17646: showHelp(p->out, "import");
! 17647: rc = 1;
! 17648: goto meta_command_exit;
! 17649: }
! 17650: }else if( strcmp(z,"-v")==0 ){
! 17651: eVerbose++;
! 17652: }else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
! 17653: nSkip = integerValue(azArg[++i]);
! 17654: }else if( strcmp(z,"-ascii")==0 ){
! 17655: sCtx.cColSep = SEP_Unit[0];
! 17656: sCtx.cRowSep = SEP_Record[0];
! 17657: xRead = ascii_read_one_field;
! 17658: useOutputMode = 0;
! 17659: }else if( strcmp(z,"-csv")==0 ){
! 17660: sCtx.cColSep = ',';
! 17661: sCtx.cRowSep = '\n';
! 17662: xRead = csv_read_one_field;
! 17663: useOutputMode = 0;
! 17664: }else{
! 17665: utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
! 17666: showHelp(p->out, "import");
! 17667: rc = 1;
! 17668: goto meta_command_exit;
! 17669: }
1.4 misho 17670: }
1.4.2.3 ! misho 17671: if( zTable==0 ){
! 17672: utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
! 17673: zFile==0 ? "FILE" : "TABLE");
! 17674: showHelp(p->out, "import");
! 17675: rc = 1;
! 17676: goto meta_command_exit;
1.2 misho 17677: }
1.4.2.3 ! misho 17678: seenInterrupt = 0;
! 17679: open_db(p, 0);
! 17680: if( useOutputMode ){
! 17681: /* If neither the --csv or --ascii options are specified, then set
! 17682: ** the column and row separator characters from the output mode. */
! 17683: nSep = strlen30(p->colSeparator);
! 17684: if( nSep==0 ){
! 17685: raw_printf(stderr,
! 17686: "Error: non-null column separator required for import\n");
! 17687: rc = 1;
! 17688: goto meta_command_exit;
! 17689: }
! 17690: if( nSep>1 ){
! 17691: raw_printf(stderr,
! 17692: "Error: multi-character column separators not allowed"
! 17693: " for import\n");
! 17694: rc = 1;
! 17695: goto meta_command_exit;
! 17696: }
1.4 misho 17697: nSep = strlen30(p->rowSeparator);
1.4.2.3 ! misho 17698: if( nSep==0 ){
! 17699: raw_printf(stderr,
! 17700: "Error: non-null row separator required for import\n");
! 17701: rc = 1;
! 17702: goto meta_command_exit;
! 17703: }
! 17704: if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
! 17705: /* When importing CSV (only), if the row separator is set to the
! 17706: ** default output row separator, change it to the default input
! 17707: ** row separator. This avoids having to maintain different input
! 17708: ** and output row separators. */
! 17709: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
! 17710: nSep = strlen30(p->rowSeparator);
! 17711: }
! 17712: if( nSep>1 ){
! 17713: raw_printf(stderr, "Error: multi-character row separators not allowed"
! 17714: " for import\n");
! 17715: rc = 1;
! 17716: goto meta_command_exit;
! 17717: }
! 17718: sCtx.cColSep = p->colSeparator[0];
! 17719: sCtx.cRowSep = p->rowSeparator[0];
1.4 misho 17720: }
17721: sCtx.zFile = zFile;
17722: sCtx.nLine = 1;
17723: if( sCtx.zFile[0]=='|' ){
17724: #ifdef SQLITE_OMIT_POPEN
17725: raw_printf(stderr, "Error: pipes are not supported in this OS\n");
1.4.2.3 ! misho 17726: rc = 1;
! 17727: goto meta_command_exit;
1.4 misho 17728: #else
17729: sCtx.in = popen(sCtx.zFile+1, "r");
17730: sCtx.zFile = "<pipe>";
1.4.2.3 ! misho 17731: sCtx.xCloser = pclose;
1.4 misho 17732: #endif
17733: }else{
17734: sCtx.in = fopen(sCtx.zFile, "rb");
1.4.2.3 ! misho 17735: sCtx.xCloser = fclose;
1.4 misho 17736: }
17737: if( sCtx.in==0 ){
17738: utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
1.4.2.3 ! misho 17739: rc = 1;
! 17740: goto meta_command_exit;
! 17741: }
! 17742: if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
! 17743: char zSep[2];
! 17744: zSep[1] = 0;
! 17745: zSep[0] = sCtx.cColSep;
! 17746: utf8_printf(p->out, "Column separator ");
! 17747: output_c_string(p->out, zSep);
! 17748: utf8_printf(p->out, ", row separator ");
! 17749: zSep[0] = sCtx.cRowSep;
! 17750: output_c_string(p->out, zSep);
! 17751: utf8_printf(p->out, "\n");
! 17752: }
! 17753: while( (nSkip--)>0 ){
! 17754: while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
1.4 misho 17755: }
1.2 misho 17756: zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
17757: if( zSql==0 ){
1.4.2.3 ! misho 17758: import_cleanup(&sCtx);
1.4.2.2 misho 17759: shell_out_of_memory();
1.2 misho 17760: }
17761: nByte = strlen30(zSql);
1.4 misho 17762: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
17763: import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
17764: if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
17765: char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
17766: char cSep = '(';
17767: while( xRead(&sCtx) ){
17768: zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
17769: cSep = ',';
17770: if( sCtx.cTerm!=sCtx.cColSep ) break;
17771: }
17772: if( cSep=='(' ){
17773: sqlite3_free(zCreate);
1.4.2.3 ! misho 17774: import_cleanup(&sCtx);
1.4 misho 17775: utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
1.4.2.3 ! misho 17776: rc = 1;
! 17777: goto meta_command_exit;
1.4 misho 17778: }
17779: zCreate = sqlite3_mprintf("%z\n)", zCreate);
1.4.2.3 ! misho 17780: if( eVerbose>=1 ){
! 17781: utf8_printf(p->out, "%s\n", zCreate);
! 17782: }
1.4 misho 17783: rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
17784: sqlite3_free(zCreate);
17785: if( rc ){
17786: utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
17787: sqlite3_errmsg(p->db));
1.4.2.3 ! misho 17788: import_cleanup(&sCtx);
! 17789: rc = 1;
! 17790: goto meta_command_exit;
1.4 misho 17791: }
17792: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
17793: }
1.2 misho 17794: sqlite3_free(zSql);
17795: if( rc ){
17796: if (pStmt) sqlite3_finalize(pStmt);
1.4 misho 17797: utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
1.4.2.3 ! misho 17798: import_cleanup(&sCtx);
! 17799: rc = 1;
! 17800: goto meta_command_exit;
1.2 misho 17801: }
17802: nCol = sqlite3_column_count(pStmt);
17803: sqlite3_finalize(pStmt);
17804: pStmt = 0;
17805: if( nCol==0 ) return 0; /* no columns, no error */
1.4 misho 17806: zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
1.2 misho 17807: if( zSql==0 ){
1.4.2.3 ! misho 17808: import_cleanup(&sCtx);
1.4.2.2 misho 17809: shell_out_of_memory();
1.2 misho 17810: }
1.4 misho 17811: sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
1.2 misho 17812: j = strlen30(zSql);
17813: for(i=1; i<nCol; i++){
17814: zSql[j++] = ',';
17815: zSql[j++] = '?';
17816: }
17817: zSql[j++] = ')';
17818: zSql[j] = 0;
1.4.2.3 ! misho 17819: if( eVerbose>=2 ){
! 17820: utf8_printf(p->out, "Insert using: %s\n", zSql);
! 17821: }
1.4 misho 17822: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
17823: sqlite3_free(zSql);
1.2 misho 17824: if( rc ){
1.4 misho 17825: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1.2 misho 17826: if (pStmt) sqlite3_finalize(pStmt);
1.4.2.3 ! misho 17827: import_cleanup(&sCtx);
! 17828: rc = 1;
! 17829: goto meta_command_exit;
1.2 misho 17830: }
1.4 misho 17831: needCommit = sqlite3_get_autocommit(p->db);
17832: if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
17833: do{
17834: int startLine = sCtx.nLine;
17835: for(i=0; i<nCol; i++){
17836: char *z = xRead(&sCtx);
17837: /*
17838: ** Did we reach end-of-file before finding any columns?
17839: ** If so, stop instead of NULL filling the remaining columns.
17840: */
17841: if( z==0 && i==0 ) break;
17842: /*
17843: ** Did we reach end-of-file OR end-of-line before finding any
17844: ** columns in ASCII mode? If so, stop instead of NULL filling
17845: ** the remaining columns.
17846: */
17847: if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
17848: sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
17849: if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
17850: utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
17851: "filling the rest with NULL\n",
17852: sCtx.zFile, startLine, nCol, i+1);
17853: i += 2;
17854: while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
17855: }
17856: }
17857: if( sCtx.cTerm==sCtx.cColSep ){
17858: do{
17859: xRead(&sCtx);
1.2 misho 17860: i++;
1.4 misho 17861: }while( sCtx.cTerm==sCtx.cColSep );
17862: utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
17863: "extras ignored\n",
17864: sCtx.zFile, startLine, nCol, i);
17865: }
17866: if( i>=nCol ){
17867: sqlite3_step(pStmt);
17868: rc = sqlite3_reset(pStmt);
17869: if( rc!=SQLITE_OK ){
17870: utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
17871: startLine, sqlite3_errmsg(p->db));
1.4.2.3 ! misho 17872: sCtx.nErr++;
! 17873: }else{
! 17874: sCtx.nRow++;
1.2 misho 17875: }
17876: }
1.4 misho 17877: }while( sCtx.cTerm!=EOF );
17878:
1.4.2.3 ! misho 17879: import_cleanup(&sCtx);
1.2 misho 17880: sqlite3_finalize(pStmt);
1.4 misho 17881: if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
1.4.2.3 ! misho 17882: if( eVerbose>0 ){
! 17883: utf8_printf(p->out,
! 17884: "Added %d rows with %d errors using %d lines of input\n",
! 17885: sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
! 17886: }
1.2 misho 17887: }else
17888:
1.4.2.1 misho 17889: #ifndef SQLITE_UNTESTABLE
17890: if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
17891: char *zSql;
17892: char *zCollist = 0;
17893: sqlite3_stmt *pStmt;
17894: int tnum = 0;
1.4.2.3 ! misho 17895: int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */
! 17896: int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
1.4.2.1 misho 17897: int i;
1.4.2.2 misho 17898: if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
17899: utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
17900: " .imposter off\n");
1.4.2.3 ! misho 17901: /* Also allowed, but not documented:
! 17902: **
! 17903: ** .imposter TABLE IMPOSTER
! 17904: **
! 17905: ** where TABLE is a WITHOUT ROWID table. In that case, the
! 17906: ** imposter is another WITHOUT ROWID table with the columns in
! 17907: ** storage order. */
1.4 misho 17908: rc = 1;
17909: goto meta_command_exit;
1.2 misho 17910: }
1.4.2.1 misho 17911: open_db(p, 0);
1.4.2.2 misho 17912: if( nArg==2 ){
17913: sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
17914: goto meta_command_exit;
17915: }
1.4.2.3 ! misho 17916: zSql = sqlite3_mprintf(
! 17917: "SELECT rootpage, 0 FROM sqlite_schema"
! 17918: " WHERE name='%q' AND type='index'"
! 17919: "UNION ALL "
! 17920: "SELECT rootpage, 1 FROM sqlite_schema"
! 17921: " WHERE name='%q' AND type='table'"
! 17922: " AND sql LIKE '%%without%%rowid%%'",
! 17923: azArg[1], azArg[1]
! 17924: );
1.4.2.1 misho 17925: sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
17926: sqlite3_free(zSql);
17927: if( sqlite3_step(pStmt)==SQLITE_ROW ){
17928: tnum = sqlite3_column_int(pStmt, 0);
1.4.2.3 ! misho 17929: isWO = sqlite3_column_int(pStmt, 1);
1.4.2.1 misho 17930: }
17931: sqlite3_finalize(pStmt);
17932: zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
17933: rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
17934: sqlite3_free(zSql);
17935: i = 0;
17936: while( sqlite3_step(pStmt)==SQLITE_ROW ){
17937: char zLabel[20];
17938: const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
17939: i++;
17940: if( zCol==0 ){
17941: if( sqlite3_column_int(pStmt,1)==-1 ){
17942: zCol = "_ROWID_";
17943: }else{
17944: sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
17945: zCol = zLabel;
17946: }
17947: }
1.4.2.3 ! misho 17948: if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){
! 17949: lenPK = (int)strlen(zCollist);
! 17950: }
1.4.2.1 misho 17951: if( zCollist==0 ){
17952: zCollist = sqlite3_mprintf("\"%w\"", zCol);
17953: }else{
17954: zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
17955: }
17956: }
17957: sqlite3_finalize(pStmt);
1.4.2.3 ! misho 17958: if( i==0 || tnum==0 ){
! 17959: utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
! 17960: rc = 1;
! 17961: sqlite3_free(zCollist);
! 17962: goto meta_command_exit;
! 17963: }
! 17964: if( lenPK==0 ) lenPK = 100000;
1.4.2.1 misho 17965: zSql = sqlite3_mprintf(
1.4.2.3 ! misho 17966: "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
! 17967: azArg[2], zCollist, lenPK, zCollist);
1.4.2.1 misho 17968: sqlite3_free(zCollist);
17969: rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
17970: if( rc==SQLITE_OK ){
17971: rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
17972: sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
17973: if( rc ){
17974: utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
17975: }else{
17976: utf8_printf(stdout, "%s;\n", zSql);
17977: raw_printf(stdout,
1.4.2.3 ! misho 17978: "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n",
! 17979: azArg[1], isWO ? "table" : "index"
1.4.2.1 misho 17980: );
17981: }
17982: }else{
17983: raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
1.2 misho 17984: rc = 1;
17985: }
1.4.2.1 misho 17986: sqlite3_free(zSql);
1.2 misho 17987: }else
1.4.2.1 misho 17988: #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
1.2 misho 17989:
17990: #ifdef SQLITE_ENABLE_IOTRACE
17991: if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
1.4 misho 17992: SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
1.2 misho 17993: if( iotrace && iotrace!=stdout ) fclose(iotrace);
17994: iotrace = 0;
17995: if( nArg<2 ){
17996: sqlite3IoTrace = 0;
17997: }else if( strcmp(azArg[1], "-")==0 ){
17998: sqlite3IoTrace = iotracePrintf;
17999: iotrace = stdout;
1.4 misho 18000: }else{
18001: iotrace = fopen(azArg[1], "w");
18002: if( iotrace==0 ){
18003: utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
18004: sqlite3IoTrace = 0;
18005: rc = 1;
18006: }else{
18007: sqlite3IoTrace = iotracePrintf;
18008: }
18009: }
18010: }else
18011: #endif
1.4.2.1 misho 18012:
1.4 misho 18013: if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
18014: static const struct {
18015: const char *zLimitName; /* Name of a limit */
18016: int limitCode; /* Integer code for that limit */
18017: } aLimit[] = {
18018: { "length", SQLITE_LIMIT_LENGTH },
18019: { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
18020: { "column", SQLITE_LIMIT_COLUMN },
18021: { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
18022: { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
18023: { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
18024: { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
18025: { "attached", SQLITE_LIMIT_ATTACHED },
18026: { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
18027: { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
18028: { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
18029: { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
18030: };
18031: int i, n2;
18032: open_db(p, 0);
18033: if( nArg==1 ){
18034: for(i=0; i<ArraySize(aLimit); i++){
18035: printf("%20s %d\n", aLimit[i].zLimitName,
18036: sqlite3_limit(p->db, aLimit[i].limitCode, -1));
18037: }
18038: }else if( nArg>3 ){
18039: raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
18040: rc = 1;
18041: goto meta_command_exit;
18042: }else{
18043: int iLimit = -1;
18044: n2 = strlen30(azArg[1]);
18045: for(i=0; i<ArraySize(aLimit); i++){
18046: if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
18047: if( iLimit<0 ){
18048: iLimit = i;
18049: }else{
18050: utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
18051: rc = 1;
18052: goto meta_command_exit;
18053: }
18054: }
18055: }
18056: if( iLimit<0 ){
18057: utf8_printf(stderr, "unknown limit: \"%s\"\n"
18058: "enter \".limits\" with no arguments for a list.\n",
18059: azArg[1]);
1.2 misho 18060: rc = 1;
1.4 misho 18061: goto meta_command_exit;
18062: }
18063: if( nArg==3 ){
18064: sqlite3_limit(p->db, aLimit[iLimit].limitCode,
18065: (int)integerValue(azArg[2]));
1.2 misho 18066: }
1.4 misho 18067: printf("%20s %d\n", aLimit[iLimit].zLimitName,
18068: sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
1.2 misho 18069: }
18070: }else
18071:
1.4.2.1 misho 18072: if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
18073: open_db(p, 0);
18074: lintDotCommand(p, azArg, nArg);
18075: }else
18076:
1.2 misho 18077: #ifndef SQLITE_OMIT_LOAD_EXTENSION
1.4 misho 18078: if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
1.2 misho 18079: const char *zFile, *zProc;
18080: char *zErrMsg = 0;
1.4 misho 18081: if( nArg<2 ){
18082: raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
18083: rc = 1;
18084: goto meta_command_exit;
18085: }
1.2 misho 18086: zFile = azArg[1];
18087: zProc = nArg>=3 ? azArg[2] : 0;
1.4 misho 18088: open_db(p, 0);
1.2 misho 18089: rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
18090: if( rc!=SQLITE_OK ){
1.4 misho 18091: utf8_printf(stderr, "Error: %s\n", zErrMsg);
1.2 misho 18092: sqlite3_free(zErrMsg);
18093: rc = 1;
18094: }
18095: }else
18096: #endif
18097:
1.4 misho 18098: if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
18099: if( nArg!=2 ){
18100: raw_printf(stderr, "Usage: .log FILENAME\n");
18101: rc = 1;
18102: }else{
18103: const char *zFile = azArg[1];
18104: output_file_close(p->pLog);
1.4.2.2 misho 18105: p->pLog = output_file_open(zFile, 0);
1.4 misho 18106: }
1.2 misho 18107: }else
18108:
1.4 misho 18109: if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
18110: const char *zMode = nArg>=2 ? azArg[1] : "";
1.4.2.2 misho 18111: int n2 = strlen30(zMode);
1.4 misho 18112: int c2 = zMode[0];
18113: if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
1.2 misho 18114: p->mode = MODE_Line;
1.4.2.1 misho 18115: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 18116: }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
1.2 misho 18117: p->mode = MODE_Column;
1.4.2.3 ! misho 18118: if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
! 18119: p->showHeader = 1;
! 18120: }
1.4.2.1 misho 18121: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 18122: }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
1.2 misho 18123: p->mode = MODE_List;
1.4.2.1 misho 18124: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
18125: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 18126: }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
1.2 misho 18127: p->mode = MODE_Html;
1.4 misho 18128: }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
1.2 misho 18129: p->mode = MODE_Tcl;
1.4 misho 18130: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
1.4.2.1 misho 18131: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 18132: }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
1.2 misho 18133: p->mode = MODE_Csv;
1.4 misho 18134: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
18135: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
18136: }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
1.2 misho 18137: p->mode = MODE_List;
1.4 misho 18138: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
18139: }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
1.2 misho 18140: p->mode = MODE_Insert;
1.4 misho 18141: set_table_name(p, nArg>=3 ? azArg[2] : "table");
1.4.2.1 misho 18142: }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
18143: p->mode = MODE_Quote;
1.4.2.3 ! misho 18144: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
! 18145: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
1.4 misho 18146: }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
18147: p->mode = MODE_Ascii;
18148: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
18149: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
1.4.2.3 ! misho 18150: }else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
! 18151: p->mode = MODE_Markdown;
! 18152: }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
! 18153: p->mode = MODE_Table;
! 18154: }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
! 18155: p->mode = MODE_Box;
! 18156: }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
! 18157: p->mode = MODE_Json;
1.4.2.2 misho 18158: }else if( nArg==1 ){
18159: raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
18160: }else{
1.4 misho 18161: raw_printf(stderr, "Error: mode should be one of: "
1.4.2.3 ! misho 18162: "ascii box column csv html insert json line list markdown "
! 18163: "quote table tabs tcl\n");
1.2 misho 18164: rc = 1;
18165: }
1.4 misho 18166: p->cMode = p->mode;
1.2 misho 18167: }else
18168:
1.4 misho 18169: if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
18170: if( nArg==2 ){
18171: sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
18172: "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
18173: }else{
18174: raw_printf(stderr, "Usage: .nullvalue STRING\n");
1.2 misho 18175: rc = 1;
18176: }
18177: }else
18178:
1.4.2.3 ! misho 18179: #ifdef SQLITE_DEBUG
! 18180: if( c=='o' && strcmp(azArg[0],"oom")==0 ){
! 18181: int i;
! 18182: for(i=1; i<nArg; i++){
! 18183: const char *z = azArg[i];
! 18184: if( z[0]=='-' && z[1]=='-' ) z++;
! 18185: if( strcmp(z,"-repeat")==0 ){
! 18186: if( i==nArg-1 ){
! 18187: raw_printf(p->out, "missing argument on \"%s\"\n", azArg[i]);
! 18188: rc = 1;
! 18189: }else{
! 18190: oomRepeat = (int)integerValue(azArg[++i]);
! 18191: }
! 18192: }else if( IsDigit(z[0]) ){
! 18193: oomCounter = (int)integerValue(azArg[i]);
! 18194: }else{
! 18195: raw_printf(p->out, "unknown argument: \"%s\"\n", azArg[i]);
! 18196: raw_printf(p->out, "Usage: .oom [--repeat N] [M]\n");
! 18197: rc = 1;
! 18198: }
! 18199: }
! 18200: if( rc==0 ){
! 18201: raw_printf(p->out, "oomCounter = %d\n", oomCounter);
! 18202: raw_printf(p->out, "oomRepeat = %d\n", oomRepeat);
! 18203: }
! 18204: }else
! 18205: #endif /* SQLITE_DEBUG */
! 18206:
1.4 misho 18207: if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
1.4.2.1 misho 18208: char *zNewFilename; /* Name of the database file to open */
18209: int iName = 1; /* Index in azArg[] of the filename */
18210: int newFlag = 0; /* True to delete file before opening */
18211: /* Close the existing database */
18212: session_close_all(p);
1.4.2.2 misho 18213: close_db(p->db);
1.4 misho 18214: p->db = 0;
1.4.2.1 misho 18215: p->zDbFilename = 0;
18216: sqlite3_free(p->zFreeOnClose);
18217: p->zFreeOnClose = 0;
1.4.2.2 misho 18218: p->openMode = SHELL_OPEN_UNSPEC;
1.4.2.3 ! misho 18219: p->openFlags = 0;
1.4.2.2 misho 18220: p->szMax = 0;
1.4.2.1 misho 18221: /* Check for command-line arguments */
18222: for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
18223: const char *z = azArg[iName];
18224: if( optionMatch(z,"new") ){
18225: newFlag = 1;
1.4.2.2 misho 18226: #ifdef SQLITE_HAVE_ZLIB
18227: }else if( optionMatch(z, "zip") ){
18228: p->openMode = SHELL_OPEN_ZIPFILE;
18229: #endif
18230: }else if( optionMatch(z, "append") ){
18231: p->openMode = SHELL_OPEN_APPENDVFS;
18232: }else if( optionMatch(z, "readonly") ){
18233: p->openMode = SHELL_OPEN_READONLY;
1.4.2.3 ! misho 18234: }else if( optionMatch(z, "nofollow") ){
! 18235: p->openFlags |= SQLITE_OPEN_NOFOLLOW;
1.4.2.2 misho 18236: #ifdef SQLITE_ENABLE_DESERIALIZE
18237: }else if( optionMatch(z, "deserialize") ){
18238: p->openMode = SHELL_OPEN_DESERIALIZE;
18239: }else if( optionMatch(z, "hexdb") ){
18240: p->openMode = SHELL_OPEN_HEXDB;
18241: }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
18242: p->szMax = integerValue(azArg[++iName]);
18243: #endif /* SQLITE_ENABLE_DESERIALIZE */
1.4.2.1 misho 18244: }else if( z[0]=='-' ){
18245: utf8_printf(stderr, "unknown option: %s\n", z);
18246: rc = 1;
18247: goto meta_command_exit;
18248: }
18249: }
18250: /* If a filename is specified, try to open it first */
18251: zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
1.4.2.2 misho 18252: if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
1.4.2.1 misho 18253: if( newFlag ) shellDeleteFile(zNewFilename);
18254: p->zDbFilename = zNewFilename;
1.4.2.2 misho 18255: open_db(p, OPEN_DB_KEEPALIVE);
1.4.2.1 misho 18256: if( p->db==0 ){
18257: utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
18258: sqlite3_free(zNewFilename);
18259: }else{
18260: p->zFreeOnClose = zNewFilename;
18261: }
18262: }
18263: if( p->db==0 ){
18264: /* As a fall-back open a TEMP database */
18265: p->zDbFilename = 0;
18266: open_db(p, 0);
1.4 misho 18267: }
1.2 misho 18268: }else
18269:
1.4.2.2 misho 18270: if( (c=='o'
18271: && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
18272: || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
1.4 misho 18273: ){
1.4.2.3 ! misho 18274: const char *zFile = 0;
1.4.2.2 misho 18275: int bTxtMode = 0;
1.4.2.3 ! misho 18276: int i;
! 18277: int eMode = 0;
! 18278: int bBOM = 0;
! 18279: int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
! 18280:
! 18281: if( c=='e' ){
! 18282: eMode = 'x';
! 18283: bOnce = 2;
! 18284: }else if( strncmp(azArg[0],"once",n)==0 ){
! 18285: bOnce = 1;
1.4 misho 18286: }
1.4.2.3 ! misho 18287: for(i=1; i<nArg; i++){
! 18288: char *z = azArg[i];
! 18289: if( z[0]=='-' ){
! 18290: if( z[1]=='-' ) z++;
! 18291: if( strcmp(z,"-bom")==0 ){
! 18292: bBOM = 1;
! 18293: }else if( c!='e' && strcmp(z,"-x")==0 ){
! 18294: eMode = 'x'; /* spreadsheet */
! 18295: }else if( c!='e' && strcmp(z,"-e")==0 ){
! 18296: eMode = 'e'; /* text editor */
! 18297: }else{
! 18298: utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n",
! 18299: azArg[i]);
! 18300: showHelp(p->out, azArg[0]);
! 18301: rc = 1;
! 18302: goto meta_command_exit;
! 18303: }
! 18304: }else if( zFile==0 ){
! 18305: zFile = z;
! 18306: }else{
! 18307: utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n",
! 18308: azArg[i]);
! 18309: showHelp(p->out, azArg[0]);
1.4 misho 18310: rc = 1;
18311: goto meta_command_exit;
18312: }
1.4.2.3 ! misho 18313: }
! 18314: if( zFile==0 ) zFile = "stdout";
! 18315: if( bOnce ){
1.4 misho 18316: p->outCount = 2;
1.3 misho 18317: }else{
1.4 misho 18318: p->outCount = 0;
1.2 misho 18319: }
1.4 misho 18320: output_reset(p);
1.4.2.2 misho 18321: #ifndef SQLITE_NOHAVE_SYSTEM
1.4.2.3 ! misho 18322: if( eMode=='e' || eMode=='x' ){
1.4.2.2 misho 18323: p->doXdgOpen = 1;
18324: outputModePush(p);
1.4.2.3 ! misho 18325: if( eMode=='x' ){
! 18326: /* spreadsheet mode. Output as CSV. */
1.4.2.2 misho 18327: newTempFile(p, "csv");
1.4.2.3 ! misho 18328: ShellClearFlag(p, SHFLG_Echo);
1.4.2.2 misho 18329: p->mode = MODE_Csv;
18330: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
18331: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
18332: }else{
1.4.2.3 ! misho 18333: /* text editor mode */
1.4.2.2 misho 18334: newTempFile(p, "txt");
18335: bTxtMode = 1;
18336: }
18337: zFile = p->zTempFile;
18338: }
18339: #endif /* SQLITE_NOHAVE_SYSTEM */
1.4 misho 18340: if( zFile[0]=='|' ){
18341: #ifdef SQLITE_OMIT_POPEN
18342: raw_printf(stderr, "Error: pipes are not supported in this OS\n");
18343: rc = 1;
18344: p->out = stdout;
18345: #else
18346: p->out = popen(zFile + 1, "w");
1.3 misho 18347: if( p->out==0 ){
1.4 misho 18348: utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
1.3 misho 18349: p->out = stdout;
18350: rc = 1;
18351: }else{
1.4.2.3 ! misho 18352: if( bBOM ) fprintf(p->out,"\357\273\277");
1.4 misho 18353: sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
1.3 misho 18354: }
1.4 misho 18355: #endif
1.2 misho 18356: }else{
1.4.2.2 misho 18357: p->out = output_file_open(zFile, bTxtMode);
1.2 misho 18358: if( p->out==0 ){
1.4 misho 18359: if( strcmp(zFile,"off")!=0 ){
18360: utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
1.3 misho 18361: }
1.4.2.2 misho 18362: p->out = stdout;
18363: rc = 1;
18364: } else {
1.4.2.3 ! misho 18365: if( bBOM ) fprintf(p->out,"\357\273\277");
1.4.2.2 misho 18366: sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
18367: }
18368: }
18369: }else
18370:
18371: if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
18372: open_db(p,0);
18373: if( nArg<=1 ) goto parameter_syntax_error;
18374:
18375: /* .parameter clear
18376: ** Clear all bind parameters by dropping the TEMP table that holds them.
18377: */
18378: if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
18379: sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
18380: 0, 0, 0);
18381: }else
18382:
18383: /* .parameter list
18384: ** List all bind parameters.
18385: */
18386: if( nArg==2 && strcmp(azArg[1],"list")==0 ){
18387: sqlite3_stmt *pStmt = 0;
18388: int rx;
18389: int len = 0;
18390: rx = sqlite3_prepare_v2(p->db,
18391: "SELECT max(length(key)) "
18392: "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
18393: if( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
18394: len = sqlite3_column_int(pStmt, 0);
18395: if( len>40 ) len = 40;
18396: }
18397: sqlite3_finalize(pStmt);
18398: pStmt = 0;
18399: if( len ){
18400: rx = sqlite3_prepare_v2(p->db,
18401: "SELECT key, quote(value) "
18402: "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
18403: while( sqlite3_step(pStmt)==SQLITE_ROW ){
18404: utf8_printf(p->out, "%-*s %s\n", len, sqlite3_column_text(pStmt,0),
18405: sqlite3_column_text(pStmt,1));
18406: }
18407: sqlite3_finalize(pStmt);
18408: }
18409: }else
18410:
18411: /* .parameter init
18412: ** Make sure the TEMP table used to hold bind parameters exists.
18413: ** Create it if necessary.
18414: */
18415: if( nArg==2 && strcmp(azArg[1],"init")==0 ){
18416: bind_table_init(p);
18417: }else
18418:
18419: /* .parameter set NAME VALUE
18420: ** Set or reset a bind parameter. NAME should be the full parameter
18421: ** name exactly as it appears in the query. (ex: $abc, @def). The
18422: ** VALUE can be in either SQL literal notation, or if not it will be
18423: ** understood to be a text string.
18424: */
18425: if( nArg==4 && strcmp(azArg[1],"set")==0 ){
18426: int rx;
18427: char *zSql;
18428: sqlite3_stmt *pStmt;
18429: const char *zKey = azArg[2];
18430: const char *zValue = azArg[3];
18431: bind_table_init(p);
18432: zSql = sqlite3_mprintf(
18433: "REPLACE INTO temp.sqlite_parameters(key,value)"
18434: "VALUES(%Q,%s);", zKey, zValue);
18435: if( zSql==0 ) shell_out_of_memory();
18436: pStmt = 0;
18437: rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
18438: sqlite3_free(zSql);
18439: if( rx!=SQLITE_OK ){
18440: sqlite3_finalize(pStmt);
18441: pStmt = 0;
18442: zSql = sqlite3_mprintf(
18443: "REPLACE INTO temp.sqlite_parameters(key,value)"
18444: "VALUES(%Q,%Q);", zKey, zValue);
18445: if( zSql==0 ) shell_out_of_memory();
18446: rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
18447: sqlite3_free(zSql);
18448: if( rx!=SQLITE_OK ){
18449: utf8_printf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
18450: sqlite3_finalize(pStmt);
18451: pStmt = 0;
18452: rc = 1;
18453: }
1.2 misho 18454: }
1.4.2.2 misho 18455: sqlite3_step(pStmt);
18456: sqlite3_finalize(pStmt);
18457: }else
18458:
18459: /* .parameter unset NAME
18460: ** Remove the NAME binding from the parameter binding table, if it
18461: ** exists.
18462: */
18463: if( nArg==3 && strcmp(azArg[1],"unset")==0 ){
18464: char *zSql = sqlite3_mprintf(
18465: "DELETE FROM temp.sqlite_parameters WHERE key=%Q", azArg[2]);
18466: if( zSql==0 ) shell_out_of_memory();
18467: sqlite3_exec(p->db, zSql, 0, 0, 0);
18468: sqlite3_free(zSql);
18469: }else
18470: /* If no command name matches, show a syntax error */
18471: parameter_syntax_error:
18472: showHelp(p->out, "parameter");
1.2 misho 18473: }else
18474:
1.3 misho 18475: if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
18476: int i;
18477: for(i=1; i<nArg; i++){
1.4 misho 18478: if( i>1 ) raw_printf(p->out, " ");
18479: utf8_printf(p->out, "%s", azArg[i]);
1.3 misho 18480: }
1.4 misho 18481: raw_printf(p->out, "\n");
1.3 misho 18482: }else
18483:
1.4.2.2 misho 18484: #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
18485: if( c=='p' && n>=3 && strncmp(azArg[0], "progress", n)==0 ){
18486: int i;
18487: int nn = 0;
18488: p->flgProgress = 0;
18489: p->mxProgress = 0;
18490: p->nProgress = 0;
18491: for(i=1; i<nArg; i++){
18492: const char *z = azArg[i];
18493: if( z[0]=='-' ){
18494: z++;
18495: if( z[0]=='-' ) z++;
18496: if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
18497: p->flgProgress |= SHELL_PROGRESS_QUIET;
18498: continue;
18499: }
18500: if( strcmp(z,"reset")==0 ){
18501: p->flgProgress |= SHELL_PROGRESS_RESET;
18502: continue;
18503: }
18504: if( strcmp(z,"once")==0 ){
18505: p->flgProgress |= SHELL_PROGRESS_ONCE;
18506: continue;
18507: }
18508: if( strcmp(z,"limit")==0 ){
18509: if( i+1>=nArg ){
18510: utf8_printf(stderr, "Error: missing argument on --limit\n");
18511: rc = 1;
18512: goto meta_command_exit;
18513: }else{
18514: p->mxProgress = (int)integerValue(azArg[++i]);
18515: }
18516: continue;
18517: }
18518: utf8_printf(stderr, "Error: unknown option: \"%s\"\n", azArg[i]);
18519: rc = 1;
18520: goto meta_command_exit;
18521: }else{
18522: nn = (int)integerValue(z);
18523: }
18524: }
18525: open_db(p, 0);
18526: sqlite3_progress_handler(p->db, nn, progress_handler, p);
18527: }else
18528: #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
18529:
1.4 misho 18530: if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
1.2 misho 18531: if( nArg >= 2) {
18532: strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
18533: }
18534: if( nArg >= 3) {
18535: strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
18536: }
18537: }else
18538:
1.4 misho 18539: if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
1.2 misho 18540: rc = 2;
18541: }else
18542:
1.4 misho 18543: if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
1.4.2.2 misho 18544: FILE *inSaved = p->in;
18545: int savedLineno = p->lineno;
1.4 misho 18546: if( nArg!=2 ){
18547: raw_printf(stderr, "Usage: .read FILE\n");
18548: rc = 1;
18549: goto meta_command_exit;
18550: }
1.4.2.3 ! misho 18551: if( notNormalFile(azArg[1])
! 18552: || (p->in = fopen(azArg[1], "rb"))==0
! 18553: ){
1.4 misho 18554: utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
1.2 misho 18555: rc = 1;
18556: }else{
1.4.2.2 misho 18557: rc = process_input(p);
18558: fclose(p->in);
1.2 misho 18559: }
1.4.2.2 misho 18560: p->in = inSaved;
18561: p->lineno = savedLineno;
1.2 misho 18562: }else
18563:
1.4 misho 18564: if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
1.2 misho 18565: const char *zSrcFile;
18566: const char *zDb;
18567: sqlite3 *pSrc;
18568: sqlite3_backup *pBackup;
18569: int nTimeout = 0;
18570:
18571: if( nArg==2 ){
18572: zSrcFile = azArg[1];
18573: zDb = "main";
1.4 misho 18574: }else if( nArg==3 ){
1.2 misho 18575: zSrcFile = azArg[2];
18576: zDb = azArg[1];
1.4 misho 18577: }else{
18578: raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
18579: rc = 1;
18580: goto meta_command_exit;
1.2 misho 18581: }
18582: rc = sqlite3_open(zSrcFile, &pSrc);
18583: if( rc!=SQLITE_OK ){
1.4 misho 18584: utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
1.4.2.2 misho 18585: close_db(pSrc);
1.2 misho 18586: return 1;
18587: }
1.4 misho 18588: open_db(p, 0);
1.2 misho 18589: pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
18590: if( pBackup==0 ){
1.4 misho 18591: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1.4.2.2 misho 18592: close_db(pSrc);
1.2 misho 18593: return 1;
18594: }
18595: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
18596: || rc==SQLITE_BUSY ){
18597: if( rc==SQLITE_BUSY ){
18598: if( nTimeout++ >= 3 ) break;
18599: sqlite3_sleep(100);
18600: }
18601: }
18602: sqlite3_backup_finish(pBackup);
18603: if( rc==SQLITE_DONE ){
18604: rc = 0;
18605: }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
1.4 misho 18606: raw_printf(stderr, "Error: source database is busy\n");
1.2 misho 18607: rc = 1;
18608: }else{
1.4 misho 18609: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1.2 misho 18610: rc = 1;
18611: }
1.4.2.2 misho 18612: close_db(pSrc);
1.2 misho 18613: }else
18614:
1.4 misho 18615: if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
18616: if( nArg==2 ){
1.4.2.2 misho 18617: p->scanstatsOn = (u8)booleanValue(azArg[1]);
1.4 misho 18618: #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
18619: raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
18620: #endif
18621: }else{
18622: raw_printf(stderr, "Usage: .scanstats on|off\n");
18623: rc = 1;
18624: }
18625: }else
18626:
18627: if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
1.4.2.2 misho 18628: ShellText sSelect;
1.4 misho 18629: ShellState data;
1.2 misho 18630: char *zErrMsg = 0;
1.4.2.2 misho 18631: const char *zDiv = "(";
18632: const char *zName = 0;
18633: int iSchema = 0;
18634: int bDebug = 0;
18635: int ii;
18636:
1.4 misho 18637: open_db(p, 0);
1.2 misho 18638: memcpy(&data, p, sizeof(data));
18639: data.showHeader = 0;
1.4 misho 18640: data.cMode = data.mode = MODE_Semi;
1.4.2.2 misho 18641: initText(&sSelect);
18642: for(ii=1; ii<nArg; ii++){
18643: if( optionMatch(azArg[ii],"indent") ){
18644: data.cMode = data.mode = MODE_Pretty;
18645: }else if( optionMatch(azArg[ii],"debug") ){
18646: bDebug = 1;
18647: }else if( zName==0 ){
18648: zName = azArg[ii];
18649: }else{
18650: raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
18651: rc = 1;
18652: goto meta_command_exit;
18653: }
1.4 misho 18654: }
1.4.2.2 misho 18655: if( zName!=0 ){
1.4.2.3 ! misho 18656: int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0
! 18657: || sqlite3_strlike(zName, "sqlite_schema", '\\')==0
! 18658: || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
! 18659: || sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
! 18660: if( isSchema ){
1.2 misho 18661: char *new_argv[2], *new_colv[2];
1.4.2.2 misho 18662: new_argv[0] = sqlite3_mprintf(
18663: "CREATE TABLE %s (\n"
1.2 misho 18664: " type text,\n"
18665: " name text,\n"
18666: " tbl_name text,\n"
18667: " rootpage integer,\n"
18668: " sql text\n"
1.4.2.3 ! misho 18669: ")", zName);
1.2 misho 18670: new_argv[1] = 0;
18671: new_colv[0] = "sql";
18672: new_colv[1] = 0;
18673: callback(&data, 1, new_argv, new_colv);
1.4.2.2 misho 18674: sqlite3_free(new_argv[0]);
18675: }
18676: }
18677: if( zDiv ){
18678: sqlite3_stmt *pStmt = 0;
18679: rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
18680: -1, &pStmt, 0);
18681: if( rc ){
18682: utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
18683: sqlite3_finalize(pStmt);
18684: rc = 1;
18685: goto meta_command_exit;
18686: }
18687: appendText(&sSelect, "SELECT sql FROM", 0);
18688: iSchema = 0;
18689: while( sqlite3_step(pStmt)==SQLITE_ROW ){
18690: const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
18691: char zScNum[30];
18692: sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
18693: appendText(&sSelect, zDiv, 0);
18694: zDiv = " UNION ALL ";
18695: appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
18696: if( sqlite3_stricmp(zDb, "main")!=0 ){
1.4.2.3 ! misho 18697: appendText(&sSelect, zDb, '\'');
1.4.2.2 misho 18698: }else{
18699: appendText(&sSelect, "NULL", 0);
18700: }
18701: appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
18702: appendText(&sSelect, zScNum, 0);
18703: appendText(&sSelect, " AS snum, ", 0);
18704: appendText(&sSelect, zDb, '\'');
18705: appendText(&sSelect, " AS sname FROM ", 0);
1.4.2.3 ! misho 18706: appendText(&sSelect, zDb, quoteChar(zDb));
! 18707: appendText(&sSelect, ".sqlite_schema", 0);
1.4.2.2 misho 18708: }
18709: sqlite3_finalize(pStmt);
1.4.2.3 ! misho 18710: #ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
1.4.2.2 misho 18711: if( zName ){
18712: appendText(&sSelect,
18713: " UNION ALL SELECT shell_module_schema(name),"
1.4.2.3 ! misho 18714: " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
! 18715: 0);
1.4.2.2 misho 18716: }
18717: #endif
18718: appendText(&sSelect, ") WHERE ", 0);
18719: if( zName ){
18720: char *zQarg = sqlite3_mprintf("%Q", zName);
18721: int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
18722: strchr(zName, '[') != 0;
18723: if( strchr(zName, '.') ){
18724: appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
18725: }else{
18726: appendText(&sSelect, "lower(tbl_name)", 0);
18727: }
18728: appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
18729: appendText(&sSelect, zQarg, 0);
18730: if( !bGlob ){
18731: appendText(&sSelect, " ESCAPE '\\' ", 0);
18732: }
18733: appendText(&sSelect, " AND ", 0);
18734: sqlite3_free(zQarg);
18735: }
18736: appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
18737: " ORDER BY snum, rowid", 0);
18738: if( bDebug ){
18739: utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
1.2 misho 18740: }else{
1.4.2.2 misho 18741: rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
1.2 misho 18742: }
1.4.2.2 misho 18743: freeText(&sSelect);
1.2 misho 18744: }
18745: if( zErrMsg ){
1.4 misho 18746: utf8_printf(stderr,"Error: %s\n", zErrMsg);
1.2 misho 18747: sqlite3_free(zErrMsg);
18748: rc = 1;
18749: }else if( rc != SQLITE_OK ){
1.4 misho 18750: raw_printf(stderr,"Error: querying schema information\n");
1.2 misho 18751: rc = 1;
18752: }else{
18753: rc = 0;
18754: }
18755: }else
18756:
1.4 misho 18757: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
18758: if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
1.4.2.3 ! misho 18759: sqlite3_unsupported_selecttrace = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffff;
1.4 misho 18760: }else
18761: #endif
18762:
18763: #if defined(SQLITE_ENABLE_SESSION)
18764: if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
18765: OpenSession *pSession = &p->aSession[0];
18766: char **azCmd = &azArg[1];
18767: int iSes = 0;
18768: int nCmd = nArg - 1;
18769: int i;
18770: if( nArg<=1 ) goto session_syntax_error;
18771: open_db(p, 0);
18772: if( nArg>=3 ){
18773: for(iSes=0; iSes<p->nSession; iSes++){
18774: if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
18775: }
18776: if( iSes<p->nSession ){
18777: pSession = &p->aSession[iSes];
18778: azCmd++;
18779: nCmd--;
18780: }else{
18781: pSession = &p->aSession[0];
18782: iSes = 0;
18783: }
18784: }
18785:
18786: /* .session attach TABLE
18787: ** Invoke the sqlite3session_attach() interface to attach a particular
18788: ** table so that it is never filtered.
18789: */
18790: if( strcmp(azCmd[0],"attach")==0 ){
18791: if( nCmd!=2 ) goto session_syntax_error;
18792: if( pSession->p==0 ){
18793: session_not_open:
18794: raw_printf(stderr, "ERROR: No sessions are open\n");
18795: }else{
18796: rc = sqlite3session_attach(pSession->p, azCmd[1]);
18797: if( rc ){
18798: raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
18799: rc = 0;
18800: }
18801: }
18802: }else
18803:
18804: /* .session changeset FILE
18805: ** .session patchset FILE
18806: ** Write a changeset or patchset into a file. The file is overwritten.
18807: */
18808: if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
18809: FILE *out = 0;
18810: if( nCmd!=2 ) goto session_syntax_error;
18811: if( pSession->p==0 ) goto session_not_open;
18812: out = fopen(azCmd[1], "wb");
18813: if( out==0 ){
1.4.2.3 ! misho 18814: utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n",
! 18815: azCmd[1]);
1.4 misho 18816: }else{
18817: int szChng;
18818: void *pChng;
18819: if( azCmd[0][0]=='c' ){
18820: rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
18821: }else{
18822: rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
18823: }
18824: if( rc ){
18825: printf("Error: error code %d\n", rc);
18826: rc = 0;
18827: }
18828: if( pChng
18829: && fwrite(pChng, szChng, 1, out)!=1 ){
18830: raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
18831: szChng);
18832: }
18833: sqlite3_free(pChng);
18834: fclose(out);
18835: }
18836: }else
18837:
18838: /* .session close
18839: ** Close the identified session
18840: */
18841: if( strcmp(azCmd[0], "close")==0 ){
18842: if( nCmd!=1 ) goto session_syntax_error;
18843: if( p->nSession ){
18844: session_close(pSession);
18845: p->aSession[iSes] = p->aSession[--p->nSession];
18846: }
18847: }else
18848:
18849: /* .session enable ?BOOLEAN?
18850: ** Query or set the enable flag
18851: */
18852: if( strcmp(azCmd[0], "enable")==0 ){
18853: int ii;
18854: if( nCmd>2 ) goto session_syntax_error;
18855: ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
18856: if( p->nSession ){
18857: ii = sqlite3session_enable(pSession->p, ii);
18858: utf8_printf(p->out, "session %s enable flag = %d\n",
18859: pSession->zName, ii);
18860: }
18861: }else
18862:
18863: /* .session filter GLOB ....
18864: ** Set a list of GLOB patterns of table names to be excluded.
18865: */
18866: if( strcmp(azCmd[0], "filter")==0 ){
18867: int ii, nByte;
18868: if( nCmd<2 ) goto session_syntax_error;
18869: if( p->nSession ){
18870: for(ii=0; ii<pSession->nFilter; ii++){
18871: sqlite3_free(pSession->azFilter[ii]);
18872: }
18873: sqlite3_free(pSession->azFilter);
18874: nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
18875: pSession->azFilter = sqlite3_malloc( nByte );
18876: if( pSession->azFilter==0 ){
18877: raw_printf(stderr, "Error: out or memory\n");
18878: exit(1);
18879: }
18880: for(ii=1; ii<nCmd; ii++){
18881: pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
18882: }
18883: pSession->nFilter = ii-1;
18884: }
18885: }else
18886:
18887: /* .session indirect ?BOOLEAN?
18888: ** Query or set the indirect flag
18889: */
18890: if( strcmp(azCmd[0], "indirect")==0 ){
18891: int ii;
18892: if( nCmd>2 ) goto session_syntax_error;
18893: ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
18894: if( p->nSession ){
18895: ii = sqlite3session_indirect(pSession->p, ii);
18896: utf8_printf(p->out, "session %s indirect flag = %d\n",
18897: pSession->zName, ii);
18898: }
18899: }else
18900:
18901: /* .session isempty
18902: ** Determine if the session is empty
18903: */
18904: if( strcmp(azCmd[0], "isempty")==0 ){
18905: int ii;
18906: if( nCmd!=1 ) goto session_syntax_error;
18907: if( p->nSession ){
18908: ii = sqlite3session_isempty(pSession->p);
18909: utf8_printf(p->out, "session %s isempty flag = %d\n",
18910: pSession->zName, ii);
18911: }
18912: }else
18913:
18914: /* .session list
18915: ** List all currently open sessions
18916: */
18917: if( strcmp(azCmd[0],"list")==0 ){
18918: for(i=0; i<p->nSession; i++){
18919: utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
18920: }
18921: }else
18922:
18923: /* .session open DB NAME
18924: ** Open a new session called NAME on the attached database DB.
18925: ** DB is normally "main".
18926: */
18927: if( strcmp(azCmd[0],"open")==0 ){
18928: char *zName;
18929: if( nCmd!=3 ) goto session_syntax_error;
18930: zName = azCmd[2];
18931: if( zName[0]==0 ) goto session_syntax_error;
18932: for(i=0; i<p->nSession; i++){
18933: if( strcmp(p->aSession[i].zName,zName)==0 ){
18934: utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
18935: goto meta_command_exit;
18936: }
18937: }
18938: if( p->nSession>=ArraySize(p->aSession) ){
18939: raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
18940: goto meta_command_exit;
18941: }
18942: pSession = &p->aSession[p->nSession];
18943: rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
18944: if( rc ){
18945: raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
18946: rc = 0;
18947: goto meta_command_exit;
18948: }
18949: pSession->nFilter = 0;
18950: sqlite3session_table_filter(pSession->p, session_filter, pSession);
18951: p->nSession++;
18952: pSession->zName = sqlite3_mprintf("%s", zName);
18953: }else
18954: /* If no command name matches, show a syntax error */
18955: session_syntax_error:
1.4.2.2 misho 18956: showHelp(p->out, "session");
1.4 misho 18957: }else
18958: #endif
18959:
18960: #ifdef SQLITE_DEBUG
18961: /* Undocumented commands for internal testing. Subject to change
18962: ** without notice. */
18963: if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
18964: if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
18965: int i, v;
18966: for(i=1; i<nArg; i++){
18967: v = booleanValue(azArg[i]);
18968: utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
18969: }
18970: }
18971: if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
18972: int i; sqlite3_int64 v;
18973: for(i=1; i<nArg; i++){
18974: char zBuf[200];
18975: v = integerValue(azArg[i]);
18976: sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
18977: utf8_printf(p->out, "%s", zBuf);
18978: }
18979: }
18980: }else
18981: #endif
18982:
1.4.2.1 misho 18983: if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){
18984: int bIsInit = 0; /* True to initialize the SELFTEST table */
18985: int bVerbose = 0; /* Verbose output */
18986: int bSelftestExists; /* True if SELFTEST already exists */
1.4.2.2 misho 18987: int i, k; /* Loop counters */
1.4.2.1 misho 18988: int nTest = 0; /* Number of tests runs */
18989: int nErr = 0; /* Number of errors seen */
18990: ShellText str; /* Answer for a query */
1.4.2.2 misho 18991: sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */
1.4.2.1 misho 18992:
18993: open_db(p,0);
18994: for(i=1; i<nArg; i++){
18995: const char *z = azArg[i];
18996: if( z[0]=='-' && z[1]=='-' ) z++;
18997: if( strcmp(z,"-init")==0 ){
18998: bIsInit = 1;
18999: }else
19000: if( strcmp(z,"-v")==0 ){
19001: bVerbose++;
19002: }else
19003: {
19004: utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
19005: azArg[i], azArg[0]);
19006: raw_printf(stderr, "Should be one of: --init -v\n");
19007: rc = 1;
19008: goto meta_command_exit;
19009: }
19010: }
19011: if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
19012: != SQLITE_OK ){
19013: bSelftestExists = 0;
19014: }else{
19015: bSelftestExists = 1;
19016: }
19017: if( bIsInit ){
19018: createSelftestTable(p);
19019: bSelftestExists = 1;
19020: }
1.4.2.2 misho 19021: initText(&str);
19022: appendText(&str, "x", 0);
19023: for(k=bSelftestExists; k>=0; k--){
19024: if( k==1 ){
19025: rc = sqlite3_prepare_v2(p->db,
19026: "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno",
19027: -1, &pStmt, 0);
19028: }else{
19029: rc = sqlite3_prepare_v2(p->db,
19030: "VALUES(0,'memo','Missing SELFTEST table - default checks only',''),"
19031: " (1,'run','PRAGMA integrity_check','ok')",
19032: -1, &pStmt, 0);
19033: }
1.4.2.1 misho 19034: if( rc ){
19035: raw_printf(stderr, "Error querying the selftest table\n");
19036: rc = 1;
1.4.2.2 misho 19037: sqlite3_finalize(pStmt);
1.4.2.1 misho 19038: goto meta_command_exit;
19039: }
1.4.2.2 misho 19040: for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){
19041: int tno = sqlite3_column_int(pStmt, 0);
19042: const char *zOp = (const char*)sqlite3_column_text(pStmt, 1);
19043: const char *zSql = (const char*)sqlite3_column_text(pStmt, 2);
19044: const char *zAns = (const char*)sqlite3_column_text(pStmt, 3);
19045:
19046: k = 0;
19047: if( bVerbose>0 ){
19048: char *zQuote = sqlite3_mprintf("%q", zSql);
19049: printf("%d: %s %s\n", tno, zOp, zSql);
19050: sqlite3_free(zQuote);
1.4.2.1 misho 19051: }
1.4.2.2 misho 19052: if( strcmp(zOp,"memo")==0 ){
19053: utf8_printf(p->out, "%s\n", zSql);
19054: }else
19055: if( strcmp(zOp,"run")==0 ){
19056: char *zErrMsg = 0;
19057: str.n = 0;
19058: str.z[0] = 0;
19059: rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
19060: nTest++;
19061: if( bVerbose ){
19062: utf8_printf(p->out, "Result: %s\n", str.z);
19063: }
19064: if( rc || zErrMsg ){
19065: nErr++;
19066: rc = 1;
19067: utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg);
19068: sqlite3_free(zErrMsg);
19069: }else if( strcmp(zAns,str.z)!=0 ){
19070: nErr++;
19071: rc = 1;
19072: utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
19073: utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z);
19074: }
19075: }else
19076: {
19077: utf8_printf(stderr,
19078: "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
1.4.2.1 misho 19079: rc = 1;
1.4.2.2 misho 19080: break;
1.4.2.1 misho 19081: }
1.4.2.2 misho 19082: } /* End loop over rows of content from SELFTEST */
19083: sqlite3_finalize(pStmt);
19084: } /* End loop over k */
1.4.2.1 misho 19085: freeText(&str);
19086: utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
19087: }else
19088:
1.4 misho 19089: if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
19090: if( nArg<2 || nArg>3 ){
19091: raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
19092: rc = 1;
19093: }
19094: if( nArg>=2 ){
19095: sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
19096: "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
19097: }
19098: if( nArg>=3 ){
19099: sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
19100: "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
19101: }
19102: }else
19103:
1.4.2.1 misho 19104: if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){
19105: const char *zLike = 0; /* Which table to checksum. 0 means everything */
19106: int i; /* Loop counter */
19107: int bSchema = 0; /* Also hash the schema */
19108: int bSeparate = 0; /* Hash each table separately */
19109: int iSize = 224; /* Hash algorithm to use */
19110: int bDebug = 0; /* Only show the query that would have run */
19111: sqlite3_stmt *pStmt; /* For querying tables names */
19112: char *zSql; /* SQL to be run */
19113: char *zSep; /* Separator */
19114: ShellText sSql; /* Complete SQL for the query to run the hash */
19115: ShellText sQuery; /* Set of queries used to read all content */
19116: open_db(p, 0);
19117: for(i=1; i<nArg; i++){
19118: const char *z = azArg[i];
19119: if( z[0]=='-' ){
19120: z++;
19121: if( z[0]=='-' ) z++;
19122: if( strcmp(z,"schema")==0 ){
19123: bSchema = 1;
19124: }else
1.4.2.2 misho 19125: if( strcmp(z,"sha3-224")==0 || strcmp(z,"sha3-256")==0
19126: || strcmp(z,"sha3-384")==0 || strcmp(z,"sha3-512")==0
1.4.2.1 misho 19127: ){
19128: iSize = atoi(&z[5]);
19129: }else
19130: if( strcmp(z,"debug")==0 ){
19131: bDebug = 1;
19132: }else
19133: {
19134: utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
19135: azArg[i], azArg[0]);
1.4.2.3 ! misho 19136: showHelp(p->out, azArg[0]);
1.4.2.1 misho 19137: rc = 1;
19138: goto meta_command_exit;
19139: }
19140: }else if( zLike ){
19141: raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
19142: rc = 1;
19143: goto meta_command_exit;
19144: }else{
19145: zLike = z;
19146: bSeparate = 1;
1.4.2.2 misho 19147: if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1;
1.4.2.1 misho 19148: }
19149: }
19150: if( bSchema ){
1.4.2.3 ! misho 19151: zSql = "SELECT lower(name) FROM sqlite_schema"
1.4.2.1 misho 19152: " WHERE type='table' AND coalesce(rootpage,0)>1"
1.4.2.3 ! misho 19153: " UNION ALL SELECT 'sqlite_schema'"
1.4.2.1 misho 19154: " ORDER BY 1 collate nocase";
19155: }else{
1.4.2.3 ! misho 19156: zSql = "SELECT lower(name) FROM sqlite_schema"
1.4.2.1 misho 19157: " WHERE type='table' AND coalesce(rootpage,0)>1"
19158: " AND name NOT LIKE 'sqlite_%'"
19159: " ORDER BY 1 collate nocase";
19160: }
19161: sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19162: initText(&sQuery);
19163: initText(&sSql);
19164: appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0);
19165: zSep = "VALUES(";
19166: while( SQLITE_ROW==sqlite3_step(pStmt) ){
19167: const char *zTab = (const char*)sqlite3_column_text(pStmt,0);
19168: if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue;
19169: if( strncmp(zTab, "sqlite_",7)!=0 ){
19170: appendText(&sQuery,"SELECT * FROM ", 0);
19171: appendText(&sQuery,zTab,'"');
19172: appendText(&sQuery," NOT INDEXED;", 0);
1.4.2.3 ! misho 19173: }else if( strcmp(zTab, "sqlite_schema")==0 ){
! 19174: appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_schema"
1.4.2.1 misho 19175: " ORDER BY name;", 0);
19176: }else if( strcmp(zTab, "sqlite_sequence")==0 ){
19177: appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence"
19178: " ORDER BY name;", 0);
19179: }else if( strcmp(zTab, "sqlite_stat1")==0 ){
19180: appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
19181: " ORDER BY tbl,idx;", 0);
1.4.2.3 ! misho 19182: }else if( strcmp(zTab, "sqlite_stat4")==0 ){
1.4.2.1 misho 19183: appendText(&sQuery, "SELECT * FROM ", 0);
19184: appendText(&sQuery, zTab, 0);
19185: appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
19186: }
19187: appendText(&sSql, zSep, 0);
19188: appendText(&sSql, sQuery.z, '\'');
19189: sQuery.n = 0;
19190: appendText(&sSql, ",", 0);
19191: appendText(&sSql, zTab, '\'');
19192: zSep = "),(";
19193: }
19194: sqlite3_finalize(pStmt);
19195: if( bSeparate ){
19196: zSql = sqlite3_mprintf(
19197: "%s))"
19198: " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
19199: " FROM [sha3sum$query]",
19200: sSql.z, iSize);
19201: }else{
19202: zSql = sqlite3_mprintf(
19203: "%s))"
19204: " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
19205: " FROM [sha3sum$query]",
19206: sSql.z, iSize);
19207: }
19208: freeText(&sQuery);
19209: freeText(&sSql);
19210: if( bDebug ){
19211: utf8_printf(p->out, "%s\n", zSql);
19212: }else{
1.4.2.2 misho 19213: shell_exec(p, zSql, 0);
1.4.2.1 misho 19214: }
19215: sqlite3_free(zSql);
19216: }else
19217:
1.4.2.2 misho 19218: #ifndef SQLITE_NOHAVE_SYSTEM
1.4 misho 19219: if( c=='s'
19220: && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
19221: ){
19222: char *zCmd;
19223: int i, x;
19224: if( nArg<2 ){
19225: raw_printf(stderr, "Usage: .system COMMAND\n");
19226: rc = 1;
19227: goto meta_command_exit;
19228: }
19229: zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
19230: for(i=2; i<nArg; i++){
19231: zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
19232: zCmd, azArg[i]);
19233: }
19234: x = system(zCmd);
19235: sqlite3_free(zCmd);
19236: if( x ) raw_printf(stderr, "System command returns %d\n", x);
1.2 misho 19237: }else
1.4.2.2 misho 19238: #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
1.2 misho 19239:
1.4 misho 19240: if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
1.4.2.2 misho 19241: static const char *azBool[] = { "off", "on", "trigger", "full"};
1.2 misho 19242: int i;
1.4 misho 19243: if( nArg!=1 ){
19244: raw_printf(stderr, "Usage: .show\n");
19245: rc = 1;
19246: goto meta_command_exit;
19247: }
1.4.2.1 misho 19248: utf8_printf(p->out, "%12.12s: %s\n","echo",
19249: azBool[ShellHasFlag(p, SHFLG_Echo)]);
1.4 misho 19250: utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
19251: utf8_printf(p->out, "%12.12s: %s\n","explain",
19252: p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
19253: utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
19254: utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
19255: utf8_printf(p->out, "%12.12s: ", "nullvalue");
19256: output_c_string(p->out, p->nullValue);
19257: raw_printf(p->out, "\n");
19258: utf8_printf(p->out,"%12.12s: %s\n","output",
1.2 misho 19259: strlen30(p->outfile) ? p->outfile : "stdout");
1.4 misho 19260: utf8_printf(p->out,"%12.12s: ", "colseparator");
19261: output_c_string(p->out, p->colSeparator);
19262: raw_printf(p->out, "\n");
19263: utf8_printf(p->out,"%12.12s: ", "rowseparator");
19264: output_c_string(p->out, p->rowSeparator);
19265: raw_printf(p->out, "\n");
19266: utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
19267: utf8_printf(p->out, "%12.12s: ", "width");
1.4.2.3 ! misho 19268: for (i=0;i<p->nWidth;i++) {
1.4 misho 19269: raw_printf(p->out, "%d ", p->colWidth[i]);
1.2 misho 19270: }
1.4 misho 19271: raw_printf(p->out, "\n");
1.4.2.1 misho 19272: utf8_printf(p->out, "%12.12s: %s\n", "filename",
19273: p->zDbFilename ? p->zDbFilename : "");
1.2 misho 19274: }else
19275:
1.4 misho 19276: if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
19277: if( nArg==2 ){
1.4.2.2 misho 19278: p->statsOn = (u8)booleanValue(azArg[1]);
1.4 misho 19279: }else if( nArg==1 ){
19280: display_stats(p->db, p, 0);
19281: }else{
19282: raw_printf(stderr, "Usage: .stats ?on|off?\n");
19283: rc = 1;
19284: }
1.2 misho 19285: }else
19286:
1.4.2.1 misho 19287: if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
19288: || (c=='i' && (strncmp(azArg[0], "indices", n)==0
19289: || strncmp(azArg[0], "indexes", n)==0) )
19290: ){
1.3 misho 19291: sqlite3_stmt *pStmt;
1.2 misho 19292: char **azResult;
1.3 misho 19293: int nRow, nAlloc;
19294: int ii;
1.4.2.2 misho 19295: ShellText s;
19296: initText(&s);
1.4 misho 19297: open_db(p, 0);
1.3 misho 19298: rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
1.4.2.2 misho 19299: if( rc ){
19300: sqlite3_finalize(pStmt);
19301: return shellDatabaseError(p->db);
19302: }
1.4 misho 19303:
1.4.2.2 misho 19304: if( nArg>2 && c=='i' ){
1.4.2.1 misho 19305: /* It is an historical accident that the .indexes command shows an error
19306: ** when called with the wrong number of arguments whereas the .tables
19307: ** command does not. */
19308: raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
19309: rc = 1;
1.4.2.2 misho 19310: sqlite3_finalize(pStmt);
1.4.2.1 misho 19311: goto meta_command_exit;
19312: }
1.4.2.2 misho 19313: for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
1.3 misho 19314: const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
1.4.2.2 misho 19315: if( zDbName==0 ) continue;
19316: if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
19317: if( sqlite3_stricmp(zDbName, "main")==0 ){
19318: appendText(&s, "SELECT name FROM ", 0);
19319: }else{
19320: appendText(&s, "SELECT ", 0);
19321: appendText(&s, zDbName, '\'');
19322: appendText(&s, "||'.'||name FROM ", 0);
19323: }
19324: appendText(&s, zDbName, '"');
1.4.2.3 ! misho 19325: appendText(&s, ".sqlite_schema ", 0);
1.4.2.1 misho 19326: if( c=='t' ){
1.4.2.2 misho 19327: appendText(&s," WHERE type IN ('table','view')"
19328: " AND name NOT LIKE 'sqlite_%'"
19329: " AND name LIKE ?1", 0);
1.3 misho 19330: }else{
1.4.2.2 misho 19331: appendText(&s," WHERE type='index'"
19332: " AND tbl_name LIKE ?1", 0);
1.3 misho 19333: }
19334: }
1.4 misho 19335: rc = sqlite3_finalize(pStmt);
1.4.2.2 misho 19336: appendText(&s, " ORDER BY 1", 0);
19337: rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
19338: freeText(&s);
1.4 misho 19339: if( rc ) return shellDatabaseError(p->db);
19340:
19341: /* Run the SQL statement prepared by the above block. Store the results
19342: ** as an array of nul-terminated strings in azResult[]. */
1.3 misho 19343: nRow = nAlloc = 0;
19344: azResult = 0;
19345: if( nArg>1 ){
19346: sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
1.2 misho 19347: }else{
1.3 misho 19348: sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
19349: }
19350: while( sqlite3_step(pStmt)==SQLITE_ROW ){
19351: if( nRow>=nAlloc ){
19352: char **azNew;
1.4 misho 19353: int n2 = nAlloc*2 + 10;
19354: azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
1.4.2.2 misho 19355: if( azNew==0 ) shell_out_of_memory();
1.4 misho 19356: nAlloc = n2;
1.3 misho 19357: azResult = azNew;
19358: }
19359: azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
1.4.2.2 misho 19360: if( 0==azResult[nRow] ) shell_out_of_memory();
1.4 misho 19361: nRow++;
1.2 misho 19362: }
1.4 misho 19363: if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
19364: rc = shellDatabaseError(p->db);
19365: }
19366:
19367: /* Pretty-print the contents of array azResult[] to the output */
19368: if( rc==0 && nRow>0 ){
1.2 misho 19369: int len, maxlen = 0;
19370: int i, j;
19371: int nPrintCol, nPrintRow;
1.3 misho 19372: for(i=0; i<nRow; i++){
1.2 misho 19373: len = strlen30(azResult[i]);
19374: if( len>maxlen ) maxlen = len;
19375: }
19376: nPrintCol = 80/(maxlen+2);
19377: if( nPrintCol<1 ) nPrintCol = 1;
19378: nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
19379: for(i=0; i<nPrintRow; i++){
1.3 misho 19380: for(j=i; j<nRow; j+=nPrintRow){
19381: char *zSp = j<nPrintRow ? "" : " ";
1.4 misho 19382: utf8_printf(p->out, "%s%-*s", zSp, maxlen,
19383: azResult[j] ? azResult[j]:"");
1.2 misho 19384: }
1.4 misho 19385: raw_printf(p->out, "\n");
1.2 misho 19386: }
19387: }
1.4 misho 19388:
1.3 misho 19389: for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
19390: sqlite3_free(azResult);
1.2 misho 19391: }else
19392:
1.4.2.1 misho 19393: /* Begin redirecting output to the file "testcase-out.txt" */
19394: if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
19395: output_reset(p);
1.4.2.2 misho 19396: p->out = output_file_open("testcase-out.txt", 0);
1.4.2.1 misho 19397: if( p->out==0 ){
19398: raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
19399: }
19400: if( nArg>=2 ){
19401: sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
19402: }else{
19403: sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
19404: }
19405: }else
19406:
19407: #ifndef SQLITE_UNTESTABLE
1.4.2.2 misho 19408: if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
1.2 misho 19409: static const struct {
19410: const char *zCtrlName; /* Name of a test-control option */
19411: int ctrlCode; /* Integer code for that option */
1.4.2.2 misho 19412: const char *zUsage; /* Usage notes */
1.2 misho 19413: } aCtrl[] = {
1.4.2.3 ! misho 19414: { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
! 19415: { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
! 19416: /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
! 19417: /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
! 19418: { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
! 19419: { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
! 19420: /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/
! 19421: { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
! 19422: { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "" },
! 19423: { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
! 19424: { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
! 19425: { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
1.4.2.2 misho 19426: #ifdef YYCOVERAGE
1.4.2.3 ! misho 19427: { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
1.4.2.2 misho 19428: #endif
1.4.2.3 ! misho 19429: { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
! 19430: { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
! 19431: { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
! 19432: { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
1.2 misho 19433: };
19434: int testctrl = -1;
1.4.2.2 misho 19435: int iCtrl = -1;
19436: int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */
19437: int isOk = 0;
1.4 misho 19438: int i, n2;
1.4.2.2 misho 19439: const char *zCmd = 0;
19440:
1.4 misho 19441: open_db(p, 0);
1.4.2.2 misho 19442: zCmd = nArg>=2 ? azArg[1] : "help";
19443:
19444: /* The argument can optionally begin with "-" or "--" */
19445: if( zCmd[0]=='-' && zCmd[1] ){
19446: zCmd++;
19447: if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
19448: }
19449:
19450: /* --help lists all test-controls */
19451: if( strcmp(zCmd,"help")==0 ){
19452: utf8_printf(p->out, "Available test-controls:\n");
19453: for(i=0; i<ArraySize(aCtrl); i++){
19454: utf8_printf(p->out, " .testctrl %s %s\n",
19455: aCtrl[i].zCtrlName, aCtrl[i].zUsage);
19456: }
19457: rc = 1;
19458: goto meta_command_exit;
19459: }
1.2 misho 19460:
19461: /* convert testctrl text option to value. allow any unique prefix
19462: ** of the option name, or a numerical value. */
1.4.2.2 misho 19463: n2 = strlen30(zCmd);
1.4 misho 19464: for(i=0; i<ArraySize(aCtrl); i++){
1.4.2.2 misho 19465: if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
1.2 misho 19466: if( testctrl<0 ){
19467: testctrl = aCtrl[i].ctrlCode;
1.4.2.2 misho 19468: iCtrl = i;
1.2 misho 19469: }else{
1.4.2.2 misho 19470: utf8_printf(stderr, "Error: ambiguous test-control: \"%s\"\n"
19471: "Use \".testctrl --help\" for help\n", zCmd);
19472: rc = 1;
19473: goto meta_command_exit;
1.2 misho 19474: }
19475: }
19476: }
1.4.2.2 misho 19477: if( testctrl<0 ){
19478: utf8_printf(stderr,"Error: unknown test-control: %s\n"
19479: "Use \".testctrl --help\" for help\n", zCmd);
1.2 misho 19480: }else{
19481: switch(testctrl){
19482:
19483: /* sqlite3_test_control(int, db, int) */
19484: case SQLITE_TESTCTRL_OPTIMIZATIONS:
19485: if( nArg==3 ){
1.4 misho 19486: int opt = (int)strtol(azArg[2], 0, 0);
19487: rc2 = sqlite3_test_control(testctrl, p->db, opt);
1.4.2.2 misho 19488: isOk = 3;
1.2 misho 19489: }
19490: break;
19491:
19492: /* sqlite3_test_control(int) */
1.4 misho 19493: case SQLITE_TESTCTRL_PRNG_SAVE:
19494: case SQLITE_TESTCTRL_PRNG_RESTORE:
1.2 misho 19495: case SQLITE_TESTCTRL_PRNG_RESET:
1.4 misho 19496: case SQLITE_TESTCTRL_BYTEORDER:
1.2 misho 19497: if( nArg==2 ){
1.4 misho 19498: rc2 = sqlite3_test_control(testctrl);
1.4.2.2 misho 19499: isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3;
1.2 misho 19500: }
19501: break;
19502:
19503: /* sqlite3_test_control(int, uint) */
1.4 misho 19504: case SQLITE_TESTCTRL_PENDING_BYTE:
1.2 misho 19505: if( nArg==3 ){
1.4 misho 19506: unsigned int opt = (unsigned int)integerValue(azArg[2]);
19507: rc2 = sqlite3_test_control(testctrl, opt);
1.4.2.2 misho 19508: isOk = 3;
1.2 misho 19509: }
19510: break;
1.4 misho 19511:
1.4.2.3 ! misho 19512: /* sqlite3_test_control(int, int, sqlite3*) */
! 19513: case SQLITE_TESTCTRL_PRNG_SEED:
! 19514: if( nArg==3 || nArg==4 ){
! 19515: int ii = (int)integerValue(azArg[2]);
! 19516: sqlite3 *db;
! 19517: if( ii==0 && strcmp(azArg[2],"random")==0 ){
! 19518: sqlite3_randomness(sizeof(ii),&ii);
! 19519: printf("-- random seed: %d\n", ii);
! 19520: }
! 19521: if( nArg==3 ){
! 19522: db = 0;
! 19523: }else{
! 19524: db = p->db;
! 19525: /* Make sure the schema has been loaded */
! 19526: sqlite3_table_column_metadata(db, 0, "x", 0, 0, 0, 0, 0, 0);
! 19527: }
! 19528: rc2 = sqlite3_test_control(testctrl, ii, db);
! 19529: isOk = 3;
! 19530: }
! 19531: break;
! 19532:
1.2 misho 19533: /* sqlite3_test_control(int, int) */
1.4 misho 19534: case SQLITE_TESTCTRL_ASSERT:
19535: case SQLITE_TESTCTRL_ALWAYS:
1.2 misho 19536: if( nArg==3 ){
1.4 misho 19537: int opt = booleanValue(azArg[2]);
19538: rc2 = sqlite3_test_control(testctrl, opt);
1.4.2.2 misho 19539: isOk = 1;
1.2 misho 19540: }
19541: break;
19542:
1.4.2.2 misho 19543: /* sqlite3_test_control(int, int) */
19544: case SQLITE_TESTCTRL_LOCALTIME_FAULT:
19545: case SQLITE_TESTCTRL_NEVER_CORRUPT:
1.2 misho 19546: if( nArg==3 ){
1.4.2.2 misho 19547: int opt = booleanValue(azArg[2]);
1.4 misho 19548: rc2 = sqlite3_test_control(testctrl, opt);
1.4.2.2 misho 19549: isOk = 3;
1.2 misho 19550: }
19551: break;
19552:
1.4.2.3 ! misho 19553: /* sqlite3_test_control(sqlite3*) */
! 19554: case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
! 19555: rc2 = sqlite3_test_control(testctrl, p->db);
! 19556: isOk = 3;
! 19557: break;
! 19558:
1.4 misho 19559: case SQLITE_TESTCTRL_IMPOSTER:
19560: if( nArg==5 ){
19561: rc2 = sqlite3_test_control(testctrl, p->db,
19562: azArg[2],
19563: integerValue(azArg[3]),
19564: integerValue(azArg[4]));
1.4.2.2 misho 19565: isOk = 3;
1.4 misho 19566: }
19567: break;
19568:
1.4.2.2 misho 19569: #ifdef YYCOVERAGE
19570: case SQLITE_TESTCTRL_PARSER_COVERAGE:
19571: if( nArg==2 ){
19572: sqlite3_test_control(testctrl, p->out);
19573: isOk = 3;
19574: }
19575: #endif
1.2 misho 19576: }
19577: }
1.4.2.2 misho 19578: if( isOk==0 && iCtrl>=0 ){
1.4.2.3 ! misho 19579: utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
1.4.2.2 misho 19580: rc = 1;
19581: }else if( isOk==1 ){
19582: raw_printf(p->out, "%d\n", rc2);
19583: }else if( isOk==2 ){
19584: raw_printf(p->out, "0x%08x\n", rc2);
19585: }
1.2 misho 19586: }else
1.4.2.1 misho 19587: #endif /* !defined(SQLITE_UNTESTABLE) */
1.2 misho 19588:
1.4 misho 19589: if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
19590: open_db(p, 0);
19591: sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
19592: }else
19593:
19594: if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
19595: if( nArg==2 ){
19596: enableTimer = booleanValue(azArg[1]);
19597: if( enableTimer && !HAS_TIMER ){
19598: raw_printf(stderr, "Error: timer not available on this system.\n");
19599: enableTimer = 0;
19600: }
19601: }else{
19602: raw_printf(stderr, "Usage: .timer on|off\n");
19603: rc = 1;
19604: }
1.2 misho 19605: }else
1.4 misho 19606:
1.4.2.2 misho 19607: #ifndef SQLITE_OMIT_TRACE
1.4 misho 19608: if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
1.4.2.2 misho 19609: int mType = 0;
19610: int jj;
1.4 misho 19611: open_db(p, 0);
1.4.2.2 misho 19612: for(jj=1; jj<nArg; jj++){
19613: const char *z = azArg[jj];
19614: if( z[0]=='-' ){
19615: if( optionMatch(z, "expanded") ){
19616: p->eTraceType = SHELL_TRACE_EXPANDED;
19617: }
19618: #ifdef SQLITE_ENABLE_NORMALIZE
19619: else if( optionMatch(z, "normalized") ){
19620: p->eTraceType = SHELL_TRACE_NORMALIZED;
19621: }
19622: #endif
19623: else if( optionMatch(z, "plain") ){
19624: p->eTraceType = SHELL_TRACE_PLAIN;
19625: }
19626: else if( optionMatch(z, "profile") ){
19627: mType |= SQLITE_TRACE_PROFILE;
19628: }
19629: else if( optionMatch(z, "row") ){
19630: mType |= SQLITE_TRACE_ROW;
19631: }
19632: else if( optionMatch(z, "stmt") ){
19633: mType |= SQLITE_TRACE_STMT;
19634: }
19635: else if( optionMatch(z, "close") ){
19636: mType |= SQLITE_TRACE_CLOSE;
19637: }
19638: else {
19639: raw_printf(stderr, "Unknown option \"%s\" on \".trace\"\n", z);
19640: rc = 1;
19641: goto meta_command_exit;
19642: }
19643: }else{
19644: output_file_close(p->traceOut);
19645: p->traceOut = output_file_open(azArg[1], 0);
19646: }
1.4 misho 19647: }
1.3 misho 19648: if( p->traceOut==0 ){
1.4 misho 19649: sqlite3_trace_v2(p->db, 0, 0, 0);
1.3 misho 19650: }else{
1.4.2.2 misho 19651: if( mType==0 ) mType = SQLITE_TRACE_STMT;
19652: sqlite3_trace_v2(p->db, mType, sql_trace_callback, p);
1.3 misho 19653: }
19654: }else
1.4.2.2 misho 19655: #endif /* !defined(SQLITE_OMIT_TRACE) */
1.3 misho 19656:
1.4.2.3 ! misho 19657: #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
! 19658: if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
! 19659: int ii;
! 19660: int lenOpt;
! 19661: char *zOpt;
! 19662: if( nArg<2 ){
! 19663: raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
! 19664: rc = 1;
! 19665: goto meta_command_exit;
! 19666: }
! 19667: open_db(p, 0);
! 19668: zOpt = azArg[1];
! 19669: if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
! 19670: lenOpt = (int)strlen(zOpt);
! 19671: if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
! 19672: assert( azArg[nArg]==0 );
! 19673: sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
! 19674: }else{
! 19675: for(ii=1; ii<nArg; ii++){
! 19676: sqlite3_create_module(p->db, azArg[ii], 0, 0);
! 19677: }
! 19678: }
! 19679: }else
! 19680: #endif
! 19681:
1.4 misho 19682: #if SQLITE_USER_AUTHENTICATION
19683: if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
19684: if( nArg<2 ){
19685: raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
19686: rc = 1;
19687: goto meta_command_exit;
19688: }
19689: open_db(p, 0);
19690: if( strcmp(azArg[1],"login")==0 ){
19691: if( nArg!=4 ){
19692: raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
19693: rc = 1;
19694: goto meta_command_exit;
19695: }
1.4.2.3 ! misho 19696: rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
! 19697: strlen30(azArg[3]));
1.4 misho 19698: if( rc ){
19699: utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
19700: rc = 1;
19701: }
19702: }else if( strcmp(azArg[1],"add")==0 ){
19703: if( nArg!=5 ){
19704: raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
19705: rc = 1;
19706: goto meta_command_exit;
19707: }
1.4.2.2 misho 19708: rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
1.4 misho 19709: booleanValue(azArg[4]));
19710: if( rc ){
19711: raw_printf(stderr, "User-Add failed: %d\n", rc);
19712: rc = 1;
19713: }
19714: }else if( strcmp(azArg[1],"edit")==0 ){
19715: if( nArg!=5 ){
19716: raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
19717: rc = 1;
19718: goto meta_command_exit;
19719: }
1.4.2.2 misho 19720: rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
1.4 misho 19721: booleanValue(azArg[4]));
19722: if( rc ){
19723: raw_printf(stderr, "User-Edit failed: %d\n", rc);
19724: rc = 1;
19725: }
19726: }else if( strcmp(azArg[1],"delete")==0 ){
19727: if( nArg!=3 ){
19728: raw_printf(stderr, "Usage: .user delete USER\n");
19729: rc = 1;
19730: goto meta_command_exit;
19731: }
19732: rc = sqlite3_user_delete(p->db, azArg[2]);
19733: if( rc ){
19734: raw_printf(stderr, "User-Delete failed: %d\n", rc);
19735: rc = 1;
19736: }
19737: }else{
19738: raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
19739: rc = 1;
19740: goto meta_command_exit;
19741: }
19742: }else
19743: #endif /* SQLITE_USER_AUTHENTICATION */
19744:
1.2 misho 19745: if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
1.4 misho 19746: utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
1.2 misho 19747: sqlite3_libversion(), sqlite3_sourceid());
1.4.2.2 misho 19748: #if SQLITE_HAVE_ZLIB
19749: utf8_printf(p->out, "zlib version %s\n", zlibVersion());
19750: #endif
19751: #define CTIMEOPT_VAL_(opt) #opt
19752: #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
19753: #if defined(__clang__) && defined(__clang_major__)
19754: utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
19755: CTIMEOPT_VAL(__clang_minor__) "."
19756: CTIMEOPT_VAL(__clang_patchlevel__) "\n");
19757: #elif defined(_MSC_VER)
19758: utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n");
19759: #elif defined(__GNUC__) && defined(__VERSION__)
19760: utf8_printf(p->out, "gcc-" __VERSION__ "\n");
19761: #endif
1.2 misho 19762: }else
19763:
1.4 misho 19764: if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
19765: const char *zDbName = nArg==2 ? azArg[1] : "main";
1.4.2.1 misho 19766: sqlite3_vfs *pVfs = 0;
1.4 misho 19767: if( p->db ){
19768: sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
19769: if( pVfs ){
19770: utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
19771: raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
19772: raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
19773: raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
19774: }
19775: }
19776: }else
19777:
19778: if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
19779: sqlite3_vfs *pVfs;
19780: sqlite3_vfs *pCurrent = 0;
19781: if( p->db ){
19782: sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
19783: }
19784: for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
19785: utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
19786: pVfs==pCurrent ? " <--- CURRENT" : "");
19787: raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
19788: raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
19789: raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
19790: if( pVfs->pNext ){
19791: raw_printf(p->out, "-----------------------------------\n");
19792: }
19793: }
19794: }else
19795:
1.2 misho 19796: if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
19797: const char *zDbName = nArg==2 ? azArg[1] : "main";
19798: char *zVfsName = 0;
19799: if( p->db ){
19800: sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
19801: if( zVfsName ){
1.4 misho 19802: utf8_printf(p->out, "%s\n", zVfsName);
1.2 misho 19803: sqlite3_free(zVfsName);
19804: }
19805: }
19806: }else
19807:
1.3 misho 19808: #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
19809: if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
1.4 misho 19810: sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
1.3 misho 19811: }else
19812: #endif
19813:
1.4 misho 19814: if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
1.2 misho 19815: int j;
19816: assert( nArg<=ArraySize(azArg) );
1.4.2.3 ! misho 19817: p->nWidth = nArg-1;
! 19818: p->colWidth = realloc(p->colWidth, p->nWidth*sizeof(int)*2);
! 19819: if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
! 19820: if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
! 19821: for(j=1; j<nArg; j++){
1.4 misho 19822: p->colWidth[j-1] = (int)integerValue(azArg[j]);
1.2 misho 19823: }
19824: }else
19825:
19826: {
1.4 misho 19827: utf8_printf(stderr, "Error: unknown command or invalid arguments: "
1.2 misho 19828: " \"%s\". Enter \".help\" for help\n", azArg[0]);
19829: rc = 1;
19830: }
19831:
1.4 misho 19832: meta_command_exit:
19833: if( p->outCount ){
19834: p->outCount--;
19835: if( p->outCount==0 ) output_reset(p);
19836: }
1.2 misho 19837: return rc;
19838: }
19839:
19840: /*
19841: ** Return TRUE if a semicolon occurs anywhere in the first N characters
19842: ** of string z[].
19843: */
1.4 misho 19844: static int line_contains_semicolon(const char *z, int N){
1.2 misho 19845: int i;
19846: for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
19847: return 0;
19848: }
19849:
19850: /*
19851: ** Test to see if a line consists entirely of whitespace.
19852: */
19853: static int _all_whitespace(const char *z){
19854: for(; *z; z++){
19855: if( IsSpace(z[0]) ) continue;
19856: if( *z=='/' && z[1]=='*' ){
19857: z += 2;
19858: while( *z && (*z!='*' || z[1]!='/') ){ z++; }
19859: if( *z==0 ) return 0;
19860: z++;
19861: continue;
19862: }
19863: if( *z=='-' && z[1]=='-' ){
19864: z += 2;
19865: while( *z && *z!='\n' ){ z++; }
19866: if( *z==0 ) return 1;
19867: continue;
19868: }
19869: return 0;
19870: }
19871: return 1;
19872: }
19873:
19874: /*
19875: ** Return TRUE if the line typed in is an SQL command terminator other
19876: ** than a semi-colon. The SQL Server style "go" command is understood
19877: ** as is the Oracle "/".
19878: */
1.4 misho 19879: static int line_is_command_terminator(const char *zLine){
1.2 misho 19880: while( IsSpace(zLine[0]) ){ zLine++; };
19881: if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
19882: return 1; /* Oracle */
19883: }
19884: if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
19885: && _all_whitespace(&zLine[2]) ){
19886: return 1; /* SQL Server */
19887: }
19888: return 0;
19889: }
19890:
19891: /*
1.4.2.2 misho 19892: ** We need a default sqlite3_complete() implementation to use in case
19893: ** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
19894: ** any arbitrary text is a complete SQL statement. This is not very
19895: ** user-friendly, but it does seem to work.
19896: */
19897: #ifdef SQLITE_OMIT_COMPLETE
19898: #define sqlite3_complete(x) 1
19899: #endif
19900:
19901: /*
1.2 misho 19902: ** Return true if zSql is a complete SQL statement. Return false if it
19903: ** ends in the middle of a string literal or C-style comment.
19904: */
1.4 misho 19905: static int line_is_complete(char *zSql, int nSql){
1.2 misho 19906: int rc;
19907: if( zSql==0 ) return 1;
19908: zSql[nSql] = ';';
19909: zSql[nSql+1] = 0;
19910: rc = sqlite3_complete(zSql);
19911: zSql[nSql] = 0;
19912: return rc;
19913: }
19914:
19915: /*
1.4.2.2 misho 19916: ** Run a single line of SQL. Return the number of errors.
1.4.2.1 misho 19917: */
19918: static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
19919: int rc;
19920: char *zErrMsg = 0;
19921:
19922: open_db(p, 0);
19923: if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
1.4.2.2 misho 19924: if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
1.4.2.1 misho 19925: BEGIN_TIMER;
1.4.2.2 misho 19926: rc = shell_exec(p, zSql, &zErrMsg);
1.4.2.1 misho 19927: END_TIMER;
19928: if( rc || zErrMsg ){
19929: char zPrefix[100];
19930: if( in!=0 || !stdin_is_interactive ){
19931: sqlite3_snprintf(sizeof(zPrefix), zPrefix,
19932: "Error: near line %d:", startline);
19933: }else{
19934: sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
19935: }
19936: if( zErrMsg!=0 ){
19937: utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
19938: sqlite3_free(zErrMsg);
19939: zErrMsg = 0;
19940: }else{
19941: utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
19942: }
19943: return 1;
19944: }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
19945: raw_printf(p->out, "changes: %3d total_changes: %d\n",
19946: sqlite3_changes(p->db), sqlite3_total_changes(p->db));
19947: }
19948: return 0;
19949: }
19950:
19951:
19952: /*
1.2 misho 19953: ** Read input from *in and process it. If *in==0 then input
19954: ** is interactive - the user is typing it it. Otherwise, input
19955: ** is coming from a file or device. A prompt is issued and history
19956: ** is saved only if input is interactive. An interrupt signal will
19957: ** cause this routine to exit immediately, unless input is interactive.
19958: **
19959: ** Return the number of errors.
19960: */
1.4.2.2 misho 19961: static int process_input(ShellState *p){
1.4 misho 19962: char *zLine = 0; /* A single input line */
19963: char *zSql = 0; /* Accumulated SQL text */
19964: int nLine; /* Length of current line */
19965: int nSql = 0; /* Bytes of zSql[] used */
19966: int nAlloc = 0; /* Allocated zSql[] space */
19967: int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
19968: int rc; /* Error code */
19969: int errCnt = 0; /* Number of errors seen */
19970: int startline = 0; /* Line number for start of current input */
1.2 misho 19971:
1.4.2.2 misho 19972: p->lineno = 0;
19973: while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
1.2 misho 19974: fflush(p->out);
1.4.2.2 misho 19975: zLine = one_input_line(p->in, zLine, nSql>0);
1.2 misho 19976: if( zLine==0 ){
1.3 misho 19977: /* End of input */
1.4.2.2 misho 19978: if( p->in==0 && stdin_is_interactive ) printf("\n");
1.3 misho 19979: break;
1.2 misho 19980: }
19981: if( seenInterrupt ){
1.4.2.2 misho 19982: if( p->in!=0 ) break;
1.2 misho 19983: seenInterrupt = 0;
19984: }
1.4.2.2 misho 19985: p->lineno++;
1.4 misho 19986: if( nSql==0 && _all_whitespace(zLine) ){
1.4.2.1 misho 19987: if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
1.4 misho 19988: continue;
19989: }
1.4.2.2 misho 19990: if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
1.4.2.1 misho 19991: if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
1.4.2.2 misho 19992: if( zLine[0]=='.' ){
19993: rc = do_meta_command(zLine, p);
19994: if( rc==2 ){ /* exit requested */
19995: break;
19996: }else if( rc ){
19997: errCnt++;
19998: }
1.2 misho 19999: }
20000: continue;
20001: }
1.4 misho 20002: if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
1.2 misho 20003: memcpy(zLine,";",2);
20004: }
1.4 misho 20005: nLine = strlen30(zLine);
20006: if( nSql+nLine+2>=nAlloc ){
20007: nAlloc = nSql+nLine+100;
20008: zSql = realloc(zSql, nAlloc);
1.4.2.2 misho 20009: if( zSql==0 ) shell_out_of_memory();
1.4 misho 20010: }
1.2 misho 20011: nSqlPrior = nSql;
1.4 misho 20012: if( nSql==0 ){
1.2 misho 20013: int i;
20014: for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
1.4 misho 20015: assert( nAlloc>0 && zSql!=0 );
20016: memcpy(zSql, zLine+i, nLine+1-i);
1.4.2.2 misho 20017: startline = p->lineno;
1.4 misho 20018: nSql = nLine-i;
1.2 misho 20019: }else{
20020: zSql[nSql++] = '\n';
1.4 misho 20021: memcpy(zSql+nSql, zLine, nLine+1);
20022: nSql += nLine;
1.2 misho 20023: }
1.4 misho 20024: if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
1.2 misho 20025: && sqlite3_complete(zSql) ){
1.4.2.2 misho 20026: errCnt += runOneSqlLine(p, zSql, p->in, startline);
1.4 misho 20027: nSql = 0;
20028: if( p->outCount ){
20029: output_reset(p);
20030: p->outCount = 0;
1.4.2.2 misho 20031: }else{
20032: clearTempFile(p);
1.4 misho 20033: }
20034: }else if( nSql && _all_whitespace(zSql) ){
1.4.2.1 misho 20035: if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
1.2 misho 20036: nSql = 0;
20037: }
20038: }
1.4.2.1 misho 20039: if( nSql && !_all_whitespace(zSql) ){
1.4.2.2 misho 20040: errCnt += runOneSqlLine(p, zSql, p->in, startline);
1.2 misho 20041: }
1.4 misho 20042: free(zSql);
1.2 misho 20043: free(zLine);
1.3 misho 20044: return errCnt>0;
1.2 misho 20045: }
20046:
20047: /*
20048: ** Return a pathname which is the user's home directory. A
1.3 misho 20049: ** 0 return indicates an error of some kind.
1.2 misho 20050: */
1.4.2.1 misho 20051: static char *find_home_dir(int clearFlag){
1.3 misho 20052: static char *home_dir = NULL;
1.4.2.1 misho 20053: if( clearFlag ){
20054: free(home_dir);
20055: home_dir = 0;
20056: return 0;
20057: }
1.3 misho 20058: if( home_dir ) return home_dir;
1.2 misho 20059:
1.4 misho 20060: #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
20061: && !defined(__RTP__) && !defined(_WRS_KERNEL)
1.3 misho 20062: {
20063: struct passwd *pwent;
20064: uid_t uid = getuid();
20065: if( (pwent=getpwuid(uid)) != NULL) {
20066: home_dir = pwent->pw_dir;
20067: }
1.2 misho 20068: }
20069: #endif
20070:
20071: #if defined(_WIN32_WCE)
20072: /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
20073: */
1.3 misho 20074: home_dir = "/";
1.2 misho 20075: #else
20076:
1.3 misho 20077: #if defined(_WIN32) || defined(WIN32)
1.2 misho 20078: if (!home_dir) {
20079: home_dir = getenv("USERPROFILE");
20080: }
20081: #endif
20082:
20083: if (!home_dir) {
20084: home_dir = getenv("HOME");
20085: }
20086:
1.3 misho 20087: #if defined(_WIN32) || defined(WIN32)
1.2 misho 20088: if (!home_dir) {
20089: char *zDrive, *zPath;
20090: int n;
20091: zDrive = getenv("HOMEDRIVE");
20092: zPath = getenv("HOMEPATH");
20093: if( zDrive && zPath ){
20094: n = strlen30(zDrive) + strlen30(zPath) + 1;
20095: home_dir = malloc( n );
20096: if( home_dir==0 ) return 0;
20097: sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
20098: return home_dir;
20099: }
20100: home_dir = "c:\\";
20101: }
20102: #endif
20103:
20104: #endif /* !_WIN32_WCE */
20105:
20106: if( home_dir ){
20107: int n = strlen30(home_dir) + 1;
20108: char *z = malloc( n );
20109: if( z ) memcpy(z, home_dir, n);
20110: home_dir = z;
20111: }
20112:
20113: return home_dir;
20114: }
20115:
20116: /*
20117: ** Read input from the file given by sqliterc_override. Or if that
20118: ** parameter is NULL, take input from ~/.sqliterc
20119: **
20120: ** Returns the number of errors.
20121: */
1.4 misho 20122: static void process_sqliterc(
20123: ShellState *p, /* Configuration data */
1.2 misho 20124: const char *sqliterc_override /* Name of config file. NULL to use default */
20125: ){
20126: char *home_dir = NULL;
20127: const char *sqliterc = sqliterc_override;
20128: char *zBuf = 0;
1.4.2.2 misho 20129: FILE *inSaved = p->in;
20130: int savedLineno = p->lineno;
1.2 misho 20131:
20132: if (sqliterc == NULL) {
1.4.2.1 misho 20133: home_dir = find_home_dir(0);
1.2 misho 20134: if( home_dir==0 ){
1.4 misho 20135: raw_printf(stderr, "-- warning: cannot find home directory;"
20136: " cannot read ~/.sqliterc\n");
20137: return;
1.2 misho 20138: }
1.3 misho 20139: zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
20140: sqliterc = zBuf;
1.2 misho 20141: }
1.4.2.2 misho 20142: p->in = fopen(sqliterc,"rb");
20143: if( p->in ){
1.2 misho 20144: if( stdin_is_interactive ){
1.4 misho 20145: utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
1.2 misho 20146: }
1.4.2.2 misho 20147: process_input(p);
20148: fclose(p->in);
1.2 misho 20149: }
1.4.2.2 misho 20150: p->in = inSaved;
20151: p->lineno = savedLineno;
1.3 misho 20152: sqlite3_free(zBuf);
1.2 misho 20153: }
20154:
20155: /*
20156: ** Show available command line options
20157: */
1.4 misho 20158: static const char zOptions[] =
1.4.2.2 misho 20159: #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
20160: " -A ARGS... run \".archive ARGS\" and exit\n"
20161: #endif
20162: " -append append the database to the end of the file\n"
1.4 misho 20163: " -ascii set output mode to 'ascii'\n"
1.2 misho 20164: " -bail stop after hitting an error\n"
20165: " -batch force batch I/O\n"
1.4.2.3 ! misho 20166: " -box set output mode to 'box'\n"
1.2 misho 20167: " -column set output mode to 'column'\n"
1.3 misho 20168: " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
1.2 misho 20169: " -csv set output mode to 'csv'\n"
1.4.2.2 misho 20170: #if defined(SQLITE_ENABLE_DESERIALIZE)
20171: " -deserialize open the database using sqlite3_deserialize()\n"
20172: #endif
1.3 misho 20173: " -echo print commands before execution\n"
20174: " -init FILENAME read/process named file\n"
20175: " -[no]header turn headers on or off\n"
20176: #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
20177: " -heap SIZE Size of heap for memsys3 or memsys5\n"
20178: #endif
20179: " -help show this message\n"
1.2 misho 20180: " -html set output mode to HTML\n"
1.3 misho 20181: " -interactive force interactive I/O\n"
1.4.2.3 ! misho 20182: " -json set output mode to 'json'\n"
1.2 misho 20183: " -line set output mode to 'line'\n"
20184: " -list set output mode to 'list'\n"
1.4 misho 20185: " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
1.4.2.3 ! misho 20186: " -markdown set output mode to 'markdown'\n"
1.4.2.2 misho 20187: #if defined(SQLITE_ENABLE_DESERIALIZE)
20188: " -maxsize N maximum size for a --deserialize database\n"
20189: #endif
20190: " -memtrace trace all memory allocations and deallocations\n"
1.4 misho 20191: " -mmap N default mmap size set to N\n"
1.3 misho 20192: #ifdef SQLITE_ENABLE_MULTIPLEX
20193: " -multiplex enable the multiplexor VFS\n"
20194: #endif
1.4 misho 20195: " -newline SEP set output row separator. Default: '\\n'\n"
1.4.2.3 ! misho 20196: " -nofollow refuse to open symbolic links to database files\n"
1.3 misho 20197: " -nullvalue TEXT set text string for NULL values. Default ''\n"
1.4 misho 20198: " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
1.4.2.2 misho 20199: " -quote set output mode to 'quote'\n"
20200: " -readonly open the database read-only\n"
1.4 misho 20201: " -separator SEP set output column separator. Default: '|'\n"
1.4.2.2 misho 20202: #ifdef SQLITE_ENABLE_SORTER_REFERENCES
20203: " -sorterref SIZE sorter references threshold size\n"
20204: #endif
1.2 misho 20205: " -stats print memory stats before each finalize\n"
1.4.2.3 ! misho 20206: " -table set output mode to 'table'\n"
1.2 misho 20207: " -version show SQLite version\n"
20208: " -vfs NAME use NAME as the default VFS\n"
20209: #ifdef SQLITE_ENABLE_VFSTRACE
20210: " -vfstrace enable tracing of all VFS calls\n"
20211: #endif
1.4.2.2 misho 20212: #ifdef SQLITE_HAVE_ZLIB
20213: " -zip open the file as a ZIP Archive\n"
20214: #endif
1.2 misho 20215: ;
20216: static void usage(int showDetail){
1.4 misho 20217: utf8_printf(stderr,
20218: "Usage: %s [OPTIONS] FILENAME [SQL]\n"
1.2 misho 20219: "FILENAME is the name of an SQLite database. A new database is created\n"
20220: "if the file does not previously exist.\n", Argv0);
20221: if( showDetail ){
1.4 misho 20222: utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
1.2 misho 20223: }else{
1.4 misho 20224: raw_printf(stderr, "Use the -help option for additional information\n");
1.2 misho 20225: }
20226: exit(1);
20227: }
20228:
20229: /*
1.4.2.2 misho 20230: ** Internal check: Verify that the SQLite is uninitialized. Print a
20231: ** error message if it is initialized.
20232: */
20233: static void verify_uninitialized(void){
20234: if( sqlite3_config(-1)==SQLITE_MISUSE ){
20235: utf8_printf(stdout, "WARNING: attempt to configure SQLite after"
20236: " initialization.\n");
20237: }
20238: }
20239:
20240: /*
1.2 misho 20241: ** Initialize the state information in data
20242: */
1.4 misho 20243: static void main_init(ShellState *data) {
1.2 misho 20244: memset(data, 0, sizeof(*data));
1.4 misho 20245: data->normalMode = data->cMode = data->mode = MODE_List;
20246: data->autoExplain = 1;
20247: memcpy(data->colSeparator,SEP_Column, 2);
20248: memcpy(data->rowSeparator,SEP_Row, 2);
1.2 misho 20249: data->showHeader = 0;
1.4 misho 20250: data->shellFlgs = SHFLG_Lookaside;
1.4.2.2 misho 20251: verify_uninitialized();
1.2 misho 20252: sqlite3_config(SQLITE_CONFIG_URI, 1);
20253: sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
1.4 misho 20254: sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
1.2 misho 20255: sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
20256: sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
20257: }
20258:
1.3 misho 20259: /*
1.4 misho 20260: ** Output text to the console in a font that attracts extra attention.
20261: */
20262: #ifdef _WIN32
20263: static void printBold(const char *zText){
1.4.2.3 ! misho 20264: #if !SQLITE_OS_WINRT
1.4 misho 20265: HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
20266: CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
20267: GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
20268: SetConsoleTextAttribute(out,
20269: FOREGROUND_RED|FOREGROUND_INTENSITY
20270: );
1.4.2.3 ! misho 20271: #endif
1.4 misho 20272: printf("%s", zText);
1.4.2.3 ! misho 20273: #if !SQLITE_OS_WINRT
1.4 misho 20274: SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
1.4.2.3 ! misho 20275: #endif
1.4 misho 20276: }
20277: #else
20278: static void printBold(const char *zText){
20279: printf("\033[1m%s\033[0m", zText);
20280: }
20281: #endif
20282:
20283: /*
1.3 misho 20284: ** Get the argument to an --option. Throw an error and die if no argument
20285: ** is available.
20286: */
20287: static char *cmdline_option_value(int argc, char **argv, int i){
20288: if( i==argc ){
1.4 misho 20289: utf8_printf(stderr, "%s: Error: missing argument to %s\n",
1.3 misho 20290: argv[0], argv[argc-1]);
20291: exit(1);
20292: }
20293: return argv[i];
20294: }
20295:
1.4 misho 20296: #ifndef SQLITE_SHELL_IS_UTF8
20297: # if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
20298: # define SQLITE_SHELL_IS_UTF8 (0)
20299: # else
20300: # define SQLITE_SHELL_IS_UTF8 (1)
20301: # endif
20302: #endif
20303:
20304: #if SQLITE_SHELL_IS_UTF8
20305: int SQLITE_CDECL main(int argc, char **argv){
20306: #else
20307: int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
20308: char **argv;
20309: #endif
1.2 misho 20310: char *zErrMsg = 0;
1.4 misho 20311: ShellState data;
1.2 misho 20312: const char *zInitFile = 0;
20313: int i;
20314: int rc = 0;
1.4 misho 20315: int warnInmemoryDb = 0;
20316: int readStdin = 1;
20317: int nCmd = 0;
20318: char **azCmd = 0;
1.4.2.2 misho 20319: const char *zVfs = 0; /* Value of -vfs command-line option */
20320: #if !SQLITE_SHELL_IS_UTF8
20321: char **argvToFree = 0;
20322: int argcToFree = 0;
20323: #endif
1.4 misho 20324:
20325: setBinaryMode(stdin, 0);
20326: setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
20327: stdin_is_interactive = isatty(0);
20328: stdout_is_console = isatty(1);
1.2 misho 20329:
1.4.2.3 ! misho 20330: #ifdef SQLITE_DEBUG
! 20331: registerOomSimulator();
! 20332: #endif
! 20333:
1.4.2.2 misho 20334: #if !defined(_WIN32_WCE)
20335: if( getenv("SQLITE_DEBUG_BREAK") ){
20336: if( isatty(0) && isatty(2) ){
20337: fprintf(stderr,
20338: "attach debugger to process %d and press any key to continue.\n",
20339: GETPID());
20340: fgetc(stdin);
20341: }else{
20342: #if defined(_WIN32) || defined(WIN32)
1.4.2.3 ! misho 20343: #if SQLITE_OS_WINRT
! 20344: __debugbreak();
! 20345: #else
1.4.2.2 misho 20346: DebugBreak();
1.4.2.3 ! misho 20347: #endif
1.4.2.2 misho 20348: #elif defined(SIGTRAP)
20349: raise(SIGTRAP);
20350: #endif
20351: }
20352: }
20353: #endif
20354:
1.4 misho 20355: #if USE_SYSTEM_SQLITE+0!=1
1.4.2.2 misho 20356: if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
1.4 misho 20357: utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
1.2 misho 20358: sqlite3_sourceid(), SQLITE_SOURCE_ID);
20359: exit(1);
20360: }
1.4 misho 20361: #endif
20362: main_init(&data);
1.4.2.2 misho 20363:
20364: /* On Windows, we must translate command-line arguments into UTF-8.
20365: ** The SQLite memory allocator subsystem has to be enabled in order to
20366: ** do this. But we want to run an sqlite3_shutdown() afterwards so that
20367: ** subsequent sqlite3_config() calls will work. So copy all results into
20368: ** memory that does not come from the SQLite memory allocator.
20369: */
1.4 misho 20370: #if !SQLITE_SHELL_IS_UTF8
20371: sqlite3_initialize();
1.4.2.2 misho 20372: argvToFree = malloc(sizeof(argv[0])*argc*2);
20373: argcToFree = argc;
20374: argv = argvToFree + argc;
20375: if( argv==0 ) shell_out_of_memory();
1.4 misho 20376: for(i=0; i<argc; i++){
1.4.2.2 misho 20377: char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
20378: int n;
20379: if( z==0 ) shell_out_of_memory();
20380: n = (int)strlen(z);
20381: argv[i] = malloc( n+1 );
20382: if( argv[i]==0 ) shell_out_of_memory();
20383: memcpy(argv[i], z, n+1);
20384: argvToFree[i] = argv[i];
20385: sqlite3_free(z);
1.4 misho 20386: }
1.4.2.2 misho 20387: sqlite3_shutdown();
1.4 misho 20388: #endif
1.4.2.2 misho 20389:
1.4 misho 20390: assert( argc>=1 && argv && argv[0] );
1.2 misho 20391: Argv0 = argv[0];
20392:
20393: /* Make sure we have a valid signal handler early, before anything
20394: ** else is done.
20395: */
20396: #ifdef SIGINT
20397: signal(SIGINT, interrupt_handler);
1.4.2.2 misho 20398: #elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
20399: SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
1.2 misho 20400: #endif
20401:
1.4 misho 20402: #ifdef SQLITE_SHELL_DBNAME_PROC
20403: {
20404: /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
20405: ** of a C-function that will provide the name of the database file. Use
20406: ** this compile-time option to embed this shell program in larger
20407: ** applications. */
20408: extern void SQLITE_SHELL_DBNAME_PROC(const char**);
20409: SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
20410: warnInmemoryDb = 0;
20411: }
20412: #endif
20413:
1.2 misho 20414: /* Do an initial pass through the command-line argument to locate
20415: ** the name of the database file, the name of the initialization file,
20416: ** the size of the alternative malloc heap,
20417: ** and the first command to execute.
20418: */
1.4.2.2 misho 20419: verify_uninitialized();
1.3 misho 20420: for(i=1; i<argc; i++){
1.2 misho 20421: char *z;
20422: z = argv[i];
1.3 misho 20423: if( z[0]!='-' ){
20424: if( data.zDbFilename==0 ){
20425: data.zDbFilename = z;
1.4 misho 20426: }else{
20427: /* Excesss arguments are interpreted as SQL (or dot-commands) and
20428: ** mean that nothing is read from stdin */
20429: readStdin = 0;
20430: nCmd++;
20431: azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
1.4.2.2 misho 20432: if( azCmd==0 ) shell_out_of_memory();
1.4 misho 20433: azCmd[nCmd-1] = z;
1.3 misho 20434: }
20435: }
20436: if( z[1]=='-' ) z++;
20437: if( strcmp(z,"-separator")==0
20438: || strcmp(z,"-nullvalue")==0
1.4 misho 20439: || strcmp(z,"-newline")==0
1.3 misho 20440: || strcmp(z,"-cmd")==0
20441: ){
20442: (void)cmdline_option_value(argc, argv, ++i);
20443: }else if( strcmp(z,"-init")==0 ){
20444: zInitFile = cmdline_option_value(argc, argv, ++i);
20445: }else if( strcmp(z,"-batch")==0 ){
20446: /* Need to check for batch mode here to so we can avoid printing
1.4 misho 20447: ** informational messages (like from process_sqliterc) before
1.3 misho 20448: ** we do the actual processing of arguments later in a second pass.
20449: */
1.2 misho 20450: stdin_is_interactive = 0;
1.3 misho 20451: }else if( strcmp(z,"-heap")==0 ){
1.2 misho 20452: #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
20453: const char *zSize;
20454: sqlite3_int64 szHeap;
20455:
1.3 misho 20456: zSize = cmdline_option_value(argc, argv, ++i);
1.4 misho 20457: szHeap = integerValue(zSize);
1.2 misho 20458: if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
20459: sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
1.4 misho 20460: #else
20461: (void)cmdline_option_value(argc, argv, ++i);
1.2 misho 20462: #endif
1.4 misho 20463: }else if( strcmp(z,"-pagecache")==0 ){
20464: int n, sz;
20465: sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
20466: if( sz>70000 ) sz = 70000;
20467: if( sz<0 ) sz = 0;
20468: n = (int)integerValue(cmdline_option_value(argc,argv,++i));
20469: sqlite3_config(SQLITE_CONFIG_PAGECACHE,
20470: (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
20471: data.shellFlgs |= SHFLG_Pagecache;
20472: }else if( strcmp(z,"-lookaside")==0 ){
20473: int n, sz;
20474: sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
20475: if( sz<0 ) sz = 0;
20476: n = (int)integerValue(cmdline_option_value(argc,argv,++i));
20477: if( n<0 ) n = 0;
20478: sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
20479: if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
1.2 misho 20480: #ifdef SQLITE_ENABLE_VFSTRACE
1.3 misho 20481: }else if( strcmp(z,"-vfstrace")==0 ){
1.2 misho 20482: extern int vfstrace_register(
20483: const char *zTraceName,
20484: const char *zOldVfsName,
20485: int (*xOut)(const char*,void*),
20486: void *pOutArg,
20487: int makeDefault
20488: );
20489: vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
20490: #endif
20491: #ifdef SQLITE_ENABLE_MULTIPLEX
1.3 misho 20492: }else if( strcmp(z,"-multiplex")==0 ){
1.2 misho 20493: extern int sqlite3_multiple_initialize(const char*,int);
20494: sqlite3_multiplex_initialize(0, 1);
20495: #endif
1.4 misho 20496: }else if( strcmp(z,"-mmap")==0 ){
20497: sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
20498: sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
1.4.2.2 misho 20499: #ifdef SQLITE_ENABLE_SORTER_REFERENCES
20500: }else if( strcmp(z,"-sorterref")==0 ){
20501: sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
20502: sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz);
20503: #endif
1.3 misho 20504: }else if( strcmp(z,"-vfs")==0 ){
1.4.2.2 misho 20505: zVfs = cmdline_option_value(argc, argv, ++i);
20506: #ifdef SQLITE_HAVE_ZLIB
20507: }else if( strcmp(z,"-zip")==0 ){
20508: data.openMode = SHELL_OPEN_ZIPFILE;
20509: #endif
20510: }else if( strcmp(z,"-append")==0 ){
20511: data.openMode = SHELL_OPEN_APPENDVFS;
20512: #ifdef SQLITE_ENABLE_DESERIALIZE
20513: }else if( strcmp(z,"-deserialize")==0 ){
20514: data.openMode = SHELL_OPEN_DESERIALIZE;
20515: }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
20516: data.szMax = integerValue(argv[++i]);
20517: #endif
20518: }else if( strcmp(z,"-readonly")==0 ){
20519: data.openMode = SHELL_OPEN_READONLY;
1.4.2.3 ! misho 20520: }else if( strcmp(z,"-nofollow")==0 ){
! 20521: data.openFlags = SQLITE_OPEN_NOFOLLOW;
1.4.2.2 misho 20522: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
20523: }else if( strncmp(z, "-A",2)==0 ){
20524: /* All remaining command-line arguments are passed to the ".archive"
20525: ** command, so ignore them */
20526: break;
20527: #endif
20528: }else if( strcmp(z, "-memtrace")==0 ){
20529: sqlite3MemTraceActivate(stderr);
20530: }
20531: }
20532: verify_uninitialized();
20533:
20534:
20535: #ifdef SQLITE_SHELL_INIT_PROC
20536: {
20537: /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name
20538: ** of a C-function that will perform initialization actions on SQLite that
20539: ** occur just before or after sqlite3_initialize(). Use this compile-time
20540: ** option to embed this shell program in larger applications. */
20541: extern void SQLITE_SHELL_INIT_PROC(void);
20542: SQLITE_SHELL_INIT_PROC();
20543: }
20544: #else
20545: /* All the sqlite3_config() calls have now been made. So it is safe
20546: ** to call sqlite3_initialize() and process any command line -vfs option. */
20547: sqlite3_initialize();
20548: #endif
20549:
20550: if( zVfs ){
20551: sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
20552: if( pVfs ){
20553: sqlite3_vfs_register(pVfs, 1);
20554: }else{
20555: utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
20556: exit(1);
1.2 misho 20557: }
20558: }
1.4.2.2 misho 20559:
1.3 misho 20560: if( data.zDbFilename==0 ){
1.2 misho 20561: #ifndef SQLITE_OMIT_MEMORYDB
20562: data.zDbFilename = ":memory:";
1.4 misho 20563: warnInmemoryDb = argc==1;
1.2 misho 20564: #else
1.4 misho 20565: utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
1.3 misho 20566: return 1;
1.2 misho 20567: #endif
20568: }
20569: data.out = stdout;
1.4.2.2 misho 20570: sqlite3_appendvfs_init(0,0,0);
1.2 misho 20571:
20572: /* Go ahead and open the database file if it already exists. If the
20573: ** file does not exist, delay opening it. This prevents empty database
20574: ** files from being created if a user mistypes the database name argument
20575: ** to the sqlite command-line tool.
20576: */
20577: if( access(data.zDbFilename, 0)==0 ){
1.4 misho 20578: open_db(&data, 0);
1.2 misho 20579: }
20580:
20581: /* Process the initialization file if there is one. If no -init option
20582: ** is given on the command line, look for a file named ~/.sqliterc and
20583: ** try to process it.
20584: */
1.4 misho 20585: process_sqliterc(&data,zInitFile);
1.2 misho 20586:
20587: /* Make a second pass through the command-line argument and set
20588: ** options. This second pass is delayed until after the initialization
20589: ** file is processed so that the command-line arguments will override
20590: ** settings in the initialization file.
20591: */
1.3 misho 20592: for(i=1; i<argc; i++){
1.2 misho 20593: char *z = argv[i];
1.3 misho 20594: if( z[0]!='-' ) continue;
1.2 misho 20595: if( z[1]=='-' ){ z++; }
20596: if( strcmp(z,"-init")==0 ){
20597: i++;
20598: }else if( strcmp(z,"-html")==0 ){
20599: data.mode = MODE_Html;
20600: }else if( strcmp(z,"-list")==0 ){
20601: data.mode = MODE_List;
1.4.2.2 misho 20602: }else if( strcmp(z,"-quote")==0 ){
20603: data.mode = MODE_Quote;
1.2 misho 20604: }else if( strcmp(z,"-line")==0 ){
20605: data.mode = MODE_Line;
20606: }else if( strcmp(z,"-column")==0 ){
20607: data.mode = MODE_Column;
1.4.2.3 ! misho 20608: }else if( strcmp(z,"-json")==0 ){
! 20609: data.mode = MODE_Json;
! 20610: }else if( strcmp(z,"-markdown")==0 ){
! 20611: data.mode = MODE_Markdown;
! 20612: }else if( strcmp(z,"-table")==0 ){
! 20613: data.mode = MODE_Table;
! 20614: }else if( strcmp(z,"-box")==0 ){
! 20615: data.mode = MODE_Box;
1.2 misho 20616: }else if( strcmp(z,"-csv")==0 ){
20617: data.mode = MODE_Csv;
1.4 misho 20618: memcpy(data.colSeparator,",",2);
1.4.2.2 misho 20619: #ifdef SQLITE_HAVE_ZLIB
20620: }else if( strcmp(z,"-zip")==0 ){
20621: data.openMode = SHELL_OPEN_ZIPFILE;
20622: #endif
20623: }else if( strcmp(z,"-append")==0 ){
20624: data.openMode = SHELL_OPEN_APPENDVFS;
20625: #ifdef SQLITE_ENABLE_DESERIALIZE
20626: }else if( strcmp(z,"-deserialize")==0 ){
20627: data.openMode = SHELL_OPEN_DESERIALIZE;
20628: }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
20629: data.szMax = integerValue(argv[++i]);
20630: #endif
20631: }else if( strcmp(z,"-readonly")==0 ){
20632: data.openMode = SHELL_OPEN_READONLY;
1.4.2.3 ! misho 20633: }else if( strcmp(z,"-nofollow")==0 ){
! 20634: data.openFlags |= SQLITE_OPEN_NOFOLLOW;
1.4 misho 20635: }else if( strcmp(z,"-ascii")==0 ){
20636: data.mode = MODE_Ascii;
20637: sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
20638: SEP_Unit);
20639: sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
20640: SEP_Record);
1.2 misho 20641: }else if( strcmp(z,"-separator")==0 ){
1.4 misho 20642: sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
20643: "%s",cmdline_option_value(argc,argv,++i));
20644: }else if( strcmp(z,"-newline")==0 ){
20645: sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
1.3 misho 20646: "%s",cmdline_option_value(argc,argv,++i));
1.2 misho 20647: }else if( strcmp(z,"-nullvalue")==0 ){
1.4 misho 20648: sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
1.3 misho 20649: "%s",cmdline_option_value(argc,argv,++i));
1.2 misho 20650: }else if( strcmp(z,"-header")==0 ){
20651: data.showHeader = 1;
20652: }else if( strcmp(z,"-noheader")==0 ){
20653: data.showHeader = 0;
20654: }else if( strcmp(z,"-echo")==0 ){
1.4.2.1 misho 20655: ShellSetFlag(&data, SHFLG_Echo);
1.4 misho 20656: }else if( strcmp(z,"-eqp")==0 ){
1.4.2.2 misho 20657: data.autoEQP = AUTOEQP_on;
1.4 misho 20658: }else if( strcmp(z,"-eqpfull")==0 ){
1.4.2.2 misho 20659: data.autoEQP = AUTOEQP_full;
1.2 misho 20660: }else if( strcmp(z,"-stats")==0 ){
20661: data.statsOn = 1;
1.4 misho 20662: }else if( strcmp(z,"-scanstats")==0 ){
20663: data.scanstatsOn = 1;
20664: }else if( strcmp(z,"-backslash")==0 ){
20665: /* Undocumented command-line option: -backslash
20666: ** Causes C-style backslash escapes to be evaluated in SQL statements
20667: ** prior to sending the SQL into SQLite. Useful for injecting
20668: ** crazy bytes in the middle of SQL statements for testing and debugging.
20669: */
1.4.2.1 misho 20670: ShellSetFlag(&data, SHFLG_Backslash);
1.2 misho 20671: }else if( strcmp(z,"-bail")==0 ){
20672: bail_on_error = 1;
20673: }else if( strcmp(z,"-version")==0 ){
20674: printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
20675: return 0;
20676: }else if( strcmp(z,"-interactive")==0 ){
20677: stdin_is_interactive = 1;
20678: }else if( strcmp(z,"-batch")==0 ){
20679: stdin_is_interactive = 0;
20680: }else if( strcmp(z,"-heap")==0 ){
20681: i++;
1.4 misho 20682: }else if( strcmp(z,"-pagecache")==0 ){
20683: i+=2;
20684: }else if( strcmp(z,"-lookaside")==0 ){
20685: i+=2;
20686: }else if( strcmp(z,"-mmap")==0 ){
20687: i++;
1.4.2.2 misho 20688: }else if( strcmp(z,"-memtrace")==0 ){
20689: i++;
20690: #ifdef SQLITE_ENABLE_SORTER_REFERENCES
20691: }else if( strcmp(z,"-sorterref")==0 ){
20692: i++;
20693: #endif
1.2 misho 20694: }else if( strcmp(z,"-vfs")==0 ){
20695: i++;
20696: #ifdef SQLITE_ENABLE_VFSTRACE
20697: }else if( strcmp(z,"-vfstrace")==0 ){
20698: i++;
20699: #endif
20700: #ifdef SQLITE_ENABLE_MULTIPLEX
20701: }else if( strcmp(z,"-multiplex")==0 ){
20702: i++;
20703: #endif
1.3 misho 20704: }else if( strcmp(z,"-help")==0 ){
1.2 misho 20705: usage(1);
1.3 misho 20706: }else if( strcmp(z,"-cmd")==0 ){
1.4 misho 20707: /* Run commands that follow -cmd first and separately from commands
20708: ** that simply appear on the command-line. This seems goofy. It would
20709: ** be better if all commands ran in the order that they appear. But
20710: ** we retain the goofy behavior for historical compatibility. */
1.3 misho 20711: if( i==argc-1 ) break;
20712: z = cmdline_option_value(argc,argv,++i);
20713: if( z[0]=='.' ){
20714: rc = do_meta_command(z, &data);
1.4 misho 20715: if( rc && bail_on_error ) return rc==2 ? 0 : rc;
1.3 misho 20716: }else{
1.4 misho 20717: open_db(&data, 0);
1.4.2.2 misho 20718: rc = shell_exec(&data, z, &zErrMsg);
1.3 misho 20719: if( zErrMsg!=0 ){
1.4 misho 20720: utf8_printf(stderr,"Error: %s\n", zErrMsg);
1.3 misho 20721: if( bail_on_error ) return rc!=0 ? rc : 1;
20722: }else if( rc!=0 ){
1.4 misho 20723: utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
1.3 misho 20724: if( bail_on_error ) return rc;
20725: }
20726: }
1.4.2.2 misho 20727: #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
20728: }else if( strncmp(z, "-A", 2)==0 ){
20729: if( nCmd>0 ){
20730: utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands"
20731: " with \"%s\"\n", z);
20732: return 1;
20733: }
20734: open_db(&data, OPEN_DB_ZIPFILE);
20735: if( z[2] ){
20736: argv[i] = &z[2];
20737: arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
20738: }else{
20739: arDotCommand(&data, 1, argv+i, argc-i);
20740: }
20741: readStdin = 0;
20742: break;
20743: #endif
1.2 misho 20744: }else{
1.4 misho 20745: utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
20746: raw_printf(stderr,"Use -help for a list of options.\n");
1.2 misho 20747: return 1;
20748: }
1.4 misho 20749: data.cMode = data.mode;
1.2 misho 20750: }
20751:
1.4 misho 20752: if( !readStdin ){
20753: /* Run all arguments that do not begin with '-' as if they were separate
20754: ** command-line inputs, except for the argToSkip argument which contains
20755: ** the database filename.
1.2 misho 20756: */
1.4 misho 20757: for(i=0; i<nCmd; i++){
20758: if( azCmd[i][0]=='.' ){
20759: rc = do_meta_command(azCmd[i], &data);
20760: if( rc ) return rc==2 ? 0 : rc;
20761: }else{
20762: open_db(&data, 0);
1.4.2.2 misho 20763: rc = shell_exec(&data, azCmd[i], &zErrMsg);
1.4 misho 20764: if( zErrMsg!=0 ){
20765: utf8_printf(stderr,"Error: %s\n", zErrMsg);
20766: return rc!=0 ? rc : 1;
20767: }else if( rc!=0 ){
20768: utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
20769: return rc;
20770: }
1.2 misho 20771: }
20772: }
1.4 misho 20773: free(azCmd);
1.2 misho 20774: }else{
20775: /* Run commands received from standard input
20776: */
20777: if( stdin_is_interactive ){
20778: char *zHome;
1.4.2.2 misho 20779: char *zHistory;
1.2 misho 20780: int nHistory;
20781: printf(
20782: "SQLite version %s %.19s\n" /*extra-version-info*/
1.4 misho 20783: "Enter \".help\" for usage hints.\n",
1.2 misho 20784: sqlite3_libversion(), sqlite3_sourceid()
20785: );
1.4 misho 20786: if( warnInmemoryDb ){
20787: printf("Connected to a ");
20788: printBold("transient in-memory database");
20789: printf(".\nUse \".open FILENAME\" to reopen on a "
20790: "persistent database.\n");
20791: }
1.4.2.2 misho 20792: zHistory = getenv("SQLITE_HISTORY");
20793: if( zHistory ){
20794: zHistory = strdup(zHistory);
20795: }else if( (zHome = find_home_dir(0))!=0 ){
1.2 misho 20796: nHistory = strlen30(zHome) + 20;
20797: if( (zHistory = malloc(nHistory))!=0 ){
20798: sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
20799: }
20800: }
1.4 misho 20801: if( zHistory ){ shell_read_history(zHistory); }
1.4.2.2 misho 20802: #if HAVE_READLINE || HAVE_EDITLINE
20803: rl_attempted_completion_function = readline_completion;
20804: #elif HAVE_LINENOISE
20805: linenoiseSetCompletionCallback(linenoise_completion);
20806: #endif
20807: data.in = 0;
20808: rc = process_input(&data);
1.2 misho 20809: if( zHistory ){
1.4.2.2 misho 20810: shell_stifle_history(2000);
1.4 misho 20811: shell_write_history(zHistory);
1.2 misho 20812: free(zHistory);
20813: }
20814: }else{
1.4.2.2 misho 20815: data.in = stdin;
20816: rc = process_input(&data);
1.2 misho 20817: }
20818: }
20819: set_table_name(&data, 0);
20820: if( data.db ){
1.4 misho 20821: session_close_all(&data);
1.4.2.2 misho 20822: close_db(data.db);
1.2 misho 20823: }
1.4 misho 20824: sqlite3_free(data.zFreeOnClose);
1.4.2.1 misho 20825: find_home_dir(1);
1.4.2.2 misho 20826: output_reset(&data);
20827: data.doXdgOpen = 0;
20828: clearTempFile(&data);
1.4 misho 20829: #if !SQLITE_SHELL_IS_UTF8
1.4.2.2 misho 20830: for(i=0; i<argcToFree; i++) free(argvToFree[i]);
20831: free(argvToFree);
1.4 misho 20832: #endif
1.4.2.3 ! misho 20833: free(data.colWidth);
1.4.2.2 misho 20834: /* Clear the global data structure so that valgrind will detect memory
20835: ** leaks */
20836: memset(&data, 0, sizeof(data));
1.2 misho 20837: return rc;
20838: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>