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 | */ |
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 | typedef unsigned int u32; |
38 | typedef unsigned short int u16; |
39 | |
40 | /* |
41 | ** Optionally #include a user-defined header, whereby compilation options |
42 | ** may be set prior to where they take effect, but after platform setup. |
43 | ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include |
44 | ** file. Note that this macro has a like effect on sqlite3.c compilation. |
45 | */ |
46 | # define SHELL_STRINGIFY_(f) #f |
47 | # define SHELL_STRINGIFY(f) SHELL_STRINGIFY_(f) |
48 | #ifdef SQLITE_CUSTOM_INCLUDE |
49 | # include SHELL_STRINGIFY(SQLITE_CUSTOM_INCLUDE) |
50 | #endif |
51 | |
52 | /* |
53 | ** Determine if we are dealing with WinRT, which provides only a subset of |
54 | ** the full Win32 API. |
55 | */ |
56 | #if !defined(SQLITE_OS_WINRT) |
57 | # define SQLITE_OS_WINRT 0 |
58 | #endif |
59 | |
60 | /* |
61 | ** If SQLITE_SHELL_FIDDLE is defined then the shell is modified |
62 | ** somewhat for use as a WASM module in a web browser. This flag |
63 | ** should only be used when building the "fiddle" web application, as |
64 | ** the browser-mode build has much different user input requirements |
65 | ** and this build mode rewires the user input subsystem to account for |
66 | ** that. |
67 | */ |
68 | |
69 | /* |
70 | ** Warning pragmas copied from msvc.h in the core. |
71 | */ |
72 | #if defined(_MSC_VER) |
73 | #pragma warning(disable : 4054) |
74 | #pragma warning(disable : 4055) |
75 | #pragma warning(disable : 4100) |
76 | #pragma warning(disable : 4127) |
77 | #pragma warning(disable : 4130) |
78 | #pragma warning(disable : 4152) |
79 | #pragma warning(disable : 4189) |
80 | #pragma warning(disable : 4206) |
81 | #pragma warning(disable : 4210) |
82 | #pragma warning(disable : 4232) |
83 | #pragma warning(disable : 4244) |
84 | #pragma warning(disable : 4305) |
85 | #pragma warning(disable : 4306) |
86 | #pragma warning(disable : 4702) |
87 | #pragma warning(disable : 4706) |
88 | #endif /* defined(_MSC_VER) */ |
89 | |
90 | /* |
91 | ** No support for loadable extensions in VxWorks. |
92 | */ |
93 | #if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION |
94 | # define SQLITE_OMIT_LOAD_EXTENSION 1 |
95 | #endif |
96 | |
97 | /* |
98 | ** Enable large-file support for fopen() and friends on unix. |
99 | */ |
100 | #ifndef SQLITE_DISABLE_LFS |
101 | # define _LARGE_FILE 1 |
102 | # ifndef _FILE_OFFSET_BITS |
103 | # define _FILE_OFFSET_BITS 64 |
104 | # endif |
105 | # define _LARGEFILE_SOURCE 1 |
106 | #endif |
107 | |
108 | #if defined(SQLITE_SHELL_FIDDLE) && !defined(_POSIX_SOURCE) |
109 | /* |
110 | ** emcc requires _POSIX_SOURCE (or one of several similar defines) |
111 | ** to expose strdup(). |
112 | */ |
113 | # define _POSIX_SOURCE |
114 | #endif |
115 | |
116 | #include <stdlib.h> |
117 | #include <string.h> |
118 | #include <stdio.h> |
119 | #include <assert.h> |
120 | #include "sqlite3.h" |
121 | typedef sqlite3_int64 i64; |
122 | typedef sqlite3_uint64 u64; |
123 | typedef unsigned char u8; |
124 | #if SQLITE_USER_AUTHENTICATION |
125 | # include "sqlite3userauth.h" |
126 | #endif |
127 | #include <ctype.h> |
128 | #include <stdarg.h> |
129 | |
130 | #if !defined(_WIN32) && !defined(WIN32) |
131 | # include <signal.h> |
132 | # if !defined(__RTP__) && !defined(_WRS_KERNEL) |
133 | # include <pwd.h> |
134 | # endif |
135 | #endif |
136 | #if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__) |
137 | # include <unistd.h> |
138 | # include <dirent.h> |
139 | # define GETPID getpid |
140 | # if defined(__MINGW32__) |
141 | # define DIRENT dirent |
142 | # ifndef S_ISLNK |
143 | # define S_ISLNK(mode) (0) |
144 | # endif |
145 | # endif |
146 | #else |
147 | # define GETPID (int)GetCurrentProcessId |
148 | #endif |
149 | #include <sys/types.h> |
150 | #include <sys/stat.h> |
151 | |
152 | #if HAVE_READLINE |
153 | # include <readline/readline.h> |
154 | # include <readline/history.h> |
155 | #endif |
156 | |
157 | #if HAVE_EDITLINE |
158 | # include <editline/readline.h> |
159 | #endif |
160 | |
161 | #if HAVE_EDITLINE || HAVE_READLINE |
162 | |
163 | # define shell_add_history(X) add_history(X) |
164 | # define shell_read_history(X) read_history(X) |
165 | # define shell_write_history(X) write_history(X) |
166 | # define shell_stifle_history(X) stifle_history(X) |
167 | # define shell_readline(X) readline(X) |
168 | |
169 | #elif HAVE_LINENOISE |
170 | |
171 | # include "linenoise.h" |
172 | # define shell_add_history(X) linenoiseHistoryAdd(X) |
173 | # define shell_read_history(X) linenoiseHistoryLoad(X) |
174 | # define shell_write_history(X) linenoiseHistorySave(X) |
175 | # define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) |
176 | # define shell_readline(X) linenoise(X) |
177 | |
178 | #else |
179 | |
180 | # define shell_read_history(X) |
181 | # define shell_write_history(X) |
182 | # define shell_stifle_history(X) |
183 | |
184 | # define SHELL_USE_LOCAL_GETLINE 1 |
185 | #endif |
186 | |
187 | |
188 | #if defined(_WIN32) || defined(WIN32) |
189 | # if SQLITE_OS_WINRT |
190 | # define SQLITE_OMIT_POPEN 1 |
191 | # else |
192 | # include <io.h> |
193 | # include <fcntl.h> |
194 | # define isatty(h) _isatty(h) |
195 | # ifndef access |
196 | # define access(f,m) _access((f),(m)) |
197 | # endif |
198 | # ifndef unlink |
199 | # define unlink _unlink |
200 | # endif |
201 | # ifndef strdup |
202 | # define strdup _strdup |
203 | # endif |
204 | # undef popen |
205 | # define popen _popen |
206 | # undef pclose |
207 | # define pclose _pclose |
208 | # endif |
209 | #else |
210 | /* Make sure isatty() has a prototype. */ |
211 | extern int isatty(int); |
212 | |
213 | # if !defined(__RTP__) && !defined(_WRS_KERNEL) |
214 | /* popen and pclose are not C89 functions and so are |
215 | ** sometimes omitted from the <stdio.h> header */ |
216 | extern FILE *popen(const char*,const char*); |
217 | extern int pclose(FILE*); |
218 | # else |
219 | # define SQLITE_OMIT_POPEN 1 |
220 | # endif |
221 | #endif |
222 | |
223 | #if defined(_WIN32_WCE) |
224 | /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() |
225 | * thus we always assume that we have a console. That can be |
226 | * overridden with the -batch command line option. |
227 | */ |
228 | #define isatty(x) 1 |
229 | #endif |
230 | |
231 | /* ctype macros that work with signed characters */ |
232 | #define IsSpace(X) isspace((unsigned char)X) |
233 | #define IsDigit(X) isdigit((unsigned char)X) |
234 | #define ToLower(X) (char)tolower((unsigned char)X) |
235 | |
236 | #if defined(_WIN32) || defined(WIN32) |
237 | #if SQLITE_OS_WINRT |
238 | #include <intrin.h> |
239 | #endif |
240 | #include <windows.h> |
241 | |
242 | /* string conversion routines only needed on Win32 */ |
243 | extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); |
244 | extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); |
245 | extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); |
246 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); |
247 | #endif |
248 | |
249 | /* On Windows, we normally run with output mode of TEXT so that \n characters |
250 | ** are automatically translated into \r\n. However, this behavior needs |
251 | ** to be disabled in some cases (ex: when generating CSV output and when |
252 | ** rendering quoted strings that contain \n characters). The following |
253 | ** routines take care of that. |
254 | */ |
255 | #if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT |
256 | static void setBinaryMode(FILE *file, int isOutput){ |
257 | if( isOutput ) fflush(file); |
258 | _setmode(_fileno(file), _O_BINARY); |
259 | } |
260 | static void setTextMode(FILE *file, int isOutput){ |
261 | if( isOutput ) fflush(file); |
262 | _setmode(_fileno(file), _O_TEXT); |
263 | } |
264 | #else |
265 | # define setBinaryMode(X,Y) |
266 | # define setTextMode(X,Y) |
267 | #endif |
268 | |
269 | /* True if the timer is enabled */ |
270 | static int enableTimer = 0; |
271 | |
272 | /* A version of strcmp() that works with NULL values */ |
273 | static int cli_strcmp(const char *a, const char *b){ |
274 | if( a==0 ) a = "" ; |
275 | if( b==0 ) b = "" ; |
276 | return strcmp(a,b); |
277 | } |
278 | static int cli_strncmp(const char *a, const char *b, size_t n){ |
279 | if( a==0 ) a = "" ; |
280 | if( b==0 ) b = "" ; |
281 | return strncmp(a,b,n); |
282 | } |
283 | |
284 | /* Return the current wall-clock time */ |
285 | static sqlite3_int64 timeOfDay(void){ |
286 | static sqlite3_vfs *clockVfs = 0; |
287 | sqlite3_int64 t; |
288 | if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); |
289 | if( clockVfs==0 ) return 0; /* Never actually happens */ |
290 | if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ |
291 | clockVfs->xCurrentTimeInt64(clockVfs, &t); |
292 | }else{ |
293 | double r; |
294 | clockVfs->xCurrentTime(clockVfs, &r); |
295 | t = (sqlite3_int64)(r*86400000.0); |
296 | } |
297 | return t; |
298 | } |
299 | |
300 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) |
301 | #include <sys/time.h> |
302 | #include <sys/resource.h> |
303 | |
304 | /* VxWorks does not support getrusage() as far as we can determine */ |
305 | #if defined(_WRS_KERNEL) || defined(__RTP__) |
306 | struct rusage { |
307 | struct timeval ru_utime; /* user CPU time used */ |
308 | struct timeval ru_stime; /* system CPU time used */ |
309 | }; |
310 | #define getrusage(A,B) memset(B,0,sizeof(*B)) |
311 | #endif |
312 | |
313 | /* Saved resource information for the beginning of an operation */ |
314 | static struct rusage sBegin; /* CPU time at start */ |
315 | static sqlite3_int64 iBegin; /* Wall-clock time at start */ |
316 | |
317 | /* |
318 | ** Begin timing an operation |
319 | */ |
320 | static void beginTimer(void){ |
321 | if( enableTimer ){ |
322 | getrusage(RUSAGE_SELF, &sBegin); |
323 | iBegin = timeOfDay(); |
324 | } |
325 | } |
326 | |
327 | /* Return the difference of two time_structs in seconds */ |
328 | static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ |
329 | return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + |
330 | (double)(pEnd->tv_sec - pStart->tv_sec); |
331 | } |
332 | |
333 | /* |
334 | ** Print the timing results. |
335 | */ |
336 | static void endTimer(void){ |
337 | if( enableTimer ){ |
338 | sqlite3_int64 iEnd = timeOfDay(); |
339 | struct rusage sEnd; |
340 | getrusage(RUSAGE_SELF, &sEnd); |
341 | printf("Run Time: real %.3f user %f sys %f\n" , |
342 | (iEnd - iBegin)*0.001, |
343 | timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), |
344 | timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); |
345 | } |
346 | } |
347 | |
348 | #define BEGIN_TIMER beginTimer() |
349 | #define END_TIMER endTimer() |
350 | #define HAS_TIMER 1 |
351 | |
352 | #elif (defined(_WIN32) || defined(WIN32)) |
353 | |
354 | /* Saved resource information for the beginning of an operation */ |
355 | static HANDLE hProcess; |
356 | static FILETIME ftKernelBegin; |
357 | static FILETIME ftUserBegin; |
358 | static sqlite3_int64 ftWallBegin; |
359 | typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, |
360 | LPFILETIME, LPFILETIME); |
361 | static GETPROCTIMES getProcessTimesAddr = NULL; |
362 | |
363 | /* |
364 | ** Check to see if we have timer support. Return 1 if necessary |
365 | ** support found (or found previously). |
366 | */ |
367 | static int hasTimer(void){ |
368 | if( getProcessTimesAddr ){ |
369 | return 1; |
370 | } else { |
371 | #if !SQLITE_OS_WINRT |
372 | /* GetProcessTimes() isn't supported in WIN95 and some other Windows |
373 | ** versions. See if the version we are running on has it, and if it |
374 | ** does, save off a pointer to it and the current process handle. |
375 | */ |
376 | hProcess = GetCurrentProcess(); |
377 | if( hProcess ){ |
378 | HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll" )); |
379 | if( NULL != hinstLib ){ |
380 | getProcessTimesAddr = |
381 | (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes" ); |
382 | if( NULL != getProcessTimesAddr ){ |
383 | return 1; |
384 | } |
385 | FreeLibrary(hinstLib); |
386 | } |
387 | } |
388 | #endif |
389 | } |
390 | return 0; |
391 | } |
392 | |
393 | /* |
394 | ** Begin timing an operation |
395 | */ |
396 | static void beginTimer(void){ |
397 | if( enableTimer && getProcessTimesAddr ){ |
398 | FILETIME ftCreation, ftExit; |
399 | getProcessTimesAddr(hProcess,&ftCreation,&ftExit, |
400 | &ftKernelBegin,&ftUserBegin); |
401 | ftWallBegin = timeOfDay(); |
402 | } |
403 | } |
404 | |
405 | /* Return the difference of two FILETIME structs in seconds */ |
406 | static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ |
407 | sqlite_int64 i64Start = *((sqlite_int64 *) pStart); |
408 | sqlite_int64 i64End = *((sqlite_int64 *) pEnd); |
409 | return (double) ((i64End - i64Start) / 10000000.0); |
410 | } |
411 | |
412 | /* |
413 | ** Print the timing results. |
414 | */ |
415 | static void endTimer(void){ |
416 | if( enableTimer && getProcessTimesAddr){ |
417 | FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; |
418 | sqlite3_int64 ftWallEnd = timeOfDay(); |
419 | getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); |
420 | printf("Run Time: real %.3f user %f sys %f\n" , |
421 | (ftWallEnd - ftWallBegin)*0.001, |
422 | timeDiff(&ftUserBegin, &ftUserEnd), |
423 | timeDiff(&ftKernelBegin, &ftKernelEnd)); |
424 | } |
425 | } |
426 | |
427 | #define BEGIN_TIMER beginTimer() |
428 | #define END_TIMER endTimer() |
429 | #define HAS_TIMER hasTimer() |
430 | |
431 | #else |
432 | #define BEGIN_TIMER |
433 | #define END_TIMER |
434 | #define HAS_TIMER 0 |
435 | #endif |
436 | |
437 | /* |
438 | ** Used to prevent warnings about unused parameters |
439 | */ |
440 | #define UNUSED_PARAMETER(x) (void)(x) |
441 | |
442 | /* |
443 | ** Number of elements in an array |
444 | */ |
445 | #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) |
446 | |
447 | /* |
448 | ** If the following flag is set, then command execution stops |
449 | ** at an error if we are not interactive. |
450 | */ |
451 | static int bail_on_error = 0; |
452 | |
453 | /* |
454 | ** Threat stdin as an interactive input if the following variable |
455 | ** is true. Otherwise, assume stdin is connected to a file or pipe. |
456 | */ |
457 | static int stdin_is_interactive = 1; |
458 | |
459 | /* |
460 | ** On Windows systems we have to know if standard output is a console |
461 | ** in order to translate UTF-8 into MBCS. The following variable is |
462 | ** true if translation is required. |
463 | */ |
464 | static int stdout_is_console = 1; |
465 | |
466 | /* |
467 | ** The following is the open SQLite database. We make a pointer |
468 | ** to this database a static variable so that it can be accessed |
469 | ** by the SIGINT handler to interrupt database processing. |
470 | */ |
471 | static sqlite3 *globalDb = 0; |
472 | |
473 | /* |
474 | ** True if an interrupt (Control-C) has been received. |
475 | */ |
476 | static volatile int seenInterrupt = 0; |
477 | |
478 | /* |
479 | ** This is the name of our program. It is set in main(), used |
480 | ** in a number of other places, mostly for error messages. |
481 | */ |
482 | static char *Argv0; |
483 | |
484 | /* |
485 | ** Prompt strings. Initialized in main. Settable with |
486 | ** .prompt main continue |
487 | */ |
488 | static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ |
489 | static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ |
490 | |
491 | /* |
492 | ** Render output like fprintf(). Except, if the output is going to the |
493 | ** console and if this is running on a Windows machine, translate the |
494 | ** output from UTF-8 into MBCS. |
495 | */ |
496 | #if defined(_WIN32) || defined(WIN32) |
497 | void utf8_printf(FILE *out, const char *zFormat, ...){ |
498 | va_list ap; |
499 | va_start(ap, zFormat); |
500 | if( stdout_is_console && (out==stdout || out==stderr) ){ |
501 | char *z1 = sqlite3_vmprintf(zFormat, ap); |
502 | char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); |
503 | sqlite3_free(z1); |
504 | fputs(z2, out); |
505 | sqlite3_free(z2); |
506 | }else{ |
507 | vfprintf(out, zFormat, ap); |
508 | } |
509 | va_end(ap); |
510 | } |
511 | #elif !defined(utf8_printf) |
512 | # define utf8_printf fprintf |
513 | #endif |
514 | |
515 | /* |
516 | ** Render output like fprintf(). This should not be used on anything that |
517 | ** includes string formatting (e.g. "%s"). |
518 | */ |
519 | #if !defined(raw_printf) |
520 | # define raw_printf fprintf |
521 | #endif |
522 | |
523 | /* Indicate out-of-memory and exit. */ |
524 | static void shell_out_of_memory(void){ |
525 | raw_printf(stderr,"Error: out of memory\n" ); |
526 | exit(1); |
527 | } |
528 | |
529 | /* Check a pointer to see if it is NULL. If it is NULL, exit with an |
530 | ** out-of-memory error. |
531 | */ |
532 | static void shell_check_oom(void *p){ |
533 | if( p==0 ) shell_out_of_memory(); |
534 | } |
535 | |
536 | /* |
537 | ** Write I/O traces to the following stream. |
538 | */ |
539 | #ifdef SQLITE_ENABLE_IOTRACE |
540 | static FILE *iotrace = 0; |
541 | #endif |
542 | |
543 | /* |
544 | ** This routine works like printf in that its first argument is a |
545 | ** format string and subsequent arguments are values to be substituted |
546 | ** in place of % fields. The result of formatting this string |
547 | ** is written to iotrace. |
548 | */ |
549 | #ifdef SQLITE_ENABLE_IOTRACE |
550 | static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ |
551 | va_list ap; |
552 | char *z; |
553 | if( iotrace==0 ) return; |
554 | va_start(ap, zFormat); |
555 | z = sqlite3_vmprintf(zFormat, ap); |
556 | va_end(ap); |
557 | utf8_printf(iotrace, "%s" , z); |
558 | sqlite3_free(z); |
559 | } |
560 | #endif |
561 | |
562 | /* |
563 | ** Output string zUtf to stream pOut as w characters. If w is negative, |
564 | ** then right-justify the text. W is the width in UTF-8 characters, not |
565 | ** in bytes. This is different from the %*.*s specification in printf |
566 | ** since with %*.*s the width is measured in bytes, not characters. |
567 | */ |
568 | static void utf8_width_print(FILE *pOut, int w, const char *zUtf){ |
569 | int i; |
570 | int n; |
571 | int aw = w<0 ? -w : w; |
572 | if( zUtf==0 ) zUtf = "" ; |
573 | for(i=n=0; zUtf[i]; i++){ |
574 | if( (zUtf[i]&0xc0)!=0x80 ){ |
575 | n++; |
576 | if( n==aw ){ |
577 | do{ i++; }while( (zUtf[i]&0xc0)==0x80 ); |
578 | break; |
579 | } |
580 | } |
581 | } |
582 | if( n>=aw ){ |
583 | utf8_printf(pOut, "%.*s" , i, zUtf); |
584 | }else if( w<0 ){ |
585 | utf8_printf(pOut, "%*s%s" , aw-n, "" , zUtf); |
586 | }else{ |
587 | utf8_printf(pOut, "%s%*s" , zUtf, aw-n, "" ); |
588 | } |
589 | } |
590 | |
591 | |
592 | /* |
593 | ** Determines if a string is a number of not. |
594 | */ |
595 | static int isNumber(const char *z, int *realnum){ |
596 | if( *z=='-' || *z=='+' ) z++; |
597 | if( !IsDigit(*z) ){ |
598 | return 0; |
599 | } |
600 | z++; |
601 | if( realnum ) *realnum = 0; |
602 | while( IsDigit(*z) ){ z++; } |
603 | if( *z=='.' ){ |
604 | z++; |
605 | if( !IsDigit(*z) ) return 0; |
606 | while( IsDigit(*z) ){ z++; } |
607 | if( realnum ) *realnum = 1; |
608 | } |
609 | if( *z=='e' || *z=='E' ){ |
610 | z++; |
611 | if( *z=='+' || *z=='-' ) z++; |
612 | if( !IsDigit(*z) ) return 0; |
613 | while( IsDigit(*z) ){ z++; } |
614 | if( realnum ) *realnum = 1; |
615 | } |
616 | return *z==0; |
617 | } |
618 | |
619 | /* |
620 | ** Compute a string length that is limited to what can be stored in |
621 | ** lower 30 bits of a 32-bit signed integer. |
622 | */ |
623 | static int strlen30(const char *z){ |
624 | const char *z2 = z; |
625 | while( *z2 ){ z2++; } |
626 | return 0x3fffffff & (int)(z2 - z); |
627 | } |
628 | |
629 | /* |
630 | ** Return the length of a string in characters. Multibyte UTF8 characters |
631 | ** count as a single character. |
632 | */ |
633 | static int strlenChar(const char *z){ |
634 | int n = 0; |
635 | while( *z ){ |
636 | if( (0xc0&*(z++))!=0x80 ) n++; |
637 | } |
638 | return n; |
639 | } |
640 | |
641 | /* |
642 | ** Return open FILE * if zFile exists, can be opened for read |
643 | ** and is an ordinary file or a character stream source. |
644 | ** Otherwise return 0. |
645 | */ |
646 | static FILE * openChrSource(const char *zFile){ |
647 | #ifdef _WIN32 |
648 | struct _stat x = {0}; |
649 | # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0) |
650 | /* On Windows, open first, then check the stream nature. This order |
651 | ** is necessary because _stat() and sibs, when checking a named pipe, |
652 | ** effectively break the pipe as its supplier sees it. */ |
653 | FILE *rv = fopen(zFile, "rb" ); |
654 | if( rv==0 ) return 0; |
655 | if( _fstat(_fileno(rv), &x) != 0 |
656 | || !STAT_CHR_SRC(x.st_mode)){ |
657 | fclose(rv); |
658 | rv = 0; |
659 | } |
660 | return rv; |
661 | #else |
662 | struct stat x = {0}; |
663 | int rc = stat(zFile, &x); |
664 | # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) |
665 | if( rc!=0 ) return 0; |
666 | if( STAT_CHR_SRC(x.st_mode) ){ |
667 | return fopen(zFile, "rb" ); |
668 | }else{ |
669 | return 0; |
670 | } |
671 | #endif |
672 | #undef STAT_CHR_SRC |
673 | } |
674 | |
675 | /* |
676 | ** This routine reads a line of text from FILE in, stores |
677 | ** the text in memory obtained from malloc() and returns a pointer |
678 | ** to the text. NULL is returned at end of file, or if malloc() |
679 | ** fails. |
680 | ** |
681 | ** If zLine is not NULL then it is a malloced buffer returned from |
682 | ** a previous call to this routine that may be reused. |
683 | */ |
684 | static char *local_getline(char *zLine, FILE *in){ |
685 | int nLine = zLine==0 ? 0 : 100; |
686 | int n = 0; |
687 | |
688 | while( 1 ){ |
689 | if( n+100>nLine ){ |
690 | nLine = nLine*2 + 100; |
691 | zLine = realloc(zLine, nLine); |
692 | shell_check_oom(zLine); |
693 | } |
694 | if( fgets(&zLine[n], nLine - n, in)==0 ){ |
695 | if( n==0 ){ |
696 | free(zLine); |
697 | return 0; |
698 | } |
699 | zLine[n] = 0; |
700 | break; |
701 | } |
702 | while( zLine[n] ) n++; |
703 | if( n>0 && zLine[n-1]=='\n' ){ |
704 | n--; |
705 | if( n>0 && zLine[n-1]=='\r' ) n--; |
706 | zLine[n] = 0; |
707 | break; |
708 | } |
709 | } |
710 | #if defined(_WIN32) || defined(WIN32) |
711 | /* For interactive input on Windows systems, translate the |
712 | ** multi-byte characterset characters into UTF-8. */ |
713 | if( stdin_is_interactive && in==stdin ){ |
714 | char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); |
715 | if( zTrans ){ |
716 | i64 nTrans = strlen(zTrans)+1; |
717 | if( nTrans>nLine ){ |
718 | zLine = realloc(zLine, nTrans); |
719 | shell_check_oom(zLine); |
720 | } |
721 | memcpy(zLine, zTrans, nTrans); |
722 | sqlite3_free(zTrans); |
723 | } |
724 | } |
725 | #endif /* defined(_WIN32) || defined(WIN32) */ |
726 | return zLine; |
727 | } |
728 | |
729 | /* |
730 | ** Retrieve a single line of input text. |
731 | ** |
732 | ** If in==0 then read from standard input and prompt before each line. |
733 | ** If isContinuation is true, then a continuation prompt is appropriate. |
734 | ** If isContinuation is zero, then the main prompt should be used. |
735 | ** |
736 | ** If zPrior is not NULL then it is a buffer from a prior call to this |
737 | ** routine that can be reused. |
738 | ** |
739 | ** The result is stored in space obtained from malloc() and must either |
740 | ** be freed by the caller or else passed back into this routine via the |
741 | ** zPrior argument for reuse. |
742 | */ |
743 | #ifndef SQLITE_SHELL_FIDDLE |
744 | static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ |
745 | char *zPrompt; |
746 | char *zResult; |
747 | if( in!=0 ){ |
748 | zResult = local_getline(zPrior, in); |
749 | }else{ |
750 | zPrompt = isContinuation ? continuePrompt : mainPrompt; |
751 | #if SHELL_USE_LOCAL_GETLINE |
752 | printf("%s" , zPrompt); |
753 | fflush(stdout); |
754 | zResult = local_getline(zPrior, stdin); |
755 | #else |
756 | free(zPrior); |
757 | zResult = shell_readline(zPrompt); |
758 | if( zResult && *zResult ) shell_add_history(zResult); |
759 | #endif |
760 | } |
761 | return zResult; |
762 | } |
763 | #endif /* !SQLITE_SHELL_FIDDLE */ |
764 | |
765 | /* |
766 | ** Return the value of a hexadecimal digit. Return -1 if the input |
767 | ** is not a hex digit. |
768 | */ |
769 | static int hexDigitValue(char c){ |
770 | if( c>='0' && c<='9' ) return c - '0'; |
771 | if( c>='a' && c<='f' ) return c - 'a' + 10; |
772 | if( c>='A' && c<='F' ) return c - 'A' + 10; |
773 | return -1; |
774 | } |
775 | |
776 | /* |
777 | ** Interpret zArg as an integer value, possibly with suffixes. |
778 | */ |
779 | static sqlite3_int64 integerValue(const char *zArg){ |
780 | sqlite3_int64 v = 0; |
781 | static const struct { char *zSuffix; int iMult; } aMult[] = { |
782 | { "KiB" , 1024 }, |
783 | { "MiB" , 1024*1024 }, |
784 | { "GiB" , 1024*1024*1024 }, |
785 | { "KB" , 1000 }, |
786 | { "MB" , 1000000 }, |
787 | { "GB" , 1000000000 }, |
788 | { "K" , 1000 }, |
789 | { "M" , 1000000 }, |
790 | { "G" , 1000000000 }, |
791 | }; |
792 | int i; |
793 | int isNeg = 0; |
794 | if( zArg[0]=='-' ){ |
795 | isNeg = 1; |
796 | zArg++; |
797 | }else if( zArg[0]=='+' ){ |
798 | zArg++; |
799 | } |
800 | if( zArg[0]=='0' && zArg[1]=='x' ){ |
801 | int x; |
802 | zArg += 2; |
803 | while( (x = hexDigitValue(zArg[0]))>=0 ){ |
804 | v = (v<<4) + x; |
805 | zArg++; |
806 | } |
807 | }else{ |
808 | while( IsDigit(zArg[0]) ){ |
809 | v = v*10 + zArg[0] - '0'; |
810 | zArg++; |
811 | } |
812 | } |
813 | for(i=0; i<ArraySize(aMult); i++){ |
814 | if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ |
815 | v *= aMult[i].iMult; |
816 | break; |
817 | } |
818 | } |
819 | return isNeg? -v : v; |
820 | } |
821 | |
822 | /* |
823 | ** A variable length string to which one can append text. |
824 | */ |
825 | typedef struct ShellText ShellText; |
826 | struct ShellText { |
827 | char *z; |
828 | int n; |
829 | int nAlloc; |
830 | }; |
831 | |
832 | /* |
833 | ** Initialize and destroy a ShellText object |
834 | */ |
835 | static void initText(ShellText *p){ |
836 | memset(p, 0, sizeof(*p)); |
837 | } |
838 | static void freeText(ShellText *p){ |
839 | free(p->z); |
840 | initText(p); |
841 | } |
842 | |
843 | /* zIn is either a pointer to a NULL-terminated string in memory obtained |
844 | ** from malloc(), or a NULL pointer. The string pointed to by zAppend is |
845 | ** added to zIn, and the result returned in memory obtained from malloc(). |
846 | ** zIn, if it was not NULL, is freed. |
847 | ** |
848 | ** If the third argument, quote, is not '\0', then it is used as a |
849 | ** quote character for zAppend. |
850 | */ |
851 | static void appendText(ShellText *p, const char *zAppend, char quote){ |
852 | i64 len; |
853 | i64 i; |
854 | i64 nAppend = strlen30(zAppend); |
855 | |
856 | len = nAppend+p->n+1; |
857 | if( quote ){ |
858 | len += 2; |
859 | for(i=0; i<nAppend; i++){ |
860 | if( zAppend[i]==quote ) len++; |
861 | } |
862 | } |
863 | |
864 | if( p->z==0 || p->n+len>=p->nAlloc ){ |
865 | p->nAlloc = p->nAlloc*2 + len + 20; |
866 | p->z = realloc(p->z, p->nAlloc); |
867 | shell_check_oom(p->z); |
868 | } |
869 | |
870 | if( quote ){ |
871 | char *zCsr = p->z+p->n; |
872 | *zCsr++ = quote; |
873 | for(i=0; i<nAppend; i++){ |
874 | *zCsr++ = zAppend[i]; |
875 | if( zAppend[i]==quote ) *zCsr++ = quote; |
876 | } |
877 | *zCsr++ = quote; |
878 | p->n = (int)(zCsr - p->z); |
879 | *zCsr = '\0'; |
880 | }else{ |
881 | memcpy(p->z+p->n, zAppend, nAppend); |
882 | p->n += nAppend; |
883 | p->z[p->n] = '\0'; |
884 | } |
885 | } |
886 | |
887 | /* |
888 | ** Attempt to determine if identifier zName needs to be quoted, either |
889 | ** because it contains non-alphanumeric characters, or because it is an |
890 | ** SQLite keyword. Be conservative in this estimate: When in doubt assume |
891 | ** that quoting is required. |
892 | ** |
893 | ** Return '"' if quoting is required. Return 0 if no quoting is required. |
894 | */ |
895 | static char quoteChar(const char *zName){ |
896 | int i; |
897 | if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"'; |
898 | for(i=0; zName[i]; i++){ |
899 | if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"'; |
900 | } |
901 | return sqlite3_keyword_check(zName, i) ? '"' : 0; |
902 | } |
903 | |
904 | /* |
905 | ** Construct a fake object name and column list to describe the structure |
906 | ** of the view, virtual table, or table valued function zSchema.zName. |
907 | */ |
908 | static char *shellFakeSchema( |
909 | sqlite3 *db, /* The database connection containing the vtab */ |
910 | const char *zSchema, /* Schema of the database holding the vtab */ |
911 | const char *zName /* The name of the virtual table */ |
912 | ){ |
913 | sqlite3_stmt *pStmt = 0; |
914 | char *zSql; |
915 | ShellText s; |
916 | char cQuote; |
917 | char *zDiv = "(" ; |
918 | int nRow = 0; |
919 | |
920 | zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;" , |
921 | zSchema ? zSchema : "main" , zName); |
922 | shell_check_oom(zSql); |
923 | sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
924 | sqlite3_free(zSql); |
925 | initText(&s); |
926 | if( zSchema ){ |
927 | cQuote = quoteChar(zSchema); |
928 | if( cQuote && sqlite3_stricmp(zSchema,"temp" )==0 ) cQuote = 0; |
929 | appendText(&s, zSchema, cQuote); |
930 | appendText(&s, "." , 0); |
931 | } |
932 | cQuote = quoteChar(zName); |
933 | appendText(&s, zName, cQuote); |
934 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
935 | const char *zCol = (const char*)sqlite3_column_text(pStmt, 1); |
936 | nRow++; |
937 | appendText(&s, zDiv, 0); |
938 | zDiv = "," ; |
939 | if( zCol==0 ) zCol = "" ; |
940 | cQuote = quoteChar(zCol); |
941 | appendText(&s, zCol, cQuote); |
942 | } |
943 | appendText(&s, ")" , 0); |
944 | sqlite3_finalize(pStmt); |
945 | if( nRow==0 ){ |
946 | freeText(&s); |
947 | s.z = 0; |
948 | } |
949 | return s.z; |
950 | } |
951 | |
952 | /* |
953 | ** SQL function: shell_module_schema(X) |
954 | ** |
955 | ** Return a fake schema for the table-valued function or eponymous virtual |
956 | ** table X. |
957 | */ |
958 | static void shellModuleSchema( |
959 | sqlite3_context *pCtx, |
960 | int nVal, |
961 | sqlite3_value **apVal |
962 | ){ |
963 | const char *zName; |
964 | char *zFake; |
965 | UNUSED_PARAMETER(nVal); |
966 | zName = (const char*)sqlite3_value_text(apVal[0]); |
967 | zFake = zName ? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0; |
968 | if( zFake ){ |
969 | sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */" , zFake), |
970 | -1, sqlite3_free); |
971 | free(zFake); |
972 | } |
973 | } |
974 | |
975 | /* |
976 | ** SQL function: shell_add_schema(S,X) |
977 | ** |
978 | ** Add the schema name X to the CREATE statement in S and return the result. |
979 | ** Examples: |
980 | ** |
981 | ** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x); |
982 | ** |
983 | ** Also works on |
984 | ** |
985 | ** CREATE INDEX |
986 | ** CREATE UNIQUE INDEX |
987 | ** CREATE VIEW |
988 | ** CREATE TRIGGER |
989 | ** CREATE VIRTUAL TABLE |
990 | ** |
991 | ** This UDF is used by the .schema command to insert the schema name of |
992 | ** attached databases into the middle of the sqlite_schema.sql field. |
993 | */ |
994 | static void shellAddSchemaName( |
995 | sqlite3_context *pCtx, |
996 | int nVal, |
997 | sqlite3_value **apVal |
998 | ){ |
999 | static const char *aPrefix[] = { |
1000 | "TABLE" , |
1001 | "INDEX" , |
1002 | "UNIQUE INDEX" , |
1003 | "VIEW" , |
1004 | "TRIGGER" , |
1005 | "VIRTUAL TABLE" |
1006 | }; |
1007 | int i = 0; |
1008 | const char *zIn = (const char*)sqlite3_value_text(apVal[0]); |
1009 | const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); |
1010 | const char *zName = (const char*)sqlite3_value_text(apVal[2]); |
1011 | sqlite3 *db = sqlite3_context_db_handle(pCtx); |
1012 | UNUSED_PARAMETER(nVal); |
1013 | if( zIn!=0 && cli_strncmp(zIn, "CREATE " , 7)==0 ){ |
1014 | for(i=0; i<ArraySize(aPrefix); i++){ |
1015 | int n = strlen30(aPrefix[i]); |
1016 | if( cli_strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){ |
1017 | char *z = 0; |
1018 | char *zFake = 0; |
1019 | if( zSchema ){ |
1020 | char cQuote = quoteChar(zSchema); |
1021 | if( cQuote && sqlite3_stricmp(zSchema,"temp" )!=0 ){ |
1022 | z = sqlite3_mprintf("%.*s \"%w\".%s" , n+7, zIn, zSchema, zIn+n+8); |
1023 | }else{ |
1024 | z = sqlite3_mprintf("%.*s %s.%s" , n+7, zIn, zSchema, zIn+n+8); |
1025 | } |
1026 | } |
1027 | if( zName |
1028 | && aPrefix[i][0]=='V' |
1029 | && (zFake = shellFakeSchema(db, zSchema, zName))!=0 |
1030 | ){ |
1031 | if( z==0 ){ |
1032 | z = sqlite3_mprintf("%s\n/* %s */" , zIn, zFake); |
1033 | }else{ |
1034 | z = sqlite3_mprintf("%z\n/* %s */" , z, zFake); |
1035 | } |
1036 | free(zFake); |
1037 | } |
1038 | if( z ){ |
1039 | sqlite3_result_text(pCtx, z, -1, sqlite3_free); |
1040 | return; |
1041 | } |
1042 | } |
1043 | } |
1044 | } |
1045 | sqlite3_result_value(pCtx, apVal[0]); |
1046 | } |
1047 | |
1048 | /* |
1049 | ** The source code for several run-time loadable extensions is inserted |
1050 | ** below by the ../tool/mkshellc.tcl script. Before processing that included |
1051 | ** code, we need to override some macros to make the included program code |
1052 | ** work here in the middle of this regular program. |
1053 | */ |
1054 | #define SQLITE_EXTENSION_INIT1 |
1055 | #define SQLITE_EXTENSION_INIT2(X) (void)(X) |
1056 | |
1057 | #if defined(_WIN32) && defined(_MSC_VER) |
1058 | /************************* Begin test_windirent.h ******************/ |
1059 | /* |
1060 | ** 2015 November 30 |
1061 | ** |
1062 | ** The author disclaims copyright to this source code. In place of |
1063 | ** a legal notice, here is a blessing: |
1064 | ** |
1065 | ** May you do good and not evil. |
1066 | ** May you find forgiveness for yourself and forgive others. |
1067 | ** May you share freely, never taking more than you give. |
1068 | ** |
1069 | ************************************************************************* |
1070 | ** This file contains declarations for most of the opendir() family of |
1071 | ** POSIX functions on Win32 using the MSVCRT. |
1072 | */ |
1073 | |
1074 | #if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H) |
1075 | #define SQLITE_WINDIRENT_H |
1076 | |
1077 | /* |
1078 | ** We need several data types from the Windows SDK header. |
1079 | */ |
1080 | |
1081 | #ifndef WIN32_LEAN_AND_MEAN |
1082 | #define WIN32_LEAN_AND_MEAN |
1083 | #endif |
1084 | |
1085 | #include "windows.h" |
1086 | |
1087 | /* |
1088 | ** We need several support functions from the SQLite core. |
1089 | */ |
1090 | |
1091 | /* #include "sqlite3.h" */ |
1092 | |
1093 | /* |
1094 | ** We need several things from the ANSI and MSVCRT headers. |
1095 | */ |
1096 | |
1097 | #include <stdio.h> |
1098 | #include <stdlib.h> |
1099 | #include <errno.h> |
1100 | #include <io.h> |
1101 | #include <limits.h> |
1102 | #include <sys/types.h> |
1103 | #include <sys/stat.h> |
1104 | |
1105 | /* |
1106 | ** We may need several defines that should have been in "sys/stat.h". |
1107 | */ |
1108 | |
1109 | #ifndef S_ISREG |
1110 | #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) |
1111 | #endif |
1112 | |
1113 | #ifndef S_ISDIR |
1114 | #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) |
1115 | #endif |
1116 | |
1117 | #ifndef S_ISLNK |
1118 | #define S_ISLNK(mode) (0) |
1119 | #endif |
1120 | |
1121 | /* |
1122 | ** We may need to provide the "mode_t" type. |
1123 | */ |
1124 | |
1125 | #ifndef MODE_T_DEFINED |
1126 | #define MODE_T_DEFINED |
1127 | typedef unsigned short mode_t; |
1128 | #endif |
1129 | |
1130 | /* |
1131 | ** We may need to provide the "ino_t" type. |
1132 | */ |
1133 | |
1134 | #ifndef INO_T_DEFINED |
1135 | #define INO_T_DEFINED |
1136 | typedef unsigned short ino_t; |
1137 | #endif |
1138 | |
1139 | /* |
1140 | ** We need to define "NAME_MAX" if it was not present in "limits.h". |
1141 | */ |
1142 | |
1143 | #ifndef NAME_MAX |
1144 | # ifdef FILENAME_MAX |
1145 | # define NAME_MAX (FILENAME_MAX) |
1146 | # else |
1147 | # define NAME_MAX (260) |
1148 | # endif |
1149 | #endif |
1150 | |
1151 | /* |
1152 | ** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T". |
1153 | */ |
1154 | |
1155 | #ifndef NULL_INTPTR_T |
1156 | # define NULL_INTPTR_T ((intptr_t)(0)) |
1157 | #endif |
1158 | |
1159 | #ifndef BAD_INTPTR_T |
1160 | # define BAD_INTPTR_T ((intptr_t)(-1)) |
1161 | #endif |
1162 | |
1163 | /* |
1164 | ** We need to provide the necessary structures and related types. |
1165 | */ |
1166 | |
1167 | #ifndef DIRENT_DEFINED |
1168 | #define DIRENT_DEFINED |
1169 | typedef struct DIRENT DIRENT; |
1170 | typedef DIRENT *LPDIRENT; |
1171 | struct DIRENT { |
1172 | ino_t d_ino; /* Sequence number, do not use. */ |
1173 | unsigned d_attributes; /* Win32 file attributes. */ |
1174 | char d_name[NAME_MAX + 1]; /* Name within the directory. */ |
1175 | }; |
1176 | #endif |
1177 | |
1178 | #ifndef DIR_DEFINED |
1179 | #define DIR_DEFINED |
1180 | typedef struct DIR DIR; |
1181 | typedef DIR *LPDIR; |
1182 | struct DIR { |
1183 | intptr_t d_handle; /* Value returned by "_findfirst". */ |
1184 | DIRENT d_first; /* DIRENT constructed based on "_findfirst". */ |
1185 | DIRENT d_next; /* DIRENT constructed based on "_findnext". */ |
1186 | }; |
1187 | #endif |
1188 | |
1189 | /* |
1190 | ** Provide a macro, for use by the implementation, to determine if a |
1191 | ** particular directory entry should be skipped over when searching for |
1192 | ** the next directory entry that should be returned by the readdir() or |
1193 | ** readdir_r() functions. |
1194 | */ |
1195 | |
1196 | #ifndef is_filtered |
1197 | # define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) |
1198 | #endif |
1199 | |
1200 | /* |
1201 | ** Provide the function prototype for the POSIX compatiable getenv() |
1202 | ** function. This function is not thread-safe. |
1203 | */ |
1204 | |
1205 | extern const char *windirent_getenv(const char *name); |
1206 | |
1207 | /* |
1208 | ** Finally, we can provide the function prototypes for the opendir(), |
1209 | ** readdir(), readdir_r(), and closedir() POSIX functions. |
1210 | */ |
1211 | |
1212 | extern LPDIR opendir(const char *dirname); |
1213 | extern LPDIRENT readdir(LPDIR dirp); |
1214 | extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result); |
1215 | extern INT closedir(LPDIR dirp); |
1216 | |
1217 | #endif /* defined(WIN32) && defined(_MSC_VER) */ |
1218 | |
1219 | /************************* End test_windirent.h ********************/ |
1220 | /************************* Begin test_windirent.c ******************/ |
1221 | /* |
1222 | ** 2015 November 30 |
1223 | ** |
1224 | ** The author disclaims copyright to this source code. In place of |
1225 | ** a legal notice, here is a blessing: |
1226 | ** |
1227 | ** May you do good and not evil. |
1228 | ** May you find forgiveness for yourself and forgive others. |
1229 | ** May you share freely, never taking more than you give. |
1230 | ** |
1231 | ************************************************************************* |
1232 | ** This file contains code to implement most of the opendir() family of |
1233 | ** POSIX functions on Win32 using the MSVCRT. |
1234 | */ |
1235 | |
1236 | #if defined(_WIN32) && defined(_MSC_VER) |
1237 | /* #include "test_windirent.h" */ |
1238 | |
1239 | /* |
1240 | ** Implementation of the POSIX getenv() function using the Win32 API. |
1241 | ** This function is not thread-safe. |
1242 | */ |
1243 | const char *windirent_getenv( |
1244 | const char *name |
1245 | ){ |
1246 | static char value[32768]; /* Maximum length, per MSDN */ |
1247 | DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */ |
1248 | DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */ |
1249 | |
1250 | memset(value, 0, sizeof(value)); |
1251 | dwRet = GetEnvironmentVariableA(name, value, dwSize); |
1252 | if( dwRet==0 || dwRet>dwSize ){ |
1253 | /* |
1254 | ** The function call to GetEnvironmentVariableA() failed -OR- |
1255 | ** the buffer is not large enough. Either way, return NULL. |
1256 | */ |
1257 | return 0; |
1258 | }else{ |
1259 | /* |
1260 | ** The function call to GetEnvironmentVariableA() succeeded |
1261 | ** -AND- the buffer contains the entire value. |
1262 | */ |
1263 | return value; |
1264 | } |
1265 | } |
1266 | |
1267 | /* |
1268 | ** Implementation of the POSIX opendir() function using the MSVCRT. |
1269 | */ |
1270 | LPDIR opendir( |
1271 | const char *dirname |
1272 | ){ |
1273 | struct _finddata_t data; |
1274 | LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR)); |
1275 | SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]); |
1276 | |
1277 | if( dirp==NULL ) return NULL; |
1278 | memset(dirp, 0, sizeof(DIR)); |
1279 | |
1280 | /* TODO: Remove this if Unix-style root paths are not used. */ |
1281 | if( sqlite3_stricmp(dirname, "/" )==0 ){ |
1282 | dirname = windirent_getenv("SystemDrive" ); |
1283 | } |
1284 | |
1285 | memset(&data, 0, sizeof(struct _finddata_t)); |
1286 | _snprintf(data.name, namesize, "%s\\*" , dirname); |
1287 | dirp->d_handle = _findfirst(data.name, &data); |
1288 | |
1289 | if( dirp->d_handle==BAD_INTPTR_T ){ |
1290 | closedir(dirp); |
1291 | return NULL; |
1292 | } |
1293 | |
1294 | /* TODO: Remove this block to allow hidden and/or system files. */ |
1295 | if( is_filtered(data) ){ |
1296 | next: |
1297 | |
1298 | memset(&data, 0, sizeof(struct _finddata_t)); |
1299 | if( _findnext(dirp->d_handle, &data)==-1 ){ |
1300 | closedir(dirp); |
1301 | return NULL; |
1302 | } |
1303 | |
1304 | /* TODO: Remove this block to allow hidden and/or system files. */ |
1305 | if( is_filtered(data) ) goto next; |
1306 | } |
1307 | |
1308 | dirp->d_first.d_attributes = data.attrib; |
1309 | strncpy(dirp->d_first.d_name, data.name, NAME_MAX); |
1310 | dirp->d_first.d_name[NAME_MAX] = '\0'; |
1311 | |
1312 | return dirp; |
1313 | } |
1314 | |
1315 | /* |
1316 | ** Implementation of the POSIX readdir() function using the MSVCRT. |
1317 | */ |
1318 | LPDIRENT readdir( |
1319 | LPDIR dirp |
1320 | ){ |
1321 | struct _finddata_t data; |
1322 | |
1323 | if( dirp==NULL ) return NULL; |
1324 | |
1325 | if( dirp->d_first.d_ino==0 ){ |
1326 | dirp->d_first.d_ino++; |
1327 | dirp->d_next.d_ino++; |
1328 | |
1329 | return &dirp->d_first; |
1330 | } |
1331 | |
1332 | next: |
1333 | |
1334 | memset(&data, 0, sizeof(struct _finddata_t)); |
1335 | if( _findnext(dirp->d_handle, &data)==-1 ) return NULL; |
1336 | |
1337 | /* TODO: Remove this block to allow hidden and/or system files. */ |
1338 | if( is_filtered(data) ) goto next; |
1339 | |
1340 | dirp->d_next.d_ino++; |
1341 | dirp->d_next.d_attributes = data.attrib; |
1342 | strncpy(dirp->d_next.d_name, data.name, NAME_MAX); |
1343 | dirp->d_next.d_name[NAME_MAX] = '\0'; |
1344 | |
1345 | return &dirp->d_next; |
1346 | } |
1347 | |
1348 | /* |
1349 | ** Implementation of the POSIX readdir_r() function using the MSVCRT. |
1350 | */ |
1351 | INT readdir_r( |
1352 | LPDIR dirp, |
1353 | LPDIRENT entry, |
1354 | LPDIRENT *result |
1355 | ){ |
1356 | struct _finddata_t data; |
1357 | |
1358 | if( dirp==NULL ) return EBADF; |
1359 | |
1360 | if( dirp->d_first.d_ino==0 ){ |
1361 | dirp->d_first.d_ino++; |
1362 | dirp->d_next.d_ino++; |
1363 | |
1364 | entry->d_ino = dirp->d_first.d_ino; |
1365 | entry->d_attributes = dirp->d_first.d_attributes; |
1366 | strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX); |
1367 | entry->d_name[NAME_MAX] = '\0'; |
1368 | |
1369 | *result = entry; |
1370 | return 0; |
1371 | } |
1372 | |
1373 | next: |
1374 | |
1375 | memset(&data, 0, sizeof(struct _finddata_t)); |
1376 | if( _findnext(dirp->d_handle, &data)==-1 ){ |
1377 | *result = NULL; |
1378 | return ENOENT; |
1379 | } |
1380 | |
1381 | /* TODO: Remove this block to allow hidden and/or system files. */ |
1382 | if( is_filtered(data) ) goto next; |
1383 | |
1384 | entry->d_ino = (ino_t)-1; /* not available */ |
1385 | entry->d_attributes = data.attrib; |
1386 | strncpy(entry->d_name, data.name, NAME_MAX); |
1387 | entry->d_name[NAME_MAX] = '\0'; |
1388 | |
1389 | *result = entry; |
1390 | return 0; |
1391 | } |
1392 | |
1393 | /* |
1394 | ** Implementation of the POSIX closedir() function using the MSVCRT. |
1395 | */ |
1396 | INT closedir( |
1397 | LPDIR dirp |
1398 | ){ |
1399 | INT result = 0; |
1400 | |
1401 | if( dirp==NULL ) return EINVAL; |
1402 | |
1403 | if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){ |
1404 | result = _findclose(dirp->d_handle); |
1405 | } |
1406 | |
1407 | sqlite3_free(dirp); |
1408 | return result; |
1409 | } |
1410 | |
1411 | #endif /* defined(WIN32) && defined(_MSC_VER) */ |
1412 | |
1413 | /************************* End test_windirent.c ********************/ |
1414 | #define dirent DIRENT |
1415 | #endif |
1416 | /************************* Begin ../ext/misc/memtrace.c ******************/ |
1417 | /* |
1418 | ** 2019-01-21 |
1419 | ** |
1420 | ** The author disclaims copyright to this source code. In place of |
1421 | ** a legal notice, here is a blessing: |
1422 | ** |
1423 | ** May you do good and not evil. |
1424 | ** May you find forgiveness for yourself and forgive others. |
1425 | ** May you share freely, never taking more than you give. |
1426 | ** |
1427 | ************************************************************************* |
1428 | ** |
1429 | ** This file implements an extension that uses the SQLITE_CONFIG_MALLOC |
1430 | ** mechanism to add a tracing layer on top of SQLite. If this extension |
1431 | ** is registered prior to sqlite3_initialize(), it will cause all memory |
1432 | ** allocation activities to be logged on standard output, or to some other |
1433 | ** FILE specified by the initializer. |
1434 | ** |
1435 | ** This file needs to be compiled into the application that uses it. |
1436 | ** |
1437 | ** This extension is used to implement the --memtrace option of the |
1438 | ** command-line shell. |
1439 | */ |
1440 | #include <assert.h> |
1441 | #include <string.h> |
1442 | #include <stdio.h> |
1443 | |
1444 | /* The original memory allocation routines */ |
1445 | static sqlite3_mem_methods memtraceBase; |
1446 | static FILE *memtraceOut; |
1447 | |
1448 | /* Methods that trace memory allocations */ |
1449 | static void *memtraceMalloc(int n){ |
1450 | if( memtraceOut ){ |
1451 | fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n" , |
1452 | memtraceBase.xRoundup(n)); |
1453 | } |
1454 | return memtraceBase.xMalloc(n); |
1455 | } |
1456 | static void memtraceFree(void *p){ |
1457 | if( p==0 ) return; |
1458 | if( memtraceOut ){ |
1459 | fprintf(memtraceOut, "MEMTRACE: free %d bytes\n" , memtraceBase.xSize(p)); |
1460 | } |
1461 | memtraceBase.xFree(p); |
1462 | } |
1463 | static void *memtraceRealloc(void *p, int n){ |
1464 | if( p==0 ) return memtraceMalloc(n); |
1465 | if( n==0 ){ |
1466 | memtraceFree(p); |
1467 | return 0; |
1468 | } |
1469 | if( memtraceOut ){ |
1470 | fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n" , |
1471 | memtraceBase.xSize(p), memtraceBase.xRoundup(n)); |
1472 | } |
1473 | return memtraceBase.xRealloc(p, n); |
1474 | } |
1475 | static int memtraceSize(void *p){ |
1476 | return memtraceBase.xSize(p); |
1477 | } |
1478 | static int memtraceRoundup(int n){ |
1479 | return memtraceBase.xRoundup(n); |
1480 | } |
1481 | static int memtraceInit(void *p){ |
1482 | return memtraceBase.xInit(p); |
1483 | } |
1484 | static void memtraceShutdown(void *p){ |
1485 | memtraceBase.xShutdown(p); |
1486 | } |
1487 | |
1488 | /* The substitute memory allocator */ |
1489 | static sqlite3_mem_methods ersaztMethods = { |
1490 | memtraceMalloc, |
1491 | memtraceFree, |
1492 | memtraceRealloc, |
1493 | memtraceSize, |
1494 | memtraceRoundup, |
1495 | memtraceInit, |
1496 | memtraceShutdown, |
1497 | 0 |
1498 | }; |
1499 | |
1500 | /* Begin tracing memory allocations to out. */ |
1501 | int sqlite3MemTraceActivate(FILE *out){ |
1502 | int rc = SQLITE_OK; |
1503 | if( memtraceBase.xMalloc==0 ){ |
1504 | rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase); |
1505 | if( rc==SQLITE_OK ){ |
1506 | rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods); |
1507 | } |
1508 | } |
1509 | memtraceOut = out; |
1510 | return rc; |
1511 | } |
1512 | |
1513 | /* Deactivate memory tracing */ |
1514 | int sqlite3MemTraceDeactivate(void){ |
1515 | int rc = SQLITE_OK; |
1516 | if( memtraceBase.xMalloc!=0 ){ |
1517 | rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase); |
1518 | if( rc==SQLITE_OK ){ |
1519 | memset(&memtraceBase, 0, sizeof(memtraceBase)); |
1520 | } |
1521 | } |
1522 | memtraceOut = 0; |
1523 | return rc; |
1524 | } |
1525 | |
1526 | /************************* End ../ext/misc/memtrace.c ********************/ |
1527 | /************************* Begin ../ext/misc/shathree.c ******************/ |
1528 | /* |
1529 | ** 2017-03-08 |
1530 | ** |
1531 | ** The author disclaims copyright to this source code. In place of |
1532 | ** a legal notice, here is a blessing: |
1533 | ** |
1534 | ** May you do good and not evil. |
1535 | ** May you find forgiveness for yourself and forgive others. |
1536 | ** May you share freely, never taking more than you give. |
1537 | ** |
1538 | ****************************************************************************** |
1539 | ** |
1540 | ** This SQLite extension implements functions that compute SHA3 hashes. |
1541 | ** Two SQL functions are implemented: |
1542 | ** |
1543 | ** sha3(X,SIZE) |
1544 | ** sha3_query(Y,SIZE) |
1545 | ** |
1546 | ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if |
1547 | ** X is NULL. |
1548 | ** |
1549 | ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y |
1550 | ** and returns a hash of their results. |
1551 | ** |
1552 | ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm |
1553 | ** is used. If SIZE is included it must be one of the integers 224, 256, |
1554 | ** 384, or 512, to determine SHA3 hash variant that is computed. |
1555 | */ |
1556 | /* #include "sqlite3ext.h" */ |
1557 | SQLITE_EXTENSION_INIT1 |
1558 | #include <assert.h> |
1559 | #include <string.h> |
1560 | #include <stdarg.h> |
1561 | |
1562 | #ifndef SQLITE_AMALGAMATION |
1563 | /* typedef sqlite3_uint64 u64; */ |
1564 | #endif /* SQLITE_AMALGAMATION */ |
1565 | |
1566 | /****************************************************************************** |
1567 | ** The Hash Engine |
1568 | */ |
1569 | /* |
1570 | ** Macros to determine whether the machine is big or little endian, |
1571 | ** and whether or not that determination is run-time or compile-time. |
1572 | ** |
1573 | ** For best performance, an attempt is made to guess at the byte-order |
1574 | ** using C-preprocessor macros. If that is unsuccessful, or if |
1575 | ** -DSHA3_BYTEORDER=0 is set, then byte-order is determined |
1576 | ** at run-time. |
1577 | */ |
1578 | #ifndef SHA3_BYTEORDER |
1579 | # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ |
1580 | defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ |
1581 | defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ |
1582 | defined(__arm__) |
1583 | # define SHA3_BYTEORDER 1234 |
1584 | # elif defined(sparc) || defined(__ppc__) |
1585 | # define SHA3_BYTEORDER 4321 |
1586 | # else |
1587 | # define SHA3_BYTEORDER 0 |
1588 | # endif |
1589 | #endif |
1590 | |
1591 | |
1592 | /* |
1593 | ** State structure for a SHA3 hash in progress |
1594 | */ |
1595 | typedef struct SHA3Context SHA3Context; |
1596 | struct SHA3Context { |
1597 | union { |
1598 | u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ |
1599 | unsigned char x[1600]; /* ... or 1600 bytes */ |
1600 | } u; |
1601 | unsigned nRate; /* Bytes of input accepted per Keccak iteration */ |
1602 | unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ |
1603 | unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ |
1604 | }; |
1605 | |
1606 | /* |
1607 | ** A single step of the Keccak mixing function for a 1600-bit state |
1608 | */ |
1609 | static void KeccakF1600Step(SHA3Context *p){ |
1610 | int i; |
1611 | u64 b0, b1, b2, b3, b4; |
1612 | u64 c0, c1, c2, c3, c4; |
1613 | u64 d0, d1, d2, d3, d4; |
1614 | static const u64 RC[] = { |
1615 | 0x0000000000000001ULL, 0x0000000000008082ULL, |
1616 | 0x800000000000808aULL, 0x8000000080008000ULL, |
1617 | 0x000000000000808bULL, 0x0000000080000001ULL, |
1618 | 0x8000000080008081ULL, 0x8000000000008009ULL, |
1619 | 0x000000000000008aULL, 0x0000000000000088ULL, |
1620 | 0x0000000080008009ULL, 0x000000008000000aULL, |
1621 | 0x000000008000808bULL, 0x800000000000008bULL, |
1622 | 0x8000000000008089ULL, 0x8000000000008003ULL, |
1623 | 0x8000000000008002ULL, 0x8000000000000080ULL, |
1624 | 0x000000000000800aULL, 0x800000008000000aULL, |
1625 | 0x8000000080008081ULL, 0x8000000000008080ULL, |
1626 | 0x0000000080000001ULL, 0x8000000080008008ULL |
1627 | }; |
1628 | # define a00 (p->u.s[0]) |
1629 | # define a01 (p->u.s[1]) |
1630 | # define a02 (p->u.s[2]) |
1631 | # define a03 (p->u.s[3]) |
1632 | # define a04 (p->u.s[4]) |
1633 | # define a10 (p->u.s[5]) |
1634 | # define a11 (p->u.s[6]) |
1635 | # define a12 (p->u.s[7]) |
1636 | # define a13 (p->u.s[8]) |
1637 | # define a14 (p->u.s[9]) |
1638 | # define a20 (p->u.s[10]) |
1639 | # define a21 (p->u.s[11]) |
1640 | # define a22 (p->u.s[12]) |
1641 | # define a23 (p->u.s[13]) |
1642 | # define a24 (p->u.s[14]) |
1643 | # define a30 (p->u.s[15]) |
1644 | # define a31 (p->u.s[16]) |
1645 | # define a32 (p->u.s[17]) |
1646 | # define a33 (p->u.s[18]) |
1647 | # define a34 (p->u.s[19]) |
1648 | # define a40 (p->u.s[20]) |
1649 | # define a41 (p->u.s[21]) |
1650 | # define a42 (p->u.s[22]) |
1651 | # define a43 (p->u.s[23]) |
1652 | # define a44 (p->u.s[24]) |
1653 | # define ROL64(a,x) ((a<<x)|(a>>(64-x))) |
1654 | |
1655 | for(i=0; i<24; i+=4){ |
1656 | c0 = a00^a10^a20^a30^a40; |
1657 | c1 = a01^a11^a21^a31^a41; |
1658 | c2 = a02^a12^a22^a32^a42; |
1659 | c3 = a03^a13^a23^a33^a43; |
1660 | c4 = a04^a14^a24^a34^a44; |
1661 | d0 = c4^ROL64(c1, 1); |
1662 | d1 = c0^ROL64(c2, 1); |
1663 | d2 = c1^ROL64(c3, 1); |
1664 | d3 = c2^ROL64(c4, 1); |
1665 | d4 = c3^ROL64(c0, 1); |
1666 | |
1667 | b0 = (a00^d0); |
1668 | b1 = ROL64((a11^d1), 44); |
1669 | b2 = ROL64((a22^d2), 43); |
1670 | b3 = ROL64((a33^d3), 21); |
1671 | b4 = ROL64((a44^d4), 14); |
1672 | a00 = b0 ^((~b1)& b2 ); |
1673 | a00 ^= RC[i]; |
1674 | a11 = b1 ^((~b2)& b3 ); |
1675 | a22 = b2 ^((~b3)& b4 ); |
1676 | a33 = b3 ^((~b4)& b0 ); |
1677 | a44 = b4 ^((~b0)& b1 ); |
1678 | |
1679 | b2 = ROL64((a20^d0), 3); |
1680 | b3 = ROL64((a31^d1), 45); |
1681 | b4 = ROL64((a42^d2), 61); |
1682 | b0 = ROL64((a03^d3), 28); |
1683 | b1 = ROL64((a14^d4), 20); |
1684 | a20 = b0 ^((~b1)& b2 ); |
1685 | a31 = b1 ^((~b2)& b3 ); |
1686 | a42 = b2 ^((~b3)& b4 ); |
1687 | a03 = b3 ^((~b4)& b0 ); |
1688 | a14 = b4 ^((~b0)& b1 ); |
1689 | |
1690 | b4 = ROL64((a40^d0), 18); |
1691 | b0 = ROL64((a01^d1), 1); |
1692 | b1 = ROL64((a12^d2), 6); |
1693 | b2 = ROL64((a23^d3), 25); |
1694 | b3 = ROL64((a34^d4), 8); |
1695 | a40 = b0 ^((~b1)& b2 ); |
1696 | a01 = b1 ^((~b2)& b3 ); |
1697 | a12 = b2 ^((~b3)& b4 ); |
1698 | a23 = b3 ^((~b4)& b0 ); |
1699 | a34 = b4 ^((~b0)& b1 ); |
1700 | |
1701 | b1 = ROL64((a10^d0), 36); |
1702 | b2 = ROL64((a21^d1), 10); |
1703 | b3 = ROL64((a32^d2), 15); |
1704 | b4 = ROL64((a43^d3), 56); |
1705 | b0 = ROL64((a04^d4), 27); |
1706 | a10 = b0 ^((~b1)& b2 ); |
1707 | a21 = b1 ^((~b2)& b3 ); |
1708 | a32 = b2 ^((~b3)& b4 ); |
1709 | a43 = b3 ^((~b4)& b0 ); |
1710 | a04 = b4 ^((~b0)& b1 ); |
1711 | |
1712 | b3 = ROL64((a30^d0), 41); |
1713 | b4 = ROL64((a41^d1), 2); |
1714 | b0 = ROL64((a02^d2), 62); |
1715 | b1 = ROL64((a13^d3), 55); |
1716 | b2 = ROL64((a24^d4), 39); |
1717 | a30 = b0 ^((~b1)& b2 ); |
1718 | a41 = b1 ^((~b2)& b3 ); |
1719 | a02 = b2 ^((~b3)& b4 ); |
1720 | a13 = b3 ^((~b4)& b0 ); |
1721 | a24 = b4 ^((~b0)& b1 ); |
1722 | |
1723 | c0 = a00^a20^a40^a10^a30; |
1724 | c1 = a11^a31^a01^a21^a41; |
1725 | c2 = a22^a42^a12^a32^a02; |
1726 | c3 = a33^a03^a23^a43^a13; |
1727 | c4 = a44^a14^a34^a04^a24; |
1728 | d0 = c4^ROL64(c1, 1); |
1729 | d1 = c0^ROL64(c2, 1); |
1730 | d2 = c1^ROL64(c3, 1); |
1731 | d3 = c2^ROL64(c4, 1); |
1732 | d4 = c3^ROL64(c0, 1); |
1733 | |
1734 | b0 = (a00^d0); |
1735 | b1 = ROL64((a31^d1), 44); |
1736 | b2 = ROL64((a12^d2), 43); |
1737 | b3 = ROL64((a43^d3), 21); |
1738 | b4 = ROL64((a24^d4), 14); |
1739 | a00 = b0 ^((~b1)& b2 ); |
1740 | a00 ^= RC[i+1]; |
1741 | a31 = b1 ^((~b2)& b3 ); |
1742 | a12 = b2 ^((~b3)& b4 ); |
1743 | a43 = b3 ^((~b4)& b0 ); |
1744 | a24 = b4 ^((~b0)& b1 ); |
1745 | |
1746 | b2 = ROL64((a40^d0), 3); |
1747 | b3 = ROL64((a21^d1), 45); |
1748 | b4 = ROL64((a02^d2), 61); |
1749 | b0 = ROL64((a33^d3), 28); |
1750 | b1 = ROL64((a14^d4), 20); |
1751 | a40 = b0 ^((~b1)& b2 ); |
1752 | a21 = b1 ^((~b2)& b3 ); |
1753 | a02 = b2 ^((~b3)& b4 ); |
1754 | a33 = b3 ^((~b4)& b0 ); |
1755 | a14 = b4 ^((~b0)& b1 ); |
1756 | |
1757 | b4 = ROL64((a30^d0), 18); |
1758 | b0 = ROL64((a11^d1), 1); |
1759 | b1 = ROL64((a42^d2), 6); |
1760 | b2 = ROL64((a23^d3), 25); |
1761 | b3 = ROL64((a04^d4), 8); |
1762 | a30 = b0 ^((~b1)& b2 ); |
1763 | a11 = b1 ^((~b2)& b3 ); |
1764 | a42 = b2 ^((~b3)& b4 ); |
1765 | a23 = b3 ^((~b4)& b0 ); |
1766 | a04 = b4 ^((~b0)& b1 ); |
1767 | |
1768 | b1 = ROL64((a20^d0), 36); |
1769 | b2 = ROL64((a01^d1), 10); |
1770 | b3 = ROL64((a32^d2), 15); |
1771 | b4 = ROL64((a13^d3), 56); |
1772 | b0 = ROL64((a44^d4), 27); |
1773 | a20 = b0 ^((~b1)& b2 ); |
1774 | a01 = b1 ^((~b2)& b3 ); |
1775 | a32 = b2 ^((~b3)& b4 ); |
1776 | a13 = b3 ^((~b4)& b0 ); |
1777 | a44 = b4 ^((~b0)& b1 ); |
1778 | |
1779 | b3 = ROL64((a10^d0), 41); |
1780 | b4 = ROL64((a41^d1), 2); |
1781 | b0 = ROL64((a22^d2), 62); |
1782 | b1 = ROL64((a03^d3), 55); |
1783 | b2 = ROL64((a34^d4), 39); |
1784 | a10 = b0 ^((~b1)& b2 ); |
1785 | a41 = b1 ^((~b2)& b3 ); |
1786 | a22 = b2 ^((~b3)& b4 ); |
1787 | a03 = b3 ^((~b4)& b0 ); |
1788 | a34 = b4 ^((~b0)& b1 ); |
1789 | |
1790 | c0 = a00^a40^a30^a20^a10; |
1791 | c1 = a31^a21^a11^a01^a41; |
1792 | c2 = a12^a02^a42^a32^a22; |
1793 | c3 = a43^a33^a23^a13^a03; |
1794 | c4 = a24^a14^a04^a44^a34; |
1795 | d0 = c4^ROL64(c1, 1); |
1796 | d1 = c0^ROL64(c2, 1); |
1797 | d2 = c1^ROL64(c3, 1); |
1798 | d3 = c2^ROL64(c4, 1); |
1799 | d4 = c3^ROL64(c0, 1); |
1800 | |
1801 | b0 = (a00^d0); |
1802 | b1 = ROL64((a21^d1), 44); |
1803 | b2 = ROL64((a42^d2), 43); |
1804 | b3 = ROL64((a13^d3), 21); |
1805 | b4 = ROL64((a34^d4), 14); |
1806 | a00 = b0 ^((~b1)& b2 ); |
1807 | a00 ^= RC[i+2]; |
1808 | a21 = b1 ^((~b2)& b3 ); |
1809 | a42 = b2 ^((~b3)& b4 ); |
1810 | a13 = b3 ^((~b4)& b0 ); |
1811 | a34 = b4 ^((~b0)& b1 ); |
1812 | |
1813 | b2 = ROL64((a30^d0), 3); |
1814 | b3 = ROL64((a01^d1), 45); |
1815 | b4 = ROL64((a22^d2), 61); |
1816 | b0 = ROL64((a43^d3), 28); |
1817 | b1 = ROL64((a14^d4), 20); |
1818 | a30 = b0 ^((~b1)& b2 ); |
1819 | a01 = b1 ^((~b2)& b3 ); |
1820 | a22 = b2 ^((~b3)& b4 ); |
1821 | a43 = b3 ^((~b4)& b0 ); |
1822 | a14 = b4 ^((~b0)& b1 ); |
1823 | |
1824 | b4 = ROL64((a10^d0), 18); |
1825 | b0 = ROL64((a31^d1), 1); |
1826 | b1 = ROL64((a02^d2), 6); |
1827 | b2 = ROL64((a23^d3), 25); |
1828 | b3 = ROL64((a44^d4), 8); |
1829 | a10 = b0 ^((~b1)& b2 ); |
1830 | a31 = b1 ^((~b2)& b3 ); |
1831 | a02 = b2 ^((~b3)& b4 ); |
1832 | a23 = b3 ^((~b4)& b0 ); |
1833 | a44 = b4 ^((~b0)& b1 ); |
1834 | |
1835 | b1 = ROL64((a40^d0), 36); |
1836 | b2 = ROL64((a11^d1), 10); |
1837 | b3 = ROL64((a32^d2), 15); |
1838 | b4 = ROL64((a03^d3), 56); |
1839 | b0 = ROL64((a24^d4), 27); |
1840 | a40 = b0 ^((~b1)& b2 ); |
1841 | a11 = b1 ^((~b2)& b3 ); |
1842 | a32 = b2 ^((~b3)& b4 ); |
1843 | a03 = b3 ^((~b4)& b0 ); |
1844 | a24 = b4 ^((~b0)& b1 ); |
1845 | |
1846 | b3 = ROL64((a20^d0), 41); |
1847 | b4 = ROL64((a41^d1), 2); |
1848 | b0 = ROL64((a12^d2), 62); |
1849 | b1 = ROL64((a33^d3), 55); |
1850 | b2 = ROL64((a04^d4), 39); |
1851 | a20 = b0 ^((~b1)& b2 ); |
1852 | a41 = b1 ^((~b2)& b3 ); |
1853 | a12 = b2 ^((~b3)& b4 ); |
1854 | a33 = b3 ^((~b4)& b0 ); |
1855 | a04 = b4 ^((~b0)& b1 ); |
1856 | |
1857 | c0 = a00^a30^a10^a40^a20; |
1858 | c1 = a21^a01^a31^a11^a41; |
1859 | c2 = a42^a22^a02^a32^a12; |
1860 | c3 = a13^a43^a23^a03^a33; |
1861 | c4 = a34^a14^a44^a24^a04; |
1862 | d0 = c4^ROL64(c1, 1); |
1863 | d1 = c0^ROL64(c2, 1); |
1864 | d2 = c1^ROL64(c3, 1); |
1865 | d3 = c2^ROL64(c4, 1); |
1866 | d4 = c3^ROL64(c0, 1); |
1867 | |
1868 | b0 = (a00^d0); |
1869 | b1 = ROL64((a01^d1), 44); |
1870 | b2 = ROL64((a02^d2), 43); |
1871 | b3 = ROL64((a03^d3), 21); |
1872 | b4 = ROL64((a04^d4), 14); |
1873 | a00 = b0 ^((~b1)& b2 ); |
1874 | a00 ^= RC[i+3]; |
1875 | a01 = b1 ^((~b2)& b3 ); |
1876 | a02 = b2 ^((~b3)& b4 ); |
1877 | a03 = b3 ^((~b4)& b0 ); |
1878 | a04 = b4 ^((~b0)& b1 ); |
1879 | |
1880 | b2 = ROL64((a10^d0), 3); |
1881 | b3 = ROL64((a11^d1), 45); |
1882 | b4 = ROL64((a12^d2), 61); |
1883 | b0 = ROL64((a13^d3), 28); |
1884 | b1 = ROL64((a14^d4), 20); |
1885 | a10 = b0 ^((~b1)& b2 ); |
1886 | a11 = b1 ^((~b2)& b3 ); |
1887 | a12 = b2 ^((~b3)& b4 ); |
1888 | a13 = b3 ^((~b4)& b0 ); |
1889 | a14 = b4 ^((~b0)& b1 ); |
1890 | |
1891 | b4 = ROL64((a20^d0), 18); |
1892 | b0 = ROL64((a21^d1), 1); |
1893 | b1 = ROL64((a22^d2), 6); |
1894 | b2 = ROL64((a23^d3), 25); |
1895 | b3 = ROL64((a24^d4), 8); |
1896 | a20 = b0 ^((~b1)& b2 ); |
1897 | a21 = b1 ^((~b2)& b3 ); |
1898 | a22 = b2 ^((~b3)& b4 ); |
1899 | a23 = b3 ^((~b4)& b0 ); |
1900 | a24 = b4 ^((~b0)& b1 ); |
1901 | |
1902 | b1 = ROL64((a30^d0), 36); |
1903 | b2 = ROL64((a31^d1), 10); |
1904 | b3 = ROL64((a32^d2), 15); |
1905 | b4 = ROL64((a33^d3), 56); |
1906 | b0 = ROL64((a34^d4), 27); |
1907 | a30 = b0 ^((~b1)& b2 ); |
1908 | a31 = b1 ^((~b2)& b3 ); |
1909 | a32 = b2 ^((~b3)& b4 ); |
1910 | a33 = b3 ^((~b4)& b0 ); |
1911 | a34 = b4 ^((~b0)& b1 ); |
1912 | |
1913 | b3 = ROL64((a40^d0), 41); |
1914 | b4 = ROL64((a41^d1), 2); |
1915 | b0 = ROL64((a42^d2), 62); |
1916 | b1 = ROL64((a43^d3), 55); |
1917 | b2 = ROL64((a44^d4), 39); |
1918 | a40 = b0 ^((~b1)& b2 ); |
1919 | a41 = b1 ^((~b2)& b3 ); |
1920 | a42 = b2 ^((~b3)& b4 ); |
1921 | a43 = b3 ^((~b4)& b0 ); |
1922 | a44 = b4 ^((~b0)& b1 ); |
1923 | } |
1924 | } |
1925 | |
1926 | /* |
1927 | ** Initialize a new hash. iSize determines the size of the hash |
1928 | ** in bits and should be one of 224, 256, 384, or 512. Or iSize |
1929 | ** can be zero to use the default hash size of 256 bits. |
1930 | */ |
1931 | static void SHA3Init(SHA3Context *p, int iSize){ |
1932 | memset(p, 0, sizeof(*p)); |
1933 | if( iSize>=128 && iSize<=512 ){ |
1934 | p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; |
1935 | }else{ |
1936 | p->nRate = (1600 - 2*256)/8; |
1937 | } |
1938 | #if SHA3_BYTEORDER==1234 |
1939 | /* Known to be little-endian at compile-time. No-op */ |
1940 | #elif SHA3_BYTEORDER==4321 |
1941 | p->ixMask = 7; /* Big-endian */ |
1942 | #else |
1943 | { |
1944 | static unsigned int one = 1; |
1945 | if( 1==*(unsigned char*)&one ){ |
1946 | /* Little endian. No byte swapping. */ |
1947 | p->ixMask = 0; |
1948 | }else{ |
1949 | /* Big endian. Byte swap. */ |
1950 | p->ixMask = 7; |
1951 | } |
1952 | } |
1953 | #endif |
1954 | } |
1955 | |
1956 | /* |
1957 | ** Make consecutive calls to the SHA3Update function to add new content |
1958 | ** to the hash |
1959 | */ |
1960 | static void SHA3Update( |
1961 | SHA3Context *p, |
1962 | const unsigned char *aData, |
1963 | unsigned int nData |
1964 | ){ |
1965 | unsigned int i = 0; |
1966 | if( aData==0 ) return; |
1967 | #if SHA3_BYTEORDER==1234 |
1968 | if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ |
1969 | for(; i+7<nData; i+=8){ |
1970 | p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; |
1971 | p->nLoaded += 8; |
1972 | if( p->nLoaded>=p->nRate ){ |
1973 | KeccakF1600Step(p); |
1974 | p->nLoaded = 0; |
1975 | } |
1976 | } |
1977 | } |
1978 | #endif |
1979 | for(; i<nData; i++){ |
1980 | #if SHA3_BYTEORDER==1234 |
1981 | p->u.x[p->nLoaded] ^= aData[i]; |
1982 | #elif SHA3_BYTEORDER==4321 |
1983 | p->u.x[p->nLoaded^0x07] ^= aData[i]; |
1984 | #else |
1985 | p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; |
1986 | #endif |
1987 | p->nLoaded++; |
1988 | if( p->nLoaded==p->nRate ){ |
1989 | KeccakF1600Step(p); |
1990 | p->nLoaded = 0; |
1991 | } |
1992 | } |
1993 | } |
1994 | |
1995 | /* |
1996 | ** After all content has been added, invoke SHA3Final() to compute |
1997 | ** the final hash. The function returns a pointer to the binary |
1998 | ** hash value. |
1999 | */ |
2000 | static unsigned char *SHA3Final(SHA3Context *p){ |
2001 | unsigned int i; |
2002 | if( p->nLoaded==p->nRate-1 ){ |
2003 | const unsigned char c1 = 0x86; |
2004 | SHA3Update(p, &c1, 1); |
2005 | }else{ |
2006 | const unsigned char c2 = 0x06; |
2007 | const unsigned char c3 = 0x80; |
2008 | SHA3Update(p, &c2, 1); |
2009 | p->nLoaded = p->nRate - 1; |
2010 | SHA3Update(p, &c3, 1); |
2011 | } |
2012 | for(i=0; i<p->nRate; i++){ |
2013 | p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; |
2014 | } |
2015 | return &p->u.x[p->nRate]; |
2016 | } |
2017 | /* End of the hashing logic |
2018 | *****************************************************************************/ |
2019 | |
2020 | /* |
2021 | ** Implementation of the sha3(X,SIZE) function. |
2022 | ** |
2023 | ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default |
2024 | ** size is 256. If X is a BLOB, it is hashed as is. |
2025 | ** For all other non-NULL types of input, X is converted into a UTF-8 string |
2026 | ** and the string is hashed without the trailing 0x00 terminator. The hash |
2027 | ** of a NULL value is NULL. |
2028 | */ |
2029 | static void sha3Func( |
2030 | sqlite3_context *context, |
2031 | int argc, |
2032 | sqlite3_value **argv |
2033 | ){ |
2034 | SHA3Context cx; |
2035 | int eType = sqlite3_value_type(argv[0]); |
2036 | int nByte = sqlite3_value_bytes(argv[0]); |
2037 | int iSize; |
2038 | if( argc==1 ){ |
2039 | iSize = 256; |
2040 | }else{ |
2041 | iSize = sqlite3_value_int(argv[1]); |
2042 | if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ |
2043 | sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " |
2044 | "384 512" , -1); |
2045 | return; |
2046 | } |
2047 | } |
2048 | if( eType==SQLITE_NULL ) return; |
2049 | SHA3Init(&cx, iSize); |
2050 | if( eType==SQLITE_BLOB ){ |
2051 | SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte); |
2052 | }else{ |
2053 | SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte); |
2054 | } |
2055 | sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); |
2056 | } |
2057 | |
2058 | /* Compute a string using sqlite3_vsnprintf() with a maximum length |
2059 | ** of 50 bytes and add it to the hash. |
2060 | */ |
2061 | static void hash_step_vformat( |
2062 | SHA3Context *p, /* Add content to this context */ |
2063 | const char *zFormat, |
2064 | ... |
2065 | ){ |
2066 | va_list ap; |
2067 | int n; |
2068 | char zBuf[50]; |
2069 | va_start(ap, zFormat); |
2070 | sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); |
2071 | va_end(ap); |
2072 | n = (int)strlen(zBuf); |
2073 | SHA3Update(p, (unsigned char*)zBuf, n); |
2074 | } |
2075 | |
2076 | /* |
2077 | ** Implementation of the sha3_query(SQL,SIZE) function. |
2078 | ** |
2079 | ** This function compiles and runs the SQL statement(s) given in the |
2080 | ** argument. The results are hashed using a SIZE-bit SHA3. The default |
2081 | ** size is 256. |
2082 | ** |
2083 | ** The format of the byte stream that is hashed is summarized as follows: |
2084 | ** |
2085 | ** S<n>:<sql> |
2086 | ** R |
2087 | ** N |
2088 | ** I<int> |
2089 | ** F<ieee-float> |
2090 | ** B<size>:<bytes> |
2091 | ** T<size>:<text> |
2092 | ** |
2093 | ** <sql> is the original SQL text for each statement run and <n> is |
2094 | ** the size of that text. The SQL text is UTF-8. A single R character |
2095 | ** occurs before the start of each row. N means a NULL value. |
2096 | ** I mean an 8-byte little-endian integer <int>. F is a floating point |
2097 | ** number with an 8-byte little-endian IEEE floating point value <ieee-float>. |
2098 | ** B means blobs of <size> bytes. T means text rendered as <size> |
2099 | ** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII |
2100 | ** text integers. |
2101 | ** |
2102 | ** For each SQL statement in the X input, there is one S segment. Each |
2103 | ** S segment is followed by zero or more R segments, one for each row in the |
2104 | ** result set. After each R, there are one or more N, I, F, B, or T segments, |
2105 | ** one for each column in the result set. Segments are concatentated directly |
2106 | ** with no delimiters of any kind. |
2107 | */ |
2108 | static void sha3QueryFunc( |
2109 | sqlite3_context *context, |
2110 | int argc, |
2111 | sqlite3_value **argv |
2112 | ){ |
2113 | sqlite3 *db = sqlite3_context_db_handle(context); |
2114 | const char *zSql = (const char*)sqlite3_value_text(argv[0]); |
2115 | sqlite3_stmt *pStmt = 0; |
2116 | int nCol; /* Number of columns in the result set */ |
2117 | int i; /* Loop counter */ |
2118 | int rc; |
2119 | int n; |
2120 | const char *z; |
2121 | SHA3Context cx; |
2122 | int iSize; |
2123 | |
2124 | if( argc==1 ){ |
2125 | iSize = 256; |
2126 | }else{ |
2127 | iSize = sqlite3_value_int(argv[1]); |
2128 | if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ |
2129 | sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " |
2130 | "384 512" , -1); |
2131 | return; |
2132 | } |
2133 | } |
2134 | if( zSql==0 ) return; |
2135 | SHA3Init(&cx, iSize); |
2136 | while( zSql[0] ){ |
2137 | rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); |
2138 | if( rc ){ |
2139 | char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s" , |
2140 | zSql, sqlite3_errmsg(db)); |
2141 | sqlite3_finalize(pStmt); |
2142 | sqlite3_result_error(context, zMsg, -1); |
2143 | sqlite3_free(zMsg); |
2144 | return; |
2145 | } |
2146 | if( !sqlite3_stmt_readonly(pStmt) ){ |
2147 | char *zMsg = sqlite3_mprintf("non-query: [%s]" , sqlite3_sql(pStmt)); |
2148 | sqlite3_finalize(pStmt); |
2149 | sqlite3_result_error(context, zMsg, -1); |
2150 | sqlite3_free(zMsg); |
2151 | return; |
2152 | } |
2153 | nCol = sqlite3_column_count(pStmt); |
2154 | z = sqlite3_sql(pStmt); |
2155 | if( z ){ |
2156 | n = (int)strlen(z); |
2157 | hash_step_vformat(&cx,"S%d:" ,n); |
2158 | SHA3Update(&cx,(unsigned char*)z,n); |
2159 | } |
2160 | |
2161 | /* Compute a hash over the result of the query */ |
2162 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ |
2163 | SHA3Update(&cx,(const unsigned char*)"R" ,1); |
2164 | for(i=0; i<nCol; i++){ |
2165 | switch( sqlite3_column_type(pStmt,i) ){ |
2166 | case SQLITE_NULL: { |
2167 | SHA3Update(&cx, (const unsigned char*)"N" ,1); |
2168 | break; |
2169 | } |
2170 | case SQLITE_INTEGER: { |
2171 | sqlite3_uint64 u; |
2172 | int j; |
2173 | unsigned char x[9]; |
2174 | sqlite3_int64 v = sqlite3_column_int64(pStmt,i); |
2175 | memcpy(&u, &v, 8); |
2176 | for(j=8; j>=1; j--){ |
2177 | x[j] = u & 0xff; |
2178 | u >>= 8; |
2179 | } |
2180 | x[0] = 'I'; |
2181 | SHA3Update(&cx, x, 9); |
2182 | break; |
2183 | } |
2184 | case SQLITE_FLOAT: { |
2185 | sqlite3_uint64 u; |
2186 | int j; |
2187 | unsigned char x[9]; |
2188 | double r = sqlite3_column_double(pStmt,i); |
2189 | memcpy(&u, &r, 8); |
2190 | for(j=8; j>=1; j--){ |
2191 | x[j] = u & 0xff; |
2192 | u >>= 8; |
2193 | } |
2194 | x[0] = 'F'; |
2195 | SHA3Update(&cx,x,9); |
2196 | break; |
2197 | } |
2198 | case SQLITE_TEXT: { |
2199 | int n2 = sqlite3_column_bytes(pStmt, i); |
2200 | const unsigned char *z2 = sqlite3_column_text(pStmt, i); |
2201 | hash_step_vformat(&cx,"T%d:" ,n2); |
2202 | SHA3Update(&cx, z2, n2); |
2203 | break; |
2204 | } |
2205 | case SQLITE_BLOB: { |
2206 | int n2 = sqlite3_column_bytes(pStmt, i); |
2207 | const unsigned char *z2 = sqlite3_column_blob(pStmt, i); |
2208 | hash_step_vformat(&cx,"B%d:" ,n2); |
2209 | SHA3Update(&cx, z2, n2); |
2210 | break; |
2211 | } |
2212 | } |
2213 | } |
2214 | } |
2215 | sqlite3_finalize(pStmt); |
2216 | } |
2217 | sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); |
2218 | } |
2219 | |
2220 | |
2221 | #ifdef _WIN32 |
2222 | |
2223 | #endif |
2224 | int sqlite3_shathree_init( |
2225 | sqlite3 *db, |
2226 | char **pzErrMsg, |
2227 | const sqlite3_api_routines *pApi |
2228 | ){ |
2229 | int rc = SQLITE_OK; |
2230 | SQLITE_EXTENSION_INIT2(pApi); |
2231 | (void)pzErrMsg; /* Unused parameter */ |
2232 | rc = sqlite3_create_function(db, "sha3" , 1, |
2233 | SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, |
2234 | 0, sha3Func, 0, 0); |
2235 | if( rc==SQLITE_OK ){ |
2236 | rc = sqlite3_create_function(db, "sha3" , 2, |
2237 | SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, |
2238 | 0, sha3Func, 0, 0); |
2239 | } |
2240 | if( rc==SQLITE_OK ){ |
2241 | rc = sqlite3_create_function(db, "sha3_query" , 1, |
2242 | SQLITE_UTF8 | SQLITE_DIRECTONLY, |
2243 | 0, sha3QueryFunc, 0, 0); |
2244 | } |
2245 | if( rc==SQLITE_OK ){ |
2246 | rc = sqlite3_create_function(db, "sha3_query" , 2, |
2247 | SQLITE_UTF8 | SQLITE_DIRECTONLY, |
2248 | 0, sha3QueryFunc, 0, 0); |
2249 | } |
2250 | return rc; |
2251 | } |
2252 | |
2253 | /************************* End ../ext/misc/shathree.c ********************/ |
2254 | /************************* Begin ../ext/misc/uint.c ******************/ |
2255 | /* |
2256 | ** 2020-04-14 |
2257 | ** |
2258 | ** The author disclaims copyright to this source code. In place of |
2259 | ** a legal notice, here is a blessing: |
2260 | ** |
2261 | ** May you do good and not evil. |
2262 | ** May you find forgiveness for yourself and forgive others. |
2263 | ** May you share freely, never taking more than you give. |
2264 | ** |
2265 | ****************************************************************************** |
2266 | ** |
2267 | ** This SQLite extension implements the UINT collating sequence. |
2268 | ** |
2269 | ** UINT works like BINARY for text, except that embedded strings |
2270 | ** of digits compare in numeric order. |
2271 | ** |
2272 | ** * Leading zeros are handled properly, in the sense that |
2273 | ** they do not mess of the maginitude comparison of embedded |
2274 | ** strings of digits. "x00123y" is equal to "x123y". |
2275 | ** |
2276 | ** * Only unsigned integers are recognized. Plus and minus |
2277 | ** signs are ignored. Decimal points and exponential notation |
2278 | ** are ignored. |
2279 | ** |
2280 | ** * Embedded integers can be of arbitrary length. Comparison |
2281 | ** is *not* limited integers that can be expressed as a |
2282 | ** 64-bit machine integer. |
2283 | */ |
2284 | /* #include "sqlite3ext.h" */ |
2285 | SQLITE_EXTENSION_INIT1 |
2286 | #include <assert.h> |
2287 | #include <string.h> |
2288 | #include <ctype.h> |
2289 | |
2290 | /* |
2291 | ** Compare text in lexicographic order, except strings of digits |
2292 | ** compare in numeric order. |
2293 | */ |
2294 | static int uintCollFunc( |
2295 | void *notUsed, |
2296 | int nKey1, const void *pKey1, |
2297 | int nKey2, const void *pKey2 |
2298 | ){ |
2299 | const unsigned char *zA = (const unsigned char*)pKey1; |
2300 | const unsigned char *zB = (const unsigned char*)pKey2; |
2301 | int i=0, j=0, x; |
2302 | (void)notUsed; |
2303 | while( i<nKey1 && j<nKey2 ){ |
2304 | x = zA[i] - zB[j]; |
2305 | if( isdigit(zA[i]) ){ |
2306 | int k; |
2307 | if( !isdigit(zB[j]) ) return x; |
2308 | while( i<nKey1 && zA[i]=='0' ){ i++; } |
2309 | while( j<nKey2 && zB[j]=='0' ){ j++; } |
2310 | k = 0; |
2311 | while( i+k<nKey1 && isdigit(zA[i+k]) |
2312 | && j+k<nKey2 && isdigit(zB[j+k]) ){ |
2313 | k++; |
2314 | } |
2315 | if( i+k<nKey1 && isdigit(zA[i+k]) ){ |
2316 | return +1; |
2317 | }else if( j+k<nKey2 && isdigit(zB[j+k]) ){ |
2318 | return -1; |
2319 | }else{ |
2320 | x = memcmp(zA+i, zB+j, k); |
2321 | if( x ) return x; |
2322 | i += k; |
2323 | j += k; |
2324 | } |
2325 | }else if( x ){ |
2326 | return x; |
2327 | }else{ |
2328 | i++; |
2329 | j++; |
2330 | } |
2331 | } |
2332 | return (nKey1 - i) - (nKey2 - j); |
2333 | } |
2334 | |
2335 | #ifdef _WIN32 |
2336 | |
2337 | #endif |
2338 | int sqlite3_uint_init( |
2339 | sqlite3 *db, |
2340 | char **pzErrMsg, |
2341 | const sqlite3_api_routines *pApi |
2342 | ){ |
2343 | SQLITE_EXTENSION_INIT2(pApi); |
2344 | (void)pzErrMsg; /* Unused parameter */ |
2345 | return sqlite3_create_collation(db, "uint" , SQLITE_UTF8, 0, uintCollFunc); |
2346 | } |
2347 | |
2348 | /************************* End ../ext/misc/uint.c ********************/ |
2349 | /************************* Begin ../ext/misc/decimal.c ******************/ |
2350 | /* |
2351 | ** 2020-06-22 |
2352 | ** |
2353 | ** The author disclaims copyright to this source code. In place of |
2354 | ** a legal notice, here is a blessing: |
2355 | ** |
2356 | ** May you do good and not evil. |
2357 | ** May you find forgiveness for yourself and forgive others. |
2358 | ** May you share freely, never taking more than you give. |
2359 | ** |
2360 | ****************************************************************************** |
2361 | ** |
2362 | ** Routines to implement arbitrary-precision decimal math. |
2363 | ** |
2364 | ** The focus here is on simplicity and correctness, not performance. |
2365 | */ |
2366 | /* #include "sqlite3ext.h" */ |
2367 | SQLITE_EXTENSION_INIT1 |
2368 | #include <assert.h> |
2369 | #include <string.h> |
2370 | #include <ctype.h> |
2371 | #include <stdlib.h> |
2372 | |
2373 | /* Mark a function parameter as unused, to suppress nuisance compiler |
2374 | ** warnings. */ |
2375 | #ifndef UNUSED_PARAMETER |
2376 | # define UNUSED_PARAMETER(X) (void)(X) |
2377 | #endif |
2378 | |
2379 | |
2380 | /* A decimal object */ |
2381 | typedef struct Decimal Decimal; |
2382 | struct Decimal { |
2383 | char sign; /* 0 for positive, 1 for negative */ |
2384 | char oom; /* True if an OOM is encountered */ |
2385 | char isNull; /* True if holds a NULL rather than a number */ |
2386 | char isInit; /* True upon initialization */ |
2387 | int nDigit; /* Total number of digits */ |
2388 | int nFrac; /* Number of digits to the right of the decimal point */ |
2389 | signed char *a; /* Array of digits. Most significant first. */ |
2390 | }; |
2391 | |
2392 | /* |
2393 | ** Release memory held by a Decimal, but do not free the object itself. |
2394 | */ |
2395 | static void decimal_clear(Decimal *p){ |
2396 | sqlite3_free(p->a); |
2397 | } |
2398 | |
2399 | /* |
2400 | ** Destroy a Decimal object |
2401 | */ |
2402 | static void decimal_free(Decimal *p){ |
2403 | if( p ){ |
2404 | decimal_clear(p); |
2405 | sqlite3_free(p); |
2406 | } |
2407 | } |
2408 | |
2409 | /* |
2410 | ** Allocate a new Decimal object. Initialize it to the number given |
2411 | ** by the input string. |
2412 | */ |
2413 | static Decimal *decimal_new( |
2414 | sqlite3_context *pCtx, |
2415 | sqlite3_value *pIn, |
2416 | int nAlt, |
2417 | const unsigned char *zAlt |
2418 | ){ |
2419 | Decimal *p; |
2420 | int n, i; |
2421 | const unsigned char *zIn; |
2422 | int iExp = 0; |
2423 | p = sqlite3_malloc( sizeof(*p) ); |
2424 | if( p==0 ) goto new_no_mem; |
2425 | p->sign = 0; |
2426 | p->oom = 0; |
2427 | p->isInit = 1; |
2428 | p->isNull = 0; |
2429 | p->nDigit = 0; |
2430 | p->nFrac = 0; |
2431 | if( zAlt ){ |
2432 | n = nAlt, |
2433 | zIn = zAlt; |
2434 | }else{ |
2435 | if( sqlite3_value_type(pIn)==SQLITE_NULL ){ |
2436 | p->a = 0; |
2437 | p->isNull = 1; |
2438 | return p; |
2439 | } |
2440 | n = sqlite3_value_bytes(pIn); |
2441 | zIn = sqlite3_value_text(pIn); |
2442 | } |
2443 | p->a = sqlite3_malloc64( n+1 ); |
2444 | if( p->a==0 ) goto new_no_mem; |
2445 | for(i=0; isspace(zIn[i]); i++){} |
2446 | if( zIn[i]=='-' ){ |
2447 | p->sign = 1; |
2448 | i++; |
2449 | }else if( zIn[i]=='+' ){ |
2450 | i++; |
2451 | } |
2452 | while( i<n && zIn[i]=='0' ) i++; |
2453 | while( i<n ){ |
2454 | char c = zIn[i]; |
2455 | if( c>='0' && c<='9' ){ |
2456 | p->a[p->nDigit++] = c - '0'; |
2457 | }else if( c=='.' ){ |
2458 | p->nFrac = p->nDigit + 1; |
2459 | }else if( c=='e' || c=='E' ){ |
2460 | int j = i+1; |
2461 | int neg = 0; |
2462 | if( j>=n ) break; |
2463 | if( zIn[j]=='-' ){ |
2464 | neg = 1; |
2465 | j++; |
2466 | }else if( zIn[j]=='+' ){ |
2467 | j++; |
2468 | } |
2469 | while( j<n && iExp<1000000 ){ |
2470 | if( zIn[j]>='0' && zIn[j]<='9' ){ |
2471 | iExp = iExp*10 + zIn[j] - '0'; |
2472 | } |
2473 | j++; |
2474 | } |
2475 | if( neg ) iExp = -iExp; |
2476 | break; |
2477 | } |
2478 | i++; |
2479 | } |
2480 | if( p->nFrac ){ |
2481 | p->nFrac = p->nDigit - (p->nFrac - 1); |
2482 | } |
2483 | if( iExp>0 ){ |
2484 | if( p->nFrac>0 ){ |
2485 | if( iExp<=p->nFrac ){ |
2486 | p->nFrac -= iExp; |
2487 | iExp = 0; |
2488 | }else{ |
2489 | iExp -= p->nFrac; |
2490 | p->nFrac = 0; |
2491 | } |
2492 | } |
2493 | if( iExp>0 ){ |
2494 | p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); |
2495 | if( p->a==0 ) goto new_no_mem; |
2496 | memset(p->a+p->nDigit, 0, iExp); |
2497 | p->nDigit += iExp; |
2498 | } |
2499 | }else if( iExp<0 ){ |
2500 | int ; |
2501 | iExp = -iExp; |
2502 | nExtra = p->nDigit - p->nFrac - 1; |
2503 | if( nExtra ){ |
2504 | if( nExtra>=iExp ){ |
2505 | p->nFrac += iExp; |
2506 | iExp = 0; |
2507 | }else{ |
2508 | iExp -= nExtra; |
2509 | p->nFrac = p->nDigit - 1; |
2510 | } |
2511 | } |
2512 | if( iExp>0 ){ |
2513 | p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); |
2514 | if( p->a==0 ) goto new_no_mem; |
2515 | memmove(p->a+iExp, p->a, p->nDigit); |
2516 | memset(p->a, 0, iExp); |
2517 | p->nDigit += iExp; |
2518 | p->nFrac += iExp; |
2519 | } |
2520 | } |
2521 | return p; |
2522 | |
2523 | new_no_mem: |
2524 | if( pCtx ) sqlite3_result_error_nomem(pCtx); |
2525 | sqlite3_free(p); |
2526 | return 0; |
2527 | } |
2528 | |
2529 | /* |
2530 | ** Make the given Decimal the result. |
2531 | */ |
2532 | static void decimal_result(sqlite3_context *pCtx, Decimal *p){ |
2533 | char *z; |
2534 | int i, j; |
2535 | int n; |
2536 | if( p==0 || p->oom ){ |
2537 | sqlite3_result_error_nomem(pCtx); |
2538 | return; |
2539 | } |
2540 | if( p->isNull ){ |
2541 | sqlite3_result_null(pCtx); |
2542 | return; |
2543 | } |
2544 | z = sqlite3_malloc( p->nDigit+4 ); |
2545 | if( z==0 ){ |
2546 | sqlite3_result_error_nomem(pCtx); |
2547 | return; |
2548 | } |
2549 | i = 0; |
2550 | if( p->nDigit==0 || (p->nDigit==1 && p->a[0]==0) ){ |
2551 | p->sign = 0; |
2552 | } |
2553 | if( p->sign ){ |
2554 | z[0] = '-'; |
2555 | i = 1; |
2556 | } |
2557 | n = p->nDigit - p->nFrac; |
2558 | if( n<=0 ){ |
2559 | z[i++] = '0'; |
2560 | } |
2561 | j = 0; |
2562 | while( n>1 && p->a[j]==0 ){ |
2563 | j++; |
2564 | n--; |
2565 | } |
2566 | while( n>0 ){ |
2567 | z[i++] = p->a[j] + '0'; |
2568 | j++; |
2569 | n--; |
2570 | } |
2571 | if( p->nFrac ){ |
2572 | z[i++] = '.'; |
2573 | do{ |
2574 | z[i++] = p->a[j] + '0'; |
2575 | j++; |
2576 | }while( j<p->nDigit ); |
2577 | } |
2578 | z[i] = 0; |
2579 | sqlite3_result_text(pCtx, z, i, sqlite3_free); |
2580 | } |
2581 | |
2582 | /* |
2583 | ** SQL Function: decimal(X) |
2584 | ** |
2585 | ** Convert input X into decimal and then back into text |
2586 | */ |
2587 | static void decimalFunc( |
2588 | sqlite3_context *context, |
2589 | int argc, |
2590 | sqlite3_value **argv |
2591 | ){ |
2592 | Decimal *p = decimal_new(context, argv[0], 0, 0); |
2593 | UNUSED_PARAMETER(argc); |
2594 | decimal_result(context, p); |
2595 | decimal_free(p); |
2596 | } |
2597 | |
2598 | /* |
2599 | ** Compare to Decimal objects. Return negative, 0, or positive if the |
2600 | ** first object is less than, equal to, or greater than the second. |
2601 | ** |
2602 | ** Preconditions for this routine: |
2603 | ** |
2604 | ** pA!=0 |
2605 | ** pA->isNull==0 |
2606 | ** pB!=0 |
2607 | ** pB->isNull==0 |
2608 | */ |
2609 | static int decimal_cmp(const Decimal *pA, const Decimal *pB){ |
2610 | int nASig, nBSig, rc, n; |
2611 | if( pA->sign!=pB->sign ){ |
2612 | return pA->sign ? -1 : +1; |
2613 | } |
2614 | if( pA->sign ){ |
2615 | const Decimal *pTemp = pA; |
2616 | pA = pB; |
2617 | pB = pTemp; |
2618 | } |
2619 | nASig = pA->nDigit - pA->nFrac; |
2620 | nBSig = pB->nDigit - pB->nFrac; |
2621 | if( nASig!=nBSig ){ |
2622 | return nASig - nBSig; |
2623 | } |
2624 | n = pA->nDigit; |
2625 | if( n>pB->nDigit ) n = pB->nDigit; |
2626 | rc = memcmp(pA->a, pB->a, n); |
2627 | if( rc==0 ){ |
2628 | rc = pA->nDigit - pB->nDigit; |
2629 | } |
2630 | return rc; |
2631 | } |
2632 | |
2633 | /* |
2634 | ** SQL Function: decimal_cmp(X, Y) |
2635 | ** |
2636 | ** Return negative, zero, or positive if X is less then, equal to, or |
2637 | ** greater than Y. |
2638 | */ |
2639 | static void decimalCmpFunc( |
2640 | sqlite3_context *context, |
2641 | int argc, |
2642 | sqlite3_value **argv |
2643 | ){ |
2644 | Decimal *pA = 0, *pB = 0; |
2645 | int rc; |
2646 | |
2647 | UNUSED_PARAMETER(argc); |
2648 | pA = decimal_new(context, argv[0], 0, 0); |
2649 | if( pA==0 || pA->isNull ) goto cmp_done; |
2650 | pB = decimal_new(context, argv[1], 0, 0); |
2651 | if( pB==0 || pB->isNull ) goto cmp_done; |
2652 | rc = decimal_cmp(pA, pB); |
2653 | if( rc<0 ) rc = -1; |
2654 | else if( rc>0 ) rc = +1; |
2655 | sqlite3_result_int(context, rc); |
2656 | cmp_done: |
2657 | decimal_free(pA); |
2658 | decimal_free(pB); |
2659 | } |
2660 | |
2661 | /* |
2662 | ** Expand the Decimal so that it has a least nDigit digits and nFrac |
2663 | ** digits to the right of the decimal point. |
2664 | */ |
2665 | static void decimal_expand(Decimal *p, int nDigit, int nFrac){ |
2666 | int nAddSig; |
2667 | int nAddFrac; |
2668 | if( p==0 ) return; |
2669 | nAddFrac = nFrac - p->nFrac; |
2670 | nAddSig = (nDigit - p->nDigit) - nAddFrac; |
2671 | if( nAddFrac==0 && nAddSig==0 ) return; |
2672 | p->a = sqlite3_realloc64(p->a, nDigit+1); |
2673 | if( p->a==0 ){ |
2674 | p->oom = 1; |
2675 | return; |
2676 | } |
2677 | if( nAddSig ){ |
2678 | memmove(p->a+nAddSig, p->a, p->nDigit); |
2679 | memset(p->a, 0, nAddSig); |
2680 | p->nDigit += nAddSig; |
2681 | } |
2682 | if( nAddFrac ){ |
2683 | memset(p->a+p->nDigit, 0, nAddFrac); |
2684 | p->nDigit += nAddFrac; |
2685 | p->nFrac += nAddFrac; |
2686 | } |
2687 | } |
2688 | |
2689 | /* |
2690 | ** Add the value pB into pA. |
2691 | ** |
2692 | ** Both pA and pB might become denormalized by this routine. |
2693 | */ |
2694 | static void decimal_add(Decimal *pA, Decimal *pB){ |
2695 | int nSig, nFrac, nDigit; |
2696 | int i, rc; |
2697 | if( pA==0 ){ |
2698 | return; |
2699 | } |
2700 | if( pA->oom || pB==0 || pB->oom ){ |
2701 | pA->oom = 1; |
2702 | return; |
2703 | } |
2704 | if( pA->isNull || pB->isNull ){ |
2705 | pA->isNull = 1; |
2706 | return; |
2707 | } |
2708 | nSig = pA->nDigit - pA->nFrac; |
2709 | if( nSig && pA->a[0]==0 ) nSig--; |
2710 | if( nSig<pB->nDigit-pB->nFrac ){ |
2711 | nSig = pB->nDigit - pB->nFrac; |
2712 | } |
2713 | nFrac = pA->nFrac; |
2714 | if( nFrac<pB->nFrac ) nFrac = pB->nFrac; |
2715 | nDigit = nSig + nFrac + 1; |
2716 | decimal_expand(pA, nDigit, nFrac); |
2717 | decimal_expand(pB, nDigit, nFrac); |
2718 | if( pA->oom || pB->oom ){ |
2719 | pA->oom = 1; |
2720 | }else{ |
2721 | if( pA->sign==pB->sign ){ |
2722 | int carry = 0; |
2723 | for(i=nDigit-1; i>=0; i--){ |
2724 | int x = pA->a[i] + pB->a[i] + carry; |
2725 | if( x>=10 ){ |
2726 | carry = 1; |
2727 | pA->a[i] = x - 10; |
2728 | }else{ |
2729 | carry = 0; |
2730 | pA->a[i] = x; |
2731 | } |
2732 | } |
2733 | }else{ |
2734 | signed char *aA, *aB; |
2735 | int borrow = 0; |
2736 | rc = memcmp(pA->a, pB->a, nDigit); |
2737 | if( rc<0 ){ |
2738 | aA = pB->a; |
2739 | aB = pA->a; |
2740 | pA->sign = !pA->sign; |
2741 | }else{ |
2742 | aA = pA->a; |
2743 | aB = pB->a; |
2744 | } |
2745 | for(i=nDigit-1; i>=0; i--){ |
2746 | int x = aA[i] - aB[i] - borrow; |
2747 | if( x<0 ){ |
2748 | pA->a[i] = x+10; |
2749 | borrow = 1; |
2750 | }else{ |
2751 | pA->a[i] = x; |
2752 | borrow = 0; |
2753 | } |
2754 | } |
2755 | } |
2756 | } |
2757 | } |
2758 | |
2759 | /* |
2760 | ** Compare text in decimal order. |
2761 | */ |
2762 | static int decimalCollFunc( |
2763 | void *notUsed, |
2764 | int nKey1, const void *pKey1, |
2765 | int nKey2, const void *pKey2 |
2766 | ){ |
2767 | const unsigned char *zA = (const unsigned char*)pKey1; |
2768 | const unsigned char *zB = (const unsigned char*)pKey2; |
2769 | Decimal *pA = decimal_new(0, 0, nKey1, zA); |
2770 | Decimal *pB = decimal_new(0, 0, nKey2, zB); |
2771 | int rc; |
2772 | UNUSED_PARAMETER(notUsed); |
2773 | if( pA==0 || pB==0 ){ |
2774 | rc = 0; |
2775 | }else{ |
2776 | rc = decimal_cmp(pA, pB); |
2777 | } |
2778 | decimal_free(pA); |
2779 | decimal_free(pB); |
2780 | return rc; |
2781 | } |
2782 | |
2783 | |
2784 | /* |
2785 | ** SQL Function: decimal_add(X, Y) |
2786 | ** decimal_sub(X, Y) |
2787 | ** |
2788 | ** Return the sum or difference of X and Y. |
2789 | */ |
2790 | static void decimalAddFunc( |
2791 | sqlite3_context *context, |
2792 | int argc, |
2793 | sqlite3_value **argv |
2794 | ){ |
2795 | Decimal *pA = decimal_new(context, argv[0], 0, 0); |
2796 | Decimal *pB = decimal_new(context, argv[1], 0, 0); |
2797 | UNUSED_PARAMETER(argc); |
2798 | decimal_add(pA, pB); |
2799 | decimal_result(context, pA); |
2800 | decimal_free(pA); |
2801 | decimal_free(pB); |
2802 | } |
2803 | static void decimalSubFunc( |
2804 | sqlite3_context *context, |
2805 | int argc, |
2806 | sqlite3_value **argv |
2807 | ){ |
2808 | Decimal *pA = decimal_new(context, argv[0], 0, 0); |
2809 | Decimal *pB = decimal_new(context, argv[1], 0, 0); |
2810 | UNUSED_PARAMETER(argc); |
2811 | if( pB ){ |
2812 | pB->sign = !pB->sign; |
2813 | decimal_add(pA, pB); |
2814 | decimal_result(context, pA); |
2815 | } |
2816 | decimal_free(pA); |
2817 | decimal_free(pB); |
2818 | } |
2819 | |
2820 | /* Aggregate funcion: decimal_sum(X) |
2821 | ** |
2822 | ** Works like sum() except that it uses decimal arithmetic for unlimited |
2823 | ** precision. |
2824 | */ |
2825 | static void decimalSumStep( |
2826 | sqlite3_context *context, |
2827 | int argc, |
2828 | sqlite3_value **argv |
2829 | ){ |
2830 | Decimal *p; |
2831 | Decimal *pArg; |
2832 | UNUSED_PARAMETER(argc); |
2833 | p = sqlite3_aggregate_context(context, sizeof(*p)); |
2834 | if( p==0 ) return; |
2835 | if( !p->isInit ){ |
2836 | p->isInit = 1; |
2837 | p->a = sqlite3_malloc(2); |
2838 | if( p->a==0 ){ |
2839 | p->oom = 1; |
2840 | }else{ |
2841 | p->a[0] = 0; |
2842 | } |
2843 | p->nDigit = 1; |
2844 | p->nFrac = 0; |
2845 | } |
2846 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; |
2847 | pArg = decimal_new(context, argv[0], 0, 0); |
2848 | decimal_add(p, pArg); |
2849 | decimal_free(pArg); |
2850 | } |
2851 | static void decimalSumInverse( |
2852 | sqlite3_context *context, |
2853 | int argc, |
2854 | sqlite3_value **argv |
2855 | ){ |
2856 | Decimal *p; |
2857 | Decimal *pArg; |
2858 | UNUSED_PARAMETER(argc); |
2859 | p = sqlite3_aggregate_context(context, sizeof(*p)); |
2860 | if( p==0 ) return; |
2861 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; |
2862 | pArg = decimal_new(context, argv[0], 0, 0); |
2863 | if( pArg ) pArg->sign = !pArg->sign; |
2864 | decimal_add(p, pArg); |
2865 | decimal_free(pArg); |
2866 | } |
2867 | static void decimalSumValue(sqlite3_context *context){ |
2868 | Decimal *p = sqlite3_aggregate_context(context, 0); |
2869 | if( p==0 ) return; |
2870 | decimal_result(context, p); |
2871 | } |
2872 | static void decimalSumFinalize(sqlite3_context *context){ |
2873 | Decimal *p = sqlite3_aggregate_context(context, 0); |
2874 | if( p==0 ) return; |
2875 | decimal_result(context, p); |
2876 | decimal_clear(p); |
2877 | } |
2878 | |
2879 | /* |
2880 | ** SQL Function: decimal_mul(X, Y) |
2881 | ** |
2882 | ** Return the product of X and Y. |
2883 | ** |
2884 | ** All significant digits after the decimal point are retained. |
2885 | ** Trailing zeros after the decimal point are omitted as long as |
2886 | ** the number of digits after the decimal point is no less than |
2887 | ** either the number of digits in either input. |
2888 | */ |
2889 | static void decimalMulFunc( |
2890 | sqlite3_context *context, |
2891 | int argc, |
2892 | sqlite3_value **argv |
2893 | ){ |
2894 | Decimal *pA = decimal_new(context, argv[0], 0, 0); |
2895 | Decimal *pB = decimal_new(context, argv[1], 0, 0); |
2896 | signed char *acc = 0; |
2897 | int i, j, k; |
2898 | int minFrac; |
2899 | UNUSED_PARAMETER(argc); |
2900 | if( pA==0 || pA->oom || pA->isNull |
2901 | || pB==0 || pB->oom || pB->isNull |
2902 | ){ |
2903 | goto mul_end; |
2904 | } |
2905 | acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 ); |
2906 | if( acc==0 ){ |
2907 | sqlite3_result_error_nomem(context); |
2908 | goto mul_end; |
2909 | } |
2910 | memset(acc, 0, pA->nDigit + pB->nDigit + 2); |
2911 | minFrac = pA->nFrac; |
2912 | if( pB->nFrac<minFrac ) minFrac = pB->nFrac; |
2913 | for(i=pA->nDigit-1; i>=0; i--){ |
2914 | signed char f = pA->a[i]; |
2915 | int carry = 0, x; |
2916 | for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){ |
2917 | x = acc[k] + f*pB->a[j] + carry; |
2918 | acc[k] = x%10; |
2919 | carry = x/10; |
2920 | } |
2921 | x = acc[k] + carry; |
2922 | acc[k] = x%10; |
2923 | acc[k-1] += x/10; |
2924 | } |
2925 | sqlite3_free(pA->a); |
2926 | pA->a = acc; |
2927 | acc = 0; |
2928 | pA->nDigit += pB->nDigit + 2; |
2929 | pA->nFrac += pB->nFrac; |
2930 | pA->sign ^= pB->sign; |
2931 | while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){ |
2932 | pA->nFrac--; |
2933 | pA->nDigit--; |
2934 | } |
2935 | decimal_result(context, pA); |
2936 | |
2937 | mul_end: |
2938 | sqlite3_free(acc); |
2939 | decimal_free(pA); |
2940 | decimal_free(pB); |
2941 | } |
2942 | |
2943 | #ifdef _WIN32 |
2944 | |
2945 | #endif |
2946 | int sqlite3_decimal_init( |
2947 | sqlite3 *db, |
2948 | char **pzErrMsg, |
2949 | const sqlite3_api_routines *pApi |
2950 | ){ |
2951 | int rc = SQLITE_OK; |
2952 | static const struct { |
2953 | const char *zFuncName; |
2954 | int nArg; |
2955 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**); |
2956 | } aFunc[] = { |
2957 | { "decimal" , 1, decimalFunc }, |
2958 | { "decimal_cmp" , 2, decimalCmpFunc }, |
2959 | { "decimal_add" , 2, decimalAddFunc }, |
2960 | { "decimal_sub" , 2, decimalSubFunc }, |
2961 | { "decimal_mul" , 2, decimalMulFunc }, |
2962 | }; |
2963 | unsigned int i; |
2964 | (void)pzErrMsg; /* Unused parameter */ |
2965 | |
2966 | SQLITE_EXTENSION_INIT2(pApi); |
2967 | |
2968 | for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ |
2969 | rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg, |
2970 | SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, |
2971 | 0, aFunc[i].xFunc, 0, 0); |
2972 | } |
2973 | if( rc==SQLITE_OK ){ |
2974 | rc = sqlite3_create_window_function(db, "decimal_sum" , 1, |
2975 | SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0, |
2976 | decimalSumStep, decimalSumFinalize, |
2977 | decimalSumValue, decimalSumInverse, 0); |
2978 | } |
2979 | if( rc==SQLITE_OK ){ |
2980 | rc = sqlite3_create_collation(db, "decimal" , SQLITE_UTF8, |
2981 | 0, decimalCollFunc); |
2982 | } |
2983 | return rc; |
2984 | } |
2985 | |
2986 | /************************* End ../ext/misc/decimal.c ********************/ |
2987 | /************************* Begin ../ext/misc/ieee754.c ******************/ |
2988 | /* |
2989 | ** 2013-04-17 |
2990 | ** |
2991 | ** The author disclaims copyright to this source code. In place of |
2992 | ** a legal notice, here is a blessing: |
2993 | ** |
2994 | ** May you do good and not evil. |
2995 | ** May you find forgiveness for yourself and forgive others. |
2996 | ** May you share freely, never taking more than you give. |
2997 | ** |
2998 | ****************************************************************************** |
2999 | ** |
3000 | ** This SQLite extension implements functions for the exact display |
3001 | ** and input of IEEE754 Binary64 floating-point numbers. |
3002 | ** |
3003 | ** ieee754(X) |
3004 | ** ieee754(Y,Z) |
3005 | ** |
3006 | ** In the first form, the value X should be a floating-point number. |
3007 | ** The function will return a string of the form 'ieee754(Y,Z)' where |
3008 | ** Y and Z are integers such that X==Y*pow(2,Z). |
3009 | ** |
3010 | ** In the second form, Y and Z are integers which are the mantissa and |
3011 | ** base-2 exponent of a new floating point number. The function returns |
3012 | ** a floating-point value equal to Y*pow(2,Z). |
3013 | ** |
3014 | ** Examples: |
3015 | ** |
3016 | ** ieee754(2.0) -> 'ieee754(2,0)' |
3017 | ** ieee754(45.25) -> 'ieee754(181,-2)' |
3018 | ** ieee754(2, 0) -> 2.0 |
3019 | ** ieee754(181, -2) -> 45.25 |
3020 | ** |
3021 | ** Two additional functions break apart the one-argument ieee754() |
3022 | ** result into separate integer values: |
3023 | ** |
3024 | ** ieee754_mantissa(45.25) -> 181 |
3025 | ** ieee754_exponent(45.25) -> -2 |
3026 | ** |
3027 | ** These functions convert binary64 numbers into blobs and back again. |
3028 | ** |
3029 | ** ieee754_from_blob(x'3ff0000000000000') -> 1.0 |
3030 | ** ieee754_to_blob(1.0) -> x'3ff0000000000000' |
3031 | ** |
3032 | ** In all single-argument functions, if the argument is an 8-byte blob |
3033 | ** then that blob is interpreted as a big-endian binary64 value. |
3034 | ** |
3035 | ** |
3036 | ** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES |
3037 | ** ----------------------------------------------- |
3038 | ** |
3039 | ** This extension in combination with the separate 'decimal' extension |
3040 | ** can be used to compute the exact decimal representation of binary64 |
3041 | ** values. To begin, first compute a table of exponent values: |
3042 | ** |
3043 | ** CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT); |
3044 | ** WITH RECURSIVE c(x,v) AS ( |
3045 | ** VALUES(0,'1') |
3046 | ** UNION ALL |
3047 | ** SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971 |
3048 | ** ) INSERT INTO pow2(x,v) SELECT x, v FROM c; |
3049 | ** WITH RECURSIVE c(x,v) AS ( |
3050 | ** VALUES(-1,'0.5') |
3051 | ** UNION ALL |
3052 | ** SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075 |
3053 | ** ) INSERT INTO pow2(x,v) SELECT x, v FROM c; |
3054 | ** |
3055 | ** Then, to compute the exact decimal representation of a floating |
3056 | ** point value (the value 47.49 is used in the example) do: |
3057 | ** |
3058 | ** WITH c(n) AS (VALUES(47.49)) |
3059 | ** ---------------^^^^^---- Replace with whatever you want |
3060 | ** SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v) |
3061 | ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n); |
3062 | ** |
3063 | ** Here is a query to show various boundry values for the binary64 |
3064 | ** number format: |
3065 | ** |
3066 | ** WITH c(name,bin) AS (VALUES |
3067 | ** ('minimum positive value', x'0000000000000001'), |
3068 | ** ('maximum subnormal value', x'000fffffffffffff'), |
3069 | ** ('mininum positive nornal value', x'0010000000000000'), |
3070 | ** ('maximum value', x'7fefffffffffffff')) |
3071 | ** SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v) |
3072 | ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin); |
3073 | ** |
3074 | */ |
3075 | /* #include "sqlite3ext.h" */ |
3076 | SQLITE_EXTENSION_INIT1 |
3077 | #include <assert.h> |
3078 | #include <string.h> |
3079 | |
3080 | /* Mark a function parameter as unused, to suppress nuisance compiler |
3081 | ** warnings. */ |
3082 | #ifndef UNUSED_PARAMETER |
3083 | # define UNUSED_PARAMETER(X) (void)(X) |
3084 | #endif |
3085 | |
3086 | /* |
3087 | ** Implementation of the ieee754() function |
3088 | */ |
3089 | static void ieee754func( |
3090 | sqlite3_context *context, |
3091 | int argc, |
3092 | sqlite3_value **argv |
3093 | ){ |
3094 | if( argc==1 ){ |
3095 | sqlite3_int64 m, a; |
3096 | double r; |
3097 | int e; |
3098 | int isNeg; |
3099 | char zResult[100]; |
3100 | assert( sizeof(m)==sizeof(r) ); |
3101 | if( sqlite3_value_type(argv[0])==SQLITE_BLOB |
3102 | && sqlite3_value_bytes(argv[0])==sizeof(r) |
3103 | ){ |
3104 | const unsigned char *x = sqlite3_value_blob(argv[0]); |
3105 | unsigned int i; |
3106 | sqlite3_uint64 v = 0; |
3107 | for(i=0; i<sizeof(r); i++){ |
3108 | v = (v<<8) | x[i]; |
3109 | } |
3110 | memcpy(&r, &v, sizeof(r)); |
3111 | }else{ |
3112 | r = sqlite3_value_double(argv[0]); |
3113 | } |
3114 | if( r<0.0 ){ |
3115 | isNeg = 1; |
3116 | r = -r; |
3117 | }else{ |
3118 | isNeg = 0; |
3119 | } |
3120 | memcpy(&a,&r,sizeof(a)); |
3121 | if( a==0 ){ |
3122 | e = 0; |
3123 | m = 0; |
3124 | }else{ |
3125 | e = a>>52; |
3126 | m = a & ((((sqlite3_int64)1)<<52)-1); |
3127 | if( e==0 ){ |
3128 | m <<= 1; |
3129 | }else{ |
3130 | m |= ((sqlite3_int64)1)<<52; |
3131 | } |
3132 | while( e<1075 && m>0 && (m&1)==0 ){ |
3133 | m >>= 1; |
3134 | e++; |
3135 | } |
3136 | if( isNeg ) m = -m; |
3137 | } |
3138 | switch( *(int*)sqlite3_user_data(context) ){ |
3139 | case 0: |
3140 | sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)" , |
3141 | m, e-1075); |
3142 | sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT); |
3143 | break; |
3144 | case 1: |
3145 | sqlite3_result_int64(context, m); |
3146 | break; |
3147 | case 2: |
3148 | sqlite3_result_int(context, e-1075); |
3149 | break; |
3150 | } |
3151 | }else{ |
3152 | sqlite3_int64 m, e, a; |
3153 | double r; |
3154 | int isNeg = 0; |
3155 | m = sqlite3_value_int64(argv[0]); |
3156 | e = sqlite3_value_int64(argv[1]); |
3157 | |
3158 | /* Limit the range of e. Ticket 22dea1cfdb9151e4 2021-03-02 */ |
3159 | if( e>10000 ){ |
3160 | e = 10000; |
3161 | }else if( e<-10000 ){ |
3162 | e = -10000; |
3163 | } |
3164 | |
3165 | if( m<0 ){ |
3166 | isNeg = 1; |
3167 | m = -m; |
3168 | if( m<0 ) return; |
3169 | }else if( m==0 && e>-1000 && e<1000 ){ |
3170 | sqlite3_result_double(context, 0.0); |
3171 | return; |
3172 | } |
3173 | while( (m>>32)&0xffe00000 ){ |
3174 | m >>= 1; |
3175 | e++; |
3176 | } |
3177 | while( m!=0 && ((m>>32)&0xfff00000)==0 ){ |
3178 | m <<= 1; |
3179 | e--; |
3180 | } |
3181 | e += 1075; |
3182 | if( e<=0 ){ |
3183 | /* Subnormal */ |
3184 | if( 1-e >= 64 ){ |
3185 | m = 0; |
3186 | }else{ |
3187 | m >>= 1-e; |
3188 | } |
3189 | e = 0; |
3190 | }else if( e>0x7ff ){ |
3191 | e = 0x7ff; |
3192 | } |
3193 | a = m & ((((sqlite3_int64)1)<<52)-1); |
3194 | a |= e<<52; |
3195 | if( isNeg ) a |= ((sqlite3_uint64)1)<<63; |
3196 | memcpy(&r, &a, sizeof(r)); |
3197 | sqlite3_result_double(context, r); |
3198 | } |
3199 | } |
3200 | |
3201 | /* |
3202 | ** Functions to convert between blobs and floats. |
3203 | */ |
3204 | static void ieee754func_from_blob( |
3205 | sqlite3_context *context, |
3206 | int argc, |
3207 | sqlite3_value **argv |
3208 | ){ |
3209 | UNUSED_PARAMETER(argc); |
3210 | if( sqlite3_value_type(argv[0])==SQLITE_BLOB |
3211 | && sqlite3_value_bytes(argv[0])==sizeof(double) |
3212 | ){ |
3213 | double r; |
3214 | const unsigned char *x = sqlite3_value_blob(argv[0]); |
3215 | unsigned int i; |
3216 | sqlite3_uint64 v = 0; |
3217 | for(i=0; i<sizeof(r); i++){ |
3218 | v = (v<<8) | x[i]; |
3219 | } |
3220 | memcpy(&r, &v, sizeof(r)); |
3221 | sqlite3_result_double(context, r); |
3222 | } |
3223 | } |
3224 | static void ieee754func_to_blob( |
3225 | sqlite3_context *context, |
3226 | int argc, |
3227 | sqlite3_value **argv |
3228 | ){ |
3229 | UNUSED_PARAMETER(argc); |
3230 | if( sqlite3_value_type(argv[0])==SQLITE_FLOAT |
3231 | || sqlite3_value_type(argv[0])==SQLITE_INTEGER |
3232 | ){ |
3233 | double r = sqlite3_value_double(argv[0]); |
3234 | sqlite3_uint64 v; |
3235 | unsigned char a[sizeof(r)]; |
3236 | unsigned int i; |
3237 | memcpy(&v, &r, sizeof(r)); |
3238 | for(i=1; i<=sizeof(r); i++){ |
3239 | a[sizeof(r)-i] = v&0xff; |
3240 | v >>= 8; |
3241 | } |
3242 | sqlite3_result_blob(context, a, sizeof(r), SQLITE_TRANSIENT); |
3243 | } |
3244 | } |
3245 | |
3246 | |
3247 | #ifdef _WIN32 |
3248 | |
3249 | #endif |
3250 | int sqlite3_ieee_init( |
3251 | sqlite3 *db, |
3252 | char **pzErrMsg, |
3253 | const sqlite3_api_routines *pApi |
3254 | ){ |
3255 | static const struct { |
3256 | char *zFName; |
3257 | int nArg; |
3258 | int iAux; |
3259 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**); |
3260 | } aFunc[] = { |
3261 | { "ieee754" , 1, 0, ieee754func }, |
3262 | { "ieee754" , 2, 0, ieee754func }, |
3263 | { "ieee754_mantissa" , 1, 1, ieee754func }, |
3264 | { "ieee754_exponent" , 1, 2, ieee754func }, |
3265 | { "ieee754_to_blob" , 1, 0, ieee754func_to_blob }, |
3266 | { "ieee754_from_blob" , 1, 0, ieee754func_from_blob }, |
3267 | |
3268 | }; |
3269 | unsigned int i; |
3270 | int rc = SQLITE_OK; |
3271 | SQLITE_EXTENSION_INIT2(pApi); |
3272 | (void)pzErrMsg; /* Unused parameter */ |
3273 | for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ |
3274 | rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg, |
3275 | SQLITE_UTF8|SQLITE_INNOCUOUS, |
3276 | (void*)&aFunc[i].iAux, |
3277 | aFunc[i].xFunc, 0, 0); |
3278 | } |
3279 | return rc; |
3280 | } |
3281 | |
3282 | /************************* End ../ext/misc/ieee754.c ********************/ |
3283 | /************************* Begin ../ext/misc/series.c ******************/ |
3284 | /* |
3285 | ** 2015-08-18 |
3286 | ** |
3287 | ** The author disclaims copyright to this source code. In place of |
3288 | ** a legal notice, here is a blessing: |
3289 | ** |
3290 | ** May you do good and not evil. |
3291 | ** May you find forgiveness for yourself and forgive others. |
3292 | ** May you share freely, never taking more than you give. |
3293 | ** |
3294 | ************************************************************************* |
3295 | ** |
3296 | ** This file demonstrates how to create a table-valued-function using |
3297 | ** a virtual table. This demo implements the generate_series() function |
3298 | ** which gives similar results to the eponymous function in PostgreSQL. |
3299 | ** Examples: |
3300 | ** |
3301 | ** SELECT * FROM generate_series(0,100,5); |
3302 | ** |
3303 | ** The query above returns integers from 0 through 100 counting by steps |
3304 | ** of 5. |
3305 | ** |
3306 | ** SELECT * FROM generate_series(0,100); |
3307 | ** |
3308 | ** Integers from 0 through 100 with a step size of 1. |
3309 | ** |
3310 | ** SELECT * FROM generate_series(20) LIMIT 10; |
3311 | ** |
3312 | ** Integers 20 through 29. |
3313 | ** |
3314 | ** HOW IT WORKS |
3315 | ** |
3316 | ** The generate_series "function" is really a virtual table with the |
3317 | ** following schema: |
3318 | ** |
3319 | ** CREATE TABLE generate_series( |
3320 | ** value, |
3321 | ** start HIDDEN, |
3322 | ** stop HIDDEN, |
3323 | ** step HIDDEN |
3324 | ** ); |
3325 | ** |
3326 | ** Function arguments in queries against this virtual table are translated |
3327 | ** into equality constraints against successive hidden columns. In other |
3328 | ** words, the following pairs of queries are equivalent to each other: |
3329 | ** |
3330 | ** SELECT * FROM generate_series(0,100,5); |
3331 | ** SELECT * FROM generate_series WHERE start=0 AND stop=100 AND step=5; |
3332 | ** |
3333 | ** SELECT * FROM generate_series(0,100); |
3334 | ** SELECT * FROM generate_series WHERE start=0 AND stop=100; |
3335 | ** |
3336 | ** SELECT * FROM generate_series(20) LIMIT 10; |
3337 | ** SELECT * FROM generate_series WHERE start=20 LIMIT 10; |
3338 | ** |
3339 | ** The generate_series virtual table implementation leaves the xCreate method |
3340 | ** set to NULL. This means that it is not possible to do a CREATE VIRTUAL |
3341 | ** TABLE command with "generate_series" as the USING argument. Instead, there |
3342 | ** is a single generate_series virtual table that is always available without |
3343 | ** having to be created first. |
3344 | ** |
3345 | ** The xBestIndex method looks for equality constraints against the hidden |
3346 | ** start, stop, and step columns, and if present, it uses those constraints |
3347 | ** to bound the sequence of generated values. If the equality constraints |
3348 | ** are missing, it uses 0 for start, 4294967295 for stop, and 1 for step. |
3349 | ** xBestIndex returns a small cost when both start and stop are available, |
3350 | ** and a very large cost if either start or stop are unavailable. This |
3351 | ** encourages the query planner to order joins such that the bounds of the |
3352 | ** series are well-defined. |
3353 | */ |
3354 | /* #include "sqlite3ext.h" */ |
3355 | SQLITE_EXTENSION_INIT1 |
3356 | #include <assert.h> |
3357 | #include <string.h> |
3358 | |
3359 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
3360 | |
3361 | |
3362 | /* series_cursor is a subclass of sqlite3_vtab_cursor which will |
3363 | ** serve as the underlying representation of a cursor that scans |
3364 | ** over rows of the result |
3365 | */ |
3366 | typedef struct series_cursor series_cursor; |
3367 | struct series_cursor { |
3368 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
3369 | int isDesc; /* True to count down rather than up */ |
3370 | sqlite3_int64 iRowid; /* The rowid */ |
3371 | sqlite3_int64 iValue; /* Current value ("value") */ |
3372 | sqlite3_int64 mnValue; /* Mimimum value ("start") */ |
3373 | sqlite3_int64 mxValue; /* Maximum value ("stop") */ |
3374 | sqlite3_int64 iStep; /* Increment ("step") */ |
3375 | }; |
3376 | |
3377 | /* |
3378 | ** The seriesConnect() method is invoked to create a new |
3379 | ** series_vtab that describes the generate_series virtual table. |
3380 | ** |
3381 | ** Think of this routine as the constructor for series_vtab objects. |
3382 | ** |
3383 | ** All this routine needs to do is: |
3384 | ** |
3385 | ** (1) Allocate the series_vtab object and initialize all fields. |
3386 | ** |
3387 | ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the |
3388 | ** result set of queries against generate_series will look like. |
3389 | */ |
3390 | static int seriesConnect( |
3391 | sqlite3 *db, |
3392 | void *pUnused, |
3393 | int argcUnused, const char *const*argvUnused, |
3394 | sqlite3_vtab **ppVtab, |
3395 | char **pzErrUnused |
3396 | ){ |
3397 | sqlite3_vtab *pNew; |
3398 | int rc; |
3399 | |
3400 | /* Column numbers */ |
3401 | #define SERIES_COLUMN_VALUE 0 |
3402 | #define SERIES_COLUMN_START 1 |
3403 | #define SERIES_COLUMN_STOP 2 |
3404 | #define SERIES_COLUMN_STEP 3 |
3405 | |
3406 | (void)pUnused; |
3407 | (void)argcUnused; |
3408 | (void)argvUnused; |
3409 | (void)pzErrUnused; |
3410 | rc = sqlite3_declare_vtab(db, |
3411 | "CREATE TABLE x(value,start hidden,stop hidden,step hidden)" ); |
3412 | if( rc==SQLITE_OK ){ |
3413 | pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); |
3414 | if( pNew==0 ) return SQLITE_NOMEM; |
3415 | memset(pNew, 0, sizeof(*pNew)); |
3416 | sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); |
3417 | } |
3418 | return rc; |
3419 | } |
3420 | |
3421 | /* |
3422 | ** This method is the destructor for series_cursor objects. |
3423 | */ |
3424 | static int seriesDisconnect(sqlite3_vtab *pVtab){ |
3425 | sqlite3_free(pVtab); |
3426 | return SQLITE_OK; |
3427 | } |
3428 | |
3429 | /* |
3430 | ** Constructor for a new series_cursor object. |
3431 | */ |
3432 | static int seriesOpen(sqlite3_vtab *pUnused, sqlite3_vtab_cursor **ppCursor){ |
3433 | series_cursor *pCur; |
3434 | (void)pUnused; |
3435 | pCur = sqlite3_malloc( sizeof(*pCur) ); |
3436 | if( pCur==0 ) return SQLITE_NOMEM; |
3437 | memset(pCur, 0, sizeof(*pCur)); |
3438 | *ppCursor = &pCur->base; |
3439 | return SQLITE_OK; |
3440 | } |
3441 | |
3442 | /* |
3443 | ** Destructor for a series_cursor. |
3444 | */ |
3445 | static int seriesClose(sqlite3_vtab_cursor *cur){ |
3446 | sqlite3_free(cur); |
3447 | return SQLITE_OK; |
3448 | } |
3449 | |
3450 | |
3451 | /* |
3452 | ** Advance a series_cursor to its next row of output. |
3453 | */ |
3454 | static int seriesNext(sqlite3_vtab_cursor *cur){ |
3455 | series_cursor *pCur = (series_cursor*)cur; |
3456 | if( pCur->isDesc ){ |
3457 | pCur->iValue -= pCur->iStep; |
3458 | }else{ |
3459 | pCur->iValue += pCur->iStep; |
3460 | } |
3461 | pCur->iRowid++; |
3462 | return SQLITE_OK; |
3463 | } |
3464 | |
3465 | /* |
3466 | ** Return values of columns for the row at which the series_cursor |
3467 | ** is currently pointing. |
3468 | */ |
3469 | static int seriesColumn( |
3470 | sqlite3_vtab_cursor *cur, /* The cursor */ |
3471 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
3472 | int i /* Which column to return */ |
3473 | ){ |
3474 | series_cursor *pCur = (series_cursor*)cur; |
3475 | sqlite3_int64 x = 0; |
3476 | switch( i ){ |
3477 | case SERIES_COLUMN_START: x = pCur->mnValue; break; |
3478 | case SERIES_COLUMN_STOP: x = pCur->mxValue; break; |
3479 | case SERIES_COLUMN_STEP: x = pCur->iStep; break; |
3480 | default: x = pCur->iValue; break; |
3481 | } |
3482 | sqlite3_result_int64(ctx, x); |
3483 | return SQLITE_OK; |
3484 | } |
3485 | |
3486 | /* |
3487 | ** Return the rowid for the current row. In this implementation, the |
3488 | ** first row returned is assigned rowid value 1, and each subsequent |
3489 | ** row a value 1 more than that of the previous. |
3490 | */ |
3491 | static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
3492 | series_cursor *pCur = (series_cursor*)cur; |
3493 | *pRowid = pCur->iRowid; |
3494 | return SQLITE_OK; |
3495 | } |
3496 | |
3497 | /* |
3498 | ** Return TRUE if the cursor has been moved off of the last |
3499 | ** row of output. |
3500 | */ |
3501 | static int seriesEof(sqlite3_vtab_cursor *cur){ |
3502 | series_cursor *pCur = (series_cursor*)cur; |
3503 | if( pCur->isDesc ){ |
3504 | return pCur->iValue < pCur->mnValue; |
3505 | }else{ |
3506 | return pCur->iValue > pCur->mxValue; |
3507 | } |
3508 | } |
3509 | |
3510 | /* True to cause run-time checking of the start=, stop=, and/or step= |
3511 | ** parameters. The only reason to do this is for testing the |
3512 | ** constraint checking logic for virtual tables in the SQLite core. |
3513 | */ |
3514 | #ifndef SQLITE_SERIES_CONSTRAINT_VERIFY |
3515 | # define SQLITE_SERIES_CONSTRAINT_VERIFY 0 |
3516 | #endif |
3517 | |
3518 | /* |
3519 | ** This method is called to "rewind" the series_cursor object back |
3520 | ** to the first row of output. This method is always called at least |
3521 | ** once prior to any call to seriesColumn() or seriesRowid() or |
3522 | ** seriesEof(). |
3523 | ** |
3524 | ** The query plan selected by seriesBestIndex is passed in the idxNum |
3525 | ** parameter. (idxStr is not used in this implementation.) idxNum |
3526 | ** is a bitmask showing which constraints are available: |
3527 | ** |
3528 | ** 1: start=VALUE |
3529 | ** 2: stop=VALUE |
3530 | ** 4: step=VALUE |
3531 | ** |
3532 | ** Also, if bit 8 is set, that means that the series should be output |
3533 | ** in descending order rather than in ascending order. If bit 16 is |
3534 | ** set, then output must appear in ascending order. |
3535 | ** |
3536 | ** This routine should initialize the cursor and position it so that it |
3537 | ** is pointing at the first row, or pointing off the end of the table |
3538 | ** (so that seriesEof() will return true) if the table is empty. |
3539 | */ |
3540 | static int seriesFilter( |
3541 | sqlite3_vtab_cursor *pVtabCursor, |
3542 | int idxNum, const char *idxStrUnused, |
3543 | int argc, sqlite3_value **argv |
3544 | ){ |
3545 | series_cursor *pCur = (series_cursor *)pVtabCursor; |
3546 | int i = 0; |
3547 | (void)idxStrUnused; |
3548 | if( idxNum & 1 ){ |
3549 | pCur->mnValue = sqlite3_value_int64(argv[i++]); |
3550 | }else{ |
3551 | pCur->mnValue = 0; |
3552 | } |
3553 | if( idxNum & 2 ){ |
3554 | pCur->mxValue = sqlite3_value_int64(argv[i++]); |
3555 | }else{ |
3556 | pCur->mxValue = 0xffffffff; |
3557 | } |
3558 | if( idxNum & 4 ){ |
3559 | pCur->iStep = sqlite3_value_int64(argv[i++]); |
3560 | if( pCur->iStep==0 ){ |
3561 | pCur->iStep = 1; |
3562 | }else if( pCur->iStep<0 ){ |
3563 | pCur->iStep = -pCur->iStep; |
3564 | if( (idxNum & 16)==0 ) idxNum |= 8; |
3565 | } |
3566 | }else{ |
3567 | pCur->iStep = 1; |
3568 | } |
3569 | for(i=0; i<argc; i++){ |
3570 | if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ |
3571 | /* If any of the constraints have a NULL value, then return no rows. |
3572 | ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */ |
3573 | pCur->mnValue = 1; |
3574 | pCur->mxValue = 0; |
3575 | break; |
3576 | } |
3577 | } |
3578 | if( idxNum & 8 ){ |
3579 | pCur->isDesc = 1; |
3580 | pCur->iValue = pCur->mxValue; |
3581 | if( pCur->iStep>0 ){ |
3582 | pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep; |
3583 | } |
3584 | }else{ |
3585 | pCur->isDesc = 0; |
3586 | pCur->iValue = pCur->mnValue; |
3587 | } |
3588 | pCur->iRowid = 1; |
3589 | return SQLITE_OK; |
3590 | } |
3591 | |
3592 | /* |
3593 | ** SQLite will invoke this method one or more times while planning a query |
3594 | ** that uses the generate_series virtual table. This routine needs to create |
3595 | ** a query plan for each invocation and compute an estimated cost for that |
3596 | ** plan. |
3597 | ** |
3598 | ** In this implementation idxNum is used to represent the |
3599 | ** query plan. idxStr is unused. |
3600 | ** |
3601 | ** The query plan is represented by bits in idxNum: |
3602 | ** |
3603 | ** (1) start = $value -- constraint exists |
3604 | ** (2) stop = $value -- constraint exists |
3605 | ** (4) step = $value -- constraint exists |
3606 | ** (8) output in descending order |
3607 | */ |
3608 | static int seriesBestIndex( |
3609 | sqlite3_vtab *pVTab, |
3610 | sqlite3_index_info *pIdxInfo |
3611 | ){ |
3612 | int i, j; /* Loop over constraints */ |
3613 | int idxNum = 0; /* The query plan bitmask */ |
3614 | int bStartSeen = 0; /* EQ constraint seen on the START column */ |
3615 | int unusableMask = 0; /* Mask of unusable constraints */ |
3616 | int nArg = 0; /* Number of arguments that seriesFilter() expects */ |
3617 | int aIdx[3]; /* Constraints on start, stop, and step */ |
3618 | const struct sqlite3_index_constraint *pConstraint; |
3619 | |
3620 | /* This implementation assumes that the start, stop, and step columns |
3621 | ** are the last three columns in the virtual table. */ |
3622 | assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 ); |
3623 | assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 ); |
3624 | |
3625 | aIdx[0] = aIdx[1] = aIdx[2] = -1; |
3626 | pConstraint = pIdxInfo->aConstraint; |
3627 | for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
3628 | int iCol; /* 0 for start, 1 for stop, 2 for step */ |
3629 | int iMask; /* bitmask for those column */ |
3630 | if( pConstraint->iColumn<SERIES_COLUMN_START ) continue; |
3631 | iCol = pConstraint->iColumn - SERIES_COLUMN_START; |
3632 | assert( iCol>=0 && iCol<=2 ); |
3633 | iMask = 1 << iCol; |
3634 | if( iCol==0 ) bStartSeen = 1; |
3635 | if( pConstraint->usable==0 ){ |
3636 | unusableMask |= iMask; |
3637 | continue; |
3638 | }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
3639 | idxNum |= iMask; |
3640 | aIdx[iCol] = i; |
3641 | } |
3642 | } |
3643 | for(i=0; i<3; i++){ |
3644 | if( (j = aIdx[i])>=0 ){ |
3645 | pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg; |
3646 | pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY; |
3647 | } |
3648 | } |
3649 | /* The current generate_column() implementation requires at least one |
3650 | ** argument (the START value). Legacy versions assumed START=0 if the |
3651 | ** first argument was omitted. Compile with -DZERO_ARGUMENT_GENERATE_SERIES |
3652 | ** to obtain the legacy behavior */ |
3653 | #ifndef ZERO_ARGUMENT_GENERATE_SERIES |
3654 | if( !bStartSeen ){ |
3655 | sqlite3_free(pVTab->zErrMsg); |
3656 | pVTab->zErrMsg = sqlite3_mprintf( |
3657 | "first argument to \"generate_series()\" missing or unusable" ); |
3658 | return SQLITE_ERROR; |
3659 | } |
3660 | #endif |
3661 | if( (unusableMask & ~idxNum)!=0 ){ |
3662 | /* The start, stop, and step columns are inputs. Therefore if there |
3663 | ** are unusable constraints on any of start, stop, or step then |
3664 | ** this plan is unusable */ |
3665 | return SQLITE_CONSTRAINT; |
3666 | } |
3667 | if( (idxNum & 3)==3 ){ |
3668 | /* Both start= and stop= boundaries are available. This is the |
3669 | ** the preferred case */ |
3670 | pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); |
3671 | pIdxInfo->estimatedRows = 1000; |
3672 | if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){ |
3673 | if( pIdxInfo->aOrderBy[0].desc ){ |
3674 | idxNum |= 8; |
3675 | }else{ |
3676 | idxNum |= 16; |
3677 | } |
3678 | pIdxInfo->orderByConsumed = 1; |
3679 | } |
3680 | }else{ |
3681 | /* If either boundary is missing, we have to generate a huge span |
3682 | ** of numbers. Make this case very expensive so that the query |
3683 | ** planner will work hard to avoid it. */ |
3684 | pIdxInfo->estimatedRows = 2147483647; |
3685 | } |
3686 | pIdxInfo->idxNum = idxNum; |
3687 | return SQLITE_OK; |
3688 | } |
3689 | |
3690 | /* |
3691 | ** This following structure defines all the methods for the |
3692 | ** generate_series virtual table. |
3693 | */ |
3694 | static sqlite3_module seriesModule = { |
3695 | 0, /* iVersion */ |
3696 | 0, /* xCreate */ |
3697 | seriesConnect, /* xConnect */ |
3698 | seriesBestIndex, /* xBestIndex */ |
3699 | seriesDisconnect, /* xDisconnect */ |
3700 | 0, /* xDestroy */ |
3701 | seriesOpen, /* xOpen - open a cursor */ |
3702 | seriesClose, /* xClose - close a cursor */ |
3703 | seriesFilter, /* xFilter - configure scan constraints */ |
3704 | seriesNext, /* xNext - advance a cursor */ |
3705 | seriesEof, /* xEof - check for end of scan */ |
3706 | seriesColumn, /* xColumn - read data */ |
3707 | seriesRowid, /* xRowid - read data */ |
3708 | 0, /* xUpdate */ |
3709 | 0, /* xBegin */ |
3710 | 0, /* xSync */ |
3711 | 0, /* xCommit */ |
3712 | 0, /* xRollback */ |
3713 | 0, /* xFindMethod */ |
3714 | 0, /* xRename */ |
3715 | 0, /* xSavepoint */ |
3716 | 0, /* xRelease */ |
3717 | 0, /* xRollbackTo */ |
3718 | 0 /* xShadowName */ |
3719 | }; |
3720 | |
3721 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
3722 | |
3723 | #ifdef _WIN32 |
3724 | |
3725 | #endif |
3726 | int sqlite3_series_init( |
3727 | sqlite3 *db, |
3728 | char **pzErrMsg, |
3729 | const sqlite3_api_routines *pApi |
3730 | ){ |
3731 | int rc = SQLITE_OK; |
3732 | SQLITE_EXTENSION_INIT2(pApi); |
3733 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
3734 | if( sqlite3_libversion_number()<3008012 && pzErrMsg!=0 ){ |
3735 | *pzErrMsg = sqlite3_mprintf( |
3736 | "generate_series() requires SQLite 3.8.12 or later" ); |
3737 | return SQLITE_ERROR; |
3738 | } |
3739 | rc = sqlite3_create_module(db, "generate_series" , &seriesModule, 0); |
3740 | #endif |
3741 | return rc; |
3742 | } |
3743 | |
3744 | /************************* End ../ext/misc/series.c ********************/ |
3745 | /************************* Begin ../ext/misc/regexp.c ******************/ |
3746 | /* |
3747 | ** 2012-11-13 |
3748 | ** |
3749 | ** The author disclaims copyright to this source code. In place of |
3750 | ** a legal notice, here is a blessing: |
3751 | ** |
3752 | ** May you do good and not evil. |
3753 | ** May you find forgiveness for yourself and forgive others. |
3754 | ** May you share freely, never taking more than you give. |
3755 | ** |
3756 | ****************************************************************************** |
3757 | ** |
3758 | ** The code in this file implements a compact but reasonably |
3759 | ** efficient regular-expression matcher for posix extended regular |
3760 | ** expressions against UTF8 text. |
3761 | ** |
3762 | ** This file is an SQLite extension. It registers a single function |
3763 | ** named "regexp(A,B)" where A is the regular expression and B is the |
3764 | ** string to be matched. By registering this function, SQLite will also |
3765 | ** then implement the "B regexp A" operator. Note that with the function |
3766 | ** the regular expression comes first, but with the operator it comes |
3767 | ** second. |
3768 | ** |
3769 | ** The following regular expression syntax is supported: |
3770 | ** |
3771 | ** X* zero or more occurrences of X |
3772 | ** X+ one or more occurrences of X |
3773 | ** X? zero or one occurrences of X |
3774 | ** X{p,q} between p and q occurrences of X |
3775 | ** (X) match X |
3776 | ** X|Y X or Y |
3777 | ** ^X X occurring at the beginning of the string |
3778 | ** X$ X occurring at the end of the string |
3779 | ** . Match any single character |
3780 | ** \c Character c where c is one of \{}()[]|*+?. |
3781 | ** \c C-language escapes for c in afnrtv. ex: \t or \n |
3782 | ** \uXXXX Where XXXX is exactly 4 hex digits, unicode value XXXX |
3783 | ** \xXX Where XX is exactly 2 hex digits, unicode value XX |
3784 | ** [abc] Any single character from the set abc |
3785 | ** [^abc] Any single character not in the set abc |
3786 | ** [a-z] Any single character in the range a-z |
3787 | ** [^a-z] Any single character not in the range a-z |
3788 | ** \b Word boundary |
3789 | ** \w Word character. [A-Za-z0-9_] |
3790 | ** \W Non-word character |
3791 | ** \d Digit |
3792 | ** \D Non-digit |
3793 | ** \s Whitespace character |
3794 | ** \S Non-whitespace character |
3795 | ** |
3796 | ** A nondeterministic finite automaton (NFA) is used for matching, so the |
3797 | ** performance is bounded by O(N*M) where N is the size of the regular |
3798 | ** expression and M is the size of the input string. The matcher never |
3799 | ** exhibits exponential behavior. Note that the X{p,q} operator expands |
3800 | ** to p copies of X following by q-p copies of X? and that the size of the |
3801 | ** regular expression in the O(N*M) performance bound is computed after |
3802 | ** this expansion. |
3803 | */ |
3804 | #include <string.h> |
3805 | #include <stdlib.h> |
3806 | /* #include "sqlite3ext.h" */ |
3807 | SQLITE_EXTENSION_INIT1 |
3808 | |
3809 | /* |
3810 | ** The following #defines change the names of some functions implemented in |
3811 | ** this file to prevent name collisions with C-library functions of the |
3812 | ** same name. |
3813 | */ |
3814 | #define re_match sqlite3re_match |
3815 | #define re_compile sqlite3re_compile |
3816 | #define re_free sqlite3re_free |
3817 | |
3818 | /* The end-of-input character */ |
3819 | #define RE_EOF 0 /* End of input */ |
3820 | #define RE_START 0xfffffff /* Start of input - larger than an UTF-8 */ |
3821 | |
3822 | /* The NFA is implemented as sequence of opcodes taken from the following |
3823 | ** set. Each opcode has a single integer argument. |
3824 | */ |
3825 | #define RE_OP_MATCH 1 /* Match the one character in the argument */ |
3826 | #define RE_OP_ANY 2 /* Match any one character. (Implements ".") */ |
3827 | #define RE_OP_ANYSTAR 3 /* Special optimized version of .* */ |
3828 | #define RE_OP_FORK 4 /* Continue to both next and opcode at iArg */ |
3829 | #define RE_OP_GOTO 5 /* Jump to opcode at iArg */ |
3830 | #define RE_OP_ACCEPT 6 /* Halt and indicate a successful match */ |
3831 | #define RE_OP_CC_INC 7 /* Beginning of a [...] character class */ |
3832 | #define RE_OP_CC_EXC 8 /* Beginning of a [^...] character class */ |
3833 | #define RE_OP_CC_VALUE 9 /* Single value in a character class */ |
3834 | #define RE_OP_CC_RANGE 10 /* Range of values in a character class */ |
3835 | #define RE_OP_WORD 11 /* Perl word character [A-Za-z0-9_] */ |
3836 | #define RE_OP_NOTWORD 12 /* Not a perl word character */ |
3837 | #define RE_OP_DIGIT 13 /* digit: [0-9] */ |
3838 | #define RE_OP_NOTDIGIT 14 /* Not a digit */ |
3839 | #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */ |
3840 | #define RE_OP_NOTSPACE 16 /* Not a digit */ |
3841 | #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */ |
3842 | #define RE_OP_ATSTART 18 /* Currently at the start of the string */ |
3843 | |
3844 | #if defined(SQLITE_DEBUG) |
3845 | /* Opcode names used for symbolic debugging */ |
3846 | static const char *ReOpName[] = { |
3847 | "EOF" , |
3848 | "MATCH" , |
3849 | "ANY" , |
3850 | "ANYSTAR" , |
3851 | "FORK" , |
3852 | "GOTO" , |
3853 | "ACCEPT" , |
3854 | "CC_INC" , |
3855 | "CC_EXC" , |
3856 | "CC_VALUE" , |
3857 | "CC_RANGE" , |
3858 | "WORD" , |
3859 | "NOTWORD" , |
3860 | "DIGIT" , |
3861 | "NOTDIGIT" , |
3862 | "SPACE" , |
3863 | "NOTSPACE" , |
3864 | "BOUNDARY" , |
3865 | "ATSTART" , |
3866 | }; |
3867 | #endif /* SQLITE_DEBUG */ |
3868 | |
3869 | |
3870 | /* Each opcode is a "state" in the NFA */ |
3871 | typedef unsigned short ReStateNumber; |
3872 | |
3873 | /* Because this is an NFA and not a DFA, multiple states can be active at |
3874 | ** once. An instance of the following object records all active states in |
3875 | ** the NFA. The implementation is optimized for the common case where the |
3876 | ** number of actives states is small. |
3877 | */ |
3878 | typedef struct ReStateSet { |
3879 | unsigned nState; /* Number of current states */ |
3880 | ReStateNumber *aState; /* Current states */ |
3881 | } ReStateSet; |
3882 | |
3883 | /* An input string read one character at a time. |
3884 | */ |
3885 | typedef struct ReInput ReInput; |
3886 | struct ReInput { |
3887 | const unsigned char *z; /* All text */ |
3888 | int i; /* Next byte to read */ |
3889 | int mx; /* EOF when i>=mx */ |
3890 | }; |
3891 | |
3892 | /* A compiled NFA (or an NFA that is in the process of being compiled) is |
3893 | ** an instance of the following object. |
3894 | */ |
3895 | typedef struct ReCompiled ReCompiled; |
3896 | struct ReCompiled { |
3897 | ReInput sIn; /* Regular expression text */ |
3898 | const char *zErr; /* Error message to return */ |
3899 | char *aOp; /* Operators for the virtual machine */ |
3900 | int *aArg; /* Arguments to each operator */ |
3901 | unsigned (*xNextChar)(ReInput*); /* Next character function */ |
3902 | unsigned char zInit[12]; /* Initial text to match */ |
3903 | int nInit; /* Number of bytes in zInit */ |
3904 | unsigned nState; /* Number of entries in aOp[] and aArg[] */ |
3905 | unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */ |
3906 | }; |
3907 | |
3908 | /* Add a state to the given state set if it is not already there */ |
3909 | static void re_add_state(ReStateSet *pSet, int newState){ |
3910 | unsigned i; |
3911 | for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return; |
3912 | pSet->aState[pSet->nState++] = (ReStateNumber)newState; |
3913 | } |
3914 | |
3915 | /* Extract the next unicode character from *pzIn and return it. Advance |
3916 | ** *pzIn to the first byte past the end of the character returned. To |
3917 | ** be clear: this routine converts utf8 to unicode. This routine is |
3918 | ** optimized for the common case where the next character is a single byte. |
3919 | */ |
3920 | static unsigned re_next_char(ReInput *p){ |
3921 | unsigned c; |
3922 | if( p->i>=p->mx ) return 0; |
3923 | c = p->z[p->i++]; |
3924 | if( c>=0x80 ){ |
3925 | if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){ |
3926 | c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f); |
3927 | if( c<0x80 ) c = 0xfffd; |
3928 | }else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80 |
3929 | && (p->z[p->i+1]&0xc0)==0x80 ){ |
3930 | c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f); |
3931 | p->i += 2; |
3932 | if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd; |
3933 | }else if( (c&0xf8)==0xf0 && p->i+2<p->mx && (p->z[p->i]&0xc0)==0x80 |
3934 | && (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){ |
3935 | c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6) |
3936 | | (p->z[p->i+2]&0x3f); |
3937 | p->i += 3; |
3938 | if( c<=0xffff || c>0x10ffff ) c = 0xfffd; |
3939 | }else{ |
3940 | c = 0xfffd; |
3941 | } |
3942 | } |
3943 | return c; |
3944 | } |
3945 | static unsigned re_next_char_nocase(ReInput *p){ |
3946 | unsigned c = re_next_char(p); |
3947 | if( c>='A' && c<='Z' ) c += 'a' - 'A'; |
3948 | return c; |
3949 | } |
3950 | |
3951 | /* Return true if c is a perl "word" character: [A-Za-z0-9_] */ |
3952 | static int re_word_char(int c){ |
3953 | return (c>='0' && c<='9') || (c>='a' && c<='z') |
3954 | || (c>='A' && c<='Z') || c=='_'; |
3955 | } |
3956 | |
3957 | /* Return true if c is a "digit" character: [0-9] */ |
3958 | static int re_digit_char(int c){ |
3959 | return (c>='0' && c<='9'); |
3960 | } |
3961 | |
3962 | /* Return true if c is a perl "space" character: [ \t\r\n\v\f] */ |
3963 | static int re_space_char(int c){ |
3964 | return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f'; |
3965 | } |
3966 | |
3967 | /* Run a compiled regular expression on the zero-terminated input |
3968 | ** string zIn[]. Return true on a match and false if there is no match. |
3969 | */ |
3970 | static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){ |
3971 | ReStateSet aStateSet[2], *pThis, *pNext; |
3972 | ReStateNumber aSpace[100]; |
3973 | ReStateNumber *pToFree; |
3974 | unsigned int i = 0; |
3975 | unsigned int iSwap = 0; |
3976 | int c = RE_START; |
3977 | int cPrev = 0; |
3978 | int rc = 0; |
3979 | ReInput in; |
3980 | |
3981 | in.z = zIn; |
3982 | in.i = 0; |
3983 | in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn); |
3984 | |
3985 | /* Look for the initial prefix match, if there is one. */ |
3986 | if( pRe->nInit ){ |
3987 | unsigned char x = pRe->zInit[0]; |
3988 | while( in.i+pRe->nInit<=in.mx |
3989 | && (zIn[in.i]!=x || |
3990 | strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0) |
3991 | ){ |
3992 | in.i++; |
3993 | } |
3994 | if( in.i+pRe->nInit>in.mx ) return 0; |
3995 | c = RE_START-1; |
3996 | } |
3997 | |
3998 | if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){ |
3999 | pToFree = 0; |
4000 | aStateSet[0].aState = aSpace; |
4001 | }else{ |
4002 | pToFree = sqlite3_malloc64( sizeof(ReStateNumber)*2*pRe->nState ); |
4003 | if( pToFree==0 ) return -1; |
4004 | aStateSet[0].aState = pToFree; |
4005 | } |
4006 | aStateSet[1].aState = &aStateSet[0].aState[pRe->nState]; |
4007 | pNext = &aStateSet[1]; |
4008 | pNext->nState = 0; |
4009 | re_add_state(pNext, 0); |
4010 | while( c!=RE_EOF && pNext->nState>0 ){ |
4011 | cPrev = c; |
4012 | c = pRe->xNextChar(&in); |
4013 | pThis = pNext; |
4014 | pNext = &aStateSet[iSwap]; |
4015 | iSwap = 1 - iSwap; |
4016 | pNext->nState = 0; |
4017 | for(i=0; i<pThis->nState; i++){ |
4018 | int x = pThis->aState[i]; |
4019 | switch( pRe->aOp[x] ){ |
4020 | case RE_OP_MATCH: { |
4021 | if( pRe->aArg[x]==c ) re_add_state(pNext, x+1); |
4022 | break; |
4023 | } |
4024 | case RE_OP_ATSTART: { |
4025 | if( cPrev==RE_START ) re_add_state(pThis, x+1); |
4026 | break; |
4027 | } |
4028 | case RE_OP_ANY: { |
4029 | if( c!=0 ) re_add_state(pNext, x+1); |
4030 | break; |
4031 | } |
4032 | case RE_OP_WORD: { |
4033 | if( re_word_char(c) ) re_add_state(pNext, x+1); |
4034 | break; |
4035 | } |
4036 | case RE_OP_NOTWORD: { |
4037 | if( !re_word_char(c) && c!=0 ) re_add_state(pNext, x+1); |
4038 | break; |
4039 | } |
4040 | case RE_OP_DIGIT: { |
4041 | if( re_digit_char(c) ) re_add_state(pNext, x+1); |
4042 | break; |
4043 | } |
4044 | case RE_OP_NOTDIGIT: { |
4045 | if( !re_digit_char(c) && c!=0 ) re_add_state(pNext, x+1); |
4046 | break; |
4047 | } |
4048 | case RE_OP_SPACE: { |
4049 | if( re_space_char(c) ) re_add_state(pNext, x+1); |
4050 | break; |
4051 | } |
4052 | case RE_OP_NOTSPACE: { |
4053 | if( !re_space_char(c) && c!=0 ) re_add_state(pNext, x+1); |
4054 | break; |
4055 | } |
4056 | case RE_OP_BOUNDARY: { |
4057 | if( re_word_char(c)!=re_word_char(cPrev) ) re_add_state(pThis, x+1); |
4058 | break; |
4059 | } |
4060 | case RE_OP_ANYSTAR: { |
4061 | re_add_state(pNext, x); |
4062 | re_add_state(pThis, x+1); |
4063 | break; |
4064 | } |
4065 | case RE_OP_FORK: { |
4066 | re_add_state(pThis, x+pRe->aArg[x]); |
4067 | re_add_state(pThis, x+1); |
4068 | break; |
4069 | } |
4070 | case RE_OP_GOTO: { |
4071 | re_add_state(pThis, x+pRe->aArg[x]); |
4072 | break; |
4073 | } |
4074 | case RE_OP_ACCEPT: { |
4075 | rc = 1; |
4076 | goto re_match_end; |
4077 | } |
4078 | case RE_OP_CC_EXC: { |
4079 | if( c==0 ) break; |
4080 | /* fall-through */ goto re_op_cc_inc; |
4081 | } |
4082 | case RE_OP_CC_INC: re_op_cc_inc: { |
4083 | int j = 1; |
4084 | int n = pRe->aArg[x]; |
4085 | int hit = 0; |
4086 | for(j=1; j>0 && j<n; j++){ |
4087 | if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){ |
4088 | if( pRe->aArg[x+j]==c ){ |
4089 | hit = 1; |
4090 | j = -1; |
4091 | } |
4092 | }else{ |
4093 | if( pRe->aArg[x+j]<=c && pRe->aArg[x+j+1]>=c ){ |
4094 | hit = 1; |
4095 | j = -1; |
4096 | }else{ |
4097 | j++; |
4098 | } |
4099 | } |
4100 | } |
4101 | if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit; |
4102 | if( hit ) re_add_state(pNext, x+n); |
4103 | break; |
4104 | } |
4105 | } |
4106 | } |
4107 | } |
4108 | for(i=0; i<pNext->nState; i++){ |
4109 | int x = pNext->aState[i]; |
4110 | while( pRe->aOp[x]==RE_OP_GOTO ) x += pRe->aArg[x]; |
4111 | if( pRe->aOp[x]==RE_OP_ACCEPT ){ rc = 1; break; } |
4112 | } |
4113 | re_match_end: |
4114 | sqlite3_free(pToFree); |
4115 | return rc; |
4116 | } |
4117 | |
4118 | /* Resize the opcode and argument arrays for an RE under construction. |
4119 | */ |
4120 | static int re_resize(ReCompiled *p, int N){ |
4121 | char *aOp; |
4122 | int *aArg; |
4123 | aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0])); |
4124 | if( aOp==0 ) return 1; |
4125 | p->aOp = aOp; |
4126 | aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0])); |
4127 | if( aArg==0 ) return 1; |
4128 | p->aArg = aArg; |
4129 | p->nAlloc = N; |
4130 | return 0; |
4131 | } |
4132 | |
4133 | /* Insert a new opcode and argument into an RE under construction. The |
4134 | ** insertion point is just prior to existing opcode iBefore. |
4135 | */ |
4136 | static int re_insert(ReCompiled *p, int iBefore, int op, int arg){ |
4137 | int i; |
4138 | if( p->nAlloc<=p->nState && re_resize(p, p->nAlloc*2) ) return 0; |
4139 | for(i=p->nState; i>iBefore; i--){ |
4140 | p->aOp[i] = p->aOp[i-1]; |
4141 | p->aArg[i] = p->aArg[i-1]; |
4142 | } |
4143 | p->nState++; |
4144 | p->aOp[iBefore] = (char)op; |
4145 | p->aArg[iBefore] = arg; |
4146 | return iBefore; |
4147 | } |
4148 | |
4149 | /* Append a new opcode and argument to the end of the RE under construction. |
4150 | */ |
4151 | static int re_append(ReCompiled *p, int op, int arg){ |
4152 | return re_insert(p, p->nState, op, arg); |
4153 | } |
4154 | |
4155 | /* Make a copy of N opcodes starting at iStart onto the end of the RE |
4156 | ** under construction. |
4157 | */ |
4158 | static void re_copy(ReCompiled *p, int iStart, int N){ |
4159 | if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return; |
4160 | memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0])); |
4161 | memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0])); |
4162 | p->nState += N; |
4163 | } |
4164 | |
4165 | /* Return true if c is a hexadecimal digit character: [0-9a-fA-F] |
4166 | ** If c is a hex digit, also set *pV = (*pV)*16 + valueof(c). If |
4167 | ** c is not a hex digit *pV is unchanged. |
4168 | */ |
4169 | static int re_hex(int c, int *pV){ |
4170 | if( c>='0' && c<='9' ){ |
4171 | c -= '0'; |
4172 | }else if( c>='a' && c<='f' ){ |
4173 | c -= 'a' - 10; |
4174 | }else if( c>='A' && c<='F' ){ |
4175 | c -= 'A' - 10; |
4176 | }else{ |
4177 | return 0; |
4178 | } |
4179 | *pV = (*pV)*16 + (c & 0xff); |
4180 | return 1; |
4181 | } |
4182 | |
4183 | /* A backslash character has been seen, read the next character and |
4184 | ** return its interpretation. |
4185 | */ |
4186 | static unsigned re_esc_char(ReCompiled *p){ |
4187 | static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]" ; |
4188 | static const char zTrans[] = "\a\f\n\r\t\v" ; |
4189 | int i, v = 0; |
4190 | char c; |
4191 | if( p->sIn.i>=p->sIn.mx ) return 0; |
4192 | c = p->sIn.z[p->sIn.i]; |
4193 | if( c=='u' && p->sIn.i+4<p->sIn.mx ){ |
4194 | const unsigned char *zIn = p->sIn.z + p->sIn.i; |
4195 | if( re_hex(zIn[1],&v) |
4196 | && re_hex(zIn[2],&v) |
4197 | && re_hex(zIn[3],&v) |
4198 | && re_hex(zIn[4],&v) |
4199 | ){ |
4200 | p->sIn.i += 5; |
4201 | return v; |
4202 | } |
4203 | } |
4204 | if( c=='x' && p->sIn.i+2<p->sIn.mx ){ |
4205 | const unsigned char *zIn = p->sIn.z + p->sIn.i; |
4206 | if( re_hex(zIn[1],&v) |
4207 | && re_hex(zIn[2],&v) |
4208 | ){ |
4209 | p->sIn.i += 3; |
4210 | return v; |
4211 | } |
4212 | } |
4213 | for(i=0; zEsc[i] && zEsc[i]!=c; i++){} |
4214 | if( zEsc[i] ){ |
4215 | if( i<6 ) c = zTrans[i]; |
4216 | p->sIn.i++; |
4217 | }else{ |
4218 | p->zErr = "unknown \\ escape" ; |
4219 | } |
4220 | return c; |
4221 | } |
4222 | |
4223 | /* Forward declaration */ |
4224 | static const char *re_subcompile_string(ReCompiled*); |
4225 | |
4226 | /* Peek at the next byte of input */ |
4227 | static unsigned char rePeek(ReCompiled *p){ |
4228 | return p->sIn.i<p->sIn.mx ? p->sIn.z[p->sIn.i] : 0; |
4229 | } |
4230 | |
4231 | /* Compile RE text into a sequence of opcodes. Continue up to the |
4232 | ** first unmatched ")" character, then return. If an error is found, |
4233 | ** return a pointer to the error message string. |
4234 | */ |
4235 | static const char *re_subcompile_re(ReCompiled *p){ |
4236 | const char *zErr; |
4237 | int iStart, iEnd, iGoto; |
4238 | iStart = p->nState; |
4239 | zErr = re_subcompile_string(p); |
4240 | if( zErr ) return zErr; |
4241 | while( rePeek(p)=='|' ){ |
4242 | iEnd = p->nState; |
4243 | re_insert(p, iStart, RE_OP_FORK, iEnd + 2 - iStart); |
4244 | iGoto = re_append(p, RE_OP_GOTO, 0); |
4245 | p->sIn.i++; |
4246 | zErr = re_subcompile_string(p); |
4247 | if( zErr ) return zErr; |
4248 | p->aArg[iGoto] = p->nState - iGoto; |
4249 | } |
4250 | return 0; |
4251 | } |
4252 | |
4253 | /* Compile an element of regular expression text (anything that can be |
4254 | ** an operand to the "|" operator). Return NULL on success or a pointer |
4255 | ** to the error message if there is a problem. |
4256 | */ |
4257 | static const char *re_subcompile_string(ReCompiled *p){ |
4258 | int iPrev = -1; |
4259 | int iStart; |
4260 | unsigned c; |
4261 | const char *zErr; |
4262 | while( (c = p->xNextChar(&p->sIn))!=0 ){ |
4263 | iStart = p->nState; |
4264 | switch( c ){ |
4265 | case '|': |
4266 | case ')': { |
4267 | p->sIn.i--; |
4268 | return 0; |
4269 | } |
4270 | case '(': { |
4271 | zErr = re_subcompile_re(p); |
4272 | if( zErr ) return zErr; |
4273 | if( rePeek(p)!=')' ) return "unmatched '('" ; |
4274 | p->sIn.i++; |
4275 | break; |
4276 | } |
4277 | case '.': { |
4278 | if( rePeek(p)=='*' ){ |
4279 | re_append(p, RE_OP_ANYSTAR, 0); |
4280 | p->sIn.i++; |
4281 | }else{ |
4282 | re_append(p, RE_OP_ANY, 0); |
4283 | } |
4284 | break; |
4285 | } |
4286 | case '*': { |
4287 | if( iPrev<0 ) return "'*' without operand" ; |
4288 | re_insert(p, iPrev, RE_OP_GOTO, p->nState - iPrev + 1); |
4289 | re_append(p, RE_OP_FORK, iPrev - p->nState + 1); |
4290 | break; |
4291 | } |
4292 | case '+': { |
4293 | if( iPrev<0 ) return "'+' without operand" ; |
4294 | re_append(p, RE_OP_FORK, iPrev - p->nState); |
4295 | break; |
4296 | } |
4297 | case '?': { |
4298 | if( iPrev<0 ) return "'?' without operand" ; |
4299 | re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1); |
4300 | break; |
4301 | } |
4302 | case '$': { |
4303 | re_append(p, RE_OP_MATCH, RE_EOF); |
4304 | break; |
4305 | } |
4306 | case '^': { |
4307 | re_append(p, RE_OP_ATSTART, 0); |
4308 | break; |
4309 | } |
4310 | case '{': { |
4311 | int m = 0, n = 0; |
4312 | int sz, j; |
4313 | if( iPrev<0 ) return "'{m,n}' without operand" ; |
4314 | while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; } |
4315 | n = m; |
4316 | if( c==',' ){ |
4317 | p->sIn.i++; |
4318 | n = 0; |
4319 | while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; } |
4320 | } |
4321 | if( c!='}' ) return "unmatched '{'" ; |
4322 | if( n>0 && n<m ) return "n less than m in '{m,n}'" ; |
4323 | p->sIn.i++; |
4324 | sz = p->nState - iPrev; |
4325 | if( m==0 ){ |
4326 | if( n==0 ) return "both m and n are zero in '{m,n}'" ; |
4327 | re_insert(p, iPrev, RE_OP_FORK, sz+1); |
4328 | iPrev++; |
4329 | n--; |
4330 | }else{ |
4331 | for(j=1; j<m; j++) re_copy(p, iPrev, sz); |
4332 | } |
4333 | for(j=m; j<n; j++){ |
4334 | re_append(p, RE_OP_FORK, sz+1); |
4335 | re_copy(p, iPrev, sz); |
4336 | } |
4337 | if( n==0 && m>0 ){ |
4338 | re_append(p, RE_OP_FORK, -sz); |
4339 | } |
4340 | break; |
4341 | } |
4342 | case '[': { |
4343 | int iFirst = p->nState; |
4344 | if( rePeek(p)=='^' ){ |
4345 | re_append(p, RE_OP_CC_EXC, 0); |
4346 | p->sIn.i++; |
4347 | }else{ |
4348 | re_append(p, RE_OP_CC_INC, 0); |
4349 | } |
4350 | while( (c = p->xNextChar(&p->sIn))!=0 ){ |
4351 | if( c=='[' && rePeek(p)==':' ){ |
4352 | return "POSIX character classes not supported" ; |
4353 | } |
4354 | if( c=='\\' ) c = re_esc_char(p); |
4355 | if( rePeek(p)=='-' ){ |
4356 | re_append(p, RE_OP_CC_RANGE, c); |
4357 | p->sIn.i++; |
4358 | c = p->xNextChar(&p->sIn); |
4359 | if( c=='\\' ) c = re_esc_char(p); |
4360 | re_append(p, RE_OP_CC_RANGE, c); |
4361 | }else{ |
4362 | re_append(p, RE_OP_CC_VALUE, c); |
4363 | } |
4364 | if( rePeek(p)==']' ){ p->sIn.i++; break; } |
4365 | } |
4366 | if( c==0 ) return "unclosed '['" ; |
4367 | p->aArg[iFirst] = p->nState - iFirst; |
4368 | break; |
4369 | } |
4370 | case '\\': { |
4371 | int specialOp = 0; |
4372 | switch( rePeek(p) ){ |
4373 | case 'b': specialOp = RE_OP_BOUNDARY; break; |
4374 | case 'd': specialOp = RE_OP_DIGIT; break; |
4375 | case 'D': specialOp = RE_OP_NOTDIGIT; break; |
4376 | case 's': specialOp = RE_OP_SPACE; break; |
4377 | case 'S': specialOp = RE_OP_NOTSPACE; break; |
4378 | case 'w': specialOp = RE_OP_WORD; break; |
4379 | case 'W': specialOp = RE_OP_NOTWORD; break; |
4380 | } |
4381 | if( specialOp ){ |
4382 | p->sIn.i++; |
4383 | re_append(p, specialOp, 0); |
4384 | }else{ |
4385 | c = re_esc_char(p); |
4386 | re_append(p, RE_OP_MATCH, c); |
4387 | } |
4388 | break; |
4389 | } |
4390 | default: { |
4391 | re_append(p, RE_OP_MATCH, c); |
4392 | break; |
4393 | } |
4394 | } |
4395 | iPrev = iStart; |
4396 | } |
4397 | return 0; |
4398 | } |
4399 | |
4400 | /* Free and reclaim all the memory used by a previously compiled |
4401 | ** regular expression. Applications should invoke this routine once |
4402 | ** for every call to re_compile() to avoid memory leaks. |
4403 | */ |
4404 | static void re_free(ReCompiled *pRe){ |
4405 | if( pRe ){ |
4406 | sqlite3_free(pRe->aOp); |
4407 | sqlite3_free(pRe->aArg); |
4408 | sqlite3_free(pRe); |
4409 | } |
4410 | } |
4411 | |
4412 | /* |
4413 | ** Compile a textual regular expression in zIn[] into a compiled regular |
4414 | ** expression suitable for us by re_match() and return a pointer to the |
4415 | ** compiled regular expression in *ppRe. Return NULL on success or an |
4416 | ** error message if something goes wrong. |
4417 | */ |
4418 | static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ |
4419 | ReCompiled *pRe; |
4420 | const char *zErr; |
4421 | int i, j; |
4422 | |
4423 | *ppRe = 0; |
4424 | pRe = sqlite3_malloc( sizeof(*pRe) ); |
4425 | if( pRe==0 ){ |
4426 | return "out of memory" ; |
4427 | } |
4428 | memset(pRe, 0, sizeof(*pRe)); |
4429 | pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char; |
4430 | if( re_resize(pRe, 30) ){ |
4431 | re_free(pRe); |
4432 | return "out of memory" ; |
4433 | } |
4434 | if( zIn[0]=='^' ){ |
4435 | zIn++; |
4436 | }else{ |
4437 | re_append(pRe, RE_OP_ANYSTAR, 0); |
4438 | } |
4439 | pRe->sIn.z = (unsigned char*)zIn; |
4440 | pRe->sIn.i = 0; |
4441 | pRe->sIn.mx = (int)strlen(zIn); |
4442 | zErr = re_subcompile_re(pRe); |
4443 | if( zErr ){ |
4444 | re_free(pRe); |
4445 | return zErr; |
4446 | } |
4447 | if( pRe->sIn.i>=pRe->sIn.mx ){ |
4448 | re_append(pRe, RE_OP_ACCEPT, 0); |
4449 | *ppRe = pRe; |
4450 | }else{ |
4451 | re_free(pRe); |
4452 | return "unrecognized character" ; |
4453 | } |
4454 | |
4455 | /* The following is a performance optimization. If the regex begins with |
4456 | ** ".*" (if the input regex lacks an initial "^") and afterwards there are |
4457 | ** one or more matching characters, enter those matching characters into |
4458 | ** zInit[]. The re_match() routine can then search ahead in the input |
4459 | ** string looking for the initial match without having to run the whole |
4460 | ** regex engine over the string. Do not worry about trying to match |
4461 | ** unicode characters beyond plane 0 - those are very rare and this is |
4462 | ** just an optimization. */ |
4463 | if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){ |
4464 | for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){ |
4465 | unsigned x = pRe->aArg[i]; |
4466 | if( x<=0x7f ){ |
4467 | pRe->zInit[j++] = (unsigned char)x; |
4468 | }else if( x<=0x7ff ){ |
4469 | pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6)); |
4470 | pRe->zInit[j++] = 0x80 | (x&0x3f); |
4471 | }else if( x<=0xffff ){ |
4472 | pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12)); |
4473 | pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f); |
4474 | pRe->zInit[j++] = 0x80 | (x&0x3f); |
4475 | }else{ |
4476 | break; |
4477 | } |
4478 | } |
4479 | if( j>0 && pRe->zInit[j-1]==0 ) j--; |
4480 | pRe->nInit = j; |
4481 | } |
4482 | return pRe->zErr; |
4483 | } |
4484 | |
4485 | /* |
4486 | ** Implementation of the regexp() SQL function. This function implements |
4487 | ** the build-in REGEXP operator. The first argument to the function is the |
4488 | ** pattern and the second argument is the string. So, the SQL statements: |
4489 | ** |
4490 | ** A REGEXP B |
4491 | ** |
4492 | ** is implemented as regexp(B,A). |
4493 | */ |
4494 | static void re_sql_func( |
4495 | sqlite3_context *context, |
4496 | int argc, |
4497 | sqlite3_value **argv |
4498 | ){ |
4499 | ReCompiled *pRe; /* Compiled regular expression */ |
4500 | const char *zPattern; /* The regular expression */ |
4501 | const unsigned char *zStr;/* String being searched */ |
4502 | const char *zErr; /* Compile error message */ |
4503 | int setAux = 0; /* True to invoke sqlite3_set_auxdata() */ |
4504 | |
4505 | (void)argc; /* Unused */ |
4506 | pRe = sqlite3_get_auxdata(context, 0); |
4507 | if( pRe==0 ){ |
4508 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
4509 | if( zPattern==0 ) return; |
4510 | zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0); |
4511 | if( zErr ){ |
4512 | re_free(pRe); |
4513 | sqlite3_result_error(context, zErr, -1); |
4514 | return; |
4515 | } |
4516 | if( pRe==0 ){ |
4517 | sqlite3_result_error_nomem(context); |
4518 | return; |
4519 | } |
4520 | setAux = 1; |
4521 | } |
4522 | zStr = (const unsigned char*)sqlite3_value_text(argv[1]); |
4523 | if( zStr!=0 ){ |
4524 | sqlite3_result_int(context, re_match(pRe, zStr, -1)); |
4525 | } |
4526 | if( setAux ){ |
4527 | sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free); |
4528 | } |
4529 | } |
4530 | |
4531 | #if defined(SQLITE_DEBUG) |
4532 | /* |
4533 | ** This function is used for testing and debugging only. It is only available |
4534 | ** if the SQLITE_DEBUG compile-time option is used. |
4535 | ** |
4536 | ** Compile a regular expression and then convert the compiled expression into |
4537 | ** text and return that text. |
4538 | */ |
4539 | static void re_bytecode_func( |
4540 | sqlite3_context *context, |
4541 | int argc, |
4542 | sqlite3_value **argv |
4543 | ){ |
4544 | const char *zPattern; |
4545 | const char *zErr; |
4546 | ReCompiled *pRe; |
4547 | sqlite3_str *pStr; |
4548 | int i; |
4549 | int n; |
4550 | char *z; |
4551 | |
4552 | zPattern = (const char*)sqlite3_value_text(argv[0]); |
4553 | if( zPattern==0 ) return; |
4554 | zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0); |
4555 | if( zErr ){ |
4556 | re_free(pRe); |
4557 | sqlite3_result_error(context, zErr, -1); |
4558 | return; |
4559 | } |
4560 | if( pRe==0 ){ |
4561 | sqlite3_result_error_nomem(context); |
4562 | return; |
4563 | } |
4564 | pStr = sqlite3_str_new(0); |
4565 | if( pStr==0 ) goto re_bytecode_func_err; |
4566 | if( pRe->nInit>0 ){ |
4567 | sqlite3_str_appendf(pStr, "INIT " ); |
4568 | for(i=0; i<pRe->nInit; i++){ |
4569 | sqlite3_str_appendf(pStr, "%02x" , pRe->zInit[i]); |
4570 | } |
4571 | sqlite3_str_appendf(pStr, "\n" ); |
4572 | } |
4573 | for(i=0; (unsigned)i<pRe->nState; i++){ |
4574 | sqlite3_str_appendf(pStr, "%-8s %4d\n" , |
4575 | ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]); |
4576 | } |
4577 | n = sqlite3_str_length(pStr); |
4578 | z = sqlite3_str_finish(pStr); |
4579 | if( n==0 ){ |
4580 | sqlite3_free(z); |
4581 | }else{ |
4582 | sqlite3_result_text(context, z, n-1, sqlite3_free); |
4583 | } |
4584 | |
4585 | re_bytecode_func_err: |
4586 | re_free(pRe); |
4587 | } |
4588 | |
4589 | #endif /* SQLITE_DEBUG */ |
4590 | |
4591 | |
4592 | /* |
4593 | ** Invoke this routine to register the regexp() function with the |
4594 | ** SQLite database connection. |
4595 | */ |
4596 | #ifdef _WIN32 |
4597 | |
4598 | #endif |
4599 | int sqlite3_regexp_init( |
4600 | sqlite3 *db, |
4601 | char **pzErrMsg, |
4602 | const sqlite3_api_routines *pApi |
4603 | ){ |
4604 | int rc = SQLITE_OK; |
4605 | SQLITE_EXTENSION_INIT2(pApi); |
4606 | (void)pzErrMsg; /* Unused */ |
4607 | rc = sqlite3_create_function(db, "regexp" , 2, |
4608 | SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, |
4609 | 0, re_sql_func, 0, 0); |
4610 | if( rc==SQLITE_OK ){ |
4611 | /* The regexpi(PATTERN,STRING) function is a case-insensitive version |
4612 | ** of regexp(PATTERN,STRING). */ |
4613 | rc = sqlite3_create_function(db, "regexpi" , 2, |
4614 | SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, |
4615 | (void*)db, re_sql_func, 0, 0); |
4616 | #if defined(SQLITE_DEBUG) |
4617 | if( rc==SQLITE_OK ){ |
4618 | rc = sqlite3_create_function(db, "regexp_bytecode" , 1, |
4619 | SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, |
4620 | 0, re_bytecode_func, 0, 0); |
4621 | } |
4622 | #endif /* SQLITE_DEBUG */ |
4623 | } |
4624 | return rc; |
4625 | } |
4626 | |
4627 | /************************* End ../ext/misc/regexp.c ********************/ |
4628 | #ifndef SQLITE_SHELL_FIDDLE |
4629 | /************************* Begin ../ext/misc/fileio.c ******************/ |
4630 | /* |
4631 | ** 2014-06-13 |
4632 | ** |
4633 | ** The author disclaims copyright to this source code. In place of |
4634 | ** a legal notice, here is a blessing: |
4635 | ** |
4636 | ** May you do good and not evil. |
4637 | ** May you find forgiveness for yourself and forgive others. |
4638 | ** May you share freely, never taking more than you give. |
4639 | ** |
4640 | ****************************************************************************** |
4641 | ** |
4642 | ** This SQLite extension implements SQL functions readfile() and |
4643 | ** writefile(), and eponymous virtual type "fsdir". |
4644 | ** |
4645 | ** WRITEFILE(FILE, DATA [, MODE [, MTIME]]): |
4646 | ** |
4647 | ** If neither of the optional arguments is present, then this UDF |
4648 | ** function writes blob DATA to file FILE. If successful, the number |
4649 | ** of bytes written is returned. If an error occurs, NULL is returned. |
4650 | ** |
4651 | ** If the first option argument - MODE - is present, then it must |
4652 | ** be passed an integer value that corresponds to a POSIX mode |
4653 | ** value (file type + permissions, as returned in the stat.st_mode |
4654 | ** field by the stat() system call). Three types of files may |
4655 | ** be written/created: |
4656 | ** |
4657 | ** regular files: (mode & 0170000)==0100000 |
4658 | ** symbolic links: (mode & 0170000)==0120000 |
4659 | ** directories: (mode & 0170000)==0040000 |
4660 | ** |
4661 | ** For a directory, the DATA is ignored. For a symbolic link, it is |
4662 | ** interpreted as text and used as the target of the link. For a |
4663 | ** regular file, it is interpreted as a blob and written into the |
4664 | ** named file. Regardless of the type of file, its permissions are |
4665 | ** set to (mode & 0777) before returning. |
4666 | ** |
4667 | ** If the optional MTIME argument is present, then it is interpreted |
4668 | ** as an integer - the number of seconds since the unix epoch. The |
4669 | ** modification-time of the target file is set to this value before |
4670 | ** returning. |
4671 | ** |
4672 | ** If three or more arguments are passed to this function and an |
4673 | ** error is encountered, an exception is raised. |
4674 | ** |
4675 | ** READFILE(FILE): |
4676 | ** |
4677 | ** Read and return the contents of file FILE (type blob) from disk. |
4678 | ** |
4679 | ** FSDIR: |
4680 | ** |
4681 | ** Used as follows: |
4682 | ** |
4683 | ** SELECT * FROM fsdir($path [, $dir]); |
4684 | ** |
4685 | ** Parameter $path is an absolute or relative pathname. If the file that it |
4686 | ** refers to does not exist, it is an error. If the path refers to a regular |
4687 | ** file or symbolic link, it returns a single row. Or, if the path refers |
4688 | ** to a directory, it returns one row for the directory, and one row for each |
4689 | ** file within the hierarchy rooted at $path. |
4690 | ** |
4691 | ** Each row has the following columns: |
4692 | ** |
4693 | ** name: Path to file or directory (text value). |
4694 | ** mode: Value of stat.st_mode for directory entry (an integer). |
4695 | ** mtime: Value of stat.st_mtime for directory entry (an integer). |
4696 | ** data: For a regular file, a blob containing the file data. For a |
4697 | ** symlink, a text value containing the text of the link. For a |
4698 | ** directory, NULL. |
4699 | ** |
4700 | ** If a non-NULL value is specified for the optional $dir parameter and |
4701 | ** $path is a relative path, then $path is interpreted relative to $dir. |
4702 | ** And the paths returned in the "name" column of the table are also |
4703 | ** relative to directory $dir. |
4704 | ** |
4705 | ** Notes on building this extension for Windows: |
4706 | ** Unless linked statically with the SQLite library, a preprocessor |
4707 | ** symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone |
4708 | ** DLL form of this extension for WIN32. See its use below for details. |
4709 | */ |
4710 | /* #include "sqlite3ext.h" */ |
4711 | SQLITE_EXTENSION_INIT1 |
4712 | #include <stdio.h> |
4713 | #include <string.h> |
4714 | #include <assert.h> |
4715 | |
4716 | #include <sys/types.h> |
4717 | #include <sys/stat.h> |
4718 | #include <fcntl.h> |
4719 | #if !defined(_WIN32) && !defined(WIN32) |
4720 | # include <unistd.h> |
4721 | # include <dirent.h> |
4722 | # include <utime.h> |
4723 | # include <sys/time.h> |
4724 | #else |
4725 | # include "windows.h" |
4726 | # include <io.h> |
4727 | # include <direct.h> |
4728 | /* # include "test_windirent.h" */ |
4729 | # define dirent DIRENT |
4730 | # ifndef chmod |
4731 | # define chmod _chmod |
4732 | # endif |
4733 | # ifndef stat |
4734 | # define stat _stat |
4735 | # endif |
4736 | # define mkdir(path,mode) _mkdir(path) |
4737 | # define lstat(path,buf) stat(path,buf) |
4738 | #endif |
4739 | #include <time.h> |
4740 | #include <errno.h> |
4741 | |
4742 | |
4743 | /* |
4744 | ** Structure of the fsdir() table-valued function |
4745 | */ |
4746 | /* 0 1 2 3 4 5 */ |
4747 | #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)" |
4748 | #define FSDIR_COLUMN_NAME 0 /* Name of the file */ |
4749 | #define FSDIR_COLUMN_MODE 1 /* Access mode */ |
4750 | #define FSDIR_COLUMN_MTIME 2 /* Last modification time */ |
4751 | #define FSDIR_COLUMN_DATA 3 /* File content */ |
4752 | #define FSDIR_COLUMN_PATH 4 /* Path to top of search */ |
4753 | #define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */ |
4754 | |
4755 | |
4756 | /* |
4757 | ** Set the result stored by context ctx to a blob containing the |
4758 | ** contents of file zName. Or, leave the result unchanged (NULL) |
4759 | ** if the file does not exist or is unreadable. |
4760 | ** |
4761 | ** If the file exceeds the SQLite blob size limit, through an |
4762 | ** SQLITE_TOOBIG error. |
4763 | ** |
4764 | ** Throw an SQLITE_IOERR if there are difficulties pulling the file |
4765 | ** off of disk. |
4766 | */ |
4767 | static void readFileContents(sqlite3_context *ctx, const char *zName){ |
4768 | FILE *in; |
4769 | sqlite3_int64 nIn; |
4770 | void *pBuf; |
4771 | sqlite3 *db; |
4772 | int mxBlob; |
4773 | |
4774 | in = fopen(zName, "rb" ); |
4775 | if( in==0 ){ |
4776 | /* File does not exist or is unreadable. Leave the result set to NULL. */ |
4777 | return; |
4778 | } |
4779 | fseek(in, 0, SEEK_END); |
4780 | nIn = ftell(in); |
4781 | rewind(in); |
4782 | db = sqlite3_context_db_handle(ctx); |
4783 | mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1); |
4784 | if( nIn>mxBlob ){ |
4785 | sqlite3_result_error_code(ctx, SQLITE_TOOBIG); |
4786 | fclose(in); |
4787 | return; |
4788 | } |
4789 | pBuf = sqlite3_malloc64( nIn ? nIn : 1 ); |
4790 | if( pBuf==0 ){ |
4791 | sqlite3_result_error_nomem(ctx); |
4792 | fclose(in); |
4793 | return; |
4794 | } |
4795 | if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){ |
4796 | sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free); |
4797 | }else{ |
4798 | sqlite3_result_error_code(ctx, SQLITE_IOERR); |
4799 | sqlite3_free(pBuf); |
4800 | } |
4801 | fclose(in); |
4802 | } |
4803 | |
4804 | /* |
4805 | ** Implementation of the "readfile(X)" SQL function. The entire content |
4806 | ** of the file named X is read and returned as a BLOB. NULL is returned |
4807 | ** if the file does not exist or is unreadable. |
4808 | */ |
4809 | static void readfileFunc( |
4810 | sqlite3_context *context, |
4811 | int argc, |
4812 | sqlite3_value **argv |
4813 | ){ |
4814 | const char *zName; |
4815 | (void)(argc); /* Unused parameter */ |
4816 | zName = (const char*)sqlite3_value_text(argv[0]); |
4817 | if( zName==0 ) return; |
4818 | readFileContents(context, zName); |
4819 | } |
4820 | |
4821 | /* |
4822 | ** Set the error message contained in context ctx to the results of |
4823 | ** vprintf(zFmt, ...). |
4824 | */ |
4825 | static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ |
4826 | char *zMsg = 0; |
4827 | va_list ap; |
4828 | va_start(ap, zFmt); |
4829 | zMsg = sqlite3_vmprintf(zFmt, ap); |
4830 | sqlite3_result_error(ctx, zMsg, -1); |
4831 | sqlite3_free(zMsg); |
4832 | va_end(ap); |
4833 | } |
4834 | |
4835 | #if defined(_WIN32) |
4836 | /* |
4837 | ** This function is designed to convert a Win32 FILETIME structure into the |
4838 | ** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC). |
4839 | */ |
4840 | static sqlite3_uint64 fileTimeToUnixTime( |
4841 | LPFILETIME pFileTime |
4842 | ){ |
4843 | SYSTEMTIME epochSystemTime; |
4844 | ULARGE_INTEGER epochIntervals; |
4845 | FILETIME epochFileTime; |
4846 | ULARGE_INTEGER fileIntervals; |
4847 | |
4848 | memset(&epochSystemTime, 0, sizeof(SYSTEMTIME)); |
4849 | epochSystemTime.wYear = 1970; |
4850 | epochSystemTime.wMonth = 1; |
4851 | epochSystemTime.wDay = 1; |
4852 | SystemTimeToFileTime(&epochSystemTime, &epochFileTime); |
4853 | epochIntervals.LowPart = epochFileTime.dwLowDateTime; |
4854 | epochIntervals.HighPart = epochFileTime.dwHighDateTime; |
4855 | |
4856 | fileIntervals.LowPart = pFileTime->dwLowDateTime; |
4857 | fileIntervals.HighPart = pFileTime->dwHighDateTime; |
4858 | |
4859 | return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000; |
4860 | } |
4861 | |
4862 | |
4863 | #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32)) |
4864 | # /* To allow a standalone DLL, use this next replacement function: */ |
4865 | # undef sqlite3_win32_utf8_to_unicode |
4866 | # define sqlite3_win32_utf8_to_unicode utf8_to_utf16 |
4867 | # |
4868 | LPWSTR utf8_to_utf16(const char *z){ |
4869 | int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0); |
4870 | LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR)); |
4871 | if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) ) |
4872 | return rv; |
4873 | sqlite3_free(rv); |
4874 | return 0; |
4875 | } |
4876 | #endif |
4877 | |
4878 | /* |
4879 | ** This function attempts to normalize the time values found in the stat() |
4880 | ** buffer to UTC. This is necessary on Win32, where the runtime library |
4881 | ** appears to return these values as local times. |
4882 | */ |
4883 | static void statTimesToUtc( |
4884 | const char *zPath, |
4885 | struct stat *pStatBuf |
4886 | ){ |
4887 | HANDLE hFindFile; |
4888 | WIN32_FIND_DATAW fd; |
4889 | LPWSTR zUnicodeName; |
4890 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); |
4891 | zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath); |
4892 | if( zUnicodeName ){ |
4893 | memset(&fd, 0, sizeof(WIN32_FIND_DATAW)); |
4894 | hFindFile = FindFirstFileW(zUnicodeName, &fd); |
4895 | if( hFindFile!=NULL ){ |
4896 | pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime); |
4897 | pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime); |
4898 | pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime); |
4899 | FindClose(hFindFile); |
4900 | } |
4901 | sqlite3_free(zUnicodeName); |
4902 | } |
4903 | } |
4904 | #endif |
4905 | |
4906 | /* |
4907 | ** This function is used in place of stat(). On Windows, special handling |
4908 | ** is required in order for the included time to be returned as UTC. On all |
4909 | ** other systems, this function simply calls stat(). |
4910 | */ |
4911 | static int fileStat( |
4912 | const char *zPath, |
4913 | struct stat *pStatBuf |
4914 | ){ |
4915 | #if defined(_WIN32) |
4916 | int rc = stat(zPath, pStatBuf); |
4917 | if( rc==0 ) statTimesToUtc(zPath, pStatBuf); |
4918 | return rc; |
4919 | #else |
4920 | return stat(zPath, pStatBuf); |
4921 | #endif |
4922 | } |
4923 | |
4924 | /* |
4925 | ** This function is used in place of lstat(). On Windows, special handling |
4926 | ** is required in order for the included time to be returned as UTC. On all |
4927 | ** other systems, this function simply calls lstat(). |
4928 | */ |
4929 | static int fileLinkStat( |
4930 | const char *zPath, |
4931 | struct stat *pStatBuf |
4932 | ){ |
4933 | #if defined(_WIN32) |
4934 | int rc = lstat(zPath, pStatBuf); |
4935 | if( rc==0 ) statTimesToUtc(zPath, pStatBuf); |
4936 | return rc; |
4937 | #else |
4938 | return lstat(zPath, pStatBuf); |
4939 | #endif |
4940 | } |
4941 | |
4942 | /* |
4943 | ** Argument zFile is the name of a file that will be created and/or written |
4944 | ** by SQL function writefile(). This function ensures that the directory |
4945 | ** zFile will be written to exists, creating it if required. The permissions |
4946 | ** for any path components created by this function are set in accordance |
4947 | ** with the current umask. |
4948 | ** |
4949 | ** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise, |
4950 | ** SQLITE_OK is returned if the directory is successfully created, or |
4951 | ** SQLITE_ERROR otherwise. |
4952 | */ |
4953 | static int makeDirectory( |
4954 | const char *zFile |
4955 | ){ |
4956 | char *zCopy = sqlite3_mprintf("%s" , zFile); |
4957 | int rc = SQLITE_OK; |
4958 | |
4959 | if( zCopy==0 ){ |
4960 | rc = SQLITE_NOMEM; |
4961 | }else{ |
4962 | int nCopy = (int)strlen(zCopy); |
4963 | int i = 1; |
4964 | |
4965 | while( rc==SQLITE_OK ){ |
4966 | struct stat sStat; |
4967 | int rc2; |
4968 | |
4969 | for(; zCopy[i]!='/' && i<nCopy; i++); |
4970 | if( i==nCopy ) break; |
4971 | zCopy[i] = '\0'; |
4972 | |
4973 | rc2 = fileStat(zCopy, &sStat); |
4974 | if( rc2!=0 ){ |
4975 | if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR; |
4976 | }else{ |
4977 | if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR; |
4978 | } |
4979 | zCopy[i] = '/'; |
4980 | i++; |
4981 | } |
4982 | |
4983 | sqlite3_free(zCopy); |
4984 | } |
4985 | |
4986 | return rc; |
4987 | } |
4988 | |
4989 | /* |
4990 | ** This function does the work for the writefile() UDF. Refer to |
4991 | ** header comments at the top of this file for details. |
4992 | */ |
4993 | static int writeFile( |
4994 | sqlite3_context *pCtx, /* Context to return bytes written in */ |
4995 | const char *zFile, /* File to write */ |
4996 | sqlite3_value *pData, /* Data to write */ |
4997 | mode_t mode, /* MODE parameter passed to writefile() */ |
4998 | sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */ |
4999 | ){ |
5000 | if( zFile==0 ) return 1; |
5001 | #if !defined(_WIN32) && !defined(WIN32) |
5002 | if( S_ISLNK(mode) ){ |
5003 | const char *zTo = (const char*)sqlite3_value_text(pData); |
5004 | if( zTo==0 || symlink(zTo, zFile)<0 ) return 1; |
5005 | }else |
5006 | #endif |
5007 | { |
5008 | if( S_ISDIR(mode) ){ |
5009 | if( mkdir(zFile, mode) ){ |
5010 | /* The mkdir() call to create the directory failed. This might not |
5011 | ** be an error though - if there is already a directory at the same |
5012 | ** path and either the permissions already match or can be changed |
5013 | ** to do so using chmod(), it is not an error. */ |
5014 | struct stat sStat; |
5015 | if( errno!=EEXIST |
5016 | || 0!=fileStat(zFile, &sStat) |
5017 | || !S_ISDIR(sStat.st_mode) |
5018 | || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777)) |
5019 | ){ |
5020 | return 1; |
5021 | } |
5022 | } |
5023 | }else{ |
5024 | sqlite3_int64 nWrite = 0; |
5025 | const char *z; |
5026 | int rc = 0; |
5027 | FILE *out = fopen(zFile, "wb" ); |
5028 | if( out==0 ) return 1; |
5029 | z = (const char*)sqlite3_value_blob(pData); |
5030 | if( z ){ |
5031 | sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out); |
5032 | nWrite = sqlite3_value_bytes(pData); |
5033 | if( nWrite!=n ){ |
5034 | rc = 1; |
5035 | } |
5036 | } |
5037 | fclose(out); |
5038 | if( rc==0 && mode && chmod(zFile, mode & 0777) ){ |
5039 | rc = 1; |
5040 | } |
5041 | if( rc ) return 2; |
5042 | sqlite3_result_int64(pCtx, nWrite); |
5043 | } |
5044 | } |
5045 | |
5046 | if( mtime>=0 ){ |
5047 | #if defined(_WIN32) |
5048 | #if !SQLITE_OS_WINRT |
5049 | /* Windows */ |
5050 | FILETIME lastAccess; |
5051 | FILETIME lastWrite; |
5052 | SYSTEMTIME currentTime; |
5053 | LONGLONG intervals; |
5054 | HANDLE hFile; |
5055 | LPWSTR zUnicodeName; |
5056 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); |
5057 | |
5058 | GetSystemTime(¤tTime); |
5059 | SystemTimeToFileTime(¤tTime, &lastAccess); |
5060 | intervals = Int32x32To64(mtime, 10000000) + 116444736000000000; |
5061 | lastWrite.dwLowDateTime = (DWORD)intervals; |
5062 | lastWrite.dwHighDateTime = intervals >> 32; |
5063 | zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); |
5064 | if( zUnicodeName==0 ){ |
5065 | return 1; |
5066 | } |
5067 | hFile = CreateFileW( |
5068 | zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, |
5069 | FILE_FLAG_BACKUP_SEMANTICS, NULL |
5070 | ); |
5071 | sqlite3_free(zUnicodeName); |
5072 | if( hFile!=INVALID_HANDLE_VALUE ){ |
5073 | BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite); |
5074 | CloseHandle(hFile); |
5075 | return !bResult; |
5076 | }else{ |
5077 | return 1; |
5078 | } |
5079 | #endif |
5080 | #elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */ |
5081 | /* Recent unix */ |
5082 | struct timespec times[2]; |
5083 | times[0].tv_nsec = times[1].tv_nsec = 0; |
5084 | times[0].tv_sec = time(0); |
5085 | times[1].tv_sec = mtime; |
5086 | if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){ |
5087 | return 1; |
5088 | } |
5089 | #else |
5090 | /* Legacy unix */ |
5091 | struct timeval times[2]; |
5092 | times[0].tv_usec = times[1].tv_usec = 0; |
5093 | times[0].tv_sec = time(0); |
5094 | times[1].tv_sec = mtime; |
5095 | if( utimes(zFile, times) ){ |
5096 | return 1; |
5097 | } |
5098 | #endif |
5099 | } |
5100 | |
5101 | return 0; |
5102 | } |
5103 | |
5104 | /* |
5105 | ** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. |
5106 | ** Refer to header comments at the top of this file for details. |
5107 | */ |
5108 | static void writefileFunc( |
5109 | sqlite3_context *context, |
5110 | int argc, |
5111 | sqlite3_value **argv |
5112 | ){ |
5113 | const char *zFile; |
5114 | mode_t mode = 0; |
5115 | int res; |
5116 | sqlite3_int64 mtime = -1; |
5117 | |
5118 | if( argc<2 || argc>4 ){ |
5119 | sqlite3_result_error(context, |
5120 | "wrong number of arguments to function writefile()" , -1 |
5121 | ); |
5122 | return; |
5123 | } |
5124 | |
5125 | zFile = (const char*)sqlite3_value_text(argv[0]); |
5126 | if( zFile==0 ) return; |
5127 | if( argc>=3 ){ |
5128 | mode = (mode_t)sqlite3_value_int(argv[2]); |
5129 | } |
5130 | if( argc==4 ){ |
5131 | mtime = sqlite3_value_int64(argv[3]); |
5132 | } |
5133 | |
5134 | res = writeFile(context, zFile, argv[1], mode, mtime); |
5135 | if( res==1 && errno==ENOENT ){ |
5136 | if( makeDirectory(zFile)==SQLITE_OK ){ |
5137 | res = writeFile(context, zFile, argv[1], mode, mtime); |
5138 | } |
5139 | } |
5140 | |
5141 | if( argc>2 && res!=0 ){ |
5142 | if( S_ISLNK(mode) ){ |
5143 | ctxErrorMsg(context, "failed to create symlink: %s" , zFile); |
5144 | }else if( S_ISDIR(mode) ){ |
5145 | ctxErrorMsg(context, "failed to create directory: %s" , zFile); |
5146 | }else{ |
5147 | ctxErrorMsg(context, "failed to write file: %s" , zFile); |
5148 | } |
5149 | } |
5150 | } |
5151 | |
5152 | /* |
5153 | ** SQL function: lsmode(MODE) |
5154 | ** |
5155 | ** Given a numberic st_mode from stat(), convert it into a human-readable |
5156 | ** text string in the style of "ls -l". |
5157 | */ |
5158 | static void lsModeFunc( |
5159 | sqlite3_context *context, |
5160 | int argc, |
5161 | sqlite3_value **argv |
5162 | ){ |
5163 | int i; |
5164 | int iMode = sqlite3_value_int(argv[0]); |
5165 | char z[16]; |
5166 | (void)argc; |
5167 | if( S_ISLNK(iMode) ){ |
5168 | z[0] = 'l'; |
5169 | }else if( S_ISREG(iMode) ){ |
5170 | z[0] = '-'; |
5171 | }else if( S_ISDIR(iMode) ){ |
5172 | z[0] = 'd'; |
5173 | }else{ |
5174 | z[0] = '?'; |
5175 | } |
5176 | for(i=0; i<3; i++){ |
5177 | int m = (iMode >> ((2-i)*3)); |
5178 | char *a = &z[1 + i*3]; |
5179 | a[0] = (m & 0x4) ? 'r' : '-'; |
5180 | a[1] = (m & 0x2) ? 'w' : '-'; |
5181 | a[2] = (m & 0x1) ? 'x' : '-'; |
5182 | } |
5183 | z[10] = '\0'; |
5184 | sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); |
5185 | } |
5186 | |
5187 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
5188 | |
5189 | /* |
5190 | ** Cursor type for recursively iterating through a directory structure. |
5191 | */ |
5192 | typedef struct fsdir_cursor fsdir_cursor; |
5193 | typedef struct FsdirLevel FsdirLevel; |
5194 | |
5195 | struct FsdirLevel { |
5196 | DIR *pDir; /* From opendir() */ |
5197 | char *zDir; /* Name of directory (nul-terminated) */ |
5198 | }; |
5199 | |
5200 | struct fsdir_cursor { |
5201 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
5202 | |
5203 | int nLvl; /* Number of entries in aLvl[] array */ |
5204 | int iLvl; /* Index of current entry */ |
5205 | FsdirLevel *aLvl; /* Hierarchy of directories being traversed */ |
5206 | |
5207 | const char *zBase; |
5208 | int nBase; |
5209 | |
5210 | struct stat sStat; /* Current lstat() results */ |
5211 | char *zPath; /* Path to current entry */ |
5212 | sqlite3_int64 iRowid; /* Current rowid */ |
5213 | }; |
5214 | |
5215 | typedef struct fsdir_tab fsdir_tab; |
5216 | struct fsdir_tab { |
5217 | sqlite3_vtab base; /* Base class - must be first */ |
5218 | }; |
5219 | |
5220 | /* |
5221 | ** Construct a new fsdir virtual table object. |
5222 | */ |
5223 | static int fsdirConnect( |
5224 | sqlite3 *db, |
5225 | void *pAux, |
5226 | int argc, const char *const*argv, |
5227 | sqlite3_vtab **ppVtab, |
5228 | char **pzErr |
5229 | ){ |
5230 | fsdir_tab *pNew = 0; |
5231 | int rc; |
5232 | (void)pAux; |
5233 | (void)argc; |
5234 | (void)argv; |
5235 | (void)pzErr; |
5236 | rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA); |
5237 | if( rc==SQLITE_OK ){ |
5238 | pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) ); |
5239 | if( pNew==0 ) return SQLITE_NOMEM; |
5240 | memset(pNew, 0, sizeof(*pNew)); |
5241 | sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); |
5242 | } |
5243 | *ppVtab = (sqlite3_vtab*)pNew; |
5244 | return rc; |
5245 | } |
5246 | |
5247 | /* |
5248 | ** This method is the destructor for fsdir vtab objects. |
5249 | */ |
5250 | static int fsdirDisconnect(sqlite3_vtab *pVtab){ |
5251 | sqlite3_free(pVtab); |
5252 | return SQLITE_OK; |
5253 | } |
5254 | |
5255 | /* |
5256 | ** Constructor for a new fsdir_cursor object. |
5257 | */ |
5258 | static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
5259 | fsdir_cursor *pCur; |
5260 | (void)p; |
5261 | pCur = sqlite3_malloc( sizeof(*pCur) ); |
5262 | if( pCur==0 ) return SQLITE_NOMEM; |
5263 | memset(pCur, 0, sizeof(*pCur)); |
5264 | pCur->iLvl = -1; |
5265 | *ppCursor = &pCur->base; |
5266 | return SQLITE_OK; |
5267 | } |
5268 | |
5269 | /* |
5270 | ** Reset a cursor back to the state it was in when first returned |
5271 | ** by fsdirOpen(). |
5272 | */ |
5273 | static void fsdirResetCursor(fsdir_cursor *pCur){ |
5274 | int i; |
5275 | for(i=0; i<=pCur->iLvl; i++){ |
5276 | FsdirLevel *pLvl = &pCur->aLvl[i]; |
5277 | if( pLvl->pDir ) closedir(pLvl->pDir); |
5278 | sqlite3_free(pLvl->zDir); |
5279 | } |
5280 | sqlite3_free(pCur->zPath); |
5281 | sqlite3_free(pCur->aLvl); |
5282 | pCur->aLvl = 0; |
5283 | pCur->zPath = 0; |
5284 | pCur->zBase = 0; |
5285 | pCur->nBase = 0; |
5286 | pCur->nLvl = 0; |
5287 | pCur->iLvl = -1; |
5288 | pCur->iRowid = 1; |
5289 | } |
5290 | |
5291 | /* |
5292 | ** Destructor for an fsdir_cursor. |
5293 | */ |
5294 | static int fsdirClose(sqlite3_vtab_cursor *cur){ |
5295 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
5296 | |
5297 | fsdirResetCursor(pCur); |
5298 | sqlite3_free(pCur); |
5299 | return SQLITE_OK; |
5300 | } |
5301 | |
5302 | /* |
5303 | ** Set the error message for the virtual table associated with cursor |
5304 | ** pCur to the results of vprintf(zFmt, ...). |
5305 | */ |
5306 | static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){ |
5307 | va_list ap; |
5308 | va_start(ap, zFmt); |
5309 | pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); |
5310 | va_end(ap); |
5311 | } |
5312 | |
5313 | |
5314 | /* |
5315 | ** Advance an fsdir_cursor to its next row of output. |
5316 | */ |
5317 | static int fsdirNext(sqlite3_vtab_cursor *cur){ |
5318 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
5319 | mode_t m = pCur->sStat.st_mode; |
5320 | |
5321 | pCur->iRowid++; |
5322 | if( S_ISDIR(m) ){ |
5323 | /* Descend into this directory */ |
5324 | int iNew = pCur->iLvl + 1; |
5325 | FsdirLevel *pLvl; |
5326 | if( iNew>=pCur->nLvl ){ |
5327 | int nNew = iNew+1; |
5328 | sqlite3_int64 nByte = nNew*sizeof(FsdirLevel); |
5329 | FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte); |
5330 | if( aNew==0 ) return SQLITE_NOMEM; |
5331 | memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl)); |
5332 | pCur->aLvl = aNew; |
5333 | pCur->nLvl = nNew; |
5334 | } |
5335 | pCur->iLvl = iNew; |
5336 | pLvl = &pCur->aLvl[iNew]; |
5337 | |
5338 | pLvl->zDir = pCur->zPath; |
5339 | pCur->zPath = 0; |
5340 | pLvl->pDir = opendir(pLvl->zDir); |
5341 | if( pLvl->pDir==0 ){ |
5342 | fsdirSetErrmsg(pCur, "cannot read directory: %s" , pCur->zPath); |
5343 | return SQLITE_ERROR; |
5344 | } |
5345 | } |
5346 | |
5347 | while( pCur->iLvl>=0 ){ |
5348 | FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl]; |
5349 | struct dirent *pEntry = readdir(pLvl->pDir); |
5350 | if( pEntry ){ |
5351 | if( pEntry->d_name[0]=='.' ){ |
5352 | if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue; |
5353 | if( pEntry->d_name[1]=='\0' ) continue; |
5354 | } |
5355 | sqlite3_free(pCur->zPath); |
5356 | pCur->zPath = sqlite3_mprintf("%s/%s" , pLvl->zDir, pEntry->d_name); |
5357 | if( pCur->zPath==0 ) return SQLITE_NOMEM; |
5358 | if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ |
5359 | fsdirSetErrmsg(pCur, "cannot stat file: %s" , pCur->zPath); |
5360 | return SQLITE_ERROR; |
5361 | } |
5362 | return SQLITE_OK; |
5363 | } |
5364 | closedir(pLvl->pDir); |
5365 | sqlite3_free(pLvl->zDir); |
5366 | pLvl->pDir = 0; |
5367 | pLvl->zDir = 0; |
5368 | pCur->iLvl--; |
5369 | } |
5370 | |
5371 | /* EOF */ |
5372 | sqlite3_free(pCur->zPath); |
5373 | pCur->zPath = 0; |
5374 | return SQLITE_OK; |
5375 | } |
5376 | |
5377 | /* |
5378 | ** Return values of columns for the row at which the series_cursor |
5379 | ** is currently pointing. |
5380 | */ |
5381 | static int fsdirColumn( |
5382 | sqlite3_vtab_cursor *cur, /* The cursor */ |
5383 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
5384 | int i /* Which column to return */ |
5385 | ){ |
5386 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
5387 | switch( i ){ |
5388 | case FSDIR_COLUMN_NAME: { |
5389 | sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT); |
5390 | break; |
5391 | } |
5392 | |
5393 | case FSDIR_COLUMN_MODE: |
5394 | sqlite3_result_int64(ctx, pCur->sStat.st_mode); |
5395 | break; |
5396 | |
5397 | case FSDIR_COLUMN_MTIME: |
5398 | sqlite3_result_int64(ctx, pCur->sStat.st_mtime); |
5399 | break; |
5400 | |
5401 | case FSDIR_COLUMN_DATA: { |
5402 | mode_t m = pCur->sStat.st_mode; |
5403 | if( S_ISDIR(m) ){ |
5404 | sqlite3_result_null(ctx); |
5405 | #if !defined(_WIN32) && !defined(WIN32) |
5406 | }else if( S_ISLNK(m) ){ |
5407 | char aStatic[64]; |
5408 | char *aBuf = aStatic; |
5409 | sqlite3_int64 nBuf = 64; |
5410 | int n; |
5411 | |
5412 | while( 1 ){ |
5413 | n = readlink(pCur->zPath, aBuf, nBuf); |
5414 | if( n<nBuf ) break; |
5415 | if( aBuf!=aStatic ) sqlite3_free(aBuf); |
5416 | nBuf = nBuf*2; |
5417 | aBuf = sqlite3_malloc64(nBuf); |
5418 | if( aBuf==0 ){ |
5419 | sqlite3_result_error_nomem(ctx); |
5420 | return SQLITE_NOMEM; |
5421 | } |
5422 | } |
5423 | |
5424 | sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT); |
5425 | if( aBuf!=aStatic ) sqlite3_free(aBuf); |
5426 | #endif |
5427 | }else{ |
5428 | readFileContents(ctx, pCur->zPath); |
5429 | } |
5430 | } |
5431 | case FSDIR_COLUMN_PATH: |
5432 | default: { |
5433 | /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters. |
5434 | ** always return their values as NULL */ |
5435 | break; |
5436 | } |
5437 | } |
5438 | return SQLITE_OK; |
5439 | } |
5440 | |
5441 | /* |
5442 | ** Return the rowid for the current row. In this implementation, the |
5443 | ** first row returned is assigned rowid value 1, and each subsequent |
5444 | ** row a value 1 more than that of the previous. |
5445 | */ |
5446 | static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
5447 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
5448 | *pRowid = pCur->iRowid; |
5449 | return SQLITE_OK; |
5450 | } |
5451 | |
5452 | /* |
5453 | ** Return TRUE if the cursor has been moved off of the last |
5454 | ** row of output. |
5455 | */ |
5456 | static int fsdirEof(sqlite3_vtab_cursor *cur){ |
5457 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
5458 | return (pCur->zPath==0); |
5459 | } |
5460 | |
5461 | /* |
5462 | ** xFilter callback. |
5463 | ** |
5464 | ** idxNum==1 PATH parameter only |
5465 | ** idxNum==2 Both PATH and DIR supplied |
5466 | */ |
5467 | static int fsdirFilter( |
5468 | sqlite3_vtab_cursor *cur, |
5469 | int idxNum, const char *idxStr, |
5470 | int argc, sqlite3_value **argv |
5471 | ){ |
5472 | const char *zDir = 0; |
5473 | fsdir_cursor *pCur = (fsdir_cursor*)cur; |
5474 | (void)idxStr; |
5475 | fsdirResetCursor(pCur); |
5476 | |
5477 | if( idxNum==0 ){ |
5478 | fsdirSetErrmsg(pCur, "table function fsdir requires an argument" ); |
5479 | return SQLITE_ERROR; |
5480 | } |
5481 | |
5482 | assert( argc==idxNum && (argc==1 || argc==2) ); |
5483 | zDir = (const char*)sqlite3_value_text(argv[0]); |
5484 | if( zDir==0 ){ |
5485 | fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument" ); |
5486 | return SQLITE_ERROR; |
5487 | } |
5488 | if( argc==2 ){ |
5489 | pCur->zBase = (const char*)sqlite3_value_text(argv[1]); |
5490 | } |
5491 | if( pCur->zBase ){ |
5492 | pCur->nBase = (int)strlen(pCur->zBase)+1; |
5493 | pCur->zPath = sqlite3_mprintf("%s/%s" , pCur->zBase, zDir); |
5494 | }else{ |
5495 | pCur->zPath = sqlite3_mprintf("%s" , zDir); |
5496 | } |
5497 | |
5498 | if( pCur->zPath==0 ){ |
5499 | return SQLITE_NOMEM; |
5500 | } |
5501 | if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ |
5502 | fsdirSetErrmsg(pCur, "cannot stat file: %s" , pCur->zPath); |
5503 | return SQLITE_ERROR; |
5504 | } |
5505 | |
5506 | return SQLITE_OK; |
5507 | } |
5508 | |
5509 | /* |
5510 | ** SQLite will invoke this method one or more times while planning a query |
5511 | ** that uses the generate_series virtual table. This routine needs to create |
5512 | ** a query plan for each invocation and compute an estimated cost for that |
5513 | ** plan. |
5514 | ** |
5515 | ** In this implementation idxNum is used to represent the |
5516 | ** query plan. idxStr is unused. |
5517 | ** |
5518 | ** The query plan is represented by values of idxNum: |
5519 | ** |
5520 | ** (1) The path value is supplied by argv[0] |
5521 | ** (2) Path is in argv[0] and dir is in argv[1] |
5522 | */ |
5523 | static int fsdirBestIndex( |
5524 | sqlite3_vtab *tab, |
5525 | sqlite3_index_info *pIdxInfo |
5526 | ){ |
5527 | int i; /* Loop over constraints */ |
5528 | int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */ |
5529 | int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */ |
5530 | int seenPath = 0; /* True if an unusable PATH= constraint is seen */ |
5531 | int seenDir = 0; /* True if an unusable DIR= constraint is seen */ |
5532 | const struct sqlite3_index_constraint *pConstraint; |
5533 | |
5534 | (void)tab; |
5535 | pConstraint = pIdxInfo->aConstraint; |
5536 | for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
5537 | if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; |
5538 | switch( pConstraint->iColumn ){ |
5539 | case FSDIR_COLUMN_PATH: { |
5540 | if( pConstraint->usable ){ |
5541 | idxPath = i; |
5542 | seenPath = 0; |
5543 | }else if( idxPath<0 ){ |
5544 | seenPath = 1; |
5545 | } |
5546 | break; |
5547 | } |
5548 | case FSDIR_COLUMN_DIR: { |
5549 | if( pConstraint->usable ){ |
5550 | idxDir = i; |
5551 | seenDir = 0; |
5552 | }else if( idxDir<0 ){ |
5553 | seenDir = 1; |
5554 | } |
5555 | break; |
5556 | } |
5557 | } |
5558 | } |
5559 | if( seenPath || seenDir ){ |
5560 | /* If input parameters are unusable, disallow this plan */ |
5561 | return SQLITE_CONSTRAINT; |
5562 | } |
5563 | |
5564 | if( idxPath<0 ){ |
5565 | pIdxInfo->idxNum = 0; |
5566 | /* The pIdxInfo->estimatedCost should have been initialized to a huge |
5567 | ** number. Leave it unchanged. */ |
5568 | pIdxInfo->estimatedRows = 0x7fffffff; |
5569 | }else{ |
5570 | pIdxInfo->aConstraintUsage[idxPath].omit = 1; |
5571 | pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1; |
5572 | if( idxDir>=0 ){ |
5573 | pIdxInfo->aConstraintUsage[idxDir].omit = 1; |
5574 | pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2; |
5575 | pIdxInfo->idxNum = 2; |
5576 | pIdxInfo->estimatedCost = 10.0; |
5577 | }else{ |
5578 | pIdxInfo->idxNum = 1; |
5579 | pIdxInfo->estimatedCost = 100.0; |
5580 | } |
5581 | } |
5582 | |
5583 | return SQLITE_OK; |
5584 | } |
5585 | |
5586 | /* |
5587 | ** Register the "fsdir" virtual table. |
5588 | */ |
5589 | static int fsdirRegister(sqlite3 *db){ |
5590 | static sqlite3_module fsdirModule = { |
5591 | 0, /* iVersion */ |
5592 | 0, /* xCreate */ |
5593 | fsdirConnect, /* xConnect */ |
5594 | fsdirBestIndex, /* xBestIndex */ |
5595 | fsdirDisconnect, /* xDisconnect */ |
5596 | 0, /* xDestroy */ |
5597 | fsdirOpen, /* xOpen - open a cursor */ |
5598 | fsdirClose, /* xClose - close a cursor */ |
5599 | fsdirFilter, /* xFilter - configure scan constraints */ |
5600 | fsdirNext, /* xNext - advance a cursor */ |
5601 | fsdirEof, /* xEof - check for end of scan */ |
5602 | fsdirColumn, /* xColumn - read data */ |
5603 | fsdirRowid, /* xRowid - read data */ |
5604 | 0, /* xUpdate */ |
5605 | 0, /* xBegin */ |
5606 | 0, /* xSync */ |
5607 | 0, /* xCommit */ |
5608 | 0, /* xRollback */ |
5609 | 0, /* xFindMethod */ |
5610 | 0, /* xRename */ |
5611 | 0, /* xSavepoint */ |
5612 | 0, /* xRelease */ |
5613 | 0, /* xRollbackTo */ |
5614 | 0, /* xShadowName */ |
5615 | }; |
5616 | |
5617 | int rc = sqlite3_create_module(db, "fsdir" , &fsdirModule, 0); |
5618 | return rc; |
5619 | } |
5620 | #else /* SQLITE_OMIT_VIRTUALTABLE */ |
5621 | # define fsdirRegister(x) SQLITE_OK |
5622 | #endif |
5623 | |
5624 | #ifdef _WIN32 |
5625 | |
5626 | #endif |
5627 | int sqlite3_fileio_init( |
5628 | sqlite3 *db, |
5629 | char **pzErrMsg, |
5630 | const sqlite3_api_routines *pApi |
5631 | ){ |
5632 | int rc = SQLITE_OK; |
5633 | SQLITE_EXTENSION_INIT2(pApi); |
5634 | (void)pzErrMsg; /* Unused parameter */ |
5635 | rc = sqlite3_create_function(db, "readfile" , 1, |
5636 | SQLITE_UTF8|SQLITE_DIRECTONLY, 0, |
5637 | readfileFunc, 0, 0); |
5638 | if( rc==SQLITE_OK ){ |
5639 | rc = sqlite3_create_function(db, "writefile" , -1, |
5640 | SQLITE_UTF8|SQLITE_DIRECTONLY, 0, |
5641 | writefileFunc, 0, 0); |
5642 | } |
5643 | if( rc==SQLITE_OK ){ |
5644 | rc = sqlite3_create_function(db, "lsmode" , 1, SQLITE_UTF8, 0, |
5645 | lsModeFunc, 0, 0); |
5646 | } |
5647 | if( rc==SQLITE_OK ){ |
5648 | rc = fsdirRegister(db); |
5649 | } |
5650 | return rc; |
5651 | } |
5652 | |
5653 | #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32)) |
5654 | /* To allow a standalone DLL, make test_windirent.c use the same |
5655 | * redefined SQLite API calls as the above extension code does. |
5656 | * Just pull in this .c to accomplish this. As a beneficial side |
5657 | * effect, this extension becomes a single translation unit. */ |
5658 | # include "test_windirent.c" |
5659 | #endif |
5660 | |
5661 | /************************* End ../ext/misc/fileio.c ********************/ |
5662 | /************************* Begin ../ext/misc/completion.c ******************/ |
5663 | /* |
5664 | ** 2017-07-10 |
5665 | ** |
5666 | ** The author disclaims copyright to this source code. In place of |
5667 | ** a legal notice, here is a blessing: |
5668 | ** |
5669 | ** May you do good and not evil. |
5670 | ** May you find forgiveness for yourself and forgive others. |
5671 | ** May you share freely, never taking more than you give. |
5672 | ** |
5673 | ************************************************************************* |
5674 | ** |
5675 | ** This file implements an eponymous virtual table that returns suggested |
5676 | ** completions for a partial SQL input. |
5677 | ** |
5678 | ** Suggested usage: |
5679 | ** |
5680 | ** SELECT DISTINCT candidate COLLATE nocase |
5681 | ** FROM completion($prefix,$wholeline) |
5682 | ** ORDER BY 1; |
5683 | ** |
5684 | ** The two query parameters are optional. $prefix is the text of the |
5685 | ** current word being typed and that is to be completed. $wholeline is |
5686 | ** the complete input line, used for context. |
5687 | ** |
5688 | ** The raw completion() table might return the same candidate multiple |
5689 | ** times, for example if the same column name is used to two or more |
5690 | ** tables. And the candidates are returned in an arbitrary order. Hence, |
5691 | ** the DISTINCT and ORDER BY are recommended. |
5692 | ** |
5693 | ** This virtual table operates at the speed of human typing, and so there |
5694 | ** is no attempt to make it fast. Even a slow implementation will be much |
5695 | ** faster than any human can type. |
5696 | ** |
5697 | */ |
5698 | /* #include "sqlite3ext.h" */ |
5699 | SQLITE_EXTENSION_INIT1 |
5700 | #include <assert.h> |
5701 | #include <string.h> |
5702 | #include <ctype.h> |
5703 | |
5704 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
5705 | |
5706 | /* completion_vtab is a subclass of sqlite3_vtab which will |
5707 | ** serve as the underlying representation of a completion virtual table |
5708 | */ |
5709 | typedef struct completion_vtab completion_vtab; |
5710 | struct completion_vtab { |
5711 | sqlite3_vtab base; /* Base class - must be first */ |
5712 | sqlite3 *db; /* Database connection for this completion vtab */ |
5713 | }; |
5714 | |
5715 | /* completion_cursor is a subclass of sqlite3_vtab_cursor which will |
5716 | ** serve as the underlying representation of a cursor that scans |
5717 | ** over rows of the result |
5718 | */ |
5719 | typedef struct completion_cursor completion_cursor; |
5720 | struct completion_cursor { |
5721 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
5722 | sqlite3 *db; /* Database connection for this cursor */ |
5723 | int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */ |
5724 | char *zPrefix; /* The prefix for the word we want to complete */ |
5725 | char *zLine; /* The whole that we want to complete */ |
5726 | const char *zCurrentRow; /* Current output row */ |
5727 | int szRow; /* Length of the zCurrentRow string */ |
5728 | sqlite3_stmt *pStmt; /* Current statement */ |
5729 | sqlite3_int64 iRowid; /* The rowid */ |
5730 | int ePhase; /* Current phase */ |
5731 | int j; /* inter-phase counter */ |
5732 | }; |
5733 | |
5734 | /* Values for ePhase: |
5735 | */ |
5736 | #define COMPLETION_FIRST_PHASE 1 |
5737 | #define COMPLETION_KEYWORDS 1 |
5738 | #define COMPLETION_PRAGMAS 2 |
5739 | #define COMPLETION_FUNCTIONS 3 |
5740 | #define COMPLETION_COLLATIONS 4 |
5741 | #define COMPLETION_INDEXES 5 |
5742 | #define COMPLETION_TRIGGERS 6 |
5743 | #define COMPLETION_DATABASES 7 |
5744 | #define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */ |
5745 | #define COMPLETION_COLUMNS 9 |
5746 | #define COMPLETION_MODULES 10 |
5747 | #define COMPLETION_EOF 11 |
5748 | |
5749 | /* |
5750 | ** The completionConnect() method is invoked to create a new |
5751 | ** completion_vtab that describes the completion virtual table. |
5752 | ** |
5753 | ** Think of this routine as the constructor for completion_vtab objects. |
5754 | ** |
5755 | ** All this routine needs to do is: |
5756 | ** |
5757 | ** (1) Allocate the completion_vtab object and initialize all fields. |
5758 | ** |
5759 | ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the |
5760 | ** result set of queries against completion will look like. |
5761 | */ |
5762 | static int completionConnect( |
5763 | sqlite3 *db, |
5764 | void *pAux, |
5765 | int argc, const char *const*argv, |
5766 | sqlite3_vtab **ppVtab, |
5767 | char **pzErr |
5768 | ){ |
5769 | completion_vtab *pNew; |
5770 | int rc; |
5771 | |
5772 | (void)(pAux); /* Unused parameter */ |
5773 | (void)(argc); /* Unused parameter */ |
5774 | (void)(argv); /* Unused parameter */ |
5775 | (void)(pzErr); /* Unused parameter */ |
5776 | |
5777 | /* Column numbers */ |
5778 | #define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */ |
5779 | #define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */ |
5780 | #define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */ |
5781 | #define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */ |
5782 | |
5783 | sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); |
5784 | rc = sqlite3_declare_vtab(db, |
5785 | "CREATE TABLE x(" |
5786 | " candidate TEXT," |
5787 | " prefix TEXT HIDDEN," |
5788 | " wholeline TEXT HIDDEN," |
5789 | " phase INT HIDDEN" /* Used for debugging only */ |
5790 | ")" ); |
5791 | if( rc==SQLITE_OK ){ |
5792 | pNew = sqlite3_malloc( sizeof(*pNew) ); |
5793 | *ppVtab = (sqlite3_vtab*)pNew; |
5794 | if( pNew==0 ) return SQLITE_NOMEM; |
5795 | memset(pNew, 0, sizeof(*pNew)); |
5796 | pNew->db = db; |
5797 | } |
5798 | return rc; |
5799 | } |
5800 | |
5801 | /* |
5802 | ** This method is the destructor for completion_cursor objects. |
5803 | */ |
5804 | static int completionDisconnect(sqlite3_vtab *pVtab){ |
5805 | sqlite3_free(pVtab); |
5806 | return SQLITE_OK; |
5807 | } |
5808 | |
5809 | /* |
5810 | ** Constructor for a new completion_cursor object. |
5811 | */ |
5812 | static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ |
5813 | completion_cursor *pCur; |
5814 | pCur = sqlite3_malloc( sizeof(*pCur) ); |
5815 | if( pCur==0 ) return SQLITE_NOMEM; |
5816 | memset(pCur, 0, sizeof(*pCur)); |
5817 | pCur->db = ((completion_vtab*)p)->db; |
5818 | *ppCursor = &pCur->base; |
5819 | return SQLITE_OK; |
5820 | } |
5821 | |
5822 | /* |
5823 | ** Reset the completion_cursor. |
5824 | */ |
5825 | static void completionCursorReset(completion_cursor *pCur){ |
5826 | sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0; |
5827 | sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0; |
5828 | sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; |
5829 | pCur->j = 0; |
5830 | } |
5831 | |
5832 | /* |
5833 | ** Destructor for a completion_cursor. |
5834 | */ |
5835 | static int completionClose(sqlite3_vtab_cursor *cur){ |
5836 | completionCursorReset((completion_cursor*)cur); |
5837 | sqlite3_free(cur); |
5838 | return SQLITE_OK; |
5839 | } |
5840 | |
5841 | /* |
5842 | ** Advance a completion_cursor to its next row of output. |
5843 | ** |
5844 | ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object |
5845 | ** record the current state of the scan. This routine sets ->zCurrentRow |
5846 | ** to the current row of output and then returns. If no more rows remain, |
5847 | ** then ->ePhase is set to COMPLETION_EOF which will signal the virtual |
5848 | ** table that has reached the end of its scan. |
5849 | ** |
5850 | ** The current implementation just lists potential identifiers and |
5851 | ** keywords and filters them by zPrefix. Future enhancements should |
5852 | ** take zLine into account to try to restrict the set of identifiers and |
5853 | ** keywords based on what would be legal at the current point of input. |
5854 | */ |
5855 | static int completionNext(sqlite3_vtab_cursor *cur){ |
5856 | completion_cursor *pCur = (completion_cursor*)cur; |
5857 | int eNextPhase = 0; /* Next phase to try if current phase reaches end */ |
5858 | int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */ |
5859 | pCur->iRowid++; |
5860 | while( pCur->ePhase!=COMPLETION_EOF ){ |
5861 | switch( pCur->ePhase ){ |
5862 | case COMPLETION_KEYWORDS: { |
5863 | if( pCur->j >= sqlite3_keyword_count() ){ |
5864 | pCur->zCurrentRow = 0; |
5865 | pCur->ePhase = COMPLETION_DATABASES; |
5866 | }else{ |
5867 | sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow); |
5868 | } |
5869 | iCol = -1; |
5870 | break; |
5871 | } |
5872 | case COMPLETION_DATABASES: { |
5873 | if( pCur->pStmt==0 ){ |
5874 | sqlite3_prepare_v2(pCur->db, "PRAGMA database_list" , -1, |
5875 | &pCur->pStmt, 0); |
5876 | } |
5877 | iCol = 1; |
5878 | eNextPhase = COMPLETION_TABLES; |
5879 | break; |
5880 | } |
5881 | case COMPLETION_TABLES: { |
5882 | if( pCur->pStmt==0 ){ |
5883 | sqlite3_stmt *pS2; |
5884 | char *zSql = 0; |
5885 | const char *zSep = "" ; |
5886 | sqlite3_prepare_v2(pCur->db, "PRAGMA database_list" , -1, &pS2, 0); |
5887 | while( sqlite3_step(pS2)==SQLITE_ROW ){ |
5888 | const char *zDb = (const char*)sqlite3_column_text(pS2, 1); |
5889 | zSql = sqlite3_mprintf( |
5890 | "%z%s" |
5891 | "SELECT name FROM \"%w\".sqlite_schema" , |
5892 | zSql, zSep, zDb |
5893 | ); |
5894 | if( zSql==0 ) return SQLITE_NOMEM; |
5895 | zSep = " UNION " ; |
5896 | } |
5897 | sqlite3_finalize(pS2); |
5898 | sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); |
5899 | sqlite3_free(zSql); |
5900 | } |
5901 | iCol = 0; |
5902 | eNextPhase = COMPLETION_COLUMNS; |
5903 | break; |
5904 | } |
5905 | case COMPLETION_COLUMNS: { |
5906 | if( pCur->pStmt==0 ){ |
5907 | sqlite3_stmt *pS2; |
5908 | char *zSql = 0; |
5909 | const char *zSep = "" ; |
5910 | sqlite3_prepare_v2(pCur->db, "PRAGMA database_list" , -1, &pS2, 0); |
5911 | while( sqlite3_step(pS2)==SQLITE_ROW ){ |
5912 | const char *zDb = (const char*)sqlite3_column_text(pS2, 1); |
5913 | zSql = sqlite3_mprintf( |
5914 | "%z%s" |
5915 | "SELECT pti.name FROM \"%w\".sqlite_schema AS sm" |
5916 | " JOIN pragma_table_info(sm.name,%Q) AS pti" |
5917 | " WHERE sm.type='table'" , |
5918 | zSql, zSep, zDb, zDb |
5919 | ); |
5920 | if( zSql==0 ) return SQLITE_NOMEM; |
5921 | zSep = " UNION " ; |
5922 | } |
5923 | sqlite3_finalize(pS2); |
5924 | sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); |
5925 | sqlite3_free(zSql); |
5926 | } |
5927 | iCol = 0; |
5928 | eNextPhase = COMPLETION_EOF; |
5929 | break; |
5930 | } |
5931 | } |
5932 | if( iCol<0 ){ |
5933 | /* This case is when the phase presets zCurrentRow */ |
5934 | if( pCur->zCurrentRow==0 ) continue; |
5935 | }else{ |
5936 | if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){ |
5937 | /* Extract the next row of content */ |
5938 | pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol); |
5939 | pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol); |
5940 | }else{ |
5941 | /* When all rows are finished, advance to the next phase */ |
5942 | sqlite3_finalize(pCur->pStmt); |
5943 | pCur->pStmt = 0; |
5944 | pCur->ePhase = eNextPhase; |
5945 | continue; |
5946 | } |
5947 | } |
5948 | if( pCur->nPrefix==0 ) break; |
5949 | if( pCur->nPrefix<=pCur->szRow |
5950 | && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 |
5951 | ){ |
5952 | break; |
5953 | } |
5954 | } |
5955 | |
5956 | return SQLITE_OK; |
5957 | } |
5958 | |
5959 | /* |
5960 | ** Return values of columns for the row at which the completion_cursor |
5961 | ** is currently pointing. |
5962 | */ |
5963 | static int completionColumn( |
5964 | sqlite3_vtab_cursor *cur, /* The cursor */ |
5965 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
5966 | int i /* Which column to return */ |
5967 | ){ |
5968 | completion_cursor *pCur = (completion_cursor*)cur; |
5969 | switch( i ){ |
5970 | case COMPLETION_COLUMN_CANDIDATE: { |
5971 | sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT); |
5972 | break; |
5973 | } |
5974 | case COMPLETION_COLUMN_PREFIX: { |
5975 | sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT); |
5976 | break; |
5977 | } |
5978 | case COMPLETION_COLUMN_WHOLELINE: { |
5979 | sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT); |
5980 | break; |
5981 | } |
5982 | case COMPLETION_COLUMN_PHASE: { |
5983 | sqlite3_result_int(ctx, pCur->ePhase); |
5984 | break; |
5985 | } |
5986 | } |
5987 | return SQLITE_OK; |
5988 | } |
5989 | |
5990 | /* |
5991 | ** Return the rowid for the current row. In this implementation, the |
5992 | ** rowid is the same as the output value. |
5993 | */ |
5994 | static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
5995 | completion_cursor *pCur = (completion_cursor*)cur; |
5996 | *pRowid = pCur->iRowid; |
5997 | return SQLITE_OK; |
5998 | } |
5999 | |
6000 | /* |
6001 | ** Return TRUE if the cursor has been moved off of the last |
6002 | ** row of output. |
6003 | */ |
6004 | static int completionEof(sqlite3_vtab_cursor *cur){ |
6005 | completion_cursor *pCur = (completion_cursor*)cur; |
6006 | return pCur->ePhase >= COMPLETION_EOF; |
6007 | } |
6008 | |
6009 | /* |
6010 | ** This method is called to "rewind" the completion_cursor object back |
6011 | ** to the first row of output. This method is always called at least |
6012 | ** once prior to any call to completionColumn() or completionRowid() or |
6013 | ** completionEof(). |
6014 | */ |
6015 | static int completionFilter( |
6016 | sqlite3_vtab_cursor *pVtabCursor, |
6017 | int idxNum, const char *idxStr, |
6018 | int argc, sqlite3_value **argv |
6019 | ){ |
6020 | completion_cursor *pCur = (completion_cursor *)pVtabCursor; |
6021 | int iArg = 0; |
6022 | (void)(idxStr); /* Unused parameter */ |
6023 | (void)(argc); /* Unused parameter */ |
6024 | completionCursorReset(pCur); |
6025 | if( idxNum & 1 ){ |
6026 | pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); |
6027 | if( pCur->nPrefix>0 ){ |
6028 | pCur->zPrefix = sqlite3_mprintf("%s" , sqlite3_value_text(argv[iArg])); |
6029 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
6030 | } |
6031 | iArg = 1; |
6032 | } |
6033 | if( idxNum & 2 ){ |
6034 | pCur->nLine = sqlite3_value_bytes(argv[iArg]); |
6035 | if( pCur->nLine>0 ){ |
6036 | pCur->zLine = sqlite3_mprintf("%s" , sqlite3_value_text(argv[iArg])); |
6037 | if( pCur->zLine==0 ) return SQLITE_NOMEM; |
6038 | } |
6039 | } |
6040 | if( pCur->zLine!=0 && pCur->zPrefix==0 ){ |
6041 | int i = pCur->nLine; |
6042 | while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ |
6043 | i--; |
6044 | } |
6045 | pCur->nPrefix = pCur->nLine - i; |
6046 | if( pCur->nPrefix>0 ){ |
6047 | pCur->zPrefix = sqlite3_mprintf("%.*s" , pCur->nPrefix, pCur->zLine + i); |
6048 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
6049 | } |
6050 | } |
6051 | pCur->iRowid = 0; |
6052 | pCur->ePhase = COMPLETION_FIRST_PHASE; |
6053 | return completionNext(pVtabCursor); |
6054 | } |
6055 | |
6056 | /* |
6057 | ** SQLite will invoke this method one or more times while planning a query |
6058 | ** that uses the completion virtual table. This routine needs to create |
6059 | ** a query plan for each invocation and compute an estimated cost for that |
6060 | ** plan. |
6061 | ** |
6062 | ** There are two hidden parameters that act as arguments to the table-valued |
6063 | ** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix" |
6064 | ** is available and bit 1 is set if "wholeline" is available. |
6065 | */ |
6066 | static int completionBestIndex( |
6067 | sqlite3_vtab *tab, |
6068 | sqlite3_index_info *pIdxInfo |
6069 | ){ |
6070 | int i; /* Loop over constraints */ |
6071 | int idxNum = 0; /* The query plan bitmask */ |
6072 | int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */ |
6073 | int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */ |
6074 | int nArg = 0; /* Number of arguments that completeFilter() expects */ |
6075 | const struct sqlite3_index_constraint *pConstraint; |
6076 | |
6077 | (void)(tab); /* Unused parameter */ |
6078 | pConstraint = pIdxInfo->aConstraint; |
6079 | for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ |
6080 | if( pConstraint->usable==0 ) continue; |
6081 | if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; |
6082 | switch( pConstraint->iColumn ){ |
6083 | case COMPLETION_COLUMN_PREFIX: |
6084 | prefixIdx = i; |
6085 | idxNum |= 1; |
6086 | break; |
6087 | case COMPLETION_COLUMN_WHOLELINE: |
6088 | wholelineIdx = i; |
6089 | idxNum |= 2; |
6090 | break; |
6091 | } |
6092 | } |
6093 | if( prefixIdx>=0 ){ |
6094 | pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg; |
6095 | pIdxInfo->aConstraintUsage[prefixIdx].omit = 1; |
6096 | } |
6097 | if( wholelineIdx>=0 ){ |
6098 | pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg; |
6099 | pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1; |
6100 | } |
6101 | pIdxInfo->idxNum = idxNum; |
6102 | pIdxInfo->estimatedCost = (double)5000 - 1000*nArg; |
6103 | pIdxInfo->estimatedRows = 500 - 100*nArg; |
6104 | return SQLITE_OK; |
6105 | } |
6106 | |
6107 | /* |
6108 | ** This following structure defines all the methods for the |
6109 | ** completion virtual table. |
6110 | */ |
6111 | static sqlite3_module completionModule = { |
6112 | 0, /* iVersion */ |
6113 | 0, /* xCreate */ |
6114 | completionConnect, /* xConnect */ |
6115 | completionBestIndex, /* xBestIndex */ |
6116 | completionDisconnect, /* xDisconnect */ |
6117 | 0, /* xDestroy */ |
6118 | completionOpen, /* xOpen - open a cursor */ |
6119 | completionClose, /* xClose - close a cursor */ |
6120 | completionFilter, /* xFilter - configure scan constraints */ |
6121 | completionNext, /* xNext - advance a cursor */ |
6122 | completionEof, /* xEof - check for end of scan */ |
6123 | completionColumn, /* xColumn - read data */ |
6124 | completionRowid, /* xRowid - read data */ |
6125 | 0, /* xUpdate */ |
6126 | 0, /* xBegin */ |
6127 | 0, /* xSync */ |
6128 | 0, /* xCommit */ |
6129 | 0, /* xRollback */ |
6130 | 0, /* xFindMethod */ |
6131 | 0, /* xRename */ |
6132 | 0, /* xSavepoint */ |
6133 | 0, /* xRelease */ |
6134 | 0, /* xRollbackTo */ |
6135 | 0 /* xShadowName */ |
6136 | }; |
6137 | |
6138 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
6139 | |
6140 | int sqlite3CompletionVtabInit(sqlite3 *db){ |
6141 | int rc = SQLITE_OK; |
6142 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
6143 | rc = sqlite3_create_module(db, "completion" , &completionModule, 0); |
6144 | #endif |
6145 | return rc; |
6146 | } |
6147 | |
6148 | #ifdef _WIN32 |
6149 | |
6150 | #endif |
6151 | int sqlite3_completion_init( |
6152 | sqlite3 *db, |
6153 | char **pzErrMsg, |
6154 | const sqlite3_api_routines *pApi |
6155 | ){ |
6156 | int rc = SQLITE_OK; |
6157 | SQLITE_EXTENSION_INIT2(pApi); |
6158 | (void)(pzErrMsg); /* Unused parameter */ |
6159 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
6160 | rc = sqlite3CompletionVtabInit(db); |
6161 | #endif |
6162 | return rc; |
6163 | } |
6164 | |
6165 | /************************* End ../ext/misc/completion.c ********************/ |
6166 | /************************* Begin ../ext/misc/appendvfs.c ******************/ |
6167 | /* |
6168 | ** 2017-10-20 |
6169 | ** |
6170 | ** The author disclaims copyright to this source code. In place of |
6171 | ** a legal notice, here is a blessing: |
6172 | ** |
6173 | ** May you do good and not evil. |
6174 | ** May you find forgiveness for yourself and forgive others. |
6175 | ** May you share freely, never taking more than you give. |
6176 | ** |
6177 | ****************************************************************************** |
6178 | ** |
6179 | ** This file implements a VFS shim that allows an SQLite database to be |
6180 | ** appended onto the end of some other file, such as an executable. |
6181 | ** |
6182 | ** A special record must appear at the end of the file that identifies the |
6183 | ** file as an appended database and provides the offset to the first page |
6184 | ** of the exposed content. (Or, it is the length of the content prefix.) |
6185 | ** For best performance page 1 should be located at a disk page boundary, |
6186 | ** though that is not required. |
6187 | ** |
6188 | ** When opening a database using this VFS, the connection might treat |
6189 | ** the file as an ordinary SQLite database, or it might treat it as a |
6190 | ** database appended onto some other file. The decision is made by |
6191 | ** applying the following rules in order: |
6192 | ** |
6193 | ** (1) An empty file is an ordinary database. |
6194 | ** |
6195 | ** (2) If the file ends with the appendvfs trailer string |
6196 | ** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database. |
6197 | ** |
6198 | ** (3) If the file begins with the standard SQLite prefix string |
6199 | ** "SQLite format 3", that file is an ordinary database. |
6200 | ** |
6201 | ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is |
6202 | ** set, then a new database is appended to the already existing file. |
6203 | ** |
6204 | ** (5) Otherwise, SQLITE_CANTOPEN is returned. |
6205 | ** |
6206 | ** To avoid unnecessary complications with the PENDING_BYTE, the size of |
6207 | ** the file containing the database is limited to 1GiB. (1073741824 bytes) |
6208 | ** This VFS will not read or write past the 1GiB mark. This restriction |
6209 | ** might be lifted in future versions. For now, if you need a larger |
6210 | ** database, then keep it in a separate file. |
6211 | ** |
6212 | ** If the file being opened is a plain database (not an appended one), then |
6213 | ** this shim is a pass-through into the default underlying VFS. (rule 3) |
6214 | **/ |
6215 | /* #include "sqlite3ext.h" */ |
6216 | SQLITE_EXTENSION_INIT1 |
6217 | #include <string.h> |
6218 | #include <assert.h> |
6219 | |
6220 | /* The append mark at the end of the database is: |
6221 | ** |
6222 | ** Start-Of-SQLite3-NNNNNNNN |
6223 | ** 123456789 123456789 12345 |
6224 | ** |
6225 | ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is |
6226 | ** the offset to page 1, and also the length of the prefix content. |
6227 | */ |
6228 | #define APND_MARK_PREFIX "Start-Of-SQLite3-" |
6229 | #define APND_MARK_PREFIX_SZ 17 |
6230 | #define APND_MARK_FOS_SZ 8 |
6231 | #define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ) |
6232 | |
6233 | /* |
6234 | ** Maximum size of the combined prefix + database + append-mark. This |
6235 | ** must be less than 0x40000000 to avoid locking issues on Windows. |
6236 | */ |
6237 | #define APND_MAX_SIZE (0x40000000) |
6238 | |
6239 | /* |
6240 | ** Try to align the database to an even multiple of APND_ROUNDUP bytes. |
6241 | */ |
6242 | #ifndef APND_ROUNDUP |
6243 | #define APND_ROUNDUP 4096 |
6244 | #endif |
6245 | #define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1)) |
6246 | #define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK) |
6247 | |
6248 | /* |
6249 | ** Forward declaration of objects used by this utility |
6250 | */ |
6251 | typedef struct sqlite3_vfs ApndVfs; |
6252 | typedef struct ApndFile ApndFile; |
6253 | |
6254 | /* Access to a lower-level VFS that (might) implement dynamic loading, |
6255 | ** access to randomness, etc. |
6256 | */ |
6257 | #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) |
6258 | #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1)) |
6259 | |
6260 | /* An open appendvfs file |
6261 | ** |
6262 | ** An instance of this structure describes the appended database file. |
6263 | ** A separate sqlite3_file object is always appended. The appended |
6264 | ** sqlite3_file object (which can be accessed using ORIGFILE()) describes |
6265 | ** the entire file, including the prefix, the database, and the |
6266 | ** append-mark. |
6267 | ** |
6268 | ** The structure of an AppendVFS database is like this: |
6269 | ** |
6270 | ** +-------------+---------+----------+-------------+ |
6271 | ** | prefix-file | padding | database | append-mark | |
6272 | ** +-------------+---------+----------+-------------+ |
6273 | ** ^ ^ |
6274 | ** | | |
6275 | ** iPgOne iMark |
6276 | ** |
6277 | ** |
6278 | ** "prefix file" - file onto which the database has been appended. |
6279 | ** "padding" - zero or more bytes inserted so that "database" |
6280 | ** starts on an APND_ROUNDUP boundary |
6281 | ** "database" - The SQLite database file |
6282 | ** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates |
6283 | ** the offset from the start of prefix-file to the start |
6284 | ** of "database". |
6285 | ** |
6286 | ** The size of the database is iMark - iPgOne. |
6287 | ** |
6288 | ** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value |
6289 | ** of iPgOne stored as a big-ending 64-bit integer. |
6290 | ** |
6291 | ** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE). |
6292 | ** Or, iMark is -1 to indicate that it has not yet been written. |
6293 | */ |
6294 | struct ApndFile { |
6295 | sqlite3_file base; /* Subclass. MUST BE FIRST! */ |
6296 | sqlite3_int64 iPgOne; /* Offset to the start of the database */ |
6297 | sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */ |
6298 | /* Always followed by another sqlite3_file that describes the whole file */ |
6299 | }; |
6300 | |
6301 | /* |
6302 | ** Methods for ApndFile |
6303 | */ |
6304 | static int apndClose(sqlite3_file*); |
6305 | static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); |
6306 | static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); |
6307 | static int apndTruncate(sqlite3_file*, sqlite3_int64 size); |
6308 | static int apndSync(sqlite3_file*, int flags); |
6309 | static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize); |
6310 | static int apndLock(sqlite3_file*, int); |
6311 | static int apndUnlock(sqlite3_file*, int); |
6312 | static int apndCheckReservedLock(sqlite3_file*, int *pResOut); |
6313 | static int apndFileControl(sqlite3_file*, int op, void *pArg); |
6314 | static int apndSectorSize(sqlite3_file*); |
6315 | static int apndDeviceCharacteristics(sqlite3_file*); |
6316 | static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**); |
6317 | static int apndShmLock(sqlite3_file*, int offset, int n, int flags); |
6318 | static void apndShmBarrier(sqlite3_file*); |
6319 | static int apndShmUnmap(sqlite3_file*, int deleteFlag); |
6320 | static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); |
6321 | static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); |
6322 | |
6323 | /* |
6324 | ** Methods for ApndVfs |
6325 | */ |
6326 | static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); |
6327 | static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir); |
6328 | static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *); |
6329 | static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); |
6330 | static void *apndDlOpen(sqlite3_vfs*, const char *zFilename); |
6331 | static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg); |
6332 | static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); |
6333 | static void apndDlClose(sqlite3_vfs*, void*); |
6334 | static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut); |
6335 | static int apndSleep(sqlite3_vfs*, int microseconds); |
6336 | static int apndCurrentTime(sqlite3_vfs*, double*); |
6337 | static int apndGetLastError(sqlite3_vfs*, int, char *); |
6338 | static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); |
6339 | static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr); |
6340 | static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z); |
6341 | static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName); |
6342 | |
6343 | static sqlite3_vfs apnd_vfs = { |
6344 | 3, /* iVersion (set when registered) */ |
6345 | 0, /* szOsFile (set when registered) */ |
6346 | 1024, /* mxPathname */ |
6347 | 0, /* pNext */ |
6348 | "apndvfs" , /* zName */ |
6349 | 0, /* pAppData (set when registered) */ |
6350 | apndOpen, /* xOpen */ |
6351 | apndDelete, /* xDelete */ |
6352 | apndAccess, /* xAccess */ |
6353 | apndFullPathname, /* xFullPathname */ |
6354 | apndDlOpen, /* xDlOpen */ |
6355 | apndDlError, /* xDlError */ |
6356 | apndDlSym, /* xDlSym */ |
6357 | apndDlClose, /* xDlClose */ |
6358 | apndRandomness, /* xRandomness */ |
6359 | apndSleep, /* xSleep */ |
6360 | apndCurrentTime, /* xCurrentTime */ |
6361 | apndGetLastError, /* xGetLastError */ |
6362 | apndCurrentTimeInt64, /* xCurrentTimeInt64 */ |
6363 | apndSetSystemCall, /* xSetSystemCall */ |
6364 | apndGetSystemCall, /* xGetSystemCall */ |
6365 | apndNextSystemCall /* xNextSystemCall */ |
6366 | }; |
6367 | |
6368 | static const sqlite3_io_methods apnd_io_methods = { |
6369 | 3, /* iVersion */ |
6370 | apndClose, /* xClose */ |
6371 | apndRead, /* xRead */ |
6372 | apndWrite, /* xWrite */ |
6373 | apndTruncate, /* xTruncate */ |
6374 | apndSync, /* xSync */ |
6375 | apndFileSize, /* xFileSize */ |
6376 | apndLock, /* xLock */ |
6377 | apndUnlock, /* xUnlock */ |
6378 | apndCheckReservedLock, /* xCheckReservedLock */ |
6379 | apndFileControl, /* xFileControl */ |
6380 | apndSectorSize, /* xSectorSize */ |
6381 | apndDeviceCharacteristics, /* xDeviceCharacteristics */ |
6382 | apndShmMap, /* xShmMap */ |
6383 | apndShmLock, /* xShmLock */ |
6384 | apndShmBarrier, /* xShmBarrier */ |
6385 | apndShmUnmap, /* xShmUnmap */ |
6386 | apndFetch, /* xFetch */ |
6387 | apndUnfetch /* xUnfetch */ |
6388 | }; |
6389 | |
6390 | /* |
6391 | ** Close an apnd-file. |
6392 | */ |
6393 | static int apndClose(sqlite3_file *pFile){ |
6394 | pFile = ORIGFILE(pFile); |
6395 | return pFile->pMethods->xClose(pFile); |
6396 | } |
6397 | |
6398 | /* |
6399 | ** Read data from an apnd-file. |
6400 | */ |
6401 | static int apndRead( |
6402 | sqlite3_file *pFile, |
6403 | void *zBuf, |
6404 | int iAmt, |
6405 | sqlite_int64 iOfst |
6406 | ){ |
6407 | ApndFile *paf = (ApndFile *)pFile; |
6408 | pFile = ORIGFILE(pFile); |
6409 | return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst); |
6410 | } |
6411 | |
6412 | /* |
6413 | ** Add the append-mark onto what should become the end of the file. |
6414 | * If and only if this succeeds, internal ApndFile.iMark is updated. |
6415 | * Parameter iWriteEnd is the appendvfs-relative offset of the new mark. |
6416 | */ |
6417 | static int apndWriteMark( |
6418 | ApndFile *paf, |
6419 | sqlite3_file *pFile, |
6420 | sqlite_int64 iWriteEnd |
6421 | ){ |
6422 | sqlite_int64 iPgOne = paf->iPgOne; |
6423 | unsigned char a[APND_MARK_SIZE]; |
6424 | int i = APND_MARK_FOS_SZ; |
6425 | int rc; |
6426 | assert(pFile == ORIGFILE(paf)); |
6427 | memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ); |
6428 | while( --i >= 0 ){ |
6429 | a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff); |
6430 | iPgOne >>= 8; |
6431 | } |
6432 | iWriteEnd += paf->iPgOne; |
6433 | if( SQLITE_OK==(rc = pFile->pMethods->xWrite |
6434 | (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){ |
6435 | paf->iMark = iWriteEnd; |
6436 | } |
6437 | return rc; |
6438 | } |
6439 | |
6440 | /* |
6441 | ** Write data to an apnd-file. |
6442 | */ |
6443 | static int apndWrite( |
6444 | sqlite3_file *pFile, |
6445 | const void *zBuf, |
6446 | int iAmt, |
6447 | sqlite_int64 iOfst |
6448 | ){ |
6449 | ApndFile *paf = (ApndFile *)pFile; |
6450 | sqlite_int64 iWriteEnd = iOfst + iAmt; |
6451 | if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL; |
6452 | pFile = ORIGFILE(pFile); |
6453 | /* If append-mark is absent or will be overwritten, write it. */ |
6454 | if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){ |
6455 | int rc = apndWriteMark(paf, pFile, iWriteEnd); |
6456 | if( SQLITE_OK!=rc ) return rc; |
6457 | } |
6458 | return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst); |
6459 | } |
6460 | |
6461 | /* |
6462 | ** Truncate an apnd-file. |
6463 | */ |
6464 | static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){ |
6465 | ApndFile *paf = (ApndFile *)pFile; |
6466 | pFile = ORIGFILE(pFile); |
6467 | /* The append mark goes out first so truncate failure does not lose it. */ |
6468 | if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR; |
6469 | /* Truncate underlying file just past append mark */ |
6470 | return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE); |
6471 | } |
6472 | |
6473 | /* |
6474 | ** Sync an apnd-file. |
6475 | */ |
6476 | static int apndSync(sqlite3_file *pFile, int flags){ |
6477 | pFile = ORIGFILE(pFile); |
6478 | return pFile->pMethods->xSync(pFile, flags); |
6479 | } |
6480 | |
6481 | /* |
6482 | ** Return the current file-size of an apnd-file. |
6483 | ** If the append mark is not yet there, the file-size is 0. |
6484 | */ |
6485 | static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ |
6486 | ApndFile *paf = (ApndFile *)pFile; |
6487 | *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0; |
6488 | return SQLITE_OK; |
6489 | } |
6490 | |
6491 | /* |
6492 | ** Lock an apnd-file. |
6493 | */ |
6494 | static int apndLock(sqlite3_file *pFile, int eLock){ |
6495 | pFile = ORIGFILE(pFile); |
6496 | return pFile->pMethods->xLock(pFile, eLock); |
6497 | } |
6498 | |
6499 | /* |
6500 | ** Unlock an apnd-file. |
6501 | */ |
6502 | static int apndUnlock(sqlite3_file *pFile, int eLock){ |
6503 | pFile = ORIGFILE(pFile); |
6504 | return pFile->pMethods->xUnlock(pFile, eLock); |
6505 | } |
6506 | |
6507 | /* |
6508 | ** Check if another file-handle holds a RESERVED lock on an apnd-file. |
6509 | */ |
6510 | static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){ |
6511 | pFile = ORIGFILE(pFile); |
6512 | return pFile->pMethods->xCheckReservedLock(pFile, pResOut); |
6513 | } |
6514 | |
6515 | /* |
6516 | ** File control method. For custom operations on an apnd-file. |
6517 | */ |
6518 | static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){ |
6519 | ApndFile *paf = (ApndFile *)pFile; |
6520 | int rc; |
6521 | pFile = ORIGFILE(pFile); |
6522 | if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne; |
6523 | rc = pFile->pMethods->xFileControl(pFile, op, pArg); |
6524 | if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ |
6525 | *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z" , paf->iPgOne,*(char**)pArg); |
6526 | } |
6527 | return rc; |
6528 | } |
6529 | |
6530 | /* |
6531 | ** Return the sector-size in bytes for an apnd-file. |
6532 | */ |
6533 | static int apndSectorSize(sqlite3_file *pFile){ |
6534 | pFile = ORIGFILE(pFile); |
6535 | return pFile->pMethods->xSectorSize(pFile); |
6536 | } |
6537 | |
6538 | /* |
6539 | ** Return the device characteristic flags supported by an apnd-file. |
6540 | */ |
6541 | static int apndDeviceCharacteristics(sqlite3_file *pFile){ |
6542 | pFile = ORIGFILE(pFile); |
6543 | return pFile->pMethods->xDeviceCharacteristics(pFile); |
6544 | } |
6545 | |
6546 | /* Create a shared memory file mapping */ |
6547 | static int apndShmMap( |
6548 | sqlite3_file *pFile, |
6549 | int iPg, |
6550 | int pgsz, |
6551 | int bExtend, |
6552 | void volatile **pp |
6553 | ){ |
6554 | pFile = ORIGFILE(pFile); |
6555 | return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp); |
6556 | } |
6557 | |
6558 | /* Perform locking on a shared-memory segment */ |
6559 | static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){ |
6560 | pFile = ORIGFILE(pFile); |
6561 | return pFile->pMethods->xShmLock(pFile,offset,n,flags); |
6562 | } |
6563 | |
6564 | /* Memory barrier operation on shared memory */ |
6565 | static void apndShmBarrier(sqlite3_file *pFile){ |
6566 | pFile = ORIGFILE(pFile); |
6567 | pFile->pMethods->xShmBarrier(pFile); |
6568 | } |
6569 | |
6570 | /* Unmap a shared memory segment */ |
6571 | static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){ |
6572 | pFile = ORIGFILE(pFile); |
6573 | return pFile->pMethods->xShmUnmap(pFile,deleteFlag); |
6574 | } |
6575 | |
6576 | /* Fetch a page of a memory-mapped file */ |
6577 | static int apndFetch( |
6578 | sqlite3_file *pFile, |
6579 | sqlite3_int64 iOfst, |
6580 | int iAmt, |
6581 | void **pp |
6582 | ){ |
6583 | ApndFile *p = (ApndFile *)pFile; |
6584 | if( p->iMark < 0 || iOfst+iAmt > p->iMark ){ |
6585 | return SQLITE_IOERR; /* Cannot read what is not yet there. */ |
6586 | } |
6587 | pFile = ORIGFILE(pFile); |
6588 | return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp); |
6589 | } |
6590 | |
6591 | /* Release a memory-mapped page */ |
6592 | static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ |
6593 | ApndFile *p = (ApndFile *)pFile; |
6594 | pFile = ORIGFILE(pFile); |
6595 | return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage); |
6596 | } |
6597 | |
6598 | /* |
6599 | ** Try to read the append-mark off the end of a file. Return the |
6600 | ** start of the appended database if the append-mark is present. |
6601 | ** If there is no valid append-mark, return -1; |
6602 | ** |
6603 | ** An append-mark is only valid if the NNNNNNNN start-of-database offset |
6604 | ** indicates that the appended database contains at least one page. The |
6605 | ** start-of-database value must be a multiple of 512. |
6606 | */ |
6607 | static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){ |
6608 | int rc, i; |
6609 | sqlite3_int64 iMark; |
6610 | int msbs = 8 * (APND_MARK_FOS_SZ-1); |
6611 | unsigned char a[APND_MARK_SIZE]; |
6612 | |
6613 | if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1; |
6614 | rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE); |
6615 | if( rc ) return -1; |
6616 | if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1; |
6617 | iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs; |
6618 | for(i=1; i<8; i++){ |
6619 | msbs -= 8; |
6620 | iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs; |
6621 | } |
6622 | if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1; |
6623 | if( iMark & 0x1ff ) return -1; |
6624 | return iMark; |
6625 | } |
6626 | |
6627 | static const char apvfsSqliteHdr[] = "SQLite format 3" ; |
6628 | /* |
6629 | ** Check to see if the file is an appendvfs SQLite database file. |
6630 | ** Return true iff it is such. Parameter sz is the file's size. |
6631 | */ |
6632 | static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){ |
6633 | int rc; |
6634 | char zHdr[16]; |
6635 | sqlite3_int64 iMark = apndReadMark(sz, pFile); |
6636 | if( iMark>=0 ){ |
6637 | /* If file has the correct end-marker, the expected odd size, and the |
6638 | ** SQLite DB type marker where the end-marker puts it, then it |
6639 | ** is an appendvfs database. |
6640 | */ |
6641 | rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark); |
6642 | if( SQLITE_OK==rc |
6643 | && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0 |
6644 | && (sz & 0x1ff) == APND_MARK_SIZE |
6645 | && sz>=512+APND_MARK_SIZE |
6646 | ){ |
6647 | return 1; /* It's an appendvfs database */ |
6648 | } |
6649 | } |
6650 | return 0; |
6651 | } |
6652 | |
6653 | /* |
6654 | ** Check to see if the file is an ordinary SQLite database file. |
6655 | ** Return true iff so. Parameter sz is the file's size. |
6656 | */ |
6657 | static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ |
6658 | char zHdr[16]; |
6659 | if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */ |
6660 | || (sz & 0x1ff) != 0 |
6661 | || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0) |
6662 | || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0 |
6663 | ){ |
6664 | return 0; |
6665 | }else{ |
6666 | return 1; |
6667 | } |
6668 | } |
6669 | |
6670 | /* |
6671 | ** Open an apnd file handle. |
6672 | */ |
6673 | static int apndOpen( |
6674 | sqlite3_vfs *pApndVfs, |
6675 | const char *zName, |
6676 | sqlite3_file *pFile, |
6677 | int flags, |
6678 | int *pOutFlags |
6679 | ){ |
6680 | ApndFile *pApndFile = (ApndFile*)pFile; |
6681 | sqlite3_file *pBaseFile = ORIGFILE(pFile); |
6682 | sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs); |
6683 | int rc; |
6684 | sqlite3_int64 sz = 0; |
6685 | if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ |
6686 | /* The appendvfs is not to be used for transient or temporary databases. |
6687 | ** Just use the base VFS open to initialize the given file object and |
6688 | ** open the underlying file. (Appendvfs is then unused for this file.) |
6689 | */ |
6690 | return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags); |
6691 | } |
6692 | memset(pApndFile, 0, sizeof(ApndFile)); |
6693 | pFile->pMethods = &apnd_io_methods; |
6694 | pApndFile->iMark = -1; /* Append mark not yet written */ |
6695 | |
6696 | rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags); |
6697 | if( rc==SQLITE_OK ){ |
6698 | rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz); |
6699 | if( rc ){ |
6700 | pBaseFile->pMethods->xClose(pBaseFile); |
6701 | } |
6702 | } |
6703 | if( rc ){ |
6704 | pFile->pMethods = 0; |
6705 | return rc; |
6706 | } |
6707 | if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){ |
6708 | /* The file being opened appears to be just an ordinary DB. Copy |
6709 | ** the base dispatch-table so this instance mimics the base VFS. |
6710 | */ |
6711 | memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile); |
6712 | return SQLITE_OK; |
6713 | } |
6714 | pApndFile->iPgOne = apndReadMark(sz, pFile); |
6715 | if( pApndFile->iPgOne>=0 ){ |
6716 | pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */ |
6717 | return SQLITE_OK; |
6718 | } |
6719 | if( (flags & SQLITE_OPEN_CREATE)==0 ){ |
6720 | pBaseFile->pMethods->xClose(pBaseFile); |
6721 | rc = SQLITE_CANTOPEN; |
6722 | pFile->pMethods = 0; |
6723 | }else{ |
6724 | /* Round newly added appendvfs location to #define'd page boundary. |
6725 | ** Note that nothing has yet been written to the underlying file. |
6726 | ** The append mark will be written along with first content write. |
6727 | ** Until then, paf->iMark value indicates it is not yet written. |
6728 | */ |
6729 | pApndFile->iPgOne = APND_START_ROUNDUP(sz); |
6730 | } |
6731 | return rc; |
6732 | } |
6733 | |
6734 | /* |
6735 | ** Delete an apnd file. |
6736 | ** For an appendvfs, this could mean delete the appendvfs portion, |
6737 | ** leaving the appendee as it was before it gained an appendvfs. |
6738 | ** For now, this code deletes the underlying file too. |
6739 | */ |
6740 | static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ |
6741 | return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync); |
6742 | } |
6743 | |
6744 | /* |
6745 | ** All other VFS methods are pass-thrus. |
6746 | */ |
6747 | static int apndAccess( |
6748 | sqlite3_vfs *pVfs, |
6749 | const char *zPath, |
6750 | int flags, |
6751 | int *pResOut |
6752 | ){ |
6753 | return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut); |
6754 | } |
6755 | static int apndFullPathname( |
6756 | sqlite3_vfs *pVfs, |
6757 | const char *zPath, |
6758 | int nOut, |
6759 | char *zOut |
6760 | ){ |
6761 | return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut); |
6762 | } |
6763 | static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){ |
6764 | return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); |
6765 | } |
6766 | static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ |
6767 | ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); |
6768 | } |
6769 | static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ |
6770 | return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); |
6771 | } |
6772 | static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){ |
6773 | ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); |
6774 | } |
6775 | static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ |
6776 | return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); |
6777 | } |
6778 | static int apndSleep(sqlite3_vfs *pVfs, int nMicro){ |
6779 | return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); |
6780 | } |
6781 | static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ |
6782 | return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); |
6783 | } |
6784 | static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){ |
6785 | return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); |
6786 | } |
6787 | static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ |
6788 | return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); |
6789 | } |
6790 | static int apndSetSystemCall( |
6791 | sqlite3_vfs *pVfs, |
6792 | const char *zName, |
6793 | sqlite3_syscall_ptr pCall |
6794 | ){ |
6795 | return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall); |
6796 | } |
6797 | static sqlite3_syscall_ptr apndGetSystemCall( |
6798 | sqlite3_vfs *pVfs, |
6799 | const char *zName |
6800 | ){ |
6801 | return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName); |
6802 | } |
6803 | static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){ |
6804 | return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName); |
6805 | } |
6806 | |
6807 | |
6808 | #ifdef _WIN32 |
6809 | |
6810 | #endif |
6811 | /* |
6812 | ** This routine is called when the extension is loaded. |
6813 | ** Register the new VFS. |
6814 | */ |
6815 | int sqlite3_appendvfs_init( |
6816 | sqlite3 *db, |
6817 | char **pzErrMsg, |
6818 | const sqlite3_api_routines *pApi |
6819 | ){ |
6820 | int rc = SQLITE_OK; |
6821 | sqlite3_vfs *pOrig; |
6822 | SQLITE_EXTENSION_INIT2(pApi); |
6823 | (void)pzErrMsg; |
6824 | (void)db; |
6825 | pOrig = sqlite3_vfs_find(0); |
6826 | if( pOrig==0 ) return SQLITE_ERROR; |
6827 | apnd_vfs.iVersion = pOrig->iVersion; |
6828 | apnd_vfs.pAppData = pOrig; |
6829 | apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile); |
6830 | rc = sqlite3_vfs_register(&apnd_vfs, 0); |
6831 | #ifdef APPENDVFS_TEST |
6832 | if( rc==SQLITE_OK ){ |
6833 | rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister); |
6834 | } |
6835 | #endif |
6836 | if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; |
6837 | return rc; |
6838 | } |
6839 | |
6840 | /************************* End ../ext/misc/appendvfs.c ********************/ |
6841 | #endif |
6842 | #ifdef SQLITE_HAVE_ZLIB |
6843 | /************************* Begin ../ext/misc/zipfile.c ******************/ |
6844 | /* |
6845 | ** 2017-12-26 |
6846 | ** |
6847 | ** The author disclaims copyright to this source code. In place of |
6848 | ** a legal notice, here is a blessing: |
6849 | ** |
6850 | ** May you do good and not evil. |
6851 | ** May you find forgiveness for yourself and forgive others. |
6852 | ** May you share freely, never taking more than you give. |
6853 | ** |
6854 | ****************************************************************************** |
6855 | ** |
6856 | ** This file implements a virtual table for reading and writing ZIP archive |
6857 | ** files. |
6858 | ** |
6859 | ** Usage example: |
6860 | ** |
6861 | ** SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename); |
6862 | ** |
6863 | ** Current limitations: |
6864 | ** |
6865 | ** * No support for encryption |
6866 | ** * No support for ZIP archives spanning multiple files |
6867 | ** * No support for zip64 extensions |
6868 | ** * Only the "inflate/deflate" (zlib) compression method is supported |
6869 | */ |
6870 | /* #include "sqlite3ext.h" */ |
6871 | SQLITE_EXTENSION_INIT1 |
6872 | #include <stdio.h> |
6873 | #include <string.h> |
6874 | #include <assert.h> |
6875 | |
6876 | #include <zlib.h> |
6877 | |
6878 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
6879 | |
6880 | #ifndef SQLITE_AMALGAMATION |
6881 | |
6882 | #ifndef UINT32_TYPE |
6883 | # ifdef HAVE_UINT32_T |
6884 | # define UINT32_TYPE uint32_t |
6885 | # else |
6886 | # define UINT32_TYPE unsigned int |
6887 | # endif |
6888 | #endif |
6889 | #ifndef UINT16_TYPE |
6890 | # ifdef HAVE_UINT16_T |
6891 | # define UINT16_TYPE uint16_t |
6892 | # else |
6893 | # define UINT16_TYPE unsigned short int |
6894 | # endif |
6895 | #endif |
6896 | /* typedef sqlite3_int64 i64; */ |
6897 | /* typedef unsigned char u8; */ |
6898 | /* typedef UINT32_TYPE u32; // 4-byte unsigned integer // */ |
6899 | /* typedef UINT16_TYPE u16; // 2-byte unsigned integer // */ |
6900 | #define MIN(a,b) ((a)<(b) ? (a) : (b)) |
6901 | |
6902 | #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
6903 | # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 |
6904 | #endif |
6905 | #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) |
6906 | # define ALWAYS(X) (1) |
6907 | # define NEVER(X) (0) |
6908 | #elif !defined(NDEBUG) |
6909 | # define ALWAYS(X) ((X)?1:(assert(0),0)) |
6910 | # define NEVER(X) ((X)?(assert(0),1):0) |
6911 | #else |
6912 | # define ALWAYS(X) (X) |
6913 | # define NEVER(X) (X) |
6914 | #endif |
6915 | |
6916 | #endif /* SQLITE_AMALGAMATION */ |
6917 | |
6918 | /* |
6919 | ** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK. |
6920 | ** |
6921 | ** In some ways it would be better to obtain these values from system |
6922 | ** header files. But, the dependency is undesirable and (a) these |
6923 | ** have been stable for decades, (b) the values are part of POSIX and |
6924 | ** are also made explicit in [man stat], and (c) are part of the |
6925 | ** file format for zip archives. |
6926 | */ |
6927 | #ifndef S_IFDIR |
6928 | # define S_IFDIR 0040000 |
6929 | #endif |
6930 | #ifndef S_IFREG |
6931 | # define S_IFREG 0100000 |
6932 | #endif |
6933 | #ifndef S_IFLNK |
6934 | # define S_IFLNK 0120000 |
6935 | #endif |
6936 | |
6937 | static const char ZIPFILE_SCHEMA[] = |
6938 | "CREATE TABLE y(" |
6939 | "name PRIMARY KEY," /* 0: Name of file in zip archive */ |
6940 | "mode," /* 1: POSIX mode for file */ |
6941 | "mtime," /* 2: Last modification time (secs since 1970)*/ |
6942 | "sz," /* 3: Size of object */ |
6943 | "rawdata," /* 4: Raw data */ |
6944 | "data," /* 5: Uncompressed data */ |
6945 | "method," /* 6: Compression method (integer) */ |
6946 | "z HIDDEN" /* 7: Name of zip file */ |
6947 | ") WITHOUT ROWID;" ; |
6948 | |
6949 | #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ |
6950 | #define ZIPFILE_BUFFER_SIZE (64*1024) |
6951 | |
6952 | |
6953 | /* |
6954 | ** Magic numbers used to read and write zip files. |
6955 | ** |
6956 | ** ZIPFILE_NEWENTRY_MADEBY: |
6957 | ** Use this value for the "version-made-by" field in new zip file |
6958 | ** entries. The upper byte indicates "unix", and the lower byte |
6959 | ** indicates that the zip file matches pkzip specification 3.0. |
6960 | ** This is what info-zip seems to do. |
6961 | ** |
6962 | ** ZIPFILE_NEWENTRY_REQUIRED: |
6963 | ** Value for "version-required-to-extract" field of new entries. |
6964 | ** Version 2.0 is required to support folders and deflate compression. |
6965 | ** |
6966 | ** ZIPFILE_NEWENTRY_FLAGS: |
6967 | ** Value for "general-purpose-bit-flags" field of new entries. Bit |
6968 | ** 11 means "utf-8 filename and comment". |
6969 | ** |
6970 | ** ZIPFILE_SIGNATURE_CDS: |
6971 | ** First 4 bytes of a valid CDS record. |
6972 | ** |
6973 | ** ZIPFILE_SIGNATURE_LFH: |
6974 | ** First 4 bytes of a valid LFH record. |
6975 | ** |
6976 | ** ZIPFILE_SIGNATURE_EOCD |
6977 | ** First 4 bytes of a valid EOCD record. |
6978 | */ |
6979 | #define ZIPFILE_EXTRA_TIMESTAMP 0x5455 |
6980 | #define ZIPFILE_NEWENTRY_MADEBY ((3<<8) + 30) |
6981 | #define ZIPFILE_NEWENTRY_REQUIRED 20 |
6982 | #define ZIPFILE_NEWENTRY_FLAGS 0x800 |
6983 | #define ZIPFILE_SIGNATURE_CDS 0x02014b50 |
6984 | #define ZIPFILE_SIGNATURE_LFH 0x04034b50 |
6985 | #define ZIPFILE_SIGNATURE_EOCD 0x06054b50 |
6986 | |
6987 | /* |
6988 | ** The sizes of the fixed-size part of each of the three main data |
6989 | ** structures in a zip archive. |
6990 | */ |
6991 | #define ZIPFILE_LFH_FIXED_SZ 30 |
6992 | #define ZIPFILE_EOCD_FIXED_SZ 22 |
6993 | #define ZIPFILE_CDS_FIXED_SZ 46 |
6994 | |
6995 | /* |
6996 | *** 4.3.16 End of central directory record: |
6997 | *** |
6998 | *** end of central dir signature 4 bytes (0x06054b50) |
6999 | *** number of this disk 2 bytes |
7000 | *** number of the disk with the |
7001 | *** start of the central directory 2 bytes |
7002 | *** total number of entries in the |
7003 | *** central directory on this disk 2 bytes |
7004 | *** total number of entries in |
7005 | *** the central directory 2 bytes |
7006 | *** size of the central directory 4 bytes |
7007 | *** offset of start of central |
7008 | *** directory with respect to |
7009 | *** the starting disk number 4 bytes |
7010 | *** .ZIP file comment length 2 bytes |
7011 | *** .ZIP file comment (variable size) |
7012 | */ |
7013 | typedef struct ZipfileEOCD ZipfileEOCD; |
7014 | struct ZipfileEOCD { |
7015 | u16 iDisk; |
7016 | u16 iFirstDisk; |
7017 | u16 nEntry; |
7018 | u16 nEntryTotal; |
7019 | u32 nSize; |
7020 | u32 iOffset; |
7021 | }; |
7022 | |
7023 | /* |
7024 | *** 4.3.12 Central directory structure: |
7025 | *** |
7026 | *** ... |
7027 | *** |
7028 | *** central file header signature 4 bytes (0x02014b50) |
7029 | *** version made by 2 bytes |
7030 | *** version needed to extract 2 bytes |
7031 | *** general purpose bit flag 2 bytes |
7032 | *** compression method 2 bytes |
7033 | *** last mod file time 2 bytes |
7034 | *** last mod file date 2 bytes |
7035 | *** crc-32 4 bytes |
7036 | *** compressed size 4 bytes |
7037 | *** uncompressed size 4 bytes |
7038 | *** file name length 2 bytes |
7039 | *** extra field length 2 bytes |
7040 | *** file comment length 2 bytes |
7041 | *** disk number start 2 bytes |
7042 | *** internal file attributes 2 bytes |
7043 | *** external file attributes 4 bytes |
7044 | *** relative offset of local header 4 bytes |
7045 | */ |
7046 | typedef struct ZipfileCDS ZipfileCDS; |
7047 | struct ZipfileCDS { |
7048 | u16 iVersionMadeBy; |
7049 | u16 iVersionExtract; |
7050 | u16 flags; |
7051 | u16 iCompression; |
7052 | u16 mTime; |
7053 | u16 mDate; |
7054 | u32 crc32; |
7055 | u32 szCompressed; |
7056 | u32 szUncompressed; |
7057 | u16 nFile; |
7058 | u16 nExtra; |
7059 | u16 nComment; |
7060 | u16 iDiskStart; |
7061 | u16 iInternalAttr; |
7062 | u32 iExternalAttr; |
7063 | u32 iOffset; |
7064 | char *zFile; /* Filename (sqlite3_malloc()) */ |
7065 | }; |
7066 | |
7067 | /* |
7068 | *** 4.3.7 Local file header: |
7069 | *** |
7070 | *** local file header signature 4 bytes (0x04034b50) |
7071 | *** version needed to extract 2 bytes |
7072 | *** general purpose bit flag 2 bytes |
7073 | *** compression method 2 bytes |
7074 | *** last mod file time 2 bytes |
7075 | *** last mod file date 2 bytes |
7076 | *** crc-32 4 bytes |
7077 | *** compressed size 4 bytes |
7078 | *** uncompressed size 4 bytes |
7079 | *** file name length 2 bytes |
7080 | *** extra field length 2 bytes |
7081 | *** |
7082 | */ |
7083 | typedef struct ZipfileLFH ZipfileLFH; |
7084 | struct ZipfileLFH { |
7085 | u16 iVersionExtract; |
7086 | u16 flags; |
7087 | u16 iCompression; |
7088 | u16 mTime; |
7089 | u16 mDate; |
7090 | u32 crc32; |
7091 | u32 szCompressed; |
7092 | u32 szUncompressed; |
7093 | u16 nFile; |
7094 | u16 nExtra; |
7095 | }; |
7096 | |
7097 | typedef struct ZipfileEntry ZipfileEntry; |
7098 | struct ZipfileEntry { |
7099 | ZipfileCDS cds; /* Parsed CDS record */ |
7100 | u32 mUnixTime; /* Modification time, in UNIX format */ |
7101 | u8 *aExtra; /* cds.nExtra+cds.nComment bytes of extra data */ |
7102 | i64 iDataOff; /* Offset to data in file (if aData==0) */ |
7103 | u8 *aData; /* cds.szCompressed bytes of compressed data */ |
7104 | ZipfileEntry *pNext; /* Next element in in-memory CDS */ |
7105 | }; |
7106 | |
7107 | /* |
7108 | ** Cursor type for zipfile tables. |
7109 | */ |
7110 | typedef struct ZipfileCsr ZipfileCsr; |
7111 | struct ZipfileCsr { |
7112 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
7113 | i64 iId; /* Cursor ID */ |
7114 | u8 bEof; /* True when at EOF */ |
7115 | u8 bNoop; /* If next xNext() call is no-op */ |
7116 | |
7117 | /* Used outside of write transactions */ |
7118 | FILE *pFile; /* Zip file */ |
7119 | i64 iNextOff; /* Offset of next record in central directory */ |
7120 | ZipfileEOCD eocd; /* Parse of central directory record */ |
7121 | |
7122 | ZipfileEntry *pFreeEntry; /* Free this list when cursor is closed or reset */ |
7123 | ZipfileEntry *pCurrent; /* Current entry */ |
7124 | ZipfileCsr *pCsrNext; /* Next cursor on same virtual table */ |
7125 | }; |
7126 | |
7127 | typedef struct ZipfileTab ZipfileTab; |
7128 | struct ZipfileTab { |
7129 | sqlite3_vtab base; /* Base class - must be first */ |
7130 | char *zFile; /* Zip file this table accesses (may be NULL) */ |
7131 | sqlite3 *db; /* Host database connection */ |
7132 | u8 *aBuffer; /* Temporary buffer used for various tasks */ |
7133 | |
7134 | ZipfileCsr *pCsrList; /* List of cursors */ |
7135 | i64 iNextCsrid; |
7136 | |
7137 | /* The following are used by write transactions only */ |
7138 | ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */ |
7139 | ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */ |
7140 | FILE *pWriteFd; /* File handle open on zip archive */ |
7141 | i64 szCurrent; /* Current size of zip archive */ |
7142 | i64 szOrig; /* Size of archive at start of transaction */ |
7143 | }; |
7144 | |
7145 | /* |
7146 | ** Set the error message contained in context ctx to the results of |
7147 | ** vprintf(zFmt, ...). |
7148 | */ |
7149 | static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ |
7150 | char *zMsg = 0; |
7151 | va_list ap; |
7152 | va_start(ap, zFmt); |
7153 | zMsg = sqlite3_vmprintf(zFmt, ap); |
7154 | sqlite3_result_error(ctx, zMsg, -1); |
7155 | sqlite3_free(zMsg); |
7156 | va_end(ap); |
7157 | } |
7158 | |
7159 | /* |
7160 | ** If string zIn is quoted, dequote it in place. Otherwise, if the string |
7161 | ** is not quoted, do nothing. |
7162 | */ |
7163 | static void zipfileDequote(char *zIn){ |
7164 | char q = zIn[0]; |
7165 | if( q=='"' || q=='\'' || q=='`' || q=='[' ){ |
7166 | int iIn = 1; |
7167 | int iOut = 0; |
7168 | if( q=='[' ) q = ']'; |
7169 | while( ALWAYS(zIn[iIn]) ){ |
7170 | char c = zIn[iIn++]; |
7171 | if( c==q && zIn[iIn++]!=q ) break; |
7172 | zIn[iOut++] = c; |
7173 | } |
7174 | zIn[iOut] = '\0'; |
7175 | } |
7176 | } |
7177 | |
7178 | /* |
7179 | ** Construct a new ZipfileTab virtual table object. |
7180 | ** |
7181 | ** argv[0] -> module name ("zipfile") |
7182 | ** argv[1] -> database name |
7183 | ** argv[2] -> table name |
7184 | ** argv[...] -> "column name" and other module argument fields. |
7185 | */ |
7186 | static int zipfileConnect( |
7187 | sqlite3 *db, |
7188 | void *pAux, |
7189 | int argc, const char *const*argv, |
7190 | sqlite3_vtab **ppVtab, |
7191 | char **pzErr |
7192 | ){ |
7193 | int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE; |
7194 | int nFile = 0; |
7195 | const char *zFile = 0; |
7196 | ZipfileTab *pNew = 0; |
7197 | int rc; |
7198 | |
7199 | /* If the table name is not "zipfile", require that the argument be |
7200 | ** specified. This stops zipfile tables from being created as: |
7201 | ** |
7202 | ** CREATE VIRTUAL TABLE zzz USING zipfile(); |
7203 | ** |
7204 | ** It does not prevent: |
7205 | ** |
7206 | ** CREATE VIRTUAL TABLE zipfile USING zipfile(); |
7207 | */ |
7208 | assert( 0==sqlite3_stricmp(argv[0], "zipfile" ) ); |
7209 | if( (0!=sqlite3_stricmp(argv[2], "zipfile" ) && argc<4) || argc>4 ){ |
7210 | *pzErr = sqlite3_mprintf("zipfile constructor requires one argument" ); |
7211 | return SQLITE_ERROR; |
7212 | } |
7213 | |
7214 | if( argc>3 ){ |
7215 | zFile = argv[3]; |
7216 | nFile = (int)strlen(zFile)+1; |
7217 | } |
7218 | |
7219 | rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA); |
7220 | if( rc==SQLITE_OK ){ |
7221 | pNew = (ZipfileTab*)sqlite3_malloc64((sqlite3_int64)nByte+nFile); |
7222 | if( pNew==0 ) return SQLITE_NOMEM; |
7223 | memset(pNew, 0, nByte+nFile); |
7224 | pNew->db = db; |
7225 | pNew->aBuffer = (u8*)&pNew[1]; |
7226 | if( zFile ){ |
7227 | pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE]; |
7228 | memcpy(pNew->zFile, zFile, nFile); |
7229 | zipfileDequote(pNew->zFile); |
7230 | } |
7231 | } |
7232 | sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); |
7233 | *ppVtab = (sqlite3_vtab*)pNew; |
7234 | return rc; |
7235 | } |
7236 | |
7237 | /* |
7238 | ** Free the ZipfileEntry structure indicated by the only argument. |
7239 | */ |
7240 | static void zipfileEntryFree(ZipfileEntry *p){ |
7241 | if( p ){ |
7242 | sqlite3_free(p->cds.zFile); |
7243 | sqlite3_free(p); |
7244 | } |
7245 | } |
7246 | |
7247 | /* |
7248 | ** Release resources that should be freed at the end of a write |
7249 | ** transaction. |
7250 | */ |
7251 | static void zipfileCleanupTransaction(ZipfileTab *pTab){ |
7252 | ZipfileEntry *pEntry; |
7253 | ZipfileEntry *pNext; |
7254 | |
7255 | if( pTab->pWriteFd ){ |
7256 | fclose(pTab->pWriteFd); |
7257 | pTab->pWriteFd = 0; |
7258 | } |
7259 | for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){ |
7260 | pNext = pEntry->pNext; |
7261 | zipfileEntryFree(pEntry); |
7262 | } |
7263 | pTab->pFirstEntry = 0; |
7264 | pTab->pLastEntry = 0; |
7265 | pTab->szCurrent = 0; |
7266 | pTab->szOrig = 0; |
7267 | } |
7268 | |
7269 | /* |
7270 | ** This method is the destructor for zipfile vtab objects. |
7271 | */ |
7272 | static int zipfileDisconnect(sqlite3_vtab *pVtab){ |
7273 | zipfileCleanupTransaction((ZipfileTab*)pVtab); |
7274 | sqlite3_free(pVtab); |
7275 | return SQLITE_OK; |
7276 | } |
7277 | |
7278 | /* |
7279 | ** Constructor for a new ZipfileCsr object. |
7280 | */ |
7281 | static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){ |
7282 | ZipfileTab *pTab = (ZipfileTab*)p; |
7283 | ZipfileCsr *pCsr; |
7284 | pCsr = sqlite3_malloc(sizeof(*pCsr)); |
7285 | *ppCsr = (sqlite3_vtab_cursor*)pCsr; |
7286 | if( pCsr==0 ){ |
7287 | return SQLITE_NOMEM; |
7288 | } |
7289 | memset(pCsr, 0, sizeof(*pCsr)); |
7290 | pCsr->iId = ++pTab->iNextCsrid; |
7291 | pCsr->pCsrNext = pTab->pCsrList; |
7292 | pTab->pCsrList = pCsr; |
7293 | return SQLITE_OK; |
7294 | } |
7295 | |
7296 | /* |
7297 | ** Reset a cursor back to the state it was in when first returned |
7298 | ** by zipfileOpen(). |
7299 | */ |
7300 | static void zipfileResetCursor(ZipfileCsr *pCsr){ |
7301 | ZipfileEntry *p; |
7302 | ZipfileEntry *pNext; |
7303 | |
7304 | pCsr->bEof = 0; |
7305 | if( pCsr->pFile ){ |
7306 | fclose(pCsr->pFile); |
7307 | pCsr->pFile = 0; |
7308 | zipfileEntryFree(pCsr->pCurrent); |
7309 | pCsr->pCurrent = 0; |
7310 | } |
7311 | |
7312 | for(p=pCsr->pFreeEntry; p; p=pNext){ |
7313 | pNext = p->pNext; |
7314 | zipfileEntryFree(p); |
7315 | } |
7316 | } |
7317 | |
7318 | /* |
7319 | ** Destructor for an ZipfileCsr. |
7320 | */ |
7321 | static int zipfileClose(sqlite3_vtab_cursor *cur){ |
7322 | ZipfileCsr *pCsr = (ZipfileCsr*)cur; |
7323 | ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab); |
7324 | ZipfileCsr **pp; |
7325 | zipfileResetCursor(pCsr); |
7326 | |
7327 | /* Remove this cursor from the ZipfileTab.pCsrList list. */ |
7328 | for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext)); |
7329 | *pp = pCsr->pCsrNext; |
7330 | |
7331 | sqlite3_free(pCsr); |
7332 | return SQLITE_OK; |
7333 | } |
7334 | |
7335 | /* |
7336 | ** Set the error message for the virtual table associated with cursor |
7337 | ** pCsr to the results of vprintf(zFmt, ...). |
7338 | */ |
7339 | static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){ |
7340 | va_list ap; |
7341 | va_start(ap, zFmt); |
7342 | sqlite3_free(pTab->base.zErrMsg); |
7343 | pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap); |
7344 | va_end(ap); |
7345 | } |
7346 | static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){ |
7347 | va_list ap; |
7348 | va_start(ap, zFmt); |
7349 | sqlite3_free(pCsr->base.pVtab->zErrMsg); |
7350 | pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); |
7351 | va_end(ap); |
7352 | } |
7353 | |
7354 | /* |
7355 | ** Read nRead bytes of data from offset iOff of file pFile into buffer |
7356 | ** aRead[]. Return SQLITE_OK if successful, or an SQLite error code |
7357 | ** otherwise. |
7358 | ** |
7359 | ** If an error does occur, output variable (*pzErrmsg) may be set to point |
7360 | ** to an English language error message. It is the responsibility of the |
7361 | ** caller to eventually free this buffer using |
7362 | ** sqlite3_free(). |
7363 | */ |
7364 | static int zipfileReadData( |
7365 | FILE *pFile, /* Read from this file */ |
7366 | u8 *aRead, /* Read into this buffer */ |
7367 | int nRead, /* Number of bytes to read */ |
7368 | i64 iOff, /* Offset to read from */ |
7369 | char **pzErrmsg /* OUT: Error message (from sqlite3_malloc) */ |
7370 | ){ |
7371 | size_t n; |
7372 | fseek(pFile, (long)iOff, SEEK_SET); |
7373 | n = fread(aRead, 1, nRead, pFile); |
7374 | if( (int)n!=nRead ){ |
7375 | *pzErrmsg = sqlite3_mprintf("error in fread()" ); |
7376 | return SQLITE_ERROR; |
7377 | } |
7378 | return SQLITE_OK; |
7379 | } |
7380 | |
7381 | static int zipfileAppendData( |
7382 | ZipfileTab *pTab, |
7383 | const u8 *aWrite, |
7384 | int nWrite |
7385 | ){ |
7386 | if( nWrite>0 ){ |
7387 | size_t n = nWrite; |
7388 | fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET); |
7389 | n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd); |
7390 | if( (int)n!=nWrite ){ |
7391 | pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()" ); |
7392 | return SQLITE_ERROR; |
7393 | } |
7394 | pTab->szCurrent += nWrite; |
7395 | } |
7396 | return SQLITE_OK; |
7397 | } |
7398 | |
7399 | /* |
7400 | ** Read and return a 16-bit little-endian unsigned integer from buffer aBuf. |
7401 | */ |
7402 | static u16 zipfileGetU16(const u8 *aBuf){ |
7403 | return (aBuf[1] << 8) + aBuf[0]; |
7404 | } |
7405 | |
7406 | /* |
7407 | ** Read and return a 32-bit little-endian unsigned integer from buffer aBuf. |
7408 | */ |
7409 | static u32 zipfileGetU32(const u8 *aBuf){ |
7410 | if( aBuf==0 ) return 0; |
7411 | return ((u32)(aBuf[3]) << 24) |
7412 | + ((u32)(aBuf[2]) << 16) |
7413 | + ((u32)(aBuf[1]) << 8) |
7414 | + ((u32)(aBuf[0]) << 0); |
7415 | } |
7416 | |
7417 | /* |
7418 | ** Write a 16-bit little endiate integer into buffer aBuf. |
7419 | */ |
7420 | static void zipfilePutU16(u8 *aBuf, u16 val){ |
7421 | aBuf[0] = val & 0xFF; |
7422 | aBuf[1] = (val>>8) & 0xFF; |
7423 | } |
7424 | |
7425 | /* |
7426 | ** Write a 32-bit little endiate integer into buffer aBuf. |
7427 | */ |
7428 | static void zipfilePutU32(u8 *aBuf, u32 val){ |
7429 | aBuf[0] = val & 0xFF; |
7430 | aBuf[1] = (val>>8) & 0xFF; |
7431 | aBuf[2] = (val>>16) & 0xFF; |
7432 | aBuf[3] = (val>>24) & 0xFF; |
7433 | } |
7434 | |
7435 | #define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) ) |
7436 | #define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) ) |
7437 | |
7438 | #define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; } |
7439 | #define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; } |
7440 | |
7441 | /* |
7442 | ** Magic numbers used to read CDS records. |
7443 | */ |
7444 | #define ZIPFILE_CDS_NFILE_OFF 28 |
7445 | #define ZIPFILE_CDS_SZCOMPRESSED_OFF 20 |
7446 | |
7447 | /* |
7448 | ** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR |
7449 | ** if the record is not well-formed, or SQLITE_OK otherwise. |
7450 | */ |
7451 | static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){ |
7452 | u8 *aRead = aBuf; |
7453 | u32 sig = zipfileRead32(aRead); |
7454 | int rc = SQLITE_OK; |
7455 | if( sig!=ZIPFILE_SIGNATURE_CDS ){ |
7456 | rc = SQLITE_ERROR; |
7457 | }else{ |
7458 | pCDS->iVersionMadeBy = zipfileRead16(aRead); |
7459 | pCDS->iVersionExtract = zipfileRead16(aRead); |
7460 | pCDS->flags = zipfileRead16(aRead); |
7461 | pCDS->iCompression = zipfileRead16(aRead); |
7462 | pCDS->mTime = zipfileRead16(aRead); |
7463 | pCDS->mDate = zipfileRead16(aRead); |
7464 | pCDS->crc32 = zipfileRead32(aRead); |
7465 | pCDS->szCompressed = zipfileRead32(aRead); |
7466 | pCDS->szUncompressed = zipfileRead32(aRead); |
7467 | assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); |
7468 | pCDS->nFile = zipfileRead16(aRead); |
7469 | pCDS->nExtra = zipfileRead16(aRead); |
7470 | pCDS->nComment = zipfileRead16(aRead); |
7471 | pCDS->iDiskStart = zipfileRead16(aRead); |
7472 | pCDS->iInternalAttr = zipfileRead16(aRead); |
7473 | pCDS->iExternalAttr = zipfileRead32(aRead); |
7474 | pCDS->iOffset = zipfileRead32(aRead); |
7475 | assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] ); |
7476 | } |
7477 | |
7478 | return rc; |
7479 | } |
7480 | |
7481 | /* |
7482 | ** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR |
7483 | ** if the record is not well-formed, or SQLITE_OK otherwise. |
7484 | */ |
7485 | static int zipfileReadLFH( |
7486 | u8 *aBuffer, |
7487 | ZipfileLFH *pLFH |
7488 | ){ |
7489 | u8 *aRead = aBuffer; |
7490 | int rc = SQLITE_OK; |
7491 | |
7492 | u32 sig = zipfileRead32(aRead); |
7493 | if( sig!=ZIPFILE_SIGNATURE_LFH ){ |
7494 | rc = SQLITE_ERROR; |
7495 | }else{ |
7496 | pLFH->iVersionExtract = zipfileRead16(aRead); |
7497 | pLFH->flags = zipfileRead16(aRead); |
7498 | pLFH->iCompression = zipfileRead16(aRead); |
7499 | pLFH->mTime = zipfileRead16(aRead); |
7500 | pLFH->mDate = zipfileRead16(aRead); |
7501 | pLFH->crc32 = zipfileRead32(aRead); |
7502 | pLFH->szCompressed = zipfileRead32(aRead); |
7503 | pLFH->szUncompressed = zipfileRead32(aRead); |
7504 | pLFH->nFile = zipfileRead16(aRead); |
7505 | pLFH->nExtra = zipfileRead16(aRead); |
7506 | } |
7507 | return rc; |
7508 | } |
7509 | |
7510 | |
7511 | /* |
7512 | ** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields. |
7513 | ** Scan through this buffer to find an "extra-timestamp" field. If one |
7514 | ** exists, extract the 32-bit modification-timestamp from it and store |
7515 | ** the value in output parameter *pmTime. |
7516 | ** |
7517 | ** Zero is returned if no extra-timestamp record could be found (and so |
7518 | ** *pmTime is left unchanged), or non-zero otherwise. |
7519 | ** |
7520 | ** The general format of an extra field is: |
7521 | ** |
7522 | ** Header ID 2 bytes |
7523 | ** Data Size 2 bytes |
7524 | ** Data N bytes |
7525 | */ |
7526 | static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){ |
7527 | int ret = 0; |
7528 | u8 *p = aExtra; |
7529 | u8 *pEnd = &aExtra[nExtra]; |
7530 | |
7531 | while( p<pEnd ){ |
7532 | u16 id = zipfileRead16(p); |
7533 | u16 nByte = zipfileRead16(p); |
7534 | |
7535 | switch( id ){ |
7536 | case ZIPFILE_EXTRA_TIMESTAMP: { |
7537 | u8 b = p[0]; |
7538 | if( b & 0x01 ){ /* 0x01 -> modtime is present */ |
7539 | *pmTime = zipfileGetU32(&p[1]); |
7540 | ret = 1; |
7541 | } |
7542 | break; |
7543 | } |
7544 | } |
7545 | |
7546 | p += nByte; |
7547 | } |
7548 | return ret; |
7549 | } |
7550 | |
7551 | /* |
7552 | ** Convert the standard MS-DOS timestamp stored in the mTime and mDate |
7553 | ** fields of the CDS structure passed as the only argument to a 32-bit |
7554 | ** UNIX seconds-since-the-epoch timestamp. Return the result. |
7555 | ** |
7556 | ** "Standard" MS-DOS time format: |
7557 | ** |
7558 | ** File modification time: |
7559 | ** Bits 00-04: seconds divided by 2 |
7560 | ** Bits 05-10: minute |
7561 | ** Bits 11-15: hour |
7562 | ** File modification date: |
7563 | ** Bits 00-04: day |
7564 | ** Bits 05-08: month (1-12) |
7565 | ** Bits 09-15: years from 1980 |
7566 | ** |
7567 | ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx |
7568 | */ |
7569 | static u32 zipfileMtime(ZipfileCDS *pCDS){ |
7570 | int Y,M,D,X1,X2,A,B,sec,min,hr; |
7571 | i64 JDsec; |
7572 | Y = (1980 + ((pCDS->mDate >> 9) & 0x7F)); |
7573 | M = ((pCDS->mDate >> 5) & 0x0F); |
7574 | D = (pCDS->mDate & 0x1F); |
7575 | sec = (pCDS->mTime & 0x1F)*2; |
7576 | min = (pCDS->mTime >> 5) & 0x3F; |
7577 | hr = (pCDS->mTime >> 11) & 0x1F; |
7578 | if( M<=2 ){ |
7579 | Y--; |
7580 | M += 12; |
7581 | } |
7582 | X1 = 36525*(Y+4716)/100; |
7583 | X2 = 306001*(M+1)/10000; |
7584 | A = Y/100; |
7585 | B = 2 - A + (A/4); |
7586 | JDsec = (i64)((X1 + X2 + D + B - 1524.5)*86400) + hr*3600 + min*60 + sec; |
7587 | return (u32)(JDsec - (i64)24405875*(i64)8640); |
7588 | } |
7589 | |
7590 | /* |
7591 | ** The opposite of zipfileMtime(). This function populates the mTime and |
7592 | ** mDate fields of the CDS structure passed as the first argument according |
7593 | ** to the UNIX timestamp value passed as the second. |
7594 | */ |
7595 | static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){ |
7596 | /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */ |
7597 | i64 JD = (i64)2440588 + mUnixTime / (24*60*60); |
7598 | |
7599 | int A, B, C, D, E; |
7600 | int yr, mon, day; |
7601 | int hr, min, sec; |
7602 | |
7603 | A = (int)((JD - 1867216.25)/36524.25); |
7604 | A = (int)(JD + 1 + A - (A/4)); |
7605 | B = A + 1524; |
7606 | C = (int)((B - 122.1)/365.25); |
7607 | D = (36525*(C&32767))/100; |
7608 | E = (int)((B-D)/30.6001); |
7609 | |
7610 | day = B - D - (int)(30.6001*E); |
7611 | mon = (E<14 ? E-1 : E-13); |
7612 | yr = mon>2 ? C-4716 : C-4715; |
7613 | |
7614 | hr = (mUnixTime % (24*60*60)) / (60*60); |
7615 | min = (mUnixTime % (60*60)) / 60; |
7616 | sec = (mUnixTime % 60); |
7617 | |
7618 | if( yr>=1980 ){ |
7619 | pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9)); |
7620 | pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11)); |
7621 | }else{ |
7622 | pCds->mDate = pCds->mTime = 0; |
7623 | } |
7624 | |
7625 | assert( mUnixTime<315507600 |
7626 | || mUnixTime==zipfileMtime(pCds) |
7627 | || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) |
7628 | /* || (mUnixTime % 2) */ |
7629 | ); |
7630 | } |
7631 | |
7632 | /* |
7633 | ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in |
7634 | ** size) containing an entire zip archive image. Or, if aBlob is NULL, |
7635 | ** then pFile is a file-handle open on a zip file. In either case, this |
7636 | ** function creates a ZipfileEntry object based on the zip archive entry |
7637 | ** for which the CDS record is at offset iOff. |
7638 | ** |
7639 | ** If successful, SQLITE_OK is returned and (*ppEntry) set to point to |
7640 | ** the new object. Otherwise, an SQLite error code is returned and the |
7641 | ** final value of (*ppEntry) undefined. |
7642 | */ |
7643 | static int zipfileGetEntry( |
7644 | ZipfileTab *pTab, /* Store any error message here */ |
7645 | const u8 *aBlob, /* Pointer to in-memory file image */ |
7646 | int nBlob, /* Size of aBlob[] in bytes */ |
7647 | FILE *pFile, /* If aBlob==0, read from this file */ |
7648 | i64 iOff, /* Offset of CDS record */ |
7649 | ZipfileEntry **ppEntry /* OUT: Pointer to new object */ |
7650 | ){ |
7651 | u8 *aRead; |
7652 | char **pzErr = &pTab->base.zErrMsg; |
7653 | int rc = SQLITE_OK; |
7654 | |
7655 | if( aBlob==0 ){ |
7656 | aRead = pTab->aBuffer; |
7657 | rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); |
7658 | }else{ |
7659 | aRead = (u8*)&aBlob[iOff]; |
7660 | } |
7661 | |
7662 | if( rc==SQLITE_OK ){ |
7663 | sqlite3_int64 nAlloc; |
7664 | ZipfileEntry *pNew; |
7665 | |
7666 | int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]); |
7667 | int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]); |
7668 | nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]); |
7669 | |
7670 | nAlloc = sizeof(ZipfileEntry) + nExtra; |
7671 | if( aBlob ){ |
7672 | nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]); |
7673 | } |
7674 | |
7675 | pNew = (ZipfileEntry*)sqlite3_malloc64(nAlloc); |
7676 | if( pNew==0 ){ |
7677 | rc = SQLITE_NOMEM; |
7678 | }else{ |
7679 | memset(pNew, 0, sizeof(ZipfileEntry)); |
7680 | rc = zipfileReadCDS(aRead, &pNew->cds); |
7681 | if( rc!=SQLITE_OK ){ |
7682 | *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld" , iOff); |
7683 | }else if( aBlob==0 ){ |
7684 | rc = zipfileReadData( |
7685 | pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr |
7686 | ); |
7687 | }else{ |
7688 | aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; |
7689 | } |
7690 | } |
7691 | |
7692 | if( rc==SQLITE_OK ){ |
7693 | u32 *pt = &pNew->mUnixTime; |
7694 | pNew->cds.zFile = sqlite3_mprintf("%.*s" , nFile, aRead); |
7695 | pNew->aExtra = (u8*)&pNew[1]; |
7696 | memcpy(pNew->aExtra, &aRead[nFile], nExtra); |
7697 | if( pNew->cds.zFile==0 ){ |
7698 | rc = SQLITE_NOMEM; |
7699 | }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){ |
7700 | pNew->mUnixTime = zipfileMtime(&pNew->cds); |
7701 | } |
7702 | } |
7703 | |
7704 | if( rc==SQLITE_OK ){ |
7705 | static const int szFix = ZIPFILE_LFH_FIXED_SZ; |
7706 | ZipfileLFH lfh; |
7707 | if( pFile ){ |
7708 | rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); |
7709 | }else{ |
7710 | aRead = (u8*)&aBlob[pNew->cds.iOffset]; |
7711 | } |
7712 | |
7713 | if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh); |
7714 | if( rc==SQLITE_OK ){ |
7715 | pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; |
7716 | pNew->iDataOff += lfh.nFile + lfh.nExtra; |
7717 | if( aBlob && pNew->cds.szCompressed ){ |
7718 | pNew->aData = &pNew->aExtra[nExtra]; |
7719 | memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); |
7720 | } |
7721 | }else{ |
7722 | *pzErr = sqlite3_mprintf("failed to read LFH at offset %d" , |
7723 | (int)pNew->cds.iOffset |
7724 | ); |
7725 | } |
7726 | } |
7727 | |
7728 | if( rc!=SQLITE_OK ){ |
7729 | zipfileEntryFree(pNew); |
7730 | }else{ |
7731 | *ppEntry = pNew; |
7732 | } |
7733 | } |
7734 | |
7735 | return rc; |
7736 | } |
7737 | |
7738 | /* |
7739 | ** Advance an ZipfileCsr to its next row of output. |
7740 | */ |
7741 | static int zipfileNext(sqlite3_vtab_cursor *cur){ |
7742 | ZipfileCsr *pCsr = (ZipfileCsr*)cur; |
7743 | int rc = SQLITE_OK; |
7744 | |
7745 | if( pCsr->pFile ){ |
7746 | i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize; |
7747 | zipfileEntryFree(pCsr->pCurrent); |
7748 | pCsr->pCurrent = 0; |
7749 | if( pCsr->iNextOff>=iEof ){ |
7750 | pCsr->bEof = 1; |
7751 | }else{ |
7752 | ZipfileEntry *p = 0; |
7753 | ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab); |
7754 | rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p); |
7755 | if( rc==SQLITE_OK ){ |
7756 | pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ; |
7757 | pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment; |
7758 | } |
7759 | pCsr->pCurrent = p; |
7760 | } |
7761 | }else{ |
7762 | if( !pCsr->bNoop ){ |
7763 | pCsr->pCurrent = pCsr->pCurrent->pNext; |
7764 | } |
7765 | if( pCsr->pCurrent==0 ){ |
7766 | pCsr->bEof = 1; |
7767 | } |
7768 | } |
7769 | |
7770 | pCsr->bNoop = 0; |
7771 | return rc; |
7772 | } |
7773 | |
7774 | static void zipfileFree(void *p) { |
7775 | sqlite3_free(p); |
7776 | } |
7777 | |
7778 | /* |
7779 | ** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the |
7780 | ** size is nOut bytes. This function uncompresses the data and sets the |
7781 | ** return value in context pCtx to the result (a blob). |
7782 | ** |
7783 | ** If an error occurs, an error code is left in pCtx instead. |
7784 | */ |
7785 | static void zipfileInflate( |
7786 | sqlite3_context *pCtx, /* Store result here */ |
7787 | const u8 *aIn, /* Compressed data */ |
7788 | int nIn, /* Size of buffer aIn[] in bytes */ |
7789 | int nOut /* Expected output size */ |
7790 | ){ |
7791 | u8 *aRes = sqlite3_malloc(nOut); |
7792 | if( aRes==0 ){ |
7793 | sqlite3_result_error_nomem(pCtx); |
7794 | }else{ |
7795 | int err; |
7796 | z_stream str; |
7797 | memset(&str, 0, sizeof(str)); |
7798 | |
7799 | str.next_in = (Byte*)aIn; |
7800 | str.avail_in = nIn; |
7801 | str.next_out = (Byte*)aRes; |
7802 | str.avail_out = nOut; |
7803 | |
7804 | err = inflateInit2(&str, -15); |
7805 | if( err!=Z_OK ){ |
7806 | zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)" , err); |
7807 | }else{ |
7808 | err = inflate(&str, Z_NO_FLUSH); |
7809 | if( err!=Z_STREAM_END ){ |
7810 | zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)" , err); |
7811 | }else{ |
7812 | sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree); |
7813 | aRes = 0; |
7814 | } |
7815 | } |
7816 | sqlite3_free(aRes); |
7817 | inflateEnd(&str); |
7818 | } |
7819 | } |
7820 | |
7821 | /* |
7822 | ** Buffer aIn (size nIn bytes) contains uncompressed data. This function |
7823 | ** compresses it and sets (*ppOut) to point to a buffer containing the |
7824 | ** compressed data. The caller is responsible for eventually calling |
7825 | ** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) |
7826 | ** is set to the size of buffer (*ppOut) in bytes. |
7827 | ** |
7828 | ** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error |
7829 | ** code is returned and an error message left in virtual-table handle |
7830 | ** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this |
7831 | ** case. |
7832 | */ |
7833 | static int zipfileDeflate( |
7834 | const u8 *aIn, int nIn, /* Input */ |
7835 | u8 **ppOut, int *pnOut, /* Output */ |
7836 | char **pzErr /* OUT: Error message */ |
7837 | ){ |
7838 | int rc = SQLITE_OK; |
7839 | sqlite3_int64 nAlloc; |
7840 | z_stream str; |
7841 | u8 *aOut; |
7842 | |
7843 | memset(&str, 0, sizeof(str)); |
7844 | str.next_in = (Bytef*)aIn; |
7845 | str.avail_in = nIn; |
7846 | deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); |
7847 | |
7848 | nAlloc = deflateBound(&str, nIn); |
7849 | aOut = (u8*)sqlite3_malloc64(nAlloc); |
7850 | if( aOut==0 ){ |
7851 | rc = SQLITE_NOMEM; |
7852 | }else{ |
7853 | int res; |
7854 | str.next_out = aOut; |
7855 | str.avail_out = nAlloc; |
7856 | res = deflate(&str, Z_FINISH); |
7857 | if( res==Z_STREAM_END ){ |
7858 | *ppOut = aOut; |
7859 | *pnOut = (int)str.total_out; |
7860 | }else{ |
7861 | sqlite3_free(aOut); |
7862 | *pzErr = sqlite3_mprintf("zipfile: deflate() error" ); |
7863 | rc = SQLITE_ERROR; |
7864 | } |
7865 | deflateEnd(&str); |
7866 | } |
7867 | |
7868 | return rc; |
7869 | } |
7870 | |
7871 | |
7872 | /* |
7873 | ** Return values of columns for the row at which the series_cursor |
7874 | ** is currently pointing. |
7875 | */ |
7876 | static int zipfileColumn( |
7877 | sqlite3_vtab_cursor *cur, /* The cursor */ |
7878 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
7879 | int i /* Which column to return */ |
7880 | ){ |
7881 | ZipfileCsr *pCsr = (ZipfileCsr*)cur; |
7882 | ZipfileCDS *pCDS = &pCsr->pCurrent->cds; |
7883 | int rc = SQLITE_OK; |
7884 | switch( i ){ |
7885 | case 0: /* name */ |
7886 | sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT); |
7887 | break; |
7888 | case 1: /* mode */ |
7889 | /* TODO: Whether or not the following is correct surely depends on |
7890 | ** the platform on which the archive was created. */ |
7891 | sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16); |
7892 | break; |
7893 | case 2: { /* mtime */ |
7894 | sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime); |
7895 | break; |
7896 | } |
7897 | case 3: { /* sz */ |
7898 | if( sqlite3_vtab_nochange(ctx)==0 ){ |
7899 | sqlite3_result_int64(ctx, pCDS->szUncompressed); |
7900 | } |
7901 | break; |
7902 | } |
7903 | case 4: /* rawdata */ |
7904 | if( sqlite3_vtab_nochange(ctx) ) break; |
7905 | case 5: { /* data */ |
7906 | if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){ |
7907 | int sz = pCDS->szCompressed; |
7908 | int szFinal = pCDS->szUncompressed; |
7909 | if( szFinal>0 ){ |
7910 | u8 *aBuf; |
7911 | u8 *aFree = 0; |
7912 | if( pCsr->pCurrent->aData ){ |
7913 | aBuf = pCsr->pCurrent->aData; |
7914 | }else{ |
7915 | aBuf = aFree = sqlite3_malloc64(sz); |
7916 | if( aBuf==0 ){ |
7917 | rc = SQLITE_NOMEM; |
7918 | }else{ |
7919 | FILE *pFile = pCsr->pFile; |
7920 | if( pFile==0 ){ |
7921 | pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd; |
7922 | } |
7923 | rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff, |
7924 | &pCsr->base.pVtab->zErrMsg |
7925 | ); |
7926 | } |
7927 | } |
7928 | if( rc==SQLITE_OK ){ |
7929 | if( i==5 && pCDS->iCompression ){ |
7930 | zipfileInflate(ctx, aBuf, sz, szFinal); |
7931 | }else{ |
7932 | sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT); |
7933 | } |
7934 | } |
7935 | sqlite3_free(aFree); |
7936 | }else{ |
7937 | /* Figure out if this is a directory or a zero-sized file. Consider |
7938 | ** it to be a directory either if the mode suggests so, or if |
7939 | ** the final character in the name is '/'. */ |
7940 | u32 mode = pCDS->iExternalAttr >> 16; |
7941 | if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){ |
7942 | sqlite3_result_blob(ctx, "" , 0, SQLITE_STATIC); |
7943 | } |
7944 | } |
7945 | } |
7946 | break; |
7947 | } |
7948 | case 6: /* method */ |
7949 | sqlite3_result_int(ctx, pCDS->iCompression); |
7950 | break; |
7951 | default: /* z */ |
7952 | assert( i==7 ); |
7953 | sqlite3_result_int64(ctx, pCsr->iId); |
7954 | break; |
7955 | } |
7956 | |
7957 | return rc; |
7958 | } |
7959 | |
7960 | /* |
7961 | ** Return TRUE if the cursor is at EOF. |
7962 | */ |
7963 | static int zipfileEof(sqlite3_vtab_cursor *cur){ |
7964 | ZipfileCsr *pCsr = (ZipfileCsr*)cur; |
7965 | return pCsr->bEof; |
7966 | } |
7967 | |
7968 | /* |
7969 | ** If aBlob is not NULL, then it points to a buffer nBlob bytes in size |
7970 | ** containing an entire zip archive image. Or, if aBlob is NULL, then pFile |
7971 | ** is guaranteed to be a file-handle open on a zip file. |
7972 | ** |
7973 | ** This function attempts to locate the EOCD record within the zip archive |
7974 | ** and populate *pEOCD with the results of decoding it. SQLITE_OK is |
7975 | ** returned if successful. Otherwise, an SQLite error code is returned and |
7976 | ** an English language error message may be left in virtual-table pTab. |
7977 | */ |
7978 | static int zipfileReadEOCD( |
7979 | ZipfileTab *pTab, /* Return errors here */ |
7980 | const u8 *aBlob, /* Pointer to in-memory file image */ |
7981 | int nBlob, /* Size of aBlob[] in bytes */ |
7982 | FILE *pFile, /* Read from this file if aBlob==0 */ |
7983 | ZipfileEOCD *pEOCD /* Object to populate */ |
7984 | ){ |
7985 | u8 *aRead = pTab->aBuffer; /* Temporary buffer */ |
7986 | int nRead; /* Bytes to read from file */ |
7987 | int rc = SQLITE_OK; |
7988 | |
7989 | memset(pEOCD, 0, sizeof(ZipfileEOCD)); |
7990 | if( aBlob==0 ){ |
7991 | i64 iOff; /* Offset to read from */ |
7992 | i64 szFile; /* Total size of file in bytes */ |
7993 | fseek(pFile, 0, SEEK_END); |
7994 | szFile = (i64)ftell(pFile); |
7995 | if( szFile==0 ){ |
7996 | return SQLITE_OK; |
7997 | } |
7998 | nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE)); |
7999 | iOff = szFile - nRead; |
8000 | rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg); |
8001 | }else{ |
8002 | nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE)); |
8003 | aRead = (u8*)&aBlob[nBlob-nRead]; |
8004 | } |
8005 | |
8006 | if( rc==SQLITE_OK ){ |
8007 | int i; |
8008 | |
8009 | /* Scan backwards looking for the signature bytes */ |
8010 | for(i=nRead-20; i>=0; i--){ |
8011 | if( aRead[i]==0x50 && aRead[i+1]==0x4b |
8012 | && aRead[i+2]==0x05 && aRead[i+3]==0x06 |
8013 | ){ |
8014 | break; |
8015 | } |
8016 | } |
8017 | if( i<0 ){ |
8018 | pTab->base.zErrMsg = sqlite3_mprintf( |
8019 | "cannot find end of central directory record" |
8020 | ); |
8021 | return SQLITE_ERROR; |
8022 | } |
8023 | |
8024 | aRead += i+4; |
8025 | pEOCD->iDisk = zipfileRead16(aRead); |
8026 | pEOCD->iFirstDisk = zipfileRead16(aRead); |
8027 | pEOCD->nEntry = zipfileRead16(aRead); |
8028 | pEOCD->nEntryTotal = zipfileRead16(aRead); |
8029 | pEOCD->nSize = zipfileRead32(aRead); |
8030 | pEOCD->iOffset = zipfileRead32(aRead); |
8031 | } |
8032 | |
8033 | return rc; |
8034 | } |
8035 | |
8036 | /* |
8037 | ** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry |
8038 | ** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added |
8039 | ** to the end of the list. Otherwise, it is added to the list immediately |
8040 | ** before pBefore (which is guaranteed to be a part of said list). |
8041 | */ |
8042 | static void zipfileAddEntry( |
8043 | ZipfileTab *pTab, |
8044 | ZipfileEntry *pBefore, |
8045 | ZipfileEntry *pNew |
8046 | ){ |
8047 | assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) ); |
8048 | assert( pNew->pNext==0 ); |
8049 | if( pBefore==0 ){ |
8050 | if( pTab->pFirstEntry==0 ){ |
8051 | pTab->pFirstEntry = pTab->pLastEntry = pNew; |
8052 | }else{ |
8053 | assert( pTab->pLastEntry->pNext==0 ); |
8054 | pTab->pLastEntry->pNext = pNew; |
8055 | pTab->pLastEntry = pNew; |
8056 | } |
8057 | }else{ |
8058 | ZipfileEntry **pp; |
8059 | for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext)); |
8060 | pNew->pNext = pBefore; |
8061 | *pp = pNew; |
8062 | } |
8063 | } |
8064 | |
8065 | static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){ |
8066 | ZipfileEOCD eocd; |
8067 | int rc; |
8068 | int i; |
8069 | i64 iOff; |
8070 | |
8071 | rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd); |
8072 | iOff = eocd.iOffset; |
8073 | for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){ |
8074 | ZipfileEntry *pNew = 0; |
8075 | rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew); |
8076 | |
8077 | if( rc==SQLITE_OK ){ |
8078 | zipfileAddEntry(pTab, 0, pNew); |
8079 | iOff += ZIPFILE_CDS_FIXED_SZ; |
8080 | iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment; |
8081 | } |
8082 | } |
8083 | return rc; |
8084 | } |
8085 | |
8086 | /* |
8087 | ** xFilter callback. |
8088 | */ |
8089 | static int zipfileFilter( |
8090 | sqlite3_vtab_cursor *cur, |
8091 | int idxNum, const char *idxStr, |
8092 | int argc, sqlite3_value **argv |
8093 | ){ |
8094 | ZipfileTab *pTab = (ZipfileTab*)cur->pVtab; |
8095 | ZipfileCsr *pCsr = (ZipfileCsr*)cur; |
8096 | const char *zFile = 0; /* Zip file to scan */ |
8097 | int rc = SQLITE_OK; /* Return Code */ |
8098 | int bInMemory = 0; /* True for an in-memory zipfile */ |
8099 | |
8100 | zipfileResetCursor(pCsr); |
8101 | |
8102 | if( pTab->zFile ){ |
8103 | zFile = pTab->zFile; |
8104 | }else if( idxNum==0 ){ |
8105 | zipfileCursorErr(pCsr, "zipfile() function requires an argument" ); |
8106 | return SQLITE_ERROR; |
8107 | }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ |
8108 | static const u8 aEmptyBlob = 0; |
8109 | const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]); |
8110 | int nBlob = sqlite3_value_bytes(argv[0]); |
8111 | assert( pTab->pFirstEntry==0 ); |
8112 | if( aBlob==0 ){ |
8113 | aBlob = &aEmptyBlob; |
8114 | nBlob = 0; |
8115 | } |
8116 | rc = zipfileLoadDirectory(pTab, aBlob, nBlob); |
8117 | pCsr->pFreeEntry = pTab->pFirstEntry; |
8118 | pTab->pFirstEntry = pTab->pLastEntry = 0; |
8119 | if( rc!=SQLITE_OK ) return rc; |
8120 | bInMemory = 1; |
8121 | }else{ |
8122 | zFile = (const char*)sqlite3_value_text(argv[0]); |
8123 | } |
8124 | |
8125 | if( 0==pTab->pWriteFd && 0==bInMemory ){ |
8126 | pCsr->pFile = fopen(zFile, "rb" ); |
8127 | if( pCsr->pFile==0 ){ |
8128 | zipfileCursorErr(pCsr, "cannot open file: %s" , zFile); |
8129 | rc = SQLITE_ERROR; |
8130 | }else{ |
8131 | rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd); |
8132 | if( rc==SQLITE_OK ){ |
8133 | if( pCsr->eocd.nEntry==0 ){ |
8134 | pCsr->bEof = 1; |
8135 | }else{ |
8136 | pCsr->iNextOff = pCsr->eocd.iOffset; |
8137 | rc = zipfileNext(cur); |
8138 | } |
8139 | } |
8140 | } |
8141 | }else{ |
8142 | pCsr->bNoop = 1; |
8143 | pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry; |
8144 | rc = zipfileNext(cur); |
8145 | } |
8146 | |
8147 | return rc; |
8148 | } |
8149 | |
8150 | /* |
8151 | ** xBestIndex callback. |
8152 | */ |
8153 | static int zipfileBestIndex( |
8154 | sqlite3_vtab *tab, |
8155 | sqlite3_index_info *pIdxInfo |
8156 | ){ |
8157 | int i; |
8158 | int idx = -1; |
8159 | int unusable = 0; |
8160 | |
8161 | for(i=0; i<pIdxInfo->nConstraint; i++){ |
8162 | const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; |
8163 | if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue; |
8164 | if( pCons->usable==0 ){ |
8165 | unusable = 1; |
8166 | }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
8167 | idx = i; |
8168 | } |
8169 | } |
8170 | pIdxInfo->estimatedCost = 1000.0; |
8171 | if( idx>=0 ){ |
8172 | pIdxInfo->aConstraintUsage[idx].argvIndex = 1; |
8173 | pIdxInfo->aConstraintUsage[idx].omit = 1; |
8174 | pIdxInfo->idxNum = 1; |
8175 | }else if( unusable ){ |
8176 | return SQLITE_CONSTRAINT; |
8177 | } |
8178 | return SQLITE_OK; |
8179 | } |
8180 | |
8181 | static ZipfileEntry *zipfileNewEntry(const char *zPath){ |
8182 | ZipfileEntry *pNew; |
8183 | pNew = sqlite3_malloc(sizeof(ZipfileEntry)); |
8184 | if( pNew ){ |
8185 | memset(pNew, 0, sizeof(ZipfileEntry)); |
8186 | pNew->cds.zFile = sqlite3_mprintf("%s" , zPath); |
8187 | if( pNew->cds.zFile==0 ){ |
8188 | sqlite3_free(pNew); |
8189 | pNew = 0; |
8190 | } |
8191 | } |
8192 | return pNew; |
8193 | } |
8194 | |
8195 | static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){ |
8196 | ZipfileCDS *pCds = &pEntry->cds; |
8197 | u8 *a = aBuf; |
8198 | |
8199 | pCds->nExtra = 9; |
8200 | |
8201 | /* Write the LFH itself */ |
8202 | zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH); |
8203 | zipfileWrite16(a, pCds->iVersionExtract); |
8204 | zipfileWrite16(a, pCds->flags); |
8205 | zipfileWrite16(a, pCds->iCompression); |
8206 | zipfileWrite16(a, pCds->mTime); |
8207 | zipfileWrite16(a, pCds->mDate); |
8208 | zipfileWrite32(a, pCds->crc32); |
8209 | zipfileWrite32(a, pCds->szCompressed); |
8210 | zipfileWrite32(a, pCds->szUncompressed); |
8211 | zipfileWrite16(a, (u16)pCds->nFile); |
8212 | zipfileWrite16(a, pCds->nExtra); |
8213 | assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] ); |
8214 | |
8215 | /* Add the file name */ |
8216 | memcpy(a, pCds->zFile, (int)pCds->nFile); |
8217 | a += (int)pCds->nFile; |
8218 | |
8219 | /* The "extra" data */ |
8220 | zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); |
8221 | zipfileWrite16(a, 5); |
8222 | *a++ = 0x01; |
8223 | zipfileWrite32(a, pEntry->mUnixTime); |
8224 | |
8225 | return a-aBuf; |
8226 | } |
8227 | |
8228 | static int zipfileAppendEntry( |
8229 | ZipfileTab *pTab, |
8230 | ZipfileEntry *pEntry, |
8231 | const u8 *pData, |
8232 | int nData |
8233 | ){ |
8234 | u8 *aBuf = pTab->aBuffer; |
8235 | int nBuf; |
8236 | int rc; |
8237 | |
8238 | nBuf = zipfileSerializeLFH(pEntry, aBuf); |
8239 | rc = zipfileAppendData(pTab, aBuf, nBuf); |
8240 | if( rc==SQLITE_OK ){ |
8241 | pEntry->iDataOff = pTab->szCurrent; |
8242 | rc = zipfileAppendData(pTab, pData, nData); |
8243 | } |
8244 | |
8245 | return rc; |
8246 | } |
8247 | |
8248 | static int zipfileGetMode( |
8249 | sqlite3_value *pVal, |
8250 | int bIsDir, /* If true, default to directory */ |
8251 | u32 *pMode, /* OUT: Mode value */ |
8252 | char **pzErr /* OUT: Error message */ |
8253 | ){ |
8254 | const char *z = (const char*)sqlite3_value_text(pVal); |
8255 | u32 mode = 0; |
8256 | if( z==0 ){ |
8257 | mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644)); |
8258 | }else if( z[0]>='0' && z[0]<='9' ){ |
8259 | mode = (unsigned int)sqlite3_value_int(pVal); |
8260 | }else{ |
8261 | const char zTemplate[11] = "-rwxrwxrwx" ; |
8262 | int i; |
8263 | if( strlen(z)!=10 ) goto parse_error; |
8264 | switch( z[0] ){ |
8265 | case '-': mode |= S_IFREG; break; |
8266 | case 'd': mode |= S_IFDIR; break; |
8267 | case 'l': mode |= S_IFLNK; break; |
8268 | default: goto parse_error; |
8269 | } |
8270 | for(i=1; i<10; i++){ |
8271 | if( z[i]==zTemplate[i] ) mode |= 1 << (9-i); |
8272 | else if( z[i]!='-' ) goto parse_error; |
8273 | } |
8274 | } |
8275 | if( ((mode & S_IFDIR)==0)==bIsDir ){ |
8276 | /* The "mode" attribute is a directory, but data has been specified. |
8277 | ** Or vice-versa - no data but "mode" is a file or symlink. */ |
8278 | *pzErr = sqlite3_mprintf("zipfile: mode does not match data" ); |
8279 | return SQLITE_CONSTRAINT; |
8280 | } |
8281 | *pMode = mode; |
8282 | return SQLITE_OK; |
8283 | |
8284 | parse_error: |
8285 | *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s" , z); |
8286 | return SQLITE_ERROR; |
8287 | } |
8288 | |
8289 | /* |
8290 | ** Both (const char*) arguments point to nul-terminated strings. Argument |
8291 | ** nB is the value of strlen(zB). This function returns 0 if the strings are |
8292 | ** identical, ignoring any trailing '/' character in either path. */ |
8293 | static int zipfileComparePath(const char *zA, const char *zB, int nB){ |
8294 | int nA = (int)strlen(zA); |
8295 | if( nA>0 && zA[nA-1]=='/' ) nA--; |
8296 | if( nB>0 && zB[nB-1]=='/' ) nB--; |
8297 | if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0; |
8298 | return 1; |
8299 | } |
8300 | |
8301 | static int zipfileBegin(sqlite3_vtab *pVtab){ |
8302 | ZipfileTab *pTab = (ZipfileTab*)pVtab; |
8303 | int rc = SQLITE_OK; |
8304 | |
8305 | assert( pTab->pWriteFd==0 ); |
8306 | if( pTab->zFile==0 || pTab->zFile[0]==0 ){ |
8307 | pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename" ); |
8308 | return SQLITE_ERROR; |
8309 | } |
8310 | |
8311 | /* Open a write fd on the file. Also load the entire central directory |
8312 | ** structure into memory. During the transaction any new file data is |
8313 | ** appended to the archive file, but the central directory is accumulated |
8314 | ** in main-memory until the transaction is committed. */ |
8315 | pTab->pWriteFd = fopen(pTab->zFile, "ab+" ); |
8316 | if( pTab->pWriteFd==0 ){ |
8317 | pTab->base.zErrMsg = sqlite3_mprintf( |
8318 | "zipfile: failed to open file %s for writing" , pTab->zFile |
8319 | ); |
8320 | rc = SQLITE_ERROR; |
8321 | }else{ |
8322 | fseek(pTab->pWriteFd, 0, SEEK_END); |
8323 | pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd); |
8324 | rc = zipfileLoadDirectory(pTab, 0, 0); |
8325 | } |
8326 | |
8327 | if( rc!=SQLITE_OK ){ |
8328 | zipfileCleanupTransaction(pTab); |
8329 | } |
8330 | |
8331 | return rc; |
8332 | } |
8333 | |
8334 | /* |
8335 | ** Return the current time as a 32-bit timestamp in UNIX epoch format (like |
8336 | ** time(2)). |
8337 | */ |
8338 | static u32 zipfileTime(void){ |
8339 | sqlite3_vfs *pVfs = sqlite3_vfs_find(0); |
8340 | u32 ret; |
8341 | if( pVfs==0 ) return 0; |
8342 | if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ |
8343 | i64 ms; |
8344 | pVfs->xCurrentTimeInt64(pVfs, &ms); |
8345 | ret = (u32)((ms/1000) - ((i64)24405875 * 8640)); |
8346 | }else{ |
8347 | double day; |
8348 | pVfs->xCurrentTime(pVfs, &day); |
8349 | ret = (u32)((day - 2440587.5) * 86400); |
8350 | } |
8351 | return ret; |
8352 | } |
8353 | |
8354 | /* |
8355 | ** Return a 32-bit timestamp in UNIX epoch format. |
8356 | ** |
8357 | ** If the value passed as the only argument is either NULL or an SQL NULL, |
8358 | ** return the current time. Otherwise, return the value stored in (*pVal) |
8359 | ** cast to a 32-bit unsigned integer. |
8360 | */ |
8361 | static u32 zipfileGetTime(sqlite3_value *pVal){ |
8362 | if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ |
8363 | return zipfileTime(); |
8364 | } |
8365 | return (u32)sqlite3_value_int64(pVal); |
8366 | } |
8367 | |
8368 | /* |
8369 | ** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry |
8370 | ** linked list. Remove it from the list and free the object. |
8371 | */ |
8372 | static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){ |
8373 | if( pOld ){ |
8374 | ZipfileEntry **pp; |
8375 | for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext)); |
8376 | *pp = (*pp)->pNext; |
8377 | zipfileEntryFree(pOld); |
8378 | } |
8379 | } |
8380 | |
8381 | /* |
8382 | ** xUpdate method. |
8383 | */ |
8384 | static int zipfileUpdate( |
8385 | sqlite3_vtab *pVtab, |
8386 | int nVal, |
8387 | sqlite3_value **apVal, |
8388 | sqlite_int64 *pRowid |
8389 | ){ |
8390 | ZipfileTab *pTab = (ZipfileTab*)pVtab; |
8391 | int rc = SQLITE_OK; /* Return Code */ |
8392 | ZipfileEntry *pNew = 0; /* New in-memory CDS entry */ |
8393 | |
8394 | u32 mode = 0; /* Mode for new entry */ |
8395 | u32 mTime = 0; /* Modification time for new entry */ |
8396 | i64 sz = 0; /* Uncompressed size */ |
8397 | const char *zPath = 0; /* Path for new entry */ |
8398 | int nPath = 0; /* strlen(zPath) */ |
8399 | const u8 *pData = 0; /* Pointer to buffer containing content */ |
8400 | int nData = 0; /* Size of pData buffer in bytes */ |
8401 | int iMethod = 0; /* Compression method for new entry */ |
8402 | u8 *pFree = 0; /* Free this */ |
8403 | char *zFree = 0; /* Also free this */ |
8404 | ZipfileEntry *pOld = 0; |
8405 | ZipfileEntry *pOld2 = 0; |
8406 | int bUpdate = 0; /* True for an update that modifies "name" */ |
8407 | int bIsDir = 0; |
8408 | u32 iCrc32 = 0; |
8409 | |
8410 | if( pTab->pWriteFd==0 ){ |
8411 | rc = zipfileBegin(pVtab); |
8412 | if( rc!=SQLITE_OK ) return rc; |
8413 | } |
8414 | |
8415 | /* If this is a DELETE or UPDATE, find the archive entry to delete. */ |
8416 | if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ |
8417 | const char *zDelete = (const char*)sqlite3_value_text(apVal[0]); |
8418 | int nDelete = (int)strlen(zDelete); |
8419 | if( nVal>1 ){ |
8420 | const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]); |
8421 | if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){ |
8422 | bUpdate = 1; |
8423 | } |
8424 | } |
8425 | for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){ |
8426 | if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){ |
8427 | break; |
8428 | } |
8429 | assert( pOld->pNext ); |
8430 | } |
8431 | } |
8432 | |
8433 | if( nVal>1 ){ |
8434 | /* Check that "sz" and "rawdata" are both NULL: */ |
8435 | if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){ |
8436 | zipfileTableErr(pTab, "sz must be NULL" ); |
8437 | rc = SQLITE_CONSTRAINT; |
8438 | } |
8439 | if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){ |
8440 | zipfileTableErr(pTab, "rawdata must be NULL" ); |
8441 | rc = SQLITE_CONSTRAINT; |
8442 | } |
8443 | |
8444 | if( rc==SQLITE_OK ){ |
8445 | if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){ |
8446 | /* data=NULL. A directory */ |
8447 | bIsDir = 1; |
8448 | }else{ |
8449 | /* Value specified for "data", and possibly "method". This must be |
8450 | ** a regular file or a symlink. */ |
8451 | const u8 *aIn = sqlite3_value_blob(apVal[7]); |
8452 | int nIn = sqlite3_value_bytes(apVal[7]); |
8453 | int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL; |
8454 | |
8455 | iMethod = sqlite3_value_int(apVal[8]); |
8456 | sz = nIn; |
8457 | pData = aIn; |
8458 | nData = nIn; |
8459 | if( iMethod!=0 && iMethod!=8 ){ |
8460 | zipfileTableErr(pTab, "unknown compression method: %d" , iMethod); |
8461 | rc = SQLITE_CONSTRAINT; |
8462 | }else{ |
8463 | if( bAuto || iMethod ){ |
8464 | int nCmp; |
8465 | rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg); |
8466 | if( rc==SQLITE_OK ){ |
8467 | if( iMethod || nCmp<nIn ){ |
8468 | iMethod = 8; |
8469 | pData = pFree; |
8470 | nData = nCmp; |
8471 | } |
8472 | } |
8473 | } |
8474 | iCrc32 = crc32(0, aIn, nIn); |
8475 | } |
8476 | } |
8477 | } |
8478 | |
8479 | if( rc==SQLITE_OK ){ |
8480 | rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg); |
8481 | } |
8482 | |
8483 | if( rc==SQLITE_OK ){ |
8484 | zPath = (const char*)sqlite3_value_text(apVal[2]); |
8485 | if( zPath==0 ) zPath = "" ; |
8486 | nPath = (int)strlen(zPath); |
8487 | mTime = zipfileGetTime(apVal[4]); |
8488 | } |
8489 | |
8490 | if( rc==SQLITE_OK && bIsDir ){ |
8491 | /* For a directory, check that the last character in the path is a |
8492 | ** '/'. This appears to be required for compatibility with info-zip |
8493 | ** (the unzip command on unix). It does not create directories |
8494 | ** otherwise. */ |
8495 | if( nPath<=0 || zPath[nPath-1]!='/' ){ |
8496 | zFree = sqlite3_mprintf("%s/" , zPath); |
8497 | zPath = (const char*)zFree; |
8498 | if( zFree==0 ){ |
8499 | rc = SQLITE_NOMEM; |
8500 | nPath = 0; |
8501 | }else{ |
8502 | nPath = (int)strlen(zPath); |
8503 | } |
8504 | } |
8505 | } |
8506 | |
8507 | /* Check that we're not inserting a duplicate entry -OR- updating an |
8508 | ** entry with a path, thereby making it into a duplicate. */ |
8509 | if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){ |
8510 | ZipfileEntry *p; |
8511 | for(p=pTab->pFirstEntry; p; p=p->pNext){ |
8512 | if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){ |
8513 | switch( sqlite3_vtab_on_conflict(pTab->db) ){ |
8514 | case SQLITE_IGNORE: { |
8515 | goto zipfile_update_done; |
8516 | } |
8517 | case SQLITE_REPLACE: { |
8518 | pOld2 = p; |
8519 | break; |
8520 | } |
8521 | default: { |
8522 | zipfileTableErr(pTab, "duplicate name: \"%s\"" , zPath); |
8523 | rc = SQLITE_CONSTRAINT; |
8524 | break; |
8525 | } |
8526 | } |
8527 | break; |
8528 | } |
8529 | } |
8530 | } |
8531 | |
8532 | if( rc==SQLITE_OK ){ |
8533 | /* Create the new CDS record. */ |
8534 | pNew = zipfileNewEntry(zPath); |
8535 | if( pNew==0 ){ |
8536 | rc = SQLITE_NOMEM; |
8537 | }else{ |
8538 | pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; |
8539 | pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; |
8540 | pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS; |
8541 | pNew->cds.iCompression = (u16)iMethod; |
8542 | zipfileMtimeToDos(&pNew->cds, mTime); |
8543 | pNew->cds.crc32 = iCrc32; |
8544 | pNew->cds.szCompressed = nData; |
8545 | pNew->cds.szUncompressed = (u32)sz; |
8546 | pNew->cds.iExternalAttr = (mode<<16); |
8547 | pNew->cds.iOffset = (u32)pTab->szCurrent; |
8548 | pNew->cds.nFile = (u16)nPath; |
8549 | pNew->mUnixTime = (u32)mTime; |
8550 | rc = zipfileAppendEntry(pTab, pNew, pData, nData); |
8551 | zipfileAddEntry(pTab, pOld, pNew); |
8552 | } |
8553 | } |
8554 | } |
8555 | |
8556 | if( rc==SQLITE_OK && (pOld || pOld2) ){ |
8557 | ZipfileCsr *pCsr; |
8558 | for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ |
8559 | if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){ |
8560 | pCsr->pCurrent = pCsr->pCurrent->pNext; |
8561 | pCsr->bNoop = 1; |
8562 | } |
8563 | } |
8564 | |
8565 | zipfileRemoveEntryFromList(pTab, pOld); |
8566 | zipfileRemoveEntryFromList(pTab, pOld2); |
8567 | } |
8568 | |
8569 | zipfile_update_done: |
8570 | sqlite3_free(pFree); |
8571 | sqlite3_free(zFree); |
8572 | return rc; |
8573 | } |
8574 | |
8575 | static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){ |
8576 | u8 *a = aBuf; |
8577 | zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD); |
8578 | zipfileWrite16(a, p->iDisk); |
8579 | zipfileWrite16(a, p->iFirstDisk); |
8580 | zipfileWrite16(a, p->nEntry); |
8581 | zipfileWrite16(a, p->nEntryTotal); |
8582 | zipfileWrite32(a, p->nSize); |
8583 | zipfileWrite32(a, p->iOffset); |
8584 | zipfileWrite16(a, 0); /* Size of trailing comment in bytes*/ |
8585 | |
8586 | return a-aBuf; |
8587 | } |
8588 | |
8589 | static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){ |
8590 | int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer); |
8591 | assert( nBuf==ZIPFILE_EOCD_FIXED_SZ ); |
8592 | return zipfileAppendData(pTab, pTab->aBuffer, nBuf); |
8593 | } |
8594 | |
8595 | /* |
8596 | ** Serialize the CDS structure into buffer aBuf[]. Return the number |
8597 | ** of bytes written. |
8598 | */ |
8599 | static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){ |
8600 | u8 *a = aBuf; |
8601 | ZipfileCDS *pCDS = &pEntry->cds; |
8602 | |
8603 | if( pEntry->aExtra==0 ){ |
8604 | pCDS->nExtra = 9; |
8605 | } |
8606 | |
8607 | zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS); |
8608 | zipfileWrite16(a, pCDS->iVersionMadeBy); |
8609 | zipfileWrite16(a, pCDS->iVersionExtract); |
8610 | zipfileWrite16(a, pCDS->flags); |
8611 | zipfileWrite16(a, pCDS->iCompression); |
8612 | zipfileWrite16(a, pCDS->mTime); |
8613 | zipfileWrite16(a, pCDS->mDate); |
8614 | zipfileWrite32(a, pCDS->crc32); |
8615 | zipfileWrite32(a, pCDS->szCompressed); |
8616 | zipfileWrite32(a, pCDS->szUncompressed); |
8617 | assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); |
8618 | zipfileWrite16(a, pCDS->nFile); |
8619 | zipfileWrite16(a, pCDS->nExtra); |
8620 | zipfileWrite16(a, pCDS->nComment); |
8621 | zipfileWrite16(a, pCDS->iDiskStart); |
8622 | zipfileWrite16(a, pCDS->iInternalAttr); |
8623 | zipfileWrite32(a, pCDS->iExternalAttr); |
8624 | zipfileWrite32(a, pCDS->iOffset); |
8625 | |
8626 | memcpy(a, pCDS->zFile, pCDS->nFile); |
8627 | a += pCDS->nFile; |
8628 | |
8629 | if( pEntry->aExtra ){ |
8630 | int n = (int)pCDS->nExtra + (int)pCDS->nComment; |
8631 | memcpy(a, pEntry->aExtra, n); |
8632 | a += n; |
8633 | }else{ |
8634 | assert( pCDS->nExtra==9 ); |
8635 | zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); |
8636 | zipfileWrite16(a, 5); |
8637 | *a++ = 0x01; |
8638 | zipfileWrite32(a, pEntry->mUnixTime); |
8639 | } |
8640 | |
8641 | return a-aBuf; |
8642 | } |
8643 | |
8644 | static int zipfileCommit(sqlite3_vtab *pVtab){ |
8645 | ZipfileTab *pTab = (ZipfileTab*)pVtab; |
8646 | int rc = SQLITE_OK; |
8647 | if( pTab->pWriteFd ){ |
8648 | i64 iOffset = pTab->szCurrent; |
8649 | ZipfileEntry *p; |
8650 | ZipfileEOCD eocd; |
8651 | int nEntry = 0; |
8652 | |
8653 | /* Write out all entries */ |
8654 | for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){ |
8655 | int n = zipfileSerializeCDS(p, pTab->aBuffer); |
8656 | rc = zipfileAppendData(pTab, pTab->aBuffer, n); |
8657 | nEntry++; |
8658 | } |
8659 | |
8660 | /* Write out the EOCD record */ |
8661 | eocd.iDisk = 0; |
8662 | eocd.iFirstDisk = 0; |
8663 | eocd.nEntry = (u16)nEntry; |
8664 | eocd.nEntryTotal = (u16)nEntry; |
8665 | eocd.nSize = (u32)(pTab->szCurrent - iOffset); |
8666 | eocd.iOffset = (u32)iOffset; |
8667 | rc = zipfileAppendEOCD(pTab, &eocd); |
8668 | |
8669 | zipfileCleanupTransaction(pTab); |
8670 | } |
8671 | return rc; |
8672 | } |
8673 | |
8674 | static int zipfileRollback(sqlite3_vtab *pVtab){ |
8675 | return zipfileCommit(pVtab); |
8676 | } |
8677 | |
8678 | static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){ |
8679 | ZipfileCsr *pCsr; |
8680 | for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ |
8681 | if( iId==pCsr->iId ) break; |
8682 | } |
8683 | return pCsr; |
8684 | } |
8685 | |
8686 | static void zipfileFunctionCds( |
8687 | sqlite3_context *context, |
8688 | int argc, |
8689 | sqlite3_value **argv |
8690 | ){ |
8691 | ZipfileCsr *pCsr; |
8692 | ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context); |
8693 | assert( argc>0 ); |
8694 | |
8695 | pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0])); |
8696 | if( pCsr ){ |
8697 | ZipfileCDS *p = &pCsr->pCurrent->cds; |
8698 | char *zRes = sqlite3_mprintf("{" |
8699 | "\"version-made-by\" : %u, " |
8700 | "\"version-to-extract\" : %u, " |
8701 | "\"flags\" : %u, " |
8702 | "\"compression\" : %u, " |
8703 | "\"time\" : %u, " |
8704 | "\"date\" : %u, " |
8705 | "\"crc32\" : %u, " |
8706 | "\"compressed-size\" : %u, " |
8707 | "\"uncompressed-size\" : %u, " |
8708 | "\"file-name-length\" : %u, " |
8709 | "\"extra-field-length\" : %u, " |
8710 | "\"file-comment-length\" : %u, " |
8711 | "\"disk-number-start\" : %u, " |
8712 | "\"internal-attr\" : %u, " |
8713 | "\"external-attr\" : %u, " |
8714 | "\"offset\" : %u }" , |
8715 | (u32)p->iVersionMadeBy, (u32)p->iVersionExtract, |
8716 | (u32)p->flags, (u32)p->iCompression, |
8717 | (u32)p->mTime, (u32)p->mDate, |
8718 | (u32)p->crc32, (u32)p->szCompressed, |
8719 | (u32)p->szUncompressed, (u32)p->nFile, |
8720 | (u32)p->nExtra, (u32)p->nComment, |
8721 | (u32)p->iDiskStart, (u32)p->iInternalAttr, |
8722 | (u32)p->iExternalAttr, (u32)p->iOffset |
8723 | ); |
8724 | |
8725 | if( zRes==0 ){ |
8726 | sqlite3_result_error_nomem(context); |
8727 | }else{ |
8728 | sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); |
8729 | sqlite3_free(zRes); |
8730 | } |
8731 | } |
8732 | } |
8733 | |
8734 | /* |
8735 | ** xFindFunction method. |
8736 | */ |
8737 | static int zipfileFindFunction( |
8738 | sqlite3_vtab *pVtab, /* Virtual table handle */ |
8739 | int nArg, /* Number of SQL function arguments */ |
8740 | const char *zName, /* Name of SQL function */ |
8741 | void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ |
8742 | void **ppArg /* OUT: User data for *pxFunc */ |
8743 | ){ |
8744 | if( sqlite3_stricmp("zipfile_cds" , zName)==0 ){ |
8745 | *pxFunc = zipfileFunctionCds; |
8746 | *ppArg = (void*)pVtab; |
8747 | return 1; |
8748 | } |
8749 | return 0; |
8750 | } |
8751 | |
8752 | typedef struct ZipfileBuffer ZipfileBuffer; |
8753 | struct ZipfileBuffer { |
8754 | u8 *a; /* Pointer to buffer */ |
8755 | int n; /* Size of buffer in bytes */ |
8756 | int nAlloc; /* Byte allocated at a[] */ |
8757 | }; |
8758 | |
8759 | typedef struct ZipfileCtx ZipfileCtx; |
8760 | struct ZipfileCtx { |
8761 | int nEntry; |
8762 | ZipfileBuffer body; |
8763 | ZipfileBuffer cds; |
8764 | }; |
8765 | |
8766 | static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){ |
8767 | if( pBuf->n+nByte>pBuf->nAlloc ){ |
8768 | u8 *aNew; |
8769 | sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512; |
8770 | int nReq = pBuf->n + nByte; |
8771 | |
8772 | while( nNew<nReq ) nNew = nNew*2; |
8773 | aNew = sqlite3_realloc64(pBuf->a, nNew); |
8774 | if( aNew==0 ) return SQLITE_NOMEM; |
8775 | pBuf->a = aNew; |
8776 | pBuf->nAlloc = (int)nNew; |
8777 | } |
8778 | return SQLITE_OK; |
8779 | } |
8780 | |
8781 | /* |
8782 | ** xStep() callback for the zipfile() aggregate. This can be called in |
8783 | ** any of the following ways: |
8784 | ** |
8785 | ** SELECT zipfile(name,data) ... |
8786 | ** SELECT zipfile(name,mode,mtime,data) ... |
8787 | ** SELECT zipfile(name,mode,mtime,data,method) ... |
8788 | */ |
8789 | static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ |
8790 | ZipfileCtx *p; /* Aggregate function context */ |
8791 | ZipfileEntry e; /* New entry to add to zip archive */ |
8792 | |
8793 | sqlite3_value *pName = 0; |
8794 | sqlite3_value *pMode = 0; |
8795 | sqlite3_value *pMtime = 0; |
8796 | sqlite3_value *pData = 0; |
8797 | sqlite3_value *pMethod = 0; |
8798 | |
8799 | int bIsDir = 0; |
8800 | u32 mode; |
8801 | int rc = SQLITE_OK; |
8802 | char *zErr = 0; |
8803 | |
8804 | int iMethod = -1; /* Compression method to use (0 or 8) */ |
8805 | |
8806 | const u8 *aData = 0; /* Possibly compressed data for new entry */ |
8807 | int nData = 0; /* Size of aData[] in bytes */ |
8808 | int szUncompressed = 0; /* Size of data before compression */ |
8809 | u8 *aFree = 0; /* Free this before returning */ |
8810 | u32 iCrc32 = 0; /* crc32 of uncompressed data */ |
8811 | |
8812 | char *zName = 0; /* Path (name) of new entry */ |
8813 | int nName = 0; /* Size of zName in bytes */ |
8814 | char *zFree = 0; /* Free this before returning */ |
8815 | int nByte; |
8816 | |
8817 | memset(&e, 0, sizeof(e)); |
8818 | p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); |
8819 | if( p==0 ) return; |
8820 | |
8821 | /* Martial the arguments into stack variables */ |
8822 | if( nVal!=2 && nVal!=4 && nVal!=5 ){ |
8823 | zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()" ); |
8824 | rc = SQLITE_ERROR; |
8825 | goto zipfile_step_out; |
8826 | } |
8827 | pName = apVal[0]; |
8828 | if( nVal==2 ){ |
8829 | pData = apVal[1]; |
8830 | }else{ |
8831 | pMode = apVal[1]; |
8832 | pMtime = apVal[2]; |
8833 | pData = apVal[3]; |
8834 | if( nVal==5 ){ |
8835 | pMethod = apVal[4]; |
8836 | } |
8837 | } |
8838 | |
8839 | /* Check that the 'name' parameter looks ok. */ |
8840 | zName = (char*)sqlite3_value_text(pName); |
8841 | nName = sqlite3_value_bytes(pName); |
8842 | if( zName==0 ){ |
8843 | zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL" ); |
8844 | rc = SQLITE_ERROR; |
8845 | goto zipfile_step_out; |
8846 | } |
8847 | |
8848 | /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use |
8849 | ** deflate compression) or NULL (choose automatically). */ |
8850 | if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){ |
8851 | iMethod = (int)sqlite3_value_int64(pMethod); |
8852 | if( iMethod!=0 && iMethod!=8 ){ |
8853 | zErr = sqlite3_mprintf("illegal method value: %d" , iMethod); |
8854 | rc = SQLITE_ERROR; |
8855 | goto zipfile_step_out; |
8856 | } |
8857 | } |
8858 | |
8859 | /* Now inspect the data. If this is NULL, then the new entry must be a |
8860 | ** directory. Otherwise, figure out whether or not the data should |
8861 | ** be deflated or simply stored in the zip archive. */ |
8862 | if( sqlite3_value_type(pData)==SQLITE_NULL ){ |
8863 | bIsDir = 1; |
8864 | iMethod = 0; |
8865 | }else{ |
8866 | aData = sqlite3_value_blob(pData); |
8867 | szUncompressed = nData = sqlite3_value_bytes(pData); |
8868 | iCrc32 = crc32(0, aData, nData); |
8869 | if( iMethod<0 || iMethod==8 ){ |
8870 | int nOut = 0; |
8871 | rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr); |
8872 | if( rc!=SQLITE_OK ){ |
8873 | goto zipfile_step_out; |
8874 | } |
8875 | if( iMethod==8 || nOut<nData ){ |
8876 | aData = aFree; |
8877 | nData = nOut; |
8878 | iMethod = 8; |
8879 | }else{ |
8880 | iMethod = 0; |
8881 | } |
8882 | } |
8883 | } |
8884 | |
8885 | /* Decode the "mode" argument. */ |
8886 | rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr); |
8887 | if( rc ) goto zipfile_step_out; |
8888 | |
8889 | /* Decode the "mtime" argument. */ |
8890 | e.mUnixTime = zipfileGetTime(pMtime); |
8891 | |
8892 | /* If this is a directory entry, ensure that there is exactly one '/' |
8893 | ** at the end of the path. Or, if this is not a directory and the path |
8894 | ** ends in '/' it is an error. */ |
8895 | if( bIsDir==0 ){ |
8896 | if( nName>0 && zName[nName-1]=='/' ){ |
8897 | zErr = sqlite3_mprintf("non-directory name must not end with /" ); |
8898 | rc = SQLITE_ERROR; |
8899 | goto zipfile_step_out; |
8900 | } |
8901 | }else{ |
8902 | if( nName==0 || zName[nName-1]!='/' ){ |
8903 | zName = zFree = sqlite3_mprintf("%s/" , zName); |
8904 | if( zName==0 ){ |
8905 | rc = SQLITE_NOMEM; |
8906 | goto zipfile_step_out; |
8907 | } |
8908 | nName = (int)strlen(zName); |
8909 | }else{ |
8910 | while( nName>1 && zName[nName-2]=='/' ) nName--; |
8911 | } |
8912 | } |
8913 | |
8914 | /* Assemble the ZipfileEntry object for the new zip archive entry */ |
8915 | e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; |
8916 | e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; |
8917 | e.cds.flags = ZIPFILE_NEWENTRY_FLAGS; |
8918 | e.cds.iCompression = (u16)iMethod; |
8919 | zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime); |
8920 | e.cds.crc32 = iCrc32; |
8921 | e.cds.szCompressed = nData; |
8922 | e.cds.szUncompressed = szUncompressed; |
8923 | e.cds.iExternalAttr = (mode<<16); |
8924 | e.cds.iOffset = p->body.n; |
8925 | e.cds.nFile = (u16)nName; |
8926 | e.cds.zFile = zName; |
8927 | |
8928 | /* Append the LFH to the body of the new archive */ |
8929 | nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9; |
8930 | if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out; |
8931 | p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]); |
8932 | |
8933 | /* Append the data to the body of the new archive */ |
8934 | if( nData>0 ){ |
8935 | if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out; |
8936 | memcpy(&p->body.a[p->body.n], aData, nData); |
8937 | p->body.n += nData; |
8938 | } |
8939 | |
8940 | /* Append the CDS record to the directory of the new archive */ |
8941 | nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9; |
8942 | if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out; |
8943 | p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]); |
8944 | |
8945 | /* Increment the count of entries in the archive */ |
8946 | p->nEntry++; |
8947 | |
8948 | zipfile_step_out: |
8949 | sqlite3_free(aFree); |
8950 | sqlite3_free(zFree); |
8951 | if( rc ){ |
8952 | if( zErr ){ |
8953 | sqlite3_result_error(pCtx, zErr, -1); |
8954 | }else{ |
8955 | sqlite3_result_error_code(pCtx, rc); |
8956 | } |
8957 | } |
8958 | sqlite3_free(zErr); |
8959 | } |
8960 | |
8961 | /* |
8962 | ** xFinalize() callback for zipfile aggregate function. |
8963 | */ |
8964 | static void zipfileFinal(sqlite3_context *pCtx){ |
8965 | ZipfileCtx *p; |
8966 | ZipfileEOCD eocd; |
8967 | sqlite3_int64 nZip; |
8968 | u8 *aZip; |
8969 | |
8970 | p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); |
8971 | if( p==0 ) return; |
8972 | if( p->nEntry>0 ){ |
8973 | memset(&eocd, 0, sizeof(eocd)); |
8974 | eocd.nEntry = (u16)p->nEntry; |
8975 | eocd.nEntryTotal = (u16)p->nEntry; |
8976 | eocd.nSize = p->cds.n; |
8977 | eocd.iOffset = p->body.n; |
8978 | |
8979 | nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ; |
8980 | aZip = (u8*)sqlite3_malloc64(nZip); |
8981 | if( aZip==0 ){ |
8982 | sqlite3_result_error_nomem(pCtx); |
8983 | }else{ |
8984 | memcpy(aZip, p->body.a, p->body.n); |
8985 | memcpy(&aZip[p->body.n], p->cds.a, p->cds.n); |
8986 | zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]); |
8987 | sqlite3_result_blob(pCtx, aZip, (int)nZip, zipfileFree); |
8988 | } |
8989 | } |
8990 | |
8991 | sqlite3_free(p->body.a); |
8992 | sqlite3_free(p->cds.a); |
8993 | } |
8994 | |
8995 | |
8996 | /* |
8997 | ** Register the "zipfile" virtual table. |
8998 | */ |
8999 | static int zipfileRegister(sqlite3 *db){ |
9000 | static sqlite3_module zipfileModule = { |
9001 | 1, /* iVersion */ |
9002 | zipfileConnect, /* xCreate */ |
9003 | zipfileConnect, /* xConnect */ |
9004 | zipfileBestIndex, /* xBestIndex */ |
9005 | zipfileDisconnect, /* xDisconnect */ |
9006 | zipfileDisconnect, /* xDestroy */ |
9007 | zipfileOpen, /* xOpen - open a cursor */ |
9008 | zipfileClose, /* xClose - close a cursor */ |
9009 | zipfileFilter, /* xFilter - configure scan constraints */ |
9010 | zipfileNext, /* xNext - advance a cursor */ |
9011 | zipfileEof, /* xEof - check for end of scan */ |
9012 | zipfileColumn, /* xColumn - read data */ |
9013 | 0, /* xRowid - read data */ |
9014 | zipfileUpdate, /* xUpdate */ |
9015 | zipfileBegin, /* xBegin */ |
9016 | 0, /* xSync */ |
9017 | zipfileCommit, /* xCommit */ |
9018 | zipfileRollback, /* xRollback */ |
9019 | zipfileFindFunction, /* xFindMethod */ |
9020 | 0, /* xRename */ |
9021 | 0, /* xSavepoint */ |
9022 | 0, /* xRelease */ |
9023 | 0, /* xRollback */ |
9024 | 0 /* xShadowName */ |
9025 | }; |
9026 | |
9027 | int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0); |
9028 | if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds" , -1); |
9029 | if( rc==SQLITE_OK ){ |
9030 | rc = sqlite3_create_function(db, "zipfile" , -1, SQLITE_UTF8, 0, 0, |
9031 | zipfileStep, zipfileFinal |
9032 | ); |
9033 | } |
9034 | assert( sizeof(i64)==8 ); |
9035 | assert( sizeof(u32)==4 ); |
9036 | assert( sizeof(u16)==2 ); |
9037 | assert( sizeof(u8)==1 ); |
9038 | return rc; |
9039 | } |
9040 | #else /* SQLITE_OMIT_VIRTUALTABLE */ |
9041 | # define zipfileRegister(x) SQLITE_OK |
9042 | #endif |
9043 | |
9044 | #ifdef _WIN32 |
9045 | |
9046 | #endif |
9047 | int sqlite3_zipfile_init( |
9048 | sqlite3 *db, |
9049 | char **pzErrMsg, |
9050 | const sqlite3_api_routines *pApi |
9051 | ){ |
9052 | SQLITE_EXTENSION_INIT2(pApi); |
9053 | (void)pzErrMsg; /* Unused parameter */ |
9054 | return zipfileRegister(db); |
9055 | } |
9056 | |
9057 | /************************* End ../ext/misc/zipfile.c ********************/ |
9058 | /************************* Begin ../ext/misc/sqlar.c ******************/ |
9059 | /* |
9060 | ** 2017-12-17 |
9061 | ** |
9062 | ** The author disclaims copyright to this source code. In place of |
9063 | ** a legal notice, here is a blessing: |
9064 | ** |
9065 | ** May you do good and not evil. |
9066 | ** May you find forgiveness for yourself and forgive others. |
9067 | ** May you share freely, never taking more than you give. |
9068 | ** |
9069 | ****************************************************************************** |
9070 | ** |
9071 | ** Utility functions sqlar_compress() and sqlar_uncompress(). Useful |
9072 | ** for working with sqlar archives and used by the shell tool's built-in |
9073 | ** sqlar support. |
9074 | */ |
9075 | /* #include "sqlite3ext.h" */ |
9076 | SQLITE_EXTENSION_INIT1 |
9077 | #include <zlib.h> |
9078 | #include <assert.h> |
9079 | |
9080 | /* |
9081 | ** Implementation of the "sqlar_compress(X)" SQL function. |
9082 | ** |
9083 | ** If the type of X is SQLITE_BLOB, and compressing that blob using |
9084 | ** zlib utility function compress() yields a smaller blob, return the |
9085 | ** compressed blob. Otherwise, return a copy of X. |
9086 | ** |
9087 | ** SQLar uses the "zlib format" for compressed content. The zlib format |
9088 | ** contains a two-byte identification header and a four-byte checksum at |
9089 | ** the end. This is different from ZIP which uses the raw deflate format. |
9090 | ** |
9091 | ** Future enhancements to SQLar might add support for new compression formats. |
9092 | ** If so, those new formats will be identified by alternative headers in the |
9093 | ** compressed data. |
9094 | */ |
9095 | static void sqlarCompressFunc( |
9096 | sqlite3_context *context, |
9097 | int argc, |
9098 | sqlite3_value **argv |
9099 | ){ |
9100 | assert( argc==1 ); |
9101 | if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ |
9102 | const Bytef *pData = sqlite3_value_blob(argv[0]); |
9103 | uLong nData = sqlite3_value_bytes(argv[0]); |
9104 | uLongf nOut = compressBound(nData); |
9105 | Bytef *pOut; |
9106 | |
9107 | pOut = (Bytef*)sqlite3_malloc(nOut); |
9108 | if( pOut==0 ){ |
9109 | sqlite3_result_error_nomem(context); |
9110 | return; |
9111 | }else{ |
9112 | if( Z_OK!=compress(pOut, &nOut, pData, nData) ){ |
9113 | sqlite3_result_error(context, "error in compress()" , -1); |
9114 | }else if( nOut<nData ){ |
9115 | sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT); |
9116 | }else{ |
9117 | sqlite3_result_value(context, argv[0]); |
9118 | } |
9119 | sqlite3_free(pOut); |
9120 | } |
9121 | }else{ |
9122 | sqlite3_result_value(context, argv[0]); |
9123 | } |
9124 | } |
9125 | |
9126 | /* |
9127 | ** Implementation of the "sqlar_uncompress(X,SZ)" SQL function |
9128 | ** |
9129 | ** Parameter SZ is interpreted as an integer. If it is less than or |
9130 | ** equal to zero, then this function returns a copy of X. Or, if |
9131 | ** SZ is equal to the size of X when interpreted as a blob, also |
9132 | ** return a copy of X. Otherwise, decompress blob X using zlib |
9133 | ** utility function uncompress() and return the results (another |
9134 | ** blob). |
9135 | */ |
9136 | static void sqlarUncompressFunc( |
9137 | sqlite3_context *context, |
9138 | int argc, |
9139 | sqlite3_value **argv |
9140 | ){ |
9141 | uLong nData; |
9142 | uLongf sz; |
9143 | |
9144 | assert( argc==2 ); |
9145 | sz = sqlite3_value_int(argv[1]); |
9146 | |
9147 | if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){ |
9148 | sqlite3_result_value(context, argv[0]); |
9149 | }else{ |
9150 | const Bytef *pData= sqlite3_value_blob(argv[0]); |
9151 | Bytef *pOut = sqlite3_malloc(sz); |
9152 | if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){ |
9153 | sqlite3_result_error(context, "error in uncompress()" , -1); |
9154 | }else{ |
9155 | sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT); |
9156 | } |
9157 | sqlite3_free(pOut); |
9158 | } |
9159 | } |
9160 | |
9161 | |
9162 | #ifdef _WIN32 |
9163 | |
9164 | #endif |
9165 | int sqlite3_sqlar_init( |
9166 | sqlite3 *db, |
9167 | char **pzErrMsg, |
9168 | const sqlite3_api_routines *pApi |
9169 | ){ |
9170 | int rc = SQLITE_OK; |
9171 | SQLITE_EXTENSION_INIT2(pApi); |
9172 | (void)pzErrMsg; /* Unused parameter */ |
9173 | rc = sqlite3_create_function(db, "sqlar_compress" , 1, |
9174 | SQLITE_UTF8|SQLITE_INNOCUOUS, 0, |
9175 | sqlarCompressFunc, 0, 0); |
9176 | if( rc==SQLITE_OK ){ |
9177 | rc = sqlite3_create_function(db, "sqlar_uncompress" , 2, |
9178 | SQLITE_UTF8|SQLITE_INNOCUOUS, 0, |
9179 | sqlarUncompressFunc, 0, 0); |
9180 | } |
9181 | return rc; |
9182 | } |
9183 | |
9184 | /************************* End ../ext/misc/sqlar.c ********************/ |
9185 | #endif |
9186 | /************************* Begin ../ext/expert/sqlite3expert.h ******************/ |
9187 | /* |
9188 | ** 2017 April 07 |
9189 | ** |
9190 | ** The author disclaims copyright to this source code. In place of |
9191 | ** a legal notice, here is a blessing: |
9192 | ** |
9193 | ** May you do good and not evil. |
9194 | ** May you find forgiveness for yourself and forgive others. |
9195 | ** May you share freely, never taking more than you give. |
9196 | ** |
9197 | ************************************************************************* |
9198 | */ |
9199 | #if !defined(SQLITEEXPERT_H) |
9200 | #define SQLITEEXPERT_H 1 |
9201 | /* #include "sqlite3.h" */ |
9202 | |
9203 | typedef struct sqlite3expert sqlite3expert; |
9204 | |
9205 | /* |
9206 | ** Create a new sqlite3expert object. |
9207 | ** |
9208 | ** If successful, a pointer to the new object is returned and (*pzErr) set |
9209 | ** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to |
9210 | ** an English-language error message. In this case it is the responsibility |
9211 | ** of the caller to eventually free the error message buffer using |
9212 | ** sqlite3_free(). |
9213 | */ |
9214 | sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr); |
9215 | |
9216 | /* |
9217 | ** Configure an sqlite3expert object. |
9218 | ** |
9219 | ** EXPERT_CONFIG_SAMPLE: |
9220 | ** By default, sqlite3_expert_analyze() generates sqlite_stat1 data for |
9221 | ** each candidate index. This involves scanning and sorting the entire |
9222 | ** contents of each user database table once for each candidate index |
9223 | ** associated with the table. For large databases, this can be |
9224 | ** prohibitively slow. This option allows the sqlite3expert object to |
9225 | ** be configured so that sqlite_stat1 data is instead generated based on a |
9226 | ** subset of each table, or so that no sqlite_stat1 data is used at all. |
9227 | ** |
9228 | ** A single integer argument is passed to this option. If the value is less |
9229 | ** than or equal to zero, then no sqlite_stat1 data is generated or used by |
9230 | ** the analysis - indexes are recommended based on the database schema only. |
9231 | ** Or, if the value is 100 or greater, complete sqlite_stat1 data is |
9232 | ** generated for each candidate index (this is the default). Finally, if the |
9233 | ** value falls between 0 and 100, then it represents the percentage of user |
9234 | ** table rows that should be considered when generating sqlite_stat1 data. |
9235 | ** |
9236 | ** Examples: |
9237 | ** |
9238 | ** // Do not generate any sqlite_stat1 data |
9239 | ** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0); |
9240 | ** |
9241 | ** // Generate sqlite_stat1 data based on 10% of the rows in each table. |
9242 | ** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10); |
9243 | */ |
9244 | int sqlite3_expert_config(sqlite3expert *p, int op, ...); |
9245 | |
9246 | #define EXPERT_CONFIG_SAMPLE 1 /* int */ |
9247 | |
9248 | /* |
9249 | ** Specify zero or more SQL statements to be included in the analysis. |
9250 | ** |
9251 | ** Buffer zSql must contain zero or more complete SQL statements. This |
9252 | ** function parses all statements contained in the buffer and adds them |
9253 | ** to the internal list of statements to analyze. If successful, SQLITE_OK |
9254 | ** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example |
9255 | ** due to a error in the SQL - an SQLite error code is returned and (*pzErr) |
9256 | ** may be set to point to an English language error message. In this case |
9257 | ** the caller is responsible for eventually freeing the error message buffer |
9258 | ** using sqlite3_free(). |
9259 | ** |
9260 | ** If an error does occur while processing one of the statements in the |
9261 | ** buffer passed as the second argument, none of the statements in the |
9262 | ** buffer are added to the analysis. |
9263 | ** |
9264 | ** This function must be called before sqlite3_expert_analyze(). If a call |
9265 | ** to this function is made on an sqlite3expert object that has already |
9266 | ** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned |
9267 | ** immediately and no statements are added to the analysis. |
9268 | */ |
9269 | int sqlite3_expert_sql( |
9270 | sqlite3expert *p, /* From a successful sqlite3_expert_new() */ |
9271 | const char *zSql, /* SQL statement(s) to add */ |
9272 | char **pzErr /* OUT: Error message (if any) */ |
9273 | ); |
9274 | |
9275 | |
9276 | /* |
9277 | ** This function is called after the sqlite3expert object has been configured |
9278 | ** with all SQL statements using sqlite3_expert_sql() to actually perform |
9279 | ** the analysis. Once this function has been called, it is not possible to |
9280 | ** add further SQL statements to the analysis. |
9281 | ** |
9282 | ** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if |
9283 | ** an error occurs, an SQLite error code is returned and (*pzErr) set to |
9284 | ** point to a buffer containing an English language error message. In this |
9285 | ** case it is the responsibility of the caller to eventually free the buffer |
9286 | ** using sqlite3_free(). |
9287 | ** |
9288 | ** If an error does occur within this function, the sqlite3expert object |
9289 | ** is no longer useful for any purpose. At that point it is no longer |
9290 | ** possible to add further SQL statements to the object or to re-attempt |
9291 | ** the analysis. The sqlite3expert object must still be freed using a call |
9292 | ** sqlite3_expert_destroy(). |
9293 | */ |
9294 | int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr); |
9295 | |
9296 | /* |
9297 | ** Return the total number of statements loaded using sqlite3_expert_sql(). |
9298 | ** The total number of SQL statements may be different from the total number |
9299 | ** to calls to sqlite3_expert_sql(). |
9300 | */ |
9301 | int sqlite3_expert_count(sqlite3expert*); |
9302 | |
9303 | /* |
9304 | ** Return a component of the report. |
9305 | ** |
9306 | ** This function is called after sqlite3_expert_analyze() to extract the |
9307 | ** results of the analysis. Each call to this function returns either a |
9308 | ** NULL pointer or a pointer to a buffer containing a nul-terminated string. |
9309 | ** The value passed as the third argument must be one of the EXPERT_REPORT_* |
9310 | ** #define constants defined below. |
9311 | ** |
9312 | ** For some EXPERT_REPORT_* parameters, the buffer returned contains |
9313 | ** information relating to a specific SQL statement. In these cases that |
9314 | ** SQL statement is identified by the value passed as the second argument. |
9315 | ** SQL statements are numbered from 0 in the order in which they are parsed. |
9316 | ** If an out-of-range value (less than zero or equal to or greater than the |
9317 | ** value returned by sqlite3_expert_count()) is passed as the second argument |
9318 | ** along with such an EXPERT_REPORT_* parameter, NULL is always returned. |
9319 | ** |
9320 | ** EXPERT_REPORT_SQL: |
9321 | ** Return the text of SQL statement iStmt. |
9322 | ** |
9323 | ** EXPERT_REPORT_INDEXES: |
9324 | ** Return a buffer containing the CREATE INDEX statements for all recommended |
9325 | ** indexes for statement iStmt. If there are no new recommeded indexes, NULL |
9326 | ** is returned. |
9327 | ** |
9328 | ** EXPERT_REPORT_PLAN: |
9329 | ** Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query |
9330 | ** iStmt after the proposed indexes have been added to the database schema. |
9331 | ** |
9332 | ** EXPERT_REPORT_CANDIDATES: |
9333 | ** Return a pointer to a buffer containing the CREATE INDEX statements |
9334 | ** for all indexes that were tested (for all SQL statements). The iStmt |
9335 | ** parameter is ignored for EXPERT_REPORT_CANDIDATES calls. |
9336 | */ |
9337 | const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport); |
9338 | |
9339 | /* |
9340 | ** Values for the third argument passed to sqlite3_expert_report(). |
9341 | */ |
9342 | #define EXPERT_REPORT_SQL 1 |
9343 | #define EXPERT_REPORT_INDEXES 2 |
9344 | #define EXPERT_REPORT_PLAN 3 |
9345 | #define EXPERT_REPORT_CANDIDATES 4 |
9346 | |
9347 | /* |
9348 | ** Free an (sqlite3expert*) handle and all associated resources. There |
9349 | ** should be one call to this function for each successful call to |
9350 | ** sqlite3-expert_new(). |
9351 | */ |
9352 | void sqlite3_expert_destroy(sqlite3expert*); |
9353 | |
9354 | #endif /* !defined(SQLITEEXPERT_H) */ |
9355 | |
9356 | /************************* End ../ext/expert/sqlite3expert.h ********************/ |
9357 | /************************* Begin ../ext/expert/sqlite3expert.c ******************/ |
9358 | /* |
9359 | ** 2017 April 09 |
9360 | ** |
9361 | ** The author disclaims copyright to this source code. In place of |
9362 | ** a legal notice, here is a blessing: |
9363 | ** |
9364 | ** May you do good and not evil. |
9365 | ** May you find forgiveness for yourself and forgive others. |
9366 | ** May you share freely, never taking more than you give. |
9367 | ** |
9368 | ************************************************************************* |
9369 | */ |
9370 | /* #include "sqlite3expert.h" */ |
9371 | #include <assert.h> |
9372 | #include <string.h> |
9373 | #include <stdio.h> |
9374 | |
9375 | #if !defined(SQLITE_AMALGAMATION) |
9376 | #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
9377 | # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 |
9378 | #endif |
9379 | #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) |
9380 | # define ALWAYS(X) (1) |
9381 | # define NEVER(X) (0) |
9382 | #elif !defined(NDEBUG) |
9383 | # define ALWAYS(X) ((X)?1:(assert(0),0)) |
9384 | # define NEVER(X) ((X)?(assert(0),1):0) |
9385 | #else |
9386 | # define ALWAYS(X) (X) |
9387 | # define NEVER(X) (X) |
9388 | #endif |
9389 | #endif /* !defined(SQLITE_AMALGAMATION) */ |
9390 | |
9391 | |
9392 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
9393 | |
9394 | /* typedef sqlite3_int64 i64; */ |
9395 | /* typedef sqlite3_uint64 u64; */ |
9396 | |
9397 | typedef struct IdxColumn IdxColumn; |
9398 | typedef struct IdxConstraint IdxConstraint; |
9399 | typedef struct IdxScan IdxScan; |
9400 | typedef struct IdxStatement IdxStatement; |
9401 | typedef struct IdxTable IdxTable; |
9402 | typedef struct IdxWrite IdxWrite; |
9403 | |
9404 | #define STRLEN (int)strlen |
9405 | |
9406 | /* |
9407 | ** A temp table name that we assume no user database will actually use. |
9408 | ** If this assumption proves incorrect triggers on the table with the |
9409 | ** conflicting name will be ignored. |
9410 | */ |
9411 | #define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776" |
9412 | |
9413 | /* |
9414 | ** A single constraint. Equivalent to either "col = ?" or "col < ?" (or |
9415 | ** any other type of single-ended range constraint on a column). |
9416 | ** |
9417 | ** pLink: |
9418 | ** Used to temporarily link IdxConstraint objects into lists while |
9419 | ** creating candidate indexes. |
9420 | */ |
9421 | struct IdxConstraint { |
9422 | char *zColl; /* Collation sequence */ |
9423 | int bRange; /* True for range, false for eq */ |
9424 | int iCol; /* Constrained table column */ |
9425 | int bFlag; /* Used by idxFindCompatible() */ |
9426 | int bDesc; /* True if ORDER BY <expr> DESC */ |
9427 | IdxConstraint *pNext; /* Next constraint in pEq or pRange list */ |
9428 | IdxConstraint *pLink; /* See above */ |
9429 | }; |
9430 | |
9431 | /* |
9432 | ** A single scan of a single table. |
9433 | */ |
9434 | struct IdxScan { |
9435 | IdxTable *pTab; /* Associated table object */ |
9436 | int iDb; /* Database containing table zTable */ |
9437 | i64 covering; /* Mask of columns required for cov. index */ |
9438 | IdxConstraint *pOrder; /* ORDER BY columns */ |
9439 | IdxConstraint *pEq; /* List of == constraints */ |
9440 | IdxConstraint *pRange; /* List of < constraints */ |
9441 | IdxScan *pNextScan; /* Next IdxScan object for same analysis */ |
9442 | }; |
9443 | |
9444 | /* |
9445 | ** Information regarding a single database table. Extracted from |
9446 | ** "PRAGMA table_info" by function idxGetTableInfo(). |
9447 | */ |
9448 | struct IdxColumn { |
9449 | char *zName; |
9450 | char *zColl; |
9451 | int iPk; |
9452 | }; |
9453 | struct IdxTable { |
9454 | int nCol; |
9455 | char *zName; /* Table name */ |
9456 | IdxColumn *aCol; |
9457 | IdxTable *pNext; /* Next table in linked list of all tables */ |
9458 | }; |
9459 | |
9460 | /* |
9461 | ** An object of the following type is created for each unique table/write-op |
9462 | ** seen. The objects are stored in a singly-linked list beginning at |
9463 | ** sqlite3expert.pWrite. |
9464 | */ |
9465 | struct IdxWrite { |
9466 | IdxTable *pTab; |
9467 | int eOp; /* SQLITE_UPDATE, DELETE or INSERT */ |
9468 | IdxWrite *pNext; |
9469 | }; |
9470 | |
9471 | /* |
9472 | ** Each statement being analyzed is represented by an instance of this |
9473 | ** structure. |
9474 | */ |
9475 | struct IdxStatement { |
9476 | int iId; /* Statement number */ |
9477 | char *zSql; /* SQL statement */ |
9478 | char *zIdx; /* Indexes */ |
9479 | char *zEQP; /* Plan */ |
9480 | IdxStatement *pNext; |
9481 | }; |
9482 | |
9483 | |
9484 | /* |
9485 | ** A hash table for storing strings. With space for a payload string |
9486 | ** with each entry. Methods are: |
9487 | ** |
9488 | ** idxHashInit() |
9489 | ** idxHashClear() |
9490 | ** idxHashAdd() |
9491 | ** idxHashSearch() |
9492 | */ |
9493 | #define IDX_HASH_SIZE 1023 |
9494 | typedef struct IdxHashEntry IdxHashEntry; |
9495 | typedef struct IdxHash IdxHash; |
9496 | struct IdxHashEntry { |
9497 | char *zKey; /* nul-terminated key */ |
9498 | char *zVal; /* nul-terminated value string */ |
9499 | char *zVal2; /* nul-terminated value string 2 */ |
9500 | IdxHashEntry *pHashNext; /* Next entry in same hash bucket */ |
9501 | IdxHashEntry *pNext; /* Next entry in hash */ |
9502 | }; |
9503 | struct IdxHash { |
9504 | IdxHashEntry *pFirst; |
9505 | IdxHashEntry *aHash[IDX_HASH_SIZE]; |
9506 | }; |
9507 | |
9508 | /* |
9509 | ** sqlite3expert object. |
9510 | */ |
9511 | struct sqlite3expert { |
9512 | int iSample; /* Percentage of tables to sample for stat1 */ |
9513 | sqlite3 *db; /* User database */ |
9514 | sqlite3 *dbm; /* In-memory db for this analysis */ |
9515 | sqlite3 *dbv; /* Vtab schema for this analysis */ |
9516 | IdxTable *pTable; /* List of all IdxTable objects */ |
9517 | IdxScan *pScan; /* List of scan objects */ |
9518 | IdxWrite *pWrite; /* List of write objects */ |
9519 | IdxStatement *pStatement; /* List of IdxStatement objects */ |
9520 | int bRun; /* True once analysis has run */ |
9521 | char **pzErrmsg; |
9522 | int rc; /* Error code from whereinfo hook */ |
9523 | IdxHash hIdx; /* Hash containing all candidate indexes */ |
9524 | char *zCandidates; /* For EXPERT_REPORT_CANDIDATES */ |
9525 | }; |
9526 | |
9527 | |
9528 | /* |
9529 | ** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). |
9530 | ** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL. |
9531 | */ |
9532 | static void *idxMalloc(int *pRc, int nByte){ |
9533 | void *pRet; |
9534 | assert( *pRc==SQLITE_OK ); |
9535 | assert( nByte>0 ); |
9536 | pRet = sqlite3_malloc(nByte); |
9537 | if( pRet ){ |
9538 | memset(pRet, 0, nByte); |
9539 | }else{ |
9540 | *pRc = SQLITE_NOMEM; |
9541 | } |
9542 | return pRet; |
9543 | } |
9544 | |
9545 | /* |
9546 | ** Initialize an IdxHash hash table. |
9547 | */ |
9548 | static void idxHashInit(IdxHash *pHash){ |
9549 | memset(pHash, 0, sizeof(IdxHash)); |
9550 | } |
9551 | |
9552 | /* |
9553 | ** Reset an IdxHash hash table. |
9554 | */ |
9555 | static void idxHashClear(IdxHash *pHash){ |
9556 | int i; |
9557 | for(i=0; i<IDX_HASH_SIZE; i++){ |
9558 | IdxHashEntry *pEntry; |
9559 | IdxHashEntry *pNext; |
9560 | for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){ |
9561 | pNext = pEntry->pHashNext; |
9562 | sqlite3_free(pEntry->zVal2); |
9563 | sqlite3_free(pEntry); |
9564 | } |
9565 | } |
9566 | memset(pHash, 0, sizeof(IdxHash)); |
9567 | } |
9568 | |
9569 | /* |
9570 | ** Return the index of the hash bucket that the string specified by the |
9571 | ** arguments to this function belongs. |
9572 | */ |
9573 | static int idxHashString(const char *z, int n){ |
9574 | unsigned int ret = 0; |
9575 | int i; |
9576 | for(i=0; i<n; i++){ |
9577 | ret += (ret<<3) + (unsigned char)(z[i]); |
9578 | } |
9579 | return (int)(ret % IDX_HASH_SIZE); |
9580 | } |
9581 | |
9582 | /* |
9583 | ** If zKey is already present in the hash table, return non-zero and do |
9584 | ** nothing. Otherwise, add an entry with key zKey and payload string zVal to |
9585 | ** the hash table passed as the second argument. |
9586 | */ |
9587 | static int idxHashAdd( |
9588 | int *pRc, |
9589 | IdxHash *pHash, |
9590 | const char *zKey, |
9591 | const char *zVal |
9592 | ){ |
9593 | int nKey = STRLEN(zKey); |
9594 | int iHash = idxHashString(zKey, nKey); |
9595 | int nVal = (zVal ? STRLEN(zVal) : 0); |
9596 | IdxHashEntry *pEntry; |
9597 | assert( iHash>=0 ); |
9598 | for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ |
9599 | if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ |
9600 | return 1; |
9601 | } |
9602 | } |
9603 | pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1); |
9604 | if( pEntry ){ |
9605 | pEntry->zKey = (char*)&pEntry[1]; |
9606 | memcpy(pEntry->zKey, zKey, nKey); |
9607 | if( zVal ){ |
9608 | pEntry->zVal = &pEntry->zKey[nKey+1]; |
9609 | memcpy(pEntry->zVal, zVal, nVal); |
9610 | } |
9611 | pEntry->pHashNext = pHash->aHash[iHash]; |
9612 | pHash->aHash[iHash] = pEntry; |
9613 | |
9614 | pEntry->pNext = pHash->pFirst; |
9615 | pHash->pFirst = pEntry; |
9616 | } |
9617 | return 0; |
9618 | } |
9619 | |
9620 | /* |
9621 | ** If zKey/nKey is present in the hash table, return a pointer to the |
9622 | ** hash-entry object. |
9623 | */ |
9624 | static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){ |
9625 | int iHash; |
9626 | IdxHashEntry *pEntry; |
9627 | if( nKey<0 ) nKey = STRLEN(zKey); |
9628 | iHash = idxHashString(zKey, nKey); |
9629 | assert( iHash>=0 ); |
9630 | for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ |
9631 | if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ |
9632 | return pEntry; |
9633 | } |
9634 | } |
9635 | return 0; |
9636 | } |
9637 | |
9638 | /* |
9639 | ** If the hash table contains an entry with a key equal to the string |
9640 | ** passed as the final two arguments to this function, return a pointer |
9641 | ** to the payload string. Otherwise, if zKey/nKey is not present in the |
9642 | ** hash table, return NULL. |
9643 | */ |
9644 | static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){ |
9645 | IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey); |
9646 | if( pEntry ) return pEntry->zVal; |
9647 | return 0; |
9648 | } |
9649 | |
9650 | /* |
9651 | ** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl |
9652 | ** variable to point to a copy of nul-terminated string zColl. |
9653 | */ |
9654 | static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){ |
9655 | IdxConstraint *pNew; |
9656 | int nColl = STRLEN(zColl); |
9657 | |
9658 | assert( *pRc==SQLITE_OK ); |
9659 | pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1); |
9660 | if( pNew ){ |
9661 | pNew->zColl = (char*)&pNew[1]; |
9662 | memcpy(pNew->zColl, zColl, nColl+1); |
9663 | } |
9664 | return pNew; |
9665 | } |
9666 | |
9667 | /* |
9668 | ** An error associated with database handle db has just occurred. Pass |
9669 | ** the error message to callback function xOut. |
9670 | */ |
9671 | static void idxDatabaseError( |
9672 | sqlite3 *db, /* Database handle */ |
9673 | char **pzErrmsg /* Write error here */ |
9674 | ){ |
9675 | *pzErrmsg = sqlite3_mprintf("%s" , sqlite3_errmsg(db)); |
9676 | } |
9677 | |
9678 | /* |
9679 | ** Prepare an SQL statement. |
9680 | */ |
9681 | static int idxPrepareStmt( |
9682 | sqlite3 *db, /* Database handle to compile against */ |
9683 | sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ |
9684 | char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ |
9685 | const char *zSql /* SQL statement to compile */ |
9686 | ){ |
9687 | int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); |
9688 | if( rc!=SQLITE_OK ){ |
9689 | *ppStmt = 0; |
9690 | idxDatabaseError(db, pzErrmsg); |
9691 | } |
9692 | return rc; |
9693 | } |
9694 | |
9695 | /* |
9696 | ** Prepare an SQL statement using the results of a printf() formatting. |
9697 | */ |
9698 | static int idxPrintfPrepareStmt( |
9699 | sqlite3 *db, /* Database handle to compile against */ |
9700 | sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ |
9701 | char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ |
9702 | const char *zFmt, /* printf() format of SQL statement */ |
9703 | ... /* Trailing printf() arguments */ |
9704 | ){ |
9705 | va_list ap; |
9706 | int rc; |
9707 | char *zSql; |
9708 | va_start(ap, zFmt); |
9709 | zSql = sqlite3_vmprintf(zFmt, ap); |
9710 | if( zSql==0 ){ |
9711 | rc = SQLITE_NOMEM; |
9712 | }else{ |
9713 | rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql); |
9714 | sqlite3_free(zSql); |
9715 | } |
9716 | va_end(ap); |
9717 | return rc; |
9718 | } |
9719 | |
9720 | |
9721 | /************************************************************************* |
9722 | ** Beginning of virtual table implementation. |
9723 | */ |
9724 | typedef struct ExpertVtab ExpertVtab; |
9725 | struct ExpertVtab { |
9726 | sqlite3_vtab base; |
9727 | IdxTable *pTab; |
9728 | sqlite3expert *pExpert; |
9729 | }; |
9730 | |
9731 | typedef struct ExpertCsr ExpertCsr; |
9732 | struct ExpertCsr { |
9733 | sqlite3_vtab_cursor base; |
9734 | sqlite3_stmt *pData; |
9735 | }; |
9736 | |
9737 | static char *expertDequote(const char *zIn){ |
9738 | int n = STRLEN(zIn); |
9739 | char *zRet = sqlite3_malloc(n); |
9740 | |
9741 | assert( zIn[0]=='\'' ); |
9742 | assert( zIn[n-1]=='\'' ); |
9743 | |
9744 | if( zRet ){ |
9745 | int iOut = 0; |
9746 | int iIn = 0; |
9747 | for(iIn=1; iIn<(n-1); iIn++){ |
9748 | if( zIn[iIn]=='\'' ){ |
9749 | assert( zIn[iIn+1]=='\'' ); |
9750 | iIn++; |
9751 | } |
9752 | zRet[iOut++] = zIn[iIn]; |
9753 | } |
9754 | zRet[iOut] = '\0'; |
9755 | } |
9756 | |
9757 | return zRet; |
9758 | } |
9759 | |
9760 | /* |
9761 | ** This function is the implementation of both the xConnect and xCreate |
9762 | ** methods of the r-tree virtual table. |
9763 | ** |
9764 | ** argv[0] -> module name |
9765 | ** argv[1] -> database name |
9766 | ** argv[2] -> table name |
9767 | ** argv[...] -> column names... |
9768 | */ |
9769 | static int expertConnect( |
9770 | sqlite3 *db, |
9771 | void *pAux, |
9772 | int argc, const char *const*argv, |
9773 | sqlite3_vtab **ppVtab, |
9774 | char **pzErr |
9775 | ){ |
9776 | sqlite3expert *pExpert = (sqlite3expert*)pAux; |
9777 | ExpertVtab *p = 0; |
9778 | int rc; |
9779 | |
9780 | if( argc!=4 ){ |
9781 | *pzErr = sqlite3_mprintf("internal error!" ); |
9782 | rc = SQLITE_ERROR; |
9783 | }else{ |
9784 | char *zCreateTable = expertDequote(argv[3]); |
9785 | if( zCreateTable ){ |
9786 | rc = sqlite3_declare_vtab(db, zCreateTable); |
9787 | if( rc==SQLITE_OK ){ |
9788 | p = idxMalloc(&rc, sizeof(ExpertVtab)); |
9789 | } |
9790 | if( rc==SQLITE_OK ){ |
9791 | p->pExpert = pExpert; |
9792 | p->pTab = pExpert->pTable; |
9793 | assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 ); |
9794 | } |
9795 | sqlite3_free(zCreateTable); |
9796 | }else{ |
9797 | rc = SQLITE_NOMEM; |
9798 | } |
9799 | } |
9800 | |
9801 | *ppVtab = (sqlite3_vtab*)p; |
9802 | return rc; |
9803 | } |
9804 | |
9805 | static int expertDisconnect(sqlite3_vtab *pVtab){ |
9806 | ExpertVtab *p = (ExpertVtab*)pVtab; |
9807 | sqlite3_free(p); |
9808 | return SQLITE_OK; |
9809 | } |
9810 | |
9811 | static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ |
9812 | ExpertVtab *p = (ExpertVtab*)pVtab; |
9813 | int rc = SQLITE_OK; |
9814 | int n = 0; |
9815 | IdxScan *pScan; |
9816 | const int opmask = |
9817 | SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT | |
9818 | SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE | |
9819 | SQLITE_INDEX_CONSTRAINT_LE; |
9820 | |
9821 | pScan = idxMalloc(&rc, sizeof(IdxScan)); |
9822 | if( pScan ){ |
9823 | int i; |
9824 | |
9825 | /* Link the new scan object into the list */ |
9826 | pScan->pTab = p->pTab; |
9827 | pScan->pNextScan = p->pExpert->pScan; |
9828 | p->pExpert->pScan = pScan; |
9829 | |
9830 | /* Add the constraints to the IdxScan object */ |
9831 | for(i=0; i<pIdxInfo->nConstraint; i++){ |
9832 | struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; |
9833 | if( pCons->usable |
9834 | && pCons->iColumn>=0 |
9835 | && p->pTab->aCol[pCons->iColumn].iPk==0 |
9836 | && (pCons->op & opmask) |
9837 | ){ |
9838 | IdxConstraint *pNew; |
9839 | const char *zColl = sqlite3_vtab_collation(pIdxInfo, i); |
9840 | pNew = idxNewConstraint(&rc, zColl); |
9841 | if( pNew ){ |
9842 | pNew->iCol = pCons->iColumn; |
9843 | if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
9844 | pNew->pNext = pScan->pEq; |
9845 | pScan->pEq = pNew; |
9846 | }else{ |
9847 | pNew->bRange = 1; |
9848 | pNew->pNext = pScan->pRange; |
9849 | pScan->pRange = pNew; |
9850 | } |
9851 | } |
9852 | n++; |
9853 | pIdxInfo->aConstraintUsage[i].argvIndex = n; |
9854 | } |
9855 | } |
9856 | |
9857 | /* Add the ORDER BY to the IdxScan object */ |
9858 | for(i=pIdxInfo->nOrderBy-1; i>=0; i--){ |
9859 | int iCol = pIdxInfo->aOrderBy[i].iColumn; |
9860 | if( iCol>=0 ){ |
9861 | IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl); |
9862 | if( pNew ){ |
9863 | pNew->iCol = iCol; |
9864 | pNew->bDesc = pIdxInfo->aOrderBy[i].desc; |
9865 | pNew->pNext = pScan->pOrder; |
9866 | pNew->pLink = pScan->pOrder; |
9867 | pScan->pOrder = pNew; |
9868 | n++; |
9869 | } |
9870 | } |
9871 | } |
9872 | } |
9873 | |
9874 | pIdxInfo->estimatedCost = 1000000.0 / (n+1); |
9875 | return rc; |
9876 | } |
9877 | |
9878 | static int expertUpdate( |
9879 | sqlite3_vtab *pVtab, |
9880 | int nData, |
9881 | sqlite3_value **azData, |
9882 | sqlite_int64 *pRowid |
9883 | ){ |
9884 | (void)pVtab; |
9885 | (void)nData; |
9886 | (void)azData; |
9887 | (void)pRowid; |
9888 | return SQLITE_OK; |
9889 | } |
9890 | |
9891 | /* |
9892 | ** Virtual table module xOpen method. |
9893 | */ |
9894 | static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ |
9895 | int rc = SQLITE_OK; |
9896 | ExpertCsr *pCsr; |
9897 | (void)pVTab; |
9898 | pCsr = idxMalloc(&rc, sizeof(ExpertCsr)); |
9899 | *ppCursor = (sqlite3_vtab_cursor*)pCsr; |
9900 | return rc; |
9901 | } |
9902 | |
9903 | /* |
9904 | ** Virtual table module xClose method. |
9905 | */ |
9906 | static int expertClose(sqlite3_vtab_cursor *cur){ |
9907 | ExpertCsr *pCsr = (ExpertCsr*)cur; |
9908 | sqlite3_finalize(pCsr->pData); |
9909 | sqlite3_free(pCsr); |
9910 | return SQLITE_OK; |
9911 | } |
9912 | |
9913 | /* |
9914 | ** Virtual table module xEof method. |
9915 | ** |
9916 | ** Return non-zero if the cursor does not currently point to a valid |
9917 | ** record (i.e if the scan has finished), or zero otherwise. |
9918 | */ |
9919 | static int expertEof(sqlite3_vtab_cursor *cur){ |
9920 | ExpertCsr *pCsr = (ExpertCsr*)cur; |
9921 | return pCsr->pData==0; |
9922 | } |
9923 | |
9924 | /* |
9925 | ** Virtual table module xNext method. |
9926 | */ |
9927 | static int expertNext(sqlite3_vtab_cursor *cur){ |
9928 | ExpertCsr *pCsr = (ExpertCsr*)cur; |
9929 | int rc = SQLITE_OK; |
9930 | |
9931 | assert( pCsr->pData ); |
9932 | rc = sqlite3_step(pCsr->pData); |
9933 | if( rc!=SQLITE_ROW ){ |
9934 | rc = sqlite3_finalize(pCsr->pData); |
9935 | pCsr->pData = 0; |
9936 | }else{ |
9937 | rc = SQLITE_OK; |
9938 | } |
9939 | |
9940 | return rc; |
9941 | } |
9942 | |
9943 | /* |
9944 | ** Virtual table module xRowid method. |
9945 | */ |
9946 | static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
9947 | (void)cur; |
9948 | *pRowid = 0; |
9949 | return SQLITE_OK; |
9950 | } |
9951 | |
9952 | /* |
9953 | ** Virtual table module xColumn method. |
9954 | */ |
9955 | static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ |
9956 | ExpertCsr *pCsr = (ExpertCsr*)cur; |
9957 | sqlite3_value *pVal; |
9958 | pVal = sqlite3_column_value(pCsr->pData, i); |
9959 | if( pVal ){ |
9960 | sqlite3_result_value(ctx, pVal); |
9961 | } |
9962 | return SQLITE_OK; |
9963 | } |
9964 | |
9965 | /* |
9966 | ** Virtual table module xFilter method. |
9967 | */ |
9968 | static int expertFilter( |
9969 | sqlite3_vtab_cursor *cur, |
9970 | int idxNum, const char *idxStr, |
9971 | int argc, sqlite3_value **argv |
9972 | ){ |
9973 | ExpertCsr *pCsr = (ExpertCsr*)cur; |
9974 | ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab); |
9975 | sqlite3expert *pExpert = pVtab->pExpert; |
9976 | int rc; |
9977 | |
9978 | (void)idxNum; |
9979 | (void)idxStr; |
9980 | (void)argc; |
9981 | (void)argv; |
9982 | rc = sqlite3_finalize(pCsr->pData); |
9983 | pCsr->pData = 0; |
9984 | if( rc==SQLITE_OK ){ |
9985 | rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, |
9986 | "SELECT * FROM main.%Q WHERE sample()" , pVtab->pTab->zName |
9987 | ); |
9988 | } |
9989 | |
9990 | if( rc==SQLITE_OK ){ |
9991 | rc = expertNext(cur); |
9992 | } |
9993 | return rc; |
9994 | } |
9995 | |
9996 | static int idxRegisterVtab(sqlite3expert *p){ |
9997 | static sqlite3_module expertModule = { |
9998 | 2, /* iVersion */ |
9999 | expertConnect, /* xCreate - create a table */ |
10000 | expertConnect, /* xConnect - connect to an existing table */ |
10001 | expertBestIndex, /* xBestIndex - Determine search strategy */ |
10002 | expertDisconnect, /* xDisconnect - Disconnect from a table */ |
10003 | expertDisconnect, /* xDestroy - Drop a table */ |
10004 | expertOpen, /* xOpen - open a cursor */ |
10005 | expertClose, /* xClose - close a cursor */ |
10006 | expertFilter, /* xFilter - configure scan constraints */ |
10007 | expertNext, /* xNext - advance a cursor */ |
10008 | expertEof, /* xEof */ |
10009 | expertColumn, /* xColumn - read data */ |
10010 | expertRowid, /* xRowid - read data */ |
10011 | expertUpdate, /* xUpdate - write data */ |
10012 | 0, /* xBegin - begin transaction */ |
10013 | 0, /* xSync - sync transaction */ |
10014 | 0, /* xCommit - commit transaction */ |
10015 | 0, /* xRollback - rollback transaction */ |
10016 | 0, /* xFindFunction - function overloading */ |
10017 | 0, /* xRename - rename the table */ |
10018 | 0, /* xSavepoint */ |
10019 | 0, /* xRelease */ |
10020 | 0, /* xRollbackTo */ |
10021 | 0, /* xShadowName */ |
10022 | }; |
10023 | |
10024 | return sqlite3_create_module(p->dbv, "expert" , &expertModule, (void*)p); |
10025 | } |
10026 | /* |
10027 | ** End of virtual table implementation. |
10028 | *************************************************************************/ |
10029 | /* |
10030 | ** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function |
10031 | ** is called, set it to the return value of sqlite3_finalize() before |
10032 | ** returning. Otherwise, discard the sqlite3_finalize() return value. |
10033 | */ |
10034 | static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){ |
10035 | int rc = sqlite3_finalize(pStmt); |
10036 | if( *pRc==SQLITE_OK ) *pRc = rc; |
10037 | } |
10038 | |
10039 | /* |
10040 | ** Attempt to allocate an IdxTable structure corresponding to table zTab |
10041 | ** in the main database of connection db. If successful, set (*ppOut) to |
10042 | ** point to the new object and return SQLITE_OK. Otherwise, return an |
10043 | ** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be |
10044 | ** set to point to an error string. |
10045 | ** |
10046 | ** It is the responsibility of the caller to eventually free either the |
10047 | ** IdxTable object or error message using sqlite3_free(). |
10048 | */ |
10049 | static int idxGetTableInfo( |
10050 | sqlite3 *db, /* Database connection to read details from */ |
10051 | const char *zTab, /* Table name */ |
10052 | IdxTable **ppOut, /* OUT: New object (if successful) */ |
10053 | char **pzErrmsg /* OUT: Error message (if not) */ |
10054 | ){ |
10055 | sqlite3_stmt *p1 = 0; |
10056 | int nCol = 0; |
10057 | int nTab; |
10058 | int nByte; |
10059 | IdxTable *pNew = 0; |
10060 | int rc, rc2; |
10061 | char *pCsr = 0; |
10062 | int nPk = 0; |
10063 | |
10064 | *ppOut = 0; |
10065 | if( zTab==0 ) return SQLITE_ERROR; |
10066 | nTab = STRLEN(zTab); |
10067 | nByte = sizeof(IdxTable) + nTab + 1; |
10068 | rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q" , zTab); |
10069 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ |
10070 | const char *zCol = (const char*)sqlite3_column_text(p1, 1); |
10071 | const char *zColSeq = 0; |
10072 | if( zCol==0 ){ |
10073 | rc = SQLITE_ERROR; |
10074 | break; |
10075 | } |
10076 | nByte += 1 + STRLEN(zCol); |
10077 | rc = sqlite3_table_column_metadata( |
10078 | db, "main" , zTab, zCol, 0, &zColSeq, 0, 0, 0 |
10079 | ); |
10080 | if( zColSeq==0 ) zColSeq = "binary" ; |
10081 | nByte += 1 + STRLEN(zColSeq); |
10082 | nCol++; |
10083 | nPk += (sqlite3_column_int(p1, 5)>0); |
10084 | } |
10085 | rc2 = sqlite3_reset(p1); |
10086 | if( rc==SQLITE_OK ) rc = rc2; |
10087 | |
10088 | nByte += sizeof(IdxColumn) * nCol; |
10089 | if( rc==SQLITE_OK ){ |
10090 | pNew = idxMalloc(&rc, nByte); |
10091 | } |
10092 | if( rc==SQLITE_OK ){ |
10093 | pNew->aCol = (IdxColumn*)&pNew[1]; |
10094 | pNew->nCol = nCol; |
10095 | pCsr = (char*)&pNew->aCol[nCol]; |
10096 | } |
10097 | |
10098 | nCol = 0; |
10099 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ |
10100 | const char *zCol = (const char*)sqlite3_column_text(p1, 1); |
10101 | const char *zColSeq = 0; |
10102 | int nCopy; |
10103 | if( zCol==0 ) continue; |
10104 | nCopy = STRLEN(zCol) + 1; |
10105 | pNew->aCol[nCol].zName = pCsr; |
10106 | pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1); |
10107 | memcpy(pCsr, zCol, nCopy); |
10108 | pCsr += nCopy; |
10109 | |
10110 | rc = sqlite3_table_column_metadata( |
10111 | db, "main" , zTab, zCol, 0, &zColSeq, 0, 0, 0 |
10112 | ); |
10113 | if( rc==SQLITE_OK ){ |
10114 | if( zColSeq==0 ) zColSeq = "binary" ; |
10115 | nCopy = STRLEN(zColSeq) + 1; |
10116 | pNew->aCol[nCol].zColl = pCsr; |
10117 | memcpy(pCsr, zColSeq, nCopy); |
10118 | pCsr += nCopy; |
10119 | } |
10120 | |
10121 | nCol++; |
10122 | } |
10123 | idxFinalize(&rc, p1); |
10124 | |
10125 | if( rc!=SQLITE_OK ){ |
10126 | sqlite3_free(pNew); |
10127 | pNew = 0; |
10128 | }else if( ALWAYS(pNew!=0) ){ |
10129 | pNew->zName = pCsr; |
10130 | if( ALWAYS(pNew->zName!=0) ) memcpy(pNew->zName, zTab, nTab+1); |
10131 | } |
10132 | |
10133 | *ppOut = pNew; |
10134 | return rc; |
10135 | } |
10136 | |
10137 | /* |
10138 | ** This function is a no-op if *pRc is set to anything other than |
10139 | ** SQLITE_OK when it is called. |
10140 | ** |
10141 | ** If *pRc is initially set to SQLITE_OK, then the text specified by |
10142 | ** the printf() style arguments is appended to zIn and the result returned |
10143 | ** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on |
10144 | ** zIn before returning. |
10145 | */ |
10146 | static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){ |
10147 | va_list ap; |
10148 | char *zAppend = 0; |
10149 | char *zRet = 0; |
10150 | int nIn = zIn ? STRLEN(zIn) : 0; |
10151 | int nAppend = 0; |
10152 | va_start(ap, zFmt); |
10153 | if( *pRc==SQLITE_OK ){ |
10154 | zAppend = sqlite3_vmprintf(zFmt, ap); |
10155 | if( zAppend ){ |
10156 | nAppend = STRLEN(zAppend); |
10157 | zRet = (char*)sqlite3_malloc(nIn + nAppend + 1); |
10158 | } |
10159 | if( zAppend && zRet ){ |
10160 | if( nIn ) memcpy(zRet, zIn, nIn); |
10161 | memcpy(&zRet[nIn], zAppend, nAppend+1); |
10162 | }else{ |
10163 | sqlite3_free(zRet); |
10164 | zRet = 0; |
10165 | *pRc = SQLITE_NOMEM; |
10166 | } |
10167 | sqlite3_free(zAppend); |
10168 | sqlite3_free(zIn); |
10169 | } |
10170 | va_end(ap); |
10171 | return zRet; |
10172 | } |
10173 | |
10174 | /* |
10175 | ** Return true if zId must be quoted in order to use it as an SQL |
10176 | ** identifier, or false otherwise. |
10177 | */ |
10178 | static int idxIdentifierRequiresQuotes(const char *zId){ |
10179 | int i; |
10180 | int nId = STRLEN(zId); |
10181 | |
10182 | if( sqlite3_keyword_check(zId, nId) ) return 1; |
10183 | |
10184 | for(i=0; zId[i]; i++){ |
10185 | if( !(zId[i]=='_') |
10186 | && !(zId[i]>='0' && zId[i]<='9') |
10187 | && !(zId[i]>='a' && zId[i]<='z') |
10188 | && !(zId[i]>='A' && zId[i]<='Z') |
10189 | ){ |
10190 | return 1; |
10191 | } |
10192 | } |
10193 | return 0; |
10194 | } |
10195 | |
10196 | /* |
10197 | ** This function appends an index column definition suitable for constraint |
10198 | ** pCons to the string passed as zIn and returns the result. |
10199 | */ |
10200 | static char *idxAppendColDefn( |
10201 | int *pRc, /* IN/OUT: Error code */ |
10202 | char *zIn, /* Column defn accumulated so far */ |
10203 | IdxTable *pTab, /* Table index will be created on */ |
10204 | IdxConstraint *pCons |
10205 | ){ |
10206 | char *zRet = zIn; |
10207 | IdxColumn *p = &pTab->aCol[pCons->iCol]; |
10208 | if( zRet ) zRet = idxAppendText(pRc, zRet, ", " ); |
10209 | |
10210 | if( idxIdentifierRequiresQuotes(p->zName) ){ |
10211 | zRet = idxAppendText(pRc, zRet, "%Q" , p->zName); |
10212 | }else{ |
10213 | zRet = idxAppendText(pRc, zRet, "%s" , p->zName); |
10214 | } |
10215 | |
10216 | if( sqlite3_stricmp(p->zColl, pCons->zColl) ){ |
10217 | if( idxIdentifierRequiresQuotes(pCons->zColl) ){ |
10218 | zRet = idxAppendText(pRc, zRet, " COLLATE %Q" , pCons->zColl); |
10219 | }else{ |
10220 | zRet = idxAppendText(pRc, zRet, " COLLATE %s" , pCons->zColl); |
10221 | } |
10222 | } |
10223 | |
10224 | if( pCons->bDesc ){ |
10225 | zRet = idxAppendText(pRc, zRet, " DESC" ); |
10226 | } |
10227 | return zRet; |
10228 | } |
10229 | |
10230 | /* |
10231 | ** Search database dbm for an index compatible with the one idxCreateFromCons() |
10232 | ** would create from arguments pScan, pEq and pTail. If no error occurs and |
10233 | ** such an index is found, return non-zero. Or, if no such index is found, |
10234 | ** return zero. |
10235 | ** |
10236 | ** If an error occurs, set *pRc to an SQLite error code and return zero. |
10237 | */ |
10238 | static int idxFindCompatible( |
10239 | int *pRc, /* OUT: Error code */ |
10240 | sqlite3* dbm, /* Database to search */ |
10241 | IdxScan *pScan, /* Scan for table to search for index on */ |
10242 | IdxConstraint *pEq, /* List of == constraints */ |
10243 | IdxConstraint *pTail /* List of range constraints */ |
10244 | ){ |
10245 | const char *zTbl = pScan->pTab->zName; |
10246 | sqlite3_stmt *pIdxList = 0; |
10247 | IdxConstraint *pIter; |
10248 | int nEq = 0; /* Number of elements in pEq */ |
10249 | int rc; |
10250 | |
10251 | /* Count the elements in list pEq */ |
10252 | for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++; |
10253 | |
10254 | rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q" , zTbl); |
10255 | while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){ |
10256 | int bMatch = 1; |
10257 | IdxConstraint *pT = pTail; |
10258 | sqlite3_stmt *pInfo = 0; |
10259 | const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1); |
10260 | if( zIdx==0 ) continue; |
10261 | |
10262 | /* Zero the IdxConstraint.bFlag values in the pEq list */ |
10263 | for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0; |
10264 | |
10265 | rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q" , zIdx); |
10266 | while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){ |
10267 | int iIdx = sqlite3_column_int(pInfo, 0); |
10268 | int iCol = sqlite3_column_int(pInfo, 1); |
10269 | const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); |
10270 | |
10271 | if( iIdx<nEq ){ |
10272 | for(pIter=pEq; pIter; pIter=pIter->pLink){ |
10273 | if( pIter->bFlag ) continue; |
10274 | if( pIter->iCol!=iCol ) continue; |
10275 | if( sqlite3_stricmp(pIter->zColl, zColl) ) continue; |
10276 | pIter->bFlag = 1; |
10277 | break; |
10278 | } |
10279 | if( pIter==0 ){ |
10280 | bMatch = 0; |
10281 | break; |
10282 | } |
10283 | }else{ |
10284 | if( pT ){ |
10285 | if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){ |
10286 | bMatch = 0; |
10287 | break; |
10288 | } |
10289 | pT = pT->pLink; |
10290 | } |
10291 | } |
10292 | } |
10293 | idxFinalize(&rc, pInfo); |
10294 | |
10295 | if( rc==SQLITE_OK && bMatch ){ |
10296 | sqlite3_finalize(pIdxList); |
10297 | return 1; |
10298 | } |
10299 | } |
10300 | idxFinalize(&rc, pIdxList); |
10301 | |
10302 | *pRc = rc; |
10303 | return 0; |
10304 | } |
10305 | |
10306 | /* Callback for sqlite3_exec() with query with leading count(*) column. |
10307 | * The first argument is expected to be an int*, referent to be incremented |
10308 | * if that leading column is not exactly '0'. |
10309 | */ |
10310 | static int countNonzeros(void* pCount, int nc, |
10311 | char* azResults[], char* azColumns[]){ |
10312 | (void)azColumns; /* Suppress unused parameter warning */ |
10313 | if( nc>0 && (azResults[0][0]!='0' || azResults[0][1]!=0) ){ |
10314 | *((int *)pCount) += 1; |
10315 | } |
10316 | return 0; |
10317 | } |
10318 | |
10319 | static int idxCreateFromCons( |
10320 | sqlite3expert *p, |
10321 | IdxScan *pScan, |
10322 | IdxConstraint *pEq, |
10323 | IdxConstraint *pTail |
10324 | ){ |
10325 | sqlite3 *dbm = p->dbm; |
10326 | int rc = SQLITE_OK; |
10327 | if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){ |
10328 | IdxTable *pTab = pScan->pTab; |
10329 | char *zCols = 0; |
10330 | char *zIdx = 0; |
10331 | IdxConstraint *pCons; |
10332 | unsigned int h = 0; |
10333 | const char *zFmt; |
10334 | |
10335 | for(pCons=pEq; pCons; pCons=pCons->pLink){ |
10336 | zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); |
10337 | } |
10338 | for(pCons=pTail; pCons; pCons=pCons->pLink){ |
10339 | zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); |
10340 | } |
10341 | |
10342 | if( rc==SQLITE_OK ){ |
10343 | /* Hash the list of columns to come up with a name for the index */ |
10344 | const char *zTable = pScan->pTab->zName; |
10345 | int quoteTable = idxIdentifierRequiresQuotes(zTable); |
10346 | char *zName = 0; /* Index name */ |
10347 | int collisions = 0; |
10348 | do{ |
10349 | int i; |
10350 | char *zFind; |
10351 | for(i=0; zCols[i]; i++){ |
10352 | h += ((h<<3) + zCols[i]); |
10353 | } |
10354 | sqlite3_free(zName); |
10355 | zName = sqlite3_mprintf("%s_idx_%08x" , zTable, h); |
10356 | if( zName==0 ) break; |
10357 | /* Is is unique among table, view and index names? */ |
10358 | zFmt = "SELECT count(*) FROM sqlite_schema WHERE name=%Q" |
10359 | " AND type in ('index','table','view')" ; |
10360 | zFind = sqlite3_mprintf(zFmt, zName); |
10361 | i = 0; |
10362 | rc = sqlite3_exec(dbm, zFind, countNonzeros, &i, 0); |
10363 | assert(rc==SQLITE_OK); |
10364 | sqlite3_free(zFind); |
10365 | if( i==0 ){ |
10366 | collisions = 0; |
10367 | break; |
10368 | } |
10369 | ++collisions; |
10370 | }while( collisions<50 && zName!=0 ); |
10371 | if( collisions ){ |
10372 | /* This return means "Gave up trying to find a unique index name." */ |
10373 | rc = SQLITE_BUSY_TIMEOUT; |
10374 | }else if( zName==0 ){ |
10375 | rc = SQLITE_NOMEM; |
10376 | }else{ |
10377 | if( quoteTable ){ |
10378 | zFmt = "CREATE INDEX \"%w\" ON \"%w\"(%s)" ; |
10379 | }else{ |
10380 | zFmt = "CREATE INDEX %s ON %s(%s)" ; |
10381 | } |
10382 | zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols); |
10383 | if( !zIdx ){ |
10384 | rc = SQLITE_NOMEM; |
10385 | }else{ |
10386 | rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg); |
10387 | if( rc!=SQLITE_OK ){ |
10388 | rc = SQLITE_BUSY_TIMEOUT; |
10389 | }else{ |
10390 | idxHashAdd(&rc, &p->hIdx, zName, zIdx); |
10391 | } |
10392 | } |
10393 | sqlite3_free(zName); |
10394 | sqlite3_free(zIdx); |
10395 | } |
10396 | } |
10397 | |
10398 | sqlite3_free(zCols); |
10399 | } |
10400 | return rc; |
10401 | } |
10402 | |
10403 | /* |
10404 | ** Return true if list pList (linked by IdxConstraint.pLink) contains |
10405 | ** a constraint compatible with *p. Otherwise return false. |
10406 | */ |
10407 | static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){ |
10408 | IdxConstraint *pCmp; |
10409 | for(pCmp=pList; pCmp; pCmp=pCmp->pLink){ |
10410 | if( p->iCol==pCmp->iCol ) return 1; |
10411 | } |
10412 | return 0; |
10413 | } |
10414 | |
10415 | static int idxCreateFromWhere( |
10416 | sqlite3expert *p, |
10417 | IdxScan *pScan, /* Create indexes for this scan */ |
10418 | IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */ |
10419 | ){ |
10420 | IdxConstraint *p1 = 0; |
10421 | IdxConstraint *pCon; |
10422 | int rc; |
10423 | |
10424 | /* Gather up all the == constraints. */ |
10425 | for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){ |
10426 | if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ |
10427 | pCon->pLink = p1; |
10428 | p1 = pCon; |
10429 | } |
10430 | } |
10431 | |
10432 | /* Create an index using the == constraints collected above. And the |
10433 | ** range constraint/ORDER BY terms passed in by the caller, if any. */ |
10434 | rc = idxCreateFromCons(p, pScan, p1, pTail); |
10435 | |
10436 | /* If no range/ORDER BY passed by the caller, create a version of the |
10437 | ** index for each range constraint. */ |
10438 | if( pTail==0 ){ |
10439 | for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){ |
10440 | assert( pCon->pLink==0 ); |
10441 | if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ |
10442 | rc = idxCreateFromCons(p, pScan, p1, pCon); |
10443 | } |
10444 | } |
10445 | } |
10446 | |
10447 | return rc; |
10448 | } |
10449 | |
10450 | /* |
10451 | ** Create candidate indexes in database [dbm] based on the data in |
10452 | ** linked-list pScan. |
10453 | */ |
10454 | static int idxCreateCandidates(sqlite3expert *p){ |
10455 | int rc = SQLITE_OK; |
10456 | IdxScan *pIter; |
10457 | |
10458 | for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){ |
10459 | rc = idxCreateFromWhere(p, pIter, 0); |
10460 | if( rc==SQLITE_OK && pIter->pOrder ){ |
10461 | rc = idxCreateFromWhere(p, pIter, pIter->pOrder); |
10462 | } |
10463 | } |
10464 | |
10465 | return rc; |
10466 | } |
10467 | |
10468 | /* |
10469 | ** Free all elements of the linked list starting at pConstraint. |
10470 | */ |
10471 | static void idxConstraintFree(IdxConstraint *pConstraint){ |
10472 | IdxConstraint *pNext; |
10473 | IdxConstraint *p; |
10474 | |
10475 | for(p=pConstraint; p; p=pNext){ |
10476 | pNext = p->pNext; |
10477 | sqlite3_free(p); |
10478 | } |
10479 | } |
10480 | |
10481 | /* |
10482 | ** Free all elements of the linked list starting from pScan up until pLast |
10483 | ** (pLast is not freed). |
10484 | */ |
10485 | static void idxScanFree(IdxScan *pScan, IdxScan *pLast){ |
10486 | IdxScan *p; |
10487 | IdxScan *pNext; |
10488 | for(p=pScan; p!=pLast; p=pNext){ |
10489 | pNext = p->pNextScan; |
10490 | idxConstraintFree(p->pOrder); |
10491 | idxConstraintFree(p->pEq); |
10492 | idxConstraintFree(p->pRange); |
10493 | sqlite3_free(p); |
10494 | } |
10495 | } |
10496 | |
10497 | /* |
10498 | ** Free all elements of the linked list starting from pStatement up |
10499 | ** until pLast (pLast is not freed). |
10500 | */ |
10501 | static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){ |
10502 | IdxStatement *p; |
10503 | IdxStatement *pNext; |
10504 | for(p=pStatement; p!=pLast; p=pNext){ |
10505 | pNext = p->pNext; |
10506 | sqlite3_free(p->zEQP); |
10507 | sqlite3_free(p->zIdx); |
10508 | sqlite3_free(p); |
10509 | } |
10510 | } |
10511 | |
10512 | /* |
10513 | ** Free the linked list of IdxTable objects starting at pTab. |
10514 | */ |
10515 | static void idxTableFree(IdxTable *pTab){ |
10516 | IdxTable *pIter; |
10517 | IdxTable *pNext; |
10518 | for(pIter=pTab; pIter; pIter=pNext){ |
10519 | pNext = pIter->pNext; |
10520 | sqlite3_free(pIter); |
10521 | } |
10522 | } |
10523 | |
10524 | /* |
10525 | ** Free the linked list of IdxWrite objects starting at pTab. |
10526 | */ |
10527 | static void idxWriteFree(IdxWrite *pTab){ |
10528 | IdxWrite *pIter; |
10529 | IdxWrite *pNext; |
10530 | for(pIter=pTab; pIter; pIter=pNext){ |
10531 | pNext = pIter->pNext; |
10532 | sqlite3_free(pIter); |
10533 | } |
10534 | } |
10535 | |
10536 | |
10537 | |
10538 | /* |
10539 | ** This function is called after candidate indexes have been created. It |
10540 | ** runs all the queries to see which indexes they prefer, and populates |
10541 | ** IdxStatement.zIdx and IdxStatement.zEQP with the results. |
10542 | */ |
10543 | static int idxFindIndexes( |
10544 | sqlite3expert *p, |
10545 | char **pzErr /* OUT: Error message (sqlite3_malloc) */ |
10546 | ){ |
10547 | IdxStatement *pStmt; |
10548 | sqlite3 *dbm = p->dbm; |
10549 | int rc = SQLITE_OK; |
10550 | |
10551 | IdxHash hIdx; |
10552 | idxHashInit(&hIdx); |
10553 | |
10554 | for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){ |
10555 | IdxHashEntry *pEntry; |
10556 | sqlite3_stmt *pExplain = 0; |
10557 | idxHashClear(&hIdx); |
10558 | rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr, |
10559 | "EXPLAIN QUERY PLAN %s" , pStmt->zSql |
10560 | ); |
10561 | while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ |
10562 | /* int iId = sqlite3_column_int(pExplain, 0); */ |
10563 | /* int iParent = sqlite3_column_int(pExplain, 1); */ |
10564 | /* int iNotUsed = sqlite3_column_int(pExplain, 2); */ |
10565 | const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); |
10566 | int nDetail; |
10567 | int i; |
10568 | |
10569 | if( !zDetail ) continue; |
10570 | nDetail = STRLEN(zDetail); |
10571 | |
10572 | for(i=0; i<nDetail; i++){ |
10573 | const char *zIdx = 0; |
10574 | if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX " , 13)==0 ){ |
10575 | zIdx = &zDetail[i+13]; |
10576 | }else if( i+22<nDetail |
10577 | && memcmp(&zDetail[i], " USING COVERING INDEX " , 22)==0 |
10578 | ){ |
10579 | zIdx = &zDetail[i+22]; |
10580 | } |
10581 | if( zIdx ){ |
10582 | const char *zSql; |
10583 | int nIdx = 0; |
10584 | while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){ |
10585 | nIdx++; |
10586 | } |
10587 | zSql = idxHashSearch(&p->hIdx, zIdx, nIdx); |
10588 | if( zSql ){ |
10589 | idxHashAdd(&rc, &hIdx, zSql, 0); |
10590 | if( rc ) goto find_indexes_out; |
10591 | } |
10592 | break; |
10593 | } |
10594 | } |
10595 | |
10596 | if( zDetail[0]!='-' ){ |
10597 | pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n" , zDetail); |
10598 | } |
10599 | } |
10600 | |
10601 | for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ |
10602 | pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n" , pEntry->zKey); |
10603 | } |
10604 | |
10605 | idxFinalize(&rc, pExplain); |
10606 | } |
10607 | |
10608 | find_indexes_out: |
10609 | idxHashClear(&hIdx); |
10610 | return rc; |
10611 | } |
10612 | |
10613 | static int idxAuthCallback( |
10614 | void *pCtx, |
10615 | int eOp, |
10616 | const char *z3, |
10617 | const char *z4, |
10618 | const char *zDb, |
10619 | const char *zTrigger |
10620 | ){ |
10621 | int rc = SQLITE_OK; |
10622 | (void)z4; |
10623 | (void)zTrigger; |
10624 | if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){ |
10625 | if( sqlite3_stricmp(zDb, "main" )==0 ){ |
10626 | sqlite3expert *p = (sqlite3expert*)pCtx; |
10627 | IdxTable *pTab; |
10628 | for(pTab=p->pTable; pTab; pTab=pTab->pNext){ |
10629 | if( 0==sqlite3_stricmp(z3, pTab->zName) ) break; |
10630 | } |
10631 | if( pTab ){ |
10632 | IdxWrite *pWrite; |
10633 | for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){ |
10634 | if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break; |
10635 | } |
10636 | if( pWrite==0 ){ |
10637 | pWrite = idxMalloc(&rc, sizeof(IdxWrite)); |
10638 | if( rc==SQLITE_OK ){ |
10639 | pWrite->pTab = pTab; |
10640 | pWrite->eOp = eOp; |
10641 | pWrite->pNext = p->pWrite; |
10642 | p->pWrite = pWrite; |
10643 | } |
10644 | } |
10645 | } |
10646 | } |
10647 | } |
10648 | return rc; |
10649 | } |
10650 | |
10651 | static int idxProcessOneTrigger( |
10652 | sqlite3expert *p, |
10653 | IdxWrite *pWrite, |
10654 | char **pzErr |
10655 | ){ |
10656 | static const char *zInt = UNIQUE_TABLE_NAME; |
10657 | static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME; |
10658 | IdxTable *pTab = pWrite->pTab; |
10659 | const char *zTab = pTab->zName; |
10660 | const char *zSql = |
10661 | "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_schema " |
10662 | "WHERE tbl_name = %Q AND type IN ('table', 'trigger') " |
10663 | "ORDER BY type;" ; |
10664 | sqlite3_stmt *pSelect = 0; |
10665 | int rc = SQLITE_OK; |
10666 | char *zWrite = 0; |
10667 | |
10668 | /* Create the table and its triggers in the temp schema */ |
10669 | rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab); |
10670 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){ |
10671 | const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0); |
10672 | if( zCreate==0 ) continue; |
10673 | rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr); |
10674 | } |
10675 | idxFinalize(&rc, pSelect); |
10676 | |
10677 | /* Rename the table in the temp schema to zInt */ |
10678 | if( rc==SQLITE_OK ){ |
10679 | char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q" , zTab, zInt); |
10680 | if( z==0 ){ |
10681 | rc = SQLITE_NOMEM; |
10682 | }else{ |
10683 | rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr); |
10684 | sqlite3_free(z); |
10685 | } |
10686 | } |
10687 | |
10688 | switch( pWrite->eOp ){ |
10689 | case SQLITE_INSERT: { |
10690 | int i; |
10691 | zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(" , zInt); |
10692 | for(i=0; i<pTab->nCol; i++){ |
10693 | zWrite = idxAppendText(&rc, zWrite, "%s?" , i==0 ? "" : ", " ); |
10694 | } |
10695 | zWrite = idxAppendText(&rc, zWrite, ")" ); |
10696 | break; |
10697 | } |
10698 | case SQLITE_UPDATE: { |
10699 | int i; |
10700 | zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET " , zInt); |
10701 | for(i=0; i<pTab->nCol; i++){ |
10702 | zWrite = idxAppendText(&rc, zWrite, "%s%Q=?" , i==0 ? "" : ", " , |
10703 | pTab->aCol[i].zName |
10704 | ); |
10705 | } |
10706 | break; |
10707 | } |
10708 | default: { |
10709 | assert( pWrite->eOp==SQLITE_DELETE ); |
10710 | if( rc==SQLITE_OK ){ |
10711 | zWrite = sqlite3_mprintf("DELETE FROM %Q" , zInt); |
10712 | if( zWrite==0 ) rc = SQLITE_NOMEM; |
10713 | } |
10714 | } |
10715 | } |
10716 | |
10717 | if( rc==SQLITE_OK ){ |
10718 | sqlite3_stmt *pX = 0; |
10719 | rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0); |
10720 | idxFinalize(&rc, pX); |
10721 | if( rc!=SQLITE_OK ){ |
10722 | idxDatabaseError(p->dbv, pzErr); |
10723 | } |
10724 | } |
10725 | sqlite3_free(zWrite); |
10726 | |
10727 | if( rc==SQLITE_OK ){ |
10728 | rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr); |
10729 | } |
10730 | |
10731 | return rc; |
10732 | } |
10733 | |
10734 | static int idxProcessTriggers(sqlite3expert *p, char **pzErr){ |
10735 | int rc = SQLITE_OK; |
10736 | IdxWrite *pEnd = 0; |
10737 | IdxWrite *pFirst = p->pWrite; |
10738 | |
10739 | while( rc==SQLITE_OK && pFirst!=pEnd ){ |
10740 | IdxWrite *pIter; |
10741 | for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){ |
10742 | rc = idxProcessOneTrigger(p, pIter, pzErr); |
10743 | } |
10744 | pEnd = pFirst; |
10745 | pFirst = p->pWrite; |
10746 | } |
10747 | |
10748 | return rc; |
10749 | } |
10750 | |
10751 | |
10752 | static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ |
10753 | int rc = idxRegisterVtab(p); |
10754 | sqlite3_stmt *pSchema = 0; |
10755 | |
10756 | /* For each table in the main db schema: |
10757 | ** |
10758 | ** 1) Add an entry to the p->pTable list, and |
10759 | ** 2) Create the equivalent virtual table in dbv. |
10760 | */ |
10761 | rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg, |
10762 | "SELECT type, name, sql, 1 FROM sqlite_schema " |
10763 | "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' " |
10764 | " UNION ALL " |
10765 | "SELECT type, name, sql, 2 FROM sqlite_schema " |
10766 | "WHERE type = 'trigger'" |
10767 | " AND tbl_name IN(SELECT name FROM sqlite_schema WHERE type = 'view') " |
10768 | "ORDER BY 4, 1" |
10769 | ); |
10770 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){ |
10771 | const char *zType = (const char*)sqlite3_column_text(pSchema, 0); |
10772 | const char *zName = (const char*)sqlite3_column_text(pSchema, 1); |
10773 | const char *zSql = (const char*)sqlite3_column_text(pSchema, 2); |
10774 | |
10775 | if( zType==0 || zName==0 ) continue; |
10776 | if( zType[0]=='v' || zType[1]=='r' ){ |
10777 | if( zSql ) rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg); |
10778 | }else{ |
10779 | IdxTable *pTab; |
10780 | rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg); |
10781 | if( rc==SQLITE_OK ){ |
10782 | int i; |
10783 | char *zInner = 0; |
10784 | char *zOuter = 0; |
10785 | pTab->pNext = p->pTable; |
10786 | p->pTable = pTab; |
10787 | |
10788 | /* The statement the vtab will pass to sqlite3_declare_vtab() */ |
10789 | zInner = idxAppendText(&rc, 0, "CREATE TABLE x(" ); |
10790 | for(i=0; i<pTab->nCol; i++){ |
10791 | zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s" , |
10792 | (i==0 ? "" : ", " ), pTab->aCol[i].zName, pTab->aCol[i].zColl |
10793 | ); |
10794 | } |
10795 | zInner = idxAppendText(&rc, zInner, ")" ); |
10796 | |
10797 | /* The CVT statement to create the vtab */ |
10798 | zOuter = idxAppendText(&rc, 0, |
10799 | "CREATE VIRTUAL TABLE %Q USING expert(%Q)" , zName, zInner |
10800 | ); |
10801 | if( rc==SQLITE_OK ){ |
10802 | rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg); |
10803 | } |
10804 | sqlite3_free(zInner); |
10805 | sqlite3_free(zOuter); |
10806 | } |
10807 | } |
10808 | } |
10809 | idxFinalize(&rc, pSchema); |
10810 | return rc; |
10811 | } |
10812 | |
10813 | struct IdxSampleCtx { |
10814 | int iTarget; |
10815 | double target; /* Target nRet/nRow value */ |
10816 | double nRow; /* Number of rows seen */ |
10817 | double nRet; /* Number of rows returned */ |
10818 | }; |
10819 | |
10820 | static void idxSampleFunc( |
10821 | sqlite3_context *pCtx, |
10822 | int argc, |
10823 | sqlite3_value **argv |
10824 | ){ |
10825 | struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx); |
10826 | int bRet; |
10827 | |
10828 | (void)argv; |
10829 | assert( argc==0 ); |
10830 | if( p->nRow==0.0 ){ |
10831 | bRet = 1; |
10832 | }else{ |
10833 | bRet = (p->nRet / p->nRow) <= p->target; |
10834 | if( bRet==0 ){ |
10835 | unsigned short rnd; |
10836 | sqlite3_randomness(2, (void*)&rnd); |
10837 | bRet = ((int)rnd % 100) <= p->iTarget; |
10838 | } |
10839 | } |
10840 | |
10841 | sqlite3_result_int(pCtx, bRet); |
10842 | p->nRow += 1.0; |
10843 | p->nRet += (double)bRet; |
10844 | } |
10845 | |
10846 | struct IdxRemCtx { |
10847 | int nSlot; |
10848 | struct IdxRemSlot { |
10849 | int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */ |
10850 | i64 iVal; /* SQLITE_INTEGER value */ |
10851 | double rVal; /* SQLITE_FLOAT value */ |
10852 | int nByte; /* Bytes of space allocated at z */ |
10853 | int n; /* Size of buffer z */ |
10854 | char *z; /* SQLITE_TEXT/BLOB value */ |
10855 | } aSlot[1]; |
10856 | }; |
10857 | |
10858 | /* |
10859 | ** Implementation of scalar function rem(). |
10860 | */ |
10861 | static void idxRemFunc( |
10862 | sqlite3_context *pCtx, |
10863 | int argc, |
10864 | sqlite3_value **argv |
10865 | ){ |
10866 | struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx); |
10867 | struct IdxRemSlot *pSlot; |
10868 | int iSlot; |
10869 | assert( argc==2 ); |
10870 | |
10871 | iSlot = sqlite3_value_int(argv[0]); |
10872 | assert( iSlot<=p->nSlot ); |
10873 | pSlot = &p->aSlot[iSlot]; |
10874 | |
10875 | switch( pSlot->eType ){ |
10876 | case SQLITE_NULL: |
10877 | /* no-op */ |
10878 | break; |
10879 | |
10880 | case SQLITE_INTEGER: |
10881 | sqlite3_result_int64(pCtx, pSlot->iVal); |
10882 | break; |
10883 | |
10884 | case SQLITE_FLOAT: |
10885 | sqlite3_result_double(pCtx, pSlot->rVal); |
10886 | break; |
10887 | |
10888 | case SQLITE_BLOB: |
10889 | sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); |
10890 | break; |
10891 | |
10892 | case SQLITE_TEXT: |
10893 | sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); |
10894 | break; |
10895 | } |
10896 | |
10897 | pSlot->eType = sqlite3_value_type(argv[1]); |
10898 | switch( pSlot->eType ){ |
10899 | case SQLITE_NULL: |
10900 | /* no-op */ |
10901 | break; |
10902 | |
10903 | case SQLITE_INTEGER: |
10904 | pSlot->iVal = sqlite3_value_int64(argv[1]); |
10905 | break; |
10906 | |
10907 | case SQLITE_FLOAT: |
10908 | pSlot->rVal = sqlite3_value_double(argv[1]); |
10909 | break; |
10910 | |
10911 | case SQLITE_BLOB: |
10912 | case SQLITE_TEXT: { |
10913 | int nByte = sqlite3_value_bytes(argv[1]); |
10914 | const void *pData = 0; |
10915 | if( nByte>pSlot->nByte ){ |
10916 | char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2); |
10917 | if( zNew==0 ){ |
10918 | sqlite3_result_error_nomem(pCtx); |
10919 | return; |
10920 | } |
10921 | pSlot->nByte = nByte*2; |
10922 | pSlot->z = zNew; |
10923 | } |
10924 | pSlot->n = nByte; |
10925 | if( pSlot->eType==SQLITE_BLOB ){ |
10926 | pData = sqlite3_value_blob(argv[1]); |
10927 | if( pData ) memcpy(pSlot->z, pData, nByte); |
10928 | }else{ |
10929 | pData = sqlite3_value_text(argv[1]); |
10930 | memcpy(pSlot->z, pData, nByte); |
10931 | } |
10932 | break; |
10933 | } |
10934 | } |
10935 | } |
10936 | |
10937 | static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){ |
10938 | int rc = SQLITE_OK; |
10939 | const char *zMax = |
10940 | "SELECT max(i.seqno) FROM " |
10941 | " sqlite_schema AS s, " |
10942 | " pragma_index_list(s.name) AS l, " |
10943 | " pragma_index_info(l.name) AS i " |
10944 | "WHERE s.type = 'table'" ; |
10945 | sqlite3_stmt *pMax = 0; |
10946 | |
10947 | *pnMax = 0; |
10948 | rc = idxPrepareStmt(db, &pMax, pzErr, zMax); |
10949 | if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ |
10950 | *pnMax = sqlite3_column_int(pMax, 0) + 1; |
10951 | } |
10952 | idxFinalize(&rc, pMax); |
10953 | |
10954 | return rc; |
10955 | } |
10956 | |
10957 | static int idxPopulateOneStat1( |
10958 | sqlite3expert *p, |
10959 | sqlite3_stmt *pIndexXInfo, |
10960 | sqlite3_stmt *pWriteStat, |
10961 | const char *zTab, |
10962 | const char *zIdx, |
10963 | char **pzErr |
10964 | ){ |
10965 | char *zCols = 0; |
10966 | char *zOrder = 0; |
10967 | char *zQuery = 0; |
10968 | int nCol = 0; |
10969 | int i; |
10970 | sqlite3_stmt *pQuery = 0; |
10971 | int *aStat = 0; |
10972 | int rc = SQLITE_OK; |
10973 | |
10974 | assert( p->iSample>0 ); |
10975 | |
10976 | /* Formulate the query text */ |
10977 | sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); |
10978 | while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){ |
10979 | const char *zComma = zCols==0 ? "" : ", " ; |
10980 | const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); |
10981 | const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); |
10982 | zCols = idxAppendText(&rc, zCols, |
10983 | "%sx.%Q IS rem(%d, x.%Q) COLLATE %s" , zComma, zName, nCol, zName, zColl |
10984 | ); |
10985 | zOrder = idxAppendText(&rc, zOrder, "%s%d" , zComma, ++nCol); |
10986 | } |
10987 | sqlite3_reset(pIndexXInfo); |
10988 | if( rc==SQLITE_OK ){ |
10989 | if( p->iSample==100 ){ |
10990 | zQuery = sqlite3_mprintf( |
10991 | "SELECT %s FROM %Q x ORDER BY %s" , zCols, zTab, zOrder |
10992 | ); |
10993 | }else{ |
10994 | zQuery = sqlite3_mprintf( |
10995 | "SELECT %s FROM temp." UNIQUE_TABLE_NAME" x ORDER BY %s" , zCols, zOrder |
10996 | ); |
10997 | } |
10998 | } |
10999 | sqlite3_free(zCols); |
11000 | sqlite3_free(zOrder); |
11001 | |
11002 | /* Formulate the query text */ |
11003 | if( rc==SQLITE_OK ){ |
11004 | sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); |
11005 | rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery); |
11006 | } |
11007 | sqlite3_free(zQuery); |
11008 | |
11009 | if( rc==SQLITE_OK ){ |
11010 | aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1)); |
11011 | } |
11012 | if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ |
11013 | IdxHashEntry *pEntry; |
11014 | char *zStat = 0; |
11015 | for(i=0; i<=nCol; i++) aStat[i] = 1; |
11016 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ |
11017 | aStat[0]++; |
11018 | for(i=0; i<nCol; i++){ |
11019 | if( sqlite3_column_int(pQuery, i)==0 ) break; |
11020 | } |
11021 | for(/*no-op*/; i<nCol; i++){ |
11022 | aStat[i+1]++; |
11023 | } |
11024 | } |
11025 | |
11026 | if( rc==SQLITE_OK ){ |
11027 | int s0 = aStat[0]; |
11028 | zStat = sqlite3_mprintf("%d" , s0); |
11029 | if( zStat==0 ) rc = SQLITE_NOMEM; |
11030 | for(i=1; rc==SQLITE_OK && i<=nCol; i++){ |
11031 | zStat = idxAppendText(&rc, zStat, " %d" , (s0+aStat[i]/2) / aStat[i]); |
11032 | } |
11033 | } |
11034 | |
11035 | if( rc==SQLITE_OK ){ |
11036 | sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC); |
11037 | sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC); |
11038 | sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC); |
11039 | sqlite3_step(pWriteStat); |
11040 | rc = sqlite3_reset(pWriteStat); |
11041 | } |
11042 | |
11043 | pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx)); |
11044 | if( pEntry ){ |
11045 | assert( pEntry->zVal2==0 ); |
11046 | pEntry->zVal2 = zStat; |
11047 | }else{ |
11048 | sqlite3_free(zStat); |
11049 | } |
11050 | } |
11051 | sqlite3_free(aStat); |
11052 | idxFinalize(&rc, pQuery); |
11053 | |
11054 | return rc; |
11055 | } |
11056 | |
11057 | static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){ |
11058 | int rc; |
11059 | char *zSql; |
11060 | |
11061 | rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME,0,0,0); |
11062 | if( rc!=SQLITE_OK ) return rc; |
11063 | |
11064 | zSql = sqlite3_mprintf( |
11065 | "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q" , zTab |
11066 | ); |
11067 | if( zSql==0 ) return SQLITE_NOMEM; |
11068 | rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0); |
11069 | sqlite3_free(zSql); |
11070 | |
11071 | return rc; |
11072 | } |
11073 | |
11074 | /* |
11075 | ** This function is called as part of sqlite3_expert_analyze(). Candidate |
11076 | ** indexes have already been created in database sqlite3expert.dbm, this |
11077 | ** function populates sqlite_stat1 table in the same database. |
11078 | ** |
11079 | ** The stat1 data is generated by querying the |
11080 | */ |
11081 | static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ |
11082 | int rc = SQLITE_OK; |
11083 | int nMax =0; |
11084 | struct IdxRemCtx *pCtx = 0; |
11085 | struct IdxSampleCtx samplectx; |
11086 | int i; |
11087 | i64 iPrev = -100000; |
11088 | sqlite3_stmt *pAllIndex = 0; |
11089 | sqlite3_stmt *pIndexXInfo = 0; |
11090 | sqlite3_stmt *pWrite = 0; |
11091 | |
11092 | const char *zAllIndex = |
11093 | "SELECT s.rowid, s.name, l.name FROM " |
11094 | " sqlite_schema AS s, " |
11095 | " pragma_index_list(s.name) AS l " |
11096 | "WHERE s.type = 'table'" ; |
11097 | const char *zIndexXInfo = |
11098 | "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key" ; |
11099 | const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)" ; |
11100 | |
11101 | /* If iSample==0, no sqlite_stat1 data is required. */ |
11102 | if( p->iSample==0 ) return SQLITE_OK; |
11103 | |
11104 | rc = idxLargestIndex(p->dbm, &nMax, pzErr); |
11105 | if( nMax<=0 || rc!=SQLITE_OK ) return rc; |
11106 | |
11107 | rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1" , 0, 0, 0); |
11108 | |
11109 | if( rc==SQLITE_OK ){ |
11110 | int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax); |
11111 | pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte); |
11112 | } |
11113 | |
11114 | if( rc==SQLITE_OK ){ |
11115 | sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); |
11116 | rc = sqlite3_create_function( |
11117 | dbrem, "rem" , 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 |
11118 | ); |
11119 | } |
11120 | if( rc==SQLITE_OK ){ |
11121 | rc = sqlite3_create_function( |
11122 | p->db, "sample" , 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 |
11123 | ); |
11124 | } |
11125 | |
11126 | if( rc==SQLITE_OK ){ |
11127 | pCtx->nSlot = nMax+1; |
11128 | rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex); |
11129 | } |
11130 | if( rc==SQLITE_OK ){ |
11131 | rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo); |
11132 | } |
11133 | if( rc==SQLITE_OK ){ |
11134 | rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite); |
11135 | } |
11136 | |
11137 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){ |
11138 | i64 iRowid = sqlite3_column_int64(pAllIndex, 0); |
11139 | const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1); |
11140 | const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2); |
11141 | if( zTab==0 || zIdx==0 ) continue; |
11142 | if( p->iSample<100 && iPrev!=iRowid ){ |
11143 | samplectx.target = (double)p->iSample / 100.0; |
11144 | samplectx.iTarget = p->iSample; |
11145 | samplectx.nRow = 0.0; |
11146 | samplectx.nRet = 0.0; |
11147 | rc = idxBuildSampleTable(p, zTab); |
11148 | if( rc!=SQLITE_OK ) break; |
11149 | } |
11150 | rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr); |
11151 | iPrev = iRowid; |
11152 | } |
11153 | if( rc==SQLITE_OK && p->iSample<100 ){ |
11154 | rc = sqlite3_exec(p->dbv, |
11155 | "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0 |
11156 | ); |
11157 | } |
11158 | |
11159 | idxFinalize(&rc, pAllIndex); |
11160 | idxFinalize(&rc, pIndexXInfo); |
11161 | idxFinalize(&rc, pWrite); |
11162 | |
11163 | if( pCtx ){ |
11164 | for(i=0; i<pCtx->nSlot; i++){ |
11165 | sqlite3_free(pCtx->aSlot[i].z); |
11166 | } |
11167 | sqlite3_free(pCtx); |
11168 | } |
11169 | |
11170 | if( rc==SQLITE_OK ){ |
11171 | rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema" , 0, 0, 0); |
11172 | } |
11173 | |
11174 | sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME,0,0,0); |
11175 | return rc; |
11176 | } |
11177 | |
11178 | /* |
11179 | ** Allocate a new sqlite3expert object. |
11180 | */ |
11181 | sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ |
11182 | int rc = SQLITE_OK; |
11183 | sqlite3expert *pNew; |
11184 | |
11185 | pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert)); |
11186 | |
11187 | /* Open two in-memory databases to work with. The "vtab database" (dbv) |
11188 | ** will contain a virtual table corresponding to each real table in |
11189 | ** the user database schema, and a copy of each view. It is used to |
11190 | ** collect information regarding the WHERE, ORDER BY and other clauses |
11191 | ** of the user's query. |
11192 | */ |
11193 | if( rc==SQLITE_OK ){ |
11194 | pNew->db = db; |
11195 | pNew->iSample = 100; |
11196 | rc = sqlite3_open(":memory:" , &pNew->dbv); |
11197 | } |
11198 | if( rc==SQLITE_OK ){ |
11199 | rc = sqlite3_open(":memory:" , &pNew->dbm); |
11200 | if( rc==SQLITE_OK ){ |
11201 | sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0); |
11202 | } |
11203 | } |
11204 | |
11205 | |
11206 | /* Copy the entire schema of database [db] into [dbm]. */ |
11207 | if( rc==SQLITE_OK ){ |
11208 | sqlite3_stmt *pSql = 0; |
11209 | rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, |
11210 | "SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'" |
11211 | " AND sql NOT LIKE 'CREATE VIRTUAL %%'" |
11212 | ); |
11213 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ |
11214 | const char *zSql = (const char*)sqlite3_column_text(pSql, 0); |
11215 | if( zSql ) rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg); |
11216 | } |
11217 | idxFinalize(&rc, pSql); |
11218 | } |
11219 | |
11220 | /* Create the vtab schema */ |
11221 | if( rc==SQLITE_OK ){ |
11222 | rc = idxCreateVtabSchema(pNew, pzErrmsg); |
11223 | } |
11224 | |
11225 | /* Register the auth callback with dbv */ |
11226 | if( rc==SQLITE_OK ){ |
11227 | sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew); |
11228 | } |
11229 | |
11230 | /* If an error has occurred, free the new object and reutrn NULL. Otherwise, |
11231 | ** return the new sqlite3expert handle. */ |
11232 | if( rc!=SQLITE_OK ){ |
11233 | sqlite3_expert_destroy(pNew); |
11234 | pNew = 0; |
11235 | } |
11236 | return pNew; |
11237 | } |
11238 | |
11239 | /* |
11240 | ** Configure an sqlite3expert object. |
11241 | */ |
11242 | int sqlite3_expert_config(sqlite3expert *p, int op, ...){ |
11243 | int rc = SQLITE_OK; |
11244 | va_list ap; |
11245 | va_start(ap, op); |
11246 | switch( op ){ |
11247 | case EXPERT_CONFIG_SAMPLE: { |
11248 | int iVal = va_arg(ap, int); |
11249 | if( iVal<0 ) iVal = 0; |
11250 | if( iVal>100 ) iVal = 100; |
11251 | p->iSample = iVal; |
11252 | break; |
11253 | } |
11254 | default: |
11255 | rc = SQLITE_NOTFOUND; |
11256 | break; |
11257 | } |
11258 | |
11259 | va_end(ap); |
11260 | return rc; |
11261 | } |
11262 | |
11263 | /* |
11264 | ** Add an SQL statement to the analysis. |
11265 | */ |
11266 | int sqlite3_expert_sql( |
11267 | sqlite3expert *p, /* From sqlite3_expert_new() */ |
11268 | const char *zSql, /* SQL statement to add */ |
11269 | char **pzErr /* OUT: Error message (if any) */ |
11270 | ){ |
11271 | IdxScan *pScanOrig = p->pScan; |
11272 | IdxStatement *pStmtOrig = p->pStatement; |
11273 | int rc = SQLITE_OK; |
11274 | const char *zStmt = zSql; |
11275 | |
11276 | if( p->bRun ) return SQLITE_MISUSE; |
11277 | |
11278 | while( rc==SQLITE_OK && zStmt && zStmt[0] ){ |
11279 | sqlite3_stmt *pStmt = 0; |
11280 | rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); |
11281 | if( rc==SQLITE_OK ){ |
11282 | if( pStmt ){ |
11283 | IdxStatement *pNew; |
11284 | const char *z = sqlite3_sql(pStmt); |
11285 | int n = STRLEN(z); |
11286 | pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1); |
11287 | if( rc==SQLITE_OK ){ |
11288 | pNew->zSql = (char*)&pNew[1]; |
11289 | memcpy(pNew->zSql, z, n+1); |
11290 | pNew->pNext = p->pStatement; |
11291 | if( p->pStatement ) pNew->iId = p->pStatement->iId+1; |
11292 | p->pStatement = pNew; |
11293 | } |
11294 | sqlite3_finalize(pStmt); |
11295 | } |
11296 | }else{ |
11297 | idxDatabaseError(p->dbv, pzErr); |
11298 | } |
11299 | } |
11300 | |
11301 | if( rc!=SQLITE_OK ){ |
11302 | idxScanFree(p->pScan, pScanOrig); |
11303 | idxStatementFree(p->pStatement, pStmtOrig); |
11304 | p->pScan = pScanOrig; |
11305 | p->pStatement = pStmtOrig; |
11306 | } |
11307 | |
11308 | return rc; |
11309 | } |
11310 | |
11311 | int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){ |
11312 | int rc; |
11313 | IdxHashEntry *pEntry; |
11314 | |
11315 | /* Do trigger processing to collect any extra IdxScan structures */ |
11316 | rc = idxProcessTriggers(p, pzErr); |
11317 | |
11318 | /* Create candidate indexes within the in-memory database file */ |
11319 | if( rc==SQLITE_OK ){ |
11320 | rc = idxCreateCandidates(p); |
11321 | }else if ( rc==SQLITE_BUSY_TIMEOUT ){ |
11322 | if( pzErr ) |
11323 | *pzErr = sqlite3_mprintf("Cannot find a unique index name to propose." ); |
11324 | return rc; |
11325 | } |
11326 | |
11327 | /* Generate the stat1 data */ |
11328 | if( rc==SQLITE_OK ){ |
11329 | rc = idxPopulateStat1(p, pzErr); |
11330 | } |
11331 | |
11332 | /* Formulate the EXPERT_REPORT_CANDIDATES text */ |
11333 | for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ |
11334 | p->zCandidates = idxAppendText(&rc, p->zCandidates, |
11335 | "%s;%s%s\n" , pEntry->zVal, |
11336 | pEntry->zVal2 ? " -- stat1: " : "" , pEntry->zVal2 |
11337 | ); |
11338 | } |
11339 | |
11340 | /* Figure out which of the candidate indexes are preferred by the query |
11341 | ** planner and report the results to the user. */ |
11342 | if( rc==SQLITE_OK ){ |
11343 | rc = idxFindIndexes(p, pzErr); |
11344 | } |
11345 | |
11346 | if( rc==SQLITE_OK ){ |
11347 | p->bRun = 1; |
11348 | } |
11349 | return rc; |
11350 | } |
11351 | |
11352 | /* |
11353 | ** Return the total number of statements that have been added to this |
11354 | ** sqlite3expert using sqlite3_expert_sql(). |
11355 | */ |
11356 | int sqlite3_expert_count(sqlite3expert *p){ |
11357 | int nRet = 0; |
11358 | if( p->pStatement ) nRet = p->pStatement->iId+1; |
11359 | return nRet; |
11360 | } |
11361 | |
11362 | /* |
11363 | ** Return a component of the report. |
11364 | */ |
11365 | const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){ |
11366 | const char *zRet = 0; |
11367 | IdxStatement *pStmt; |
11368 | |
11369 | if( p->bRun==0 ) return 0; |
11370 | for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext); |
11371 | switch( eReport ){ |
11372 | case EXPERT_REPORT_SQL: |
11373 | if( pStmt ) zRet = pStmt->zSql; |
11374 | break; |
11375 | case EXPERT_REPORT_INDEXES: |
11376 | if( pStmt ) zRet = pStmt->zIdx; |
11377 | break; |
11378 | case EXPERT_REPORT_PLAN: |
11379 | if( pStmt ) zRet = pStmt->zEQP; |
11380 | break; |
11381 | case EXPERT_REPORT_CANDIDATES: |
11382 | zRet = p->zCandidates; |
11383 | break; |
11384 | } |
11385 | return zRet; |
11386 | } |
11387 | |
11388 | /* |
11389 | ** Free an sqlite3expert object. |
11390 | */ |
11391 | void sqlite3_expert_destroy(sqlite3expert *p){ |
11392 | if( p ){ |
11393 | sqlite3_close(p->dbm); |
11394 | sqlite3_close(p->dbv); |
11395 | idxScanFree(p->pScan, 0); |
11396 | idxStatementFree(p->pStatement, 0); |
11397 | idxTableFree(p->pTable); |
11398 | idxWriteFree(p->pWrite); |
11399 | idxHashClear(&p->hIdx); |
11400 | sqlite3_free(p->zCandidates); |
11401 | sqlite3_free(p); |
11402 | } |
11403 | } |
11404 | |
11405 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
11406 | |
11407 | /************************* End ../ext/expert/sqlite3expert.c ********************/ |
11408 | |
11409 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) |
11410 | #define SQLITE_SHELL_HAVE_RECOVER 1 |
11411 | #else |
11412 | #define SQLITE_SHELL_HAVE_RECOVER 0 |
11413 | #endif |
11414 | #if SQLITE_SHELL_HAVE_RECOVER |
11415 | /************************* Begin ../ext/recover/dbdata.c ******************/ |
11416 | /* |
11417 | ** 2019-04-17 |
11418 | ** |
11419 | ** The author disclaims copyright to this source code. In place of |
11420 | ** a legal notice, here is a blessing: |
11421 | ** |
11422 | ** May you do good and not evil. |
11423 | ** May you find forgiveness for yourself and forgive others. |
11424 | ** May you share freely, never taking more than you give. |
11425 | ** |
11426 | ****************************************************************************** |
11427 | ** |
11428 | ** This file contains an implementation of two eponymous virtual tables, |
11429 | ** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the |
11430 | ** "sqlite_dbpage" eponymous virtual table be available. |
11431 | ** |
11432 | ** SQLITE_DBDATA: |
11433 | ** sqlite_dbdata is used to extract data directly from a database b-tree |
11434 | ** page and its associated overflow pages, bypassing the b-tree layer. |
11435 | ** The table schema is equivalent to: |
11436 | ** |
11437 | ** CREATE TABLE sqlite_dbdata( |
11438 | ** pgno INTEGER, |
11439 | ** cell INTEGER, |
11440 | ** field INTEGER, |
11441 | ** value ANY, |
11442 | ** schema TEXT HIDDEN |
11443 | ** ); |
11444 | ** |
11445 | ** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE |
11446 | ** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND |
11447 | ** "schema". |
11448 | ** |
11449 | ** Each page of the database is inspected. If it cannot be interpreted as |
11450 | ** a b-tree page, or if it is a b-tree page containing 0 entries, the |
11451 | ** sqlite_dbdata table contains no rows for that page. Otherwise, the |
11452 | ** table contains one row for each field in the record associated with |
11453 | ** each cell on the page. For intkey b-trees, the key value is stored in |
11454 | ** field -1. |
11455 | ** |
11456 | ** For example, for the database: |
11457 | ** |
11458 | ** CREATE TABLE t1(a, b); -- root page is page 2 |
11459 | ** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five'); |
11460 | ** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten'); |
11461 | ** |
11462 | ** the sqlite_dbdata table contains, as well as from entries related to |
11463 | ** page 1, content equivalent to: |
11464 | ** |
11465 | ** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES |
11466 | ** (2, 0, -1, 5 ), |
11467 | ** (2, 0, 0, 'v' ), |
11468 | ** (2, 0, 1, 'five'), |
11469 | ** (2, 1, -1, 10 ), |
11470 | ** (2, 1, 0, 'x' ), |
11471 | ** (2, 1, 1, 'ten' ); |
11472 | ** |
11473 | ** If database corruption is encountered, this module does not report an |
11474 | ** error. Instead, it attempts to extract as much data as possible and |
11475 | ** ignores the corruption. |
11476 | ** |
11477 | ** SQLITE_DBPTR: |
11478 | ** The sqlite_dbptr table has the following schema: |
11479 | ** |
11480 | ** CREATE TABLE sqlite_dbptr( |
11481 | ** pgno INTEGER, |
11482 | ** child INTEGER, |
11483 | ** schema TEXT HIDDEN |
11484 | ** ); |
11485 | ** |
11486 | ** It contains one entry for each b-tree pointer between a parent and |
11487 | ** child page in the database. |
11488 | */ |
11489 | |
11490 | #if !defined(SQLITEINT_H) |
11491 | /* #include "sqlite3ext.h" */ |
11492 | |
11493 | /* typedef unsigned char u8; */ |
11494 | /* typedef unsigned int u32; */ |
11495 | |
11496 | #endif |
11497 | SQLITE_EXTENSION_INIT1 |
11498 | #include <string.h> |
11499 | #include <assert.h> |
11500 | |
11501 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
11502 | |
11503 | #define DBDATA_PADDING_BYTES 100 |
11504 | |
11505 | typedef struct DbdataTable DbdataTable; |
11506 | typedef struct DbdataCursor DbdataCursor; |
11507 | |
11508 | /* Cursor object */ |
11509 | struct DbdataCursor { |
11510 | sqlite3_vtab_cursor base; /* Base class. Must be first */ |
11511 | sqlite3_stmt *pStmt; /* For fetching database pages */ |
11512 | |
11513 | int iPgno; /* Current page number */ |
11514 | u8 *aPage; /* Buffer containing page */ |
11515 | int nPage; /* Size of aPage[] in bytes */ |
11516 | int nCell; /* Number of cells on aPage[] */ |
11517 | int iCell; /* Current cell number */ |
11518 | int bOnePage; /* True to stop after one page */ |
11519 | int szDb; |
11520 | sqlite3_int64 iRowid; |
11521 | |
11522 | /* Only for the sqlite_dbdata table */ |
11523 | u8 *pRec; /* Buffer containing current record */ |
11524 | sqlite3_int64 nRec; /* Size of pRec[] in bytes */ |
11525 | sqlite3_int64 nHdr; /* Size of header in bytes */ |
11526 | int iField; /* Current field number */ |
11527 | u8 *pHdrPtr; |
11528 | u8 *pPtr; |
11529 | u32 enc; /* Text encoding */ |
11530 | |
11531 | sqlite3_int64 iIntkey; /* Integer key value */ |
11532 | }; |
11533 | |
11534 | /* Table object */ |
11535 | struct DbdataTable { |
11536 | sqlite3_vtab base; /* Base class. Must be first */ |
11537 | sqlite3 *db; /* The database connection */ |
11538 | sqlite3_stmt *pStmt; /* For fetching database pages */ |
11539 | int bPtr; /* True for sqlite3_dbptr table */ |
11540 | }; |
11541 | |
11542 | /* Column and schema definitions for sqlite_dbdata */ |
11543 | #define DBDATA_COLUMN_PGNO 0 |
11544 | #define DBDATA_COLUMN_CELL 1 |
11545 | #define DBDATA_COLUMN_FIELD 2 |
11546 | #define DBDATA_COLUMN_VALUE 3 |
11547 | #define DBDATA_COLUMN_SCHEMA 4 |
11548 | #define DBDATA_SCHEMA \ |
11549 | "CREATE TABLE x(" \ |
11550 | " pgno INTEGER," \ |
11551 | " cell INTEGER," \ |
11552 | " field INTEGER," \ |
11553 | " value ANY," \ |
11554 | " schema TEXT HIDDEN" \ |
11555 | ")" |
11556 | |
11557 | /* Column and schema definitions for sqlite_dbptr */ |
11558 | #define DBPTR_COLUMN_PGNO 0 |
11559 | #define DBPTR_COLUMN_CHILD 1 |
11560 | #define DBPTR_COLUMN_SCHEMA 2 |
11561 | #define DBPTR_SCHEMA \ |
11562 | "CREATE TABLE x(" \ |
11563 | " pgno INTEGER," \ |
11564 | " child INTEGER," \ |
11565 | " schema TEXT HIDDEN" \ |
11566 | ")" |
11567 | |
11568 | /* |
11569 | ** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual |
11570 | ** table. |
11571 | */ |
11572 | static int dbdataConnect( |
11573 | sqlite3 *db, |
11574 | void *pAux, |
11575 | int argc, const char *const*argv, |
11576 | sqlite3_vtab **ppVtab, |
11577 | char **pzErr |
11578 | ){ |
11579 | DbdataTable *pTab = 0; |
11580 | int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA); |
11581 | |
11582 | if( rc==SQLITE_OK ){ |
11583 | pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable)); |
11584 | if( pTab==0 ){ |
11585 | rc = SQLITE_NOMEM; |
11586 | }else{ |
11587 | memset(pTab, 0, sizeof(DbdataTable)); |
11588 | pTab->db = db; |
11589 | pTab->bPtr = (pAux!=0); |
11590 | } |
11591 | } |
11592 | |
11593 | *ppVtab = (sqlite3_vtab*)pTab; |
11594 | return rc; |
11595 | } |
11596 | |
11597 | /* |
11598 | ** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table. |
11599 | */ |
11600 | static int dbdataDisconnect(sqlite3_vtab *pVtab){ |
11601 | DbdataTable *pTab = (DbdataTable*)pVtab; |
11602 | if( pTab ){ |
11603 | sqlite3_finalize(pTab->pStmt); |
11604 | sqlite3_free(pVtab); |
11605 | } |
11606 | return SQLITE_OK; |
11607 | } |
11608 | |
11609 | /* |
11610 | ** This function interprets two types of constraints: |
11611 | ** |
11612 | ** schema=? |
11613 | ** pgno=? |
11614 | ** |
11615 | ** If neither are present, idxNum is set to 0. If schema=? is present, |
11616 | ** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit |
11617 | ** in idxNum is set. |
11618 | ** |
11619 | ** If both parameters are present, schema is in position 0 and pgno in |
11620 | ** position 1. |
11621 | */ |
11622 | static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){ |
11623 | DbdataTable *pTab = (DbdataTable*)tab; |
11624 | int i; |
11625 | int iSchema = -1; |
11626 | int iPgno = -1; |
11627 | int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA); |
11628 | |
11629 | for(i=0; i<pIdx->nConstraint; i++){ |
11630 | struct sqlite3_index_constraint *p = &pIdx->aConstraint[i]; |
11631 | if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ |
11632 | if( p->iColumn==colSchema ){ |
11633 | if( p->usable==0 ) return SQLITE_CONSTRAINT; |
11634 | iSchema = i; |
11635 | } |
11636 | if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){ |
11637 | iPgno = i; |
11638 | } |
11639 | } |
11640 | } |
11641 | |
11642 | if( iSchema>=0 ){ |
11643 | pIdx->aConstraintUsage[iSchema].argvIndex = 1; |
11644 | pIdx->aConstraintUsage[iSchema].omit = 1; |
11645 | } |
11646 | if( iPgno>=0 ){ |
11647 | pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0); |
11648 | pIdx->aConstraintUsage[iPgno].omit = 1; |
11649 | pIdx->estimatedCost = 100; |
11650 | pIdx->estimatedRows = 50; |
11651 | |
11652 | if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){ |
11653 | int iCol = pIdx->aOrderBy[0].iColumn; |
11654 | if( pIdx->nOrderBy==1 ){ |
11655 | pIdx->orderByConsumed = (iCol==0 || iCol==1); |
11656 | }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){ |
11657 | pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1); |
11658 | } |
11659 | } |
11660 | |
11661 | }else{ |
11662 | pIdx->estimatedCost = 100000000; |
11663 | pIdx->estimatedRows = 1000000000; |
11664 | } |
11665 | pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00); |
11666 | return SQLITE_OK; |
11667 | } |
11668 | |
11669 | /* |
11670 | ** Open a new sqlite_dbdata or sqlite_dbptr cursor. |
11671 | */ |
11672 | static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ |
11673 | DbdataCursor *pCsr; |
11674 | |
11675 | pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor)); |
11676 | if( pCsr==0 ){ |
11677 | return SQLITE_NOMEM; |
11678 | }else{ |
11679 | memset(pCsr, 0, sizeof(DbdataCursor)); |
11680 | pCsr->base.pVtab = pVTab; |
11681 | } |
11682 | |
11683 | *ppCursor = (sqlite3_vtab_cursor *)pCsr; |
11684 | return SQLITE_OK; |
11685 | } |
11686 | |
11687 | /* |
11688 | ** Restore a cursor object to the state it was in when first allocated |
11689 | ** by dbdataOpen(). |
11690 | */ |
11691 | static void dbdataResetCursor(DbdataCursor *pCsr){ |
11692 | DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab); |
11693 | if( pTab->pStmt==0 ){ |
11694 | pTab->pStmt = pCsr->pStmt; |
11695 | }else{ |
11696 | sqlite3_finalize(pCsr->pStmt); |
11697 | } |
11698 | pCsr->pStmt = 0; |
11699 | pCsr->iPgno = 1; |
11700 | pCsr->iCell = 0; |
11701 | pCsr->iField = 0; |
11702 | pCsr->bOnePage = 0; |
11703 | sqlite3_free(pCsr->aPage); |
11704 | sqlite3_free(pCsr->pRec); |
11705 | pCsr->pRec = 0; |
11706 | pCsr->aPage = 0; |
11707 | } |
11708 | |
11709 | /* |
11710 | ** Close an sqlite_dbdata or sqlite_dbptr cursor. |
11711 | */ |
11712 | static int dbdataClose(sqlite3_vtab_cursor *pCursor){ |
11713 | DbdataCursor *pCsr = (DbdataCursor*)pCursor; |
11714 | dbdataResetCursor(pCsr); |
11715 | sqlite3_free(pCsr); |
11716 | return SQLITE_OK; |
11717 | } |
11718 | |
11719 | /* |
11720 | ** Utility methods to decode 16 and 32-bit big-endian unsigned integers. |
11721 | */ |
11722 | static u32 get_uint16(unsigned char *a){ |
11723 | return (a[0]<<8)|a[1]; |
11724 | } |
11725 | static u32 get_uint32(unsigned char *a){ |
11726 | return ((u32)a[0]<<24) |
11727 | | ((u32)a[1]<<16) |
11728 | | ((u32)a[2]<<8) |
11729 | | ((u32)a[3]); |
11730 | } |
11731 | |
11732 | /* |
11733 | ** Load page pgno from the database via the sqlite_dbpage virtual table. |
11734 | ** If successful, set (*ppPage) to point to a buffer containing the page |
11735 | ** data, (*pnPage) to the size of that buffer in bytes and return |
11736 | ** SQLITE_OK. In this case it is the responsibility of the caller to |
11737 | ** eventually free the buffer using sqlite3_free(). |
11738 | ** |
11739 | ** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and |
11740 | ** return an SQLite error code. |
11741 | */ |
11742 | static int dbdataLoadPage( |
11743 | DbdataCursor *pCsr, /* Cursor object */ |
11744 | u32 pgno, /* Page number of page to load */ |
11745 | u8 **ppPage, /* OUT: pointer to page buffer */ |
11746 | int *pnPage /* OUT: Size of (*ppPage) in bytes */ |
11747 | ){ |
11748 | int rc2; |
11749 | int rc = SQLITE_OK; |
11750 | sqlite3_stmt *pStmt = pCsr->pStmt; |
11751 | |
11752 | *ppPage = 0; |
11753 | *pnPage = 0; |
11754 | if( pgno>0 ){ |
11755 | sqlite3_bind_int64(pStmt, 2, pgno); |
11756 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
11757 | int nCopy = sqlite3_column_bytes(pStmt, 0); |
11758 | if( nCopy>0 ){ |
11759 | u8 *pPage; |
11760 | pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES); |
11761 | if( pPage==0 ){ |
11762 | rc = SQLITE_NOMEM; |
11763 | }else{ |
11764 | const u8 *pCopy = sqlite3_column_blob(pStmt, 0); |
11765 | memcpy(pPage, pCopy, nCopy); |
11766 | memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES); |
11767 | } |
11768 | *ppPage = pPage; |
11769 | *pnPage = nCopy; |
11770 | } |
11771 | } |
11772 | rc2 = sqlite3_reset(pStmt); |
11773 | if( rc==SQLITE_OK ) rc = rc2; |
11774 | } |
11775 | |
11776 | return rc; |
11777 | } |
11778 | |
11779 | /* |
11780 | ** Read a varint. Put the value in *pVal and return the number of bytes. |
11781 | */ |
11782 | static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){ |
11783 | sqlite3_uint64 u = 0; |
11784 | int i; |
11785 | for(i=0; i<8; i++){ |
11786 | u = (u<<7) + (z[i]&0x7f); |
11787 | if( (z[i]&0x80)==0 ){ *pVal = (sqlite3_int64)u; return i+1; } |
11788 | } |
11789 | u = (u<<8) + (z[i]&0xff); |
11790 | *pVal = (sqlite3_int64)u; |
11791 | return 9; |
11792 | } |
11793 | |
11794 | /* |
11795 | ** Like dbdataGetVarint(), but set the output to 0 if it is less than 0 |
11796 | ** or greater than 0xFFFFFFFF. This can be used for all varints in an |
11797 | ** SQLite database except for key values in intkey tables. |
11798 | */ |
11799 | static int dbdataGetVarintU32(const u8 *z, sqlite3_int64 *pVal){ |
11800 | sqlite3_int64 val; |
11801 | int nRet = dbdataGetVarint(z, &val); |
11802 | if( val<0 || val>0xFFFFFFFF ) val = 0; |
11803 | *pVal = val; |
11804 | return nRet; |
11805 | } |
11806 | |
11807 | /* |
11808 | ** Return the number of bytes of space used by an SQLite value of type |
11809 | ** eType. |
11810 | */ |
11811 | static int dbdataValueBytes(int eType){ |
11812 | switch( eType ){ |
11813 | case 0: case 8: case 9: |
11814 | case 10: case 11: |
11815 | return 0; |
11816 | case 1: |
11817 | return 1; |
11818 | case 2: |
11819 | return 2; |
11820 | case 3: |
11821 | return 3; |
11822 | case 4: |
11823 | return 4; |
11824 | case 5: |
11825 | return 6; |
11826 | case 6: |
11827 | case 7: |
11828 | return 8; |
11829 | default: |
11830 | if( eType>0 ){ |
11831 | return ((eType-12) / 2); |
11832 | } |
11833 | return 0; |
11834 | } |
11835 | } |
11836 | |
11837 | /* |
11838 | ** Load a value of type eType from buffer pData and use it to set the |
11839 | ** result of context object pCtx. |
11840 | */ |
11841 | static void dbdataValue( |
11842 | sqlite3_context *pCtx, |
11843 | u32 enc, |
11844 | int eType, |
11845 | u8 *pData, |
11846 | sqlite3_int64 nData |
11847 | ){ |
11848 | if( eType>=0 && dbdataValueBytes(eType)<=nData ){ |
11849 | switch( eType ){ |
11850 | case 0: |
11851 | case 10: |
11852 | case 11: |
11853 | sqlite3_result_null(pCtx); |
11854 | break; |
11855 | |
11856 | case 8: |
11857 | sqlite3_result_int(pCtx, 0); |
11858 | break; |
11859 | case 9: |
11860 | sqlite3_result_int(pCtx, 1); |
11861 | break; |
11862 | |
11863 | case 1: case 2: case 3: case 4: case 5: case 6: case 7: { |
11864 | sqlite3_uint64 v = (signed char)pData[0]; |
11865 | pData++; |
11866 | switch( eType ){ |
11867 | case 7: |
11868 | case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; |
11869 | case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; |
11870 | case 4: v = (v<<8) + pData[0]; pData++; |
11871 | case 3: v = (v<<8) + pData[0]; pData++; |
11872 | case 2: v = (v<<8) + pData[0]; pData++; |
11873 | } |
11874 | |
11875 | if( eType==7 ){ |
11876 | double r; |
11877 | memcpy(&r, &v, sizeof(r)); |
11878 | sqlite3_result_double(pCtx, r); |
11879 | }else{ |
11880 | sqlite3_result_int64(pCtx, (sqlite3_int64)v); |
11881 | } |
11882 | break; |
11883 | } |
11884 | |
11885 | default: { |
11886 | int n = ((eType-12) / 2); |
11887 | if( eType % 2 ){ |
11888 | switch( enc ){ |
11889 | #ifndef SQLITE_OMIT_UTF16 |
11890 | case SQLITE_UTF16BE: |
11891 | sqlite3_result_text16be(pCtx, (void*)pData, n, SQLITE_TRANSIENT); |
11892 | break; |
11893 | case SQLITE_UTF16LE: |
11894 | sqlite3_result_text16le(pCtx, (void*)pData, n, SQLITE_TRANSIENT); |
11895 | break; |
11896 | #endif |
11897 | default: |
11898 | sqlite3_result_text(pCtx, (char*)pData, n, SQLITE_TRANSIENT); |
11899 | break; |
11900 | } |
11901 | }else{ |
11902 | sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); |
11903 | } |
11904 | } |
11905 | } |
11906 | } |
11907 | } |
11908 | |
11909 | /* |
11910 | ** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry. |
11911 | */ |
11912 | static int dbdataNext(sqlite3_vtab_cursor *pCursor){ |
11913 | DbdataCursor *pCsr = (DbdataCursor*)pCursor; |
11914 | DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; |
11915 | |
11916 | pCsr->iRowid++; |
11917 | while( 1 ){ |
11918 | int rc; |
11919 | int iOff = (pCsr->iPgno==1 ? 100 : 0); |
11920 | int bNextPage = 0; |
11921 | |
11922 | if( pCsr->aPage==0 ){ |
11923 | while( 1 ){ |
11924 | if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK; |
11925 | rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage); |
11926 | if( rc!=SQLITE_OK ) return rc; |
11927 | if( pCsr->aPage ) break; |
11928 | if( pCsr->bOnePage ) return SQLITE_OK; |
11929 | pCsr->iPgno++; |
11930 | } |
11931 | pCsr->iCell = pTab->bPtr ? -2 : 0; |
11932 | pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]); |
11933 | } |
11934 | |
11935 | if( pTab->bPtr ){ |
11936 | if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){ |
11937 | pCsr->iCell = pCsr->nCell; |
11938 | } |
11939 | pCsr->iCell++; |
11940 | if( pCsr->iCell>=pCsr->nCell ){ |
11941 | sqlite3_free(pCsr->aPage); |
11942 | pCsr->aPage = 0; |
11943 | if( pCsr->bOnePage ) return SQLITE_OK; |
11944 | pCsr->iPgno++; |
11945 | }else{ |
11946 | return SQLITE_OK; |
11947 | } |
11948 | }else{ |
11949 | /* If there is no record loaded, load it now. */ |
11950 | if( pCsr->pRec==0 ){ |
11951 | int bHasRowid = 0; |
11952 | int nPointer = 0; |
11953 | sqlite3_int64 nPayload = 0; |
11954 | sqlite3_int64 nHdr = 0; |
11955 | int iHdr; |
11956 | int U, X; |
11957 | int nLocal; |
11958 | |
11959 | switch( pCsr->aPage[iOff] ){ |
11960 | case 0x02: |
11961 | nPointer = 4; |
11962 | break; |
11963 | case 0x0a: |
11964 | break; |
11965 | case 0x0d: |
11966 | bHasRowid = 1; |
11967 | break; |
11968 | default: |
11969 | /* This is not a b-tree page with records on it. Continue. */ |
11970 | pCsr->iCell = pCsr->nCell; |
11971 | break; |
11972 | } |
11973 | |
11974 | if( pCsr->iCell>=pCsr->nCell ){ |
11975 | bNextPage = 1; |
11976 | }else{ |
11977 | |
11978 | iOff += 8 + nPointer + pCsr->iCell*2; |
11979 | if( iOff>pCsr->nPage ){ |
11980 | bNextPage = 1; |
11981 | }else{ |
11982 | iOff = get_uint16(&pCsr->aPage[iOff]); |
11983 | } |
11984 | |
11985 | /* For an interior node cell, skip past the child-page number */ |
11986 | iOff += nPointer; |
11987 | |
11988 | /* Load the "byte of payload including overflow" field */ |
11989 | if( bNextPage || iOff>pCsr->nPage ){ |
11990 | bNextPage = 1; |
11991 | }else{ |
11992 | iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload); |
11993 | } |
11994 | |
11995 | /* If this is a leaf intkey cell, load the rowid */ |
11996 | if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){ |
11997 | iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey); |
11998 | } |
11999 | |
12000 | /* Figure out how much data to read from the local page */ |
12001 | U = pCsr->nPage; |
12002 | if( bHasRowid ){ |
12003 | X = U-35; |
12004 | }else{ |
12005 | X = ((U-12)*64/255)-23; |
12006 | } |
12007 | if( nPayload<=X ){ |
12008 | nLocal = nPayload; |
12009 | }else{ |
12010 | int M, K; |
12011 | M = ((U-12)*32/255)-23; |
12012 | K = M+((nPayload-M)%(U-4)); |
12013 | if( K<=X ){ |
12014 | nLocal = K; |
12015 | }else{ |
12016 | nLocal = M; |
12017 | } |
12018 | } |
12019 | |
12020 | if( bNextPage || nLocal+iOff>pCsr->nPage ){ |
12021 | bNextPage = 1; |
12022 | }else{ |
12023 | |
12024 | /* Allocate space for payload. And a bit more to catch small buffer |
12025 | ** overruns caused by attempting to read a varint or similar from |
12026 | ** near the end of a corrupt record. */ |
12027 | pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES); |
12028 | if( pCsr->pRec==0 ) return SQLITE_NOMEM; |
12029 | memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES); |
12030 | pCsr->nRec = nPayload; |
12031 | |
12032 | /* Load the nLocal bytes of payload */ |
12033 | memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal); |
12034 | iOff += nLocal; |
12035 | |
12036 | /* Load content from overflow pages */ |
12037 | if( nPayload>nLocal ){ |
12038 | sqlite3_int64 nRem = nPayload - nLocal; |
12039 | u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); |
12040 | while( nRem>0 ){ |
12041 | u8 *aOvfl = 0; |
12042 | int nOvfl = 0; |
12043 | int nCopy; |
12044 | rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl); |
12045 | assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage ); |
12046 | if( rc!=SQLITE_OK ) return rc; |
12047 | if( aOvfl==0 ) break; |
12048 | |
12049 | nCopy = U-4; |
12050 | if( nCopy>nRem ) nCopy = nRem; |
12051 | memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); |
12052 | nRem -= nCopy; |
12053 | |
12054 | pgnoOvfl = get_uint32(aOvfl); |
12055 | sqlite3_free(aOvfl); |
12056 | } |
12057 | } |
12058 | |
12059 | iHdr = dbdataGetVarintU32(pCsr->pRec, &nHdr); |
12060 | if( nHdr>nPayload ) nHdr = 0; |
12061 | pCsr->nHdr = nHdr; |
12062 | pCsr->pHdrPtr = &pCsr->pRec[iHdr]; |
12063 | pCsr->pPtr = &pCsr->pRec[pCsr->nHdr]; |
12064 | pCsr->iField = (bHasRowid ? -1 : 0); |
12065 | } |
12066 | } |
12067 | }else{ |
12068 | pCsr->iField++; |
12069 | if( pCsr->iField>0 ){ |
12070 | sqlite3_int64 iType; |
12071 | if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){ |
12072 | bNextPage = 1; |
12073 | }else{ |
12074 | pCsr->pHdrPtr += dbdataGetVarintU32(pCsr->pHdrPtr, &iType); |
12075 | pCsr->pPtr += dbdataValueBytes(iType); |
12076 | } |
12077 | } |
12078 | } |
12079 | |
12080 | if( bNextPage ){ |
12081 | sqlite3_free(pCsr->aPage); |
12082 | sqlite3_free(pCsr->pRec); |
12083 | pCsr->aPage = 0; |
12084 | pCsr->pRec = 0; |
12085 | if( pCsr->bOnePage ) return SQLITE_OK; |
12086 | pCsr->iPgno++; |
12087 | }else{ |
12088 | if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){ |
12089 | return SQLITE_OK; |
12090 | } |
12091 | |
12092 | /* Advance to the next cell. The next iteration of the loop will load |
12093 | ** the record and so on. */ |
12094 | sqlite3_free(pCsr->pRec); |
12095 | pCsr->pRec = 0; |
12096 | pCsr->iCell++; |
12097 | } |
12098 | } |
12099 | } |
12100 | |
12101 | assert( !"can't get here" ); |
12102 | return SQLITE_OK; |
12103 | } |
12104 | |
12105 | /* |
12106 | ** Return true if the cursor is at EOF. |
12107 | */ |
12108 | static int dbdataEof(sqlite3_vtab_cursor *pCursor){ |
12109 | DbdataCursor *pCsr = (DbdataCursor*)pCursor; |
12110 | return pCsr->aPage==0; |
12111 | } |
12112 | |
12113 | /* |
12114 | ** Return true if nul-terminated string zSchema ends in "()". Or false |
12115 | ** otherwise. |
12116 | */ |
12117 | static int dbdataIsFunction(const char *zSchema){ |
12118 | size_t n = strlen(zSchema); |
12119 | if( n>2 && zSchema[n-2]=='(' && zSchema[n-1]==')' ){ |
12120 | return (int)n-2; |
12121 | } |
12122 | return 0; |
12123 | } |
12124 | |
12125 | /* |
12126 | ** Determine the size in pages of database zSchema (where zSchema is |
12127 | ** "main", "temp" or the name of an attached database) and set |
12128 | ** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise, |
12129 | ** an SQLite error code. |
12130 | */ |
12131 | static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){ |
12132 | DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab; |
12133 | char *zSql = 0; |
12134 | int rc, rc2; |
12135 | int nFunc = 0; |
12136 | sqlite3_stmt *pStmt = 0; |
12137 | |
12138 | if( (nFunc = dbdataIsFunction(zSchema))>0 ){ |
12139 | zSql = sqlite3_mprintf("SELECT %.*s(0)" , nFunc, zSchema); |
12140 | }else{ |
12141 | zSql = sqlite3_mprintf("PRAGMA %Q.page_count" , zSchema); |
12142 | } |
12143 | if( zSql==0 ) return SQLITE_NOMEM; |
12144 | |
12145 | rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0); |
12146 | sqlite3_free(zSql); |
12147 | if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ |
12148 | pCsr->szDb = sqlite3_column_int(pStmt, 0); |
12149 | } |
12150 | rc2 = sqlite3_finalize(pStmt); |
12151 | if( rc==SQLITE_OK ) rc = rc2; |
12152 | return rc; |
12153 | } |
12154 | |
12155 | /* |
12156 | ** Attempt to figure out the encoding of the database by retrieving page 1 |
12157 | ** and inspecting the header field. If successful, set the pCsr->enc variable |
12158 | ** and return SQLITE_OK. Otherwise, return an SQLite error code. |
12159 | */ |
12160 | static int dbdataGetEncoding(DbdataCursor *pCsr){ |
12161 | int rc = SQLITE_OK; |
12162 | int nPg1 = 0; |
12163 | u8 *aPg1 = 0; |
12164 | rc = dbdataLoadPage(pCsr, 1, &aPg1, &nPg1); |
12165 | assert( rc!=SQLITE_OK || nPg1==0 || nPg1>=512 ); |
12166 | if( rc==SQLITE_OK && nPg1>0 ){ |
12167 | pCsr->enc = get_uint32(&aPg1[56]); |
12168 | } |
12169 | sqlite3_free(aPg1); |
12170 | return rc; |
12171 | } |
12172 | |
12173 | |
12174 | /* |
12175 | ** xFilter method for sqlite_dbdata and sqlite_dbptr. |
12176 | */ |
12177 | static int dbdataFilter( |
12178 | sqlite3_vtab_cursor *pCursor, |
12179 | int idxNum, const char *idxStr, |
12180 | int argc, sqlite3_value **argv |
12181 | ){ |
12182 | DbdataCursor *pCsr = (DbdataCursor*)pCursor; |
12183 | DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; |
12184 | int rc = SQLITE_OK; |
12185 | const char *zSchema = "main" ; |
12186 | |
12187 | dbdataResetCursor(pCsr); |
12188 | assert( pCsr->iPgno==1 ); |
12189 | if( idxNum & 0x01 ){ |
12190 | zSchema = (const char*)sqlite3_value_text(argv[0]); |
12191 | if( zSchema==0 ) zSchema = "" ; |
12192 | } |
12193 | if( idxNum & 0x02 ){ |
12194 | pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]); |
12195 | pCsr->bOnePage = 1; |
12196 | }else{ |
12197 | rc = dbdataDbsize(pCsr, zSchema); |
12198 | } |
12199 | |
12200 | if( rc==SQLITE_OK ){ |
12201 | int nFunc = 0; |
12202 | if( pTab->pStmt ){ |
12203 | pCsr->pStmt = pTab->pStmt; |
12204 | pTab->pStmt = 0; |
12205 | }else if( (nFunc = dbdataIsFunction(zSchema))>0 ){ |
12206 | char *zSql = sqlite3_mprintf("SELECT %.*s(?2)" , nFunc, zSchema); |
12207 | if( zSql==0 ){ |
12208 | rc = SQLITE_NOMEM; |
12209 | }else{ |
12210 | rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); |
12211 | sqlite3_free(zSql); |
12212 | } |
12213 | }else{ |
12214 | rc = sqlite3_prepare_v2(pTab->db, |
12215 | "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?" , -1, |
12216 | &pCsr->pStmt, 0 |
12217 | ); |
12218 | } |
12219 | } |
12220 | if( rc==SQLITE_OK ){ |
12221 | rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT); |
12222 | }else{ |
12223 | pTab->base.zErrMsg = sqlite3_mprintf("%s" , sqlite3_errmsg(pTab->db)); |
12224 | } |
12225 | |
12226 | /* Try to determine the encoding of the db by inspecting the header |
12227 | ** field on page 1. */ |
12228 | if( rc==SQLITE_OK ){ |
12229 | rc = dbdataGetEncoding(pCsr); |
12230 | } |
12231 | |
12232 | if( rc==SQLITE_OK ){ |
12233 | rc = dbdataNext(pCursor); |
12234 | } |
12235 | return rc; |
12236 | } |
12237 | |
12238 | /* |
12239 | ** Return a column for the sqlite_dbdata or sqlite_dbptr table. |
12240 | */ |
12241 | static int dbdataColumn( |
12242 | sqlite3_vtab_cursor *pCursor, |
12243 | sqlite3_context *ctx, |
12244 | int i |
12245 | ){ |
12246 | DbdataCursor *pCsr = (DbdataCursor*)pCursor; |
12247 | DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; |
12248 | if( pTab->bPtr ){ |
12249 | switch( i ){ |
12250 | case DBPTR_COLUMN_PGNO: |
12251 | sqlite3_result_int64(ctx, pCsr->iPgno); |
12252 | break; |
12253 | case DBPTR_COLUMN_CHILD: { |
12254 | int iOff = pCsr->iPgno==1 ? 100 : 0; |
12255 | if( pCsr->iCell<0 ){ |
12256 | iOff += 8; |
12257 | }else{ |
12258 | iOff += 12 + pCsr->iCell*2; |
12259 | if( iOff>pCsr->nPage ) return SQLITE_OK; |
12260 | iOff = get_uint16(&pCsr->aPage[iOff]); |
12261 | } |
12262 | if( iOff<=pCsr->nPage ){ |
12263 | sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff])); |
12264 | } |
12265 | break; |
12266 | } |
12267 | } |
12268 | }else{ |
12269 | switch( i ){ |
12270 | case DBDATA_COLUMN_PGNO: |
12271 | sqlite3_result_int64(ctx, pCsr->iPgno); |
12272 | break; |
12273 | case DBDATA_COLUMN_CELL: |
12274 | sqlite3_result_int(ctx, pCsr->iCell); |
12275 | break; |
12276 | case DBDATA_COLUMN_FIELD: |
12277 | sqlite3_result_int(ctx, pCsr->iField); |
12278 | break; |
12279 | case DBDATA_COLUMN_VALUE: { |
12280 | if( pCsr->iField<0 ){ |
12281 | sqlite3_result_int64(ctx, pCsr->iIntkey); |
12282 | }else if( &pCsr->pRec[pCsr->nRec] >= pCsr->pPtr ){ |
12283 | sqlite3_int64 iType; |
12284 | dbdataGetVarintU32(pCsr->pHdrPtr, &iType); |
12285 | dbdataValue( |
12286 | ctx, pCsr->enc, iType, pCsr->pPtr, |
12287 | &pCsr->pRec[pCsr->nRec] - pCsr->pPtr |
12288 | ); |
12289 | } |
12290 | break; |
12291 | } |
12292 | } |
12293 | } |
12294 | return SQLITE_OK; |
12295 | } |
12296 | |
12297 | /* |
12298 | ** Return the rowid for an sqlite_dbdata or sqlite_dptr table. |
12299 | */ |
12300 | static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ |
12301 | DbdataCursor *pCsr = (DbdataCursor*)pCursor; |
12302 | *pRowid = pCsr->iRowid; |
12303 | return SQLITE_OK; |
12304 | } |
12305 | |
12306 | |
12307 | /* |
12308 | ** Invoke this routine to register the "sqlite_dbdata" virtual table module |
12309 | */ |
12310 | static int sqlite3DbdataRegister(sqlite3 *db){ |
12311 | static sqlite3_module dbdata_module = { |
12312 | 0, /* iVersion */ |
12313 | 0, /* xCreate */ |
12314 | dbdataConnect, /* xConnect */ |
12315 | dbdataBestIndex, /* xBestIndex */ |
12316 | dbdataDisconnect, /* xDisconnect */ |
12317 | 0, /* xDestroy */ |
12318 | dbdataOpen, /* xOpen - open a cursor */ |
12319 | dbdataClose, /* xClose - close a cursor */ |
12320 | dbdataFilter, /* xFilter - configure scan constraints */ |
12321 | dbdataNext, /* xNext - advance a cursor */ |
12322 | dbdataEof, /* xEof - check for end of scan */ |
12323 | dbdataColumn, /* xColumn - read data */ |
12324 | dbdataRowid, /* xRowid - read data */ |
12325 | 0, /* xUpdate */ |
12326 | 0, /* xBegin */ |
12327 | 0, /* xSync */ |
12328 | 0, /* xCommit */ |
12329 | 0, /* xRollback */ |
12330 | 0, /* xFindMethod */ |
12331 | 0, /* xRename */ |
12332 | 0, /* xSavepoint */ |
12333 | 0, /* xRelease */ |
12334 | 0, /* xRollbackTo */ |
12335 | 0 /* xShadowName */ |
12336 | }; |
12337 | |
12338 | int rc = sqlite3_create_module(db, "sqlite_dbdata" , &dbdata_module, 0); |
12339 | if( rc==SQLITE_OK ){ |
12340 | rc = sqlite3_create_module(db, "sqlite_dbptr" , &dbdata_module, (void*)1); |
12341 | } |
12342 | return rc; |
12343 | } |
12344 | |
12345 | #ifdef _WIN32 |
12346 | |
12347 | #endif |
12348 | int sqlite3_dbdata_init( |
12349 | sqlite3 *db, |
12350 | char **pzErrMsg, |
12351 | const sqlite3_api_routines *pApi |
12352 | ){ |
12353 | SQLITE_EXTENSION_INIT2(pApi); |
12354 | return sqlite3DbdataRegister(db); |
12355 | } |
12356 | |
12357 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
12358 | |
12359 | /************************* End ../ext/recover/dbdata.c ********************/ |
12360 | /************************* Begin ../ext/recover/sqlite3recover.h ******************/ |
12361 | /* |
12362 | ** 2022-08-27 |
12363 | ** |
12364 | ** The author disclaims copyright to this source code. In place of |
12365 | ** a legal notice, here is a blessing: |
12366 | ** |
12367 | ** May you do good and not evil. |
12368 | ** May you find forgiveness for yourself and forgive others. |
12369 | ** May you share freely, never taking more than you give. |
12370 | ** |
12371 | ************************************************************************* |
12372 | ** |
12373 | ** This file contains the public interface to the "recover" extension - |
12374 | ** an SQLite extension designed to recover data from corrupted database |
12375 | ** files. |
12376 | */ |
12377 | |
12378 | /* |
12379 | ** OVERVIEW: |
12380 | ** |
12381 | ** To use the API to recover data from a corrupted database, an |
12382 | ** application: |
12383 | ** |
12384 | ** 1) Creates an sqlite3_recover handle by calling either |
12385 | ** sqlite3_recover_init() or sqlite3_recover_init_sql(). |
12386 | ** |
12387 | ** 2) Configures the new handle using one or more calls to |
12388 | ** sqlite3_recover_config(). |
12389 | ** |
12390 | ** 3) Executes the recovery by repeatedly calling sqlite3_recover_step() on |
12391 | ** the handle until it returns something other than SQLITE_OK. If it |
12392 | ** returns SQLITE_DONE, then the recovery operation completed without |
12393 | ** error. If it returns some other non-SQLITE_OK value, then an error |
12394 | ** has occurred. |
12395 | ** |
12396 | ** 4) Retrieves any error code and English language error message using the |
12397 | ** sqlite3_recover_errcode() and sqlite3_recover_errmsg() APIs, |
12398 | ** respectively. |
12399 | ** |
12400 | ** 5) Destroys the sqlite3_recover handle and frees all resources |
12401 | ** using sqlite3_recover_finish(). |
12402 | ** |
12403 | ** The application may abandon the recovery operation at any point |
12404 | ** before it is finished by passing the sqlite3_recover handle to |
12405 | ** sqlite3_recover_finish(). This is not an error, but the final state |
12406 | ** of the output database, or the results of running the partial script |
12407 | ** delivered to the SQL callback, are undefined. |
12408 | */ |
12409 | |
12410 | #ifndef _SQLITE_RECOVER_H |
12411 | #define _SQLITE_RECOVER_H |
12412 | |
12413 | /* #include "sqlite3.h" */ |
12414 | |
12415 | #ifdef __cplusplus |
12416 | extern "C" { |
12417 | #endif |
12418 | |
12419 | /* |
12420 | ** An instance of the sqlite3_recover object represents a recovery |
12421 | ** operation in progress. |
12422 | ** |
12423 | ** Constructors: |
12424 | ** |
12425 | ** sqlite3_recover_init() |
12426 | ** sqlite3_recover_init_sql() |
12427 | ** |
12428 | ** Destructor: |
12429 | ** |
12430 | ** sqlite3_recover_finish() |
12431 | ** |
12432 | ** Methods: |
12433 | ** |
12434 | ** sqlite3_recover_config() |
12435 | ** sqlite3_recover_errcode() |
12436 | ** sqlite3_recover_errmsg() |
12437 | ** sqlite3_recover_run() |
12438 | ** sqlite3_recover_step() |
12439 | */ |
12440 | typedef struct sqlite3_recover sqlite3_recover; |
12441 | |
12442 | /* |
12443 | ** These two APIs attempt to create and return a new sqlite3_recover object. |
12444 | ** In both cases the first two arguments identify the (possibly |
12445 | ** corrupt) database to recover data from. The first argument is an open |
12446 | ** database handle and the second the name of a database attached to that |
12447 | ** handle (i.e. "main", "temp" or the name of an attached database). |
12448 | ** |
12449 | ** If sqlite3_recover_init() is used to create the new sqlite3_recover |
12450 | ** handle, then data is recovered into a new database, identified by |
12451 | ** string parameter zUri. zUri may be an absolute or relative file path, |
12452 | ** or may be an SQLite URI. If the identified database file already exists, |
12453 | ** it is overwritten. |
12454 | ** |
12455 | ** If sqlite3_recover_init_sql() is invoked, then any recovered data will |
12456 | ** be returned to the user as a series of SQL statements. Executing these |
12457 | ** SQL statements results in the same database as would have been created |
12458 | ** had sqlite3_recover_init() been used. For each SQL statement in the |
12459 | ** output, the callback function passed as the third argument (xSql) is |
12460 | ** invoked once. The first parameter is a passed a copy of the fourth argument |
12461 | ** to this function (pCtx) as its first parameter, and a pointer to a |
12462 | ** nul-terminated buffer containing the SQL statement formated as UTF-8 as |
12463 | ** the second. If the xSql callback returns any value other than SQLITE_OK, |
12464 | ** then processing is immediately abandoned and the value returned used as |
12465 | ** the recover handle error code (see below). |
12466 | ** |
12467 | ** If an out-of-memory error occurs, NULL may be returned instead of |
12468 | ** a valid handle. In all other cases, it is the responsibility of the |
12469 | ** application to avoid resource leaks by ensuring that |
12470 | ** sqlite3_recover_finish() is called on all allocated handles. |
12471 | */ |
12472 | sqlite3_recover *sqlite3_recover_init( |
12473 | sqlite3* db, |
12474 | const char *zDb, |
12475 | const char *zUri |
12476 | ); |
12477 | sqlite3_recover *sqlite3_recover_init_sql( |
12478 | sqlite3* db, |
12479 | const char *zDb, |
12480 | int (*xSql)(void*, const char*), |
12481 | void *pCtx |
12482 | ); |
12483 | |
12484 | /* |
12485 | ** Configure an sqlite3_recover object that has just been created using |
12486 | ** sqlite3_recover_init() or sqlite3_recover_init_sql(). This function |
12487 | ** may only be called before the first call to sqlite3_recover_step() |
12488 | ** or sqlite3_recover_run() on the object. |
12489 | ** |
12490 | ** The second argument passed to this function must be one of the |
12491 | ** SQLITE_RECOVER_* symbols defined below. Valid values for the third argument |
12492 | ** depend on the specific SQLITE_RECOVER_* symbol in use. |
12493 | ** |
12494 | ** SQLITE_OK is returned if the configuration operation was successful, |
12495 | ** or an SQLite error code otherwise. |
12496 | */ |
12497 | int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg); |
12498 | |
12499 | /* |
12500 | ** SQLITE_RECOVER_LOST_AND_FOUND: |
12501 | ** The pArg argument points to a string buffer containing the name |
12502 | ** of a "lost-and-found" table in the output database, or NULL. If |
12503 | ** the argument is non-NULL and the database contains seemingly |
12504 | ** valid pages that cannot be associated with any table in the |
12505 | ** recovered part of the schema, data is extracted from these |
12506 | ** pages to add to the lost-and-found table. |
12507 | ** |
12508 | ** SQLITE_RECOVER_FREELIST_CORRUPT: |
12509 | ** The pArg value must actually be a pointer to a value of type |
12510 | ** int containing value 0 or 1 cast as a (void*). If this option is set |
12511 | ** (argument is 1) and a lost-and-found table has been configured using |
12512 | ** SQLITE_RECOVER_LOST_AND_FOUND, then is assumed that the freelist is |
12513 | ** corrupt and an attempt is made to recover records from pages that |
12514 | ** appear to be linked into the freelist. Otherwise, pages on the freelist |
12515 | ** are ignored. Setting this option can recover more data from the |
12516 | ** database, but often ends up "recovering" deleted records. The default |
12517 | ** value is 0 (clear). |
12518 | ** |
12519 | ** SQLITE_RECOVER_ROWIDS: |
12520 | ** The pArg value must actually be a pointer to a value of type |
12521 | ** int containing value 0 or 1 cast as a (void*). If this option is set |
12522 | ** (argument is 1), then an attempt is made to recover rowid values |
12523 | ** that are not also INTEGER PRIMARY KEY values. If this option is |
12524 | ** clear, then new rowids are assigned to all recovered rows. The |
12525 | ** default value is 1 (set). |
12526 | ** |
12527 | ** SQLITE_RECOVER_SLOWINDEXES: |
12528 | ** The pArg value must actually be a pointer to a value of type |
12529 | ** int containing value 0 or 1 cast as a (void*). If this option is clear |
12530 | ** (argument is 0), then when creating an output database, the recover |
12531 | ** module creates and populates non-UNIQUE indexes right at the end of the |
12532 | ** recovery operation - after all recoverable data has been inserted |
12533 | ** into the new database. This is faster overall, but means that the |
12534 | ** final call to sqlite3_recover_step() for a recovery operation may |
12535 | ** be need to create a large number of indexes, which may be very slow. |
12536 | ** |
12537 | ** Or, if this option is set (argument is 1), then non-UNIQUE indexes |
12538 | ** are created in the output database before it is populated with |
12539 | ** recovered data. This is slower overall, but avoids the slow call |
12540 | ** to sqlite3_recover_step() at the end of the recovery operation. |
12541 | ** |
12542 | ** The default option value is 0. |
12543 | */ |
12544 | #define SQLITE_RECOVER_LOST_AND_FOUND 1 |
12545 | #define SQLITE_RECOVER_FREELIST_CORRUPT 2 |
12546 | #define SQLITE_RECOVER_ROWIDS 3 |
12547 | #define SQLITE_RECOVER_SLOWINDEXES 4 |
12548 | |
12549 | /* |
12550 | ** Perform a unit of work towards the recovery operation. This function |
12551 | ** must normally be called multiple times to complete database recovery. |
12552 | ** |
12553 | ** If no error occurs but the recovery operation is not completed, this |
12554 | ** function returns SQLITE_OK. If recovery has been completed successfully |
12555 | ** then SQLITE_DONE is returned. If an error has occurred, then an SQLite |
12556 | ** error code (e.g. SQLITE_IOERR or SQLITE_NOMEM) is returned. It is not |
12557 | ** considered an error if some or all of the data cannot be recovered |
12558 | ** due to database corruption. |
12559 | ** |
12560 | ** Once sqlite3_recover_step() has returned a value other than SQLITE_OK, |
12561 | ** all further such calls on the same recover handle are no-ops that return |
12562 | ** the same non-SQLITE_OK value. |
12563 | */ |
12564 | int sqlite3_recover_step(sqlite3_recover*); |
12565 | |
12566 | /* |
12567 | ** Run the recovery operation to completion. Return SQLITE_OK if successful, |
12568 | ** or an SQLite error code otherwise. Calling this function is the same |
12569 | ** as executing: |
12570 | ** |
12571 | ** while( SQLITE_OK==sqlite3_recover_step(p) ); |
12572 | ** return sqlite3_recover_errcode(p); |
12573 | */ |
12574 | int sqlite3_recover_run(sqlite3_recover*); |
12575 | |
12576 | /* |
12577 | ** If an error has been encountered during a prior call to |
12578 | ** sqlite3_recover_step(), then this function attempts to return a |
12579 | ** pointer to a buffer containing an English language explanation of |
12580 | ** the error. If no error message is available, or if an out-of memory |
12581 | ** error occurs while attempting to allocate a buffer in which to format |
12582 | ** the error message, NULL is returned. |
12583 | ** |
12584 | ** The returned buffer remains valid until the sqlite3_recover handle is |
12585 | ** destroyed using sqlite3_recover_finish(). |
12586 | */ |
12587 | const char *sqlite3_recover_errmsg(sqlite3_recover*); |
12588 | |
12589 | /* |
12590 | ** If this function is called on an sqlite3_recover handle after |
12591 | ** an error occurs, an SQLite error code is returned. Otherwise, SQLITE_OK. |
12592 | */ |
12593 | int sqlite3_recover_errcode(sqlite3_recover*); |
12594 | |
12595 | /* |
12596 | ** Clean up a recovery object created by a call to sqlite3_recover_init(). |
12597 | ** The results of using a recovery object with any API after it has been |
12598 | ** passed to this function are undefined. |
12599 | ** |
12600 | ** This function returns the same value as sqlite3_recover_errcode(). |
12601 | */ |
12602 | int sqlite3_recover_finish(sqlite3_recover*); |
12603 | |
12604 | |
12605 | #ifdef __cplusplus |
12606 | } /* end of the 'extern "C"' block */ |
12607 | #endif |
12608 | |
12609 | #endif /* ifndef _SQLITE_RECOVER_H */ |
12610 | |
12611 | /************************* End ../ext/recover/sqlite3recover.h ********************/ |
12612 | /************************* Begin ../ext/recover/sqlite3recover.c ******************/ |
12613 | /* |
12614 | ** 2022-08-27 |
12615 | ** |
12616 | ** The author disclaims copyright to this source code. In place of |
12617 | ** a legal notice, here is a blessing: |
12618 | ** |
12619 | ** May you do good and not evil. |
12620 | ** May you find forgiveness for yourself and forgive others. |
12621 | ** May you share freely, never taking more than you give. |
12622 | ** |
12623 | ************************************************************************* |
12624 | ** |
12625 | */ |
12626 | |
12627 | |
12628 | /* #include "sqlite3recover.h" */ |
12629 | #include <assert.h> |
12630 | #include <string.h> |
12631 | |
12632 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
12633 | |
12634 | /* |
12635 | ** Declaration for public API function in file dbdata.c. This may be called |
12636 | ** with NULL as the final two arguments to register the sqlite_dbptr and |
12637 | ** sqlite_dbdata virtual tables with a database handle. |
12638 | */ |
12639 | #ifdef _WIN32 |
12640 | |
12641 | #endif |
12642 | int sqlite3_dbdata_init(sqlite3*, char**, const sqlite3_api_routines*); |
12643 | |
12644 | /* typedef unsigned int u32; */ |
12645 | /* typedef unsigned char u8; */ |
12646 | /* typedef sqlite3_int64 i64; */ |
12647 | |
12648 | typedef struct RecoverTable RecoverTable; |
12649 | typedef struct RecoverColumn RecoverColumn; |
12650 | |
12651 | /* |
12652 | ** When recovering rows of data that can be associated with table |
12653 | ** definitions recovered from the sqlite_schema table, each table is |
12654 | ** represented by an instance of the following object. |
12655 | ** |
12656 | ** iRoot: |
12657 | ** The root page in the original database. Not necessarily (and usually |
12658 | ** not) the same in the recovered database. |
12659 | ** |
12660 | ** zTab: |
12661 | ** Name of the table. |
12662 | ** |
12663 | ** nCol/aCol[]: |
12664 | ** aCol[] is an array of nCol columns. In the order in which they appear |
12665 | ** in the table. |
12666 | ** |
12667 | ** bIntkey: |
12668 | ** Set to true for intkey tables, false for WITHOUT ROWID. |
12669 | ** |
12670 | ** iRowidBind: |
12671 | ** Each column in the aCol[] array has associated with it the index of |
12672 | ** the bind parameter its values will be bound to in the INSERT statement |
12673 | ** used to construct the output database. If the table does has a rowid |
12674 | ** but not an INTEGER PRIMARY KEY column, then iRowidBind contains the |
12675 | ** index of the bind paramater to which the rowid value should be bound. |
12676 | ** Otherwise, it contains -1. If the table does contain an INTEGER PRIMARY |
12677 | ** KEY column, then the rowid value should be bound to the index associated |
12678 | ** with the column. |
12679 | ** |
12680 | ** pNext: |
12681 | ** All RecoverTable objects used by the recovery operation are allocated |
12682 | ** and populated as part of creating the recovered database schema in |
12683 | ** the output database, before any non-schema data are recovered. They |
12684 | ** are then stored in a singly-linked list linked by this variable beginning |
12685 | ** at sqlite3_recover.pTblList. |
12686 | */ |
12687 | struct RecoverTable { |
12688 | u32 iRoot; /* Root page in original database */ |
12689 | char *zTab; /* Name of table */ |
12690 | int nCol; /* Number of columns in table */ |
12691 | RecoverColumn *aCol; /* Array of columns */ |
12692 | int bIntkey; /* True for intkey, false for without rowid */ |
12693 | int iRowidBind; /* If >0, bind rowid to INSERT here */ |
12694 | RecoverTable *pNext; |
12695 | }; |
12696 | |
12697 | /* |
12698 | ** Each database column is represented by an instance of the following object |
12699 | ** stored in the RecoverTable.aCol[] array of the associated table. |
12700 | ** |
12701 | ** iField: |
12702 | ** The index of the associated field within database records. Or -1 if |
12703 | ** there is no associated field (e.g. for virtual generated columns). |
12704 | ** |
12705 | ** iBind: |
12706 | ** The bind index of the INSERT statement to bind this columns values |
12707 | ** to. Or 0 if there is no such index (iff (iField<0)). |
12708 | ** |
12709 | ** bIPK: |
12710 | ** True if this is the INTEGER PRIMARY KEY column. |
12711 | ** |
12712 | ** zCol: |
12713 | ** Name of column. |
12714 | ** |
12715 | ** eHidden: |
12716 | ** A RECOVER_EHIDDEN_* constant value (see below for interpretation of each). |
12717 | */ |
12718 | struct RecoverColumn { |
12719 | int iField; /* Field in record on disk */ |
12720 | int iBind; /* Binding to use in INSERT */ |
12721 | int bIPK; /* True for IPK column */ |
12722 | char *zCol; |
12723 | int eHidden; |
12724 | }; |
12725 | |
12726 | #define RECOVER_EHIDDEN_NONE 0 /* Normal database column */ |
12727 | #define RECOVER_EHIDDEN_HIDDEN 1 /* Column is __HIDDEN__ */ |
12728 | #define RECOVER_EHIDDEN_VIRTUAL 2 /* Virtual generated column */ |
12729 | #define RECOVER_EHIDDEN_STORED 3 /* Stored generated column */ |
12730 | |
12731 | /* |
12732 | ** Bitmap object used to track pages in the input database. Allocated |
12733 | ** and manipulated only by the following functions: |
12734 | ** |
12735 | ** recoverBitmapAlloc() |
12736 | ** recoverBitmapFree() |
12737 | ** recoverBitmapSet() |
12738 | ** recoverBitmapQuery() |
12739 | ** |
12740 | ** nPg: |
12741 | ** Largest page number that may be stored in the bitmap. The range |
12742 | ** of valid keys is 1 to nPg, inclusive. |
12743 | ** |
12744 | ** aElem[]: |
12745 | ** Array large enough to contain a bit for each key. For key value |
12746 | ** iKey, the associated bit is the bit (iKey%32) of aElem[iKey/32]. |
12747 | ** In other words, the following is true if bit iKey is set, or |
12748 | ** false if it is clear: |
12749 | ** |
12750 | ** (aElem[iKey/32] & (1 << (iKey%32))) ? 1 : 0 |
12751 | */ |
12752 | typedef struct RecoverBitmap RecoverBitmap; |
12753 | struct RecoverBitmap { |
12754 | i64 nPg; /* Size of bitmap */ |
12755 | u32 aElem[1]; /* Array of 32-bit bitmasks */ |
12756 | }; |
12757 | |
12758 | /* |
12759 | ** State variables (part of the sqlite3_recover structure) used while |
12760 | ** recovering data for tables identified in the recovered schema (state |
12761 | ** RECOVER_STATE_WRITING). |
12762 | */ |
12763 | typedef struct RecoverStateW1 RecoverStateW1; |
12764 | struct RecoverStateW1 { |
12765 | sqlite3_stmt *pTbls; |
12766 | sqlite3_stmt *pSel; |
12767 | sqlite3_stmt *pInsert; |
12768 | int nInsert; |
12769 | |
12770 | RecoverTable *pTab; /* Table currently being written */ |
12771 | int nMax; /* Max column count in any schema table */ |
12772 | sqlite3_value **apVal; /* Array of nMax values */ |
12773 | int nVal; /* Number of valid entries in apVal[] */ |
12774 | int bHaveRowid; |
12775 | i64 iRowid; |
12776 | i64 iPrevPage; |
12777 | int iPrevCell; |
12778 | }; |
12779 | |
12780 | /* |
12781 | ** State variables (part of the sqlite3_recover structure) used while |
12782 | ** recovering data destined for the lost and found table (states |
12783 | ** RECOVER_STATE_LOSTANDFOUND[123]). |
12784 | */ |
12785 | typedef struct RecoverStateLAF RecoverStateLAF; |
12786 | struct RecoverStateLAF { |
12787 | RecoverBitmap *pUsed; |
12788 | i64 nPg; /* Size of db in pages */ |
12789 | sqlite3_stmt *pAllAndParent; |
12790 | sqlite3_stmt *pMapInsert; |
12791 | sqlite3_stmt *pMaxField; |
12792 | sqlite3_stmt *pUsedPages; |
12793 | sqlite3_stmt *pFindRoot; |
12794 | sqlite3_stmt *pInsert; /* INSERT INTO lost_and_found ... */ |
12795 | sqlite3_stmt *pAllPage; |
12796 | sqlite3_stmt *pPageData; |
12797 | sqlite3_value **apVal; |
12798 | int nMaxField; |
12799 | }; |
12800 | |
12801 | /* |
12802 | ** Main recover handle structure. |
12803 | */ |
12804 | struct sqlite3_recover { |
12805 | /* Copies of sqlite3_recover_init[_sql]() parameters */ |
12806 | sqlite3 *dbIn; /* Input database */ |
12807 | char *zDb; /* Name of input db ("main" etc.) */ |
12808 | char *zUri; /* URI for output database */ |
12809 | void *pSqlCtx; /* SQL callback context */ |
12810 | int (*xSql)(void*,const char*); /* Pointer to SQL callback function */ |
12811 | |
12812 | /* Values configured by sqlite3_recover_config() */ |
12813 | char *zStateDb; /* State database to use (or NULL) */ |
12814 | char *zLostAndFound; /* Name of lost-and-found table (or NULL) */ |
12815 | int bFreelistCorrupt; /* SQLITE_RECOVER_FREELIST_CORRUPT setting */ |
12816 | int bRecoverRowid; /* SQLITE_RECOVER_ROWIDS setting */ |
12817 | int bSlowIndexes; /* SQLITE_RECOVER_SLOWINDEXES setting */ |
12818 | |
12819 | int pgsz; |
12820 | int detected_pgsz; |
12821 | int nReserve; |
12822 | u8 *pPage1Disk; |
12823 | u8 *pPage1Cache; |
12824 | |
12825 | /* Error code and error message */ |
12826 | int errCode; /* For sqlite3_recover_errcode() */ |
12827 | char *zErrMsg; /* For sqlite3_recover_errmsg() */ |
12828 | |
12829 | int eState; |
12830 | int bCloseTransaction; |
12831 | |
12832 | /* Variables used with eState==RECOVER_STATE_WRITING */ |
12833 | RecoverStateW1 w1; |
12834 | |
12835 | /* Variables used with states RECOVER_STATE_LOSTANDFOUND[123] */ |
12836 | RecoverStateLAF laf; |
12837 | |
12838 | /* Fields used within sqlite3_recover_run() */ |
12839 | sqlite3 *dbOut; /* Output database */ |
12840 | sqlite3_stmt *pGetPage; /* SELECT against input db sqlite_dbdata */ |
12841 | RecoverTable *pTblList; /* List of tables recovered from schema */ |
12842 | }; |
12843 | |
12844 | /* |
12845 | ** The various states in which an sqlite3_recover object may exist: |
12846 | ** |
12847 | ** RECOVER_STATE_INIT: |
12848 | ** The object is initially created in this state. sqlite3_recover_step() |
12849 | ** has yet to be called. This is the only state in which it is permitted |
12850 | ** to call sqlite3_recover_config(). |
12851 | ** |
12852 | ** RECOVER_STATE_WRITING: |
12853 | ** |
12854 | ** RECOVER_STATE_LOSTANDFOUND1: |
12855 | ** State to populate the bitmap of pages used by other tables or the |
12856 | ** database freelist. |
12857 | ** |
12858 | ** RECOVER_STATE_LOSTANDFOUND2: |
12859 | ** Populate the recovery.map table - used to figure out a "root" page |
12860 | ** for each lost page from in the database from which records are |
12861 | ** extracted. |
12862 | ** |
12863 | ** RECOVER_STATE_LOSTANDFOUND3: |
12864 | ** Populate the lost-and-found table itself. |
12865 | */ |
12866 | #define RECOVER_STATE_INIT 0 |
12867 | #define RECOVER_STATE_WRITING 1 |
12868 | #define RECOVER_STATE_LOSTANDFOUND1 2 |
12869 | #define RECOVER_STATE_LOSTANDFOUND2 3 |
12870 | #define RECOVER_STATE_LOSTANDFOUND3 4 |
12871 | #define RECOVER_STATE_SCHEMA2 5 |
12872 | #define RECOVER_STATE_DONE 6 |
12873 | |
12874 | |
12875 | /* |
12876 | ** Global variables used by this extension. |
12877 | */ |
12878 | typedef struct RecoverGlobal RecoverGlobal; |
12879 | struct RecoverGlobal { |
12880 | const sqlite3_io_methods *pMethods; |
12881 | sqlite3_recover *p; |
12882 | }; |
12883 | static RecoverGlobal recover_g; |
12884 | |
12885 | /* |
12886 | ** Use this static SQLite mutex to protect the globals during the |
12887 | ** first call to sqlite3_recover_step(). |
12888 | */ |
12889 | #define RECOVER_MUTEX_ID SQLITE_MUTEX_STATIC_APP2 |
12890 | |
12891 | |
12892 | /* |
12893 | ** Default value for SQLITE_RECOVER_ROWIDS (sqlite3_recover.bRecoverRowid). |
12894 | */ |
12895 | #define RECOVER_ROWID_DEFAULT 1 |
12896 | |
12897 | /* |
12898 | ** Mutex handling: |
12899 | ** |
12900 | ** recoverEnterMutex() - Enter the recovery mutex |
12901 | ** recoverLeaveMutex() - Leave the recovery mutex |
12902 | ** recoverAssertMutexHeld() - Assert that the recovery mutex is held |
12903 | */ |
12904 | #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0 |
12905 | # define recoverEnterMutex() |
12906 | # define recoverLeaveMutex() |
12907 | #else |
12908 | static void recoverEnterMutex(void){ |
12909 | sqlite3_mutex_enter(sqlite3_mutex_alloc(RECOVER_MUTEX_ID)); |
12910 | } |
12911 | static void recoverLeaveMutex(void){ |
12912 | sqlite3_mutex_leave(sqlite3_mutex_alloc(RECOVER_MUTEX_ID)); |
12913 | } |
12914 | #endif |
12915 | #if SQLITE_THREADSAFE+0>=1 && defined(SQLITE_DEBUG) |
12916 | static void recoverAssertMutexHeld(void){ |
12917 | assert( sqlite3_mutex_held(sqlite3_mutex_alloc(RECOVER_MUTEX_ID)) ); |
12918 | } |
12919 | #else |
12920 | # define recoverAssertMutexHeld() |
12921 | #endif |
12922 | |
12923 | |
12924 | /* |
12925 | ** Like strlen(). But handles NULL pointer arguments. |
12926 | */ |
12927 | static int recoverStrlen(const char *zStr){ |
12928 | if( zStr==0 ) return 0; |
12929 | return (int)(strlen(zStr)&0x7fffffff); |
12930 | } |
12931 | |
12932 | /* |
12933 | ** This function is a no-op if the recover handle passed as the first |
12934 | ** argument already contains an error (if p->errCode!=SQLITE_OK). |
12935 | ** |
12936 | ** Otherwise, an attempt is made to allocate, zero and return a buffer nByte |
12937 | ** bytes in size. If successful, a pointer to the new buffer is returned. Or, |
12938 | ** if an OOM error occurs, NULL is returned and the handle error code |
12939 | ** (p->errCode) set to SQLITE_NOMEM. |
12940 | */ |
12941 | static void *recoverMalloc(sqlite3_recover *p, i64 nByte){ |
12942 | void *pRet = 0; |
12943 | assert( nByte>0 ); |
12944 | if( p->errCode==SQLITE_OK ){ |
12945 | pRet = sqlite3_malloc64(nByte); |
12946 | if( pRet ){ |
12947 | memset(pRet, 0, nByte); |
12948 | }else{ |
12949 | p->errCode = SQLITE_NOMEM; |
12950 | } |
12951 | } |
12952 | return pRet; |
12953 | } |
12954 | |
12955 | /* |
12956 | ** Set the error code and error message for the recover handle passed as |
12957 | ** the first argument. The error code is set to the value of parameter |
12958 | ** errCode. |
12959 | ** |
12960 | ** Parameter zFmt must be a printf() style formatting string. The handle |
12961 | ** error message is set to the result of using any trailing arguments for |
12962 | ** parameter substitutions in the formatting string. |
12963 | ** |
12964 | ** For example: |
12965 | ** |
12966 | ** recoverError(p, SQLITE_ERROR, "no such table: %s", zTablename); |
12967 | */ |
12968 | static int recoverError( |
12969 | sqlite3_recover *p, |
12970 | int errCode, |
12971 | const char *zFmt, ... |
12972 | ){ |
12973 | char *z = 0; |
12974 | va_list ap; |
12975 | va_start(ap, zFmt); |
12976 | if( zFmt ){ |
12977 | z = sqlite3_vmprintf(zFmt, ap); |
12978 | va_end(ap); |
12979 | } |
12980 | sqlite3_free(p->zErrMsg); |
12981 | p->zErrMsg = z; |
12982 | p->errCode = errCode; |
12983 | return errCode; |
12984 | } |
12985 | |
12986 | |
12987 | /* |
12988 | ** This function is a no-op if p->errCode is initially other than SQLITE_OK. |
12989 | ** In this case it returns NULL. |
12990 | ** |
12991 | ** Otherwise, an attempt is made to allocate and return a bitmap object |
12992 | ** large enough to store a bit for all page numbers between 1 and nPg, |
12993 | ** inclusive. The bitmap is initially zeroed. |
12994 | */ |
12995 | static RecoverBitmap *recoverBitmapAlloc(sqlite3_recover *p, i64 nPg){ |
12996 | int nElem = (nPg+1+31) / 32; |
12997 | int nByte = sizeof(RecoverBitmap) + nElem*sizeof(u32); |
12998 | RecoverBitmap *pRet = (RecoverBitmap*)recoverMalloc(p, nByte); |
12999 | |
13000 | if( pRet ){ |
13001 | pRet->nPg = nPg; |
13002 | } |
13003 | return pRet; |
13004 | } |
13005 | |
13006 | /* |
13007 | ** Free a bitmap object allocated by recoverBitmapAlloc(). |
13008 | */ |
13009 | static void recoverBitmapFree(RecoverBitmap *pMap){ |
13010 | sqlite3_free(pMap); |
13011 | } |
13012 | |
13013 | /* |
13014 | ** Set the bit associated with page iPg in bitvec pMap. |
13015 | */ |
13016 | static void recoverBitmapSet(RecoverBitmap *pMap, i64 iPg){ |
13017 | if( iPg<=pMap->nPg ){ |
13018 | int iElem = (iPg / 32); |
13019 | int iBit = (iPg % 32); |
13020 | pMap->aElem[iElem] |= (((u32)1) << iBit); |
13021 | } |
13022 | } |
13023 | |
13024 | /* |
13025 | ** Query bitmap object pMap for the state of the bit associated with page |
13026 | ** iPg. Return 1 if it is set, or 0 otherwise. |
13027 | */ |
13028 | static int recoverBitmapQuery(RecoverBitmap *pMap, i64 iPg){ |
13029 | int ret = 1; |
13030 | if( iPg<=pMap->nPg && iPg>0 ){ |
13031 | int iElem = (iPg / 32); |
13032 | int iBit = (iPg % 32); |
13033 | ret = (pMap->aElem[iElem] & (((u32)1) << iBit)) ? 1 : 0; |
13034 | } |
13035 | return ret; |
13036 | } |
13037 | |
13038 | /* |
13039 | ** Set the recover handle error to the error code and message returned by |
13040 | ** calling sqlite3_errcode() and sqlite3_errmsg(), respectively, on database |
13041 | ** handle db. |
13042 | */ |
13043 | static int recoverDbError(sqlite3_recover *p, sqlite3 *db){ |
13044 | return recoverError(p, sqlite3_errcode(db), "%s" , sqlite3_errmsg(db)); |
13045 | } |
13046 | |
13047 | /* |
13048 | ** This function is a no-op if recover handle p already contains an error |
13049 | ** (if p->errCode!=SQLITE_OK). |
13050 | ** |
13051 | ** Otherwise, it attempts to prepare the SQL statement in zSql against |
13052 | ** database handle db. If successful, the statement handle is returned. |
13053 | ** Or, if an error occurs, NULL is returned and an error left in the |
13054 | ** recover handle. |
13055 | */ |
13056 | static sqlite3_stmt *recoverPrepare( |
13057 | sqlite3_recover *p, |
13058 | sqlite3 *db, |
13059 | const char *zSql |
13060 | ){ |
13061 | sqlite3_stmt *pStmt = 0; |
13062 | if( p->errCode==SQLITE_OK ){ |
13063 | if( sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) ){ |
13064 | recoverDbError(p, db); |
13065 | } |
13066 | } |
13067 | return pStmt; |
13068 | } |
13069 | |
13070 | /* |
13071 | ** This function is a no-op if recover handle p already contains an error |
13072 | ** (if p->errCode!=SQLITE_OK). |
13073 | ** |
13074 | ** Otherwise, argument zFmt is used as a printf() style format string, |
13075 | ** along with any trailing arguments, to create an SQL statement. This |
13076 | ** SQL statement is prepared against database handle db and, if successful, |
13077 | ** the statment handle returned. Or, if an error occurs - either during |
13078 | ** the printf() formatting or when preparing the resulting SQL - an |
13079 | ** error code and message are left in the recover handle. |
13080 | */ |
13081 | static sqlite3_stmt *recoverPreparePrintf( |
13082 | sqlite3_recover *p, |
13083 | sqlite3 *db, |
13084 | const char *zFmt, ... |
13085 | ){ |
13086 | sqlite3_stmt *pStmt = 0; |
13087 | if( p->errCode==SQLITE_OK ){ |
13088 | va_list ap; |
13089 | char *z; |
13090 | va_start(ap, zFmt); |
13091 | z = sqlite3_vmprintf(zFmt, ap); |
13092 | va_end(ap); |
13093 | if( z==0 ){ |
13094 | p->errCode = SQLITE_NOMEM; |
13095 | }else{ |
13096 | pStmt = recoverPrepare(p, db, z); |
13097 | sqlite3_free(z); |
13098 | } |
13099 | } |
13100 | return pStmt; |
13101 | } |
13102 | |
13103 | /* |
13104 | ** Reset SQLite statement handle pStmt. If the call to sqlite3_reset() |
13105 | ** indicates that an error occurred, and there is not already an error |
13106 | ** in the recover handle passed as the first argument, set the error |
13107 | ** code and error message appropriately. |
13108 | ** |
13109 | ** This function returns a copy of the statement handle pointer passed |
13110 | ** as the second argument. |
13111 | */ |
13112 | static sqlite3_stmt *recoverReset(sqlite3_recover *p, sqlite3_stmt *pStmt){ |
13113 | int rc = sqlite3_reset(pStmt); |
13114 | if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT && p->errCode==SQLITE_OK ){ |
13115 | recoverDbError(p, sqlite3_db_handle(pStmt)); |
13116 | } |
13117 | return pStmt; |
13118 | } |
13119 | |
13120 | /* |
13121 | ** Finalize SQLite statement handle pStmt. If the call to sqlite3_reset() |
13122 | ** indicates that an error occurred, and there is not already an error |
13123 | ** in the recover handle passed as the first argument, set the error |
13124 | ** code and error message appropriately. |
13125 | */ |
13126 | static void recoverFinalize(sqlite3_recover *p, sqlite3_stmt *pStmt){ |
13127 | sqlite3 *db = sqlite3_db_handle(pStmt); |
13128 | int rc = sqlite3_finalize(pStmt); |
13129 | if( rc!=SQLITE_OK && p->errCode==SQLITE_OK ){ |
13130 | recoverDbError(p, db); |
13131 | } |
13132 | } |
13133 | |
13134 | /* |
13135 | ** This function is a no-op if recover handle p already contains an error |
13136 | ** (if p->errCode!=SQLITE_OK). A copy of p->errCode is returned in this |
13137 | ** case. |
13138 | ** |
13139 | ** Otherwise, execute SQL script zSql. If successful, return SQLITE_OK. |
13140 | ** Or, if an error occurs, leave an error code and message in the recover |
13141 | ** handle and return a copy of the error code. |
13142 | */ |
13143 | static int recoverExec(sqlite3_recover *p, sqlite3 *db, const char *zSql){ |
13144 | if( p->errCode==SQLITE_OK ){ |
13145 | int rc = sqlite3_exec(db, zSql, 0, 0, 0); |
13146 | if( rc ){ |
13147 | recoverDbError(p, db); |
13148 | } |
13149 | } |
13150 | return p->errCode; |
13151 | } |
13152 | |
13153 | /* |
13154 | ** Bind the value pVal to parameter iBind of statement pStmt. Leave an |
13155 | ** error in the recover handle passed as the first argument if an error |
13156 | ** (e.g. an OOM) occurs. |
13157 | */ |
13158 | static void recoverBindValue( |
13159 | sqlite3_recover *p, |
13160 | sqlite3_stmt *pStmt, |
13161 | int iBind, |
13162 | sqlite3_value *pVal |
13163 | ){ |
13164 | if( p->errCode==SQLITE_OK ){ |
13165 | int rc = sqlite3_bind_value(pStmt, iBind, pVal); |
13166 | if( rc ) recoverError(p, rc, 0); |
13167 | } |
13168 | } |
13169 | |
13170 | /* |
13171 | ** This function is a no-op if recover handle p already contains an error |
13172 | ** (if p->errCode!=SQLITE_OK). NULL is returned in this case. |
13173 | ** |
13174 | ** Otherwise, an attempt is made to interpret zFmt as a printf() style |
13175 | ** formatting string and the result of using the trailing arguments for |
13176 | ** parameter substitution with it written into a buffer obtained from |
13177 | ** sqlite3_malloc(). If successful, a pointer to the buffer is returned. |
13178 | ** It is the responsibility of the caller to eventually free the buffer |
13179 | ** using sqlite3_free(). |
13180 | ** |
13181 | ** Or, if an error occurs, an error code and message is left in the recover |
13182 | ** handle and NULL returned. |
13183 | */ |
13184 | static char *recoverMPrintf(sqlite3_recover *p, const char *zFmt, ...){ |
13185 | va_list ap; |
13186 | char *z; |
13187 | va_start(ap, zFmt); |
13188 | z = sqlite3_vmprintf(zFmt, ap); |
13189 | va_end(ap); |
13190 | if( p->errCode==SQLITE_OK ){ |
13191 | if( z==0 ) p->errCode = SQLITE_NOMEM; |
13192 | }else{ |
13193 | sqlite3_free(z); |
13194 | z = 0; |
13195 | } |
13196 | return z; |
13197 | } |
13198 | |
13199 | /* |
13200 | ** This function is a no-op if recover handle p already contains an error |
13201 | ** (if p->errCode!=SQLITE_OK). Zero is returned in this case. |
13202 | ** |
13203 | ** Otherwise, execute "PRAGMA page_count" against the input database. If |
13204 | ** successful, return the integer result. Or, if an error occurs, leave an |
13205 | ** error code and error message in the sqlite3_recover handle and return |
13206 | ** zero. |
13207 | */ |
13208 | static i64 recoverPageCount(sqlite3_recover *p){ |
13209 | i64 nPg = 0; |
13210 | if( p->errCode==SQLITE_OK ){ |
13211 | sqlite3_stmt *pStmt = 0; |
13212 | pStmt = recoverPreparePrintf(p, p->dbIn, "PRAGMA %Q.page_count" , p->zDb); |
13213 | if( pStmt ){ |
13214 | sqlite3_step(pStmt); |
13215 | nPg = sqlite3_column_int64(pStmt, 0); |
13216 | } |
13217 | recoverFinalize(p, pStmt); |
13218 | } |
13219 | return nPg; |
13220 | } |
13221 | |
13222 | /* |
13223 | ** Implementation of SQL scalar function "read_i32". The first argument to |
13224 | ** this function must be a blob. The second a non-negative integer. This |
13225 | ** function reads and returns a 32-bit big-endian integer from byte |
13226 | ** offset (4*<arg2>) of the blob. |
13227 | ** |
13228 | ** SELECT read_i32(<blob>, <idx>) |
13229 | */ |
13230 | static void recoverReadI32( |
13231 | sqlite3_context *context, |
13232 | int argc, |
13233 | sqlite3_value **argv |
13234 | ){ |
13235 | const unsigned char *pBlob; |
13236 | int nBlob; |
13237 | int iInt; |
13238 | |
13239 | assert( argc==2 ); |
13240 | nBlob = sqlite3_value_bytes(argv[0]); |
13241 | pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]); |
13242 | iInt = sqlite3_value_int(argv[1]) & 0xFFFF; |
13243 | |
13244 | if( (iInt+1)*4<=nBlob ){ |
13245 | const unsigned char *a = &pBlob[iInt*4]; |
13246 | i64 iVal = ((i64)a[0]<<24) |
13247 | + ((i64)a[1]<<16) |
13248 | + ((i64)a[2]<< 8) |
13249 | + ((i64)a[3]<< 0); |
13250 | sqlite3_result_int64(context, iVal); |
13251 | } |
13252 | } |
13253 | |
13254 | /* |
13255 | ** Implementation of SQL scalar function "page_is_used". This function |
13256 | ** is used as part of the procedure for locating orphan rows for the |
13257 | ** lost-and-found table, and it depends on those routines having populated |
13258 | ** the sqlite3_recover.laf.pUsed variable. |
13259 | ** |
13260 | ** The only argument to this function is a page-number. It returns true |
13261 | ** if the page has already been used somehow during data recovery, or false |
13262 | ** otherwise. |
13263 | ** |
13264 | ** SELECT page_is_used(<pgno>); |
13265 | */ |
13266 | static void recoverPageIsUsed( |
13267 | sqlite3_context *pCtx, |
13268 | int nArg, |
13269 | sqlite3_value **apArg |
13270 | ){ |
13271 | sqlite3_recover *p = (sqlite3_recover*)sqlite3_user_data(pCtx); |
13272 | i64 pgno = sqlite3_value_int64(apArg[0]); |
13273 | assert( nArg==1 ); |
13274 | sqlite3_result_int(pCtx, recoverBitmapQuery(p->laf.pUsed, pgno)); |
13275 | } |
13276 | |
13277 | /* |
13278 | ** The implementation of a user-defined SQL function invoked by the |
13279 | ** sqlite_dbdata and sqlite_dbptr virtual table modules to access pages |
13280 | ** of the database being recovered. |
13281 | ** |
13282 | ** This function always takes a single integer argument. If the argument |
13283 | ** is zero, then the value returned is the number of pages in the db being |
13284 | ** recovered. If the argument is greater than zero, it is a page number. |
13285 | ** The value returned in this case is an SQL blob containing the data for |
13286 | ** the identified page of the db being recovered. e.g. |
13287 | ** |
13288 | ** SELECT getpage(0); -- return number of pages in db |
13289 | ** SELECT getpage(4); -- return page 4 of db as a blob of data |
13290 | */ |
13291 | static void recoverGetPage( |
13292 | sqlite3_context *pCtx, |
13293 | int nArg, |
13294 | sqlite3_value **apArg |
13295 | ){ |
13296 | sqlite3_recover *p = (sqlite3_recover*)sqlite3_user_data(pCtx); |
13297 | i64 pgno = sqlite3_value_int64(apArg[0]); |
13298 | sqlite3_stmt *pStmt = 0; |
13299 | |
13300 | assert( nArg==1 ); |
13301 | if( pgno==0 ){ |
13302 | i64 nPg = recoverPageCount(p); |
13303 | sqlite3_result_int64(pCtx, nPg); |
13304 | return; |
13305 | }else{ |
13306 | if( p->pGetPage==0 ){ |
13307 | pStmt = p->pGetPage = recoverPreparePrintf( |
13308 | p, p->dbIn, "SELECT data FROM sqlite_dbpage(%Q) WHERE pgno=?" , p->zDb |
13309 | ); |
13310 | }else if( p->errCode==SQLITE_OK ){ |
13311 | pStmt = p->pGetPage; |
13312 | } |
13313 | |
13314 | if( pStmt ){ |
13315 | sqlite3_bind_int64(pStmt, 1, pgno); |
13316 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
13317 | const u8 *aPg; |
13318 | int nPg; |
13319 | assert( p->errCode==SQLITE_OK ); |
13320 | aPg = sqlite3_column_blob(pStmt, 0); |
13321 | nPg = sqlite3_column_bytes(pStmt, 0); |
13322 | if( pgno==1 && nPg==p->pgsz && 0==memcmp(p->pPage1Cache, aPg, nPg) ){ |
13323 | aPg = p->pPage1Disk; |
13324 | } |
13325 | sqlite3_result_blob(pCtx, aPg, nPg-p->nReserve, SQLITE_TRANSIENT); |
13326 | } |
13327 | recoverReset(p, pStmt); |
13328 | } |
13329 | } |
13330 | |
13331 | if( p->errCode ){ |
13332 | if( p->zErrMsg ) sqlite3_result_error(pCtx, p->zErrMsg, -1); |
13333 | sqlite3_result_error_code(pCtx, p->errCode); |
13334 | } |
13335 | } |
13336 | |
13337 | /* |
13338 | ** Find a string that is not found anywhere in z[]. Return a pointer |
13339 | ** to that string. |
13340 | ** |
13341 | ** Try to use zA and zB first. If both of those are already found in z[] |
13342 | ** then make up some string and store it in the buffer zBuf. |
13343 | */ |
13344 | static const char *recoverUnusedString( |
13345 | const char *z, /* Result must not appear anywhere in z */ |
13346 | const char *zA, const char *zB, /* Try these first */ |
13347 | char *zBuf /* Space to store a generated string */ |
13348 | ){ |
13349 | unsigned i = 0; |
13350 | if( strstr(z, zA)==0 ) return zA; |
13351 | if( strstr(z, zB)==0 ) return zB; |
13352 | do{ |
13353 | sqlite3_snprintf(20,zBuf,"(%s%u)" , zA, i++); |
13354 | }while( strstr(z,zBuf)!=0 ); |
13355 | return zBuf; |
13356 | } |
13357 | |
13358 | /* |
13359 | ** Implementation of scalar SQL function "escape_crnl". The argument passed to |
13360 | ** this function is the output of built-in function quote(). If the first |
13361 | ** character of the input is "'", indicating that the value passed to quote() |
13362 | ** was a text value, then this function searches the input for "\n" and "\r" |
13363 | ** characters and adds a wrapper similar to the following: |
13364 | ** |
13365 | ** replace(replace(<input>, '\n', char(10), '\r', char(13)); |
13366 | ** |
13367 | ** Or, if the first character of the input is not "'", then a copy of the input |
13368 | ** is returned. |
13369 | */ |
13370 | static void recoverEscapeCrnl( |
13371 | sqlite3_context *context, |
13372 | int argc, |
13373 | sqlite3_value **argv |
13374 | ){ |
13375 | const char *zText = (const char*)sqlite3_value_text(argv[0]); |
13376 | if( zText && zText[0]=='\'' ){ |
13377 | int nText = sqlite3_value_bytes(argv[0]); |
13378 | int i; |
13379 | char zBuf1[20]; |
13380 | char zBuf2[20]; |
13381 | const char *zNL = 0; |
13382 | const char *zCR = 0; |
13383 | int nCR = 0; |
13384 | int nNL = 0; |
13385 | |
13386 | for(i=0; zText[i]; i++){ |
13387 | if( zNL==0 && zText[i]=='\n' ){ |
13388 | zNL = recoverUnusedString(zText, "\\n" , "\\012" , zBuf1); |
13389 | nNL = (int)strlen(zNL); |
13390 | } |
13391 | if( zCR==0 && zText[i]=='\r' ){ |
13392 | zCR = recoverUnusedString(zText, "\\r" , "\\015" , zBuf2); |
13393 | nCR = (int)strlen(zCR); |
13394 | } |
13395 | } |
13396 | |
13397 | if( zNL || zCR ){ |
13398 | int iOut = 0; |
13399 | i64 nMax = (nNL > nCR) ? nNL : nCR; |
13400 | i64 nAlloc = nMax * nText + (nMax+64)*2; |
13401 | char *zOut = (char*)sqlite3_malloc64(nAlloc); |
13402 | if( zOut==0 ){ |
13403 | sqlite3_result_error_nomem(context); |
13404 | return; |
13405 | } |
13406 | |
13407 | if( zNL && zCR ){ |
13408 | memcpy(&zOut[iOut], "replace(replace(" , 16); |
13409 | iOut += 16; |
13410 | }else{ |
13411 | memcpy(&zOut[iOut], "replace(" , 8); |
13412 | iOut += 8; |
13413 | } |
13414 | for(i=0; zText[i]; i++){ |
13415 | if( zText[i]=='\n' ){ |
13416 | memcpy(&zOut[iOut], zNL, nNL); |
13417 | iOut += nNL; |
13418 | }else if( zText[i]=='\r' ){ |
13419 | memcpy(&zOut[iOut], zCR, nCR); |
13420 | iOut += nCR; |
13421 | }else{ |
13422 | zOut[iOut] = zText[i]; |
13423 | iOut++; |
13424 | } |
13425 | } |
13426 | |
13427 | if( zNL ){ |
13428 | memcpy(&zOut[iOut], ",'" , 2); iOut += 2; |
13429 | memcpy(&zOut[iOut], zNL, nNL); iOut += nNL; |
13430 | memcpy(&zOut[iOut], "', char(10))" , 12); iOut += 12; |
13431 | } |
13432 | if( zCR ){ |
13433 | memcpy(&zOut[iOut], ",'" , 2); iOut += 2; |
13434 | memcpy(&zOut[iOut], zCR, nCR); iOut += nCR; |
13435 | memcpy(&zOut[iOut], "', char(13))" , 12); iOut += 12; |
13436 | } |
13437 | |
13438 | sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT); |
13439 | sqlite3_free(zOut); |
13440 | return; |
13441 | } |
13442 | } |
13443 | |
13444 | sqlite3_result_value(context, argv[0]); |
13445 | } |
13446 | |
13447 | /* |
13448 | ** This function is a no-op if recover handle p already contains an error |
13449 | ** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in |
13450 | ** this case. |
13451 | ** |
13452 | ** Otherwise, attempt to populate temporary table "recovery.schema" with the |
13453 | ** parts of the database schema that can be extracted from the input database. |
13454 | ** |
13455 | ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code |
13456 | ** and error message are left in the recover handle and a copy of the |
13457 | ** error code returned. It is not considered an error if part of all of |
13458 | ** the database schema cannot be recovered due to corruption. |
13459 | */ |
13460 | static int recoverCacheSchema(sqlite3_recover *p){ |
13461 | return recoverExec(p, p->dbOut, |
13462 | "WITH RECURSIVE pages(p) AS (" |
13463 | " SELECT 1" |
13464 | " UNION" |
13465 | " SELECT child FROM sqlite_dbptr('getpage()'), pages WHERE pgno=p" |
13466 | ")" |
13467 | "INSERT INTO recovery.schema SELECT" |
13468 | " max(CASE WHEN field=0 THEN value ELSE NULL END)," |
13469 | " max(CASE WHEN field=1 THEN value ELSE NULL END)," |
13470 | " max(CASE WHEN field=2 THEN value ELSE NULL END)," |
13471 | " max(CASE WHEN field=3 THEN value ELSE NULL END)," |
13472 | " max(CASE WHEN field=4 THEN value ELSE NULL END)" |
13473 | "FROM sqlite_dbdata('getpage()') WHERE pgno IN (" |
13474 | " SELECT p FROM pages" |
13475 | ") GROUP BY pgno, cell" |
13476 | ); |
13477 | } |
13478 | |
13479 | /* |
13480 | ** If this recover handle is not in SQL callback mode (i.e. was not created |
13481 | ** using sqlite3_recover_init_sql()) of if an error has already occurred, |
13482 | ** this function is a no-op. Otherwise, issue a callback with SQL statement |
13483 | ** zSql as the parameter. |
13484 | ** |
13485 | ** If the callback returns non-zero, set the recover handle error code to |
13486 | ** the value returned (so that the caller will abandon processing). |
13487 | */ |
13488 | static void recoverSqlCallback(sqlite3_recover *p, const char *zSql){ |
13489 | if( p->errCode==SQLITE_OK && p->xSql ){ |
13490 | int res = p->xSql(p->pSqlCtx, zSql); |
13491 | if( res ){ |
13492 | recoverError(p, SQLITE_ERROR, "callback returned an error - %d" , res); |
13493 | } |
13494 | } |
13495 | } |
13496 | |
13497 | /* |
13498 | ** Transfer the following settings from the input database to the output |
13499 | ** database: |
13500 | ** |
13501 | ** + page-size, |
13502 | ** + auto-vacuum settings, |
13503 | ** + database encoding, |
13504 | ** + user-version (PRAGMA user_version), and |
13505 | ** + application-id (PRAGMA application_id), and |
13506 | */ |
13507 | static void recoverTransferSettings(sqlite3_recover *p){ |
13508 | const char *aPragma[] = { |
13509 | "encoding" , |
13510 | "page_size" , |
13511 | "auto_vacuum" , |
13512 | "user_version" , |
13513 | "application_id" |
13514 | }; |
13515 | int ii; |
13516 | |
13517 | /* Truncate the output database to 0 pages in size. This is done by |
13518 | ** opening a new, empty, temp db, then using the backup API to clobber |
13519 | ** any existing output db with a copy of it. */ |
13520 | if( p->errCode==SQLITE_OK ){ |
13521 | sqlite3 *db2 = 0; |
13522 | int rc = sqlite3_open("" , &db2); |
13523 | if( rc!=SQLITE_OK ){ |
13524 | recoverDbError(p, db2); |
13525 | return; |
13526 | } |
13527 | |
13528 | for(ii=0; ii<sizeof(aPragma)/sizeof(aPragma[0]); ii++){ |
13529 | const char *zPrag = aPragma[ii]; |
13530 | sqlite3_stmt *p1 = 0; |
13531 | p1 = recoverPreparePrintf(p, p->dbIn, "PRAGMA %Q.%s" , p->zDb, zPrag); |
13532 | if( p->errCode==SQLITE_OK && sqlite3_step(p1)==SQLITE_ROW ){ |
13533 | const char *zArg = (const char*)sqlite3_column_text(p1, 0); |
13534 | char *z2 = recoverMPrintf(p, "PRAGMA %s = %Q" , zPrag, zArg); |
13535 | recoverSqlCallback(p, z2); |
13536 | recoverExec(p, db2, z2); |
13537 | sqlite3_free(z2); |
13538 | if( zArg==0 ){ |
13539 | recoverError(p, SQLITE_NOMEM, 0); |
13540 | } |
13541 | } |
13542 | recoverFinalize(p, p1); |
13543 | } |
13544 | recoverExec(p, db2, "CREATE TABLE t1(a); DROP TABLE t1;" ); |
13545 | |
13546 | if( p->errCode==SQLITE_OK ){ |
13547 | sqlite3 *db = p->dbOut; |
13548 | sqlite3_backup *pBackup = sqlite3_backup_init(db, "main" , db2, "main" ); |
13549 | if( pBackup ){ |
13550 | sqlite3_backup_step(pBackup, -1); |
13551 | p->errCode = sqlite3_backup_finish(pBackup); |
13552 | }else{ |
13553 | recoverDbError(p, db); |
13554 | } |
13555 | } |
13556 | |
13557 | sqlite3_close(db2); |
13558 | } |
13559 | } |
13560 | |
13561 | /* |
13562 | ** This function is a no-op if recover handle p already contains an error |
13563 | ** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in |
13564 | ** this case. |
13565 | ** |
13566 | ** Otherwise, an attempt is made to open the output database, attach |
13567 | ** and create the schema of the temporary database used to store |
13568 | ** intermediate data, and to register all required user functions and |
13569 | ** virtual table modules with the output handle. |
13570 | ** |
13571 | ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code |
13572 | ** and error message are left in the recover handle and a copy of the |
13573 | ** error code returned. |
13574 | */ |
13575 | static int recoverOpenOutput(sqlite3_recover *p){ |
13576 | struct Func { |
13577 | const char *zName; |
13578 | int nArg; |
13579 | void (*xFunc)(sqlite3_context*,int,sqlite3_value **); |
13580 | } aFunc[] = { |
13581 | { "getpage" , 1, recoverGetPage }, |
13582 | { "page_is_used" , 1, recoverPageIsUsed }, |
13583 | { "read_i32" , 2, recoverReadI32 }, |
13584 | { "escape_crnl" , 1, recoverEscapeCrnl }, |
13585 | }; |
13586 | |
13587 | const int flags = SQLITE_OPEN_URI|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE; |
13588 | sqlite3 *db = 0; /* New database handle */ |
13589 | int ii; /* For iterating through aFunc[] */ |
13590 | |
13591 | assert( p->dbOut==0 ); |
13592 | |
13593 | if( sqlite3_open_v2(p->zUri, &db, flags, 0) ){ |
13594 | recoverDbError(p, db); |
13595 | } |
13596 | |
13597 | /* Register the sqlite_dbdata and sqlite_dbptr virtual table modules. |
13598 | ** These two are registered with the output database handle - this |
13599 | ** module depends on the input handle supporting the sqlite_dbpage |
13600 | ** virtual table only. */ |
13601 | if( p->errCode==SQLITE_OK ){ |
13602 | p->errCode = sqlite3_dbdata_init(db, 0, 0); |
13603 | } |
13604 | |
13605 | /* Register the custom user-functions with the output handle. */ |
13606 | for(ii=0; p->errCode==SQLITE_OK && ii<sizeof(aFunc)/sizeof(aFunc[0]); ii++){ |
13607 | p->errCode = sqlite3_create_function(db, aFunc[ii].zName, |
13608 | aFunc[ii].nArg, SQLITE_UTF8, (void*)p, aFunc[ii].xFunc, 0, 0 |
13609 | ); |
13610 | } |
13611 | |
13612 | p->dbOut = db; |
13613 | return p->errCode; |
13614 | } |
13615 | |
13616 | /* |
13617 | ** Attach the auxiliary database 'recovery' to the output database handle. |
13618 | ** This temporary database is used during the recovery process and then |
13619 | ** discarded. |
13620 | */ |
13621 | static void recoverOpenRecovery(sqlite3_recover *p){ |
13622 | char *zSql = recoverMPrintf(p, "ATTACH %Q AS recovery;" , p->zStateDb); |
13623 | recoverExec(p, p->dbOut, zSql); |
13624 | recoverExec(p, p->dbOut, |
13625 | "PRAGMA writable_schema = 1;" |
13626 | "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);" |
13627 | "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);" |
13628 | ); |
13629 | sqlite3_free(zSql); |
13630 | } |
13631 | |
13632 | |
13633 | /* |
13634 | ** This function is a no-op if recover handle p already contains an error |
13635 | ** (if p->errCode!=SQLITE_OK). |
13636 | ** |
13637 | ** Otherwise, argument zName must be the name of a table that has just been |
13638 | ** created in the output database. This function queries the output db |
13639 | ** for the schema of said table, and creates a RecoverTable object to |
13640 | ** store the schema in memory. The new RecoverTable object is linked into |
13641 | ** the list at sqlite3_recover.pTblList. |
13642 | ** |
13643 | ** Parameter iRoot must be the root page of table zName in the INPUT |
13644 | ** database. |
13645 | */ |
13646 | static void recoverAddTable( |
13647 | sqlite3_recover *p, |
13648 | const char *zName, /* Name of table created in output db */ |
13649 | i64 iRoot /* Root page of same table in INPUT db */ |
13650 | ){ |
13651 | sqlite3_stmt *pStmt = recoverPreparePrintf(p, p->dbOut, |
13652 | "PRAGMA table_xinfo(%Q)" , zName |
13653 | ); |
13654 | |
13655 | if( pStmt ){ |
13656 | int iPk = -1; |
13657 | int iBind = 1; |
13658 | RecoverTable *pNew = 0; |
13659 | int nCol = 0; |
13660 | int nName = recoverStrlen(zName); |
13661 | int nByte = 0; |
13662 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
13663 | nCol++; |
13664 | nByte += (sqlite3_column_bytes(pStmt, 1)+1); |
13665 | } |
13666 | nByte += sizeof(RecoverTable) + nCol*sizeof(RecoverColumn) + nName+1; |
13667 | recoverReset(p, pStmt); |
13668 | |
13669 | pNew = recoverMalloc(p, nByte); |
13670 | if( pNew ){ |
13671 | int i = 0; |
13672 | int iField = 0; |
13673 | char *csr = 0; |
13674 | pNew->aCol = (RecoverColumn*)&pNew[1]; |
13675 | pNew->zTab = csr = (char*)&pNew->aCol[nCol]; |
13676 | pNew->nCol = nCol; |
13677 | pNew->iRoot = iRoot; |
13678 | memcpy(csr, zName, nName); |
13679 | csr += nName+1; |
13680 | |
13681 | for(i=0; sqlite3_step(pStmt)==SQLITE_ROW; i++){ |
13682 | int iPKF = sqlite3_column_int(pStmt, 5); |
13683 | int n = sqlite3_column_bytes(pStmt, 1); |
13684 | const char *z = (const char*)sqlite3_column_text(pStmt, 1); |
13685 | const char *zType = (const char*)sqlite3_column_text(pStmt, 2); |
13686 | int eHidden = sqlite3_column_int(pStmt, 6); |
13687 | |
13688 | if( iPk==-1 && iPKF==1 && !sqlite3_stricmp("integer" , zType) ) iPk = i; |
13689 | if( iPKF>1 ) iPk = -2; |
13690 | pNew->aCol[i].zCol = csr; |
13691 | pNew->aCol[i].eHidden = eHidden; |
13692 | if( eHidden==RECOVER_EHIDDEN_VIRTUAL ){ |
13693 | pNew->aCol[i].iField = -1; |
13694 | }else{ |
13695 | pNew->aCol[i].iField = iField++; |
13696 | } |
13697 | if( eHidden!=RECOVER_EHIDDEN_VIRTUAL |
13698 | && eHidden!=RECOVER_EHIDDEN_STORED |
13699 | ){ |
13700 | pNew->aCol[i].iBind = iBind++; |
13701 | } |
13702 | memcpy(csr, z, n); |
13703 | csr += (n+1); |
13704 | } |
13705 | |
13706 | pNew->pNext = p->pTblList; |
13707 | p->pTblList = pNew; |
13708 | pNew->bIntkey = 1; |
13709 | } |
13710 | |
13711 | recoverFinalize(p, pStmt); |
13712 | |
13713 | pStmt = recoverPreparePrintf(p, p->dbOut, "PRAGMA index_xinfo(%Q)" , zName); |
13714 | while( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ |
13715 | int iField = sqlite3_column_int(pStmt, 0); |
13716 | int iCol = sqlite3_column_int(pStmt, 1); |
13717 | |
13718 | assert( iField<pNew->nCol && iCol<pNew->nCol ); |
13719 | pNew->aCol[iCol].iField = iField; |
13720 | |
13721 | pNew->bIntkey = 0; |
13722 | iPk = -2; |
13723 | } |
13724 | recoverFinalize(p, pStmt); |
13725 | |
13726 | if( p->errCode==SQLITE_OK ){ |
13727 | if( iPk>=0 ){ |
13728 | pNew->aCol[iPk].bIPK = 1; |
13729 | }else if( pNew->bIntkey ){ |
13730 | pNew->iRowidBind = iBind++; |
13731 | } |
13732 | } |
13733 | } |
13734 | } |
13735 | |
13736 | /* |
13737 | ** This function is called after recoverCacheSchema() has cached those parts |
13738 | ** of the input database schema that could be recovered in temporary table |
13739 | ** "recovery.schema". This function creates in the output database copies |
13740 | ** of all parts of that schema that must be created before the tables can |
13741 | ** be populated. Specifically, this means: |
13742 | ** |
13743 | ** * all tables that are not VIRTUAL, and |
13744 | ** * UNIQUE indexes. |
13745 | ** |
13746 | ** If the recovery handle uses SQL callbacks, then callbacks containing |
13747 | ** the associated "CREATE TABLE" and "CREATE INDEX" statements are made. |
13748 | ** |
13749 | ** Additionally, records are added to the sqlite_schema table of the |
13750 | ** output database for any VIRTUAL tables. The CREATE VIRTUAL TABLE |
13751 | ** records are written directly to sqlite_schema, not actually executed. |
13752 | ** If the handle is in SQL callback mode, then callbacks are invoked |
13753 | ** with equivalent SQL statements. |
13754 | */ |
13755 | static int recoverWriteSchema1(sqlite3_recover *p){ |
13756 | sqlite3_stmt *pSelect = 0; |
13757 | sqlite3_stmt *pTblname = 0; |
13758 | |
13759 | pSelect = recoverPrepare(p, p->dbOut, |
13760 | "WITH dbschema(rootpage, name, sql, tbl, isVirtual, isIndex) AS (" |
13761 | " SELECT rootpage, name, sql, " |
13762 | " type='table', " |
13763 | " sql LIKE 'create virtual%'," |
13764 | " (type='index' AND (sql LIKE '%unique%' OR ?1))" |
13765 | " FROM recovery.schema" |
13766 | ")" |
13767 | "SELECT rootpage, tbl, isVirtual, name, sql" |
13768 | " FROM dbschema " |
13769 | " WHERE tbl OR isIndex" |
13770 | " ORDER BY tbl DESC, name=='sqlite_sequence' DESC" |
13771 | ); |
13772 | |
13773 | pTblname = recoverPrepare(p, p->dbOut, |
13774 | "SELECT name FROM sqlite_schema " |
13775 | "WHERE type='table' ORDER BY rowid DESC LIMIT 1" |
13776 | ); |
13777 | |
13778 | if( pSelect ){ |
13779 | sqlite3_bind_int(pSelect, 1, p->bSlowIndexes); |
13780 | while( sqlite3_step(pSelect)==SQLITE_ROW ){ |
13781 | i64 iRoot = sqlite3_column_int64(pSelect, 0); |
13782 | int bTable = sqlite3_column_int(pSelect, 1); |
13783 | int bVirtual = sqlite3_column_int(pSelect, 2); |
13784 | const char *zName = (const char*)sqlite3_column_text(pSelect, 3); |
13785 | const char *zSql = (const char*)sqlite3_column_text(pSelect, 4); |
13786 | char *zFree = 0; |
13787 | int rc = SQLITE_OK; |
13788 | |
13789 | if( bVirtual ){ |
13790 | zSql = (const char*)(zFree = recoverMPrintf(p, |
13791 | "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)" , |
13792 | zName, zName, zSql |
13793 | )); |
13794 | } |
13795 | rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0); |
13796 | if( rc==SQLITE_OK ){ |
13797 | recoverSqlCallback(p, zSql); |
13798 | if( bTable && !bVirtual ){ |
13799 | if( SQLITE_ROW==sqlite3_step(pTblname) ){ |
13800 | const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0); |
13801 | recoverAddTable(p, zTbl, iRoot); |
13802 | } |
13803 | recoverReset(p, pTblname); |
13804 | } |
13805 | }else if( rc!=SQLITE_ERROR ){ |
13806 | recoverDbError(p, p->dbOut); |
13807 | } |
13808 | sqlite3_free(zFree); |
13809 | } |
13810 | } |
13811 | recoverFinalize(p, pSelect); |
13812 | recoverFinalize(p, pTblname); |
13813 | |
13814 | return p->errCode; |
13815 | } |
13816 | |
13817 | /* |
13818 | ** This function is called after the output database has been populated. It |
13819 | ** adds all recovered schema elements that were not created in the output |
13820 | ** database by recoverWriteSchema1() - everything except for tables and |
13821 | ** UNIQUE indexes. Specifically: |
13822 | ** |
13823 | ** * views, |
13824 | ** * triggers, |
13825 | ** * non-UNIQUE indexes. |
13826 | ** |
13827 | ** If the recover handle is in SQL callback mode, then equivalent callbacks |
13828 | ** are issued to create the schema elements. |
13829 | */ |
13830 | static int recoverWriteSchema2(sqlite3_recover *p){ |
13831 | sqlite3_stmt *pSelect = 0; |
13832 | |
13833 | pSelect = recoverPrepare(p, p->dbOut, |
13834 | p->bSlowIndexes ? |
13835 | "SELECT rootpage, sql FROM recovery.schema " |
13836 | " WHERE type!='table' AND type!='index'" |
13837 | : |
13838 | "SELECT rootpage, sql FROM recovery.schema " |
13839 | " WHERE type!='table' AND (type!='index' OR sql NOT LIKE '%unique%')" |
13840 | ); |
13841 | |
13842 | if( pSelect ){ |
13843 | while( sqlite3_step(pSelect)==SQLITE_ROW ){ |
13844 | const char *zSql = (const char*)sqlite3_column_text(pSelect, 1); |
13845 | int rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0); |
13846 | if( rc==SQLITE_OK ){ |
13847 | recoverSqlCallback(p, zSql); |
13848 | }else if( rc!=SQLITE_ERROR ){ |
13849 | recoverDbError(p, p->dbOut); |
13850 | } |
13851 | } |
13852 | } |
13853 | recoverFinalize(p, pSelect); |
13854 | |
13855 | return p->errCode; |
13856 | } |
13857 | |
13858 | /* |
13859 | ** This function is a no-op if recover handle p already contains an error |
13860 | ** (if p->errCode!=SQLITE_OK). In this case it returns NULL. |
13861 | ** |
13862 | ** Otherwise, if the recover handle is configured to create an output |
13863 | ** database (was created by sqlite3_recover_init()), then this function |
13864 | ** prepares and returns an SQL statement to INSERT a new record into table |
13865 | ** pTab, assuming the first nField fields of a record extracted from disk |
13866 | ** are valid. |
13867 | ** |
13868 | ** For example, if table pTab is: |
13869 | ** |
13870 | ** CREATE TABLE name(a, b GENERATED ALWAYS AS (a+1) STORED, c, d, e); |
13871 | ** |
13872 | ** And nField is 4, then the SQL statement prepared and returned is: |
13873 | ** |
13874 | ** INSERT INTO (a, c, d) VALUES (?1, ?2, ?3); |
13875 | ** |
13876 | ** In this case even though 4 values were extracted from the input db, |
13877 | ** only 3 are written to the output, as the generated STORED column |
13878 | ** cannot be written. |
13879 | ** |
13880 | ** If the recover handle is in SQL callback mode, then the SQL statement |
13881 | ** prepared is such that evaluating it returns a single row containing |
13882 | ** a single text value - itself an SQL statement similar to the above, |
13883 | ** except with SQL literals in place of the variables. For example: |
13884 | ** |
13885 | ** SELECT 'INSERT INTO (a, c, d) VALUES (' |
13886 | ** || quote(?1) || ', ' |
13887 | ** || quote(?2) || ', ' |
13888 | ** || quote(?3) || ')'; |
13889 | ** |
13890 | ** In either case, it is the responsibility of the caller to eventually |
13891 | ** free the statement handle using sqlite3_finalize(). |
13892 | */ |
13893 | static sqlite3_stmt *recoverInsertStmt( |
13894 | sqlite3_recover *p, |
13895 | RecoverTable *pTab, |
13896 | int nField |
13897 | ){ |
13898 | sqlite3_stmt *pRet = 0; |
13899 | const char *zSep = "" ; |
13900 | const char *zSqlSep = "" ; |
13901 | char *zSql = 0; |
13902 | char *zFinal = 0; |
13903 | char *zBind = 0; |
13904 | int ii; |
13905 | int bSql = p->xSql ? 1 : 0; |
13906 | |
13907 | if( nField<=0 ) return 0; |
13908 | |
13909 | assert( nField<=pTab->nCol ); |
13910 | |
13911 | zSql = recoverMPrintf(p, "INSERT OR IGNORE INTO %Q(" , pTab->zTab); |
13912 | |
13913 | if( pTab->iRowidBind ){ |
13914 | assert( pTab->bIntkey ); |
13915 | zSql = recoverMPrintf(p, "%z_rowid_" , zSql); |
13916 | if( bSql ){ |
13917 | zBind = recoverMPrintf(p, "%zquote(?%d)" , zBind, pTab->iRowidBind); |
13918 | }else{ |
13919 | zBind = recoverMPrintf(p, "%z?%d" , zBind, pTab->iRowidBind); |
13920 | } |
13921 | zSqlSep = "||', '||" ; |
13922 | zSep = ", " ; |
13923 | } |
13924 | |
13925 | for(ii=0; ii<nField; ii++){ |
13926 | int eHidden = pTab->aCol[ii].eHidden; |
13927 | if( eHidden!=RECOVER_EHIDDEN_VIRTUAL |
13928 | && eHidden!=RECOVER_EHIDDEN_STORED |
13929 | ){ |
13930 | assert( pTab->aCol[ii].iField>=0 && pTab->aCol[ii].iBind>=1 ); |
13931 | zSql = recoverMPrintf(p, "%z%s%Q" , zSql, zSep, pTab->aCol[ii].zCol); |
13932 | |
13933 | if( bSql ){ |
13934 | zBind = recoverMPrintf(p, |
13935 | "%z%sescape_crnl(quote(?%d))" , zBind, zSqlSep, pTab->aCol[ii].iBind |
13936 | ); |
13937 | zSqlSep = "||', '||" ; |
13938 | }else{ |
13939 | zBind = recoverMPrintf(p, "%z%s?%d" , zBind, zSep, pTab->aCol[ii].iBind); |
13940 | } |
13941 | zSep = ", " ; |
13942 | } |
13943 | } |
13944 | |
13945 | if( bSql ){ |
13946 | zFinal = recoverMPrintf(p, "SELECT %Q || ') VALUES (' || %s || ')'" , |
13947 | zSql, zBind |
13948 | ); |
13949 | }else{ |
13950 | zFinal = recoverMPrintf(p, "%s) VALUES (%s)" , zSql, zBind); |
13951 | } |
13952 | |
13953 | pRet = recoverPrepare(p, p->dbOut, zFinal); |
13954 | sqlite3_free(zSql); |
13955 | sqlite3_free(zBind); |
13956 | sqlite3_free(zFinal); |
13957 | |
13958 | return pRet; |
13959 | } |
13960 | |
13961 | |
13962 | /* |
13963 | ** Search the list of RecoverTable objects at p->pTblList for one that |
13964 | ** has root page iRoot in the input database. If such an object is found, |
13965 | ** return a pointer to it. Otherwise, return NULL. |
13966 | */ |
13967 | static RecoverTable *recoverFindTable(sqlite3_recover *p, u32 iRoot){ |
13968 | RecoverTable *pRet = 0; |
13969 | for(pRet=p->pTblList; pRet && pRet->iRoot!=iRoot; pRet=pRet->pNext); |
13970 | return pRet; |
13971 | } |
13972 | |
13973 | /* |
13974 | ** This function attempts to create a lost and found table within the |
13975 | ** output db. If successful, it returns a pointer to a buffer containing |
13976 | ** the name of the new table. It is the responsibility of the caller to |
13977 | ** eventually free this buffer using sqlite3_free(). |
13978 | ** |
13979 | ** If an error occurs, NULL is returned and an error code and error |
13980 | ** message left in the recover handle. |
13981 | */ |
13982 | static char *recoverLostAndFoundCreate( |
13983 | sqlite3_recover *p, /* Recover object */ |
13984 | int nField /* Number of column fields in new table */ |
13985 | ){ |
13986 | char *zTbl = 0; |
13987 | sqlite3_stmt *pProbe = 0; |
13988 | int ii = 0; |
13989 | |
13990 | pProbe = recoverPrepare(p, p->dbOut, |
13991 | "SELECT 1 FROM sqlite_schema WHERE name=?" |
13992 | ); |
13993 | for(ii=-1; zTbl==0 && p->errCode==SQLITE_OK && ii<1000; ii++){ |
13994 | int bFail = 0; |
13995 | if( ii<0 ){ |
13996 | zTbl = recoverMPrintf(p, "%s" , p->zLostAndFound); |
13997 | }else{ |
13998 | zTbl = recoverMPrintf(p, "%s_%d" , p->zLostAndFound, ii); |
13999 | } |
14000 | |
14001 | if( p->errCode==SQLITE_OK ){ |
14002 | sqlite3_bind_text(pProbe, 1, zTbl, -1, SQLITE_STATIC); |
14003 | if( SQLITE_ROW==sqlite3_step(pProbe) ){ |
14004 | bFail = 1; |
14005 | } |
14006 | recoverReset(p, pProbe); |
14007 | } |
14008 | |
14009 | if( bFail ){ |
14010 | sqlite3_clear_bindings(pProbe); |
14011 | sqlite3_free(zTbl); |
14012 | zTbl = 0; |
14013 | } |
14014 | } |
14015 | recoverFinalize(p, pProbe); |
14016 | |
14017 | if( zTbl ){ |
14018 | const char *zSep = 0; |
14019 | char *zField = 0; |
14020 | char *zSql = 0; |
14021 | |
14022 | zSep = "rootpgno INTEGER, pgno INTEGER, nfield INTEGER, id INTEGER, " ; |
14023 | for(ii=0; p->errCode==SQLITE_OK && ii<nField; ii++){ |
14024 | zField = recoverMPrintf(p, "%z%sc%d" , zField, zSep, ii); |
14025 | zSep = ", " ; |
14026 | } |
14027 | |
14028 | zSql = recoverMPrintf(p, "CREATE TABLE %s(%s)" , zTbl, zField); |
14029 | sqlite3_free(zField); |
14030 | |
14031 | recoverExec(p, p->dbOut, zSql); |
14032 | recoverSqlCallback(p, zSql); |
14033 | sqlite3_free(zSql); |
14034 | }else if( p->errCode==SQLITE_OK ){ |
14035 | recoverError( |
14036 | p, SQLITE_ERROR, "failed to create %s output table" , p->zLostAndFound |
14037 | ); |
14038 | } |
14039 | |
14040 | return zTbl; |
14041 | } |
14042 | |
14043 | /* |
14044 | ** Synthesize and prepare an INSERT statement to write to the lost_and_found |
14045 | ** table in the output database. The name of the table is zTab, and it has |
14046 | ** nField c* fields. |
14047 | */ |
14048 | static sqlite3_stmt *recoverLostAndFoundInsert( |
14049 | sqlite3_recover *p, |
14050 | const char *zTab, |
14051 | int nField |
14052 | ){ |
14053 | int nTotal = nField + 4; |
14054 | int ii; |
14055 | char *zBind = 0; |
14056 | sqlite3_stmt *pRet = 0; |
14057 | |
14058 | if( p->xSql==0 ){ |
14059 | for(ii=0; ii<nTotal; ii++){ |
14060 | zBind = recoverMPrintf(p, "%z%s?" , zBind, zBind?", " :"" , ii); |
14061 | } |
14062 | pRet = recoverPreparePrintf( |
14063 | p, p->dbOut, "INSERT INTO %s VALUES(%s)" , zTab, zBind |
14064 | ); |
14065 | }else{ |
14066 | const char *zSep = "" ; |
14067 | for(ii=0; ii<nTotal; ii++){ |
14068 | zBind = recoverMPrintf(p, "%z%squote(?)" , zBind, zSep); |
14069 | zSep = "|| ', ' ||" ; |
14070 | } |
14071 | pRet = recoverPreparePrintf( |
14072 | p, p->dbOut, "SELECT 'INSERT INTO %s VALUES(' || %s || ')'" , zTab, zBind |
14073 | ); |
14074 | } |
14075 | |
14076 | sqlite3_free(zBind); |
14077 | return pRet; |
14078 | } |
14079 | |
14080 | /* |
14081 | ** Input database page iPg contains data that will be written to the |
14082 | ** lost-and-found table of the output database. This function attempts |
14083 | ** to identify the root page of the tree that page iPg belonged to. |
14084 | ** If successful, it sets output variable (*piRoot) to the page number |
14085 | ** of the root page and returns SQLITE_OK. Otherwise, if an error occurs, |
14086 | ** an SQLite error code is returned and the final value of *piRoot |
14087 | ** undefined. |
14088 | */ |
14089 | static int recoverLostAndFoundFindRoot( |
14090 | sqlite3_recover *p, |
14091 | i64 iPg, |
14092 | i64 *piRoot |
14093 | ){ |
14094 | RecoverStateLAF *pLaf = &p->laf; |
14095 | |
14096 | if( pLaf->pFindRoot==0 ){ |
14097 | pLaf->pFindRoot = recoverPrepare(p, p->dbOut, |
14098 | "WITH RECURSIVE p(pgno) AS (" |
14099 | " SELECT ?" |
14100 | " UNION" |
14101 | " SELECT parent FROM recovery.map AS m, p WHERE m.pgno=p.pgno" |
14102 | ") " |
14103 | "SELECT p.pgno FROM p, recovery.map m WHERE m.pgno=p.pgno " |
14104 | " AND m.parent IS NULL" |
14105 | ); |
14106 | } |
14107 | if( p->errCode==SQLITE_OK ){ |
14108 | sqlite3_bind_int64(pLaf->pFindRoot, 1, iPg); |
14109 | if( sqlite3_step(pLaf->pFindRoot)==SQLITE_ROW ){ |
14110 | *piRoot = sqlite3_column_int64(pLaf->pFindRoot, 0); |
14111 | }else{ |
14112 | *piRoot = iPg; |
14113 | } |
14114 | recoverReset(p, pLaf->pFindRoot); |
14115 | } |
14116 | return p->errCode; |
14117 | } |
14118 | |
14119 | /* |
14120 | ** Recover data from page iPage of the input database and write it to |
14121 | ** the lost-and-found table in the output database. |
14122 | */ |
14123 | static void recoverLostAndFoundOnePage(sqlite3_recover *p, i64 iPage){ |
14124 | RecoverStateLAF *pLaf = &p->laf; |
14125 | sqlite3_value **apVal = pLaf->apVal; |
14126 | sqlite3_stmt *pPageData = pLaf->pPageData; |
14127 | sqlite3_stmt *pInsert = pLaf->pInsert; |
14128 | |
14129 | int nVal = -1; |
14130 | int iPrevCell = 0; |
14131 | i64 iRoot = 0; |
14132 | int bHaveRowid = 0; |
14133 | i64 iRowid = 0; |
14134 | int ii = 0; |
14135 | |
14136 | if( recoverLostAndFoundFindRoot(p, iPage, &iRoot) ) return; |
14137 | sqlite3_bind_int64(pPageData, 1, iPage); |
14138 | while( p->errCode==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPageData) ){ |
14139 | int iCell = sqlite3_column_int64(pPageData, 0); |
14140 | int iField = sqlite3_column_int64(pPageData, 1); |
14141 | |
14142 | if( iPrevCell!=iCell && nVal>=0 ){ |
14143 | /* Insert the new row */ |
14144 | sqlite3_bind_int64(pInsert, 1, iRoot); /* rootpgno */ |
14145 | sqlite3_bind_int64(pInsert, 2, iPage); /* pgno */ |
14146 | sqlite3_bind_int(pInsert, 3, nVal); /* nfield */ |
14147 | if( bHaveRowid ){ |
14148 | sqlite3_bind_int64(pInsert, 4, iRowid); /* id */ |
14149 | } |
14150 | for(ii=0; ii<nVal; ii++){ |
14151 | recoverBindValue(p, pInsert, 5+ii, apVal[ii]); |
14152 | } |
14153 | if( sqlite3_step(pInsert)==SQLITE_ROW ){ |
14154 | recoverSqlCallback(p, (const char*)sqlite3_column_text(pInsert, 0)); |
14155 | } |
14156 | recoverReset(p, pInsert); |
14157 | |
14158 | /* Discard the accumulated row data */ |
14159 | for(ii=0; ii<nVal; ii++){ |
14160 | sqlite3_value_free(apVal[ii]); |
14161 | apVal[ii] = 0; |
14162 | } |
14163 | sqlite3_clear_bindings(pInsert); |
14164 | bHaveRowid = 0; |
14165 | nVal = -1; |
14166 | } |
14167 | |
14168 | if( iCell<0 ) break; |
14169 | |
14170 | if( iField<0 ){ |
14171 | assert( nVal==-1 ); |
14172 | iRowid = sqlite3_column_int64(pPageData, 2); |
14173 | bHaveRowid = 1; |
14174 | nVal = 0; |
14175 | }else if( iField<pLaf->nMaxField ){ |
14176 | sqlite3_value *pVal = sqlite3_column_value(pPageData, 2); |
14177 | apVal[iField] = sqlite3_value_dup(pVal); |
14178 | assert( iField==nVal || (nVal==-1 && iField==0) ); |
14179 | nVal = iField+1; |
14180 | if( apVal[iField]==0 ){ |
14181 | recoverError(p, SQLITE_NOMEM, 0); |
14182 | } |
14183 | } |
14184 | |
14185 | iPrevCell = iCell; |
14186 | } |
14187 | recoverReset(p, pPageData); |
14188 | |
14189 | for(ii=0; ii<nVal; ii++){ |
14190 | sqlite3_value_free(apVal[ii]); |
14191 | apVal[ii] = 0; |
14192 | } |
14193 | } |
14194 | |
14195 | /* |
14196 | ** Perform one step (sqlite3_recover_step()) of work for the connection |
14197 | ** passed as the only argument, which is guaranteed to be in |
14198 | ** RECOVER_STATE_LOSTANDFOUND3 state - during which the lost-and-found |
14199 | ** table of the output database is populated with recovered data that can |
14200 | ** not be assigned to any recovered schema object. |
14201 | */ |
14202 | static int recoverLostAndFound3Step(sqlite3_recover *p){ |
14203 | RecoverStateLAF *pLaf = &p->laf; |
14204 | if( p->errCode==SQLITE_OK ){ |
14205 | if( pLaf->pInsert==0 ){ |
14206 | return SQLITE_DONE; |
14207 | }else{ |
14208 | if( p->errCode==SQLITE_OK ){ |
14209 | int res = sqlite3_step(pLaf->pAllPage); |
14210 | if( res==SQLITE_ROW ){ |
14211 | i64 iPage = sqlite3_column_int64(pLaf->pAllPage, 0); |
14212 | if( recoverBitmapQuery(pLaf->pUsed, iPage)==0 ){ |
14213 | recoverLostAndFoundOnePage(p, iPage); |
14214 | } |
14215 | }else{ |
14216 | recoverReset(p, pLaf->pAllPage); |
14217 | return SQLITE_DONE; |
14218 | } |
14219 | } |
14220 | } |
14221 | } |
14222 | return SQLITE_OK; |
14223 | } |
14224 | |
14225 | /* |
14226 | ** Initialize resources required in RECOVER_STATE_LOSTANDFOUND3 |
14227 | ** state - during which the lost-and-found table of the output database |
14228 | ** is populated with recovered data that can not be assigned to any |
14229 | ** recovered schema object. |
14230 | */ |
14231 | static void recoverLostAndFound3Init(sqlite3_recover *p){ |
14232 | RecoverStateLAF *pLaf = &p->laf; |
14233 | |
14234 | if( pLaf->nMaxField>0 ){ |
14235 | char *zTab = 0; /* Name of lost_and_found table */ |
14236 | |
14237 | zTab = recoverLostAndFoundCreate(p, pLaf->nMaxField); |
14238 | pLaf->pInsert = recoverLostAndFoundInsert(p, zTab, pLaf->nMaxField); |
14239 | sqlite3_free(zTab); |
14240 | |
14241 | pLaf->pAllPage = recoverPreparePrintf(p, p->dbOut, |
14242 | "WITH RECURSIVE seq(ii) AS (" |
14243 | " SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld" |
14244 | ")" |
14245 | "SELECT ii FROM seq" , p->laf.nPg |
14246 | ); |
14247 | pLaf->pPageData = recoverPrepare(p, p->dbOut, |
14248 | "SELECT cell, field, value " |
14249 | "FROM sqlite_dbdata('getpage()') d WHERE d.pgno=? " |
14250 | "UNION ALL " |
14251 | "SELECT -1, -1, -1" |
14252 | ); |
14253 | |
14254 | pLaf->apVal = (sqlite3_value**)recoverMalloc(p, |
14255 | pLaf->nMaxField*sizeof(sqlite3_value*) |
14256 | ); |
14257 | } |
14258 | } |
14259 | |
14260 | /* |
14261 | ** Initialize resources required in RECOVER_STATE_WRITING state - during which |
14262 | ** tables recovered from the schema of the input database are populated with |
14263 | ** recovered data. |
14264 | */ |
14265 | static int recoverWriteDataInit(sqlite3_recover *p){ |
14266 | RecoverStateW1 *p1 = &p->w1; |
14267 | RecoverTable *pTbl = 0; |
14268 | int nByte = 0; |
14269 | |
14270 | /* Figure out the maximum number of columns for any table in the schema */ |
14271 | assert( p1->nMax==0 ); |
14272 | for(pTbl=p->pTblList; pTbl; pTbl=pTbl->pNext){ |
14273 | if( pTbl->nCol>p1->nMax ) p1->nMax = pTbl->nCol; |
14274 | } |
14275 | |
14276 | /* Allocate an array of (sqlite3_value*) in which to accumulate the values |
14277 | ** that will be written to the output database in a single row. */ |
14278 | nByte = sizeof(sqlite3_value*) * (p1->nMax+1); |
14279 | p1->apVal = (sqlite3_value**)recoverMalloc(p, nByte); |
14280 | if( p1->apVal==0 ) return p->errCode; |
14281 | |
14282 | /* Prepare the SELECT to loop through schema tables (pTbls) and the SELECT |
14283 | ** to loop through cells that appear to belong to a single table (pSel). */ |
14284 | p1->pTbls = recoverPrepare(p, p->dbOut, |
14285 | "SELECT rootpage FROM recovery.schema " |
14286 | " WHERE type='table' AND (sql NOT LIKE 'create virtual%')" |
14287 | " ORDER BY (tbl_name='sqlite_sequence') ASC" |
14288 | ); |
14289 | p1->pSel = recoverPrepare(p, p->dbOut, |
14290 | "WITH RECURSIVE pages(page) AS (" |
14291 | " SELECT ?1" |
14292 | " UNION" |
14293 | " SELECT child FROM sqlite_dbptr('getpage()'), pages " |
14294 | " WHERE pgno=page" |
14295 | ") " |
14296 | "SELECT page, cell, field, value " |
14297 | "FROM sqlite_dbdata('getpage()') d, pages p WHERE p.page=d.pgno " |
14298 | "UNION ALL " |
14299 | "SELECT 0, 0, 0, 0" |
14300 | ); |
14301 | |
14302 | return p->errCode; |
14303 | } |
14304 | |
14305 | /* |
14306 | ** Clean up resources allocated by recoverWriteDataInit() (stuff in |
14307 | ** sqlite3_recover.w1). |
14308 | */ |
14309 | static void recoverWriteDataCleanup(sqlite3_recover *p){ |
14310 | RecoverStateW1 *p1 = &p->w1; |
14311 | int ii; |
14312 | for(ii=0; ii<p1->nVal; ii++){ |
14313 | sqlite3_value_free(p1->apVal[ii]); |
14314 | } |
14315 | sqlite3_free(p1->apVal); |
14316 | recoverFinalize(p, p1->pInsert); |
14317 | recoverFinalize(p, p1->pTbls); |
14318 | recoverFinalize(p, p1->pSel); |
14319 | memset(p1, 0, sizeof(*p1)); |
14320 | } |
14321 | |
14322 | /* |
14323 | ** Perform one step (sqlite3_recover_step()) of work for the connection |
14324 | ** passed as the only argument, which is guaranteed to be in |
14325 | ** RECOVER_STATE_WRITING state - during which tables recovered from the |
14326 | ** schema of the input database are populated with recovered data. |
14327 | */ |
14328 | static int recoverWriteDataStep(sqlite3_recover *p){ |
14329 | RecoverStateW1 *p1 = &p->w1; |
14330 | sqlite3_stmt *pSel = p1->pSel; |
14331 | sqlite3_value **apVal = p1->apVal; |
14332 | |
14333 | if( p->errCode==SQLITE_OK && p1->pTab==0 ){ |
14334 | if( sqlite3_step(p1->pTbls)==SQLITE_ROW ){ |
14335 | i64 iRoot = sqlite3_column_int64(p1->pTbls, 0); |
14336 | p1->pTab = recoverFindTable(p, iRoot); |
14337 | |
14338 | recoverFinalize(p, p1->pInsert); |
14339 | p1->pInsert = 0; |
14340 | |
14341 | /* If this table is unknown, return early. The caller will invoke this |
14342 | ** function again and it will move on to the next table. */ |
14343 | if( p1->pTab==0 ) return p->errCode; |
14344 | |
14345 | /* If this is the sqlite_sequence table, delete any rows added by |
14346 | ** earlier INSERT statements on tables with AUTOINCREMENT primary |
14347 | ** keys before recovering its contents. The p1->pTbls SELECT statement |
14348 | ** is rigged to deliver "sqlite_sequence" last of all, so we don't |
14349 | ** worry about it being modified after it is recovered. */ |
14350 | if( sqlite3_stricmp("sqlite_sequence" , p1->pTab->zTab)==0 ){ |
14351 | recoverExec(p, p->dbOut, "DELETE FROM sqlite_sequence" ); |
14352 | recoverSqlCallback(p, "DELETE FROM sqlite_sequence" ); |
14353 | } |
14354 | |
14355 | /* Bind the root page of this table within the original database to |
14356 | ** SELECT statement p1->pSel. The SELECT statement will then iterate |
14357 | ** through cells that look like they belong to table pTab. */ |
14358 | sqlite3_bind_int64(pSel, 1, iRoot); |
14359 | |
14360 | p1->nVal = 0; |
14361 | p1->bHaveRowid = 0; |
14362 | p1->iPrevPage = -1; |
14363 | p1->iPrevCell = -1; |
14364 | }else{ |
14365 | return SQLITE_DONE; |
14366 | } |
14367 | } |
14368 | assert( p->errCode!=SQLITE_OK || p1->pTab ); |
14369 | |
14370 | if( p->errCode==SQLITE_OK && sqlite3_step(pSel)==SQLITE_ROW ){ |
14371 | RecoverTable *pTab = p1->pTab; |
14372 | |
14373 | i64 iPage = sqlite3_column_int64(pSel, 0); |
14374 | int iCell = sqlite3_column_int(pSel, 1); |
14375 | int iField = sqlite3_column_int(pSel, 2); |
14376 | sqlite3_value *pVal = sqlite3_column_value(pSel, 3); |
14377 | int bNewCell = (p1->iPrevPage!=iPage || p1->iPrevCell!=iCell); |
14378 | |
14379 | assert( bNewCell==0 || (iField==-1 || iField==0) ); |
14380 | assert( bNewCell || iField==p1->nVal || p1->nVal==pTab->nCol ); |
14381 | |
14382 | if( bNewCell ){ |
14383 | int ii = 0; |
14384 | if( p1->nVal>=0 ){ |
14385 | if( p1->pInsert==0 || p1->nVal!=p1->nInsert ){ |
14386 | recoverFinalize(p, p1->pInsert); |
14387 | p1->pInsert = recoverInsertStmt(p, pTab, p1->nVal); |
14388 | p1->nInsert = p1->nVal; |
14389 | } |
14390 | if( p1->nVal>0 ){ |
14391 | sqlite3_stmt *pInsert = p1->pInsert; |
14392 | for(ii=0; ii<pTab->nCol; ii++){ |
14393 | RecoverColumn *pCol = &pTab->aCol[ii]; |
14394 | int iBind = pCol->iBind; |
14395 | if( iBind>0 ){ |
14396 | if( pCol->bIPK ){ |
14397 | sqlite3_bind_int64(pInsert, iBind, p1->iRowid); |
14398 | }else if( pCol->iField<p1->nVal ){ |
14399 | recoverBindValue(p, pInsert, iBind, apVal[pCol->iField]); |
14400 | } |
14401 | } |
14402 | } |
14403 | if( p->bRecoverRowid && pTab->iRowidBind>0 && p1->bHaveRowid ){ |
14404 | sqlite3_bind_int64(pInsert, pTab->iRowidBind, p1->iRowid); |
14405 | } |
14406 | if( SQLITE_ROW==sqlite3_step(pInsert) ){ |
14407 | const char *z = (const char*)sqlite3_column_text(pInsert, 0); |
14408 | recoverSqlCallback(p, z); |
14409 | } |
14410 | recoverReset(p, pInsert); |
14411 | assert( p->errCode || pInsert ); |
14412 | if( pInsert ) sqlite3_clear_bindings(pInsert); |
14413 | } |
14414 | } |
14415 | |
14416 | for(ii=0; ii<p1->nVal; ii++){ |
14417 | sqlite3_value_free(apVal[ii]); |
14418 | apVal[ii] = 0; |
14419 | } |
14420 | p1->nVal = -1; |
14421 | p1->bHaveRowid = 0; |
14422 | } |
14423 | |
14424 | if( iPage!=0 ){ |
14425 | if( iField<0 ){ |
14426 | p1->iRowid = sqlite3_column_int64(pSel, 3); |
14427 | assert( p1->nVal==-1 ); |
14428 | p1->nVal = 0; |
14429 | p1->bHaveRowid = 1; |
14430 | }else if( iField<pTab->nCol ){ |
14431 | assert( apVal[iField]==0 ); |
14432 | apVal[iField] = sqlite3_value_dup( pVal ); |
14433 | if( apVal[iField]==0 ){ |
14434 | recoverError(p, SQLITE_NOMEM, 0); |
14435 | } |
14436 | p1->nVal = iField+1; |
14437 | } |
14438 | p1->iPrevCell = iCell; |
14439 | p1->iPrevPage = iPage; |
14440 | } |
14441 | }else{ |
14442 | recoverReset(p, pSel); |
14443 | p1->pTab = 0; |
14444 | } |
14445 | |
14446 | return p->errCode; |
14447 | } |
14448 | |
14449 | /* |
14450 | ** Initialize resources required by sqlite3_recover_step() in |
14451 | ** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not |
14452 | ** already allocated to a recovered schema element is determined. |
14453 | */ |
14454 | static void recoverLostAndFound1Init(sqlite3_recover *p){ |
14455 | RecoverStateLAF *pLaf = &p->laf; |
14456 | sqlite3_stmt *pStmt = 0; |
14457 | |
14458 | assert( p->laf.pUsed==0 ); |
14459 | pLaf->nPg = recoverPageCount(p); |
14460 | pLaf->pUsed = recoverBitmapAlloc(p, pLaf->nPg); |
14461 | |
14462 | /* Prepare a statement to iterate through all pages that are part of any tree |
14463 | ** in the recoverable part of the input database schema to the bitmap. And, |
14464 | ** if !p->bFreelistCorrupt, add all pages that appear to be part of the |
14465 | ** freelist. */ |
14466 | pStmt = recoverPrepare( |
14467 | p, p->dbOut, |
14468 | "WITH trunk(pgno) AS (" |
14469 | " SELECT read_i32(getpage(1), 8) AS x WHERE x>0" |
14470 | " UNION" |
14471 | " SELECT read_i32(getpage(trunk.pgno), 0) AS x FROM trunk WHERE x>0" |
14472 | ")," |
14473 | "trunkdata(pgno, data) AS (" |
14474 | " SELECT pgno, getpage(pgno) FROM trunk" |
14475 | ")," |
14476 | "freelist(data, n, freepgno) AS (" |
14477 | " SELECT data, min(16384, read_i32(data, 1)-1), pgno FROM trunkdata" |
14478 | " UNION ALL" |
14479 | " SELECT data, n-1, read_i32(data, 2+n) FROM freelist WHERE n>=0" |
14480 | ")," |
14481 | "" |
14482 | "roots(r) AS (" |
14483 | " SELECT 1 UNION ALL" |
14484 | " SELECT rootpage FROM recovery.schema WHERE rootpage>0" |
14485 | ")," |
14486 | "used(page) AS (" |
14487 | " SELECT r FROM roots" |
14488 | " UNION" |
14489 | " SELECT child FROM sqlite_dbptr('getpage()'), used " |
14490 | " WHERE pgno=page" |
14491 | ") " |
14492 | "SELECT page FROM used" |
14493 | " UNION ALL " |
14494 | "SELECT freepgno FROM freelist WHERE NOT ?" |
14495 | ); |
14496 | if( pStmt ) sqlite3_bind_int(pStmt, 1, p->bFreelistCorrupt); |
14497 | pLaf->pUsedPages = pStmt; |
14498 | } |
14499 | |
14500 | /* |
14501 | ** Perform one step (sqlite3_recover_step()) of work for the connection |
14502 | ** passed as the only argument, which is guaranteed to be in |
14503 | ** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not |
14504 | ** already allocated to a recovered schema element is determined. |
14505 | */ |
14506 | static int recoverLostAndFound1Step(sqlite3_recover *p){ |
14507 | RecoverStateLAF *pLaf = &p->laf; |
14508 | int rc = p->errCode; |
14509 | if( rc==SQLITE_OK ){ |
14510 | rc = sqlite3_step(pLaf->pUsedPages); |
14511 | if( rc==SQLITE_ROW ){ |
14512 | i64 iPg = sqlite3_column_int64(pLaf->pUsedPages, 0); |
14513 | recoverBitmapSet(pLaf->pUsed, iPg); |
14514 | rc = SQLITE_OK; |
14515 | }else{ |
14516 | recoverFinalize(p, pLaf->pUsedPages); |
14517 | pLaf->pUsedPages = 0; |
14518 | } |
14519 | } |
14520 | return rc; |
14521 | } |
14522 | |
14523 | /* |
14524 | ** Initialize resources required by RECOVER_STATE_LOSTANDFOUND2 |
14525 | ** state - during which the pages identified in RECOVER_STATE_LOSTANDFOUND1 |
14526 | ** are sorted into sets that likely belonged to the same database tree. |
14527 | */ |
14528 | static void recoverLostAndFound2Init(sqlite3_recover *p){ |
14529 | RecoverStateLAF *pLaf = &p->laf; |
14530 | |
14531 | assert( p->laf.pAllAndParent==0 ); |
14532 | assert( p->laf.pMapInsert==0 ); |
14533 | assert( p->laf.pMaxField==0 ); |
14534 | assert( p->laf.nMaxField==0 ); |
14535 | |
14536 | pLaf->pMapInsert = recoverPrepare(p, p->dbOut, |
14537 | "INSERT OR IGNORE INTO recovery.map(pgno, parent) VALUES(?, ?)" |
14538 | ); |
14539 | pLaf->pAllAndParent = recoverPreparePrintf(p, p->dbOut, |
14540 | "WITH RECURSIVE seq(ii) AS (" |
14541 | " SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld" |
14542 | ")" |
14543 | "SELECT pgno, child FROM sqlite_dbptr('getpage()') " |
14544 | " UNION ALL " |
14545 | "SELECT NULL, ii FROM seq" , p->laf.nPg |
14546 | ); |
14547 | pLaf->pMaxField = recoverPreparePrintf(p, p->dbOut, |
14548 | "SELECT max(field)+1 FROM sqlite_dbdata('getpage') WHERE pgno = ?" |
14549 | ); |
14550 | } |
14551 | |
14552 | /* |
14553 | ** Perform one step (sqlite3_recover_step()) of work for the connection |
14554 | ** passed as the only argument, which is guaranteed to be in |
14555 | ** RECOVER_STATE_LOSTANDFOUND2 state - during which the pages identified |
14556 | ** in RECOVER_STATE_LOSTANDFOUND1 are sorted into sets that likely belonged |
14557 | ** to the same database tree. |
14558 | */ |
14559 | static int recoverLostAndFound2Step(sqlite3_recover *p){ |
14560 | RecoverStateLAF *pLaf = &p->laf; |
14561 | if( p->errCode==SQLITE_OK ){ |
14562 | int res = sqlite3_step(pLaf->pAllAndParent); |
14563 | if( res==SQLITE_ROW ){ |
14564 | i64 iChild = sqlite3_column_int(pLaf->pAllAndParent, 1); |
14565 | if( recoverBitmapQuery(pLaf->pUsed, iChild)==0 ){ |
14566 | sqlite3_bind_int64(pLaf->pMapInsert, 1, iChild); |
14567 | sqlite3_bind_value(pLaf->pMapInsert, 2, |
14568 | sqlite3_column_value(pLaf->pAllAndParent, 0) |
14569 | ); |
14570 | sqlite3_step(pLaf->pMapInsert); |
14571 | recoverReset(p, pLaf->pMapInsert); |
14572 | sqlite3_bind_int64(pLaf->pMaxField, 1, iChild); |
14573 | if( SQLITE_ROW==sqlite3_step(pLaf->pMaxField) ){ |
14574 | int nMax = sqlite3_column_int(pLaf->pMaxField, 0); |
14575 | if( nMax>pLaf->nMaxField ) pLaf->nMaxField = nMax; |
14576 | } |
14577 | recoverReset(p, pLaf->pMaxField); |
14578 | } |
14579 | }else{ |
14580 | recoverFinalize(p, pLaf->pAllAndParent); |
14581 | pLaf->pAllAndParent =0; |
14582 | return SQLITE_DONE; |
14583 | } |
14584 | } |
14585 | return p->errCode; |
14586 | } |
14587 | |
14588 | /* |
14589 | ** Free all resources allocated as part of sqlite3_recover_step() calls |
14590 | ** in one of the RECOVER_STATE_LOSTANDFOUND[123] states. |
14591 | */ |
14592 | static void recoverLostAndFoundCleanup(sqlite3_recover *p){ |
14593 | recoverBitmapFree(p->laf.pUsed); |
14594 | p->laf.pUsed = 0; |
14595 | sqlite3_finalize(p->laf.pUsedPages); |
14596 | sqlite3_finalize(p->laf.pAllAndParent); |
14597 | sqlite3_finalize(p->laf.pMapInsert); |
14598 | sqlite3_finalize(p->laf.pMaxField); |
14599 | sqlite3_finalize(p->laf.pFindRoot); |
14600 | sqlite3_finalize(p->laf.pInsert); |
14601 | sqlite3_finalize(p->laf.pAllPage); |
14602 | sqlite3_finalize(p->laf.pPageData); |
14603 | p->laf.pUsedPages = 0; |
14604 | p->laf.pAllAndParent = 0; |
14605 | p->laf.pMapInsert = 0; |
14606 | p->laf.pMaxField = 0; |
14607 | p->laf.pFindRoot = 0; |
14608 | p->laf.pInsert = 0; |
14609 | p->laf.pAllPage = 0; |
14610 | p->laf.pPageData = 0; |
14611 | sqlite3_free(p->laf.apVal); |
14612 | p->laf.apVal = 0; |
14613 | } |
14614 | |
14615 | /* |
14616 | ** Free all resources allocated as part of sqlite3_recover_step() calls. |
14617 | */ |
14618 | static void recoverFinalCleanup(sqlite3_recover *p){ |
14619 | RecoverTable *pTab = 0; |
14620 | RecoverTable *pNext = 0; |
14621 | |
14622 | recoverWriteDataCleanup(p); |
14623 | recoverLostAndFoundCleanup(p); |
14624 | |
14625 | for(pTab=p->pTblList; pTab; pTab=pNext){ |
14626 | pNext = pTab->pNext; |
14627 | sqlite3_free(pTab); |
14628 | } |
14629 | p->pTblList = 0; |
14630 | sqlite3_finalize(p->pGetPage); |
14631 | p->pGetPage = 0; |
14632 | sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0); |
14633 | |
14634 | { |
14635 | #ifndef NDEBUG |
14636 | int res = |
14637 | #endif |
14638 | sqlite3_close(p->dbOut); |
14639 | assert( res==SQLITE_OK ); |
14640 | } |
14641 | p->dbOut = 0; |
14642 | } |
14643 | |
14644 | /* |
14645 | ** Decode and return an unsigned 16-bit big-endian integer value from |
14646 | ** buffer a[]. |
14647 | */ |
14648 | static u32 recoverGetU16(const u8 *a){ |
14649 | return (((u32)a[0])<<8) + ((u32)a[1]); |
14650 | } |
14651 | |
14652 | /* |
14653 | ** Decode and return an unsigned 32-bit big-endian integer value from |
14654 | ** buffer a[]. |
14655 | */ |
14656 | static u32 recoverGetU32(const u8 *a){ |
14657 | return (((u32)a[0])<<24) + (((u32)a[1])<<16) + (((u32)a[2])<<8) + ((u32)a[3]); |
14658 | } |
14659 | |
14660 | /* |
14661 | ** Decode an SQLite varint from buffer a[]. Write the decoded value to (*pVal) |
14662 | ** and return the number of bytes consumed. |
14663 | */ |
14664 | static int recoverGetVarint(const u8 *a, i64 *pVal){ |
14665 | sqlite3_uint64 u = 0; |
14666 | int i; |
14667 | for(i=0; i<8; i++){ |
14668 | u = (u<<7) + (a[i]&0x7f); |
14669 | if( (a[i]&0x80)==0 ){ *pVal = (sqlite3_int64)u; return i+1; } |
14670 | } |
14671 | u = (u<<8) + (a[i]&0xff); |
14672 | *pVal = (sqlite3_int64)u; |
14673 | return 9; |
14674 | } |
14675 | |
14676 | /* |
14677 | ** The second argument points to a buffer n bytes in size. If this buffer |
14678 | ** or a prefix thereof appears to contain a well-formed SQLite b-tree page, |
14679 | ** return the page-size in bytes. Otherwise, if the buffer does not |
14680 | ** appear to contain a well-formed b-tree page, return 0. |
14681 | */ |
14682 | static int recoverIsValidPage(u8 *aTmp, const u8 *a, int n){ |
14683 | u8 *aUsed = aTmp; |
14684 | int nFrag = 0; |
14685 | int nActual = 0; |
14686 | int iFree = 0; |
14687 | int nCell = 0; /* Number of cells on page */ |
14688 | int iCellOff = 0; /* Offset of cell array in page */ |
14689 | int iContent = 0; |
14690 | int eType = 0; |
14691 | int ii = 0; |
14692 | |
14693 | eType = (int)a[0]; |
14694 | if( eType!=0x02 && eType!=0x05 && eType!=0x0A && eType!=0x0D ) return 0; |
14695 | |
14696 | iFree = (int)recoverGetU16(&a[1]); |
14697 | nCell = (int)recoverGetU16(&a[3]); |
14698 | iContent = (int)recoverGetU16(&a[5]); |
14699 | if( iContent==0 ) iContent = 65536; |
14700 | nFrag = (int)a[7]; |
14701 | |
14702 | if( iContent>n ) return 0; |
14703 | |
14704 | memset(aUsed, 0, n); |
14705 | memset(aUsed, 0xFF, iContent); |
14706 | |
14707 | /* Follow the free-list. This is the same format for all b-tree pages. */ |
14708 | if( iFree && iFree<=iContent ) return 0; |
14709 | while( iFree ){ |
14710 | int iNext = 0; |
14711 | int nByte = 0; |
14712 | if( iFree>(n-4) ) return 0; |
14713 | iNext = recoverGetU16(&a[iFree]); |
14714 | nByte = recoverGetU16(&a[iFree+2]); |
14715 | if( iFree+nByte>n ) return 0; |
14716 | if( iNext && iNext<iFree+nByte ) return 0; |
14717 | memset(&aUsed[iFree], 0xFF, nByte); |
14718 | iFree = iNext; |
14719 | } |
14720 | |
14721 | /* Run through the cells */ |
14722 | if( eType==0x02 || eType==0x05 ){ |
14723 | iCellOff = 12; |
14724 | }else{ |
14725 | iCellOff = 8; |
14726 | } |
14727 | if( (iCellOff + 2*nCell)>iContent ) return 0; |
14728 | for(ii=0; ii<nCell; ii++){ |
14729 | int iByte; |
14730 | i64 nPayload = 0; |
14731 | int nByte = 0; |
14732 | int iOff = recoverGetU16(&a[iCellOff + 2*ii]); |
14733 | if( iOff<iContent || iOff>n ){ |
14734 | return 0; |
14735 | } |
14736 | if( eType==0x05 || eType==0x02 ) nByte += 4; |
14737 | nByte += recoverGetVarint(&a[iOff+nByte], &nPayload); |
14738 | if( eType==0x0D ){ |
14739 | i64 dummy = 0; |
14740 | nByte += recoverGetVarint(&a[iOff+nByte], &dummy); |
14741 | } |
14742 | if( eType!=0x05 ){ |
14743 | int X = (eType==0x0D) ? n-35 : (((n-12)*64/255)-23); |
14744 | int M = ((n-12)*32/255)-23; |
14745 | int K = M+((nPayload-M)%(n-4)); |
14746 | |
14747 | if( nPayload<X ){ |
14748 | nByte += nPayload; |
14749 | }else if( K<=X ){ |
14750 | nByte += K+4; |
14751 | }else{ |
14752 | nByte += M+4; |
14753 | } |
14754 | } |
14755 | |
14756 | if( iOff+nByte>n ){ |
14757 | return 0; |
14758 | } |
14759 | for(iByte=iOff; iByte<(iOff+nByte); iByte++){ |
14760 | if( aUsed[iByte]!=0 ){ |
14761 | return 0; |
14762 | } |
14763 | aUsed[iByte] = 0xFF; |
14764 | } |
14765 | } |
14766 | |
14767 | nActual = 0; |
14768 | for(ii=0; ii<n; ii++){ |
14769 | if( aUsed[ii]==0 ) nActual++; |
14770 | } |
14771 | return (nActual==nFrag); |
14772 | } |
14773 | |
14774 | |
14775 | static int recoverVfsClose(sqlite3_file*); |
14776 | static int recoverVfsRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); |
14777 | static int recoverVfsWrite(sqlite3_file*, const void*, int, sqlite3_int64); |
14778 | static int recoverVfsTruncate(sqlite3_file*, sqlite3_int64 size); |
14779 | static int recoverVfsSync(sqlite3_file*, int flags); |
14780 | static int recoverVfsFileSize(sqlite3_file*, sqlite3_int64 *pSize); |
14781 | static int recoverVfsLock(sqlite3_file*, int); |
14782 | static int recoverVfsUnlock(sqlite3_file*, int); |
14783 | static int recoverVfsCheckReservedLock(sqlite3_file*, int *pResOut); |
14784 | static int recoverVfsFileControl(sqlite3_file*, int op, void *pArg); |
14785 | static int recoverVfsSectorSize(sqlite3_file*); |
14786 | static int recoverVfsDeviceCharacteristics(sqlite3_file*); |
14787 | static int recoverVfsShmMap(sqlite3_file*, int, int, int, void volatile**); |
14788 | static int recoverVfsShmLock(sqlite3_file*, int offset, int n, int flags); |
14789 | static void recoverVfsShmBarrier(sqlite3_file*); |
14790 | static int recoverVfsShmUnmap(sqlite3_file*, int deleteFlag); |
14791 | static int recoverVfsFetch(sqlite3_file*, sqlite3_int64, int, void**); |
14792 | static int recoverVfsUnfetch(sqlite3_file *pFd, sqlite3_int64 iOff, void *p); |
14793 | |
14794 | static sqlite3_io_methods recover_methods = { |
14795 | 2, /* iVersion */ |
14796 | recoverVfsClose, |
14797 | recoverVfsRead, |
14798 | recoverVfsWrite, |
14799 | recoverVfsTruncate, |
14800 | recoverVfsSync, |
14801 | recoverVfsFileSize, |
14802 | recoverVfsLock, |
14803 | recoverVfsUnlock, |
14804 | recoverVfsCheckReservedLock, |
14805 | recoverVfsFileControl, |
14806 | recoverVfsSectorSize, |
14807 | recoverVfsDeviceCharacteristics, |
14808 | recoverVfsShmMap, |
14809 | recoverVfsShmLock, |
14810 | recoverVfsShmBarrier, |
14811 | recoverVfsShmUnmap, |
14812 | recoverVfsFetch, |
14813 | recoverVfsUnfetch |
14814 | }; |
14815 | |
14816 | static int recoverVfsClose(sqlite3_file *pFd){ |
14817 | assert( pFd->pMethods!=&recover_methods ); |
14818 | return pFd->pMethods->xClose(pFd); |
14819 | } |
14820 | |
14821 | /* |
14822 | ** Write value v to buffer a[] as a 16-bit big-endian unsigned integer. |
14823 | */ |
14824 | static void recoverPutU16(u8 *a, u32 v){ |
14825 | a[0] = (v>>8) & 0x00FF; |
14826 | a[1] = (v>>0) & 0x00FF; |
14827 | } |
14828 | |
14829 | /* |
14830 | ** Write value v to buffer a[] as a 32-bit big-endian unsigned integer. |
14831 | */ |
14832 | static void recoverPutU32(u8 *a, u32 v){ |
14833 | a[0] = (v>>24) & 0x00FF; |
14834 | a[1] = (v>>16) & 0x00FF; |
14835 | a[2] = (v>>8) & 0x00FF; |
14836 | a[3] = (v>>0) & 0x00FF; |
14837 | } |
14838 | |
14839 | /* |
14840 | ** Detect the page-size of the database opened by file-handle pFd by |
14841 | ** searching the first part of the file for a well-formed SQLite b-tree |
14842 | ** page. If parameter nReserve is non-zero, then as well as searching for |
14843 | ** a b-tree page with zero reserved bytes, this function searches for one |
14844 | ** with nReserve reserved bytes at the end of it. |
14845 | ** |
14846 | ** If successful, set variable p->detected_pgsz to the detected page-size |
14847 | ** in bytes and return SQLITE_OK. Or, if no error occurs but no valid page |
14848 | ** can be found, return SQLITE_OK but leave p->detected_pgsz set to 0. Or, |
14849 | ** if an error occurs (e.g. an IO or OOM error), then an SQLite error code |
14850 | ** is returned. The final value of p->detected_pgsz is undefined in this |
14851 | ** case. |
14852 | */ |
14853 | static int recoverVfsDetectPagesize( |
14854 | sqlite3_recover *p, /* Recover handle */ |
14855 | sqlite3_file *pFd, /* File-handle open on input database */ |
14856 | u32 nReserve, /* Possible nReserve value */ |
14857 | i64 nSz /* Size of database file in bytes */ |
14858 | ){ |
14859 | int rc = SQLITE_OK; |
14860 | const int nMin = 512; |
14861 | const int nMax = 65536; |
14862 | const int nMaxBlk = 4; |
14863 | u32 pgsz = 0; |
14864 | int iBlk = 0; |
14865 | u8 *aPg = 0; |
14866 | u8 *aTmp = 0; |
14867 | int nBlk = 0; |
14868 | |
14869 | aPg = (u8*)sqlite3_malloc(2*nMax); |
14870 | if( aPg==0 ) return SQLITE_NOMEM; |
14871 | aTmp = &aPg[nMax]; |
14872 | |
14873 | nBlk = (nSz+nMax-1)/nMax; |
14874 | if( nBlk>nMaxBlk ) nBlk = nMaxBlk; |
14875 | |
14876 | do { |
14877 | for(iBlk=0; rc==SQLITE_OK && iBlk<nBlk; iBlk++){ |
14878 | int nByte = (nSz>=((iBlk+1)*nMax)) ? nMax : (nSz % nMax); |
14879 | memset(aPg, 0, nMax); |
14880 | rc = pFd->pMethods->xRead(pFd, aPg, nByte, iBlk*nMax); |
14881 | if( rc==SQLITE_OK ){ |
14882 | int pgsz2; |
14883 | for(pgsz2=(pgsz ? pgsz*2 : nMin); pgsz2<=nMax; pgsz2=pgsz2*2){ |
14884 | int iOff; |
14885 | for(iOff=0; iOff<nMax; iOff+=pgsz2){ |
14886 | if( recoverIsValidPage(aTmp, &aPg[iOff], pgsz2-nReserve) ){ |
14887 | pgsz = pgsz2; |
14888 | break; |
14889 | } |
14890 | } |
14891 | } |
14892 | } |
14893 | } |
14894 | if( pgsz>(u32)p->detected_pgsz ){ |
14895 | p->detected_pgsz = pgsz; |
14896 | p->nReserve = nReserve; |
14897 | } |
14898 | if( nReserve==0 ) break; |
14899 | nReserve = 0; |
14900 | }while( 1 ); |
14901 | |
14902 | p->detected_pgsz = pgsz; |
14903 | sqlite3_free(aPg); |
14904 | return rc; |
14905 | } |
14906 | |
14907 | /* |
14908 | ** The xRead() method of the wrapper VFS. This is used to intercept calls |
14909 | ** to read page 1 of the input database. |
14910 | */ |
14911 | static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){ |
14912 | int rc = SQLITE_OK; |
14913 | if( pFd->pMethods==&recover_methods ){ |
14914 | pFd->pMethods = recover_g.pMethods; |
14915 | rc = pFd->pMethods->xRead(pFd, aBuf, nByte, iOff); |
14916 | if( nByte==16 ){ |
14917 | sqlite3_randomness(16, aBuf); |
14918 | }else |
14919 | if( rc==SQLITE_OK && iOff==0 && nByte>=108 ){ |
14920 | /* Ensure that the database has a valid header file. The only fields |
14921 | ** that really matter to recovery are: |
14922 | ** |
14923 | ** + Database page size (16-bits at offset 16) |
14924 | ** + Size of db in pages (32-bits at offset 28) |
14925 | ** + Database encoding (32-bits at offset 56) |
14926 | ** |
14927 | ** Also preserved are: |
14928 | ** |
14929 | ** + first freelist page (32-bits at offset 32) |
14930 | ** + size of freelist (32-bits at offset 36) |
14931 | ** + the wal-mode flags (16-bits at offset 18) |
14932 | ** |
14933 | ** We also try to preserve the auto-vacuum, incr-value, user-version |
14934 | ** and application-id fields - all 32 bit quantities at offsets |
14935 | ** 52, 60, 64 and 68. All other fields are set to known good values. |
14936 | ** |
14937 | ** Byte offset 105 should also contain the page-size as a 16-bit |
14938 | ** integer. |
14939 | */ |
14940 | const int aPreserve[] = {32, 36, 52, 60, 64, 68}; |
14941 | u8 aHdr[108] = { |
14942 | 0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66, |
14943 | 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00, |
14944 | 0xFF, 0xFF, 0x01, 0x01, 0x00, 0x40, 0x20, 0x20, |
14945 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, |
14946 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
14947 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, |
14948 | 0x00, 0x00, 0x10, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, |
14949 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
14950 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
14951 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
14952 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
14953 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
14954 | 0x00, 0x2e, 0x5b, 0x30, |
14955 | |
14956 | 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00 |
14957 | }; |
14958 | u8 *a = (u8*)aBuf; |
14959 | |
14960 | u32 pgsz = recoverGetU16(&a[16]); |
14961 | u32 nReserve = a[20]; |
14962 | u32 enc = recoverGetU32(&a[56]); |
14963 | u32 dbsz = 0; |
14964 | i64 dbFileSize = 0; |
14965 | int ii; |
14966 | sqlite3_recover *p = recover_g.p; |
14967 | |
14968 | if( pgsz==0x01 ) pgsz = 65536; |
14969 | rc = pFd->pMethods->xFileSize(pFd, &dbFileSize); |
14970 | |
14971 | if( rc==SQLITE_OK && p->detected_pgsz==0 ){ |
14972 | rc = recoverVfsDetectPagesize(p, pFd, nReserve, dbFileSize); |
14973 | } |
14974 | if( p->detected_pgsz ){ |
14975 | pgsz = p->detected_pgsz; |
14976 | nReserve = p->nReserve; |
14977 | } |
14978 | |
14979 | if( pgsz ){ |
14980 | dbsz = dbFileSize / pgsz; |
14981 | } |
14982 | if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16BE && enc!=SQLITE_UTF16LE ){ |
14983 | enc = SQLITE_UTF8; |
14984 | } |
14985 | |
14986 | sqlite3_free(p->pPage1Cache); |
14987 | p->pPage1Cache = 0; |
14988 | p->pPage1Disk = 0; |
14989 | |
14990 | p->pgsz = nByte; |
14991 | p->pPage1Cache = (u8*)recoverMalloc(p, nByte*2); |
14992 | if( p->pPage1Cache ){ |
14993 | p->pPage1Disk = &p->pPage1Cache[nByte]; |
14994 | memcpy(p->pPage1Disk, aBuf, nByte); |
14995 | aHdr[18] = a[18]; |
14996 | aHdr[19] = a[19]; |
14997 | recoverPutU32(&aHdr[28], dbsz); |
14998 | recoverPutU32(&aHdr[56], enc); |
14999 | recoverPutU16(&aHdr[105], pgsz-nReserve); |
15000 | if( pgsz==65536 ) pgsz = 1; |
15001 | recoverPutU16(&aHdr[16], pgsz); |
15002 | aHdr[20] = nReserve; |
15003 | for(ii=0; ii<sizeof(aPreserve)/sizeof(aPreserve[0]); ii++){ |
15004 | memcpy(&aHdr[aPreserve[ii]], &a[aPreserve[ii]], 4); |
15005 | } |
15006 | memcpy(aBuf, aHdr, sizeof(aHdr)); |
15007 | memset(&((u8*)aBuf)[sizeof(aHdr)], 0, nByte-sizeof(aHdr)); |
15008 | |
15009 | memcpy(p->pPage1Cache, aBuf, nByte); |
15010 | }else{ |
15011 | rc = p->errCode; |
15012 | } |
15013 | |
15014 | } |
15015 | pFd->pMethods = &recover_methods; |
15016 | }else{ |
15017 | rc = pFd->pMethods->xRead(pFd, aBuf, nByte, iOff); |
15018 | } |
15019 | return rc; |
15020 | } |
15021 | |
15022 | /* |
15023 | ** Used to make sqlite3_io_methods wrapper methods less verbose. |
15024 | */ |
15025 | #define RECOVER_VFS_WRAPPER(code) \ |
15026 | int rc = SQLITE_OK; \ |
15027 | if( pFd->pMethods==&recover_methods ){ \ |
15028 | pFd->pMethods = recover_g.pMethods; \ |
15029 | rc = code; \ |
15030 | pFd->pMethods = &recover_methods; \ |
15031 | }else{ \ |
15032 | rc = code; \ |
15033 | } \ |
15034 | return rc; |
15035 | |
15036 | /* |
15037 | ** Methods of the wrapper VFS. All methods except for xRead() and xClose() |
15038 | ** simply uninstall the sqlite3_io_methods wrapper, invoke the equivalent |
15039 | ** method on the lower level VFS, then reinstall the wrapper before returning. |
15040 | ** Those that return an integer value use the RECOVER_VFS_WRAPPER macro. |
15041 | */ |
15042 | static int recoverVfsWrite( |
15043 | sqlite3_file *pFd, const void *aBuf, int nByte, i64 iOff |
15044 | ){ |
15045 | RECOVER_VFS_WRAPPER ( |
15046 | pFd->pMethods->xWrite(pFd, aBuf, nByte, iOff) |
15047 | ); |
15048 | } |
15049 | static int recoverVfsTruncate(sqlite3_file *pFd, sqlite3_int64 size){ |
15050 | RECOVER_VFS_WRAPPER ( |
15051 | pFd->pMethods->xTruncate(pFd, size) |
15052 | ); |
15053 | } |
15054 | static int recoverVfsSync(sqlite3_file *pFd, int flags){ |
15055 | RECOVER_VFS_WRAPPER ( |
15056 | pFd->pMethods->xSync(pFd, flags) |
15057 | ); |
15058 | } |
15059 | static int recoverVfsFileSize(sqlite3_file *pFd, sqlite3_int64 *pSize){ |
15060 | RECOVER_VFS_WRAPPER ( |
15061 | pFd->pMethods->xFileSize(pFd, pSize) |
15062 | ); |
15063 | } |
15064 | static int recoverVfsLock(sqlite3_file *pFd, int eLock){ |
15065 | RECOVER_VFS_WRAPPER ( |
15066 | pFd->pMethods->xLock(pFd, eLock) |
15067 | ); |
15068 | } |
15069 | static int recoverVfsUnlock(sqlite3_file *pFd, int eLock){ |
15070 | RECOVER_VFS_WRAPPER ( |
15071 | pFd->pMethods->xUnlock(pFd, eLock) |
15072 | ); |
15073 | } |
15074 | static int recoverVfsCheckReservedLock(sqlite3_file *pFd, int *pResOut){ |
15075 | RECOVER_VFS_WRAPPER ( |
15076 | pFd->pMethods->xCheckReservedLock(pFd, pResOut) |
15077 | ); |
15078 | } |
15079 | static int recoverVfsFileControl(sqlite3_file *pFd, int op, void *pArg){ |
15080 | RECOVER_VFS_WRAPPER ( |
15081 | (pFd->pMethods ? pFd->pMethods->xFileControl(pFd, op, pArg) : SQLITE_NOTFOUND) |
15082 | ); |
15083 | } |
15084 | static int recoverVfsSectorSize(sqlite3_file *pFd){ |
15085 | RECOVER_VFS_WRAPPER ( |
15086 | pFd->pMethods->xSectorSize(pFd) |
15087 | ); |
15088 | } |
15089 | static int recoverVfsDeviceCharacteristics(sqlite3_file *pFd){ |
15090 | RECOVER_VFS_WRAPPER ( |
15091 | pFd->pMethods->xDeviceCharacteristics(pFd) |
15092 | ); |
15093 | } |
15094 | static int recoverVfsShmMap( |
15095 | sqlite3_file *pFd, int iPg, int pgsz, int bExtend, void volatile **pp |
15096 | ){ |
15097 | RECOVER_VFS_WRAPPER ( |
15098 | pFd->pMethods->xShmMap(pFd, iPg, pgsz, bExtend, pp) |
15099 | ); |
15100 | } |
15101 | static int recoverVfsShmLock(sqlite3_file *pFd, int offset, int n, int flags){ |
15102 | RECOVER_VFS_WRAPPER ( |
15103 | pFd->pMethods->xShmLock(pFd, offset, n, flags) |
15104 | ); |
15105 | } |
15106 | static void recoverVfsShmBarrier(sqlite3_file *pFd){ |
15107 | if( pFd->pMethods==&recover_methods ){ |
15108 | pFd->pMethods = recover_g.pMethods; |
15109 | pFd->pMethods->xShmBarrier(pFd); |
15110 | pFd->pMethods = &recover_methods; |
15111 | }else{ |
15112 | pFd->pMethods->xShmBarrier(pFd); |
15113 | } |
15114 | } |
15115 | static int recoverVfsShmUnmap(sqlite3_file *pFd, int deleteFlag){ |
15116 | RECOVER_VFS_WRAPPER ( |
15117 | pFd->pMethods->xShmUnmap(pFd, deleteFlag) |
15118 | ); |
15119 | } |
15120 | |
15121 | static int recoverVfsFetch( |
15122 | sqlite3_file *pFd, |
15123 | sqlite3_int64 iOff, |
15124 | int iAmt, |
15125 | void **pp |
15126 | ){ |
15127 | *pp = 0; |
15128 | return SQLITE_OK; |
15129 | } |
15130 | static int recoverVfsUnfetch(sqlite3_file *pFd, sqlite3_int64 iOff, void *p){ |
15131 | return SQLITE_OK; |
15132 | } |
15133 | |
15134 | /* |
15135 | ** Install the VFS wrapper around the file-descriptor open on the input |
15136 | ** database for recover handle p. Mutex RECOVER_MUTEX_ID must be held |
15137 | ** when this function is called. |
15138 | */ |
15139 | static void recoverInstallWrapper(sqlite3_recover *p){ |
15140 | sqlite3_file *pFd = 0; |
15141 | assert( recover_g.pMethods==0 ); |
15142 | recoverAssertMutexHeld(); |
15143 | sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd); |
15144 | assert( pFd==0 || pFd->pMethods!=&recover_methods ); |
15145 | if( pFd && pFd->pMethods ){ |
15146 | int iVersion = 1 + (pFd->pMethods->iVersion>1 && pFd->pMethods->xShmMap!=0); |
15147 | recover_g.pMethods = pFd->pMethods; |
15148 | recover_g.p = p; |
15149 | recover_methods.iVersion = iVersion; |
15150 | pFd->pMethods = &recover_methods; |
15151 | } |
15152 | } |
15153 | |
15154 | /* |
15155 | ** Uninstall the VFS wrapper that was installed around the file-descriptor open |
15156 | ** on the input database for recover handle p. Mutex RECOVER_MUTEX_ID must be |
15157 | ** held when this function is called. |
15158 | */ |
15159 | static void recoverUninstallWrapper(sqlite3_recover *p){ |
15160 | sqlite3_file *pFd = 0; |
15161 | recoverAssertMutexHeld(); |
15162 | sqlite3_file_control(p->dbIn, p->zDb,SQLITE_FCNTL_FILE_POINTER,(void*)&pFd); |
15163 | if( pFd && pFd->pMethods ){ |
15164 | pFd->pMethods = recover_g.pMethods; |
15165 | recover_g.pMethods = 0; |
15166 | recover_g.p = 0; |
15167 | } |
15168 | } |
15169 | |
15170 | /* |
15171 | ** This function does the work of a single sqlite3_recover_step() call. It |
15172 | ** is guaranteed that the handle is not in an error state when this |
15173 | ** function is called. |
15174 | */ |
15175 | static void recoverStep(sqlite3_recover *p){ |
15176 | assert( p && p->errCode==SQLITE_OK ); |
15177 | switch( p->eState ){ |
15178 | case RECOVER_STATE_INIT: |
15179 | /* This is the very first call to sqlite3_recover_step() on this object. |
15180 | */ |
15181 | recoverSqlCallback(p, "BEGIN" ); |
15182 | recoverSqlCallback(p, "PRAGMA writable_schema = on" ); |
15183 | |
15184 | recoverEnterMutex(); |
15185 | recoverInstallWrapper(p); |
15186 | |
15187 | /* Open the output database. And register required virtual tables and |
15188 | ** user functions with the new handle. */ |
15189 | recoverOpenOutput(p); |
15190 | |
15191 | /* Open transactions on both the input and output databases. */ |
15192 | sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0); |
15193 | recoverExec(p, p->dbIn, "PRAGMA writable_schema = on" ); |
15194 | recoverExec(p, p->dbIn, "BEGIN" ); |
15195 | if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1; |
15196 | recoverExec(p, p->dbIn, "SELECT 1 FROM sqlite_schema" ); |
15197 | recoverTransferSettings(p); |
15198 | recoverOpenRecovery(p); |
15199 | recoverCacheSchema(p); |
15200 | |
15201 | recoverUninstallWrapper(p); |
15202 | recoverLeaveMutex(); |
15203 | |
15204 | recoverExec(p, p->dbOut, "BEGIN" ); |
15205 | |
15206 | recoverWriteSchema1(p); |
15207 | p->eState = RECOVER_STATE_WRITING; |
15208 | break; |
15209 | |
15210 | case RECOVER_STATE_WRITING: { |
15211 | if( p->w1.pTbls==0 ){ |
15212 | recoverWriteDataInit(p); |
15213 | } |
15214 | if( SQLITE_DONE==recoverWriteDataStep(p) ){ |
15215 | recoverWriteDataCleanup(p); |
15216 | if( p->zLostAndFound ){ |
15217 | p->eState = RECOVER_STATE_LOSTANDFOUND1; |
15218 | }else{ |
15219 | p->eState = RECOVER_STATE_SCHEMA2; |
15220 | } |
15221 | } |
15222 | break; |
15223 | } |
15224 | |
15225 | case RECOVER_STATE_LOSTANDFOUND1: { |
15226 | if( p->laf.pUsed==0 ){ |
15227 | recoverLostAndFound1Init(p); |
15228 | } |
15229 | if( SQLITE_DONE==recoverLostAndFound1Step(p) ){ |
15230 | p->eState = RECOVER_STATE_LOSTANDFOUND2; |
15231 | } |
15232 | break; |
15233 | } |
15234 | case RECOVER_STATE_LOSTANDFOUND2: { |
15235 | if( p->laf.pAllAndParent==0 ){ |
15236 | recoverLostAndFound2Init(p); |
15237 | } |
15238 | if( SQLITE_DONE==recoverLostAndFound2Step(p) ){ |
15239 | p->eState = RECOVER_STATE_LOSTANDFOUND3; |
15240 | } |
15241 | break; |
15242 | } |
15243 | |
15244 | case RECOVER_STATE_LOSTANDFOUND3: { |
15245 | if( p->laf.pInsert==0 ){ |
15246 | recoverLostAndFound3Init(p); |
15247 | } |
15248 | if( SQLITE_DONE==recoverLostAndFound3Step(p) ){ |
15249 | p->eState = RECOVER_STATE_SCHEMA2; |
15250 | } |
15251 | break; |
15252 | } |
15253 | |
15254 | case RECOVER_STATE_SCHEMA2: { |
15255 | int rc = SQLITE_OK; |
15256 | |
15257 | recoverWriteSchema2(p); |
15258 | p->eState = RECOVER_STATE_DONE; |
15259 | |
15260 | /* If no error has occurred, commit the write transaction on the output |
15261 | ** database. Regardless of whether or not an error has occurred, make |
15262 | ** an attempt to end the read transaction on the input database. */ |
15263 | recoverExec(p, p->dbOut, "COMMIT" ); |
15264 | rc = sqlite3_exec(p->dbIn, "END" , 0, 0, 0); |
15265 | if( p->errCode==SQLITE_OK ) p->errCode = rc; |
15266 | |
15267 | recoverSqlCallback(p, "PRAGMA writable_schema = off" ); |
15268 | recoverSqlCallback(p, "COMMIT" ); |
15269 | p->eState = RECOVER_STATE_DONE; |
15270 | recoverFinalCleanup(p); |
15271 | break; |
15272 | }; |
15273 | |
15274 | case RECOVER_STATE_DONE: { |
15275 | /* no-op */ |
15276 | break; |
15277 | }; |
15278 | } |
15279 | } |
15280 | |
15281 | |
15282 | /* |
15283 | ** This is a worker function that does the heavy lifting for both init |
15284 | ** functions: |
15285 | ** |
15286 | ** sqlite3_recover_init() |
15287 | ** sqlite3_recover_init_sql() |
15288 | ** |
15289 | ** All this function does is allocate space for the recover handle and |
15290 | ** take copies of the input parameters. All the real work is done within |
15291 | ** sqlite3_recover_run(). |
15292 | */ |
15293 | sqlite3_recover *recoverInit( |
15294 | sqlite3* db, |
15295 | const char *zDb, |
15296 | const char *zUri, /* Output URI for _recover_init() */ |
15297 | int (*xSql)(void*, const char*),/* SQL callback for _recover_init_sql() */ |
15298 | void *pSqlCtx /* Context arg for _recover_init_sql() */ |
15299 | ){ |
15300 | sqlite3_recover *pRet = 0; |
15301 | int nDb = 0; |
15302 | int nUri = 0; |
15303 | int nByte = 0; |
15304 | |
15305 | if( zDb==0 ){ zDb = "main" ; } |
15306 | |
15307 | nDb = recoverStrlen(zDb); |
15308 | nUri = recoverStrlen(zUri); |
15309 | |
15310 | nByte = sizeof(sqlite3_recover) + nDb+1 + nUri+1; |
15311 | pRet = (sqlite3_recover*)sqlite3_malloc(nByte); |
15312 | if( pRet ){ |
15313 | memset(pRet, 0, nByte); |
15314 | pRet->dbIn = db; |
15315 | pRet->zDb = (char*)&pRet[1]; |
15316 | pRet->zUri = &pRet->zDb[nDb+1]; |
15317 | memcpy(pRet->zDb, zDb, nDb); |
15318 | if( nUri>0 && zUri ) memcpy(pRet->zUri, zUri, nUri); |
15319 | pRet->xSql = xSql; |
15320 | pRet->pSqlCtx = pSqlCtx; |
15321 | pRet->bRecoverRowid = RECOVER_ROWID_DEFAULT; |
15322 | } |
15323 | |
15324 | return pRet; |
15325 | } |
15326 | |
15327 | /* |
15328 | ** Initialize a recovery handle that creates a new database containing |
15329 | ** the recovered data. |
15330 | */ |
15331 | sqlite3_recover *sqlite3_recover_init( |
15332 | sqlite3* db, |
15333 | const char *zDb, |
15334 | const char *zUri |
15335 | ){ |
15336 | return recoverInit(db, zDb, zUri, 0, 0); |
15337 | } |
15338 | |
15339 | /* |
15340 | ** Initialize a recovery handle that returns recovered data in the |
15341 | ** form of SQL statements via a callback. |
15342 | */ |
15343 | sqlite3_recover *sqlite3_recover_init_sql( |
15344 | sqlite3* db, |
15345 | const char *zDb, |
15346 | int (*xSql)(void*, const char*), |
15347 | void *pSqlCtx |
15348 | ){ |
15349 | return recoverInit(db, zDb, 0, xSql, pSqlCtx); |
15350 | } |
15351 | |
15352 | /* |
15353 | ** Return the handle error message, if any. |
15354 | */ |
15355 | const char *sqlite3_recover_errmsg(sqlite3_recover *p){ |
15356 | return (p && p->errCode!=SQLITE_NOMEM) ? p->zErrMsg : "out of memory" ; |
15357 | } |
15358 | |
15359 | /* |
15360 | ** Return the handle error code. |
15361 | */ |
15362 | int sqlite3_recover_errcode(sqlite3_recover *p){ |
15363 | return p ? p->errCode : SQLITE_NOMEM; |
15364 | } |
15365 | |
15366 | /* |
15367 | ** Configure the handle. |
15368 | */ |
15369 | int sqlite3_recover_config(sqlite3_recover *p, int op, void *pArg){ |
15370 | int rc = SQLITE_OK; |
15371 | if( p==0 ){ |
15372 | rc = SQLITE_NOMEM; |
15373 | }else if( p->eState!=RECOVER_STATE_INIT ){ |
15374 | rc = SQLITE_MISUSE; |
15375 | }else{ |
15376 | switch( op ){ |
15377 | case 789: |
15378 | /* This undocumented magic configuration option is used to set the |
15379 | ** name of the auxiliary database that is ATTACH-ed to the database |
15380 | ** connection and used to hold state information during the |
15381 | ** recovery process. This option is for debugging use only and |
15382 | ** is subject to change or removal at any time. */ |
15383 | sqlite3_free(p->zStateDb); |
15384 | p->zStateDb = recoverMPrintf(p, "%s" , (char*)pArg); |
15385 | break; |
15386 | |
15387 | case SQLITE_RECOVER_LOST_AND_FOUND: { |
15388 | const char *zArg = (const char*)pArg; |
15389 | sqlite3_free(p->zLostAndFound); |
15390 | if( zArg ){ |
15391 | p->zLostAndFound = recoverMPrintf(p, "%s" , zArg); |
15392 | }else{ |
15393 | p->zLostAndFound = 0; |
15394 | } |
15395 | break; |
15396 | } |
15397 | |
15398 | case SQLITE_RECOVER_FREELIST_CORRUPT: |
15399 | p->bFreelistCorrupt = *(int*)pArg; |
15400 | break; |
15401 | |
15402 | case SQLITE_RECOVER_ROWIDS: |
15403 | p->bRecoverRowid = *(int*)pArg; |
15404 | break; |
15405 | |
15406 | case SQLITE_RECOVER_SLOWINDEXES: |
15407 | p->bSlowIndexes = *(int*)pArg; |
15408 | break; |
15409 | |
15410 | default: |
15411 | rc = SQLITE_NOTFOUND; |
15412 | break; |
15413 | } |
15414 | } |
15415 | |
15416 | return rc; |
15417 | } |
15418 | |
15419 | /* |
15420 | ** Do a unit of work towards the recovery job. Return SQLITE_OK if |
15421 | ** no error has occurred but database recovery is not finished, SQLITE_DONE |
15422 | ** if database recovery has been successfully completed, or an SQLite |
15423 | ** error code if an error has occurred. |
15424 | */ |
15425 | int sqlite3_recover_step(sqlite3_recover *p){ |
15426 | if( p==0 ) return SQLITE_NOMEM; |
15427 | if( p->errCode==SQLITE_OK ) recoverStep(p); |
15428 | if( p->eState==RECOVER_STATE_DONE && p->errCode==SQLITE_OK ){ |
15429 | return SQLITE_DONE; |
15430 | } |
15431 | return p->errCode; |
15432 | } |
15433 | |
15434 | /* |
15435 | ** Do the configured recovery operation. Return SQLITE_OK if successful, or |
15436 | ** else an SQLite error code. |
15437 | */ |
15438 | int sqlite3_recover_run(sqlite3_recover *p){ |
15439 | while( SQLITE_OK==sqlite3_recover_step(p) ); |
15440 | return sqlite3_recover_errcode(p); |
15441 | } |
15442 | |
15443 | |
15444 | /* |
15445 | ** Free all resources associated with the recover handle passed as the only |
15446 | ** argument. The results of using a handle with any sqlite3_recover_** |
15447 | ** API function after it has been passed to this function are undefined. |
15448 | ** |
15449 | ** A copy of the value returned by the first call made to sqlite3_recover_run() |
15450 | ** on this handle is returned, or SQLITE_OK if sqlite3_recover_run() has |
15451 | ** not been called on this handle. |
15452 | */ |
15453 | int sqlite3_recover_finish(sqlite3_recover *p){ |
15454 | int rc; |
15455 | if( p==0 ){ |
15456 | rc = SQLITE_NOMEM; |
15457 | }else{ |
15458 | recoverFinalCleanup(p); |
15459 | if( p->bCloseTransaction && sqlite3_get_autocommit(p->dbIn)==0 ){ |
15460 | rc = sqlite3_exec(p->dbIn, "END" , 0, 0, 0); |
15461 | if( p->errCode==SQLITE_OK ) p->errCode = rc; |
15462 | } |
15463 | rc = p->errCode; |
15464 | sqlite3_free(p->zErrMsg); |
15465 | sqlite3_free(p->zStateDb); |
15466 | sqlite3_free(p->zLostAndFound); |
15467 | sqlite3_free(p->pPage1Cache); |
15468 | sqlite3_free(p); |
15469 | } |
15470 | return rc; |
15471 | } |
15472 | |
15473 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
15474 | |
15475 | /************************* End ../ext/recover/sqlite3recover.c ********************/ |
15476 | #endif |
15477 | |
15478 | #if defined(SQLITE_ENABLE_SESSION) |
15479 | /* |
15480 | ** State information for a single open session |
15481 | */ |
15482 | typedef struct OpenSession OpenSession; |
15483 | struct OpenSession { |
15484 | char *zName; /* Symbolic name for this session */ |
15485 | int nFilter; /* Number of xFilter rejection GLOB patterns */ |
15486 | char **azFilter; /* Array of xFilter rejection GLOB patterns */ |
15487 | sqlite3_session *p; /* The open session */ |
15488 | }; |
15489 | #endif |
15490 | |
15491 | typedef struct ExpertInfo ExpertInfo; |
15492 | struct ExpertInfo { |
15493 | sqlite3expert *pExpert; |
15494 | int bVerbose; |
15495 | }; |
15496 | |
15497 | /* A single line in the EQP output */ |
15498 | typedef struct EQPGraphRow EQPGraphRow; |
15499 | struct EQPGraphRow { |
15500 | int iEqpId; /* ID for this row */ |
15501 | int iParentId; /* ID of the parent row */ |
15502 | EQPGraphRow *pNext; /* Next row in sequence */ |
15503 | char zText[1]; /* Text to display for this row */ |
15504 | }; |
15505 | |
15506 | /* All EQP output is collected into an instance of the following */ |
15507 | typedef struct EQPGraph EQPGraph; |
15508 | struct EQPGraph { |
15509 | EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */ |
15510 | EQPGraphRow *pLast; /* Last element of the pRow list */ |
15511 | char zPrefix[100]; /* Graph prefix */ |
15512 | }; |
15513 | |
15514 | /* Parameters affecting columnar mode result display (defaulting together) */ |
15515 | typedef struct ColModeOpts { |
15516 | int iWrap; /* In columnar modes, wrap lines reaching this limit */ |
15517 | u8 bQuote; /* Quote results for .mode box and table */ |
15518 | u8 bWordWrap; /* In columnar modes, wrap at word boundaries */ |
15519 | } ColModeOpts; |
15520 | #define ColModeOpts_default { 60, 0, 0 } |
15521 | #define ColModeOpts_default_qbox { 60, 1, 0 } |
15522 | |
15523 | /* |
15524 | ** State information about the database connection is contained in an |
15525 | ** instance of the following structure. |
15526 | */ |
15527 | typedef struct ShellState ShellState; |
15528 | struct ShellState { |
15529 | sqlite3 *db; /* The database */ |
15530 | u8 autoExplain; /* Automatically turn on .explain mode */ |
15531 | u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ |
15532 | u8 autoEQPtest; /* autoEQP is in test mode */ |
15533 | u8 autoEQPtrace; /* autoEQP is in trace mode */ |
15534 | u8 scanstatsOn; /* True to display scan stats before each finalize */ |
15535 | u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ |
15536 | u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ |
15537 | u8 nEqpLevel; /* Depth of the EQP output graph */ |
15538 | u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ |
15539 | u8 bSafeMode; /* True to prohibit unsafe operations */ |
15540 | u8 bSafeModePersist; /* The long-term value of bSafeMode */ |
15541 | ColModeOpts cmOpts; /* Option values affecting columnar mode output */ |
15542 | unsigned statsOn; /* True to display memory stats before each finalize */ |
15543 | unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ |
15544 | int inputNesting; /* Track nesting level of .read and other redirects */ |
15545 | int outCount; /* Revert to stdout when reaching zero */ |
15546 | int cnt; /* Number of records displayed so far */ |
15547 | int lineno; /* Line number of last line read from in */ |
15548 | int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */ |
15549 | FILE *in; /* Read commands from this stream */ |
15550 | FILE *out; /* Write results here */ |
15551 | FILE *traceOut; /* Output for sqlite3_trace() */ |
15552 | int nErr; /* Number of errors seen */ |
15553 | int mode; /* An output mode setting */ |
15554 | int modePrior; /* Saved mode */ |
15555 | int cMode; /* temporary output mode for the current query */ |
15556 | int normalMode; /* Output mode before ".explain on" */ |
15557 | int writableSchema; /* True if PRAGMA writable_schema=ON */ |
15558 | int ; /* True to show column names in List or Column mode */ |
15559 | int nCheck; /* Number of ".check" commands run */ |
15560 | unsigned nProgress; /* Number of progress callbacks encountered */ |
15561 | unsigned mxProgress; /* Maximum progress callbacks before failing */ |
15562 | unsigned flgProgress; /* Flags for the progress callback */ |
15563 | unsigned shellFlgs; /* Various flags */ |
15564 | unsigned priorShFlgs; /* Saved copy of flags */ |
15565 | sqlite3_int64 szMax; /* --maxsize argument to .open */ |
15566 | char *zDestTable; /* Name of destination table when MODE_Insert */ |
15567 | char *zTempFile; /* Temporary file that might need deleting */ |
15568 | char zTestcase[30]; /* Name of current test case */ |
15569 | char colSeparator[20]; /* Column separator character for several modes */ |
15570 | char rowSeparator[20]; /* Row separator character for MODE_Ascii */ |
15571 | char colSepPrior[20]; /* Saved column separator */ |
15572 | char rowSepPrior[20]; /* Saved row separator */ |
15573 | int *colWidth; /* Requested width of each column in columnar modes */ |
15574 | int *actualWidth; /* Actual width of each column */ |
15575 | int nWidth; /* Number of slots in colWidth[] and actualWidth[] */ |
15576 | char nullValue[20]; /* The text to print when a NULL comes back from |
15577 | ** the database */ |
15578 | char outfile[FILENAME_MAX]; /* Filename for *out */ |
15579 | sqlite3_stmt *pStmt; /* Current statement if any. */ |
15580 | FILE *pLog; /* Write log output here */ |
15581 | struct AuxDb { /* Storage space for auxiliary database connections */ |
15582 | sqlite3 *db; /* Connection pointer */ |
15583 | const char *zDbFilename; /* Filename used to open the connection */ |
15584 | char *zFreeOnClose; /* Free this memory allocation on close */ |
15585 | #if defined(SQLITE_ENABLE_SESSION) |
15586 | int nSession; /* Number of active sessions */ |
15587 | OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ |
15588 | #endif |
15589 | } aAuxDb[5], /* Array of all database connections */ |
15590 | *pAuxDb; /* Currently active database connection */ |
15591 | int *aiIndent; /* Array of indents used in MODE_Explain */ |
15592 | int nIndent; /* Size of array aiIndent[] */ |
15593 | int iIndent; /* Index of current op in aiIndent[] */ |
15594 | char *zNonce; /* Nonce for temporary safe-mode excapes */ |
15595 | EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ |
15596 | ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ |
15597 | #ifdef SQLITE_SHELL_FIDDLE |
15598 | struct { |
15599 | const char * zInput; /* Input string from wasm/JS proxy */ |
15600 | const char * zPos; /* Cursor pos into zInput */ |
15601 | const char * zDefaultDbName; /* Default name for db file */ |
15602 | } wasm; |
15603 | #endif |
15604 | }; |
15605 | |
15606 | #ifdef SQLITE_SHELL_FIDDLE |
15607 | static ShellState shellState; |
15608 | #endif |
15609 | |
15610 | |
15611 | /* Allowed values for ShellState.autoEQP |
15612 | */ |
15613 | #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */ |
15614 | #define AUTOEQP_on 1 /* Automatic EQP is on */ |
15615 | #define AUTOEQP_trigger 2 /* On and also show plans for triggers */ |
15616 | #define AUTOEQP_full 3 /* Show full EXPLAIN */ |
15617 | |
15618 | /* Allowed values for ShellState.openMode |
15619 | */ |
15620 | #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ |
15621 | #define SHELL_OPEN_NORMAL 1 /* Normal database file */ |
15622 | #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ |
15623 | #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ |
15624 | #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ |
15625 | #define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */ |
15626 | #define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */ |
15627 | |
15628 | /* Allowed values for ShellState.eTraceType |
15629 | */ |
15630 | #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ |
15631 | #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ |
15632 | #define SHELL_TRACE_NORMALIZED 2 /* Show normalized SQL text */ |
15633 | |
15634 | /* Bits in the ShellState.flgProgress variable */ |
15635 | #define SHELL_PROGRESS_QUIET 0x01 /* Omit announcing every progress callback */ |
15636 | #define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progres |
15637 | ** callback limit is reached, and for each |
15638 | ** top-level SQL statement */ |
15639 | #define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */ |
15640 | |
15641 | /* |
15642 | ** These are the allowed shellFlgs values |
15643 | */ |
15644 | #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */ |
15645 | #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */ |
15646 | #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */ |
15647 | #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */ |
15648 | #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ |
15649 | #define SHFLG_CountChanges 0x00000020 /* .changes setting */ |
15650 | #define SHFLG_Echo 0x00000040 /* .echo on/off, or --echo setting */ |
15651 | #define 0x00000080 /* showHeader has been specified */ |
15652 | #define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */ |
15653 | #define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */ |
15654 | |
15655 | /* |
15656 | ** Macros for testing and setting shellFlgs |
15657 | */ |
15658 | #define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0) |
15659 | #define ShellSetFlag(P,X) ((P)->shellFlgs|=(X)) |
15660 | #define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X))) |
15661 | |
15662 | /* |
15663 | ** These are the allowed modes. |
15664 | */ |
15665 | #define MODE_Line 0 /* One column per line. Blank line between records */ |
15666 | #define MODE_Column 1 /* One record per line in neat columns */ |
15667 | #define MODE_List 2 /* One record per line with a separator */ |
15668 | #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ |
15669 | #define MODE_Html 4 /* Generate an XHTML table */ |
15670 | #define MODE_Insert 5 /* Generate SQL "insert" statements */ |
15671 | #define MODE_Quote 6 /* Quote values as for SQL */ |
15672 | #define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */ |
15673 | #define MODE_Csv 8 /* Quote strings, numbers are plain */ |
15674 | #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ |
15675 | #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ |
15676 | #define MODE_Pretty 11 /* Pretty-print schemas */ |
15677 | #define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */ |
15678 | #define MODE_Json 13 /* Output JSON */ |
15679 | #define MODE_Markdown 14 /* Markdown formatting */ |
15680 | #define MODE_Table 15 /* MySQL-style table formatting */ |
15681 | #define MODE_Box 16 /* Unicode box-drawing characters */ |
15682 | #define MODE_Count 17 /* Output only a count of the rows of output */ |
15683 | #define MODE_Off 18 /* No query output shown */ |
15684 | |
15685 | static const char *modeDescr[] = { |
15686 | "line" , |
15687 | "column" , |
15688 | "list" , |
15689 | "semi" , |
15690 | "html" , |
15691 | "insert" , |
15692 | "quote" , |
15693 | "tcl" , |
15694 | "csv" , |
15695 | "explain" , |
15696 | "ascii" , |
15697 | "prettyprint" , |
15698 | "eqp" , |
15699 | "json" , |
15700 | "markdown" , |
15701 | "table" , |
15702 | "box" , |
15703 | "count" , |
15704 | "off" |
15705 | }; |
15706 | |
15707 | /* |
15708 | ** These are the column/row/line separators used by the various |
15709 | ** import/export modes. |
15710 | */ |
15711 | #define SEP_Column "|" |
15712 | #define SEP_Row "\n" |
15713 | #define SEP_Tab "\t" |
15714 | #define SEP_Space " " |
15715 | #define SEP_Comma "," |
15716 | #define SEP_CrLf "\r\n" |
15717 | #define SEP_Unit "\x1F" |
15718 | #define SEP_Record "\x1E" |
15719 | |
15720 | /* |
15721 | ** Limit input nesting via .read or any other input redirect. |
15722 | ** It's not too expensive, so a generous allowance can be made. |
15723 | */ |
15724 | #define MAX_INPUT_NESTING 25 |
15725 | |
15726 | /* |
15727 | ** A callback for the sqlite3_log() interface. |
15728 | */ |
15729 | static void shellLog(void *pArg, int iErrCode, const char *zMsg){ |
15730 | ShellState *p = (ShellState*)pArg; |
15731 | if( p->pLog==0 ) return; |
15732 | utf8_printf(p->pLog, "(%d) %s\n" , iErrCode, zMsg); |
15733 | fflush(p->pLog); |
15734 | } |
15735 | |
15736 | /* |
15737 | ** SQL function: shell_putsnl(X) |
15738 | ** |
15739 | ** Write the text X to the screen (or whatever output is being directed) |
15740 | ** adding a newline at the end, and then return X. |
15741 | */ |
15742 | static void shellPutsFunc( |
15743 | sqlite3_context *pCtx, |
15744 | int nVal, |
15745 | sqlite3_value **apVal |
15746 | ){ |
15747 | ShellState *p = (ShellState*)sqlite3_user_data(pCtx); |
15748 | (void)nVal; |
15749 | utf8_printf(p->out, "%s\n" , sqlite3_value_text(apVal[0])); |
15750 | sqlite3_result_value(pCtx, apVal[0]); |
15751 | } |
15752 | |
15753 | /* |
15754 | ** If in safe mode, print an error message described by the arguments |
15755 | ** and exit immediately. |
15756 | */ |
15757 | static void failIfSafeMode( |
15758 | ShellState *p, |
15759 | const char *zErrMsg, |
15760 | ... |
15761 | ){ |
15762 | if( p->bSafeMode ){ |
15763 | va_list ap; |
15764 | char *zMsg; |
15765 | va_start(ap, zErrMsg); |
15766 | zMsg = sqlite3_vmprintf(zErrMsg, ap); |
15767 | va_end(ap); |
15768 | raw_printf(stderr, "line %d: " , p->lineno); |
15769 | utf8_printf(stderr, "%s\n" , zMsg); |
15770 | exit(1); |
15771 | } |
15772 | } |
15773 | |
15774 | /* |
15775 | ** SQL function: edit(VALUE) |
15776 | ** edit(VALUE,EDITOR) |
15777 | ** |
15778 | ** These steps: |
15779 | ** |
15780 | ** (1) Write VALUE into a temporary file. |
15781 | ** (2) Run program EDITOR on that temporary file. |
15782 | ** (3) Read the temporary file back and return its content as the result. |
15783 | ** (4) Delete the temporary file |
15784 | ** |
15785 | ** If the EDITOR argument is omitted, use the value in the VISUAL |
15786 | ** environment variable. If still there is no EDITOR, through an error. |
15787 | ** |
15788 | ** Also throw an error if the EDITOR program returns a non-zero exit code. |
15789 | */ |
15790 | #ifndef SQLITE_NOHAVE_SYSTEM |
15791 | static void editFunc( |
15792 | sqlite3_context *context, |
15793 | int argc, |
15794 | sqlite3_value **argv |
15795 | ){ |
15796 | const char *zEditor; |
15797 | char *zTempFile = 0; |
15798 | sqlite3 *db; |
15799 | char *zCmd = 0; |
15800 | int bBin; |
15801 | int rc; |
15802 | int hasCRNL = 0; |
15803 | FILE *f = 0; |
15804 | sqlite3_int64 sz; |
15805 | sqlite3_int64 x; |
15806 | unsigned char *p = 0; |
15807 | |
15808 | if( argc==2 ){ |
15809 | zEditor = (const char*)sqlite3_value_text(argv[1]); |
15810 | }else{ |
15811 | zEditor = getenv("VISUAL" ); |
15812 | } |
15813 | if( zEditor==0 ){ |
15814 | sqlite3_result_error(context, "no editor for edit()" , -1); |
15815 | return; |
15816 | } |
15817 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ |
15818 | sqlite3_result_error(context, "NULL input to edit()" , -1); |
15819 | return; |
15820 | } |
15821 | db = sqlite3_context_db_handle(context); |
15822 | zTempFile = 0; |
15823 | sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile); |
15824 | if( zTempFile==0 ){ |
15825 | sqlite3_uint64 r = 0; |
15826 | sqlite3_randomness(sizeof(r), &r); |
15827 | zTempFile = sqlite3_mprintf("temp%llx" , r); |
15828 | if( zTempFile==0 ){ |
15829 | sqlite3_result_error_nomem(context); |
15830 | return; |
15831 | } |
15832 | } |
15833 | bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; |
15834 | /* When writing the file to be edited, do \n to \r\n conversions on systems |
15835 | ** that want \r\n line endings */ |
15836 | f = fopen(zTempFile, bBin ? "wb" : "w" ); |
15837 | if( f==0 ){ |
15838 | sqlite3_result_error(context, "edit() cannot open temp file" , -1); |
15839 | goto edit_func_end; |
15840 | } |
15841 | sz = sqlite3_value_bytes(argv[0]); |
15842 | if( bBin ){ |
15843 | x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f); |
15844 | }else{ |
15845 | const char *z = (const char*)sqlite3_value_text(argv[0]); |
15846 | /* Remember whether or not the value originally contained \r\n */ |
15847 | if( z && strstr(z,"\r\n" )!=0 ) hasCRNL = 1; |
15848 | x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f); |
15849 | } |
15850 | fclose(f); |
15851 | f = 0; |
15852 | if( x!=sz ){ |
15853 | sqlite3_result_error(context, "edit() could not write the whole file" , -1); |
15854 | goto edit_func_end; |
15855 | } |
15856 | zCmd = sqlite3_mprintf("%s \"%s\"" , zEditor, zTempFile); |
15857 | if( zCmd==0 ){ |
15858 | sqlite3_result_error_nomem(context); |
15859 | goto edit_func_end; |
15860 | } |
15861 | rc = system(zCmd); |
15862 | sqlite3_free(zCmd); |
15863 | if( rc ){ |
15864 | sqlite3_result_error(context, "EDITOR returned non-zero" , -1); |
15865 | goto edit_func_end; |
15866 | } |
15867 | f = fopen(zTempFile, "rb" ); |
15868 | if( f==0 ){ |
15869 | sqlite3_result_error(context, |
15870 | "edit() cannot reopen temp file after edit" , -1); |
15871 | goto edit_func_end; |
15872 | } |
15873 | fseek(f, 0, SEEK_END); |
15874 | sz = ftell(f); |
15875 | rewind(f); |
15876 | p = sqlite3_malloc64( sz+1 ); |
15877 | if( p==0 ){ |
15878 | sqlite3_result_error_nomem(context); |
15879 | goto edit_func_end; |
15880 | } |
15881 | x = fread(p, 1, (size_t)sz, f); |
15882 | fclose(f); |
15883 | f = 0; |
15884 | if( x!=sz ){ |
15885 | sqlite3_result_error(context, "could not read back the whole file" , -1); |
15886 | goto edit_func_end; |
15887 | } |
15888 | if( bBin ){ |
15889 | sqlite3_result_blob64(context, p, sz, sqlite3_free); |
15890 | }else{ |
15891 | sqlite3_int64 i, j; |
15892 | if( hasCRNL ){ |
15893 | /* If the original contains \r\n then do no conversions back to \n */ |
15894 | }else{ |
15895 | /* If the file did not originally contain \r\n then convert any new |
15896 | ** \r\n back into \n */ |
15897 | for(i=j=0; i<sz; i++){ |
15898 | if( p[i]=='\r' && p[i+1]=='\n' ) i++; |
15899 | p[j++] = p[i]; |
15900 | } |
15901 | sz = j; |
15902 | p[sz] = 0; |
15903 | } |
15904 | sqlite3_result_text64(context, (const char*)p, sz, |
15905 | sqlite3_free, SQLITE_UTF8); |
15906 | } |
15907 | p = 0; |
15908 | |
15909 | edit_func_end: |
15910 | if( f ) fclose(f); |
15911 | unlink(zTempFile); |
15912 | sqlite3_free(zTempFile); |
15913 | sqlite3_free(p); |
15914 | } |
15915 | #endif /* SQLITE_NOHAVE_SYSTEM */ |
15916 | |
15917 | /* |
15918 | ** Save or restore the current output mode |
15919 | */ |
15920 | static void outputModePush(ShellState *p){ |
15921 | p->modePrior = p->mode; |
15922 | p->priorShFlgs = p->shellFlgs; |
15923 | memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator)); |
15924 | memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator)); |
15925 | } |
15926 | static void outputModePop(ShellState *p){ |
15927 | p->mode = p->modePrior; |
15928 | p->shellFlgs = p->priorShFlgs; |
15929 | memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator)); |
15930 | memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator)); |
15931 | } |
15932 | |
15933 | /* |
15934 | ** Output the given string as a hex-encoded blob (eg. X'1234' ) |
15935 | */ |
15936 | static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ |
15937 | int i; |
15938 | unsigned char *aBlob = (unsigned char*)pBlob; |
15939 | |
15940 | char *zStr = sqlite3_malloc(nBlob*2 + 1); |
15941 | shell_check_oom(zStr); |
15942 | |
15943 | for(i=0; i<nBlob; i++){ |
15944 | static const char aHex[] = { |
15945 | '0', '1', '2', '3', '4', '5', '6', '7', |
15946 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' |
15947 | }; |
15948 | zStr[i*2] = aHex[ (aBlob[i] >> 4) ]; |
15949 | zStr[i*2+1] = aHex[ (aBlob[i] & 0x0F) ]; |
15950 | } |
15951 | zStr[i*2] = '\0'; |
15952 | |
15953 | raw_printf(out,"X'%s'" , zStr); |
15954 | sqlite3_free(zStr); |
15955 | } |
15956 | |
15957 | /* |
15958 | ** Find a string that is not found anywhere in z[]. Return a pointer |
15959 | ** to that string. |
15960 | ** |
15961 | ** Try to use zA and zB first. If both of those are already found in z[] |
15962 | ** then make up some string and store it in the buffer zBuf. |
15963 | */ |
15964 | static const char *unused_string( |
15965 | const char *z, /* Result must not appear anywhere in z */ |
15966 | const char *zA, const char *zB, /* Try these first */ |
15967 | char *zBuf /* Space to store a generated string */ |
15968 | ){ |
15969 | unsigned i = 0; |
15970 | if( strstr(z, zA)==0 ) return zA; |
15971 | if( strstr(z, zB)==0 ) return zB; |
15972 | do{ |
15973 | sqlite3_snprintf(20,zBuf,"(%s%u)" , zA, i++); |
15974 | }while( strstr(z,zBuf)!=0 ); |
15975 | return zBuf; |
15976 | } |
15977 | |
15978 | /* |
15979 | ** Output the given string as a quoted string using SQL quoting conventions. |
15980 | ** |
15981 | ** See also: output_quoted_escaped_string() |
15982 | */ |
15983 | static void output_quoted_string(FILE *out, const char *z){ |
15984 | int i; |
15985 | char c; |
15986 | setBinaryMode(out, 1); |
15987 | for(i=0; (c = z[i])!=0 && c!='\''; i++){} |
15988 | if( c==0 ){ |
15989 | utf8_printf(out,"'%s'" ,z); |
15990 | }else{ |
15991 | raw_printf(out, "'" ); |
15992 | while( *z ){ |
15993 | for(i=0; (c = z[i])!=0 && c!='\''; i++){} |
15994 | if( c=='\'' ) i++; |
15995 | if( i ){ |
15996 | utf8_printf(out, "%.*s" , i, z); |
15997 | z += i; |
15998 | } |
15999 | if( c=='\'' ){ |
16000 | raw_printf(out, "'" ); |
16001 | continue; |
16002 | } |
16003 | if( c==0 ){ |
16004 | break; |
16005 | } |
16006 | z++; |
16007 | } |
16008 | raw_printf(out, "'" ); |
16009 | } |
16010 | setTextMode(out, 1); |
16011 | } |
16012 | |
16013 | /* |
16014 | ** Output the given string as a quoted string using SQL quoting conventions. |
16015 | ** Additionallly , escape the "\n" and "\r" characters so that they do not |
16016 | ** get corrupted by end-of-line translation facilities in some operating |
16017 | ** systems. |
16018 | ** |
16019 | ** This is like output_quoted_string() but with the addition of the \r\n |
16020 | ** escape mechanism. |
16021 | */ |
16022 | static void output_quoted_escaped_string(FILE *out, const char *z){ |
16023 | int i; |
16024 | char c; |
16025 | setBinaryMode(out, 1); |
16026 | for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} |
16027 | if( c==0 ){ |
16028 | utf8_printf(out,"'%s'" ,z); |
16029 | }else{ |
16030 | const char *zNL = 0; |
16031 | const char *zCR = 0; |
16032 | int nNL = 0; |
16033 | int nCR = 0; |
16034 | char zBuf1[20], zBuf2[20]; |
16035 | for(i=0; z[i]; i++){ |
16036 | if( z[i]=='\n' ) nNL++; |
16037 | if( z[i]=='\r' ) nCR++; |
16038 | } |
16039 | if( nNL ){ |
16040 | raw_printf(out, "replace(" ); |
16041 | zNL = unused_string(z, "\\n" , "\\012" , zBuf1); |
16042 | } |
16043 | if( nCR ){ |
16044 | raw_printf(out, "replace(" ); |
16045 | zCR = unused_string(z, "\\r" , "\\015" , zBuf2); |
16046 | } |
16047 | raw_printf(out, "'" ); |
16048 | while( *z ){ |
16049 | for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} |
16050 | if( c=='\'' ) i++; |
16051 | if( i ){ |
16052 | utf8_printf(out, "%.*s" , i, z); |
16053 | z += i; |
16054 | } |
16055 | if( c=='\'' ){ |
16056 | raw_printf(out, "'" ); |
16057 | continue; |
16058 | } |
16059 | if( c==0 ){ |
16060 | break; |
16061 | } |
16062 | z++; |
16063 | if( c=='\n' ){ |
16064 | raw_printf(out, "%s" , zNL); |
16065 | continue; |
16066 | } |
16067 | raw_printf(out, "%s" , zCR); |
16068 | } |
16069 | raw_printf(out, "'" ); |
16070 | if( nCR ){ |
16071 | raw_printf(out, ",'%s',char(13))" , zCR); |
16072 | } |
16073 | if( nNL ){ |
16074 | raw_printf(out, ",'%s',char(10))" , zNL); |
16075 | } |
16076 | } |
16077 | setTextMode(out, 1); |
16078 | } |
16079 | |
16080 | /* |
16081 | ** Output the given string as a quoted according to C or TCL quoting rules. |
16082 | */ |
16083 | static void output_c_string(FILE *out, const char *z){ |
16084 | unsigned int c; |
16085 | fputc('"', out); |
16086 | while( (c = *(z++))!=0 ){ |
16087 | if( c=='\\' ){ |
16088 | fputc(c, out); |
16089 | fputc(c, out); |
16090 | }else if( c=='"' ){ |
16091 | fputc('\\', out); |
16092 | fputc('"', out); |
16093 | }else if( c=='\t' ){ |
16094 | fputc('\\', out); |
16095 | fputc('t', out); |
16096 | }else if( c=='\n' ){ |
16097 | fputc('\\', out); |
16098 | fputc('n', out); |
16099 | }else if( c=='\r' ){ |
16100 | fputc('\\', out); |
16101 | fputc('r', out); |
16102 | }else if( !isprint(c&0xff) ){ |
16103 | raw_printf(out, "\\%03o" , c&0xff); |
16104 | }else{ |
16105 | fputc(c, out); |
16106 | } |
16107 | } |
16108 | fputc('"', out); |
16109 | } |
16110 | |
16111 | /* |
16112 | ** Output the given string as a quoted according to JSON quoting rules. |
16113 | */ |
16114 | static void output_json_string(FILE *out, const char *z, i64 n){ |
16115 | unsigned int c; |
16116 | if( n<0 ) n = strlen(z); |
16117 | fputc('"', out); |
16118 | while( n-- ){ |
16119 | c = *(z++); |
16120 | if( c=='\\' || c=='"' ){ |
16121 | fputc('\\', out); |
16122 | fputc(c, out); |
16123 | }else if( c<=0x1f ){ |
16124 | fputc('\\', out); |
16125 | if( c=='\b' ){ |
16126 | fputc('b', out); |
16127 | }else if( c=='\f' ){ |
16128 | fputc('f', out); |
16129 | }else if( c=='\n' ){ |
16130 | fputc('n', out); |
16131 | }else if( c=='\r' ){ |
16132 | fputc('r', out); |
16133 | }else if( c=='\t' ){ |
16134 | fputc('t', out); |
16135 | }else{ |
16136 | raw_printf(out, "u%04x" ,c); |
16137 | } |
16138 | }else{ |
16139 | fputc(c, out); |
16140 | } |
16141 | } |
16142 | fputc('"', out); |
16143 | } |
16144 | |
16145 | /* |
16146 | ** Output the given string with characters that are special to |
16147 | ** HTML escaped. |
16148 | */ |
16149 | static void output_html_string(FILE *out, const char *z){ |
16150 | int i; |
16151 | if( z==0 ) z = "" ; |
16152 | while( *z ){ |
16153 | for(i=0; z[i] |
16154 | && z[i]!='<' |
16155 | && z[i]!='&' |
16156 | && z[i]!='>' |
16157 | && z[i]!='\"' |
16158 | && z[i]!='\''; |
16159 | i++){} |
16160 | if( i>0 ){ |
16161 | utf8_printf(out,"%.*s" ,i,z); |
16162 | } |
16163 | if( z[i]=='<' ){ |
16164 | raw_printf(out,"<" ); |
16165 | }else if( z[i]=='&' ){ |
16166 | raw_printf(out,"&" ); |
16167 | }else if( z[i]=='>' ){ |
16168 | raw_printf(out,">" ); |
16169 | }else if( z[i]=='\"' ){ |
16170 | raw_printf(out,""" ); |
16171 | }else if( z[i]=='\'' ){ |
16172 | raw_printf(out,"'" ); |
16173 | }else{ |
16174 | break; |
16175 | } |
16176 | z += i + 1; |
16177 | } |
16178 | } |
16179 | |
16180 | /* |
16181 | ** If a field contains any character identified by a 1 in the following |
16182 | ** array, then the string must be quoted for CSV. |
16183 | */ |
16184 | static const char needCsvQuote[] = { |
16185 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16186 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16187 | 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, |
16188 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
16189 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
16190 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
16191 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
16192 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, |
16193 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16194 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16195 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16196 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16197 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16198 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16199 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16200 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
16201 | }; |
16202 | |
16203 | /* |
16204 | ** Output a single term of CSV. Actually, p->colSeparator is used for |
16205 | ** the separator, which may or may not be a comma. p->nullValue is |
16206 | ** the null value. Strings are quoted if necessary. The separator |
16207 | ** is only issued if bSep is true. |
16208 | */ |
16209 | static void output_csv(ShellState *p, const char *z, int bSep){ |
16210 | FILE *out = p->out; |
16211 | if( z==0 ){ |
16212 | utf8_printf(out,"%s" ,p->nullValue); |
16213 | }else{ |
16214 | unsigned i; |
16215 | for(i=0; z[i]; i++){ |
16216 | if( needCsvQuote[((unsigned char*)z)[i]] ){ |
16217 | i = 0; |
16218 | break; |
16219 | } |
16220 | } |
16221 | if( i==0 || strstr(z, p->colSeparator)!=0 ){ |
16222 | char *zQuoted = sqlite3_mprintf("\"%w\"" , z); |
16223 | shell_check_oom(zQuoted); |
16224 | utf8_printf(out, "%s" , zQuoted); |
16225 | sqlite3_free(zQuoted); |
16226 | }else{ |
16227 | utf8_printf(out, "%s" , z); |
16228 | } |
16229 | } |
16230 | if( bSep ){ |
16231 | utf8_printf(p->out, "%s" , p->colSeparator); |
16232 | } |
16233 | } |
16234 | |
16235 | /* |
16236 | ** This routine runs when the user presses Ctrl-C |
16237 | */ |
16238 | static void interrupt_handler(int NotUsed){ |
16239 | UNUSED_PARAMETER(NotUsed); |
16240 | seenInterrupt++; |
16241 | if( seenInterrupt>2 ) exit(1); |
16242 | if( globalDb ) sqlite3_interrupt(globalDb); |
16243 | } |
16244 | |
16245 | #if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) |
16246 | /* |
16247 | ** This routine runs for console events (e.g. Ctrl-C) on Win32 |
16248 | */ |
16249 | static BOOL WINAPI ConsoleCtrlHandler( |
16250 | DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */ |
16251 | ){ |
16252 | if( dwCtrlType==CTRL_C_EVENT ){ |
16253 | interrupt_handler(0); |
16254 | return TRUE; |
16255 | } |
16256 | return FALSE; |
16257 | } |
16258 | #endif |
16259 | |
16260 | #ifndef SQLITE_OMIT_AUTHORIZATION |
16261 | /* |
16262 | ** This authorizer runs in safe mode. |
16263 | */ |
16264 | static int safeModeAuth( |
16265 | void *pClientData, |
16266 | int op, |
16267 | const char *zA1, |
16268 | const char *zA2, |
16269 | const char *zA3, |
16270 | const char *zA4 |
16271 | ){ |
16272 | ShellState *p = (ShellState*)pClientData; |
16273 | static const char *azProhibitedFunctions[] = { |
16274 | "edit" , |
16275 | "fts3_tokenizer" , |
16276 | "load_extension" , |
16277 | "readfile" , |
16278 | "writefile" , |
16279 | "zipfile" , |
16280 | "zipfile_cds" , |
16281 | }; |
16282 | UNUSED_PARAMETER(zA1); |
16283 | UNUSED_PARAMETER(zA3); |
16284 | UNUSED_PARAMETER(zA4); |
16285 | switch( op ){ |
16286 | case SQLITE_ATTACH: { |
16287 | #ifndef SQLITE_SHELL_FIDDLE |
16288 | /* In WASM builds the filesystem is a virtual sandbox, so |
16289 | ** there's no harm in using ATTACH. */ |
16290 | failIfSafeMode(p, "cannot run ATTACH in safe mode" ); |
16291 | #endif |
16292 | break; |
16293 | } |
16294 | case SQLITE_FUNCTION: { |
16295 | int i; |
16296 | for(i=0; i<ArraySize(azProhibitedFunctions); i++){ |
16297 | if( sqlite3_stricmp(zA2, azProhibitedFunctions[i])==0 ){ |
16298 | failIfSafeMode(p, "cannot use the %s() function in safe mode" , |
16299 | azProhibitedFunctions[i]); |
16300 | } |
16301 | } |
16302 | break; |
16303 | } |
16304 | } |
16305 | return SQLITE_OK; |
16306 | } |
16307 | |
16308 | /* |
16309 | ** When the ".auth ON" is set, the following authorizer callback is |
16310 | ** invoked. It always returns SQLITE_OK. |
16311 | */ |
16312 | static int shellAuth( |
16313 | void *pClientData, |
16314 | int op, |
16315 | const char *zA1, |
16316 | const char *zA2, |
16317 | const char *zA3, |
16318 | const char *zA4 |
16319 | ){ |
16320 | ShellState *p = (ShellState*)pClientData; |
16321 | static const char *azAction[] = { 0, |
16322 | "CREATE_INDEX" , "CREATE_TABLE" , "CREATE_TEMP_INDEX" , |
16323 | "CREATE_TEMP_TABLE" , "CREATE_TEMP_TRIGGER" , "CREATE_TEMP_VIEW" , |
16324 | "CREATE_TRIGGER" , "CREATE_VIEW" , "DELETE" , |
16325 | "DROP_INDEX" , "DROP_TABLE" , "DROP_TEMP_INDEX" , |
16326 | "DROP_TEMP_TABLE" , "DROP_TEMP_TRIGGER" , "DROP_TEMP_VIEW" , |
16327 | "DROP_TRIGGER" , "DROP_VIEW" , "INSERT" , |
16328 | "PRAGMA" , "READ" , "SELECT" , |
16329 | "TRANSACTION" , "UPDATE" , "ATTACH" , |
16330 | "DETACH" , "ALTER_TABLE" , "REINDEX" , |
16331 | "ANALYZE" , "CREATE_VTABLE" , "DROP_VTABLE" , |
16332 | "FUNCTION" , "SAVEPOINT" , "RECURSIVE" |
16333 | }; |
16334 | int i; |
16335 | const char *az[4]; |
16336 | az[0] = zA1; |
16337 | az[1] = zA2; |
16338 | az[2] = zA3; |
16339 | az[3] = zA4; |
16340 | utf8_printf(p->out, "authorizer: %s" , azAction[op]); |
16341 | for(i=0; i<4; i++){ |
16342 | raw_printf(p->out, " " ); |
16343 | if( az[i] ){ |
16344 | output_c_string(p->out, az[i]); |
16345 | }else{ |
16346 | raw_printf(p->out, "NULL" ); |
16347 | } |
16348 | } |
16349 | raw_printf(p->out, "\n" ); |
16350 | if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4); |
16351 | return SQLITE_OK; |
16352 | } |
16353 | #endif |
16354 | |
16355 | /* |
16356 | ** Print a schema statement. Part of MODE_Semi and MODE_Pretty output. |
16357 | ** |
16358 | ** This routine converts some CREATE TABLE statements for shadow tables |
16359 | ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements. |
16360 | ** |
16361 | ** If the schema statement in z[] contains a start-of-comment and if |
16362 | ** sqlite3_complete() returns false, try to terminate the comment before |
16363 | ** printing the result. https://sqlite.org/forum/forumpost/d7be961c5c |
16364 | */ |
16365 | static void printSchemaLine(FILE *out, const char *z, const char *zTail){ |
16366 | char *zToFree = 0; |
16367 | if( z==0 ) return; |
16368 | if( zTail==0 ) return; |
16369 | if( zTail[0]==';' && (strstr(z, "/*" )!=0 || strstr(z,"--" )!=0) ){ |
16370 | const char *zOrig = z; |
16371 | static const char *azTerm[] = { "" , "*/" , "\n" }; |
16372 | int i; |
16373 | for(i=0; i<ArraySize(azTerm); i++){ |
16374 | char *zNew = sqlite3_mprintf("%s%s;" , zOrig, azTerm[i]); |
16375 | if( sqlite3_complete(zNew) ){ |
16376 | size_t n = strlen(zNew); |
16377 | zNew[n-1] = 0; |
16378 | zToFree = zNew; |
16379 | z = zNew; |
16380 | break; |
16381 | } |
16382 | sqlite3_free(zNew); |
16383 | } |
16384 | } |
16385 | if( sqlite3_strglob("CREATE TABLE ['\"]*" , z)==0 ){ |
16386 | utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s" , z+13, zTail); |
16387 | }else{ |
16388 | utf8_printf(out, "%s%s" , z, zTail); |
16389 | } |
16390 | sqlite3_free(zToFree); |
16391 | } |
16392 | static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ |
16393 | char c = z[n]; |
16394 | z[n] = 0; |
16395 | printSchemaLine(out, z, zTail); |
16396 | z[n] = c; |
16397 | } |
16398 | |
16399 | /* |
16400 | ** Return true if string z[] has nothing but whitespace and comments to the |
16401 | ** end of the first line. |
16402 | */ |
16403 | static int wsToEol(const char *z){ |
16404 | int i; |
16405 | for(i=0; z[i]; i++){ |
16406 | if( z[i]=='\n' ) return 1; |
16407 | if( IsSpace(z[i]) ) continue; |
16408 | if( z[i]=='-' && z[i+1]=='-' ) return 1; |
16409 | return 0; |
16410 | } |
16411 | return 1; |
16412 | } |
16413 | |
16414 | /* |
16415 | ** Add a new entry to the EXPLAIN QUERY PLAN data |
16416 | */ |
16417 | static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){ |
16418 | EQPGraphRow *pNew; |
16419 | i64 nText; |
16420 | if( zText==0 ) return; |
16421 | nText = strlen(zText); |
16422 | if( p->autoEQPtest ){ |
16423 | utf8_printf(p->out, "%d,%d,%s\n" , iEqpId, p2, zText); |
16424 | } |
16425 | pNew = sqlite3_malloc64( sizeof(*pNew) + nText ); |
16426 | shell_check_oom(pNew); |
16427 | pNew->iEqpId = iEqpId; |
16428 | pNew->iParentId = p2; |
16429 | memcpy(pNew->zText, zText, nText+1); |
16430 | pNew->pNext = 0; |
16431 | if( p->sGraph.pLast ){ |
16432 | p->sGraph.pLast->pNext = pNew; |
16433 | }else{ |
16434 | p->sGraph.pRow = pNew; |
16435 | } |
16436 | p->sGraph.pLast = pNew; |
16437 | } |
16438 | |
16439 | /* |
16440 | ** Free and reset the EXPLAIN QUERY PLAN data that has been collected |
16441 | ** in p->sGraph. |
16442 | */ |
16443 | static void eqp_reset(ShellState *p){ |
16444 | EQPGraphRow *pRow, *pNext; |
16445 | for(pRow = p->sGraph.pRow; pRow; pRow = pNext){ |
16446 | pNext = pRow->pNext; |
16447 | sqlite3_free(pRow); |
16448 | } |
16449 | memset(&p->sGraph, 0, sizeof(p->sGraph)); |
16450 | } |
16451 | |
16452 | /* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after |
16453 | ** pOld, or return the first such line if pOld is NULL |
16454 | */ |
16455 | static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){ |
16456 | EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow; |
16457 | while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext; |
16458 | return pRow; |
16459 | } |
16460 | |
16461 | /* Render a single level of the graph that has iEqpId as its parent. Called |
16462 | ** recursively to render sublevels. |
16463 | */ |
16464 | static void eqp_render_level(ShellState *p, int iEqpId){ |
16465 | EQPGraphRow *pRow, *pNext; |
16466 | i64 n = strlen(p->sGraph.zPrefix); |
16467 | char *z; |
16468 | for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ |
16469 | pNext = eqp_next_row(p, iEqpId, pRow); |
16470 | z = pRow->zText; |
16471 | utf8_printf(p->out, "%s%s%s\n" , p->sGraph.zPrefix, |
16472 | pNext ? "|--" : "`--" , z); |
16473 | if( n<(i64)sizeof(p->sGraph.zPrefix)-7 ){ |
16474 | memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " " , 4); |
16475 | eqp_render_level(p, pRow->iEqpId); |
16476 | p->sGraph.zPrefix[n] = 0; |
16477 | } |
16478 | } |
16479 | } |
16480 | |
16481 | /* |
16482 | ** Display and reset the EXPLAIN QUERY PLAN data |
16483 | */ |
16484 | static void eqp_render(ShellState *p){ |
16485 | EQPGraphRow *pRow = p->sGraph.pRow; |
16486 | if( pRow ){ |
16487 | if( pRow->zText[0]=='-' ){ |
16488 | if( pRow->pNext==0 ){ |
16489 | eqp_reset(p); |
16490 | return; |
16491 | } |
16492 | utf8_printf(p->out, "%s\n" , pRow->zText+3); |
16493 | p->sGraph.pRow = pRow->pNext; |
16494 | sqlite3_free(pRow); |
16495 | }else{ |
16496 | utf8_printf(p->out, "QUERY PLAN\n" ); |
16497 | } |
16498 | p->sGraph.zPrefix[0] = 0; |
16499 | eqp_render_level(p, 0); |
16500 | eqp_reset(p); |
16501 | } |
16502 | } |
16503 | |
16504 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
16505 | /* |
16506 | ** Progress handler callback. |
16507 | */ |
16508 | static int progress_handler(void *pClientData) { |
16509 | ShellState *p = (ShellState*)pClientData; |
16510 | p->nProgress++; |
16511 | if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){ |
16512 | raw_printf(p->out, "Progress limit reached (%u)\n" , p->nProgress); |
16513 | if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; |
16514 | if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0; |
16515 | return 1; |
16516 | } |
16517 | if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){ |
16518 | raw_printf(p->out, "Progress %u\n" , p->nProgress); |
16519 | } |
16520 | return 0; |
16521 | } |
16522 | #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */ |
16523 | |
16524 | /* |
16525 | ** Print N dashes |
16526 | */ |
16527 | static void print_dashes(FILE *out, int N){ |
16528 | const char zDash[] = "--------------------------------------------------" ; |
16529 | const int nDash = sizeof(zDash) - 1; |
16530 | while( N>nDash ){ |
16531 | fputs(zDash, out); |
16532 | N -= nDash; |
16533 | } |
16534 | raw_printf(out, "%.*s" , N, zDash); |
16535 | } |
16536 | |
16537 | /* |
16538 | ** Print a markdown or table-style row separator using ascii-art |
16539 | */ |
16540 | static void print_row_separator( |
16541 | ShellState *p, |
16542 | int nArg, |
16543 | const char *zSep |
16544 | ){ |
16545 | int i; |
16546 | if( nArg>0 ){ |
16547 | fputs(zSep, p->out); |
16548 | print_dashes(p->out, p->actualWidth[0]+2); |
16549 | for(i=1; i<nArg; i++){ |
16550 | fputs(zSep, p->out); |
16551 | print_dashes(p->out, p->actualWidth[i]+2); |
16552 | } |
16553 | fputs(zSep, p->out); |
16554 | } |
16555 | fputs("\n" , p->out); |
16556 | } |
16557 | |
16558 | /* |
16559 | ** This is the callback routine that the shell |
16560 | ** invokes for each row of a query result. |
16561 | */ |
16562 | static int shell_callback( |
16563 | void *pArg, |
16564 | int nArg, /* Number of result columns */ |
16565 | char **azArg, /* Text of each result column */ |
16566 | char **azCol, /* Column names */ |
16567 | int *aiType /* Column types. Might be NULL */ |
16568 | ){ |
16569 | int i; |
16570 | ShellState *p = (ShellState*)pArg; |
16571 | |
16572 | if( azArg==0 ) return 0; |
16573 | switch( p->cMode ){ |
16574 | case MODE_Count: |
16575 | case MODE_Off: { |
16576 | break; |
16577 | } |
16578 | case MODE_Line: { |
16579 | int w = 5; |
16580 | if( azArg==0 ) break; |
16581 | for(i=0; i<nArg; i++){ |
16582 | int len = strlen30(azCol[i] ? azCol[i] : "" ); |
16583 | if( len>w ) w = len; |
16584 | } |
16585 | if( p->cnt++>0 ) utf8_printf(p->out, "%s" , p->rowSeparator); |
16586 | for(i=0; i<nArg; i++){ |
16587 | utf8_printf(p->out,"%*s = %s%s" , w, azCol[i], |
16588 | azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); |
16589 | } |
16590 | break; |
16591 | } |
16592 | case MODE_Explain: { |
16593 | static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13}; |
16594 | if( nArg>ArraySize(aExplainWidth) ){ |
16595 | nArg = ArraySize(aExplainWidth); |
16596 | } |
16597 | if( p->cnt++==0 ){ |
16598 | for(i=0; i<nArg; i++){ |
16599 | int w = aExplainWidth[i]; |
16600 | utf8_width_print(p->out, w, azCol[i]); |
16601 | fputs(i==nArg-1 ? "\n" : " " , p->out); |
16602 | } |
16603 | for(i=0; i<nArg; i++){ |
16604 | int w = aExplainWidth[i]; |
16605 | print_dashes(p->out, w); |
16606 | fputs(i==nArg-1 ? "\n" : " " , p->out); |
16607 | } |
16608 | } |
16609 | if( azArg==0 ) break; |
16610 | for(i=0; i<nArg; i++){ |
16611 | int w = aExplainWidth[i]; |
16612 | if( i==nArg-1 ) w = 0; |
16613 | if( azArg[i] && strlenChar(azArg[i])>w ){ |
16614 | w = strlenChar(azArg[i]); |
16615 | } |
16616 | if( i==1 && p->aiIndent && p->pStmt ){ |
16617 | if( p->iIndent<p->nIndent ){ |
16618 | utf8_printf(p->out, "%*.s" , p->aiIndent[p->iIndent], "" ); |
16619 | } |
16620 | p->iIndent++; |
16621 | } |
16622 | utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue); |
16623 | fputs(i==nArg-1 ? "\n" : " " , p->out); |
16624 | } |
16625 | break; |
16626 | } |
16627 | case MODE_Semi: { /* .schema and .fullschema output */ |
16628 | printSchemaLine(p->out, azArg[0], ";\n" ); |
16629 | break; |
16630 | } |
16631 | case MODE_Pretty: { /* .schema and .fullschema with --indent */ |
16632 | char *z; |
16633 | int j; |
16634 | int nParen = 0; |
16635 | char cEnd = 0; |
16636 | char c; |
16637 | int nLine = 0; |
16638 | assert( nArg==1 ); |
16639 | if( azArg[0]==0 ) break; |
16640 | if( sqlite3_strlike("CREATE VIEW%" , azArg[0], 0)==0 |
16641 | || sqlite3_strlike("CREATE TRIG%" , azArg[0], 0)==0 |
16642 | ){ |
16643 | utf8_printf(p->out, "%s;\n" , azArg[0]); |
16644 | break; |
16645 | } |
16646 | z = sqlite3_mprintf("%s" , azArg[0]); |
16647 | shell_check_oom(z); |
16648 | j = 0; |
16649 | for(i=0; IsSpace(z[i]); i++){} |
16650 | for(; (c = z[i])!=0; i++){ |
16651 | if( IsSpace(c) ){ |
16652 | if( z[j-1]=='\r' ) z[j-1] = '\n'; |
16653 | if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; |
16654 | }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ |
16655 | j--; |
16656 | } |
16657 | z[j++] = c; |
16658 | } |
16659 | while( j>0 && IsSpace(z[j-1]) ){ j--; } |
16660 | z[j] = 0; |
16661 | if( strlen30(z)>=79 ){ |
16662 | for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */ |
16663 | if( c==cEnd ){ |
16664 | cEnd = 0; |
16665 | }else if( c=='"' || c=='\'' || c=='`' ){ |
16666 | cEnd = c; |
16667 | }else if( c=='[' ){ |
16668 | cEnd = ']'; |
16669 | }else if( c=='-' && z[i+1]=='-' ){ |
16670 | cEnd = '\n'; |
16671 | }else if( c=='(' ){ |
16672 | nParen++; |
16673 | }else if( c==')' ){ |
16674 | nParen--; |
16675 | if( nLine>0 && nParen==0 && j>0 ){ |
16676 | printSchemaLineN(p->out, z, j, "\n" ); |
16677 | j = 0; |
16678 | } |
16679 | } |
16680 | z[j++] = c; |
16681 | if( nParen==1 && cEnd==0 |
16682 | && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1))) |
16683 | ){ |
16684 | if( c=='\n' ) j--; |
16685 | printSchemaLineN(p->out, z, j, "\n " ); |
16686 | j = 0; |
16687 | nLine++; |
16688 | while( IsSpace(z[i+1]) ){ i++; } |
16689 | } |
16690 | } |
16691 | z[j] = 0; |
16692 | } |
16693 | printSchemaLine(p->out, z, ";\n" ); |
16694 | sqlite3_free(z); |
16695 | break; |
16696 | } |
16697 | case MODE_List: { |
16698 | if( p->cnt++==0 && p->showHeader ){ |
16699 | for(i=0; i<nArg; i++){ |
16700 | utf8_printf(p->out,"%s%s" ,azCol[i], |
16701 | i==nArg-1 ? p->rowSeparator : p->colSeparator); |
16702 | } |
16703 | } |
16704 | if( azArg==0 ) break; |
16705 | for(i=0; i<nArg; i++){ |
16706 | char *z = azArg[i]; |
16707 | if( z==0 ) z = p->nullValue; |
16708 | utf8_printf(p->out, "%s" , z); |
16709 | if( i<nArg-1 ){ |
16710 | utf8_printf(p->out, "%s" , p->colSeparator); |
16711 | }else{ |
16712 | utf8_printf(p->out, "%s" , p->rowSeparator); |
16713 | } |
16714 | } |
16715 | break; |
16716 | } |
16717 | case MODE_Html: { |
16718 | if( p->cnt++==0 && p->showHeader ){ |
16719 | raw_printf(p->out,"<TR>" ); |
16720 | for(i=0; i<nArg; i++){ |
16721 | raw_printf(p->out,"<TH>" ); |
16722 | output_html_string(p->out, azCol[i]); |
16723 | raw_printf(p->out,"</TH>\n" ); |
16724 | } |
16725 | raw_printf(p->out,"</TR>\n" ); |
16726 | } |
16727 | if( azArg==0 ) break; |
16728 | raw_printf(p->out,"<TR>" ); |
16729 | for(i=0; i<nArg; i++){ |
16730 | raw_printf(p->out,"<TD>" ); |
16731 | output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); |
16732 | raw_printf(p->out,"</TD>\n" ); |
16733 | } |
16734 | raw_printf(p->out,"</TR>\n" ); |
16735 | break; |
16736 | } |
16737 | case MODE_Tcl: { |
16738 | if( p->cnt++==0 && p->showHeader ){ |
16739 | for(i=0; i<nArg; i++){ |
16740 | output_c_string(p->out,azCol[i] ? azCol[i] : "" ); |
16741 | if(i<nArg-1) utf8_printf(p->out, "%s" , p->colSeparator); |
16742 | } |
16743 | utf8_printf(p->out, "%s" , p->rowSeparator); |
16744 | } |
16745 | if( azArg==0 ) break; |
16746 | for(i=0; i<nArg; i++){ |
16747 | output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); |
16748 | if(i<nArg-1) utf8_printf(p->out, "%s" , p->colSeparator); |
16749 | } |
16750 | utf8_printf(p->out, "%s" , p->rowSeparator); |
16751 | break; |
16752 | } |
16753 | case MODE_Csv: { |
16754 | setBinaryMode(p->out, 1); |
16755 | if( p->cnt++==0 && p->showHeader ){ |
16756 | for(i=0; i<nArg; i++){ |
16757 | output_csv(p, azCol[i] ? azCol[i] : "" , i<nArg-1); |
16758 | } |
16759 | utf8_printf(p->out, "%s" , p->rowSeparator); |
16760 | } |
16761 | if( nArg>0 ){ |
16762 | for(i=0; i<nArg; i++){ |
16763 | output_csv(p, azArg[i], i<nArg-1); |
16764 | } |
16765 | utf8_printf(p->out, "%s" , p->rowSeparator); |
16766 | } |
16767 | setTextMode(p->out, 1); |
16768 | break; |
16769 | } |
16770 | case MODE_Insert: { |
16771 | if( azArg==0 ) break; |
16772 | utf8_printf(p->out,"INSERT INTO %s" ,p->zDestTable); |
16773 | if( p->showHeader ){ |
16774 | raw_printf(p->out,"(" ); |
16775 | for(i=0; i<nArg; i++){ |
16776 | if( i>0 ) raw_printf(p->out, "," ); |
16777 | if( quoteChar(azCol[i]) ){ |
16778 | char *z = sqlite3_mprintf("\"%w\"" , azCol[i]); |
16779 | shell_check_oom(z); |
16780 | utf8_printf(p->out, "%s" , z); |
16781 | sqlite3_free(z); |
16782 | }else{ |
16783 | raw_printf(p->out, "%s" , azCol[i]); |
16784 | } |
16785 | } |
16786 | raw_printf(p->out,")" ); |
16787 | } |
16788 | p->cnt++; |
16789 | for(i=0; i<nArg; i++){ |
16790 | raw_printf(p->out, i>0 ? "," : " VALUES(" ); |
16791 | if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ |
16792 | utf8_printf(p->out,"NULL" ); |
16793 | }else if( aiType && aiType[i]==SQLITE_TEXT ){ |
16794 | if( ShellHasFlag(p, SHFLG_Newlines) ){ |
16795 | output_quoted_string(p->out, azArg[i]); |
16796 | }else{ |
16797 | output_quoted_escaped_string(p->out, azArg[i]); |
16798 | } |
16799 | }else if( aiType && aiType[i]==SQLITE_INTEGER ){ |
16800 | utf8_printf(p->out,"%s" , azArg[i]); |
16801 | }else if( aiType && aiType[i]==SQLITE_FLOAT ){ |
16802 | char z[50]; |
16803 | double r = sqlite3_column_double(p->pStmt, i); |
16804 | sqlite3_uint64 ur; |
16805 | memcpy(&ur,&r,sizeof(r)); |
16806 | if( ur==0x7ff0000000000000LL ){ |
16807 | raw_printf(p->out, "1e999" ); |
16808 | }else if( ur==0xfff0000000000000LL ){ |
16809 | raw_printf(p->out, "-1e999" ); |
16810 | }else{ |
16811 | sqlite3_int64 ir = (sqlite3_int64)r; |
16812 | if( r==(double)ir ){ |
16813 | sqlite3_snprintf(50,z,"%lld.0" , ir); |
16814 | }else{ |
16815 | sqlite3_snprintf(50,z,"%!.20g" , r); |
16816 | } |
16817 | raw_printf(p->out, "%s" , z); |
16818 | } |
16819 | }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ |
16820 | const void *pBlob = sqlite3_column_blob(p->pStmt, i); |
16821 | int nBlob = sqlite3_column_bytes(p->pStmt, i); |
16822 | output_hex_blob(p->out, pBlob, nBlob); |
16823 | }else if( isNumber(azArg[i], 0) ){ |
16824 | utf8_printf(p->out,"%s" , azArg[i]); |
16825 | }else if( ShellHasFlag(p, SHFLG_Newlines) ){ |
16826 | output_quoted_string(p->out, azArg[i]); |
16827 | }else{ |
16828 | output_quoted_escaped_string(p->out, azArg[i]); |
16829 | } |
16830 | } |
16831 | raw_printf(p->out,");\n" ); |
16832 | break; |
16833 | } |
16834 | case MODE_Json: { |
16835 | if( azArg==0 ) break; |
16836 | if( p->cnt==0 ){ |
16837 | fputs("[{" , p->out); |
16838 | }else{ |
16839 | fputs(",\n{" , p->out); |
16840 | } |
16841 | p->cnt++; |
16842 | for(i=0; i<nArg; i++){ |
16843 | output_json_string(p->out, azCol[i], -1); |
16844 | putc(':', p->out); |
16845 | if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ |
16846 | fputs("null" ,p->out); |
16847 | }else if( aiType && aiType[i]==SQLITE_FLOAT ){ |
16848 | char z[50]; |
16849 | double r = sqlite3_column_double(p->pStmt, i); |
16850 | sqlite3_uint64 ur; |
16851 | memcpy(&ur,&r,sizeof(r)); |
16852 | if( ur==0x7ff0000000000000LL ){ |
16853 | raw_printf(p->out, "1e999" ); |
16854 | }else if( ur==0xfff0000000000000LL ){ |
16855 | raw_printf(p->out, "-1e999" ); |
16856 | }else{ |
16857 | sqlite3_snprintf(50,z,"%!.20g" , r); |
16858 | raw_printf(p->out, "%s" , z); |
16859 | } |
16860 | }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ |
16861 | const void *pBlob = sqlite3_column_blob(p->pStmt, i); |
16862 | int nBlob = sqlite3_column_bytes(p->pStmt, i); |
16863 | output_json_string(p->out, pBlob, nBlob); |
16864 | }else if( aiType && aiType[i]==SQLITE_TEXT ){ |
16865 | output_json_string(p->out, azArg[i], -1); |
16866 | }else{ |
16867 | utf8_printf(p->out,"%s" , azArg[i]); |
16868 | } |
16869 | if( i<nArg-1 ){ |
16870 | putc(',', p->out); |
16871 | } |
16872 | } |
16873 | putc('}', p->out); |
16874 | break; |
16875 | } |
16876 | case MODE_Quote: { |
16877 | if( azArg==0 ) break; |
16878 | if( p->cnt==0 && p->showHeader ){ |
16879 | for(i=0; i<nArg; i++){ |
16880 | if( i>0 ) fputs(p->colSeparator, p->out); |
16881 | output_quoted_string(p->out, azCol[i]); |
16882 | } |
16883 | fputs(p->rowSeparator, p->out); |
16884 | } |
16885 | p->cnt++; |
16886 | for(i=0; i<nArg; i++){ |
16887 | if( i>0 ) fputs(p->colSeparator, p->out); |
16888 | if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ |
16889 | utf8_printf(p->out,"NULL" ); |
16890 | }else if( aiType && aiType[i]==SQLITE_TEXT ){ |
16891 | output_quoted_string(p->out, azArg[i]); |
16892 | }else if( aiType && aiType[i]==SQLITE_INTEGER ){ |
16893 | utf8_printf(p->out,"%s" , azArg[i]); |
16894 | }else if( aiType && aiType[i]==SQLITE_FLOAT ){ |
16895 | char z[50]; |
16896 | double r = sqlite3_column_double(p->pStmt, i); |
16897 | sqlite3_snprintf(50,z,"%!.20g" , r); |
16898 | raw_printf(p->out, "%s" , z); |
16899 | }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ |
16900 | const void *pBlob = sqlite3_column_blob(p->pStmt, i); |
16901 | int nBlob = sqlite3_column_bytes(p->pStmt, i); |
16902 | output_hex_blob(p->out, pBlob, nBlob); |
16903 | }else if( isNumber(azArg[i], 0) ){ |
16904 | utf8_printf(p->out,"%s" , azArg[i]); |
16905 | }else{ |
16906 | output_quoted_string(p->out, azArg[i]); |
16907 | } |
16908 | } |
16909 | fputs(p->rowSeparator, p->out); |
16910 | break; |
16911 | } |
16912 | case MODE_Ascii: { |
16913 | if( p->cnt++==0 && p->showHeader ){ |
16914 | for(i=0; i<nArg; i++){ |
16915 | if( i>0 ) utf8_printf(p->out, "%s" , p->colSeparator); |
16916 | utf8_printf(p->out,"%s" ,azCol[i] ? azCol[i] : "" ); |
16917 | } |
16918 | utf8_printf(p->out, "%s" , p->rowSeparator); |
16919 | } |
16920 | if( azArg==0 ) break; |
16921 | for(i=0; i<nArg; i++){ |
16922 | if( i>0 ) utf8_printf(p->out, "%s" , p->colSeparator); |
16923 | utf8_printf(p->out,"%s" ,azArg[i] ? azArg[i] : p->nullValue); |
16924 | } |
16925 | utf8_printf(p->out, "%s" , p->rowSeparator); |
16926 | break; |
16927 | } |
16928 | case MODE_EQP: { |
16929 | eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]); |
16930 | break; |
16931 | } |
16932 | } |
16933 | return 0; |
16934 | } |
16935 | |
16936 | /* |
16937 | ** This is the callback routine that the SQLite library |
16938 | ** invokes for each row of a query result. |
16939 | */ |
16940 | static int callback(void *pArg, int nArg, char **azArg, char **azCol){ |
16941 | /* since we don't have type info, call the shell_callback with a NULL value */ |
16942 | return shell_callback(pArg, nArg, azArg, azCol, NULL); |
16943 | } |
16944 | |
16945 | /* |
16946 | ** This is the callback routine from sqlite3_exec() that appends all |
16947 | ** output onto the end of a ShellText object. |
16948 | */ |
16949 | static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ |
16950 | ShellText *p = (ShellText*)pArg; |
16951 | int i; |
16952 | UNUSED_PARAMETER(az); |
16953 | if( azArg==0 ) return 0; |
16954 | if( p->n ) appendText(p, "|" , 0); |
16955 | for(i=0; i<nArg; i++){ |
16956 | if( i ) appendText(p, "," , 0); |
16957 | if( azArg[i] ) appendText(p, azArg[i], 0); |
16958 | } |
16959 | return 0; |
16960 | } |
16961 | |
16962 | /* |
16963 | ** Generate an appropriate SELFTEST table in the main database. |
16964 | */ |
16965 | static void createSelftestTable(ShellState *p){ |
16966 | char *zErrMsg = 0; |
16967 | sqlite3_exec(p->db, |
16968 | "SAVEPOINT selftest_init;\n" |
16969 | "CREATE TABLE IF NOT EXISTS selftest(\n" |
16970 | " tno INTEGER PRIMARY KEY,\n" /* Test number */ |
16971 | " op TEXT,\n" /* Operator: memo run */ |
16972 | " cmd TEXT,\n" /* Command text */ |
16973 | " ans TEXT\n" /* Desired answer */ |
16974 | ");" |
16975 | "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n" |
16976 | "INSERT INTO [_shell$self](rowid,op,cmd)\n" |
16977 | " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n" |
16978 | " 'memo','Tests generated by --init');\n" |
16979 | "INSERT INTO [_shell$self]\n" |
16980 | " SELECT 'run',\n" |
16981 | " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql " |
16982 | "FROM sqlite_schema ORDER BY 2'',224))',\n" |
16983 | " hex(sha3_query('SELECT type,name,tbl_name,sql " |
16984 | "FROM sqlite_schema ORDER BY 2',224));\n" |
16985 | "INSERT INTO [_shell$self]\n" |
16986 | " SELECT 'run'," |
16987 | " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||" |
16988 | " printf('%w',name) || '\" NOT INDEXED'',224))',\n" |
16989 | " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n" |
16990 | " FROM (\n" |
16991 | " SELECT name FROM sqlite_schema\n" |
16992 | " WHERE type='table'\n" |
16993 | " AND name<>'selftest'\n" |
16994 | " AND coalesce(rootpage,0)>0\n" |
16995 | " )\n" |
16996 | " ORDER BY name;\n" |
16997 | "INSERT INTO [_shell$self]\n" |
16998 | " VALUES('run','PRAGMA integrity_check','ok');\n" |
16999 | "INSERT INTO selftest(tno,op,cmd,ans)" |
17000 | " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n" |
17001 | "DROP TABLE [_shell$self];" |
17002 | ,0,0,&zErrMsg); |
17003 | if( zErrMsg ){ |
17004 | utf8_printf(stderr, "SELFTEST initialization failure: %s\n" , zErrMsg); |
17005 | sqlite3_free(zErrMsg); |
17006 | } |
17007 | sqlite3_exec(p->db, "RELEASE selftest_init" ,0,0,0); |
17008 | } |
17009 | |
17010 | |
17011 | /* |
17012 | ** Set the destination table field of the ShellState structure to |
17013 | ** the name of the table given. Escape any quote characters in the |
17014 | ** table name. |
17015 | */ |
17016 | static void set_table_name(ShellState *p, const char *zName){ |
17017 | int i, n; |
17018 | char cQuote; |
17019 | char *z; |
17020 | |
17021 | if( p->zDestTable ){ |
17022 | free(p->zDestTable); |
17023 | p->zDestTable = 0; |
17024 | } |
17025 | if( zName==0 ) return; |
17026 | cQuote = quoteChar(zName); |
17027 | n = strlen30(zName); |
17028 | if( cQuote ) n += n+2; |
17029 | z = p->zDestTable = malloc( n+1 ); |
17030 | shell_check_oom(z); |
17031 | n = 0; |
17032 | if( cQuote ) z[n++] = cQuote; |
17033 | for(i=0; zName[i]; i++){ |
17034 | z[n++] = zName[i]; |
17035 | if( zName[i]==cQuote ) z[n++] = cQuote; |
17036 | } |
17037 | if( cQuote ) z[n++] = cQuote; |
17038 | z[n] = 0; |
17039 | } |
17040 | |
17041 | /* |
17042 | ** Maybe construct two lines of text that point out the position of a |
17043 | ** syntax error. Return a pointer to the text, in memory obtained from |
17044 | ** sqlite3_malloc(). Or, if the most recent error does not involve a |
17045 | ** specific token that we can point to, return an empty string. |
17046 | ** |
17047 | ** In all cases, the memory returned is obtained from sqlite3_malloc64() |
17048 | ** and should be released by the caller invoking sqlite3_free(). |
17049 | */ |
17050 | static char *shell_error_context(const char *zSql, sqlite3 *db){ |
17051 | int iOffset; |
17052 | size_t len; |
17053 | char *zCode; |
17054 | char *zMsg; |
17055 | int i; |
17056 | if( db==0 |
17057 | || zSql==0 |
17058 | || (iOffset = sqlite3_error_offset(db))<0 |
17059 | ){ |
17060 | return sqlite3_mprintf("" ); |
17061 | } |
17062 | while( iOffset>50 ){ |
17063 | iOffset--; |
17064 | zSql++; |
17065 | while( (zSql[0]&0xc0)==0x80 ){ zSql++; iOffset--; } |
17066 | } |
17067 | len = strlen(zSql); |
17068 | if( len>78 ){ |
17069 | len = 78; |
17070 | while( (zSql[len]&0xc0)==0x80 ) len--; |
17071 | } |
17072 | zCode = sqlite3_mprintf("%.*s" , len, zSql); |
17073 | shell_check_oom(zCode); |
17074 | for(i=0; zCode[i]; i++){ if( IsSpace(zSql[i]) ) zCode[i] = ' '; } |
17075 | if( iOffset<25 ){ |
17076 | zMsg = sqlite3_mprintf("\n %z\n %*s^--- error here" , zCode, iOffset, "" ); |
17077 | }else{ |
17078 | zMsg = sqlite3_mprintf("\n %z\n %*serror here ---^" , zCode, iOffset-14, "" ); |
17079 | } |
17080 | return zMsg; |
17081 | } |
17082 | |
17083 | |
17084 | /* |
17085 | ** Execute a query statement that will generate SQL output. Print |
17086 | ** the result columns, comma-separated, on a line and then add a |
17087 | ** semicolon terminator to the end of that line. |
17088 | ** |
17089 | ** If the number of columns is 1 and that column contains text "--" |
17090 | ** then write the semicolon on a separate line. That way, if a |
17091 | ** "--" comment occurs at the end of the statement, the comment |
17092 | ** won't consume the semicolon terminator. |
17093 | */ |
17094 | static int run_table_dump_query( |
17095 | ShellState *p, /* Query context */ |
17096 | const char *zSelect /* SELECT statement to extract content */ |
17097 | ){ |
17098 | sqlite3_stmt *pSelect; |
17099 | int rc; |
17100 | int nResult; |
17101 | int i; |
17102 | const char *z; |
17103 | rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); |
17104 | if( rc!=SQLITE_OK || !pSelect ){ |
17105 | char *zContext = shell_error_context(zSelect, p->db); |
17106 | utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n%s" , rc, |
17107 | sqlite3_errmsg(p->db), zContext); |
17108 | sqlite3_free(zContext); |
17109 | if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; |
17110 | return rc; |
17111 | } |
17112 | rc = sqlite3_step(pSelect); |
17113 | nResult = sqlite3_column_count(pSelect); |
17114 | while( rc==SQLITE_ROW ){ |
17115 | z = (const char*)sqlite3_column_text(pSelect, 0); |
17116 | utf8_printf(p->out, "%s" , z); |
17117 | for(i=1; i<nResult; i++){ |
17118 | utf8_printf(p->out, ",%s" , sqlite3_column_text(pSelect, i)); |
17119 | } |
17120 | if( z==0 ) z = "" ; |
17121 | while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; |
17122 | if( z[0] ){ |
17123 | raw_printf(p->out, "\n;\n" ); |
17124 | }else{ |
17125 | raw_printf(p->out, ";\n" ); |
17126 | } |
17127 | rc = sqlite3_step(pSelect); |
17128 | } |
17129 | rc = sqlite3_finalize(pSelect); |
17130 | if( rc!=SQLITE_OK ){ |
17131 | utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n" , rc, |
17132 | sqlite3_errmsg(p->db)); |
17133 | if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; |
17134 | } |
17135 | return rc; |
17136 | } |
17137 | |
17138 | /* |
17139 | ** Allocate space and save off string indicating current error. |
17140 | */ |
17141 | static char *save_err_msg( |
17142 | sqlite3 *db, /* Database to query */ |
17143 | const char *zPhase, /* When the error occcurs */ |
17144 | int rc, /* Error code returned from API */ |
17145 | const char *zSql /* SQL string, or NULL */ |
17146 | ){ |
17147 | char *zErr; |
17148 | char *zContext; |
17149 | sqlite3_str *pStr = sqlite3_str_new(0); |
17150 | sqlite3_str_appendf(pStr, "%s, %s" , zPhase, sqlite3_errmsg(db)); |
17151 | if( rc>1 ){ |
17152 | sqlite3_str_appendf(pStr, " (%d)" , rc); |
17153 | } |
17154 | zContext = shell_error_context(zSql, db); |
17155 | if( zContext ){ |
17156 | sqlite3_str_appendall(pStr, zContext); |
17157 | sqlite3_free(zContext); |
17158 | } |
17159 | zErr = sqlite3_str_finish(pStr); |
17160 | shell_check_oom(zErr); |
17161 | return zErr; |
17162 | } |
17163 | |
17164 | #ifdef __linux__ |
17165 | /* |
17166 | ** Attempt to display I/O stats on Linux using /proc/PID/io |
17167 | */ |
17168 | static void displayLinuxIoStats(FILE *out){ |
17169 | FILE *in; |
17170 | char z[200]; |
17171 | sqlite3_snprintf(sizeof(z), z, "/proc/%d/io" , getpid()); |
17172 | in = fopen(z, "rb" ); |
17173 | if( in==0 ) return; |
17174 | while( fgets(z, sizeof(z), in)!=0 ){ |
17175 | static const struct { |
17176 | const char *zPattern; |
17177 | const char *zDesc; |
17178 | } aTrans[] = { |
17179 | { "rchar: " , "Bytes received by read():" }, |
17180 | { "wchar: " , "Bytes sent to write():" }, |
17181 | { "syscr: " , "Read() system calls:" }, |
17182 | { "syscw: " , "Write() system calls:" }, |
17183 | { "read_bytes: " , "Bytes read from storage:" }, |
17184 | { "write_bytes: " , "Bytes written to storage:" }, |
17185 | { "cancelled_write_bytes: " , "Cancelled write bytes:" }, |
17186 | }; |
17187 | int i; |
17188 | for(i=0; i<ArraySize(aTrans); i++){ |
17189 | int n = strlen30(aTrans[i].zPattern); |
17190 | if( cli_strncmp(aTrans[i].zPattern, z, n)==0 ){ |
17191 | utf8_printf(out, "%-36s %s" , aTrans[i].zDesc, &z[n]); |
17192 | break; |
17193 | } |
17194 | } |
17195 | } |
17196 | fclose(in); |
17197 | } |
17198 | #endif |
17199 | |
17200 | /* |
17201 | ** Display a single line of status using 64-bit values. |
17202 | */ |
17203 | static void displayStatLine( |
17204 | ShellState *p, /* The shell context */ |
17205 | char *zLabel, /* Label for this one line */ |
17206 | char *zFormat, /* Format for the result */ |
17207 | int iStatusCtrl, /* Which status to display */ |
17208 | int bReset /* True to reset the stats */ |
17209 | ){ |
17210 | sqlite3_int64 iCur = -1; |
17211 | sqlite3_int64 iHiwtr = -1; |
17212 | int i, nPercent; |
17213 | char zLine[200]; |
17214 | sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset); |
17215 | for(i=0, nPercent=0; zFormat[i]; i++){ |
17216 | if( zFormat[i]=='%' ) nPercent++; |
17217 | } |
17218 | if( nPercent>1 ){ |
17219 | sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr); |
17220 | }else{ |
17221 | sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr); |
17222 | } |
17223 | raw_printf(p->out, "%-36s %s\n" , zLabel, zLine); |
17224 | } |
17225 | |
17226 | /* |
17227 | ** Display memory stats. |
17228 | */ |
17229 | static int display_stats( |
17230 | sqlite3 *db, /* Database to query */ |
17231 | ShellState *pArg, /* Pointer to ShellState */ |
17232 | int bReset /* True to reset the stats */ |
17233 | ){ |
17234 | int iCur; |
17235 | int iHiwtr; |
17236 | FILE *out; |
17237 | if( pArg==0 || pArg->out==0 ) return 0; |
17238 | out = pArg->out; |
17239 | |
17240 | if( pArg->pStmt && pArg->statsOn==2 ){ |
17241 | int nCol, i, x; |
17242 | sqlite3_stmt *pStmt = pArg->pStmt; |
17243 | char z[100]; |
17244 | nCol = sqlite3_column_count(pStmt); |
17245 | raw_printf(out, "%-36s %d\n" , "Number of output columns:" , nCol); |
17246 | for(i=0; i<nCol; i++){ |
17247 | sqlite3_snprintf(sizeof(z),z,"Column %d %nname:" , i, &x); |
17248 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_name(pStmt,i)); |
17249 | #ifndef SQLITE_OMIT_DECLTYPE |
17250 | sqlite3_snprintf(30, z+x, "declared type:" ); |
17251 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_decltype(pStmt, i)); |
17252 | #endif |
17253 | #ifdef SQLITE_ENABLE_COLUMN_METADATA |
17254 | sqlite3_snprintf(30, z+x, "database name:" ); |
17255 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_database_name(pStmt,i)); |
17256 | sqlite3_snprintf(30, z+x, "table name:" ); |
17257 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_table_name(pStmt,i)); |
17258 | sqlite3_snprintf(30, z+x, "origin name:" ); |
17259 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_origin_name(pStmt,i)); |
17260 | #endif |
17261 | } |
17262 | } |
17263 | |
17264 | if( pArg->statsOn==3 ){ |
17265 | if( pArg->pStmt ){ |
17266 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); |
17267 | raw_printf(pArg->out, "VM-steps: %d\n" , iCur); |
17268 | } |
17269 | return 0; |
17270 | } |
17271 | |
17272 | displayStatLine(pArg, "Memory Used:" , |
17273 | "%lld (max %lld) bytes" , SQLITE_STATUS_MEMORY_USED, bReset); |
17274 | displayStatLine(pArg, "Number of Outstanding Allocations:" , |
17275 | "%lld (max %lld)" , SQLITE_STATUS_MALLOC_COUNT, bReset); |
17276 | if( pArg->shellFlgs & SHFLG_Pagecache ){ |
17277 | displayStatLine(pArg, "Number of Pcache Pages Used:" , |
17278 | "%lld (max %lld) pages" , SQLITE_STATUS_PAGECACHE_USED, bReset); |
17279 | } |
17280 | displayStatLine(pArg, "Number of Pcache Overflow Bytes:" , |
17281 | "%lld (max %lld) bytes" , SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); |
17282 | displayStatLine(pArg, "Largest Allocation:" , |
17283 | "%lld bytes" , SQLITE_STATUS_MALLOC_SIZE, bReset); |
17284 | displayStatLine(pArg, "Largest Pcache Allocation:" , |
17285 | "%lld bytes" , SQLITE_STATUS_PAGECACHE_SIZE, bReset); |
17286 | #ifdef YYTRACKMAXSTACKDEPTH |
17287 | displayStatLine(pArg, "Deepest Parser Stack:" , |
17288 | "%lld (max %lld)" , SQLITE_STATUS_PARSER_STACK, bReset); |
17289 | #endif |
17290 | |
17291 | if( db ){ |
17292 | if( pArg->shellFlgs & SHFLG_Lookaside ){ |
17293 | iHiwtr = iCur = -1; |
17294 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, |
17295 | &iCur, &iHiwtr, bReset); |
17296 | raw_printf(pArg->out, |
17297 | "Lookaside Slots Used: %d (max %d)\n" , |
17298 | iCur, iHiwtr); |
17299 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, |
17300 | &iCur, &iHiwtr, bReset); |
17301 | raw_printf(pArg->out, "Successful lookaside attempts: %d\n" , |
17302 | iHiwtr); |
17303 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, |
17304 | &iCur, &iHiwtr, bReset); |
17305 | raw_printf(pArg->out, "Lookaside failures due to size: %d\n" , |
17306 | iHiwtr); |
17307 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, |
17308 | &iCur, &iHiwtr, bReset); |
17309 | raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n" , |
17310 | iHiwtr); |
17311 | } |
17312 | iHiwtr = iCur = -1; |
17313 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); |
17314 | raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n" , |
17315 | iCur); |
17316 | iHiwtr = iCur = -1; |
17317 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); |
17318 | raw_printf(pArg->out, "Page cache hits: %d\n" , iCur); |
17319 | iHiwtr = iCur = -1; |
17320 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); |
17321 | raw_printf(pArg->out, "Page cache misses: %d\n" , iCur); |
17322 | iHiwtr = iCur = -1; |
17323 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); |
17324 | raw_printf(pArg->out, "Page cache writes: %d\n" , iCur); |
17325 | iHiwtr = iCur = -1; |
17326 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); |
17327 | raw_printf(pArg->out, "Page cache spills: %d\n" , iCur); |
17328 | iHiwtr = iCur = -1; |
17329 | sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); |
17330 | raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n" , |
17331 | iCur); |
17332 | iHiwtr = iCur = -1; |
17333 | sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); |
17334 | raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n" , |
17335 | iCur); |
17336 | } |
17337 | |
17338 | if( pArg->pStmt ){ |
17339 | int iHit, iMiss; |
17340 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, |
17341 | bReset); |
17342 | raw_printf(pArg->out, "Fullscan Steps: %d\n" , iCur); |
17343 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); |
17344 | raw_printf(pArg->out, "Sort Operations: %d\n" , iCur); |
17345 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); |
17346 | raw_printf(pArg->out, "Autoindex Inserts: %d\n" , iCur); |
17347 | iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, bReset); |
17348 | iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, bReset); |
17349 | if( iHit || iMiss ){ |
17350 | raw_printf(pArg->out, "Bloom filter bypass taken: %d/%d\n" , |
17351 | iHit, iHit+iMiss); |
17352 | } |
17353 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); |
17354 | raw_printf(pArg->out, "Virtual Machine Steps: %d\n" , iCur); |
17355 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset); |
17356 | raw_printf(pArg->out, "Reprepare operations: %d\n" , iCur); |
17357 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); |
17358 | raw_printf(pArg->out, "Number of times run: %d\n" , iCur); |
17359 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset); |
17360 | raw_printf(pArg->out, "Memory used by prepared stmt: %d\n" , iCur); |
17361 | } |
17362 | |
17363 | #ifdef __linux__ |
17364 | displayLinuxIoStats(pArg->out); |
17365 | #endif |
17366 | |
17367 | /* Do not remove this machine readable comment: extra-stats-output-here */ |
17368 | |
17369 | return 0; |
17370 | } |
17371 | |
17372 | /* |
17373 | ** Display scan stats. |
17374 | */ |
17375 | static void display_scanstats( |
17376 | sqlite3 *db, /* Database to query */ |
17377 | ShellState *pArg /* Pointer to ShellState */ |
17378 | ){ |
17379 | #ifndef SQLITE_ENABLE_STMT_SCANSTATUS |
17380 | UNUSED_PARAMETER(db); |
17381 | UNUSED_PARAMETER(pArg); |
17382 | #else |
17383 | int i, k, n, mx; |
17384 | raw_printf(pArg->out, "-------- scanstats --------\n" ); |
17385 | mx = 0; |
17386 | for(k=0; k<=mx; k++){ |
17387 | double rEstLoop = 1.0; |
17388 | for(i=n=0; 1; i++){ |
17389 | sqlite3_stmt *p = pArg->pStmt; |
17390 | sqlite3_int64 nLoop, nVisit; |
17391 | double rEst; |
17392 | int iSid; |
17393 | const char *zExplain; |
17394 | if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){ |
17395 | break; |
17396 | } |
17397 | sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid); |
17398 | if( iSid>mx ) mx = iSid; |
17399 | if( iSid!=k ) continue; |
17400 | if( n==0 ){ |
17401 | rEstLoop = (double)nLoop; |
17402 | if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n" , k); |
17403 | } |
17404 | n++; |
17405 | sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit); |
17406 | sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst); |
17407 | sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); |
17408 | utf8_printf(pArg->out, "Loop %2d: %s\n" , n, zExplain); |
17409 | rEstLoop *= rEst; |
17410 | raw_printf(pArg->out, |
17411 | " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n" , |
17412 | nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst |
17413 | ); |
17414 | } |
17415 | } |
17416 | raw_printf(pArg->out, "---------------------------\n" ); |
17417 | #endif |
17418 | } |
17419 | |
17420 | /* |
17421 | ** Parameter azArray points to a zero-terminated array of strings. zStr |
17422 | ** points to a single nul-terminated string. Return non-zero if zStr |
17423 | ** is equal, according to strcmp(), to any of the strings in the array. |
17424 | ** Otherwise, return zero. |
17425 | */ |
17426 | static int str_in_array(const char *zStr, const char **azArray){ |
17427 | int i; |
17428 | for(i=0; azArray[i]; i++){ |
17429 | if( 0==cli_strcmp(zStr, azArray[i]) ) return 1; |
17430 | } |
17431 | return 0; |
17432 | } |
17433 | |
17434 | /* |
17435 | ** If compiled statement pSql appears to be an EXPLAIN statement, allocate |
17436 | ** and populate the ShellState.aiIndent[] array with the number of |
17437 | ** spaces each opcode should be indented before it is output. |
17438 | ** |
17439 | ** The indenting rules are: |
17440 | ** |
17441 | ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent |
17442 | ** all opcodes that occur between the p2 jump destination and the opcode |
17443 | ** itself by 2 spaces. |
17444 | ** |
17445 | ** * Do the previous for "Return" instructions for when P2 is positive. |
17446 | ** See tag-20220407a in wherecode.c and vdbe.c. |
17447 | ** |
17448 | ** * For each "Goto", if the jump destination is earlier in the program |
17449 | ** and ends on one of: |
17450 | ** Yield SeekGt SeekLt RowSetRead Rewind |
17451 | ** or if the P1 parameter is one instead of zero, |
17452 | ** then indent all opcodes between the earlier instruction |
17453 | ** and "Goto" by 2 spaces. |
17454 | */ |
17455 | static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ |
17456 | const char *zSql; /* The text of the SQL statement */ |
17457 | const char *z; /* Used to check if this is an EXPLAIN */ |
17458 | int *abYield = 0; /* True if op is an OP_Yield */ |
17459 | int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ |
17460 | int iOp; /* Index of operation in p->aiIndent[] */ |
17461 | |
17462 | const char *azNext[] = { "Next" , "Prev" , "VPrev" , "VNext" , "SorterNext" , |
17463 | "Return" , 0 }; |
17464 | const char *azYield[] = { "Yield" , "SeekLT" , "SeekGT" , "RowSetRead" , |
17465 | "Rewind" , 0 }; |
17466 | const char *azGoto[] = { "Goto" , 0 }; |
17467 | |
17468 | /* Try to figure out if this is really an EXPLAIN statement. If this |
17469 | ** cannot be verified, return early. */ |
17470 | if( sqlite3_column_count(pSql)!=8 ){ |
17471 | p->cMode = p->mode; |
17472 | return; |
17473 | } |
17474 | zSql = sqlite3_sql(pSql); |
17475 | if( zSql==0 ) return; |
17476 | for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++); |
17477 | if( sqlite3_strnicmp(z, "explain" , 7) ){ |
17478 | p->cMode = p->mode; |
17479 | return; |
17480 | } |
17481 | |
17482 | for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){ |
17483 | int i; |
17484 | int iAddr = sqlite3_column_int(pSql, 0); |
17485 | const char *zOp = (const char*)sqlite3_column_text(pSql, 1); |
17486 | |
17487 | /* Set p2 to the P2 field of the current opcode. Then, assuming that |
17488 | ** p2 is an instruction address, set variable p2op to the index of that |
17489 | ** instruction in the aiIndent[] array. p2 and p2op may be different if |
17490 | ** the current instruction is part of a sub-program generated by an |
17491 | ** SQL trigger or foreign key. */ |
17492 | int p2 = sqlite3_column_int(pSql, 3); |
17493 | int p2op = (p2 + (iOp-iAddr)); |
17494 | |
17495 | /* Grow the p->aiIndent array as required */ |
17496 | if( iOp>=nAlloc ){ |
17497 | if( iOp==0 ){ |
17498 | /* Do further verfication that this is explain output. Abort if |
17499 | ** it is not */ |
17500 | static const char *explainCols[] = { |
17501 | "addr" , "opcode" , "p1" , "p2" , "p3" , "p4" , "p5" , "comment" }; |
17502 | int jj; |
17503 | for(jj=0; jj<ArraySize(explainCols); jj++){ |
17504 | if( cli_strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){ |
17505 | p->cMode = p->mode; |
17506 | sqlite3_reset(pSql); |
17507 | return; |
17508 | } |
17509 | } |
17510 | } |
17511 | nAlloc += 100; |
17512 | p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); |
17513 | shell_check_oom(p->aiIndent); |
17514 | abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); |
17515 | shell_check_oom(abYield); |
17516 | } |
17517 | abYield[iOp] = str_in_array(zOp, azYield); |
17518 | p->aiIndent[iOp] = 0; |
17519 | p->nIndent = iOp+1; |
17520 | |
17521 | if( str_in_array(zOp, azNext) && p2op>0 ){ |
17522 | for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2; |
17523 | } |
17524 | if( str_in_array(zOp, azGoto) && p2op<p->nIndent |
17525 | && (abYield[p2op] || sqlite3_column_int(pSql, 2)) |
17526 | ){ |
17527 | for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2; |
17528 | } |
17529 | } |
17530 | |
17531 | p->iIndent = 0; |
17532 | sqlite3_free(abYield); |
17533 | sqlite3_reset(pSql); |
17534 | } |
17535 | |
17536 | /* |
17537 | ** Free the array allocated by explain_data_prepare(). |
17538 | */ |
17539 | static void explain_data_delete(ShellState *p){ |
17540 | sqlite3_free(p->aiIndent); |
17541 | p->aiIndent = 0; |
17542 | p->nIndent = 0; |
17543 | p->iIndent = 0; |
17544 | } |
17545 | |
17546 | /* |
17547 | ** Disable and restore .wheretrace and .treetrace/.selecttrace settings. |
17548 | */ |
17549 | static unsigned int savedSelectTrace; |
17550 | static unsigned int savedWhereTrace; |
17551 | static void disable_debug_trace_modes(void){ |
17552 | unsigned int zero = 0; |
17553 | sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace); |
17554 | sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &zero); |
17555 | sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace); |
17556 | sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &zero); |
17557 | } |
17558 | static void restore_debug_trace_modes(void){ |
17559 | sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace); |
17560 | sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace); |
17561 | } |
17562 | |
17563 | /* Create the TEMP table used to store parameter bindings */ |
17564 | static void bind_table_init(ShellState *p){ |
17565 | int wrSchema = 0; |
17566 | int defensiveMode = 0; |
17567 | sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode); |
17568 | sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0); |
17569 | sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema); |
17570 | sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0); |
17571 | sqlite3_exec(p->db, |
17572 | "CREATE TABLE IF NOT EXISTS temp.sqlite_parameters(\n" |
17573 | " key TEXT PRIMARY KEY,\n" |
17574 | " value\n" |
17575 | ") WITHOUT ROWID;" , |
17576 | 0, 0, 0); |
17577 | sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0); |
17578 | sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, defensiveMode, 0); |
17579 | } |
17580 | |
17581 | /* |
17582 | ** Bind parameters on a prepared statement. |
17583 | ** |
17584 | ** Parameter bindings are taken from a TEMP table of the form: |
17585 | ** |
17586 | ** CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value) |
17587 | ** WITHOUT ROWID; |
17588 | ** |
17589 | ** No bindings occur if this table does not exist. The name of the table |
17590 | ** begins with "sqlite_" so that it will not collide with ordinary application |
17591 | ** tables. The table must be in the TEMP schema. |
17592 | */ |
17593 | static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){ |
17594 | int nVar; |
17595 | int i; |
17596 | int rc; |
17597 | sqlite3_stmt *pQ = 0; |
17598 | |
17599 | nVar = sqlite3_bind_parameter_count(pStmt); |
17600 | if( nVar==0 ) return; /* Nothing to do */ |
17601 | if( sqlite3_table_column_metadata(pArg->db, "TEMP" , "sqlite_parameters" , |
17602 | "key" , 0, 0, 0, 0, 0)!=SQLITE_OK ){ |
17603 | return; /* Parameter table does not exist */ |
17604 | } |
17605 | rc = sqlite3_prepare_v2(pArg->db, |
17606 | "SELECT value FROM temp.sqlite_parameters" |
17607 | " WHERE key=?1" , -1, &pQ, 0); |
17608 | if( rc || pQ==0 ) return; |
17609 | for(i=1; i<=nVar; i++){ |
17610 | char zNum[30]; |
17611 | const char *zVar = sqlite3_bind_parameter_name(pStmt, i); |
17612 | if( zVar==0 ){ |
17613 | sqlite3_snprintf(sizeof(zNum),zNum,"?%d" ,i); |
17614 | zVar = zNum; |
17615 | } |
17616 | sqlite3_bind_text(pQ, 1, zVar, -1, SQLITE_STATIC); |
17617 | if( sqlite3_step(pQ)==SQLITE_ROW ){ |
17618 | sqlite3_bind_value(pStmt, i, sqlite3_column_value(pQ, 0)); |
17619 | }else{ |
17620 | sqlite3_bind_null(pStmt, i); |
17621 | } |
17622 | sqlite3_reset(pQ); |
17623 | } |
17624 | sqlite3_finalize(pQ); |
17625 | } |
17626 | |
17627 | /* |
17628 | ** UTF8 box-drawing characters. Imagine box lines like this: |
17629 | ** |
17630 | ** 1 |
17631 | ** | |
17632 | ** 4 --+-- 2 |
17633 | ** | |
17634 | ** 3 |
17635 | ** |
17636 | ** Each box characters has between 2 and 4 of the lines leading from |
17637 | ** the center. The characters are here identified by the numbers of |
17638 | ** their corresponding lines. |
17639 | */ |
17640 | #define BOX_24 "\342\224\200" /* U+2500 --- */ |
17641 | #define BOX_13 "\342\224\202" /* U+2502 | */ |
17642 | #define BOX_23 "\342\224\214" /* U+250c ,- */ |
17643 | #define BOX_34 "\342\224\220" /* U+2510 -, */ |
17644 | #define BOX_12 "\342\224\224" /* U+2514 '- */ |
17645 | #define BOX_14 "\342\224\230" /* U+2518 -' */ |
17646 | #define BOX_123 "\342\224\234" /* U+251c |- */ |
17647 | #define BOX_134 "\342\224\244" /* U+2524 -| */ |
17648 | #define BOX_234 "\342\224\254" /* U+252c -,- */ |
17649 | #define BOX_124 "\342\224\264" /* U+2534 -'- */ |
17650 | #define BOX_1234 "\342\224\274" /* U+253c -|- */ |
17651 | |
17652 | /* Draw horizontal line N characters long using unicode box |
17653 | ** characters |
17654 | */ |
17655 | static void print_box_line(FILE *out, int N){ |
17656 | const char zDash[] = |
17657 | BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 |
17658 | BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24; |
17659 | const int nDash = sizeof(zDash) - 1; |
17660 | N *= 3; |
17661 | while( N>nDash ){ |
17662 | utf8_printf(out, zDash); |
17663 | N -= nDash; |
17664 | } |
17665 | utf8_printf(out, "%.*s" , N, zDash); |
17666 | } |
17667 | |
17668 | /* |
17669 | ** Draw a horizontal separator for a MODE_Box table. |
17670 | */ |
17671 | static void print_box_row_separator( |
17672 | ShellState *p, |
17673 | int nArg, |
17674 | const char *zSep1, |
17675 | const char *zSep2, |
17676 | const char *zSep3 |
17677 | ){ |
17678 | int i; |
17679 | if( nArg>0 ){ |
17680 | utf8_printf(p->out, "%s" , zSep1); |
17681 | print_box_line(p->out, p->actualWidth[0]+2); |
17682 | for(i=1; i<nArg; i++){ |
17683 | utf8_printf(p->out, "%s" , zSep2); |
17684 | print_box_line(p->out, p->actualWidth[i]+2); |
17685 | } |
17686 | utf8_printf(p->out, "%s" , zSep3); |
17687 | } |
17688 | fputs("\n" , p->out); |
17689 | } |
17690 | |
17691 | /* |
17692 | ** z[] is a line of text that is to be displayed the .mode box or table or |
17693 | ** similar tabular formats. z[] might contain control characters such |
17694 | ** as \n, \t, \f, or \r. |
17695 | ** |
17696 | ** Compute characters to display on the first line of z[]. Stop at the |
17697 | ** first \r, \n, or \f. Expand \t into spaces. Return a copy (obtained |
17698 | ** from malloc()) of that first line, which caller should free sometime. |
17699 | ** Write anything to display on the next line into *pzTail. If this is |
17700 | ** the last line, write a NULL into *pzTail. (*pzTail is not allocated.) |
17701 | */ |
17702 | static char *translateForDisplayAndDup( |
17703 | const unsigned char *z, /* Input text to be transformed */ |
17704 | const unsigned char **pzTail, /* OUT: Tail of the input for next line */ |
17705 | int mxWidth, /* Max width. 0 means no limit */ |
17706 | u8 bWordWrap /* If true, avoid breaking mid-word */ |
17707 | ){ |
17708 | int i; /* Input bytes consumed */ |
17709 | int j; /* Output bytes generated */ |
17710 | int k; /* Input bytes to be displayed */ |
17711 | int n; /* Output column number */ |
17712 | unsigned char *zOut; /* Output text */ |
17713 | |
17714 | if( z==0 ){ |
17715 | *pzTail = 0; |
17716 | return 0; |
17717 | } |
17718 | if( mxWidth<0 ) mxWidth = -mxWidth; |
17719 | if( mxWidth==0 ) mxWidth = 1000000; |
17720 | i = j = n = 0; |
17721 | while( n<mxWidth ){ |
17722 | if( z[i]>=' ' ){ |
17723 | n++; |
17724 | do{ i++; j++; }while( (z[i]&0xc0)==0x80 ); |
17725 | continue; |
17726 | } |
17727 | if( z[i]=='\t' ){ |
17728 | do{ |
17729 | n++; |
17730 | j++; |
17731 | }while( (n&7)!=0 && n<mxWidth ); |
17732 | i++; |
17733 | continue; |
17734 | } |
17735 | break; |
17736 | } |
17737 | if( n>=mxWidth && bWordWrap ){ |
17738 | /* Perhaps try to back up to a better place to break the line */ |
17739 | for(k=i; k>i/2; k--){ |
17740 | if( isspace(z[k-1]) ) break; |
17741 | } |
17742 | if( k<=i/2 ){ |
17743 | for(k=i; k>i/2; k--){ |
17744 | if( isalnum(z[k-1])!=isalnum(z[k]) && (z[k]&0xc0)!=0x80 ) break; |
17745 | } |
17746 | } |
17747 | if( k<=i/2 ){ |
17748 | k = i; |
17749 | }else{ |
17750 | i = k; |
17751 | while( z[i]==' ' ) i++; |
17752 | } |
17753 | }else{ |
17754 | k = i; |
17755 | } |
17756 | if( n>=mxWidth && z[i]>=' ' ){ |
17757 | *pzTail = &z[i]; |
17758 | }else if( z[i]=='\r' && z[i+1]=='\n' ){ |
17759 | *pzTail = z[i+2] ? &z[i+2] : 0; |
17760 | }else if( z[i]==0 || z[i+1]==0 ){ |
17761 | *pzTail = 0; |
17762 | }else{ |
17763 | *pzTail = &z[i+1]; |
17764 | } |
17765 | zOut = malloc( j+1 ); |
17766 | shell_check_oom(zOut); |
17767 | i = j = n = 0; |
17768 | while( i<k ){ |
17769 | if( z[i]>=' ' ){ |
17770 | n++; |
17771 | do{ zOut[j++] = z[i++]; }while( (z[i]&0xc0)==0x80 ); |
17772 | continue; |
17773 | } |
17774 | if( z[i]=='\t' ){ |
17775 | do{ |
17776 | n++; |
17777 | zOut[j++] = ' '; |
17778 | }while( (n&7)!=0 && n<mxWidth ); |
17779 | i++; |
17780 | continue; |
17781 | } |
17782 | break; |
17783 | } |
17784 | zOut[j] = 0; |
17785 | return (char*)zOut; |
17786 | } |
17787 | |
17788 | /* Extract the value of the i-th current column for pStmt as an SQL literal |
17789 | ** value. Memory is obtained from sqlite3_malloc64() and must be freed by |
17790 | ** the caller. |
17791 | */ |
17792 | static char *quoted_column(sqlite3_stmt *pStmt, int i){ |
17793 | switch( sqlite3_column_type(pStmt, i) ){ |
17794 | case SQLITE_NULL: { |
17795 | return sqlite3_mprintf("NULL" ); |
17796 | } |
17797 | case SQLITE_INTEGER: |
17798 | case SQLITE_FLOAT: { |
17799 | return sqlite3_mprintf("%s" ,sqlite3_column_text(pStmt,i)); |
17800 | } |
17801 | case SQLITE_TEXT: { |
17802 | return sqlite3_mprintf("%Q" ,sqlite3_column_text(pStmt,i)); |
17803 | } |
17804 | case SQLITE_BLOB: { |
17805 | int j; |
17806 | sqlite3_str *pStr = sqlite3_str_new(0); |
17807 | const unsigned char *a = sqlite3_column_blob(pStmt,i); |
17808 | int n = sqlite3_column_bytes(pStmt,i); |
17809 | sqlite3_str_append(pStr, "x'" , 2); |
17810 | for(j=0; j<n; j++){ |
17811 | sqlite3_str_appendf(pStr, "%02x" , a[j]); |
17812 | } |
17813 | sqlite3_str_append(pStr, "'" , 1); |
17814 | return sqlite3_str_finish(pStr); |
17815 | } |
17816 | } |
17817 | return 0; /* Not reached */ |
17818 | } |
17819 | |
17820 | /* |
17821 | ** Run a prepared statement and output the result in one of the |
17822 | ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table, |
17823 | ** or MODE_Box. |
17824 | ** |
17825 | ** This is different from ordinary exec_prepared_stmt() in that |
17826 | ** it has to run the entire query and gather the results into memory |
17827 | ** first, in order to determine column widths, before providing |
17828 | ** any output. |
17829 | */ |
17830 | static void exec_prepared_stmt_columnar( |
17831 | ShellState *p, /* Pointer to ShellState */ |
17832 | sqlite3_stmt *pStmt /* Statment to run */ |
17833 | ){ |
17834 | sqlite3_int64 nRow = 0; |
17835 | int nColumn = 0; |
17836 | char **azData = 0; |
17837 | sqlite3_int64 nAlloc = 0; |
17838 | char *abRowDiv = 0; |
17839 | const unsigned char *uz; |
17840 | const char *z; |
17841 | char **azQuoted = 0; |
17842 | int rc; |
17843 | sqlite3_int64 i, nData; |
17844 | int j, nTotal, w, n; |
17845 | const char *colSep = 0; |
17846 | const char *rowSep = 0; |
17847 | const unsigned char **azNextLine = 0; |
17848 | int bNextLine = 0; |
17849 | int bMultiLineRowExists = 0; |
17850 | int bw = p->cmOpts.bWordWrap; |
17851 | const char *zEmpty = "" ; |
17852 | const char *zShowNull = p->nullValue; |
17853 | |
17854 | rc = sqlite3_step(pStmt); |
17855 | if( rc!=SQLITE_ROW ) return; |
17856 | nColumn = sqlite3_column_count(pStmt); |
17857 | nAlloc = nColumn*4; |
17858 | if( nAlloc<=0 ) nAlloc = 1; |
17859 | azData = sqlite3_malloc64( nAlloc*sizeof(char*) ); |
17860 | shell_check_oom(azData); |
17861 | azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) ); |
17862 | shell_check_oom((void*)azNextLine); |
17863 | memset((void*)azNextLine, 0, nColumn*sizeof(char*) ); |
17864 | if( p->cmOpts.bQuote ){ |
17865 | azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) ); |
17866 | shell_check_oom(azQuoted); |
17867 | memset(azQuoted, 0, nColumn*sizeof(char*) ); |
17868 | } |
17869 | abRowDiv = sqlite3_malloc64( nAlloc/nColumn ); |
17870 | shell_check_oom(abRowDiv); |
17871 | if( nColumn>p->nWidth ){ |
17872 | p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int)); |
17873 | shell_check_oom(p->colWidth); |
17874 | for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0; |
17875 | p->nWidth = nColumn; |
17876 | p->actualWidth = &p->colWidth[nColumn]; |
17877 | } |
17878 | memset(p->actualWidth, 0, nColumn*sizeof(int)); |
17879 | for(i=0; i<nColumn; i++){ |
17880 | w = p->colWidth[i]; |
17881 | if( w<0 ) w = -w; |
17882 | p->actualWidth[i] = w; |
17883 | } |
17884 | for(i=0; i<nColumn; i++){ |
17885 | const unsigned char *zNotUsed; |
17886 | int wx = p->colWidth[i]; |
17887 | if( wx==0 ){ |
17888 | wx = p->cmOpts.iWrap; |
17889 | } |
17890 | if( wx<0 ) wx = -wx; |
17891 | uz = (const unsigned char*)sqlite3_column_name(pStmt,i); |
17892 | azData[i] = translateForDisplayAndDup(uz, &zNotUsed, wx, bw); |
17893 | } |
17894 | do{ |
17895 | int useNextLine = bNextLine; |
17896 | bNextLine = 0; |
17897 | if( (nRow+2)*nColumn >= nAlloc ){ |
17898 | nAlloc *= 2; |
17899 | azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*)); |
17900 | shell_check_oom(azData); |
17901 | abRowDiv = sqlite3_realloc64(abRowDiv, nAlloc/nColumn); |
17902 | shell_check_oom(abRowDiv); |
17903 | } |
17904 | abRowDiv[nRow] = 1; |
17905 | nRow++; |
17906 | for(i=0; i<nColumn; i++){ |
17907 | int wx = p->colWidth[i]; |
17908 | if( wx==0 ){ |
17909 | wx = p->cmOpts.iWrap; |
17910 | } |
17911 | if( wx<0 ) wx = -wx; |
17912 | if( useNextLine ){ |
17913 | uz = azNextLine[i]; |
17914 | if( uz==0 ) uz = (u8*)zEmpty; |
17915 | }else if( p->cmOpts.bQuote ){ |
17916 | sqlite3_free(azQuoted[i]); |
17917 | azQuoted[i] = quoted_column(pStmt,i); |
17918 | uz = (const unsigned char*)azQuoted[i]; |
17919 | }else{ |
17920 | uz = (const unsigned char*)sqlite3_column_text(pStmt,i); |
17921 | if( uz==0 ) uz = (u8*)zShowNull; |
17922 | } |
17923 | azData[nRow*nColumn + i] |
17924 | = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw); |
17925 | if( azNextLine[i] ){ |
17926 | bNextLine = 1; |
17927 | abRowDiv[nRow-1] = 0; |
17928 | bMultiLineRowExists = 1; |
17929 | } |
17930 | } |
17931 | }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW ); |
17932 | nTotal = nColumn*(nRow+1); |
17933 | for(i=0; i<nTotal; i++){ |
17934 | z = azData[i]; |
17935 | if( z==0 ) z = (char*)zEmpty; |
17936 | n = strlenChar(z); |
17937 | j = i%nColumn; |
17938 | if( n>p->actualWidth[j] ) p->actualWidth[j] = n; |
17939 | } |
17940 | if( seenInterrupt ) goto columnar_end; |
17941 | if( nColumn==0 ) goto columnar_end; |
17942 | switch( p->cMode ){ |
17943 | case MODE_Column: { |
17944 | colSep = " " ; |
17945 | rowSep = "\n" ; |
17946 | if( p->showHeader ){ |
17947 | for(i=0; i<nColumn; i++){ |
17948 | w = p->actualWidth[i]; |
17949 | if( p->colWidth[i]<0 ) w = -w; |
17950 | utf8_width_print(p->out, w, azData[i]); |
17951 | fputs(i==nColumn-1?"\n" :" " , p->out); |
17952 | } |
17953 | for(i=0; i<nColumn; i++){ |
17954 | print_dashes(p->out, p->actualWidth[i]); |
17955 | fputs(i==nColumn-1?"\n" :" " , p->out); |
17956 | } |
17957 | } |
17958 | break; |
17959 | } |
17960 | case MODE_Table: { |
17961 | colSep = " | " ; |
17962 | rowSep = " |\n" ; |
17963 | print_row_separator(p, nColumn, "+" ); |
17964 | fputs("| " , p->out); |
17965 | for(i=0; i<nColumn; i++){ |
17966 | w = p->actualWidth[i]; |
17967 | n = strlenChar(azData[i]); |
17968 | utf8_printf(p->out, "%*s%s%*s" , (w-n)/2, "" , azData[i], (w-n+1)/2, "" ); |
17969 | fputs(i==nColumn-1?" |\n" :" | " , p->out); |
17970 | } |
17971 | print_row_separator(p, nColumn, "+" ); |
17972 | break; |
17973 | } |
17974 | case MODE_Markdown: { |
17975 | colSep = " | " ; |
17976 | rowSep = " |\n" ; |
17977 | fputs("| " , p->out); |
17978 | for(i=0; i<nColumn; i++){ |
17979 | w = p->actualWidth[i]; |
17980 | n = strlenChar(azData[i]); |
17981 | utf8_printf(p->out, "%*s%s%*s" , (w-n)/2, "" , azData[i], (w-n+1)/2, "" ); |
17982 | fputs(i==nColumn-1?" |\n" :" | " , p->out); |
17983 | } |
17984 | print_row_separator(p, nColumn, "|" ); |
17985 | break; |
17986 | } |
17987 | case MODE_Box: { |
17988 | colSep = " " BOX_13 " " ; |
17989 | rowSep = " " BOX_13 "\n" ; |
17990 | print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34); |
17991 | utf8_printf(p->out, BOX_13 " " ); |
17992 | for(i=0; i<nColumn; i++){ |
17993 | w = p->actualWidth[i]; |
17994 | n = strlenChar(azData[i]); |
17995 | utf8_printf(p->out, "%*s%s%*s%s" , |
17996 | (w-n)/2, "" , azData[i], (w-n+1)/2, "" , |
17997 | i==nColumn-1?" " BOX_13"\n" :" " BOX_13" " ); |
17998 | } |
17999 | print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134); |
18000 | break; |
18001 | } |
18002 | } |
18003 | for(i=nColumn, j=0; i<nTotal; i++, j++){ |
18004 | if( j==0 && p->cMode!=MODE_Column ){ |
18005 | utf8_printf(p->out, "%s" , p->cMode==MODE_Box?BOX_13" " :"| " ); |
18006 | } |
18007 | z = azData[i]; |
18008 | if( z==0 ) z = p->nullValue; |
18009 | w = p->actualWidth[j]; |
18010 | if( p->colWidth[j]<0 ) w = -w; |
18011 | utf8_width_print(p->out, w, z); |
18012 | if( j==nColumn-1 ){ |
18013 | utf8_printf(p->out, "%s" , rowSep); |
18014 | if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){ |
18015 | if( p->cMode==MODE_Table ){ |
18016 | print_row_separator(p, nColumn, "+" ); |
18017 | }else if( p->cMode==MODE_Box ){ |
18018 | print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134); |
18019 | }else if( p->cMode==MODE_Column ){ |
18020 | raw_printf(p->out, "\n" ); |
18021 | } |
18022 | } |
18023 | j = -1; |
18024 | if( seenInterrupt ) goto columnar_end; |
18025 | }else{ |
18026 | utf8_printf(p->out, "%s" , colSep); |
18027 | } |
18028 | } |
18029 | if( p->cMode==MODE_Table ){ |
18030 | print_row_separator(p, nColumn, "+" ); |
18031 | }else if( p->cMode==MODE_Box ){ |
18032 | print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14); |
18033 | } |
18034 | columnar_end: |
18035 | if( seenInterrupt ){ |
18036 | utf8_printf(p->out, "Interrupt\n" ); |
18037 | } |
18038 | nData = (nRow+1)*nColumn; |
18039 | for(i=0; i<nData; i++){ |
18040 | z = azData[i]; |
18041 | if( z!=zEmpty && z!=zShowNull ) free(azData[i]); |
18042 | } |
18043 | sqlite3_free(azData); |
18044 | sqlite3_free((void*)azNextLine); |
18045 | sqlite3_free(abRowDiv); |
18046 | if( azQuoted ){ |
18047 | for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]); |
18048 | sqlite3_free(azQuoted); |
18049 | } |
18050 | } |
18051 | |
18052 | /* |
18053 | ** Run a prepared statement |
18054 | */ |
18055 | static void exec_prepared_stmt( |
18056 | ShellState *pArg, /* Pointer to ShellState */ |
18057 | sqlite3_stmt *pStmt /* Statment to run */ |
18058 | ){ |
18059 | int rc; |
18060 | sqlite3_uint64 nRow = 0; |
18061 | |
18062 | if( pArg->cMode==MODE_Column |
18063 | || pArg->cMode==MODE_Table |
18064 | || pArg->cMode==MODE_Box |
18065 | || pArg->cMode==MODE_Markdown |
18066 | ){ |
18067 | exec_prepared_stmt_columnar(pArg, pStmt); |
18068 | return; |
18069 | } |
18070 | |
18071 | /* perform the first step. this will tell us if we |
18072 | ** have a result set or not and how wide it is. |
18073 | */ |
18074 | rc = sqlite3_step(pStmt); |
18075 | /* if we have a result set... */ |
18076 | if( SQLITE_ROW == rc ){ |
18077 | /* allocate space for col name ptr, value ptr, and type */ |
18078 | int nCol = sqlite3_column_count(pStmt); |
18079 | void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); |
18080 | if( !pData ){ |
18081 | shell_out_of_memory(); |
18082 | }else{ |
18083 | char **azCols = (char **)pData; /* Names of result columns */ |
18084 | char **azVals = &azCols[nCol]; /* Results */ |
18085 | int *aiTypes = (int *)&azVals[nCol]; /* Result types */ |
18086 | int i, x; |
18087 | assert(sizeof(int) <= sizeof(char *)); |
18088 | /* save off ptrs to column names */ |
18089 | for(i=0; i<nCol; i++){ |
18090 | azCols[i] = (char *)sqlite3_column_name(pStmt, i); |
18091 | } |
18092 | do{ |
18093 | nRow++; |
18094 | /* extract the data and data types */ |
18095 | for(i=0; i<nCol; i++){ |
18096 | aiTypes[i] = x = sqlite3_column_type(pStmt, i); |
18097 | if( x==SQLITE_BLOB |
18098 | && pArg |
18099 | && (pArg->cMode==MODE_Insert || pArg->cMode==MODE_Quote) |
18100 | ){ |
18101 | azVals[i] = "" ; |
18102 | }else{ |
18103 | azVals[i] = (char*)sqlite3_column_text(pStmt, i); |
18104 | } |
18105 | if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ |
18106 | rc = SQLITE_NOMEM; |
18107 | break; /* from for */ |
18108 | } |
18109 | } /* end for */ |
18110 | |
18111 | /* if data and types extracted successfully... */ |
18112 | if( SQLITE_ROW == rc ){ |
18113 | /* call the supplied callback with the result row data */ |
18114 | if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){ |
18115 | rc = SQLITE_ABORT; |
18116 | }else{ |
18117 | rc = sqlite3_step(pStmt); |
18118 | } |
18119 | } |
18120 | } while( SQLITE_ROW == rc ); |
18121 | sqlite3_free(pData); |
18122 | if( pArg->cMode==MODE_Json ){ |
18123 | fputs("]\n" , pArg->out); |
18124 | }else if( pArg->cMode==MODE_Count ){ |
18125 | char zBuf[200]; |
18126 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n" , |
18127 | nRow, nRow!=1 ? "s" : "" ); |
18128 | printf("%s" , zBuf); |
18129 | } |
18130 | } |
18131 | } |
18132 | } |
18133 | |
18134 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
18135 | /* |
18136 | ** This function is called to process SQL if the previous shell command |
18137 | ** was ".expert". It passes the SQL in the second argument directly to |
18138 | ** the sqlite3expert object. |
18139 | ** |
18140 | ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error |
18141 | ** code. In this case, (*pzErr) may be set to point to a buffer containing |
18142 | ** an English language error message. It is the responsibility of the |
18143 | ** caller to eventually free this buffer using sqlite3_free(). |
18144 | */ |
18145 | static int expertHandleSQL( |
18146 | ShellState *pState, |
18147 | const char *zSql, |
18148 | char **pzErr |
18149 | ){ |
18150 | assert( pState->expert.pExpert ); |
18151 | assert( pzErr==0 || *pzErr==0 ); |
18152 | return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr); |
18153 | } |
18154 | |
18155 | /* |
18156 | ** This function is called either to silently clean up the object |
18157 | ** created by the ".expert" command (if bCancel==1), or to generate a |
18158 | ** report from it and then clean it up (if bCancel==0). |
18159 | ** |
18160 | ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error |
18161 | ** code. In this case, (*pzErr) may be set to point to a buffer containing |
18162 | ** an English language error message. It is the responsibility of the |
18163 | ** caller to eventually free this buffer using sqlite3_free(). |
18164 | */ |
18165 | static int expertFinish( |
18166 | ShellState *pState, |
18167 | int bCancel, |
18168 | char **pzErr |
18169 | ){ |
18170 | int rc = SQLITE_OK; |
18171 | sqlite3expert *p = pState->expert.pExpert; |
18172 | assert( p ); |
18173 | assert( bCancel || pzErr==0 || *pzErr==0 ); |
18174 | if( bCancel==0 ){ |
18175 | FILE *out = pState->out; |
18176 | int bVerbose = pState->expert.bVerbose; |
18177 | |
18178 | rc = sqlite3_expert_analyze(p, pzErr); |
18179 | if( rc==SQLITE_OK ){ |
18180 | int nQuery = sqlite3_expert_count(p); |
18181 | int i; |
18182 | |
18183 | if( bVerbose ){ |
18184 | const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES); |
18185 | raw_printf(out, "-- Candidates -----------------------------\n" ); |
18186 | raw_printf(out, "%s\n" , zCand); |
18187 | } |
18188 | for(i=0; i<nQuery; i++){ |
18189 | const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL); |
18190 | const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES); |
18191 | const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN); |
18192 | if( zIdx==0 ) zIdx = "(no new indexes)\n" ; |
18193 | if( bVerbose ){ |
18194 | raw_printf(out, "-- Query %d --------------------------------\n" ,i+1); |
18195 | raw_printf(out, "%s\n\n" , zSql); |
18196 | } |
18197 | raw_printf(out, "%s\n" , zIdx); |
18198 | raw_printf(out, "%s\n" , zEQP); |
18199 | } |
18200 | } |
18201 | } |
18202 | sqlite3_expert_destroy(p); |
18203 | pState->expert.pExpert = 0; |
18204 | return rc; |
18205 | } |
18206 | |
18207 | /* |
18208 | ** Implementation of ".expert" dot command. |
18209 | */ |
18210 | static int expertDotCommand( |
18211 | ShellState *pState, /* Current shell tool state */ |
18212 | char **azArg, /* Array of arguments passed to dot command */ |
18213 | int nArg /* Number of entries in azArg[] */ |
18214 | ){ |
18215 | int rc = SQLITE_OK; |
18216 | char *zErr = 0; |
18217 | int i; |
18218 | int iSample = 0; |
18219 | |
18220 | assert( pState->expert.pExpert==0 ); |
18221 | memset(&pState->expert, 0, sizeof(ExpertInfo)); |
18222 | |
18223 | for(i=1; rc==SQLITE_OK && i<nArg; i++){ |
18224 | char *z = azArg[i]; |
18225 | int n; |
18226 | if( z[0]=='-' && z[1]=='-' ) z++; |
18227 | n = strlen30(z); |
18228 | if( n>=2 && 0==cli_strncmp(z, "-verbose" , n) ){ |
18229 | pState->expert.bVerbose = 1; |
18230 | } |
18231 | else if( n>=2 && 0==cli_strncmp(z, "-sample" , n) ){ |
18232 | if( i==(nArg-1) ){ |
18233 | raw_printf(stderr, "option requires an argument: %s\n" , z); |
18234 | rc = SQLITE_ERROR; |
18235 | }else{ |
18236 | iSample = (int)integerValue(azArg[++i]); |
18237 | if( iSample<0 || iSample>100 ){ |
18238 | raw_printf(stderr, "value out of range: %s\n" , azArg[i]); |
18239 | rc = SQLITE_ERROR; |
18240 | } |
18241 | } |
18242 | } |
18243 | else{ |
18244 | raw_printf(stderr, "unknown option: %s\n" , z); |
18245 | rc = SQLITE_ERROR; |
18246 | } |
18247 | } |
18248 | |
18249 | if( rc==SQLITE_OK ){ |
18250 | pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); |
18251 | if( pState->expert.pExpert==0 ){ |
18252 | raw_printf(stderr, "sqlite3_expert_new: %s\n" , zErr ? zErr : "out of memory" ); |
18253 | rc = SQLITE_ERROR; |
18254 | }else{ |
18255 | sqlite3_expert_config( |
18256 | pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample |
18257 | ); |
18258 | } |
18259 | } |
18260 | sqlite3_free(zErr); |
18261 | |
18262 | return rc; |
18263 | } |
18264 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
18265 | |
18266 | /* |
18267 | ** Execute a statement or set of statements. Print |
18268 | ** any result rows/columns depending on the current mode |
18269 | ** set via the supplied callback. |
18270 | ** |
18271 | ** This is very similar to SQLite's built-in sqlite3_exec() |
18272 | ** function except it takes a slightly different callback |
18273 | ** and callback data argument. |
18274 | */ |
18275 | static int shell_exec( |
18276 | ShellState *pArg, /* Pointer to ShellState */ |
18277 | const char *zSql, /* SQL to be evaluated */ |
18278 | char **pzErrMsg /* Error msg written here */ |
18279 | ){ |
18280 | sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ |
18281 | int rc = SQLITE_OK; /* Return Code */ |
18282 | int rc2; |
18283 | const char *zLeftover; /* Tail of unprocessed SQL */ |
18284 | sqlite3 *db = pArg->db; |
18285 | |
18286 | if( pzErrMsg ){ |
18287 | *pzErrMsg = NULL; |
18288 | } |
18289 | |
18290 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
18291 | if( pArg->expert.pExpert ){ |
18292 | rc = expertHandleSQL(pArg, zSql, pzErrMsg); |
18293 | return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); |
18294 | } |
18295 | #endif |
18296 | |
18297 | while( zSql[0] && (SQLITE_OK == rc) ){ |
18298 | static const char *zStmtSql; |
18299 | rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); |
18300 | if( SQLITE_OK != rc ){ |
18301 | if( pzErrMsg ){ |
18302 | *pzErrMsg = save_err_msg(db, "in prepare" , rc, zSql); |
18303 | } |
18304 | }else{ |
18305 | if( !pStmt ){ |
18306 | /* this happens for a comment or white-space */ |
18307 | zSql = zLeftover; |
18308 | while( IsSpace(zSql[0]) ) zSql++; |
18309 | continue; |
18310 | } |
18311 | zStmtSql = sqlite3_sql(pStmt); |
18312 | if( zStmtSql==0 ) zStmtSql = "" ; |
18313 | while( IsSpace(zStmtSql[0]) ) zStmtSql++; |
18314 | |
18315 | /* save off the prepared statment handle and reset row count */ |
18316 | if( pArg ){ |
18317 | pArg->pStmt = pStmt; |
18318 | pArg->cnt = 0; |
18319 | } |
18320 | |
18321 | /* Show the EXPLAIN QUERY PLAN if .eqp is on */ |
18322 | if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){ |
18323 | sqlite3_stmt *pExplain; |
18324 | char *zEQP; |
18325 | int triggerEQP = 0; |
18326 | disable_debug_trace_modes(); |
18327 | sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP); |
18328 | if( pArg->autoEQP>=AUTOEQP_trigger ){ |
18329 | sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0); |
18330 | } |
18331 | zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s" , zStmtSql); |
18332 | shell_check_oom(zEQP); |
18333 | rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); |
18334 | if( rc==SQLITE_OK ){ |
18335 | while( sqlite3_step(pExplain)==SQLITE_ROW ){ |
18336 | const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3); |
18337 | int iEqpId = sqlite3_column_int(pExplain, 0); |
18338 | int iParentId = sqlite3_column_int(pExplain, 1); |
18339 | if( zEQPLine==0 ) zEQPLine = "" ; |
18340 | if( zEQPLine[0]=='-' ) eqp_render(pArg); |
18341 | eqp_append(pArg, iEqpId, iParentId, zEQPLine); |
18342 | } |
18343 | eqp_render(pArg); |
18344 | } |
18345 | sqlite3_finalize(pExplain); |
18346 | sqlite3_free(zEQP); |
18347 | if( pArg->autoEQP>=AUTOEQP_full ){ |
18348 | /* Also do an EXPLAIN for ".eqp full" mode */ |
18349 | zEQP = sqlite3_mprintf("EXPLAIN %s" , zStmtSql); |
18350 | shell_check_oom(zEQP); |
18351 | rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); |
18352 | if( rc==SQLITE_OK ){ |
18353 | pArg->cMode = MODE_Explain; |
18354 | explain_data_prepare(pArg, pExplain); |
18355 | exec_prepared_stmt(pArg, pExplain); |
18356 | explain_data_delete(pArg); |
18357 | } |
18358 | sqlite3_finalize(pExplain); |
18359 | sqlite3_free(zEQP); |
18360 | } |
18361 | if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){ |
18362 | sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); |
18363 | /* Reprepare pStmt before reactiving trace modes */ |
18364 | sqlite3_finalize(pStmt); |
18365 | sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
18366 | if( pArg ) pArg->pStmt = pStmt; |
18367 | } |
18368 | restore_debug_trace_modes(); |
18369 | } |
18370 | |
18371 | if( pArg ){ |
18372 | pArg->cMode = pArg->mode; |
18373 | if( pArg->autoExplain ){ |
18374 | if( sqlite3_stmt_isexplain(pStmt)==1 ){ |
18375 | pArg->cMode = MODE_Explain; |
18376 | } |
18377 | if( sqlite3_stmt_isexplain(pStmt)==2 ){ |
18378 | pArg->cMode = MODE_EQP; |
18379 | } |
18380 | } |
18381 | |
18382 | /* If the shell is currently in ".explain" mode, gather the extra |
18383 | ** data required to add indents to the output.*/ |
18384 | if( pArg->cMode==MODE_Explain ){ |
18385 | explain_data_prepare(pArg, pStmt); |
18386 | } |
18387 | } |
18388 | |
18389 | bind_prepared_stmt(pArg, pStmt); |
18390 | exec_prepared_stmt(pArg, pStmt); |
18391 | explain_data_delete(pArg); |
18392 | eqp_render(pArg); |
18393 | |
18394 | /* print usage stats if stats on */ |
18395 | if( pArg && pArg->statsOn ){ |
18396 | display_stats(db, pArg, 0); |
18397 | } |
18398 | |
18399 | /* print loop-counters if required */ |
18400 | if( pArg && pArg->scanstatsOn ){ |
18401 | display_scanstats(db, pArg); |
18402 | } |
18403 | |
18404 | /* Finalize the statement just executed. If this fails, save a |
18405 | ** copy of the error message. Otherwise, set zSql to point to the |
18406 | ** next statement to execute. */ |
18407 | rc2 = sqlite3_finalize(pStmt); |
18408 | if( rc!=SQLITE_NOMEM ) rc = rc2; |
18409 | if( rc==SQLITE_OK ){ |
18410 | zSql = zLeftover; |
18411 | while( IsSpace(zSql[0]) ) zSql++; |
18412 | }else if( pzErrMsg ){ |
18413 | *pzErrMsg = save_err_msg(db, "stepping" , rc, 0); |
18414 | } |
18415 | |
18416 | /* clear saved stmt handle */ |
18417 | if( pArg ){ |
18418 | pArg->pStmt = NULL; |
18419 | } |
18420 | } |
18421 | } /* end while */ |
18422 | |
18423 | return rc; |
18424 | } |
18425 | |
18426 | /* |
18427 | ** Release memory previously allocated by tableColumnList(). |
18428 | */ |
18429 | static void freeColumnList(char **azCol){ |
18430 | int i; |
18431 | for(i=1; azCol[i]; i++){ |
18432 | sqlite3_free(azCol[i]); |
18433 | } |
18434 | /* azCol[0] is a static string */ |
18435 | sqlite3_free(azCol); |
18436 | } |
18437 | |
18438 | /* |
18439 | ** Return a list of pointers to strings which are the names of all |
18440 | ** columns in table zTab. The memory to hold the names is dynamically |
18441 | ** allocated and must be released by the caller using a subsequent call |
18442 | ** to freeColumnList(). |
18443 | ** |
18444 | ** The azCol[0] entry is usually NULL. However, if zTab contains a rowid |
18445 | ** value that needs to be preserved, then azCol[0] is filled in with the |
18446 | ** name of the rowid column. |
18447 | ** |
18448 | ** The first regular column in the table is azCol[1]. The list is terminated |
18449 | ** by an entry with azCol[i]==0. |
18450 | */ |
18451 | static char **tableColumnList(ShellState *p, const char *zTab){ |
18452 | char **azCol = 0; |
18453 | sqlite3_stmt *pStmt; |
18454 | char *zSql; |
18455 | int nCol = 0; |
18456 | int nAlloc = 0; |
18457 | int nPK = 0; /* Number of PRIMARY KEY columns seen */ |
18458 | int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ |
18459 | int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); |
18460 | int rc; |
18461 | |
18462 | zSql = sqlite3_mprintf("PRAGMA table_info=%Q" , zTab); |
18463 | shell_check_oom(zSql); |
18464 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
18465 | sqlite3_free(zSql); |
18466 | if( rc ) return 0; |
18467 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
18468 | if( nCol>=nAlloc-2 ){ |
18469 | nAlloc = nAlloc*2 + nCol + 10; |
18470 | azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); |
18471 | shell_check_oom(azCol); |
18472 | } |
18473 | azCol[++nCol] = sqlite3_mprintf("%s" , sqlite3_column_text(pStmt, 1)); |
18474 | shell_check_oom(azCol[nCol]); |
18475 | if( sqlite3_column_int(pStmt, 5) ){ |
18476 | nPK++; |
18477 | if( nPK==1 |
18478 | && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2), |
18479 | "INTEGER" )==0 |
18480 | ){ |
18481 | isIPK = 1; |
18482 | }else{ |
18483 | isIPK = 0; |
18484 | } |
18485 | } |
18486 | } |
18487 | sqlite3_finalize(pStmt); |
18488 | if( azCol==0 ) return 0; |
18489 | azCol[0] = 0; |
18490 | azCol[nCol+1] = 0; |
18491 | |
18492 | /* The decision of whether or not a rowid really needs to be preserved |
18493 | ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table |
18494 | ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve |
18495 | ** rowids on tables where the rowid is inaccessible because there are other |
18496 | ** columns in the table named "rowid", "_rowid_", and "oid". |
18497 | */ |
18498 | if( preserveRowid && isIPK ){ |
18499 | /* If a single PRIMARY KEY column with type INTEGER was seen, then it |
18500 | ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID |
18501 | ** table or a INTEGER PRIMARY KEY DESC column, neither of which are |
18502 | ** ROWID aliases. To distinguish these cases, check to see if |
18503 | ** there is a "pk" entry in "PRAGMA index_list". There will be |
18504 | ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. |
18505 | */ |
18506 | zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" |
18507 | " WHERE origin='pk'" , zTab); |
18508 | shell_check_oom(zSql); |
18509 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
18510 | sqlite3_free(zSql); |
18511 | if( rc ){ |
18512 | freeColumnList(azCol); |
18513 | return 0; |
18514 | } |
18515 | rc = sqlite3_step(pStmt); |
18516 | sqlite3_finalize(pStmt); |
18517 | preserveRowid = rc==SQLITE_ROW; |
18518 | } |
18519 | if( preserveRowid ){ |
18520 | /* Only preserve the rowid if we can find a name to use for the |
18521 | ** rowid */ |
18522 | static char *azRowid[] = { "rowid" , "_rowid_" , "oid" }; |
18523 | int i, j; |
18524 | for(j=0; j<3; j++){ |
18525 | for(i=1; i<=nCol; i++){ |
18526 | if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break; |
18527 | } |
18528 | if( i>nCol ){ |
18529 | /* At this point, we know that azRowid[j] is not the name of any |
18530 | ** ordinary column in the table. Verify that azRowid[j] is a valid |
18531 | ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID |
18532 | ** tables will fail this last check */ |
18533 | rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); |
18534 | if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; |
18535 | break; |
18536 | } |
18537 | } |
18538 | } |
18539 | return azCol; |
18540 | } |
18541 | |
18542 | /* |
18543 | ** Toggle the reverse_unordered_selects setting. |
18544 | */ |
18545 | static void toggleSelectOrder(sqlite3 *db){ |
18546 | sqlite3_stmt *pStmt = 0; |
18547 | int iSetting = 0; |
18548 | char zStmt[100]; |
18549 | sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects" , -1, &pStmt, 0); |
18550 | if( sqlite3_step(pStmt)==SQLITE_ROW ){ |
18551 | iSetting = sqlite3_column_int(pStmt, 0); |
18552 | } |
18553 | sqlite3_finalize(pStmt); |
18554 | sqlite3_snprintf(sizeof(zStmt), zStmt, |
18555 | "PRAGMA reverse_unordered_selects(%d)" , !iSetting); |
18556 | sqlite3_exec(db, zStmt, 0, 0, 0); |
18557 | } |
18558 | |
18559 | /* |
18560 | ** This is a different callback routine used for dumping the database. |
18561 | ** Each row received by this callback consists of a table name, |
18562 | ** the table type ("index" or "table") and SQL to create the table. |
18563 | ** This routine should print text sufficient to recreate the table. |
18564 | */ |
18565 | static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ |
18566 | int rc; |
18567 | const char *zTable; |
18568 | const char *zType; |
18569 | const char *zSql; |
18570 | ShellState *p = (ShellState *)pArg; |
18571 | int dataOnly; |
18572 | int noSys; |
18573 | |
18574 | UNUSED_PARAMETER(azNotUsed); |
18575 | if( nArg!=3 || azArg==0 ) return 0; |
18576 | zTable = azArg[0]; |
18577 | zType = azArg[1]; |
18578 | zSql = azArg[2]; |
18579 | if( zTable==0 ) return 0; |
18580 | if( zType==0 ) return 0; |
18581 | dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0; |
18582 | noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0; |
18583 | |
18584 | if( cli_strcmp(zTable, "sqlite_sequence" )==0 && !noSys ){ |
18585 | if( !dataOnly ) raw_printf(p->out, "DELETE FROM sqlite_sequence;\n" ); |
18586 | }else if( sqlite3_strglob("sqlite_stat?" , zTable)==0 && !noSys ){ |
18587 | if( !dataOnly ) raw_printf(p->out, "ANALYZE sqlite_schema;\n" ); |
18588 | }else if( cli_strncmp(zTable, "sqlite_" , 7)==0 ){ |
18589 | return 0; |
18590 | }else if( dataOnly ){ |
18591 | /* no-op */ |
18592 | }else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE" , 20)==0 ){ |
18593 | char *zIns; |
18594 | if( !p->writableSchema ){ |
18595 | raw_printf(p->out, "PRAGMA writable_schema=ON;\n" ); |
18596 | p->writableSchema = 1; |
18597 | } |
18598 | zIns = sqlite3_mprintf( |
18599 | "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)" |
18600 | "VALUES('table','%q','%q',0,'%q');" , |
18601 | zTable, zTable, zSql); |
18602 | shell_check_oom(zIns); |
18603 | utf8_printf(p->out, "%s\n" , zIns); |
18604 | sqlite3_free(zIns); |
18605 | return 0; |
18606 | }else{ |
18607 | printSchemaLine(p->out, zSql, ";\n" ); |
18608 | } |
18609 | |
18610 | if( cli_strcmp(zType, "table" )==0 ){ |
18611 | ShellText sSelect; |
18612 | ShellText sTable; |
18613 | char **azCol; |
18614 | int i; |
18615 | char *savedDestTable; |
18616 | int savedMode; |
18617 | |
18618 | azCol = tableColumnList(p, zTable); |
18619 | if( azCol==0 ){ |
18620 | p->nErr++; |
18621 | return 0; |
18622 | } |
18623 | |
18624 | /* Always quote the table name, even if it appears to be pure ascii, |
18625 | ** in case it is a keyword. Ex: INSERT INTO "table" ... */ |
18626 | initText(&sTable); |
18627 | appendText(&sTable, zTable, quoteChar(zTable)); |
18628 | /* If preserving the rowid, add a column list after the table name. |
18629 | ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" |
18630 | ** instead of the usual "INSERT INTO tab VALUES(...)". |
18631 | */ |
18632 | if( azCol[0] ){ |
18633 | appendText(&sTable, "(" , 0); |
18634 | appendText(&sTable, azCol[0], 0); |
18635 | for(i=1; azCol[i]; i++){ |
18636 | appendText(&sTable, "," , 0); |
18637 | appendText(&sTable, azCol[i], quoteChar(azCol[i])); |
18638 | } |
18639 | appendText(&sTable, ")" , 0); |
18640 | } |
18641 | |
18642 | /* Build an appropriate SELECT statement */ |
18643 | initText(&sSelect); |
18644 | appendText(&sSelect, "SELECT " , 0); |
18645 | if( azCol[0] ){ |
18646 | appendText(&sSelect, azCol[0], 0); |
18647 | appendText(&sSelect, "," , 0); |
18648 | } |
18649 | for(i=1; azCol[i]; i++){ |
18650 | appendText(&sSelect, azCol[i], quoteChar(azCol[i])); |
18651 | if( azCol[i+1] ){ |
18652 | appendText(&sSelect, "," , 0); |
18653 | } |
18654 | } |
18655 | freeColumnList(azCol); |
18656 | appendText(&sSelect, " FROM " , 0); |
18657 | appendText(&sSelect, zTable, quoteChar(zTable)); |
18658 | |
18659 | savedDestTable = p->zDestTable; |
18660 | savedMode = p->mode; |
18661 | p->zDestTable = sTable.z; |
18662 | p->mode = p->cMode = MODE_Insert; |
18663 | rc = shell_exec(p, sSelect.z, 0); |
18664 | if( (rc&0xff)==SQLITE_CORRUPT ){ |
18665 | raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n" ); |
18666 | toggleSelectOrder(p->db); |
18667 | shell_exec(p, sSelect.z, 0); |
18668 | toggleSelectOrder(p->db); |
18669 | } |
18670 | p->zDestTable = savedDestTable; |
18671 | p->mode = savedMode; |
18672 | freeText(&sTable); |
18673 | freeText(&sSelect); |
18674 | if( rc ) p->nErr++; |
18675 | } |
18676 | return 0; |
18677 | } |
18678 | |
18679 | /* |
18680 | ** Run zQuery. Use dump_callback() as the callback routine so that |
18681 | ** the contents of the query are output as SQL statements. |
18682 | ** |
18683 | ** If we get a SQLITE_CORRUPT error, rerun the query after appending |
18684 | ** "ORDER BY rowid DESC" to the end. |
18685 | */ |
18686 | static int run_schema_dump_query( |
18687 | ShellState *p, |
18688 | const char *zQuery |
18689 | ){ |
18690 | int rc; |
18691 | char *zErr = 0; |
18692 | rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); |
18693 | if( rc==SQLITE_CORRUPT ){ |
18694 | char *zQ2; |
18695 | int len = strlen30(zQuery); |
18696 | raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n" ); |
18697 | if( zErr ){ |
18698 | utf8_printf(p->out, "/****** %s ******/\n" , zErr); |
18699 | sqlite3_free(zErr); |
18700 | zErr = 0; |
18701 | } |
18702 | zQ2 = malloc( len+100 ); |
18703 | if( zQ2==0 ) return rc; |
18704 | sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC" , zQuery); |
18705 | rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); |
18706 | if( rc ){ |
18707 | utf8_printf(p->out, "/****** ERROR: %s ******/\n" , zErr); |
18708 | }else{ |
18709 | rc = SQLITE_CORRUPT; |
18710 | } |
18711 | sqlite3_free(zErr); |
18712 | free(zQ2); |
18713 | } |
18714 | return rc; |
18715 | } |
18716 | |
18717 | /* |
18718 | ** Text of help messages. |
18719 | ** |
18720 | ** The help text for each individual command begins with a line that starts |
18721 | ** with ".". Subsequent lines are supplemental information. |
18722 | ** |
18723 | ** There must be two or more spaces between the end of the command and the |
18724 | ** start of the description of what that command does. |
18725 | */ |
18726 | static const char *(azHelp[]) = { |
18727 | #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) \ |
18728 | && !defined(SQLITE_SHELL_FIDDLE) |
18729 | ".archive ... Manage SQL archives" , |
18730 | " Each command must have exactly one of the following options:" , |
18731 | " -c, --create Create a new archive" , |
18732 | " -u, --update Add or update files with changed mtime" , |
18733 | " -i, --insert Like -u but always add even if unchanged" , |
18734 | " -r, --remove Remove files from archive" , |
18735 | " -t, --list List contents of archive" , |
18736 | " -x, --extract Extract files from archive" , |
18737 | " Optional arguments:" , |
18738 | " -v, --verbose Print each filename as it is processed" , |
18739 | " -f FILE, --file FILE Use archive FILE (default is current db)" , |
18740 | " -a FILE, --append FILE Open FILE using the apndvfs VFS" , |
18741 | " -C DIR, --directory DIR Read/extract files from directory DIR" , |
18742 | " -g, --glob Use glob matching for names in archive" , |
18743 | " -n, --dryrun Show the SQL that would have occurred" , |
18744 | " Examples:" , |
18745 | " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar" , |
18746 | " .ar -tf ARCHIVE # List members of ARCHIVE" , |
18747 | " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE" , |
18748 | " See also:" , |
18749 | " http://sqlite.org/cli.html#sqlite_archive_support" , |
18750 | #endif |
18751 | #ifndef SQLITE_OMIT_AUTHORIZATION |
18752 | ".auth ON|OFF Show authorizer callbacks" , |
18753 | #endif |
18754 | #ifndef SQLITE_SHELL_FIDDLE |
18755 | ".backup ?DB? FILE Backup DB (default \"main\") to FILE" , |
18756 | " Options:" , |
18757 | " --append Use the appendvfs" , |
18758 | " --async Write to FILE without journal and fsync()" , |
18759 | #endif |
18760 | ".bail on|off Stop after hitting an error. Default OFF" , |
18761 | ".binary on|off Turn binary output on or off. Default OFF" , |
18762 | #ifndef SQLITE_SHELL_FIDDLE |
18763 | ".cd DIRECTORY Change the working directory to DIRECTORY" , |
18764 | #endif |
18765 | ".changes on|off Show number of rows changed by SQL" , |
18766 | #ifndef SQLITE_SHELL_FIDDLE |
18767 | ".check GLOB Fail if output since .testcase does not match" , |
18768 | ".clone NEWDB Clone data into NEWDB from the existing database" , |
18769 | #endif |
18770 | ".connection [close] [#] Open or close an auxiliary database connection" , |
18771 | ".databases List names and files of attached databases" , |
18772 | ".dbconfig ?op? ?val? List or change sqlite3_db_config() options" , |
18773 | #if SQLITE_SHELL_HAVE_RECOVER |
18774 | ".dbinfo ?DB? Show status information about the database" , |
18775 | #endif |
18776 | ".dump ?OBJECTS? Render database content as SQL" , |
18777 | " Options:" , |
18778 | " --data-only Output only INSERT statements" , |
18779 | " --newlines Allow unescaped newline characters in output" , |
18780 | " --nosys Omit system tables (ex: \"sqlite_stat1\")" , |
18781 | " --preserve-rowids Include ROWID values in the output" , |
18782 | " OBJECTS is a LIKE pattern for tables, indexes, triggers or views to dump" , |
18783 | " Additional LIKE patterns can be given in subsequent arguments" , |
18784 | ".echo on|off Turn command echo on or off" , |
18785 | ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN" , |
18786 | " Other Modes:" , |
18787 | #ifdef SQLITE_DEBUG |
18788 | " test Show raw EXPLAIN QUERY PLAN output" , |
18789 | " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"" , |
18790 | #endif |
18791 | " trigger Like \"full\" but also show trigger bytecode" , |
18792 | #ifndef SQLITE_SHELL_FIDDLE |
18793 | ".excel Display the output of next command in spreadsheet" , |
18794 | " --bom Put a UTF8 byte-order mark on intermediate file" , |
18795 | #endif |
18796 | #ifndef SQLITE_SHELL_FIDDLE |
18797 | ".exit ?CODE? Exit this program with return-code CODE" , |
18798 | #endif |
18799 | ".expert EXPERIMENTAL. Suggest indexes for queries" , |
18800 | ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto" , |
18801 | ".filectrl CMD ... Run various sqlite3_file_control() operations" , |
18802 | " --schema SCHEMA Use SCHEMA instead of \"main\"" , |
18803 | " --help Show CMD details" , |
18804 | ".fullschema ?--indent? Show schema and the content of sqlite_stat tables" , |
18805 | ".headers on|off Turn display of headers on or off" , |
18806 | ".help ?-all? ?PATTERN? Show help text for PATTERN" , |
18807 | #ifndef SQLITE_SHELL_FIDDLE |
18808 | ".import FILE TABLE Import data from FILE into TABLE" , |
18809 | " Options:" , |
18810 | " --ascii Use \\037 and \\036 as column and row separators" , |
18811 | " --csv Use , and \\n as column and row separators" , |
18812 | " --skip N Skip the first N rows of input" , |
18813 | " --schema S Target table to be S.TABLE" , |
18814 | " -v \"Verbose\" - increase auxiliary output" , |
18815 | " Notes:" , |
18816 | " * If TABLE does not exist, it is created. The first row of input" , |
18817 | " determines the column names." , |
18818 | " * If neither --csv or --ascii are used, the input mode is derived" , |
18819 | " from the \".mode\" output mode" , |
18820 | " * If FILE begins with \"|\" then it is a command that generates the" , |
18821 | " input text." , |
18822 | #endif |
18823 | #ifndef SQLITE_OMIT_TEST_CONTROL |
18824 | ".imposter INDEX TABLE Create imposter table TABLE on index INDEX" , |
18825 | #endif |
18826 | ".indexes ?TABLE? Show names of indexes" , |
18827 | " If TABLE is specified, only show indexes for" , |
18828 | " tables matching TABLE using the LIKE operator." , |
18829 | #ifdef SQLITE_ENABLE_IOTRACE |
18830 | ".iotrace FILE Enable I/O diagnostic logging to FILE" , |
18831 | #endif |
18832 | ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT" , |
18833 | ".lint OPTIONS Report potential schema issues." , |
18834 | " Options:" , |
18835 | " fkey-indexes Find missing foreign key indexes" , |
18836 | #if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_FIDDLE) |
18837 | ".load FILE ?ENTRY? Load an extension library" , |
18838 | #endif |
18839 | #ifndef SQLITE_SHELL_FIDDLE |
18840 | ".log FILE|off Turn logging on or off. FILE can be stderr/stdout" , |
18841 | #endif |
18842 | ".mode MODE ?OPTIONS? Set output mode" , |
18843 | " MODE is one of:" , |
18844 | " ascii Columns/rows delimited by 0x1F and 0x1E" , |
18845 | " box Tables using unicode box-drawing characters" , |
18846 | " csv Comma-separated values" , |
18847 | " column Output in columns. (See .width)" , |
18848 | " html HTML <table> code" , |
18849 | " insert SQL insert statements for TABLE" , |
18850 | " json Results in a JSON array" , |
18851 | " line One value per line" , |
18852 | " list Values delimited by \"|\"" , |
18853 | " markdown Markdown table format" , |
18854 | " qbox Shorthand for \"box --wrap 60 --quote\"" , |
18855 | " quote Escape answers as for SQL" , |
18856 | " table ASCII-art table" , |
18857 | " tabs Tab-separated values" , |
18858 | " tcl TCL list elements" , |
18859 | " OPTIONS: (for columnar modes or insert mode):" , |
18860 | " --wrap N Wrap output lines to no longer than N characters" , |
18861 | " --wordwrap B Wrap or not at word boundaries per B (on/off)" , |
18862 | " --ww Shorthand for \"--wordwrap 1\"" , |
18863 | " --quote Quote output text as SQL literals" , |
18864 | " --noquote Do not quote output text" , |
18865 | " TABLE The name of SQL table used for \"insert\" mode" , |
18866 | #ifndef SQLITE_SHELL_FIDDLE |
18867 | ".nonce STRING Suspend safe mode for one command if nonce matches" , |
18868 | #endif |
18869 | ".nullvalue STRING Use STRING in place of NULL values" , |
18870 | #ifndef SQLITE_SHELL_FIDDLE |
18871 | ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE" , |
18872 | " If FILE begins with '|' then open as a pipe" , |
18873 | " --bom Put a UTF8 byte-order mark at the beginning" , |
18874 | " -e Send output to the system text editor" , |
18875 | " -x Send output as CSV to a spreadsheet (same as \".excel\")" , |
18876 | /* Note that .open is (partially) available in WASM builds but is |
18877 | ** currently only intended to be used by the fiddle tool, not |
18878 | ** end users, so is "undocumented." */ |
18879 | ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE" , |
18880 | " Options:" , |
18881 | " --append Use appendvfs to append database to the end of FILE" , |
18882 | #endif |
18883 | #ifndef SQLITE_OMIT_DESERIALIZE |
18884 | " --deserialize Load into memory using sqlite3_deserialize()" , |
18885 | " --hexdb Load the output of \"dbtotxt\" as an in-memory db" , |
18886 | " --maxsize N Maximum size for --hexdb or --deserialized database" , |
18887 | #endif |
18888 | " --new Initialize FILE to an empty database" , |
18889 | " --nofollow Do not follow symbolic links" , |
18890 | " --readonly Open FILE readonly" , |
18891 | " --zip FILE is a ZIP archive" , |
18892 | #ifndef SQLITE_SHELL_FIDDLE |
18893 | ".output ?FILE? Send output to FILE or stdout if FILE is omitted" , |
18894 | " If FILE begins with '|' then open it as a pipe." , |
18895 | " Options:" , |
18896 | " --bom Prefix output with a UTF8 byte-order mark" , |
18897 | " -e Send output to the system text editor" , |
18898 | " -x Send output as CSV to a spreadsheet" , |
18899 | #endif |
18900 | ".parameter CMD ... Manage SQL parameter bindings" , |
18901 | " clear Erase all bindings" , |
18902 | " init Initialize the TEMP table that holds bindings" , |
18903 | " list List the current parameter bindings" , |
18904 | " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE" , |
18905 | " PARAMETER should start with one of: $ : @ ?" , |
18906 | " unset PARAMETER Remove PARAMETER from the binding table" , |
18907 | ".print STRING... Print literal STRING" , |
18908 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
18909 | ".progress N Invoke progress handler after every N opcodes" , |
18910 | " --limit N Interrupt after N progress callbacks" , |
18911 | " --once Do no more than one progress interrupt" , |
18912 | " --quiet|-q No output except at interrupts" , |
18913 | " --reset Reset the count for each input and interrupt" , |
18914 | #endif |
18915 | ".prompt MAIN CONTINUE Replace the standard prompts" , |
18916 | #ifndef SQLITE_SHELL_FIDDLE |
18917 | ".quit Exit this program" , |
18918 | ".read FILE Read input from FILE or command output" , |
18919 | " If FILE begins with \"|\", it is a command that generates the input." , |
18920 | #endif |
18921 | #if SQLITE_SHELL_HAVE_RECOVER |
18922 | ".recover Recover as much data as possible from corrupt db." , |
18923 | " --ignore-freelist Ignore pages that appear to be on db freelist" , |
18924 | " --lost-and-found TABLE Alternative name for the lost-and-found table" , |
18925 | " --no-rowids Do not attempt to recover rowid values" , |
18926 | " that are not also INTEGER PRIMARY KEYs" , |
18927 | #endif |
18928 | #ifndef SQLITE_SHELL_FIDDLE |
18929 | ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE" , |
18930 | ".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)" , |
18931 | #endif |
18932 | ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off" , |
18933 | ".schema ?PATTERN? Show the CREATE statements matching PATTERN" , |
18934 | " Options:" , |
18935 | " --indent Try to pretty-print the schema" , |
18936 | " --nosys Omit objects whose names start with \"sqlite_\"" , |
18937 | ".selftest ?OPTIONS? Run tests defined in the SELFTEST table" , |
18938 | " Options:" , |
18939 | " --init Create a new SELFTEST table" , |
18940 | " -v Verbose output" , |
18941 | ".separator COL ?ROW? Change the column and row separators" , |
18942 | #if defined(SQLITE_ENABLE_SESSION) |
18943 | ".session ?NAME? CMD ... Create or control sessions" , |
18944 | " Subcommands:" , |
18945 | " attach TABLE Attach TABLE" , |
18946 | " changeset FILE Write a changeset into FILE" , |
18947 | " close Close one session" , |
18948 | " enable ?BOOLEAN? Set or query the enable bit" , |
18949 | " filter GLOB... Reject tables matching GLOBs" , |
18950 | " indirect ?BOOLEAN? Mark or query the indirect status" , |
18951 | " isempty Query whether the session is empty" , |
18952 | " list List currently open session names" , |
18953 | " open DB NAME Open a new session on DB" , |
18954 | " patchset FILE Write a patchset into FILE" , |
18955 | " If ?NAME? is omitted, the first defined session is used." , |
18956 | #endif |
18957 | ".sha3sum ... Compute a SHA3 hash of database content" , |
18958 | " Options:" , |
18959 | " --schema Also hash the sqlite_schema table" , |
18960 | " --sha3-224 Use the sha3-224 algorithm" , |
18961 | " --sha3-256 Use the sha3-256 algorithm (default)" , |
18962 | " --sha3-384 Use the sha3-384 algorithm" , |
18963 | " --sha3-512 Use the sha3-512 algorithm" , |
18964 | " Any other argument is a LIKE pattern for tables to hash" , |
18965 | #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) |
18966 | ".shell CMD ARGS... Run CMD ARGS... in a system shell" , |
18967 | #endif |
18968 | ".show Show the current values for various settings" , |
18969 | ".stats ?ARG? Show stats or turn stats on or off" , |
18970 | " off Turn off automatic stat display" , |
18971 | " on Turn on automatic stat display" , |
18972 | " stmt Show statement stats" , |
18973 | " vmstep Show the virtual machine step count only" , |
18974 | #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) |
18975 | ".system CMD ARGS... Run CMD ARGS... in a system shell" , |
18976 | #endif |
18977 | ".tables ?TABLE? List names of tables matching LIKE pattern TABLE" , |
18978 | #ifndef SQLITE_SHELL_FIDDLE |
18979 | ".testcase NAME Begin redirecting output to 'testcase-out.txt'" , |
18980 | #endif |
18981 | ".testctrl CMD ... Run various sqlite3_test_control() operations" , |
18982 | " Run \".testctrl\" with no arguments for details" , |
18983 | ".timeout MS Try opening locked tables for MS milliseconds" , |
18984 | ".timer on|off Turn SQL timer on or off" , |
18985 | #ifndef SQLITE_OMIT_TRACE |
18986 | ".trace ?OPTIONS? Output each SQL statement as it is run" , |
18987 | " FILE Send output to FILE" , |
18988 | " stdout Send output to stdout" , |
18989 | " stderr Send output to stderr" , |
18990 | " off Disable tracing" , |
18991 | " --expanded Expand query parameters" , |
18992 | #ifdef SQLITE_ENABLE_NORMALIZE |
18993 | " --normalized Normal the SQL statements" , |
18994 | #endif |
18995 | " --plain Show SQL as it is input" , |
18996 | " --stmt Trace statement execution (SQLITE_TRACE_STMT)" , |
18997 | " --profile Profile statements (SQLITE_TRACE_PROFILE)" , |
18998 | " --row Trace each row (SQLITE_TRACE_ROW)" , |
18999 | " --close Trace connection close (SQLITE_TRACE_CLOSE)" , |
19000 | #endif /* SQLITE_OMIT_TRACE */ |
19001 | #ifdef SQLITE_DEBUG |
19002 | ".unmodule NAME ... Unregister virtual table modules" , |
19003 | " --allexcept Unregister everything except those named" , |
19004 | #endif |
19005 | ".vfsinfo ?AUX? Information about the top-level VFS" , |
19006 | ".vfslist List all available VFSes" , |
19007 | ".vfsname ?AUX? Print the name of the VFS stack" , |
19008 | ".width NUM1 NUM2 ... Set minimum column widths for columnar output" , |
19009 | " Negative values right-justify" , |
19010 | }; |
19011 | |
19012 | /* |
19013 | ** Output help text. |
19014 | ** |
19015 | ** zPattern describes the set of commands for which help text is provided. |
19016 | ** If zPattern is NULL, then show all commands, but only give a one-line |
19017 | ** description of each. |
19018 | ** |
19019 | ** Return the number of matches. |
19020 | */ |
19021 | static int showHelp(FILE *out, const char *zPattern){ |
19022 | int i = 0; |
19023 | int j = 0; |
19024 | int n = 0; |
19025 | char *zPat; |
19026 | if( zPattern==0 |
19027 | || zPattern[0]=='0' |
19028 | || cli_strcmp(zPattern,"-a" )==0 |
19029 | || cli_strcmp(zPattern,"-all" )==0 |
19030 | || cli_strcmp(zPattern,"--all" )==0 |
19031 | ){ |
19032 | /* Show all commands, but only one line per command */ |
19033 | if( zPattern==0 ) zPattern = "" ; |
19034 | for(i=0; i<ArraySize(azHelp); i++){ |
19035 | if( azHelp[i][0]=='.' || zPattern[0] ){ |
19036 | utf8_printf(out, "%s\n" , azHelp[i]); |
19037 | n++; |
19038 | } |
19039 | } |
19040 | }else{ |
19041 | /* Look for commands that for which zPattern is an exact prefix */ |
19042 | zPat = sqlite3_mprintf(".%s*" , zPattern); |
19043 | shell_check_oom(zPat); |
19044 | for(i=0; i<ArraySize(azHelp); i++){ |
19045 | if( sqlite3_strglob(zPat, azHelp[i])==0 ){ |
19046 | utf8_printf(out, "%s\n" , azHelp[i]); |
19047 | j = i+1; |
19048 | n++; |
19049 | } |
19050 | } |
19051 | sqlite3_free(zPat); |
19052 | if( n ){ |
19053 | if( n==1 ){ |
19054 | /* when zPattern is a prefix of exactly one command, then include the |
19055 | ** details of that command, which should begin at offset j */ |
19056 | while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){ |
19057 | utf8_printf(out, "%s\n" , azHelp[j]); |
19058 | j++; |
19059 | } |
19060 | } |
19061 | return n; |
19062 | } |
19063 | /* Look for commands that contain zPattern anywhere. Show the complete |
19064 | ** text of all commands that match. */ |
19065 | zPat = sqlite3_mprintf("%%%s%%" , zPattern); |
19066 | shell_check_oom(zPat); |
19067 | for(i=0; i<ArraySize(azHelp); i++){ |
19068 | if( azHelp[i][0]=='.' ) j = i; |
19069 | if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){ |
19070 | utf8_printf(out, "%s\n" , azHelp[j]); |
19071 | while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){ |
19072 | j++; |
19073 | utf8_printf(out, "%s\n" , azHelp[j]); |
19074 | } |
19075 | i = j; |
19076 | n++; |
19077 | } |
19078 | } |
19079 | sqlite3_free(zPat); |
19080 | } |
19081 | return n; |
19082 | } |
19083 | |
19084 | /* Forward reference */ |
19085 | static int process_input(ShellState *p); |
19086 | |
19087 | /* |
19088 | ** Read the content of file zName into memory obtained from sqlite3_malloc64() |
19089 | ** and return a pointer to the buffer. The caller is responsible for freeing |
19090 | ** the memory. |
19091 | ** |
19092 | ** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes |
19093 | ** read. |
19094 | ** |
19095 | ** For convenience, a nul-terminator byte is always appended to the data read |
19096 | ** from the file before the buffer is returned. This byte is not included in |
19097 | ** the final value of (*pnByte), if applicable. |
19098 | ** |
19099 | ** NULL is returned if any error is encountered. The final value of *pnByte |
19100 | ** is undefined in this case. |
19101 | */ |
19102 | static char *readFile(const char *zName, int *pnByte){ |
19103 | FILE *in = fopen(zName, "rb" ); |
19104 | long nIn; |
19105 | size_t nRead; |
19106 | char *pBuf; |
19107 | if( in==0 ) return 0; |
19108 | fseek(in, 0, SEEK_END); |
19109 | nIn = ftell(in); |
19110 | rewind(in); |
19111 | pBuf = sqlite3_malloc64( nIn+1 ); |
19112 | if( pBuf==0 ){ fclose(in); return 0; } |
19113 | nRead = fread(pBuf, nIn, 1, in); |
19114 | fclose(in); |
19115 | if( nRead!=1 ){ |
19116 | sqlite3_free(pBuf); |
19117 | return 0; |
19118 | } |
19119 | pBuf[nIn] = 0; |
19120 | if( pnByte ) *pnByte = nIn; |
19121 | return pBuf; |
19122 | } |
19123 | |
19124 | #if defined(SQLITE_ENABLE_SESSION) |
19125 | /* |
19126 | ** Close a single OpenSession object and release all of its associated |
19127 | ** resources. |
19128 | */ |
19129 | static void session_close(OpenSession *pSession){ |
19130 | int i; |
19131 | sqlite3session_delete(pSession->p); |
19132 | sqlite3_free(pSession->zName); |
19133 | for(i=0; i<pSession->nFilter; i++){ |
19134 | sqlite3_free(pSession->azFilter[i]); |
19135 | } |
19136 | sqlite3_free(pSession->azFilter); |
19137 | memset(pSession, 0, sizeof(OpenSession)); |
19138 | } |
19139 | #endif |
19140 | |
19141 | /* |
19142 | ** Close all OpenSession objects and release all associated resources. |
19143 | */ |
19144 | #if defined(SQLITE_ENABLE_SESSION) |
19145 | static void session_close_all(ShellState *p, int i){ |
19146 | int j; |
19147 | struct AuxDb *pAuxDb = i<0 ? p->pAuxDb : &p->aAuxDb[i]; |
19148 | for(j=0; j<pAuxDb->nSession; j++){ |
19149 | session_close(&pAuxDb->aSession[j]); |
19150 | } |
19151 | pAuxDb->nSession = 0; |
19152 | } |
19153 | #else |
19154 | # define session_close_all(X,Y) |
19155 | #endif |
19156 | |
19157 | /* |
19158 | ** Implementation of the xFilter function for an open session. Omit |
19159 | ** any tables named by ".session filter" but let all other table through. |
19160 | */ |
19161 | #if defined(SQLITE_ENABLE_SESSION) |
19162 | static int session_filter(void *pCtx, const char *zTab){ |
19163 | OpenSession *pSession = (OpenSession*)pCtx; |
19164 | int i; |
19165 | for(i=0; i<pSession->nFilter; i++){ |
19166 | if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0; |
19167 | } |
19168 | return 1; |
19169 | } |
19170 | #endif |
19171 | |
19172 | /* |
19173 | ** Try to deduce the type of file for zName based on its content. Return |
19174 | ** one of the SHELL_OPEN_* constants. |
19175 | ** |
19176 | ** If the file does not exist or is empty but its name looks like a ZIP |
19177 | ** archive and the dfltZip flag is true, then assume it is a ZIP archive. |
19178 | ** Otherwise, assume an ordinary database regardless of the filename if |
19179 | ** the type cannot be determined from content. |
19180 | */ |
19181 | int deduceDatabaseType(const char *zName, int dfltZip){ |
19182 | FILE *f = fopen(zName, "rb" ); |
19183 | size_t n; |
19184 | int rc = SHELL_OPEN_UNSPEC; |
19185 | char zBuf[100]; |
19186 | if( f==0 ){ |
19187 | if( dfltZip && sqlite3_strlike("%.zip" ,zName,0)==0 ){ |
19188 | return SHELL_OPEN_ZIPFILE; |
19189 | }else{ |
19190 | return SHELL_OPEN_NORMAL; |
19191 | } |
19192 | } |
19193 | n = fread(zBuf, 16, 1, f); |
19194 | if( n==1 && memcmp(zBuf, "SQLite format 3" , 16)==0 ){ |
19195 | fclose(f); |
19196 | return SHELL_OPEN_NORMAL; |
19197 | } |
19198 | fseek(f, -25, SEEK_END); |
19199 | n = fread(zBuf, 25, 1, f); |
19200 | if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-" , 17)==0 ){ |
19201 | rc = SHELL_OPEN_APPENDVFS; |
19202 | }else{ |
19203 | fseek(f, -22, SEEK_END); |
19204 | n = fread(zBuf, 22, 1, f); |
19205 | if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05 |
19206 | && zBuf[3]==0x06 ){ |
19207 | rc = SHELL_OPEN_ZIPFILE; |
19208 | }else if( n==0 && dfltZip && sqlite3_strlike("%.zip" ,zName,0)==0 ){ |
19209 | rc = SHELL_OPEN_ZIPFILE; |
19210 | } |
19211 | } |
19212 | fclose(f); |
19213 | return rc; |
19214 | } |
19215 | |
19216 | #ifndef SQLITE_OMIT_DESERIALIZE |
19217 | /* |
19218 | ** Reconstruct an in-memory database using the output from the "dbtotxt" |
19219 | ** program. Read content from the file in p->aAuxDb[].zDbFilename. |
19220 | ** If p->aAuxDb[].zDbFilename is 0, then read from standard input. |
19221 | */ |
19222 | static unsigned char *readHexDb(ShellState *p, int *pnData){ |
19223 | unsigned char *a = 0; |
19224 | int nLine; |
19225 | int n = 0; |
19226 | int pgsz = 0; |
19227 | int iOffset = 0; |
19228 | int j, k; |
19229 | int rc; |
19230 | FILE *in; |
19231 | const char *zDbFilename = p->pAuxDb->zDbFilename; |
19232 | unsigned int x[16]; |
19233 | char zLine[1000]; |
19234 | if( zDbFilename ){ |
19235 | in = fopen(zDbFilename, "r" ); |
19236 | if( in==0 ){ |
19237 | utf8_printf(stderr, "cannot open \"%s\" for reading\n" , zDbFilename); |
19238 | return 0; |
19239 | } |
19240 | nLine = 0; |
19241 | }else{ |
19242 | in = p->in; |
19243 | nLine = p->lineno; |
19244 | if( in==0 ) in = stdin; |
19245 | } |
19246 | *pnData = 0; |
19247 | nLine++; |
19248 | if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; |
19249 | rc = sscanf(zLine, "| size %d pagesize %d" , &n, &pgsz); |
19250 | if( rc!=2 ) goto readHexDb_error; |
19251 | if( n<0 ) goto readHexDb_error; |
19252 | if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error; |
19253 | n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */ |
19254 | a = sqlite3_malloc( n ? n : 1 ); |
19255 | shell_check_oom(a); |
19256 | memset(a, 0, n); |
19257 | if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ |
19258 | utf8_printf(stderr, "invalid pagesize\n" ); |
19259 | goto readHexDb_error; |
19260 | } |
19261 | for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){ |
19262 | rc = sscanf(zLine, "| page %d offset %d" , &j, &k); |
19263 | if( rc==2 ){ |
19264 | iOffset = k; |
19265 | continue; |
19266 | } |
19267 | if( cli_strncmp(zLine, "| end " , 6)==0 ){ |
19268 | break; |
19269 | } |
19270 | rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x" , |
19271 | &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], |
19272 | &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); |
19273 | if( rc==17 ){ |
19274 | k = iOffset+j; |
19275 | if( k+16<=n && k>=0 ){ |
19276 | int ii; |
19277 | for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff; |
19278 | } |
19279 | } |
19280 | } |
19281 | *pnData = n; |
19282 | if( in!=p->in ){ |
19283 | fclose(in); |
19284 | }else{ |
19285 | p->lineno = nLine; |
19286 | } |
19287 | return a; |
19288 | |
19289 | readHexDb_error: |
19290 | if( in!=p->in ){ |
19291 | fclose(in); |
19292 | }else{ |
19293 | while( fgets(zLine, sizeof(zLine), p->in)!=0 ){ |
19294 | nLine++; |
19295 | if(cli_strncmp(zLine, "| end " , 6)==0 ) break; |
19296 | } |
19297 | p->lineno = nLine; |
19298 | } |
19299 | sqlite3_free(a); |
19300 | utf8_printf(stderr,"Error on line %d of --hexdb input\n" , nLine); |
19301 | return 0; |
19302 | } |
19303 | #endif /* SQLITE_OMIT_DESERIALIZE */ |
19304 | |
19305 | /* |
19306 | ** Scalar function "shell_int32". The first argument to this function |
19307 | ** must be a blob. The second a non-negative integer. This function |
19308 | ** reads and returns a 32-bit big-endian integer from byte |
19309 | ** offset (4*<arg2>) of the blob. |
19310 | */ |
19311 | static void shellInt32( |
19312 | sqlite3_context *context, |
19313 | int argc, |
19314 | sqlite3_value **argv |
19315 | ){ |
19316 | const unsigned char *pBlob; |
19317 | int nBlob; |
19318 | int iInt; |
19319 | |
19320 | UNUSED_PARAMETER(argc); |
19321 | nBlob = sqlite3_value_bytes(argv[0]); |
19322 | pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]); |
19323 | iInt = sqlite3_value_int(argv[1]); |
19324 | |
19325 | if( iInt>=0 && (iInt+1)*4<=nBlob ){ |
19326 | const unsigned char *a = &pBlob[iInt*4]; |
19327 | sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24) |
19328 | + ((sqlite3_int64)a[1]<<16) |
19329 | + ((sqlite3_int64)a[2]<< 8) |
19330 | + ((sqlite3_int64)a[3]<< 0); |
19331 | sqlite3_result_int64(context, iVal); |
19332 | } |
19333 | } |
19334 | |
19335 | /* |
19336 | ** Scalar function "shell_idquote(X)" returns string X quoted as an identifier, |
19337 | ** using "..." with internal double-quote characters doubled. |
19338 | */ |
19339 | static void shellIdQuote( |
19340 | sqlite3_context *context, |
19341 | int argc, |
19342 | sqlite3_value **argv |
19343 | ){ |
19344 | const char *zName = (const char*)sqlite3_value_text(argv[0]); |
19345 | UNUSED_PARAMETER(argc); |
19346 | if( zName ){ |
19347 | char *z = sqlite3_mprintf("\"%w\"" , zName); |
19348 | sqlite3_result_text(context, z, -1, sqlite3_free); |
19349 | } |
19350 | } |
19351 | |
19352 | /* |
19353 | ** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X. |
19354 | */ |
19355 | static void shellUSleepFunc( |
19356 | sqlite3_context *context, |
19357 | int argcUnused, |
19358 | sqlite3_value **argv |
19359 | ){ |
19360 | int sleep = sqlite3_value_int(argv[0]); |
19361 | (void)argcUnused; |
19362 | sqlite3_sleep(sleep/1000); |
19363 | sqlite3_result_int(context, sleep); |
19364 | } |
19365 | |
19366 | /* |
19367 | ** Scalar function "shell_escape_crnl" used by the .recover command. |
19368 | ** The argument passed to this function is the output of built-in |
19369 | ** function quote(). If the first character of the input is "'", |
19370 | ** indicating that the value passed to quote() was a text value, |
19371 | ** then this function searches the input for "\n" and "\r" characters |
19372 | ** and adds a wrapper similar to the following: |
19373 | ** |
19374 | ** replace(replace(<input>, '\n', char(10), '\r', char(13)); |
19375 | ** |
19376 | ** Or, if the first character of the input is not "'", then a copy |
19377 | ** of the input is returned. |
19378 | */ |
19379 | static void shellEscapeCrnl( |
19380 | sqlite3_context *context, |
19381 | int argc, |
19382 | sqlite3_value **argv |
19383 | ){ |
19384 | const char *zText = (const char*)sqlite3_value_text(argv[0]); |
19385 | UNUSED_PARAMETER(argc); |
19386 | if( zText && zText[0]=='\'' ){ |
19387 | i64 nText = sqlite3_value_bytes(argv[0]); |
19388 | i64 i; |
19389 | char zBuf1[20]; |
19390 | char zBuf2[20]; |
19391 | const char *zNL = 0; |
19392 | const char *zCR = 0; |
19393 | i64 nCR = 0; |
19394 | i64 nNL = 0; |
19395 | |
19396 | for(i=0; zText[i]; i++){ |
19397 | if( zNL==0 && zText[i]=='\n' ){ |
19398 | zNL = unused_string(zText, "\\n" , "\\012" , zBuf1); |
19399 | nNL = strlen(zNL); |
19400 | } |
19401 | if( zCR==0 && zText[i]=='\r' ){ |
19402 | zCR = unused_string(zText, "\\r" , "\\015" , zBuf2); |
19403 | nCR = strlen(zCR); |
19404 | } |
19405 | } |
19406 | |
19407 | if( zNL || zCR ){ |
19408 | i64 iOut = 0; |
19409 | i64 nMax = (nNL > nCR) ? nNL : nCR; |
19410 | i64 nAlloc = nMax * nText + (nMax+64)*2; |
19411 | char *zOut = (char*)sqlite3_malloc64(nAlloc); |
19412 | if( zOut==0 ){ |
19413 | sqlite3_result_error_nomem(context); |
19414 | return; |
19415 | } |
19416 | |
19417 | if( zNL && zCR ){ |
19418 | memcpy(&zOut[iOut], "replace(replace(" , 16); |
19419 | iOut += 16; |
19420 | }else{ |
19421 | memcpy(&zOut[iOut], "replace(" , 8); |
19422 | iOut += 8; |
19423 | } |
19424 | for(i=0; zText[i]; i++){ |
19425 | if( zText[i]=='\n' ){ |
19426 | memcpy(&zOut[iOut], zNL, nNL); |
19427 | iOut += nNL; |
19428 | }else if( zText[i]=='\r' ){ |
19429 | memcpy(&zOut[iOut], zCR, nCR); |
19430 | iOut += nCR; |
19431 | }else{ |
19432 | zOut[iOut] = zText[i]; |
19433 | iOut++; |
19434 | } |
19435 | } |
19436 | |
19437 | if( zNL ){ |
19438 | memcpy(&zOut[iOut], ",'" , 2); iOut += 2; |
19439 | memcpy(&zOut[iOut], zNL, nNL); iOut += nNL; |
19440 | memcpy(&zOut[iOut], "', char(10))" , 12); iOut += 12; |
19441 | } |
19442 | if( zCR ){ |
19443 | memcpy(&zOut[iOut], ",'" , 2); iOut += 2; |
19444 | memcpy(&zOut[iOut], zCR, nCR); iOut += nCR; |
19445 | memcpy(&zOut[iOut], "', char(13))" , 12); iOut += 12; |
19446 | } |
19447 | |
19448 | sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT); |
19449 | sqlite3_free(zOut); |
19450 | return; |
19451 | } |
19452 | } |
19453 | |
19454 | sqlite3_result_value(context, argv[0]); |
19455 | } |
19456 | |
19457 | /* Flags for open_db(). |
19458 | ** |
19459 | ** The default behavior of open_db() is to exit(1) if the database fails to |
19460 | ** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error |
19461 | ** but still returns without calling exit. |
19462 | ** |
19463 | ** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a |
19464 | ** ZIP archive if the file does not exist or is empty and its name matches |
19465 | ** the *.zip pattern. |
19466 | */ |
19467 | #define OPEN_DB_KEEPALIVE 0x001 /* Return after error if true */ |
19468 | #define OPEN_DB_ZIPFILE 0x002 /* Open as ZIP if name matches *.zip */ |
19469 | |
19470 | /* |
19471 | ** Make sure the database is open. If it is not, then open it. If |
19472 | ** the database fails to open, print an error message and exit. |
19473 | */ |
19474 | static void open_db(ShellState *p, int openFlags){ |
19475 | if( p->db==0 ){ |
19476 | const char *zDbFilename = p->pAuxDb->zDbFilename; |
19477 | if( p->openMode==SHELL_OPEN_UNSPEC ){ |
19478 | if( zDbFilename==0 || zDbFilename[0]==0 ){ |
19479 | p->openMode = SHELL_OPEN_NORMAL; |
19480 | }else{ |
19481 | p->openMode = (u8)deduceDatabaseType(zDbFilename, |
19482 | (openFlags & OPEN_DB_ZIPFILE)!=0); |
19483 | } |
19484 | } |
19485 | switch( p->openMode ){ |
19486 | case SHELL_OPEN_APPENDVFS: { |
19487 | sqlite3_open_v2(zDbFilename, &p->db, |
19488 | SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs" ); |
19489 | break; |
19490 | } |
19491 | case SHELL_OPEN_HEXDB: |
19492 | case SHELL_OPEN_DESERIALIZE: { |
19493 | sqlite3_open(0, &p->db); |
19494 | break; |
19495 | } |
19496 | case SHELL_OPEN_ZIPFILE: { |
19497 | sqlite3_open(":memory:" , &p->db); |
19498 | break; |
19499 | } |
19500 | case SHELL_OPEN_READONLY: { |
19501 | sqlite3_open_v2(zDbFilename, &p->db, |
19502 | SQLITE_OPEN_READONLY|p->openFlags, 0); |
19503 | break; |
19504 | } |
19505 | case SHELL_OPEN_UNSPEC: |
19506 | case SHELL_OPEN_NORMAL: { |
19507 | sqlite3_open_v2(zDbFilename, &p->db, |
19508 | SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0); |
19509 | break; |
19510 | } |
19511 | } |
19512 | globalDb = p->db; |
19513 | if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ |
19514 | utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n" , |
19515 | zDbFilename, sqlite3_errmsg(p->db)); |
19516 | if( openFlags & OPEN_DB_KEEPALIVE ){ |
19517 | sqlite3_open(":memory:" , &p->db); |
19518 | return; |
19519 | } |
19520 | exit(1); |
19521 | } |
19522 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
19523 | sqlite3_enable_load_extension(p->db, 1); |
19524 | #endif |
19525 | sqlite3_shathree_init(p->db, 0, 0); |
19526 | sqlite3_uint_init(p->db, 0, 0); |
19527 | sqlite3_decimal_init(p->db, 0, 0); |
19528 | sqlite3_regexp_init(p->db, 0, 0); |
19529 | sqlite3_ieee_init(p->db, 0, 0); |
19530 | sqlite3_series_init(p->db, 0, 0); |
19531 | #ifndef SQLITE_SHELL_FIDDLE |
19532 | sqlite3_fileio_init(p->db, 0, 0); |
19533 | sqlite3_completion_init(p->db, 0, 0); |
19534 | #endif |
19535 | #if SQLITE_SHELL_HAVE_RECOVER |
19536 | sqlite3_dbdata_init(p->db, 0, 0); |
19537 | #endif |
19538 | #ifdef SQLITE_HAVE_ZLIB |
19539 | if( !p->bSafeModePersist ){ |
19540 | sqlite3_zipfile_init(p->db, 0, 0); |
19541 | sqlite3_sqlar_init(p->db, 0, 0); |
19542 | } |
19543 | #endif |
19544 | sqlite3_create_function(p->db, "shell_add_schema" , 3, SQLITE_UTF8, 0, |
19545 | shellAddSchemaName, 0, 0); |
19546 | sqlite3_create_function(p->db, "shell_module_schema" , 1, SQLITE_UTF8, 0, |
19547 | shellModuleSchema, 0, 0); |
19548 | sqlite3_create_function(p->db, "shell_putsnl" , 1, SQLITE_UTF8, p, |
19549 | shellPutsFunc, 0, 0); |
19550 | sqlite3_create_function(p->db, "shell_escape_crnl" , 1, SQLITE_UTF8, 0, |
19551 | shellEscapeCrnl, 0, 0); |
19552 | sqlite3_create_function(p->db, "shell_int32" , 2, SQLITE_UTF8, 0, |
19553 | shellInt32, 0, 0); |
19554 | sqlite3_create_function(p->db, "shell_idquote" , 1, SQLITE_UTF8, 0, |
19555 | shellIdQuote, 0, 0); |
19556 | sqlite3_create_function(p->db, "usleep" ,1,SQLITE_UTF8,0, |
19557 | shellUSleepFunc, 0, 0); |
19558 | #ifndef SQLITE_NOHAVE_SYSTEM |
19559 | sqlite3_create_function(p->db, "edit" , 1, SQLITE_UTF8, 0, |
19560 | editFunc, 0, 0); |
19561 | sqlite3_create_function(p->db, "edit" , 2, SQLITE_UTF8, 0, |
19562 | editFunc, 0, 0); |
19563 | #endif |
19564 | if( p->openMode==SHELL_OPEN_ZIPFILE ){ |
19565 | char *zSql = sqlite3_mprintf( |
19566 | "CREATE VIRTUAL TABLE zip USING zipfile(%Q);" , zDbFilename); |
19567 | shell_check_oom(zSql); |
19568 | sqlite3_exec(p->db, zSql, 0, 0, 0); |
19569 | sqlite3_free(zSql); |
19570 | } |
19571 | #ifndef SQLITE_OMIT_DESERIALIZE |
19572 | else |
19573 | if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){ |
19574 | int rc; |
19575 | int nData = 0; |
19576 | unsigned char *aData; |
19577 | if( p->openMode==SHELL_OPEN_DESERIALIZE ){ |
19578 | aData = (unsigned char*)readFile(zDbFilename, &nData); |
19579 | }else{ |
19580 | aData = readHexDb(p, &nData); |
19581 | if( aData==0 ){ |
19582 | return; |
19583 | } |
19584 | } |
19585 | rc = sqlite3_deserialize(p->db, "main" , aData, nData, nData, |
19586 | SQLITE_DESERIALIZE_RESIZEABLE | |
19587 | SQLITE_DESERIALIZE_FREEONCLOSE); |
19588 | if( rc ){ |
19589 | utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n" , rc); |
19590 | } |
19591 | if( p->szMax>0 ){ |
19592 | sqlite3_file_control(p->db, "main" , SQLITE_FCNTL_SIZE_LIMIT, &p->szMax); |
19593 | } |
19594 | } |
19595 | #endif |
19596 | } |
19597 | if( p->bSafeModePersist && p->db!=0 ){ |
19598 | sqlite3_set_authorizer(p->db, safeModeAuth, p); |
19599 | } |
19600 | } |
19601 | |
19602 | /* |
19603 | ** Attempt to close the databaes connection. Report errors. |
19604 | */ |
19605 | void close_db(sqlite3 *db){ |
19606 | int rc = sqlite3_close(db); |
19607 | if( rc ){ |
19608 | utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n" , |
19609 | rc, sqlite3_errmsg(db)); |
19610 | } |
19611 | } |
19612 | |
19613 | #if HAVE_READLINE || HAVE_EDITLINE |
19614 | /* |
19615 | ** Readline completion callbacks |
19616 | */ |
19617 | static char *readline_completion_generator(const char *text, int state){ |
19618 | static sqlite3_stmt *pStmt = 0; |
19619 | char *zRet; |
19620 | if( state==0 ){ |
19621 | char *zSql; |
19622 | sqlite3_finalize(pStmt); |
19623 | zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" |
19624 | " FROM completion(%Q) ORDER BY 1" , text); |
19625 | shell_check_oom(zSql); |
19626 | sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); |
19627 | sqlite3_free(zSql); |
19628 | } |
19629 | if( sqlite3_step(pStmt)==SQLITE_ROW ){ |
19630 | const char *z = (const char*)sqlite3_column_text(pStmt,0); |
19631 | zRet = z ? strdup(z) : 0; |
19632 | }else{ |
19633 | sqlite3_finalize(pStmt); |
19634 | pStmt = 0; |
19635 | zRet = 0; |
19636 | } |
19637 | return zRet; |
19638 | } |
19639 | static char **readline_completion(const char *zText, int iStart, int iEnd){ |
19640 | rl_attempted_completion_over = 1; |
19641 | return rl_completion_matches(zText, readline_completion_generator); |
19642 | } |
19643 | |
19644 | #elif HAVE_LINENOISE |
19645 | /* |
19646 | ** Linenoise completion callback |
19647 | */ |
19648 | static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){ |
19649 | i64 nLine = strlen(zLine); |
19650 | i64 i, iStart; |
19651 | sqlite3_stmt *pStmt = 0; |
19652 | char *zSql; |
19653 | char zBuf[1000]; |
19654 | |
19655 | if( nLine>sizeof(zBuf)-30 ) return; |
19656 | if( zLine[0]=='.' || zLine[0]=='#') return; |
19657 | for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){} |
19658 | if( i==nLine-1 ) return; |
19659 | iStart = i+1; |
19660 | memcpy(zBuf, zLine, iStart); |
19661 | zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" |
19662 | " FROM completion(%Q,%Q) ORDER BY 1" , |
19663 | &zLine[iStart], zLine); |
19664 | shell_check_oom(zSql); |
19665 | sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); |
19666 | sqlite3_free(zSql); |
19667 | sqlite3_exec(globalDb, "PRAGMA page_count" , 0, 0, 0); /* Load the schema */ |
19668 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
19669 | const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0); |
19670 | int nCompletion = sqlite3_column_bytes(pStmt, 0); |
19671 | if( iStart+nCompletion < sizeof(zBuf)-1 && zCompletion ){ |
19672 | memcpy(zBuf+iStart, zCompletion, nCompletion+1); |
19673 | linenoiseAddCompletion(lc, zBuf); |
19674 | } |
19675 | } |
19676 | sqlite3_finalize(pStmt); |
19677 | } |
19678 | #endif |
19679 | |
19680 | /* |
19681 | ** Do C-language style dequoting. |
19682 | ** |
19683 | ** \a -> alarm |
19684 | ** \b -> backspace |
19685 | ** \t -> tab |
19686 | ** \n -> newline |
19687 | ** \v -> vertical tab |
19688 | ** \f -> form feed |
19689 | ** \r -> carriage return |
19690 | ** \s -> space |
19691 | ** \" -> " |
19692 | ** \' -> ' |
19693 | ** \\ -> backslash |
19694 | ** \NNN -> ascii character NNN in octal |
19695 | */ |
19696 | static void resolve_backslashes(char *z){ |
19697 | int i, j; |
19698 | char c; |
19699 | while( *z && *z!='\\' ) z++; |
19700 | for(i=j=0; (c = z[i])!=0; i++, j++){ |
19701 | if( c=='\\' && z[i+1]!=0 ){ |
19702 | c = z[++i]; |
19703 | if( c=='a' ){ |
19704 | c = '\a'; |
19705 | }else if( c=='b' ){ |
19706 | c = '\b'; |
19707 | }else if( c=='t' ){ |
19708 | c = '\t'; |
19709 | }else if( c=='n' ){ |
19710 | c = '\n'; |
19711 | }else if( c=='v' ){ |
19712 | c = '\v'; |
19713 | }else if( c=='f' ){ |
19714 | c = '\f'; |
19715 | }else if( c=='r' ){ |
19716 | c = '\r'; |
19717 | }else if( c=='"' ){ |
19718 | c = '"'; |
19719 | }else if( c=='\'' ){ |
19720 | c = '\''; |
19721 | }else if( c=='\\' ){ |
19722 | c = '\\'; |
19723 | }else if( c>='0' && c<='7' ){ |
19724 | c -= '0'; |
19725 | if( z[i+1]>='0' && z[i+1]<='7' ){ |
19726 | i++; |
19727 | c = (c<<3) + z[i] - '0'; |
19728 | if( z[i+1]>='0' && z[i+1]<='7' ){ |
19729 | i++; |
19730 | c = (c<<3) + z[i] - '0'; |
19731 | } |
19732 | } |
19733 | } |
19734 | } |
19735 | z[j] = c; |
19736 | } |
19737 | if( j<i ) z[j] = 0; |
19738 | } |
19739 | |
19740 | /* |
19741 | ** Interpret zArg as either an integer or a boolean value. Return 1 or 0 |
19742 | ** for TRUE and FALSE. Return the integer value if appropriate. |
19743 | */ |
19744 | static int booleanValue(const char *zArg){ |
19745 | int i; |
19746 | if( zArg[0]=='0' && zArg[1]=='x' ){ |
19747 | for(i=2; hexDigitValue(zArg[i])>=0; i++){} |
19748 | }else{ |
19749 | for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} |
19750 | } |
19751 | if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff); |
19752 | if( sqlite3_stricmp(zArg, "on" )==0 || sqlite3_stricmp(zArg,"yes" )==0 ){ |
19753 | return 1; |
19754 | } |
19755 | if( sqlite3_stricmp(zArg, "off" )==0 || sqlite3_stricmp(zArg,"no" )==0 ){ |
19756 | return 0; |
19757 | } |
19758 | utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n" , |
19759 | zArg); |
19760 | return 0; |
19761 | } |
19762 | |
19763 | /* |
19764 | ** Set or clear a shell flag according to a boolean value. |
19765 | */ |
19766 | static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){ |
19767 | if( booleanValue(zArg) ){ |
19768 | ShellSetFlag(p, mFlag); |
19769 | }else{ |
19770 | ShellClearFlag(p, mFlag); |
19771 | } |
19772 | } |
19773 | |
19774 | /* |
19775 | ** Close an output file, assuming it is not stderr or stdout |
19776 | */ |
19777 | static void output_file_close(FILE *f){ |
19778 | if( f && f!=stdout && f!=stderr ) fclose(f); |
19779 | } |
19780 | |
19781 | /* |
19782 | ** Try to open an output file. The names "stdout" and "stderr" are |
19783 | ** recognized and do the right thing. NULL is returned if the output |
19784 | ** filename is "off". |
19785 | */ |
19786 | static FILE *output_file_open(const char *zFile, int bTextMode){ |
19787 | FILE *f; |
19788 | if( cli_strcmp(zFile,"stdout" )==0 ){ |
19789 | f = stdout; |
19790 | }else if( cli_strcmp(zFile, "stderr" )==0 ){ |
19791 | f = stderr; |
19792 | }else if( cli_strcmp(zFile, "off" )==0 ){ |
19793 | f = 0; |
19794 | }else{ |
19795 | f = fopen(zFile, bTextMode ? "w" : "wb" ); |
19796 | if( f==0 ){ |
19797 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , zFile); |
19798 | } |
19799 | } |
19800 | return f; |
19801 | } |
19802 | |
19803 | #ifndef SQLITE_OMIT_TRACE |
19804 | /* |
19805 | ** A routine for handling output from sqlite3_trace(). |
19806 | */ |
19807 | static int sql_trace_callback( |
19808 | unsigned mType, /* The trace type */ |
19809 | void *pArg, /* The ShellState pointer */ |
19810 | void *pP, /* Usually a pointer to sqlite_stmt */ |
19811 | void *pX /* Auxiliary output */ |
19812 | ){ |
19813 | ShellState *p = (ShellState*)pArg; |
19814 | sqlite3_stmt *pStmt; |
19815 | const char *zSql; |
19816 | i64 nSql; |
19817 | if( p->traceOut==0 ) return 0; |
19818 | if( mType==SQLITE_TRACE_CLOSE ){ |
19819 | utf8_printf(p->traceOut, "-- closing database connection\n" ); |
19820 | return 0; |
19821 | } |
19822 | if( mType!=SQLITE_TRACE_ROW && ((const char*)pX)[0]=='-' ){ |
19823 | zSql = (const char*)pX; |
19824 | }else{ |
19825 | pStmt = (sqlite3_stmt*)pP; |
19826 | switch( p->eTraceType ){ |
19827 | case SHELL_TRACE_EXPANDED: { |
19828 | zSql = sqlite3_expanded_sql(pStmt); |
19829 | break; |
19830 | } |
19831 | #ifdef SQLITE_ENABLE_NORMALIZE |
19832 | case SHELL_TRACE_NORMALIZED: { |
19833 | zSql = sqlite3_normalized_sql(pStmt); |
19834 | break; |
19835 | } |
19836 | #endif |
19837 | default: { |
19838 | zSql = sqlite3_sql(pStmt); |
19839 | break; |
19840 | } |
19841 | } |
19842 | } |
19843 | if( zSql==0 ) return 0; |
19844 | nSql = strlen(zSql); |
19845 | if( nSql>1000000000 ) nSql = 1000000000; |
19846 | while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; } |
19847 | switch( mType ){ |
19848 | case SQLITE_TRACE_ROW: |
19849 | case SQLITE_TRACE_STMT: { |
19850 | utf8_printf(p->traceOut, "%.*s;\n" , (int)nSql, zSql); |
19851 | break; |
19852 | } |
19853 | case SQLITE_TRACE_PROFILE: { |
19854 | sqlite3_int64 nNanosec = *(sqlite3_int64*)pX; |
19855 | utf8_printf(p->traceOut, "%.*s; -- %lld ns\n" , (int)nSql, zSql, nNanosec); |
19856 | break; |
19857 | } |
19858 | } |
19859 | return 0; |
19860 | } |
19861 | #endif |
19862 | |
19863 | /* |
19864 | ** A no-op routine that runs with the ".breakpoint" doc-command. This is |
19865 | ** a useful spot to set a debugger breakpoint. |
19866 | */ |
19867 | static void test_breakpoint(void){ |
19868 | static int nCall = 0; |
19869 | nCall++; |
19870 | } |
19871 | |
19872 | /* |
19873 | ** An object used to read a CSV and other files for import. |
19874 | */ |
19875 | typedef struct ImportCtx ImportCtx; |
19876 | struct ImportCtx { |
19877 | const char *zFile; /* Name of the input file */ |
19878 | FILE *in; /* Read the CSV text from this input stream */ |
19879 | int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */ |
19880 | char *z; /* Accumulated text for a field */ |
19881 | int n; /* Number of bytes in z */ |
19882 | int nAlloc; /* Space allocated for z[] */ |
19883 | int nLine; /* Current line number */ |
19884 | int nRow; /* Number of rows imported */ |
19885 | int nErr; /* Number of errors encountered */ |
19886 | int bNotFirst; /* True if one or more bytes already read */ |
19887 | int cTerm; /* Character that terminated the most recent field */ |
19888 | int cColSep; /* The column separator character. (Usually ",") */ |
19889 | int cRowSep; /* The row separator character. (Usually "\n") */ |
19890 | }; |
19891 | |
19892 | /* Clean up resourced used by an ImportCtx */ |
19893 | static void import_cleanup(ImportCtx *p){ |
19894 | if( p->in!=0 && p->xCloser!=0 ){ |
19895 | p->xCloser(p->in); |
19896 | p->in = 0; |
19897 | } |
19898 | sqlite3_free(p->z); |
19899 | p->z = 0; |
19900 | } |
19901 | |
19902 | /* Append a single byte to z[] */ |
19903 | static void import_append_char(ImportCtx *p, int c){ |
19904 | if( p->n+1>=p->nAlloc ){ |
19905 | p->nAlloc += p->nAlloc + 100; |
19906 | p->z = sqlite3_realloc64(p->z, p->nAlloc); |
19907 | shell_check_oom(p->z); |
19908 | } |
19909 | p->z[p->n++] = (char)c; |
19910 | } |
19911 | |
19912 | /* Read a single field of CSV text. Compatible with rfc4180 and extended |
19913 | ** with the option of having a separator other than ",". |
19914 | ** |
19915 | ** + Input comes from p->in. |
19916 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
19917 | ** from sqlite3_malloc64(). |
19918 | ** + Use p->cSep as the column separator. The default is ",". |
19919 | ** + Use p->rSep as the row separator. The default is "\n". |
19920 | ** + Keep track of the line number in p->nLine. |
19921 | ** + Store the character that terminates the field in p->cTerm. Store |
19922 | ** EOF on end-of-file. |
19923 | ** + Report syntax errors on stderr |
19924 | */ |
19925 | static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ |
19926 | int c; |
19927 | int cSep = p->cColSep; |
19928 | int rSep = p->cRowSep; |
19929 | p->n = 0; |
19930 | c = fgetc(p->in); |
19931 | if( c==EOF || seenInterrupt ){ |
19932 | p->cTerm = EOF; |
19933 | return 0; |
19934 | } |
19935 | if( c=='"' ){ |
19936 | int pc, ppc; |
19937 | int startLine = p->nLine; |
19938 | int cQuote = c; |
19939 | pc = ppc = 0; |
19940 | while( 1 ){ |
19941 | c = fgetc(p->in); |
19942 | if( c==rSep ) p->nLine++; |
19943 | if( c==cQuote ){ |
19944 | if( pc==cQuote ){ |
19945 | pc = 0; |
19946 | continue; |
19947 | } |
19948 | } |
19949 | if( (c==cSep && pc==cQuote) |
19950 | || (c==rSep && pc==cQuote) |
19951 | || (c==rSep && pc=='\r' && ppc==cQuote) |
19952 | || (c==EOF && pc==cQuote) |
19953 | ){ |
19954 | do{ p->n--; }while( p->z[p->n]!=cQuote ); |
19955 | p->cTerm = c; |
19956 | break; |
19957 | } |
19958 | if( pc==cQuote && c!='\r' ){ |
19959 | utf8_printf(stderr, "%s:%d: unescaped %c character\n" , |
19960 | p->zFile, p->nLine, cQuote); |
19961 | } |
19962 | if( c==EOF ){ |
19963 | utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n" , |
19964 | p->zFile, startLine, cQuote); |
19965 | p->cTerm = c; |
19966 | break; |
19967 | } |
19968 | import_append_char(p, c); |
19969 | ppc = pc; |
19970 | pc = c; |
19971 | } |
19972 | }else{ |
19973 | /* If this is the first field being parsed and it begins with the |
19974 | ** UTF-8 BOM (0xEF BB BF) then skip the BOM */ |
19975 | if( (c&0xff)==0xef && p->bNotFirst==0 ){ |
19976 | import_append_char(p, c); |
19977 | c = fgetc(p->in); |
19978 | if( (c&0xff)==0xbb ){ |
19979 | import_append_char(p, c); |
19980 | c = fgetc(p->in); |
19981 | if( (c&0xff)==0xbf ){ |
19982 | p->bNotFirst = 1; |
19983 | p->n = 0; |
19984 | return csv_read_one_field(p); |
19985 | } |
19986 | } |
19987 | } |
19988 | while( c!=EOF && c!=cSep && c!=rSep ){ |
19989 | import_append_char(p, c); |
19990 | c = fgetc(p->in); |
19991 | } |
19992 | if( c==rSep ){ |
19993 | p->nLine++; |
19994 | if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; |
19995 | } |
19996 | p->cTerm = c; |
19997 | } |
19998 | if( p->z ) p->z[p->n] = 0; |
19999 | p->bNotFirst = 1; |
20000 | return p->z; |
20001 | } |
20002 | |
20003 | /* Read a single field of ASCII delimited text. |
20004 | ** |
20005 | ** + Input comes from p->in. |
20006 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
20007 | ** from sqlite3_malloc64(). |
20008 | ** + Use p->cSep as the column separator. The default is "\x1F". |
20009 | ** + Use p->rSep as the row separator. The default is "\x1E". |
20010 | ** + Keep track of the row number in p->nLine. |
20011 | ** + Store the character that terminates the field in p->cTerm. Store |
20012 | ** EOF on end-of-file. |
20013 | ** + Report syntax errors on stderr |
20014 | */ |
20015 | static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){ |
20016 | int c; |
20017 | int cSep = p->cColSep; |
20018 | int rSep = p->cRowSep; |
20019 | p->n = 0; |
20020 | c = fgetc(p->in); |
20021 | if( c==EOF || seenInterrupt ){ |
20022 | p->cTerm = EOF; |
20023 | return 0; |
20024 | } |
20025 | while( c!=EOF && c!=cSep && c!=rSep ){ |
20026 | import_append_char(p, c); |
20027 | c = fgetc(p->in); |
20028 | } |
20029 | if( c==rSep ){ |
20030 | p->nLine++; |
20031 | } |
20032 | p->cTerm = c; |
20033 | if( p->z ) p->z[p->n] = 0; |
20034 | return p->z; |
20035 | } |
20036 | |
20037 | /* |
20038 | ** Try to transfer data for table zTable. If an error is seen while |
20039 | ** moving forward, try to go backwards. The backwards movement won't |
20040 | ** work for WITHOUT ROWID tables. |
20041 | */ |
20042 | static void tryToCloneData( |
20043 | ShellState *p, |
20044 | sqlite3 *newDb, |
20045 | const char *zTable |
20046 | ){ |
20047 | sqlite3_stmt *pQuery = 0; |
20048 | sqlite3_stmt *pInsert = 0; |
20049 | char *zQuery = 0; |
20050 | char *zInsert = 0; |
20051 | int rc; |
20052 | int i, j, n; |
20053 | int nTable = strlen30(zTable); |
20054 | int k = 0; |
20055 | int cnt = 0; |
20056 | const int spinRate = 10000; |
20057 | |
20058 | zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"" , zTable); |
20059 | shell_check_oom(zQuery); |
20060 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
20061 | if( rc ){ |
20062 | utf8_printf(stderr, "Error %d: %s on [%s]\n" , |
20063 | sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), |
20064 | zQuery); |
20065 | goto end_data_xfer; |
20066 | } |
20067 | n = sqlite3_column_count(pQuery); |
20068 | zInsert = sqlite3_malloc64(200 + nTable + n*3); |
20069 | shell_check_oom(zInsert); |
20070 | sqlite3_snprintf(200+nTable,zInsert, |
20071 | "INSERT OR IGNORE INTO \"%s\" VALUES(?" , zTable); |
20072 | i = strlen30(zInsert); |
20073 | for(j=1; j<n; j++){ |
20074 | memcpy(zInsert+i, ",?" , 2); |
20075 | i += 2; |
20076 | } |
20077 | memcpy(zInsert+i, ");" , 3); |
20078 | rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); |
20079 | if( rc ){ |
20080 | utf8_printf(stderr, "Error %d: %s on [%s]\n" , |
20081 | sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), |
20082 | zQuery); |
20083 | goto end_data_xfer; |
20084 | } |
20085 | for(k=0; k<2; k++){ |
20086 | while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ |
20087 | for(i=0; i<n; i++){ |
20088 | switch( sqlite3_column_type(pQuery, i) ){ |
20089 | case SQLITE_NULL: { |
20090 | sqlite3_bind_null(pInsert, i+1); |
20091 | break; |
20092 | } |
20093 | case SQLITE_INTEGER: { |
20094 | sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i)); |
20095 | break; |
20096 | } |
20097 | case SQLITE_FLOAT: { |
20098 | sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i)); |
20099 | break; |
20100 | } |
20101 | case SQLITE_TEXT: { |
20102 | sqlite3_bind_text(pInsert, i+1, |
20103 | (const char*)sqlite3_column_text(pQuery,i), |
20104 | -1, SQLITE_STATIC); |
20105 | break; |
20106 | } |
20107 | case SQLITE_BLOB: { |
20108 | sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i), |
20109 | sqlite3_column_bytes(pQuery,i), |
20110 | SQLITE_STATIC); |
20111 | break; |
20112 | } |
20113 | } |
20114 | } /* End for */ |
20115 | rc = sqlite3_step(pInsert); |
20116 | if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ |
20117 | utf8_printf(stderr, "Error %d: %s\n" , sqlite3_extended_errcode(newDb), |
20118 | sqlite3_errmsg(newDb)); |
20119 | } |
20120 | sqlite3_reset(pInsert); |
20121 | cnt++; |
20122 | if( (cnt%spinRate)==0 ){ |
20123 | printf("%c\b" , "|/-\\" [(cnt/spinRate)%4]); |
20124 | fflush(stdout); |
20125 | } |
20126 | } /* End while */ |
20127 | if( rc==SQLITE_DONE ) break; |
20128 | sqlite3_finalize(pQuery); |
20129 | sqlite3_free(zQuery); |
20130 | zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;" , |
20131 | zTable); |
20132 | shell_check_oom(zQuery); |
20133 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
20134 | if( rc ){ |
20135 | utf8_printf(stderr, "Warning: cannot step \"%s\" backwards" , zTable); |
20136 | break; |
20137 | } |
20138 | } /* End for(k=0...) */ |
20139 | |
20140 | end_data_xfer: |
20141 | sqlite3_finalize(pQuery); |
20142 | sqlite3_finalize(pInsert); |
20143 | sqlite3_free(zQuery); |
20144 | sqlite3_free(zInsert); |
20145 | } |
20146 | |
20147 | |
20148 | /* |
20149 | ** Try to transfer all rows of the schema that match zWhere. For |
20150 | ** each row, invoke xForEach() on the object defined by that row. |
20151 | ** If an error is encountered while moving forward through the |
20152 | ** sqlite_schema table, try again moving backwards. |
20153 | */ |
20154 | static void tryToCloneSchema( |
20155 | ShellState *p, |
20156 | sqlite3 *newDb, |
20157 | const char *zWhere, |
20158 | void (*xForEach)(ShellState*,sqlite3*,const char*) |
20159 | ){ |
20160 | sqlite3_stmt *pQuery = 0; |
20161 | char *zQuery = 0; |
20162 | int rc; |
20163 | const unsigned char *zName; |
20164 | const unsigned char *zSql; |
20165 | char *zErrMsg = 0; |
20166 | |
20167 | zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema" |
20168 | " WHERE %s" , zWhere); |
20169 | shell_check_oom(zQuery); |
20170 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
20171 | if( rc ){ |
20172 | utf8_printf(stderr, "Error: (%d) %s on [%s]\n" , |
20173 | sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), |
20174 | zQuery); |
20175 | goto end_schema_xfer; |
20176 | } |
20177 | while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ |
20178 | zName = sqlite3_column_text(pQuery, 0); |
20179 | zSql = sqlite3_column_text(pQuery, 1); |
20180 | if( zName==0 || zSql==0 ) continue; |
20181 | printf("%s... " , zName); fflush(stdout); |
20182 | sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); |
20183 | if( zErrMsg ){ |
20184 | utf8_printf(stderr, "Error: %s\nSQL: [%s]\n" , zErrMsg, zSql); |
20185 | sqlite3_free(zErrMsg); |
20186 | zErrMsg = 0; |
20187 | } |
20188 | if( xForEach ){ |
20189 | xForEach(p, newDb, (const char*)zName); |
20190 | } |
20191 | printf("done\n" ); |
20192 | } |
20193 | if( rc!=SQLITE_DONE ){ |
20194 | sqlite3_finalize(pQuery); |
20195 | sqlite3_free(zQuery); |
20196 | zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema" |
20197 | " WHERE %s ORDER BY rowid DESC" , zWhere); |
20198 | shell_check_oom(zQuery); |
20199 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
20200 | if( rc ){ |
20201 | utf8_printf(stderr, "Error: (%d) %s on [%s]\n" , |
20202 | sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), |
20203 | zQuery); |
20204 | goto end_schema_xfer; |
20205 | } |
20206 | while( sqlite3_step(pQuery)==SQLITE_ROW ){ |
20207 | zName = sqlite3_column_text(pQuery, 0); |
20208 | zSql = sqlite3_column_text(pQuery, 1); |
20209 | if( zName==0 || zSql==0 ) continue; |
20210 | printf("%s... " , zName); fflush(stdout); |
20211 | sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); |
20212 | if( zErrMsg ){ |
20213 | utf8_printf(stderr, "Error: %s\nSQL: [%s]\n" , zErrMsg, zSql); |
20214 | sqlite3_free(zErrMsg); |
20215 | zErrMsg = 0; |
20216 | } |
20217 | if( xForEach ){ |
20218 | xForEach(p, newDb, (const char*)zName); |
20219 | } |
20220 | printf("done\n" ); |
20221 | } |
20222 | } |
20223 | end_schema_xfer: |
20224 | sqlite3_finalize(pQuery); |
20225 | sqlite3_free(zQuery); |
20226 | } |
20227 | |
20228 | /* |
20229 | ** Open a new database file named "zNewDb". Try to recover as much information |
20230 | ** as possible out of the main database (which might be corrupt) and write it |
20231 | ** into zNewDb. |
20232 | */ |
20233 | static void tryToClone(ShellState *p, const char *zNewDb){ |
20234 | int rc; |
20235 | sqlite3 *newDb = 0; |
20236 | if( access(zNewDb,0)==0 ){ |
20237 | utf8_printf(stderr, "File \"%s\" already exists.\n" , zNewDb); |
20238 | return; |
20239 | } |
20240 | rc = sqlite3_open(zNewDb, &newDb); |
20241 | if( rc ){ |
20242 | utf8_printf(stderr, "Cannot create output database: %s\n" , |
20243 | sqlite3_errmsg(newDb)); |
20244 | }else{ |
20245 | sqlite3_exec(p->db, "PRAGMA writable_schema=ON;" , 0, 0, 0); |
20246 | sqlite3_exec(newDb, "BEGIN EXCLUSIVE;" , 0, 0, 0); |
20247 | tryToCloneSchema(p, newDb, "type='table'" , tryToCloneData); |
20248 | tryToCloneSchema(p, newDb, "type!='table'" , 0); |
20249 | sqlite3_exec(newDb, "COMMIT;" , 0, 0, 0); |
20250 | sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;" , 0, 0, 0); |
20251 | } |
20252 | close_db(newDb); |
20253 | } |
20254 | |
20255 | /* |
20256 | ** Change the output file back to stdout. |
20257 | ** |
20258 | ** If the p->doXdgOpen flag is set, that means the output was being |
20259 | ** redirected to a temporary file named by p->zTempFile. In that case, |
20260 | ** launch start/open/xdg-open on that temporary file. |
20261 | */ |
20262 | static void output_reset(ShellState *p){ |
20263 | if( p->outfile[0]=='|' ){ |
20264 | #ifndef SQLITE_OMIT_POPEN |
20265 | pclose(p->out); |
20266 | #endif |
20267 | }else{ |
20268 | output_file_close(p->out); |
20269 | #ifndef SQLITE_NOHAVE_SYSTEM |
20270 | if( p->doXdgOpen ){ |
20271 | const char *zXdgOpenCmd = |
20272 | #if defined(_WIN32) |
20273 | "start" ; |
20274 | #elif defined(__APPLE__) |
20275 | "open" ; |
20276 | #else |
20277 | "xdg-open" ; |
20278 | #endif |
20279 | char *zCmd; |
20280 | zCmd = sqlite3_mprintf("%s %s" , zXdgOpenCmd, p->zTempFile); |
20281 | if( system(zCmd) ){ |
20282 | utf8_printf(stderr, "Failed: [%s]\n" , zCmd); |
20283 | }else{ |
20284 | /* Give the start/open/xdg-open command some time to get |
20285 | ** going before we continue, and potential delete the |
20286 | ** p->zTempFile data file out from under it */ |
20287 | sqlite3_sleep(2000); |
20288 | } |
20289 | sqlite3_free(zCmd); |
20290 | outputModePop(p); |
20291 | p->doXdgOpen = 0; |
20292 | } |
20293 | #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ |
20294 | } |
20295 | p->outfile[0] = 0; |
20296 | p->out = stdout; |
20297 | } |
20298 | |
20299 | /* |
20300 | ** Run an SQL command and return the single integer result. |
20301 | */ |
20302 | static int db_int(sqlite3 *db, const char *zSql){ |
20303 | sqlite3_stmt *pStmt; |
20304 | int res = 0; |
20305 | sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
20306 | if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ |
20307 | res = sqlite3_column_int(pStmt,0); |
20308 | } |
20309 | sqlite3_finalize(pStmt); |
20310 | return res; |
20311 | } |
20312 | |
20313 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) |
20314 | /* |
20315 | ** Convert a 2-byte or 4-byte big-endian integer into a native integer |
20316 | */ |
20317 | static unsigned int get2byteInt(unsigned char *a){ |
20318 | return (a[0]<<8) + a[1]; |
20319 | } |
20320 | static unsigned int get4byteInt(unsigned char *a){ |
20321 | return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; |
20322 | } |
20323 | |
20324 | /* |
20325 | ** Implementation of the ".dbinfo" command. |
20326 | ** |
20327 | ** Return 1 on error, 2 to exit, and 0 otherwise. |
20328 | */ |
20329 | static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ |
20330 | static const struct { const char *zName; int ofst; } aField[] = { |
20331 | { "file change counter:" , 24 }, |
20332 | { "database page count:" , 28 }, |
20333 | { "freelist page count:" , 36 }, |
20334 | { "schema cookie:" , 40 }, |
20335 | { "schema format:" , 44 }, |
20336 | { "default cache size:" , 48 }, |
20337 | { "autovacuum top root:" , 52 }, |
20338 | { "incremental vacuum:" , 64 }, |
20339 | { "text encoding:" , 56 }, |
20340 | { "user version:" , 60 }, |
20341 | { "application id:" , 68 }, |
20342 | { "software version:" , 96 }, |
20343 | }; |
20344 | static const struct { const char *zName; const char *zSql; } aQuery[] = { |
20345 | { "number of tables:" , |
20346 | "SELECT count(*) FROM %s WHERE type='table'" }, |
20347 | { "number of indexes:" , |
20348 | "SELECT count(*) FROM %s WHERE type='index'" }, |
20349 | { "number of triggers:" , |
20350 | "SELECT count(*) FROM %s WHERE type='trigger'" }, |
20351 | { "number of views:" , |
20352 | "SELECT count(*) FROM %s WHERE type='view'" }, |
20353 | { "schema size:" , |
20354 | "SELECT total(length(sql)) FROM %s" }, |
20355 | }; |
20356 | int i, rc; |
20357 | unsigned iDataVersion; |
20358 | char *zSchemaTab; |
20359 | char *zDb = nArg>=2 ? azArg[1] : "main" ; |
20360 | sqlite3_stmt *pStmt = 0; |
20361 | unsigned char aHdr[100]; |
20362 | open_db(p, 0); |
20363 | if( p->db==0 ) return 1; |
20364 | rc = sqlite3_prepare_v2(p->db, |
20365 | "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1" , |
20366 | -1, &pStmt, 0); |
20367 | if( rc ){ |
20368 | utf8_printf(stderr, "error: %s\n" , sqlite3_errmsg(p->db)); |
20369 | sqlite3_finalize(pStmt); |
20370 | return 1; |
20371 | } |
20372 | sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC); |
20373 | if( sqlite3_step(pStmt)==SQLITE_ROW |
20374 | && sqlite3_column_bytes(pStmt,0)>100 |
20375 | ){ |
20376 | memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100); |
20377 | sqlite3_finalize(pStmt); |
20378 | }else{ |
20379 | raw_printf(stderr, "unable to read database header\n" ); |
20380 | sqlite3_finalize(pStmt); |
20381 | return 1; |
20382 | } |
20383 | i = get2byteInt(aHdr+16); |
20384 | if( i==1 ) i = 65536; |
20385 | utf8_printf(p->out, "%-20s %d\n" , "database page size:" , i); |
20386 | utf8_printf(p->out, "%-20s %d\n" , "write format:" , aHdr[18]); |
20387 | utf8_printf(p->out, "%-20s %d\n" , "read format:" , aHdr[19]); |
20388 | utf8_printf(p->out, "%-20s %d\n" , "reserved bytes:" , aHdr[20]); |
20389 | for(i=0; i<ArraySize(aField); i++){ |
20390 | int ofst = aField[i].ofst; |
20391 | unsigned int val = get4byteInt(aHdr + ofst); |
20392 | utf8_printf(p->out, "%-20s %u" , aField[i].zName, val); |
20393 | switch( ofst ){ |
20394 | case 56: { |
20395 | if( val==1 ) raw_printf(p->out, " (utf8)" ); |
20396 | if( val==2 ) raw_printf(p->out, " (utf16le)" ); |
20397 | if( val==3 ) raw_printf(p->out, " (utf16be)" ); |
20398 | } |
20399 | } |
20400 | raw_printf(p->out, "\n" ); |
20401 | } |
20402 | if( zDb==0 ){ |
20403 | zSchemaTab = sqlite3_mprintf("main.sqlite_schema" ); |
20404 | }else if( cli_strcmp(zDb,"temp" )==0 ){ |
20405 | zSchemaTab = sqlite3_mprintf("%s" , "sqlite_temp_schema" ); |
20406 | }else{ |
20407 | zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema" , zDb); |
20408 | } |
20409 | for(i=0; i<ArraySize(aQuery); i++){ |
20410 | char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); |
20411 | int val = db_int(p->db, zSql); |
20412 | sqlite3_free(zSql); |
20413 | utf8_printf(p->out, "%-20s %d\n" , aQuery[i].zName, val); |
20414 | } |
20415 | sqlite3_free(zSchemaTab); |
20416 | sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion); |
20417 | utf8_printf(p->out, "%-20s %u\n" , "data version" , iDataVersion); |
20418 | return 0; |
20419 | } |
20420 | #endif /* SQLITE_SHELL_HAVE_RECOVER */ |
20421 | |
20422 | /* |
20423 | ** Print the current sqlite3_errmsg() value to stderr and return 1. |
20424 | */ |
20425 | static int shellDatabaseError(sqlite3 *db){ |
20426 | const char *zErr = sqlite3_errmsg(db); |
20427 | utf8_printf(stderr, "Error: %s\n" , zErr); |
20428 | return 1; |
20429 | } |
20430 | |
20431 | /* |
20432 | ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE |
20433 | ** if they match and FALSE (0) if they do not match. |
20434 | ** |
20435 | ** Globbing rules: |
20436 | ** |
20437 | ** '*' Matches any sequence of zero or more characters. |
20438 | ** |
20439 | ** '?' Matches exactly one character. |
20440 | ** |
20441 | ** [...] Matches one character from the enclosed list of |
20442 | ** characters. |
20443 | ** |
20444 | ** [^...] Matches one character not in the enclosed list. |
20445 | ** |
20446 | ** '#' Matches any sequence of one or more digits with an |
20447 | ** optional + or - sign in front |
20448 | ** |
20449 | ** ' ' Any span of whitespace matches any other span of |
20450 | ** whitespace. |
20451 | ** |
20452 | ** Extra whitespace at the end of z[] is ignored. |
20453 | */ |
20454 | static int testcase_glob(const char *zGlob, const char *z){ |
20455 | int c, c2; |
20456 | int invert; |
20457 | int seen; |
20458 | |
20459 | while( (c = (*(zGlob++)))!=0 ){ |
20460 | if( IsSpace(c) ){ |
20461 | if( !IsSpace(*z) ) return 0; |
20462 | while( IsSpace(*zGlob) ) zGlob++; |
20463 | while( IsSpace(*z) ) z++; |
20464 | }else if( c=='*' ){ |
20465 | while( (c=(*(zGlob++))) == '*' || c=='?' ){ |
20466 | if( c=='?' && (*(z++))==0 ) return 0; |
20467 | } |
20468 | if( c==0 ){ |
20469 | return 1; |
20470 | }else if( c=='[' ){ |
20471 | while( *z && testcase_glob(zGlob-1,z)==0 ){ |
20472 | z++; |
20473 | } |
20474 | return (*z)!=0; |
20475 | } |
20476 | while( (c2 = (*(z++)))!=0 ){ |
20477 | while( c2!=c ){ |
20478 | c2 = *(z++); |
20479 | if( c2==0 ) return 0; |
20480 | } |
20481 | if( testcase_glob(zGlob,z) ) return 1; |
20482 | } |
20483 | return 0; |
20484 | }else if( c=='?' ){ |
20485 | if( (*(z++))==0 ) return 0; |
20486 | }else if( c=='[' ){ |
20487 | int prior_c = 0; |
20488 | seen = 0; |
20489 | invert = 0; |
20490 | c = *(z++); |
20491 | if( c==0 ) return 0; |
20492 | c2 = *(zGlob++); |
20493 | if( c2=='^' ){ |
20494 | invert = 1; |
20495 | c2 = *(zGlob++); |
20496 | } |
20497 | if( c2==']' ){ |
20498 | if( c==']' ) seen = 1; |
20499 | c2 = *(zGlob++); |
20500 | } |
20501 | while( c2 && c2!=']' ){ |
20502 | if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ |
20503 | c2 = *(zGlob++); |
20504 | if( c>=prior_c && c<=c2 ) seen = 1; |
20505 | prior_c = 0; |
20506 | }else{ |
20507 | if( c==c2 ){ |
20508 | seen = 1; |
20509 | } |
20510 | prior_c = c2; |
20511 | } |
20512 | c2 = *(zGlob++); |
20513 | } |
20514 | if( c2==0 || (seen ^ invert)==0 ) return 0; |
20515 | }else if( c=='#' ){ |
20516 | if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++; |
20517 | if( !IsDigit(z[0]) ) return 0; |
20518 | z++; |
20519 | while( IsDigit(z[0]) ){ z++; } |
20520 | }else{ |
20521 | if( c!=(*(z++)) ) return 0; |
20522 | } |
20523 | } |
20524 | while( IsSpace(*z) ){ z++; } |
20525 | return *z==0; |
20526 | } |
20527 | |
20528 | |
20529 | /* |
20530 | ** Compare the string as a command-line option with either one or two |
20531 | ** initial "-" characters. |
20532 | */ |
20533 | static int optionMatch(const char *zStr, const char *zOpt){ |
20534 | if( zStr[0]!='-' ) return 0; |
20535 | zStr++; |
20536 | if( zStr[0]=='-' ) zStr++; |
20537 | return cli_strcmp(zStr, zOpt)==0; |
20538 | } |
20539 | |
20540 | /* |
20541 | ** Delete a file. |
20542 | */ |
20543 | int shellDeleteFile(const char *zFilename){ |
20544 | int rc; |
20545 | #ifdef _WIN32 |
20546 | wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename); |
20547 | rc = _wunlink(z); |
20548 | sqlite3_free(z); |
20549 | #else |
20550 | rc = unlink(zFilename); |
20551 | #endif |
20552 | return rc; |
20553 | } |
20554 | |
20555 | /* |
20556 | ** Try to delete the temporary file (if there is one) and free the |
20557 | ** memory used to hold the name of the temp file. |
20558 | */ |
20559 | static void clearTempFile(ShellState *p){ |
20560 | if( p->zTempFile==0 ) return; |
20561 | if( p->doXdgOpen ) return; |
20562 | if( shellDeleteFile(p->zTempFile) ) return; |
20563 | sqlite3_free(p->zTempFile); |
20564 | p->zTempFile = 0; |
20565 | } |
20566 | |
20567 | /* |
20568 | ** Create a new temp file name with the given suffix. |
20569 | */ |
20570 | static void newTempFile(ShellState *p, const char *zSuffix){ |
20571 | clearTempFile(p); |
20572 | sqlite3_free(p->zTempFile); |
20573 | p->zTempFile = 0; |
20574 | if( p->db ){ |
20575 | sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile); |
20576 | } |
20577 | if( p->zTempFile==0 ){ |
20578 | /* If p->db is an in-memory database then the TEMPFILENAME file-control |
20579 | ** will not work and we will need to fallback to guessing */ |
20580 | char *zTemp; |
20581 | sqlite3_uint64 r; |
20582 | sqlite3_randomness(sizeof(r), &r); |
20583 | zTemp = getenv("TEMP" ); |
20584 | if( zTemp==0 ) zTemp = getenv("TMP" ); |
20585 | if( zTemp==0 ){ |
20586 | #ifdef _WIN32 |
20587 | zTemp = "\\tmp" ; |
20588 | #else |
20589 | zTemp = "/tmp" ; |
20590 | #endif |
20591 | } |
20592 | p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s" , zTemp, r, zSuffix); |
20593 | }else{ |
20594 | p->zTempFile = sqlite3_mprintf("%z.%s" , p->zTempFile, zSuffix); |
20595 | } |
20596 | shell_check_oom(p->zTempFile); |
20597 | } |
20598 | |
20599 | |
20600 | /* |
20601 | ** The implementation of SQL scalar function fkey_collate_clause(), used |
20602 | ** by the ".lint fkey-indexes" command. This scalar function is always |
20603 | ** called with four arguments - the parent table name, the parent column name, |
20604 | ** the child table name and the child column name. |
20605 | ** |
20606 | ** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col') |
20607 | ** |
20608 | ** If either of the named tables or columns do not exist, this function |
20609 | ** returns an empty string. An empty string is also returned if both tables |
20610 | ** and columns exist but have the same default collation sequence. Or, |
20611 | ** if both exist but the default collation sequences are different, this |
20612 | ** function returns the string " COLLATE <parent-collation>", where |
20613 | ** <parent-collation> is the default collation sequence of the parent column. |
20614 | */ |
20615 | static void shellFkeyCollateClause( |
20616 | sqlite3_context *pCtx, |
20617 | int nVal, |
20618 | sqlite3_value **apVal |
20619 | ){ |
20620 | sqlite3 *db = sqlite3_context_db_handle(pCtx); |
20621 | const char *zParent; |
20622 | const char *zParentCol; |
20623 | const char *zParentSeq; |
20624 | const char *zChild; |
20625 | const char *zChildCol; |
20626 | const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */ |
20627 | int rc; |
20628 | |
20629 | assert( nVal==4 ); |
20630 | zParent = (const char*)sqlite3_value_text(apVal[0]); |
20631 | zParentCol = (const char*)sqlite3_value_text(apVal[1]); |
20632 | zChild = (const char*)sqlite3_value_text(apVal[2]); |
20633 | zChildCol = (const char*)sqlite3_value_text(apVal[3]); |
20634 | |
20635 | sqlite3_result_text(pCtx, "" , -1, SQLITE_STATIC); |
20636 | rc = sqlite3_table_column_metadata( |
20637 | db, "main" , zParent, zParentCol, 0, &zParentSeq, 0, 0, 0 |
20638 | ); |
20639 | if( rc==SQLITE_OK ){ |
20640 | rc = sqlite3_table_column_metadata( |
20641 | db, "main" , zChild, zChildCol, 0, &zChildSeq, 0, 0, 0 |
20642 | ); |
20643 | } |
20644 | |
20645 | if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){ |
20646 | char *z = sqlite3_mprintf(" COLLATE %s" , zParentSeq); |
20647 | sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); |
20648 | sqlite3_free(z); |
20649 | } |
20650 | } |
20651 | |
20652 | |
20653 | /* |
20654 | ** The implementation of dot-command ".lint fkey-indexes". |
20655 | */ |
20656 | static int lintFkeyIndexes( |
20657 | ShellState *pState, /* Current shell tool state */ |
20658 | char **azArg, /* Array of arguments passed to dot command */ |
20659 | int nArg /* Number of entries in azArg[] */ |
20660 | ){ |
20661 | sqlite3 *db = pState->db; /* Database handle to query "main" db of */ |
20662 | FILE *out = pState->out; /* Stream to write non-error output to */ |
20663 | int bVerbose = 0; /* If -verbose is present */ |
20664 | int bGroupByParent = 0; /* If -groupbyparent is present */ |
20665 | int i; /* To iterate through azArg[] */ |
20666 | const char *zIndent = "" ; /* How much to indent CREATE INDEX by */ |
20667 | int rc; /* Return code */ |
20668 | sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ |
20669 | |
20670 | /* |
20671 | ** This SELECT statement returns one row for each foreign key constraint |
20672 | ** in the schema of the main database. The column values are: |
20673 | ** |
20674 | ** 0. The text of an SQL statement similar to: |
20675 | ** |
20676 | ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?" |
20677 | ** |
20678 | ** This SELECT is similar to the one that the foreign keys implementation |
20679 | ** needs to run internally on child tables. If there is an index that can |
20680 | ** be used to optimize this query, then it can also be used by the FK |
20681 | ** implementation to optimize DELETE or UPDATE statements on the parent |
20682 | ** table. |
20683 | ** |
20684 | ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by |
20685 | ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema |
20686 | ** contains an index that can be used to optimize the query. |
20687 | ** |
20688 | ** 2. Human readable text that describes the child table and columns. e.g. |
20689 | ** |
20690 | ** "child_table(child_key1, child_key2)" |
20691 | ** |
20692 | ** 3. Human readable text that describes the parent table and columns. e.g. |
20693 | ** |
20694 | ** "parent_table(parent_key1, parent_key2)" |
20695 | ** |
20696 | ** 4. A full CREATE INDEX statement for an index that could be used to |
20697 | ** optimize DELETE or UPDATE statements on the parent table. e.g. |
20698 | ** |
20699 | ** "CREATE INDEX child_table_child_key ON child_table(child_key)" |
20700 | ** |
20701 | ** 5. The name of the parent table. |
20702 | ** |
20703 | ** These six values are used by the C logic below to generate the report. |
20704 | */ |
20705 | const char *zSql = |
20706 | "SELECT " |
20707 | " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '" |
20708 | " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " |
20709 | " || fkey_collate_clause(" |
20710 | " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" |
20711 | ", " |
20712 | " 'SEARCH ' || s.name || ' USING COVERING INDEX*('" |
20713 | " || group_concat('*=?', ' AND ') || ')'" |
20714 | ", " |
20715 | " s.name || '(' || group_concat(f.[from], ', ') || ')'" |
20716 | ", " |
20717 | " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'" |
20718 | ", " |
20719 | " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))" |
20720 | " || ' ON ' || quote(s.name) || '('" |
20721 | " || group_concat(quote(f.[from]) ||" |
20722 | " fkey_collate_clause(" |
20723 | " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')" |
20724 | " || ');'" |
20725 | ", " |
20726 | " f.[table] " |
20727 | "FROM sqlite_schema AS s, pragma_foreign_key_list(s.name) AS f " |
20728 | "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) " |
20729 | "GROUP BY s.name, f.id " |
20730 | "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" |
20731 | ; |
20732 | const char *zGlobIPK = "SEARCH * USING INTEGER PRIMARY KEY (rowid=?)" ; |
20733 | |
20734 | for(i=2; i<nArg; i++){ |
20735 | int n = strlen30(azArg[i]); |
20736 | if( n>1 && sqlite3_strnicmp("-verbose" , azArg[i], n)==0 ){ |
20737 | bVerbose = 1; |
20738 | } |
20739 | else if( n>1 && sqlite3_strnicmp("-groupbyparent" , azArg[i], n)==0 ){ |
20740 | bGroupByParent = 1; |
20741 | zIndent = " " ; |
20742 | } |
20743 | else{ |
20744 | raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n" , |
20745 | azArg[0], azArg[1] |
20746 | ); |
20747 | return SQLITE_ERROR; |
20748 | } |
20749 | } |
20750 | |
20751 | /* Register the fkey_collate_clause() SQL function */ |
20752 | rc = sqlite3_create_function(db, "fkey_collate_clause" , 4, SQLITE_UTF8, |
20753 | 0, shellFkeyCollateClause, 0, 0 |
20754 | ); |
20755 | |
20756 | |
20757 | if( rc==SQLITE_OK ){ |
20758 | rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); |
20759 | } |
20760 | if( rc==SQLITE_OK ){ |
20761 | sqlite3_bind_int(pSql, 1, bGroupByParent); |
20762 | } |
20763 | |
20764 | if( rc==SQLITE_OK ){ |
20765 | int rc2; |
20766 | char *zPrev = 0; |
20767 | while( SQLITE_ROW==sqlite3_step(pSql) ){ |
20768 | int res = -1; |
20769 | sqlite3_stmt *pExplain = 0; |
20770 | const char *zEQP = (const char*)sqlite3_column_text(pSql, 0); |
20771 | const char *zGlob = (const char*)sqlite3_column_text(pSql, 1); |
20772 | const char *zFrom = (const char*)sqlite3_column_text(pSql, 2); |
20773 | const char *zTarget = (const char*)sqlite3_column_text(pSql, 3); |
20774 | const char *zCI = (const char*)sqlite3_column_text(pSql, 4); |
20775 | const char *zParent = (const char*)sqlite3_column_text(pSql, 5); |
20776 | |
20777 | if( zEQP==0 ) continue; |
20778 | if( zGlob==0 ) continue; |
20779 | rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); |
20780 | if( rc!=SQLITE_OK ) break; |
20781 | if( SQLITE_ROW==sqlite3_step(pExplain) ){ |
20782 | const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3); |
20783 | res = zPlan!=0 && ( 0==sqlite3_strglob(zGlob, zPlan) |
20784 | || 0==sqlite3_strglob(zGlobIPK, zPlan)); |
20785 | } |
20786 | rc = sqlite3_finalize(pExplain); |
20787 | if( rc!=SQLITE_OK ) break; |
20788 | |
20789 | if( res<0 ){ |
20790 | raw_printf(stderr, "Error: internal error" ); |
20791 | break; |
20792 | }else{ |
20793 | if( bGroupByParent |
20794 | && (bVerbose || res==0) |
20795 | && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) |
20796 | ){ |
20797 | raw_printf(out, "-- Parent table %s\n" , zParent); |
20798 | sqlite3_free(zPrev); |
20799 | zPrev = sqlite3_mprintf("%s" , zParent); |
20800 | } |
20801 | |
20802 | if( res==0 ){ |
20803 | raw_printf(out, "%s%s --> %s\n" , zIndent, zCI, zTarget); |
20804 | }else if( bVerbose ){ |
20805 | raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n" , |
20806 | zIndent, zFrom, zTarget |
20807 | ); |
20808 | } |
20809 | } |
20810 | } |
20811 | sqlite3_free(zPrev); |
20812 | |
20813 | if( rc!=SQLITE_OK ){ |
20814 | raw_printf(stderr, "%s\n" , sqlite3_errmsg(db)); |
20815 | } |
20816 | |
20817 | rc2 = sqlite3_finalize(pSql); |
20818 | if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ |
20819 | rc = rc2; |
20820 | raw_printf(stderr, "%s\n" , sqlite3_errmsg(db)); |
20821 | } |
20822 | }else{ |
20823 | raw_printf(stderr, "%s\n" , sqlite3_errmsg(db)); |
20824 | } |
20825 | |
20826 | return rc; |
20827 | } |
20828 | |
20829 | /* |
20830 | ** Implementation of ".lint" dot command. |
20831 | */ |
20832 | static int lintDotCommand( |
20833 | ShellState *pState, /* Current shell tool state */ |
20834 | char **azArg, /* Array of arguments passed to dot command */ |
20835 | int nArg /* Number of entries in azArg[] */ |
20836 | ){ |
20837 | int n; |
20838 | n = (nArg>=2 ? strlen30(azArg[1]) : 0); |
20839 | if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes" , n) ) goto usage; |
20840 | return lintFkeyIndexes(pState, azArg, nArg); |
20841 | |
20842 | usage: |
20843 | raw_printf(stderr, "Usage %s sub-command ?switches...?\n" , azArg[0]); |
20844 | raw_printf(stderr, "Where sub-commands are:\n" ); |
20845 | raw_printf(stderr, " fkey-indexes\n" ); |
20846 | return SQLITE_ERROR; |
20847 | } |
20848 | |
20849 | #if !defined SQLITE_OMIT_VIRTUALTABLE |
20850 | static void shellPrepare( |
20851 | sqlite3 *db, |
20852 | int *pRc, |
20853 | const char *zSql, |
20854 | sqlite3_stmt **ppStmt |
20855 | ){ |
20856 | *ppStmt = 0; |
20857 | if( *pRc==SQLITE_OK ){ |
20858 | int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); |
20859 | if( rc!=SQLITE_OK ){ |
20860 | raw_printf(stderr, "sql error: %s (%d)\n" , |
20861 | sqlite3_errmsg(db), sqlite3_errcode(db) |
20862 | ); |
20863 | *pRc = rc; |
20864 | } |
20865 | } |
20866 | } |
20867 | |
20868 | /* |
20869 | ** Create a prepared statement using printf-style arguments for the SQL. |
20870 | ** |
20871 | ** This routine is could be marked "static". But it is not always used, |
20872 | ** depending on compile-time options. By omitting the "static", we avoid |
20873 | ** nuisance compiler warnings about "defined but not used". |
20874 | */ |
20875 | void shellPreparePrintf( |
20876 | sqlite3 *db, |
20877 | int *pRc, |
20878 | sqlite3_stmt **ppStmt, |
20879 | const char *zFmt, |
20880 | ... |
20881 | ){ |
20882 | *ppStmt = 0; |
20883 | if( *pRc==SQLITE_OK ){ |
20884 | va_list ap; |
20885 | char *z; |
20886 | va_start(ap, zFmt); |
20887 | z = sqlite3_vmprintf(zFmt, ap); |
20888 | va_end(ap); |
20889 | if( z==0 ){ |
20890 | *pRc = SQLITE_NOMEM; |
20891 | }else{ |
20892 | shellPrepare(db, pRc, z, ppStmt); |
20893 | sqlite3_free(z); |
20894 | } |
20895 | } |
20896 | } |
20897 | |
20898 | /* Finalize the prepared statement created using shellPreparePrintf(). |
20899 | ** |
20900 | ** This routine is could be marked "static". But it is not always used, |
20901 | ** depending on compile-time options. By omitting the "static", we avoid |
20902 | ** nuisance compiler warnings about "defined but not used". |
20903 | */ |
20904 | void shellFinalize( |
20905 | int *pRc, |
20906 | sqlite3_stmt *pStmt |
20907 | ){ |
20908 | if( pStmt ){ |
20909 | sqlite3 *db = sqlite3_db_handle(pStmt); |
20910 | int rc = sqlite3_finalize(pStmt); |
20911 | if( *pRc==SQLITE_OK ){ |
20912 | if( rc!=SQLITE_OK ){ |
20913 | raw_printf(stderr, "SQL error: %s\n" , sqlite3_errmsg(db)); |
20914 | } |
20915 | *pRc = rc; |
20916 | } |
20917 | } |
20918 | } |
20919 | |
20920 | /* Reset the prepared statement created using shellPreparePrintf(). |
20921 | ** |
20922 | ** This routine is could be marked "static". But it is not always used, |
20923 | ** depending on compile-time options. By omitting the "static", we avoid |
20924 | ** nuisance compiler warnings about "defined but not used". |
20925 | */ |
20926 | void shellReset( |
20927 | int *pRc, |
20928 | sqlite3_stmt *pStmt |
20929 | ){ |
20930 | int rc = sqlite3_reset(pStmt); |
20931 | if( *pRc==SQLITE_OK ){ |
20932 | if( rc!=SQLITE_OK ){ |
20933 | sqlite3 *db = sqlite3_db_handle(pStmt); |
20934 | raw_printf(stderr, "SQL error: %s\n" , sqlite3_errmsg(db)); |
20935 | } |
20936 | *pRc = rc; |
20937 | } |
20938 | } |
20939 | #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */ |
20940 | |
20941 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
20942 | /****************************************************************************** |
20943 | ** The ".archive" or ".ar" command. |
20944 | */ |
20945 | /* |
20946 | ** Structure representing a single ".ar" command. |
20947 | */ |
20948 | typedef struct ArCommand ArCommand; |
20949 | struct ArCommand { |
20950 | u8 eCmd; /* An AR_CMD_* value */ |
20951 | u8 bVerbose; /* True if --verbose */ |
20952 | u8 bZip; /* True if the archive is a ZIP */ |
20953 | u8 bDryRun; /* True if --dry-run */ |
20954 | u8 bAppend; /* True if --append */ |
20955 | u8 bGlob; /* True if --glob */ |
20956 | u8 fromCmdLine; /* Run from -A instead of .archive */ |
20957 | int nArg; /* Number of command arguments */ |
20958 | char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */ |
20959 | const char *zFile; /* --file argument, or NULL */ |
20960 | const char *zDir; /* --directory argument, or NULL */ |
20961 | char **azArg; /* Array of command arguments */ |
20962 | ShellState *p; /* Shell state */ |
20963 | sqlite3 *db; /* Database containing the archive */ |
20964 | }; |
20965 | |
20966 | /* |
20967 | ** Print a usage message for the .ar command to stderr and return SQLITE_ERROR. |
20968 | */ |
20969 | static int arUsage(FILE *f){ |
20970 | showHelp(f,"archive" ); |
20971 | return SQLITE_ERROR; |
20972 | } |
20973 | |
20974 | /* |
20975 | ** Print an error message for the .ar command to stderr and return |
20976 | ** SQLITE_ERROR. |
20977 | */ |
20978 | static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){ |
20979 | va_list ap; |
20980 | char *z; |
20981 | va_start(ap, zFmt); |
20982 | z = sqlite3_vmprintf(zFmt, ap); |
20983 | va_end(ap); |
20984 | utf8_printf(stderr, "Error: %s\n" , z); |
20985 | if( pAr->fromCmdLine ){ |
20986 | utf8_printf(stderr, "Use \"-A\" for more help\n" ); |
20987 | }else{ |
20988 | utf8_printf(stderr, "Use \".archive --help\" for more help\n" ); |
20989 | } |
20990 | sqlite3_free(z); |
20991 | return SQLITE_ERROR; |
20992 | } |
20993 | |
20994 | /* |
20995 | ** Values for ArCommand.eCmd. |
20996 | */ |
20997 | #define AR_CMD_CREATE 1 |
20998 | #define AR_CMD_UPDATE 2 |
20999 | #define AR_CMD_INSERT 3 |
21000 | #define AR_CMD_EXTRACT 4 |
21001 | #define AR_CMD_LIST 5 |
21002 | #define AR_CMD_HELP 6 |
21003 | #define AR_CMD_REMOVE 7 |
21004 | |
21005 | /* |
21006 | ** Other (non-command) switches. |
21007 | */ |
21008 | #define AR_SWITCH_VERBOSE 8 |
21009 | #define AR_SWITCH_FILE 9 |
21010 | #define AR_SWITCH_DIRECTORY 10 |
21011 | #define AR_SWITCH_APPEND 11 |
21012 | #define AR_SWITCH_DRYRUN 12 |
21013 | #define AR_SWITCH_GLOB 13 |
21014 | |
21015 | static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){ |
21016 | switch( eSwitch ){ |
21017 | case AR_CMD_CREATE: |
21018 | case AR_CMD_EXTRACT: |
21019 | case AR_CMD_LIST: |
21020 | case AR_CMD_REMOVE: |
21021 | case AR_CMD_UPDATE: |
21022 | case AR_CMD_INSERT: |
21023 | case AR_CMD_HELP: |
21024 | if( pAr->eCmd ){ |
21025 | return arErrorMsg(pAr, "multiple command options" ); |
21026 | } |
21027 | pAr->eCmd = eSwitch; |
21028 | break; |
21029 | |
21030 | case AR_SWITCH_DRYRUN: |
21031 | pAr->bDryRun = 1; |
21032 | break; |
21033 | case AR_SWITCH_GLOB: |
21034 | pAr->bGlob = 1; |
21035 | break; |
21036 | case AR_SWITCH_VERBOSE: |
21037 | pAr->bVerbose = 1; |
21038 | break; |
21039 | case AR_SWITCH_APPEND: |
21040 | pAr->bAppend = 1; |
21041 | /* Fall thru into --file */ |
21042 | case AR_SWITCH_FILE: |
21043 | pAr->zFile = zArg; |
21044 | break; |
21045 | case AR_SWITCH_DIRECTORY: |
21046 | pAr->zDir = zArg; |
21047 | break; |
21048 | } |
21049 | |
21050 | return SQLITE_OK; |
21051 | } |
21052 | |
21053 | /* |
21054 | ** Parse the command line for an ".ar" command. The results are written into |
21055 | ** structure (*pAr). SQLITE_OK is returned if the command line is parsed |
21056 | ** successfully, otherwise an error message is written to stderr and |
21057 | ** SQLITE_ERROR returned. |
21058 | */ |
21059 | static int arParseCommand( |
21060 | char **azArg, /* Array of arguments passed to dot command */ |
21061 | int nArg, /* Number of entries in azArg[] */ |
21062 | ArCommand *pAr /* Populate this object */ |
21063 | ){ |
21064 | struct ArSwitch { |
21065 | const char *zLong; |
21066 | char cShort; |
21067 | u8 eSwitch; |
21068 | u8 bArg; |
21069 | } aSwitch[] = { |
21070 | { "create" , 'c', AR_CMD_CREATE, 0 }, |
21071 | { "extract" , 'x', AR_CMD_EXTRACT, 0 }, |
21072 | { "insert" , 'i', AR_CMD_INSERT, 0 }, |
21073 | { "list" , 't', AR_CMD_LIST, 0 }, |
21074 | { "remove" , 'r', AR_CMD_REMOVE, 0 }, |
21075 | { "update" , 'u', AR_CMD_UPDATE, 0 }, |
21076 | { "help" , 'h', AR_CMD_HELP, 0 }, |
21077 | { "verbose" , 'v', AR_SWITCH_VERBOSE, 0 }, |
21078 | { "file" , 'f', AR_SWITCH_FILE, 1 }, |
21079 | { "append" , 'a', AR_SWITCH_APPEND, 1 }, |
21080 | { "directory" , 'C', AR_SWITCH_DIRECTORY, 1 }, |
21081 | { "dryrun" , 'n', AR_SWITCH_DRYRUN, 0 }, |
21082 | { "glob" , 'g', AR_SWITCH_GLOB, 0 }, |
21083 | }; |
21084 | int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch); |
21085 | struct ArSwitch *pEnd = &aSwitch[nSwitch]; |
21086 | |
21087 | if( nArg<=1 ){ |
21088 | utf8_printf(stderr, "Wrong number of arguments. Usage:\n" ); |
21089 | return arUsage(stderr); |
21090 | }else{ |
21091 | char *z = azArg[1]; |
21092 | if( z[0]!='-' ){ |
21093 | /* Traditional style [tar] invocation */ |
21094 | int i; |
21095 | int iArg = 2; |
21096 | for(i=0; z[i]; i++){ |
21097 | const char *zArg = 0; |
21098 | struct ArSwitch *pOpt; |
21099 | for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ |
21100 | if( z[i]==pOpt->cShort ) break; |
21101 | } |
21102 | if( pOpt==pEnd ){ |
21103 | return arErrorMsg(pAr, "unrecognized option: %c" , z[i]); |
21104 | } |
21105 | if( pOpt->bArg ){ |
21106 | if( iArg>=nArg ){ |
21107 | return arErrorMsg(pAr, "option requires an argument: %c" ,z[i]); |
21108 | } |
21109 | zArg = azArg[iArg++]; |
21110 | } |
21111 | if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR; |
21112 | } |
21113 | pAr->nArg = nArg-iArg; |
21114 | if( pAr->nArg>0 ){ |
21115 | pAr->azArg = &azArg[iArg]; |
21116 | } |
21117 | }else{ |
21118 | /* Non-traditional invocation */ |
21119 | int iArg; |
21120 | for(iArg=1; iArg<nArg; iArg++){ |
21121 | int n; |
21122 | z = azArg[iArg]; |
21123 | if( z[0]!='-' ){ |
21124 | /* All remaining command line words are command arguments. */ |
21125 | pAr->azArg = &azArg[iArg]; |
21126 | pAr->nArg = nArg-iArg; |
21127 | break; |
21128 | } |
21129 | n = strlen30(z); |
21130 | |
21131 | if( z[1]!='-' ){ |
21132 | int i; |
21133 | /* One or more short options */ |
21134 | for(i=1; i<n; i++){ |
21135 | const char *zArg = 0; |
21136 | struct ArSwitch *pOpt; |
21137 | for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ |
21138 | if( z[i]==pOpt->cShort ) break; |
21139 | } |
21140 | if( pOpt==pEnd ){ |
21141 | return arErrorMsg(pAr, "unrecognized option: %c" , z[i]); |
21142 | } |
21143 | if( pOpt->bArg ){ |
21144 | if( i<(n-1) ){ |
21145 | zArg = &z[i+1]; |
21146 | i = n; |
21147 | }else{ |
21148 | if( iArg>=(nArg-1) ){ |
21149 | return arErrorMsg(pAr, "option requires an argument: %c" , |
21150 | z[i]); |
21151 | } |
21152 | zArg = azArg[++iArg]; |
21153 | } |
21154 | } |
21155 | if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR; |
21156 | } |
21157 | }else if( z[2]=='\0' ){ |
21158 | /* A -- option, indicating that all remaining command line words |
21159 | ** are command arguments. */ |
21160 | pAr->azArg = &azArg[iArg+1]; |
21161 | pAr->nArg = nArg-iArg-1; |
21162 | break; |
21163 | }else{ |
21164 | /* A long option */ |
21165 | const char *zArg = 0; /* Argument for option, if any */ |
21166 | struct ArSwitch *pMatch = 0; /* Matching option */ |
21167 | struct ArSwitch *pOpt; /* Iterator */ |
21168 | for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ |
21169 | const char *zLong = pOpt->zLong; |
21170 | if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){ |
21171 | if( pMatch ){ |
21172 | return arErrorMsg(pAr, "ambiguous option: %s" ,z); |
21173 | }else{ |
21174 | pMatch = pOpt; |
21175 | } |
21176 | } |
21177 | } |
21178 | |
21179 | if( pMatch==0 ){ |
21180 | return arErrorMsg(pAr, "unrecognized option: %s" , z); |
21181 | } |
21182 | if( pMatch->bArg ){ |
21183 | if( iArg>=(nArg-1) ){ |
21184 | return arErrorMsg(pAr, "option requires an argument: %s" , z); |
21185 | } |
21186 | zArg = azArg[++iArg]; |
21187 | } |
21188 | if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR; |
21189 | } |
21190 | } |
21191 | } |
21192 | } |
21193 | |
21194 | return SQLITE_OK; |
21195 | } |
21196 | |
21197 | /* |
21198 | ** This function assumes that all arguments within the ArCommand.azArg[] |
21199 | ** array refer to archive members, as for the --extract, --list or --remove |
21200 | ** commands. It checks that each of them are "present". If any specified |
21201 | ** file is not present in the archive, an error is printed to stderr and an |
21202 | ** error code returned. Otherwise, if all specified arguments are present |
21203 | ** in the archive, SQLITE_OK is returned. Here, "present" means either an |
21204 | ** exact equality when pAr->bGlob is false or a "name GLOB pattern" match |
21205 | ** when pAr->bGlob is true. |
21206 | ** |
21207 | ** This function strips any trailing '/' characters from each argument. |
21208 | ** This is consistent with the way the [tar] command seems to work on |
21209 | ** Linux. |
21210 | */ |
21211 | static int arCheckEntries(ArCommand *pAr){ |
21212 | int rc = SQLITE_OK; |
21213 | if( pAr->nArg ){ |
21214 | int i, j; |
21215 | sqlite3_stmt *pTest = 0; |
21216 | const char *zSel = (pAr->bGlob) |
21217 | ? "SELECT name FROM %s WHERE glob($name,name)" |
21218 | : "SELECT name FROM %s WHERE name=$name" ; |
21219 | |
21220 | shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable); |
21221 | j = sqlite3_bind_parameter_index(pTest, "$name" ); |
21222 | for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){ |
21223 | char *z = pAr->azArg[i]; |
21224 | int n = strlen30(z); |
21225 | int bOk = 0; |
21226 | while( n>0 && z[n-1]=='/' ) n--; |
21227 | z[n] = '\0'; |
21228 | sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC); |
21229 | if( SQLITE_ROW==sqlite3_step(pTest) ){ |
21230 | bOk = 1; |
21231 | } |
21232 | shellReset(&rc, pTest); |
21233 | if( rc==SQLITE_OK && bOk==0 ){ |
21234 | utf8_printf(stderr, "not found in archive: %s\n" , z); |
21235 | rc = SQLITE_ERROR; |
21236 | } |
21237 | } |
21238 | shellFinalize(&rc, pTest); |
21239 | } |
21240 | return rc; |
21241 | } |
21242 | |
21243 | /* |
21244 | ** Format a WHERE clause that can be used against the "sqlar" table to |
21245 | ** identify all archive members that match the command arguments held |
21246 | ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning. |
21247 | ** The caller is responsible for eventually calling sqlite3_free() on |
21248 | ** any non-NULL (*pzWhere) value. Here, "match" means strict equality |
21249 | ** when pAr->bGlob is false and GLOB match when pAr->bGlob is true. |
21250 | */ |
21251 | static void arWhereClause( |
21252 | int *pRc, |
21253 | ArCommand *pAr, |
21254 | char **pzWhere /* OUT: New WHERE clause */ |
21255 | ){ |
21256 | char *zWhere = 0; |
21257 | const char *zSameOp = (pAr->bGlob)? "GLOB" : "=" ; |
21258 | if( *pRc==SQLITE_OK ){ |
21259 | if( pAr->nArg==0 ){ |
21260 | zWhere = sqlite3_mprintf("1" ); |
21261 | }else{ |
21262 | int i; |
21263 | const char *zSep = "" ; |
21264 | for(i=0; i<pAr->nArg; i++){ |
21265 | const char *z = pAr->azArg[i]; |
21266 | zWhere = sqlite3_mprintf( |
21267 | "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'" , |
21268 | zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z |
21269 | ); |
21270 | if( zWhere==0 ){ |
21271 | *pRc = SQLITE_NOMEM; |
21272 | break; |
21273 | } |
21274 | zSep = " OR " ; |
21275 | } |
21276 | } |
21277 | } |
21278 | *pzWhere = zWhere; |
21279 | } |
21280 | |
21281 | /* |
21282 | ** Implementation of .ar "lisT" command. |
21283 | */ |
21284 | static int arListCommand(ArCommand *pAr){ |
21285 | const char *zSql = "SELECT %s FROM %s WHERE %s" ; |
21286 | const char *azCols[] = { |
21287 | "name" , |
21288 | "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name" |
21289 | }; |
21290 | |
21291 | char *zWhere = 0; |
21292 | sqlite3_stmt *pSql = 0; |
21293 | int rc; |
21294 | |
21295 | rc = arCheckEntries(pAr); |
21296 | arWhereClause(&rc, pAr, &zWhere); |
21297 | |
21298 | shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose], |
21299 | pAr->zSrcTable, zWhere); |
21300 | if( pAr->bDryRun ){ |
21301 | utf8_printf(pAr->p->out, "%s\n" , sqlite3_sql(pSql)); |
21302 | }else{ |
21303 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ |
21304 | if( pAr->bVerbose ){ |
21305 | utf8_printf(pAr->p->out, "%s % 10d %s %s\n" , |
21306 | sqlite3_column_text(pSql, 0), |
21307 | sqlite3_column_int(pSql, 1), |
21308 | sqlite3_column_text(pSql, 2), |
21309 | sqlite3_column_text(pSql, 3) |
21310 | ); |
21311 | }else{ |
21312 | utf8_printf(pAr->p->out, "%s\n" , sqlite3_column_text(pSql, 0)); |
21313 | } |
21314 | } |
21315 | } |
21316 | shellFinalize(&rc, pSql); |
21317 | sqlite3_free(zWhere); |
21318 | return rc; |
21319 | } |
21320 | |
21321 | |
21322 | /* |
21323 | ** Implementation of .ar "Remove" command. |
21324 | */ |
21325 | static int arRemoveCommand(ArCommand *pAr){ |
21326 | int rc = 0; |
21327 | char *zSql = 0; |
21328 | char *zWhere = 0; |
21329 | |
21330 | if( pAr->nArg ){ |
21331 | /* Verify that args actually exist within the archive before proceeding. |
21332 | ** And formulate a WHERE clause to match them. */ |
21333 | rc = arCheckEntries(pAr); |
21334 | arWhereClause(&rc, pAr, &zWhere); |
21335 | } |
21336 | if( rc==SQLITE_OK ){ |
21337 | zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;" , |
21338 | pAr->zSrcTable, zWhere); |
21339 | if( pAr->bDryRun ){ |
21340 | utf8_printf(pAr->p->out, "%s\n" , zSql); |
21341 | }else{ |
21342 | char *zErr = 0; |
21343 | rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;" , 0, 0, 0); |
21344 | if( rc==SQLITE_OK ){ |
21345 | rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); |
21346 | if( rc!=SQLITE_OK ){ |
21347 | sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;" , 0, 0, 0); |
21348 | }else{ |
21349 | rc = sqlite3_exec(pAr->db, "RELEASE ar;" , 0, 0, 0); |
21350 | } |
21351 | } |
21352 | if( zErr ){ |
21353 | utf8_printf(stdout, "ERROR: %s\n" , zErr); |
21354 | sqlite3_free(zErr); |
21355 | } |
21356 | } |
21357 | } |
21358 | sqlite3_free(zWhere); |
21359 | sqlite3_free(zSql); |
21360 | return rc; |
21361 | } |
21362 | |
21363 | /* |
21364 | ** Implementation of .ar "eXtract" command. |
21365 | */ |
21366 | static int arExtractCommand(ArCommand *pAr){ |
21367 | const char *zSql1 = |
21368 | "SELECT " |
21369 | " ($dir || name)," |
21370 | " writefile(($dir || name), %s, mode, mtime) " |
21371 | "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)" |
21372 | " AND name NOT GLOB '*..[/\\]*'" ; |
21373 | |
21374 | const char *azExtraArg[] = { |
21375 | "sqlar_uncompress(data, sz)" , |
21376 | "data" |
21377 | }; |
21378 | |
21379 | sqlite3_stmt *pSql = 0; |
21380 | int rc = SQLITE_OK; |
21381 | char *zDir = 0; |
21382 | char *zWhere = 0; |
21383 | int i, j; |
21384 | |
21385 | /* If arguments are specified, check that they actually exist within |
21386 | ** the archive before proceeding. And formulate a WHERE clause to |
21387 | ** match them. */ |
21388 | rc = arCheckEntries(pAr); |
21389 | arWhereClause(&rc, pAr, &zWhere); |
21390 | |
21391 | if( rc==SQLITE_OK ){ |
21392 | if( pAr->zDir ){ |
21393 | zDir = sqlite3_mprintf("%s/" , pAr->zDir); |
21394 | }else{ |
21395 | zDir = sqlite3_mprintf("" ); |
21396 | } |
21397 | if( zDir==0 ) rc = SQLITE_NOMEM; |
21398 | } |
21399 | |
21400 | shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, |
21401 | azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere |
21402 | ); |
21403 | |
21404 | if( rc==SQLITE_OK ){ |
21405 | j = sqlite3_bind_parameter_index(pSql, "$dir" ); |
21406 | sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC); |
21407 | |
21408 | /* Run the SELECT statement twice. The first time, writefile() is called |
21409 | ** for all archive members that should be extracted. The second time, |
21410 | ** only for the directories. This is because the timestamps for |
21411 | ** extracted directories must be reset after they are populated (as |
21412 | ** populating them changes the timestamp). */ |
21413 | for(i=0; i<2; i++){ |
21414 | j = sqlite3_bind_parameter_index(pSql, "$dirOnly" ); |
21415 | sqlite3_bind_int(pSql, j, i); |
21416 | if( pAr->bDryRun ){ |
21417 | utf8_printf(pAr->p->out, "%s\n" , sqlite3_sql(pSql)); |
21418 | }else{ |
21419 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ |
21420 | if( i==0 && pAr->bVerbose ){ |
21421 | utf8_printf(pAr->p->out, "%s\n" , sqlite3_column_text(pSql, 0)); |
21422 | } |
21423 | } |
21424 | } |
21425 | shellReset(&rc, pSql); |
21426 | } |
21427 | shellFinalize(&rc, pSql); |
21428 | } |
21429 | |
21430 | sqlite3_free(zDir); |
21431 | sqlite3_free(zWhere); |
21432 | return rc; |
21433 | } |
21434 | |
21435 | /* |
21436 | ** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out. |
21437 | */ |
21438 | static int arExecSql(ArCommand *pAr, const char *zSql){ |
21439 | int rc; |
21440 | if( pAr->bDryRun ){ |
21441 | utf8_printf(pAr->p->out, "%s\n" , zSql); |
21442 | rc = SQLITE_OK; |
21443 | }else{ |
21444 | char *zErr = 0; |
21445 | rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); |
21446 | if( zErr ){ |
21447 | utf8_printf(stdout, "ERROR: %s\n" , zErr); |
21448 | sqlite3_free(zErr); |
21449 | } |
21450 | } |
21451 | return rc; |
21452 | } |
21453 | |
21454 | |
21455 | /* |
21456 | ** Implementation of .ar "create", "insert", and "update" commands. |
21457 | ** |
21458 | ** create -> Create a new SQL archive |
21459 | ** insert -> Insert or reinsert all files listed |
21460 | ** update -> Insert files that have changed or that were not |
21461 | ** previously in the archive |
21462 | ** |
21463 | ** Create the "sqlar" table in the database if it does not already exist. |
21464 | ** Then add each file in the azFile[] array to the archive. Directories |
21465 | ** are added recursively. If argument bVerbose is non-zero, a message is |
21466 | ** printed on stdout for each file archived. |
21467 | ** |
21468 | ** The create command is the same as update, except that it drops |
21469 | ** any existing "sqlar" table before beginning. The "insert" command |
21470 | ** always overwrites every file named on the command-line, where as |
21471 | ** "update" only overwrites if the size or mtime or mode has changed. |
21472 | */ |
21473 | static int arCreateOrUpdateCommand( |
21474 | ArCommand *pAr, /* Command arguments and options */ |
21475 | int bUpdate, /* true for a --create. */ |
21476 | int bOnlyIfChanged /* Only update if file has changed */ |
21477 | ){ |
21478 | const char *zCreate = |
21479 | "CREATE TABLE IF NOT EXISTS sqlar(\n" |
21480 | " name TEXT PRIMARY KEY, -- name of the file\n" |
21481 | " mode INT, -- access permissions\n" |
21482 | " mtime INT, -- last modification time\n" |
21483 | " sz INT, -- original file size\n" |
21484 | " data BLOB -- compressed content\n" |
21485 | ")" ; |
21486 | const char *zDrop = "DROP TABLE IF EXISTS sqlar" ; |
21487 | const char *zInsertFmt[2] = { |
21488 | "REPLACE INTO %s(name,mode,mtime,sz,data)\n" |
21489 | " SELECT\n" |
21490 | " %s,\n" |
21491 | " mode,\n" |
21492 | " mtime,\n" |
21493 | " CASE substr(lsmode(mode),1,1)\n" |
21494 | " WHEN '-' THEN length(data)\n" |
21495 | " WHEN 'd' THEN 0\n" |
21496 | " ELSE -1 END,\n" |
21497 | " sqlar_compress(data)\n" |
21498 | " FROM fsdir(%Q,%Q) AS disk\n" |
21499 | " WHERE lsmode(mode) NOT LIKE '?%%'%s;" |
21500 | , |
21501 | "REPLACE INTO %s(name,mode,mtime,data)\n" |
21502 | " SELECT\n" |
21503 | " %s,\n" |
21504 | " mode,\n" |
21505 | " mtime,\n" |
21506 | " data\n" |
21507 | " FROM fsdir(%Q,%Q) AS disk\n" |
21508 | " WHERE lsmode(mode) NOT LIKE '?%%'%s;" |
21509 | }; |
21510 | int i; /* For iterating through azFile[] */ |
21511 | int rc; /* Return code */ |
21512 | const char *zTab = 0; /* SQL table into which to insert */ |
21513 | char *zSql; |
21514 | char zTemp[50]; |
21515 | char *zExists = 0; |
21516 | |
21517 | arExecSql(pAr, "PRAGMA page_size=512" ); |
21518 | rc = arExecSql(pAr, "SAVEPOINT ar;" ); |
21519 | if( rc!=SQLITE_OK ) return rc; |
21520 | zTemp[0] = 0; |
21521 | if( pAr->bZip ){ |
21522 | /* Initialize the zipfile virtual table, if necessary */ |
21523 | if( pAr->zFile ){ |
21524 | sqlite3_uint64 r; |
21525 | sqlite3_randomness(sizeof(r),&r); |
21526 | sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx" ,r); |
21527 | zTab = zTemp; |
21528 | zSql = sqlite3_mprintf( |
21529 | "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)" , |
21530 | zTab, pAr->zFile |
21531 | ); |
21532 | rc = arExecSql(pAr, zSql); |
21533 | sqlite3_free(zSql); |
21534 | }else{ |
21535 | zTab = "zip" ; |
21536 | } |
21537 | }else{ |
21538 | /* Initialize the table for an SQLAR */ |
21539 | zTab = "sqlar" ; |
21540 | if( bUpdate==0 ){ |
21541 | rc = arExecSql(pAr, zDrop); |
21542 | if( rc!=SQLITE_OK ) goto end_ar_transaction; |
21543 | } |
21544 | rc = arExecSql(pAr, zCreate); |
21545 | } |
21546 | if( bOnlyIfChanged ){ |
21547 | zExists = sqlite3_mprintf( |
21548 | " AND NOT EXISTS(" |
21549 | "SELECT 1 FROM %s AS mem" |
21550 | " WHERE mem.name=disk.name" |
21551 | " AND mem.mtime=disk.mtime" |
21552 | " AND mem.mode=disk.mode)" , zTab); |
21553 | }else{ |
21554 | zExists = sqlite3_mprintf("" ); |
21555 | } |
21556 | if( zExists==0 ) rc = SQLITE_NOMEM; |
21557 | for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){ |
21558 | char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab, |
21559 | pAr->bVerbose ? "shell_putsnl(name)" : "name" , |
21560 | pAr->azArg[i], pAr->zDir, zExists); |
21561 | rc = arExecSql(pAr, zSql2); |
21562 | sqlite3_free(zSql2); |
21563 | } |
21564 | end_ar_transaction: |
21565 | if( rc!=SQLITE_OK ){ |
21566 | sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;" , 0, 0, 0); |
21567 | }else{ |
21568 | rc = arExecSql(pAr, "RELEASE ar;" ); |
21569 | if( pAr->bZip && pAr->zFile ){ |
21570 | zSql = sqlite3_mprintf("DROP TABLE %s" , zTemp); |
21571 | arExecSql(pAr, zSql); |
21572 | sqlite3_free(zSql); |
21573 | } |
21574 | } |
21575 | sqlite3_free(zExists); |
21576 | return rc; |
21577 | } |
21578 | |
21579 | /* |
21580 | ** Implementation of ".ar" dot command. |
21581 | */ |
21582 | static int arDotCommand( |
21583 | ShellState *pState, /* Current shell tool state */ |
21584 | int fromCmdLine, /* True if -A command-line option, not .ar cmd */ |
21585 | char **azArg, /* Array of arguments passed to dot command */ |
21586 | int nArg /* Number of entries in azArg[] */ |
21587 | ){ |
21588 | ArCommand cmd; |
21589 | int rc; |
21590 | memset(&cmd, 0, sizeof(cmd)); |
21591 | cmd.fromCmdLine = fromCmdLine; |
21592 | rc = arParseCommand(azArg, nArg, &cmd); |
21593 | if( rc==SQLITE_OK ){ |
21594 | int eDbType = SHELL_OPEN_UNSPEC; |
21595 | cmd.p = pState; |
21596 | cmd.db = pState->db; |
21597 | if( cmd.zFile ){ |
21598 | eDbType = deduceDatabaseType(cmd.zFile, 1); |
21599 | }else{ |
21600 | eDbType = pState->openMode; |
21601 | } |
21602 | if( eDbType==SHELL_OPEN_ZIPFILE ){ |
21603 | if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){ |
21604 | if( cmd.zFile==0 ){ |
21605 | cmd.zSrcTable = sqlite3_mprintf("zip" ); |
21606 | }else{ |
21607 | cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)" , cmd.zFile); |
21608 | } |
21609 | } |
21610 | cmd.bZip = 1; |
21611 | }else if( cmd.zFile ){ |
21612 | int flags; |
21613 | if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS; |
21614 | if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT |
21615 | || cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){ |
21616 | flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; |
21617 | }else{ |
21618 | flags = SQLITE_OPEN_READONLY; |
21619 | } |
21620 | cmd.db = 0; |
21621 | if( cmd.bDryRun ){ |
21622 | utf8_printf(pState->out, "-- open database '%s'%s\n" , cmd.zFile, |
21623 | eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "" ); |
21624 | } |
21625 | rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, |
21626 | eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); |
21627 | if( rc!=SQLITE_OK ){ |
21628 | utf8_printf(stderr, "cannot open file: %s (%s)\n" , |
21629 | cmd.zFile, sqlite3_errmsg(cmd.db) |
21630 | ); |
21631 | goto end_ar_command; |
21632 | } |
21633 | sqlite3_fileio_init(cmd.db, 0, 0); |
21634 | sqlite3_sqlar_init(cmd.db, 0, 0); |
21635 | sqlite3_create_function(cmd.db, "shell_putsnl" , 1, SQLITE_UTF8, cmd.p, |
21636 | shellPutsFunc, 0, 0); |
21637 | |
21638 | } |
21639 | if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){ |
21640 | if( cmd.eCmd!=AR_CMD_CREATE |
21641 | && sqlite3_table_column_metadata(cmd.db,0,"sqlar" ,"name" ,0,0,0,0,0) |
21642 | ){ |
21643 | utf8_printf(stderr, "database does not contain an 'sqlar' table\n" ); |
21644 | rc = SQLITE_ERROR; |
21645 | goto end_ar_command; |
21646 | } |
21647 | cmd.zSrcTable = sqlite3_mprintf("sqlar" ); |
21648 | } |
21649 | |
21650 | switch( cmd.eCmd ){ |
21651 | case AR_CMD_CREATE: |
21652 | rc = arCreateOrUpdateCommand(&cmd, 0, 0); |
21653 | break; |
21654 | |
21655 | case AR_CMD_EXTRACT: |
21656 | rc = arExtractCommand(&cmd); |
21657 | break; |
21658 | |
21659 | case AR_CMD_LIST: |
21660 | rc = arListCommand(&cmd); |
21661 | break; |
21662 | |
21663 | case AR_CMD_HELP: |
21664 | arUsage(pState->out); |
21665 | break; |
21666 | |
21667 | case AR_CMD_INSERT: |
21668 | rc = arCreateOrUpdateCommand(&cmd, 1, 0); |
21669 | break; |
21670 | |
21671 | case AR_CMD_REMOVE: |
21672 | rc = arRemoveCommand(&cmd); |
21673 | break; |
21674 | |
21675 | default: |
21676 | assert( cmd.eCmd==AR_CMD_UPDATE ); |
21677 | rc = arCreateOrUpdateCommand(&cmd, 1, 1); |
21678 | break; |
21679 | } |
21680 | } |
21681 | end_ar_command: |
21682 | if( cmd.db!=pState->db ){ |
21683 | close_db(cmd.db); |
21684 | } |
21685 | sqlite3_free(cmd.zSrcTable); |
21686 | |
21687 | return rc; |
21688 | } |
21689 | /* End of the ".archive" or ".ar" command logic |
21690 | *******************************************************************************/ |
21691 | #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ |
21692 | |
21693 | #if SQLITE_SHELL_HAVE_RECOVER |
21694 | |
21695 | /* |
21696 | ** This function is used as a callback by the recover extension. Simply |
21697 | ** print the supplied SQL statement to stdout. |
21698 | */ |
21699 | static int recoverSqlCb(void *pCtx, const char *zSql){ |
21700 | ShellState *pState = (ShellState*)pCtx; |
21701 | utf8_printf(pState->out, "%s;\n" , zSql); |
21702 | return SQLITE_OK; |
21703 | } |
21704 | |
21705 | /* |
21706 | ** This function is called to recover data from the database. A script |
21707 | ** to construct a new database containing all recovered data is output |
21708 | ** on stream pState->out. |
21709 | */ |
21710 | static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ |
21711 | int rc = SQLITE_OK; |
21712 | const char *zRecoveryDb = "" ; /* Name of "recovery" database. Debug only */ |
21713 | const char *zLAF = "lost_and_found" ; |
21714 | int bFreelist = 1; /* 0 if --ignore-freelist is specified */ |
21715 | int bRowids = 1; /* 0 if --no-rowids */ |
21716 | sqlite3_recover *p = 0; |
21717 | int i = 0; |
21718 | |
21719 | for(i=1; i<nArg; i++){ |
21720 | char *z = azArg[i]; |
21721 | int n; |
21722 | if( z[0]=='-' && z[1]=='-' ) z++; |
21723 | n = strlen30(z); |
21724 | if( n<=17 && memcmp("-ignore-freelist" , z, n)==0 ){ |
21725 | bFreelist = 0; |
21726 | }else |
21727 | if( n<=12 && memcmp("-recovery-db" , z, n)==0 && i<(nArg-1) ){ |
21728 | /* This option determines the name of the ATTACH-ed database used |
21729 | ** internally by the recovery extension. The default is "" which |
21730 | ** means to use a temporary database that is automatically deleted |
21731 | ** when closed. This option is undocumented and might disappear at |
21732 | ** any moment. */ |
21733 | i++; |
21734 | zRecoveryDb = azArg[i]; |
21735 | }else |
21736 | if( n<=15 && memcmp("-lost-and-found" , z, n)==0 && i<(nArg-1) ){ |
21737 | i++; |
21738 | zLAF = azArg[i]; |
21739 | }else |
21740 | if( n<=10 && memcmp("-no-rowids" , z, n)==0 ){ |
21741 | bRowids = 0; |
21742 | } |
21743 | else{ |
21744 | utf8_printf(stderr, "unexpected option: %s\n" , azArg[i]); |
21745 | showHelp(pState->out, azArg[0]); |
21746 | return 1; |
21747 | } |
21748 | } |
21749 | |
21750 | p = sqlite3_recover_init_sql( |
21751 | pState->db, "main" , recoverSqlCb, (void*)pState |
21752 | ); |
21753 | |
21754 | sqlite3_recover_config(p, 789, (void*)zRecoveryDb); /* Debug use only */ |
21755 | sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF); |
21756 | sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids); |
21757 | sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist); |
21758 | |
21759 | sqlite3_recover_run(p); |
21760 | if( sqlite3_recover_errcode(p)!=SQLITE_OK ){ |
21761 | const char *zErr = sqlite3_recover_errmsg(p); |
21762 | int errCode = sqlite3_recover_errcode(p); |
21763 | raw_printf(stderr, "sql error: %s (%d)\n" , zErr, errCode); |
21764 | } |
21765 | rc = sqlite3_recover_finish(p); |
21766 | return rc; |
21767 | } |
21768 | #endif /* SQLITE_SHELL_HAVE_RECOVER */ |
21769 | |
21770 | |
21771 | /* |
21772 | * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it. |
21773 | * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE, |
21774 | * close db and set it to 0, and return the columns spec, to later |
21775 | * be sqlite3_free()'ed by the caller. |
21776 | * The return is 0 when either: |
21777 | * (a) The db was not initialized and zCol==0 (There are no columns.) |
21778 | * (b) zCol!=0 (Column was added, db initialized as needed.) |
21779 | * The 3rd argument, pRenamed, references an out parameter. If the |
21780 | * pointer is non-zero, its referent will be set to a summary of renames |
21781 | * done if renaming was necessary, or set to 0 if none was done. The out |
21782 | * string (if any) must be sqlite3_free()'ed by the caller. |
21783 | */ |
21784 | #ifdef SHELL_DEBUG |
21785 | #define rc_err_oom_die(rc) \ |
21786 | if( rc==SQLITE_NOMEM ) shell_check_oom(0); \ |
21787 | else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \ |
21788 | fprintf(stderr,"E:%d\n",rc), assert(0) |
21789 | #else |
21790 | static void rc_err_oom_die(int rc){ |
21791 | if( rc==SQLITE_NOMEM ) shell_check_oom(0); |
21792 | assert(rc==SQLITE_OK||rc==SQLITE_DONE); |
21793 | } |
21794 | #endif |
21795 | |
21796 | #ifdef SHELL_COLFIX_DB /* If this is set, the DB can be in a file. */ |
21797 | static char zCOL_DB[] = SHELL_STRINGIFY(SHELL_COLFIX_DB); |
21798 | #else /* Otherwise, memory is faster/better for the transient DB. */ |
21799 | static const char *zCOL_DB = ":memory:" ; |
21800 | #endif |
21801 | |
21802 | /* Define character (as C string) to separate generated column ordinal |
21803 | * from protected part of incoming column names. This defaults to "_" |
21804 | * so that incoming column identifiers that did not need not be quoted |
21805 | * remain usable without being quoted. It must be one character. |
21806 | */ |
21807 | #ifndef SHELL_AUTOCOLUMN_SEP |
21808 | # define AUTOCOLUMN_SEP "_" |
21809 | #else |
21810 | # define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP) |
21811 | #endif |
21812 | |
21813 | static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, char **pzRenamed){ |
21814 | /* Queries and D{D,M}L used here */ |
21815 | static const char * const zTabMake = "\ |
21816 | CREATE TABLE ColNames(\ |
21817 | cpos INTEGER PRIMARY KEY,\ |
21818 | name TEXT, nlen INT, chop INT, reps INT, suff TEXT);\ |
21819 | CREATE VIEW RepeatedNames AS \ |
21820 | SELECT DISTINCT t.name FROM ColNames t \ |
21821 | WHERE t.name COLLATE NOCASE IN (\ |
21822 | SELECT o.name FROM ColNames o WHERE o.cpos<>t.cpos\ |
21823 | );\ |
21824 | " ; |
21825 | static const char * const zTabFill = "\ |
21826 | INSERT INTO ColNames(name,nlen,chop,reps,suff)\ |
21827 | VALUES(iif(length(?1)>0,?1,'?'),max(length(?1),1),0,0,'')\ |
21828 | " ; |
21829 | static const char * const zHasDupes = "\ |
21830 | SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\ |
21831 | <count(name) FROM ColNames\ |
21832 | " ; |
21833 | #ifdef SHELL_COLUMN_RENAME_CLEAN |
21834 | static const char * const zDedoctor = "\ |
21835 | UPDATE ColNames SET chop=iif(\ |
21836 | (substring(name,nlen,1) BETWEEN '0' AND '9')\ |
21837 | AND (rtrim(name,'0123456790') glob '*" AUTOCOLUMN_SEP"'),\ |
21838 | nlen-length(rtrim(name, '" AUTOCOLUMN_SEP"0123456789')),\ |
21839 | 0\ |
21840 | )\ |
21841 | " ; |
21842 | #endif |
21843 | static const char * const zSetReps = "\ |
21844 | UPDATE ColNames AS t SET reps=\ |
21845 | (SELECT count(*) FROM ColNames d \ |
21846 | WHERE substring(t.name,1,t.nlen-t.chop)=substring(d.name,1,d.nlen-d.chop)\ |
21847 | COLLATE NOCASE\ |
21848 | )\ |
21849 | " ; |
21850 | #ifdef SQLITE_ENABLE_MATH_FUNCTIONS |
21851 | static const char * const zColDigits = "\ |
21852 | SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \ |
21853 | " ; |
21854 | #else |
21855 | /* Counting on SQLITE_MAX_COLUMN < 100,000 here. (32767 is the hard limit.) */ |
21856 | static const char * const zColDigits = "\ |
21857 | SELECT CASE WHEN (nc < 10) THEN 1 WHEN (nc < 100) THEN 2 \ |
21858 | WHEN (nc < 1000) THEN 3 WHEN (nc < 10000) THEN 4 \ |
21859 | ELSE 5 FROM (SELECT count(*) AS nc FROM ColNames) \ |
21860 | " ; |
21861 | #endif |
21862 | static const char * const zRenameRank = |
21863 | #ifdef SHELL_COLUMN_RENAME_CLEAN |
21864 | "UPDATE ColNames AS t SET suff=" |
21865 | "iif(reps>1, printf('%c%0*d', '" AUTOCOLUMN_SEP"', $1, cpos), '')" |
21866 | #else /* ...RENAME_MINIMAL_ONE_PASS */ |
21867 | "WITH Lzn(nlz) AS (" /* Find minimum extraneous leading 0's for uniqueness */ |
21868 | " SELECT 0 AS nlz" |
21869 | " UNION" |
21870 | " SELECT nlz+1 AS nlz FROM Lzn" |
21871 | " WHERE EXISTS(" |
21872 | " SELECT 1" |
21873 | " FROM ColNames t, ColNames o" |
21874 | " WHERE" |
21875 | " iif(t.name IN (SELECT * FROM RepeatedNames)," |
21876 | " printf('%s" AUTOCOLUMN_SEP"%s'," |
21877 | " t.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,t.cpos),2))," |
21878 | " t.name" |
21879 | " )" |
21880 | " =" |
21881 | " iif(o.name IN (SELECT * FROM RepeatedNames)," |
21882 | " printf('%s" AUTOCOLUMN_SEP"%s'," |
21883 | " o.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,o.cpos),2))," |
21884 | " o.name" |
21885 | " )" |
21886 | " COLLATE NOCASE" |
21887 | " AND o.cpos<>t.cpos" |
21888 | " GROUP BY t.cpos" |
21889 | " )" |
21890 | ") UPDATE Colnames AS t SET" |
21891 | " chop = 0," /* No chopping, never touch incoming names. */ |
21892 | " suff = iif(name IN (SELECT * FROM RepeatedNames)," |
21893 | " printf('" AUTOCOLUMN_SEP"%s', substring(" |
21894 | " printf('%.*c%0.*d',(SELECT max(nlz) FROM Lzn)+1,'0',1,t.cpos),2))," |
21895 | " ''" |
21896 | " )" |
21897 | #endif |
21898 | ; |
21899 | static const char * const zCollectVar = "\ |
21900 | SELECT\ |
21901 | '('||x'0a'\ |
21902 | || group_concat(\ |
21903 | cname||' TEXT',\ |
21904 | ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\ |
21905 | ||')' AS ColsSpec \ |
21906 | FROM (\ |
21907 | SELECT cpos, printf('\"%w\"',printf('%!.*s%s', nlen-chop,name,suff)) AS cname \ |
21908 | FROM ColNames ORDER BY cpos\ |
21909 | )" ; |
21910 | static const char * const zRenamesDone = |
21911 | "SELECT group_concat(" |
21912 | " printf('\"%w\" to \"%w\"',name,printf('%!.*s%s', nlen-chop, name, suff))," |
21913 | " ','||x'0a')" |
21914 | "FROM ColNames WHERE suff<>'' OR chop!=0" |
21915 | ; |
21916 | int rc; |
21917 | sqlite3_stmt *pStmt = 0; |
21918 | assert(pDb!=0); |
21919 | if( zColNew ){ |
21920 | /* Add initial or additional column. Init db if necessary. */ |
21921 | if( *pDb==0 ){ |
21922 | if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0; |
21923 | #ifdef SHELL_COLFIX_DB |
21924 | if(*zCOL_DB!=':') |
21925 | sqlite3_exec(*pDb,"drop table if exists ColNames;" |
21926 | "drop view if exists RepeatedNames;" ,0,0,0); |
21927 | #endif |
21928 | rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0); |
21929 | rc_err_oom_die(rc); |
21930 | } |
21931 | assert(*pDb!=0); |
21932 | rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0); |
21933 | rc_err_oom_die(rc); |
21934 | rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0); |
21935 | rc_err_oom_die(rc); |
21936 | rc = sqlite3_step(pStmt); |
21937 | rc_err_oom_die(rc); |
21938 | sqlite3_finalize(pStmt); |
21939 | return 0; |
21940 | }else if( *pDb==0 ){ |
21941 | return 0; |
21942 | }else{ |
21943 | /* Formulate the columns spec, close the DB, zero *pDb. */ |
21944 | char *zColsSpec = 0; |
21945 | int hasDupes = db_int(*pDb, zHasDupes); |
21946 | int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0; |
21947 | if( hasDupes ){ |
21948 | #ifdef SHELL_COLUMN_RENAME_CLEAN |
21949 | rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0); |
21950 | rc_err_oom_die(rc); |
21951 | #endif |
21952 | rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0); |
21953 | rc_err_oom_die(rc); |
21954 | rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0); |
21955 | rc_err_oom_die(rc); |
21956 | sqlite3_bind_int(pStmt, 1, nDigits); |
21957 | rc = sqlite3_step(pStmt); |
21958 | sqlite3_finalize(pStmt); |
21959 | assert(rc==SQLITE_DONE); |
21960 | } |
21961 | assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */ |
21962 | rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0); |
21963 | rc_err_oom_die(rc); |
21964 | rc = sqlite3_step(pStmt); |
21965 | if( rc==SQLITE_ROW ){ |
21966 | zColsSpec = sqlite3_mprintf("%s" , sqlite3_column_text(pStmt, 0)); |
21967 | }else{ |
21968 | zColsSpec = 0; |
21969 | } |
21970 | if( pzRenamed!=0 ){ |
21971 | if( !hasDupes ) *pzRenamed = 0; |
21972 | else{ |
21973 | sqlite3_finalize(pStmt); |
21974 | if( SQLITE_OK==sqlite3_prepare_v2(*pDb, zRenamesDone, -1, &pStmt, 0) |
21975 | && SQLITE_ROW==sqlite3_step(pStmt) ){ |
21976 | *pzRenamed = sqlite3_mprintf("%s" , sqlite3_column_text(pStmt, 0)); |
21977 | }else |
21978 | *pzRenamed = 0; |
21979 | } |
21980 | } |
21981 | sqlite3_finalize(pStmt); |
21982 | sqlite3_close(*pDb); |
21983 | *pDb = 0; |
21984 | return zColsSpec; |
21985 | } |
21986 | } |
21987 | |
21988 | /* |
21989 | ** If an input line begins with "." then invoke this routine to |
21990 | ** process that line. |
21991 | ** |
21992 | ** Return 1 on error, 2 to exit, and 0 otherwise. |
21993 | */ |
21994 | static int do_meta_command(char *zLine, ShellState *p){ |
21995 | int h = 1; |
21996 | int nArg = 0; |
21997 | int n, c; |
21998 | int rc = 0; |
21999 | char *azArg[52]; |
22000 | |
22001 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
22002 | if( p->expert.pExpert ){ |
22003 | expertFinish(p, 1, 0); |
22004 | } |
22005 | #endif |
22006 | |
22007 | /* Parse the input line into tokens. |
22008 | */ |
22009 | while( zLine[h] && nArg<ArraySize(azArg)-1 ){ |
22010 | while( IsSpace(zLine[h]) ){ h++; } |
22011 | if( zLine[h]==0 ) break; |
22012 | if( zLine[h]=='\'' || zLine[h]=='"' ){ |
22013 | int delim = zLine[h++]; |
22014 | azArg[nArg++] = &zLine[h]; |
22015 | while( zLine[h] && zLine[h]!=delim ){ |
22016 | if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++; |
22017 | h++; |
22018 | } |
22019 | if( zLine[h]==delim ){ |
22020 | zLine[h++] = 0; |
22021 | } |
22022 | if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); |
22023 | }else{ |
22024 | azArg[nArg++] = &zLine[h]; |
22025 | while( zLine[h] && !IsSpace(zLine[h]) ){ h++; } |
22026 | if( zLine[h] ) zLine[h++] = 0; |
22027 | resolve_backslashes(azArg[nArg-1]); |
22028 | } |
22029 | } |
22030 | azArg[nArg] = 0; |
22031 | |
22032 | /* Process the input line. |
22033 | */ |
22034 | if( nArg==0 ) return 0; /* no tokens, no error */ |
22035 | n = strlen30(azArg[0]); |
22036 | c = azArg[0][0]; |
22037 | clearTempFile(p); |
22038 | |
22039 | #ifndef SQLITE_OMIT_AUTHORIZATION |
22040 | if( c=='a' && cli_strncmp(azArg[0], "auth" , n)==0 ){ |
22041 | if( nArg!=2 ){ |
22042 | raw_printf(stderr, "Usage: .auth ON|OFF\n" ); |
22043 | rc = 1; |
22044 | goto meta_command_exit; |
22045 | } |
22046 | open_db(p, 0); |
22047 | if( booleanValue(azArg[1]) ){ |
22048 | sqlite3_set_authorizer(p->db, shellAuth, p); |
22049 | }else if( p->bSafeModePersist ){ |
22050 | sqlite3_set_authorizer(p->db, safeModeAuth, p); |
22051 | }else{ |
22052 | sqlite3_set_authorizer(p->db, 0, 0); |
22053 | } |
22054 | }else |
22055 | #endif |
22056 | |
22057 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) \ |
22058 | && !defined(SQLITE_SHELL_FIDDLE) |
22059 | if( c=='a' && cli_strncmp(azArg[0], "archive" , n)==0 ){ |
22060 | open_db(p, 0); |
22061 | failIfSafeMode(p, "cannot run .archive in safe mode" ); |
22062 | rc = arDotCommand(p, 0, azArg, nArg); |
22063 | }else |
22064 | #endif |
22065 | |
22066 | #ifndef SQLITE_SHELL_FIDDLE |
22067 | if( (c=='b' && n>=3 && cli_strncmp(azArg[0], "backup" , n)==0) |
22068 | || (c=='s' && n>=3 && cli_strncmp(azArg[0], "save" , n)==0) |
22069 | ){ |
22070 | const char *zDestFile = 0; |
22071 | const char *zDb = 0; |
22072 | sqlite3 *pDest; |
22073 | sqlite3_backup *pBackup; |
22074 | int j; |
22075 | int bAsync = 0; |
22076 | const char *zVfs = 0; |
22077 | failIfSafeMode(p, "cannot run .%s in safe mode" , azArg[0]); |
22078 | for(j=1; j<nArg; j++){ |
22079 | const char *z = azArg[j]; |
22080 | if( z[0]=='-' ){ |
22081 | if( z[1]=='-' ) z++; |
22082 | if( cli_strcmp(z, "-append" )==0 ){ |
22083 | zVfs = "apndvfs" ; |
22084 | }else |
22085 | if( cli_strcmp(z, "-async" )==0 ){ |
22086 | bAsync = 1; |
22087 | }else |
22088 | { |
22089 | utf8_printf(stderr, "unknown option: %s\n" , azArg[j]); |
22090 | return 1; |
22091 | } |
22092 | }else if( zDestFile==0 ){ |
22093 | zDestFile = azArg[j]; |
22094 | }else if( zDb==0 ){ |
22095 | zDb = zDestFile; |
22096 | zDestFile = azArg[j]; |
22097 | }else{ |
22098 | raw_printf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n" ); |
22099 | return 1; |
22100 | } |
22101 | } |
22102 | if( zDestFile==0 ){ |
22103 | raw_printf(stderr, "missing FILENAME argument on .backup\n" ); |
22104 | return 1; |
22105 | } |
22106 | if( zDb==0 ) zDb = "main" ; |
22107 | rc = sqlite3_open_v2(zDestFile, &pDest, |
22108 | SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs); |
22109 | if( rc!=SQLITE_OK ){ |
22110 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , zDestFile); |
22111 | close_db(pDest); |
22112 | return 1; |
22113 | } |
22114 | if( bAsync ){ |
22115 | sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;" , |
22116 | 0, 0, 0); |
22117 | } |
22118 | open_db(p, 0); |
22119 | pBackup = sqlite3_backup_init(pDest, "main" , p->db, zDb); |
22120 | if( pBackup==0 ){ |
22121 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(pDest)); |
22122 | close_db(pDest); |
22123 | return 1; |
22124 | } |
22125 | while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} |
22126 | sqlite3_backup_finish(pBackup); |
22127 | if( rc==SQLITE_DONE ){ |
22128 | rc = 0; |
22129 | }else{ |
22130 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(pDest)); |
22131 | rc = 1; |
22132 | } |
22133 | close_db(pDest); |
22134 | }else |
22135 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
22136 | |
22137 | if( c=='b' && n>=3 && cli_strncmp(azArg[0], "bail" , n)==0 ){ |
22138 | if( nArg==2 ){ |
22139 | bail_on_error = booleanValue(azArg[1]); |
22140 | }else{ |
22141 | raw_printf(stderr, "Usage: .bail on|off\n" ); |
22142 | rc = 1; |
22143 | } |
22144 | }else |
22145 | |
22146 | if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary" , n)==0 ){ |
22147 | if( nArg==2 ){ |
22148 | if( booleanValue(azArg[1]) ){ |
22149 | setBinaryMode(p->out, 1); |
22150 | }else{ |
22151 | setTextMode(p->out, 1); |
22152 | } |
22153 | }else{ |
22154 | raw_printf(stderr, "Usage: .binary on|off\n" ); |
22155 | rc = 1; |
22156 | } |
22157 | }else |
22158 | |
22159 | /* The undocumented ".breakpoint" command causes a call to the no-op |
22160 | ** routine named test_breakpoint(). |
22161 | */ |
22162 | if( c=='b' && n>=3 && cli_strncmp(azArg[0], "breakpoint" , n)==0 ){ |
22163 | test_breakpoint(); |
22164 | }else |
22165 | |
22166 | #ifndef SQLITE_SHELL_FIDDLE |
22167 | if( c=='c' && cli_strcmp(azArg[0],"cd" )==0 ){ |
22168 | failIfSafeMode(p, "cannot run .cd in safe mode" ); |
22169 | if( nArg==2 ){ |
22170 | #if defined(_WIN32) || defined(WIN32) |
22171 | wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]); |
22172 | rc = !SetCurrentDirectoryW(z); |
22173 | sqlite3_free(z); |
22174 | #else |
22175 | rc = chdir(azArg[1]); |
22176 | #endif |
22177 | if( rc ){ |
22178 | utf8_printf(stderr, "Cannot change to directory \"%s\"\n" , azArg[1]); |
22179 | rc = 1; |
22180 | } |
22181 | }else{ |
22182 | raw_printf(stderr, "Usage: .cd DIRECTORY\n" ); |
22183 | rc = 1; |
22184 | } |
22185 | }else |
22186 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
22187 | |
22188 | if( c=='c' && n>=3 && cli_strncmp(azArg[0], "changes" , n)==0 ){ |
22189 | if( nArg==2 ){ |
22190 | setOrClearFlag(p, SHFLG_CountChanges, azArg[1]); |
22191 | }else{ |
22192 | raw_printf(stderr, "Usage: .changes on|off\n" ); |
22193 | rc = 1; |
22194 | } |
22195 | }else |
22196 | |
22197 | #ifndef SQLITE_SHELL_FIDDLE |
22198 | /* Cancel output redirection, if it is currently set (by .testcase) |
22199 | ** Then read the content of the testcase-out.txt file and compare against |
22200 | ** azArg[1]. If there are differences, report an error and exit. |
22201 | */ |
22202 | if( c=='c' && n>=3 && cli_strncmp(azArg[0], "check" , n)==0 ){ |
22203 | char *zRes = 0; |
22204 | output_reset(p); |
22205 | if( nArg!=2 ){ |
22206 | raw_printf(stderr, "Usage: .check GLOB-PATTERN\n" ); |
22207 | rc = 2; |
22208 | }else if( (zRes = readFile("testcase-out.txt" , 0))==0 ){ |
22209 | raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n" ); |
22210 | rc = 2; |
22211 | }else if( testcase_glob(azArg[1],zRes)==0 ){ |
22212 | utf8_printf(stderr, |
22213 | "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n" , |
22214 | p->zTestcase, azArg[1], zRes); |
22215 | rc = 1; |
22216 | }else{ |
22217 | utf8_printf(stdout, "testcase-%s ok\n" , p->zTestcase); |
22218 | p->nCheck++; |
22219 | } |
22220 | sqlite3_free(zRes); |
22221 | }else |
22222 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
22223 | |
22224 | #ifndef SQLITE_SHELL_FIDDLE |
22225 | if( c=='c' && cli_strncmp(azArg[0], "clone" , n)==0 ){ |
22226 | failIfSafeMode(p, "cannot run .clone in safe mode" ); |
22227 | if( nArg==2 ){ |
22228 | tryToClone(p, azArg[1]); |
22229 | }else{ |
22230 | raw_printf(stderr, "Usage: .clone FILENAME\n" ); |
22231 | rc = 1; |
22232 | } |
22233 | }else |
22234 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
22235 | |
22236 | if( c=='c' && cli_strncmp(azArg[0], "connection" , n)==0 ){ |
22237 | if( nArg==1 ){ |
22238 | /* List available connections */ |
22239 | int i; |
22240 | for(i=0; i<ArraySize(p->aAuxDb); i++){ |
22241 | const char *zFile = p->aAuxDb[i].zDbFilename; |
22242 | if( p->aAuxDb[i].db==0 && p->pAuxDb!=&p->aAuxDb[i] ){ |
22243 | zFile = "(not open)" ; |
22244 | }else if( zFile==0 ){ |
22245 | zFile = "(memory)" ; |
22246 | }else if( zFile[0]==0 ){ |
22247 | zFile = "(temporary-file)" ; |
22248 | } |
22249 | if( p->pAuxDb == &p->aAuxDb[i] ){ |
22250 | utf8_printf(stdout, "ACTIVE %d: %s\n" , i, zFile); |
22251 | }else if( p->aAuxDb[i].db!=0 ){ |
22252 | utf8_printf(stdout, " %d: %s\n" , i, zFile); |
22253 | } |
22254 | } |
22255 | }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){ |
22256 | int i = azArg[1][0] - '0'; |
22257 | if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && i<ArraySize(p->aAuxDb) ){ |
22258 | p->pAuxDb->db = p->db; |
22259 | p->pAuxDb = &p->aAuxDb[i]; |
22260 | globalDb = p->db = p->pAuxDb->db; |
22261 | p->pAuxDb->db = 0; |
22262 | } |
22263 | }else if( nArg==3 && cli_strcmp(azArg[1], "close" )==0 |
22264 | && IsDigit(azArg[2][0]) && azArg[2][1]==0 ){ |
22265 | int i = azArg[2][0] - '0'; |
22266 | if( i<0 || i>=ArraySize(p->aAuxDb) ){ |
22267 | /* No-op */ |
22268 | }else if( p->pAuxDb == &p->aAuxDb[i] ){ |
22269 | raw_printf(stderr, "cannot close the active database connection\n" ); |
22270 | rc = 1; |
22271 | }else if( p->aAuxDb[i].db ){ |
22272 | session_close_all(p, i); |
22273 | close_db(p->aAuxDb[i].db); |
22274 | p->aAuxDb[i].db = 0; |
22275 | } |
22276 | }else{ |
22277 | raw_printf(stderr, "Usage: .connection [close] [CONNECTION-NUMBER]\n" ); |
22278 | rc = 1; |
22279 | } |
22280 | }else |
22281 | |
22282 | if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases" , n)==0 ){ |
22283 | char **azName = 0; |
22284 | int nName = 0; |
22285 | sqlite3_stmt *pStmt; |
22286 | int i; |
22287 | open_db(p, 0); |
22288 | rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list" , -1, &pStmt, 0); |
22289 | if( rc ){ |
22290 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
22291 | rc = 1; |
22292 | }else{ |
22293 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
22294 | const char *zSchema = (const char *)sqlite3_column_text(pStmt,1); |
22295 | const char *zFile = (const char*)sqlite3_column_text(pStmt,2); |
22296 | if( zSchema==0 || zFile==0 ) continue; |
22297 | azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*)); |
22298 | shell_check_oom(azName); |
22299 | azName[nName*2] = strdup(zSchema); |
22300 | azName[nName*2+1] = strdup(zFile); |
22301 | nName++; |
22302 | } |
22303 | } |
22304 | sqlite3_finalize(pStmt); |
22305 | for(i=0; i<nName; i++){ |
22306 | int eTxn = sqlite3_txn_state(p->db, azName[i*2]); |
22307 | int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]); |
22308 | const char *z = azName[i*2+1]; |
22309 | utf8_printf(p->out, "%s: %s %s%s\n" , |
22310 | azName[i*2], |
22311 | z && z[0] ? z : "\"\"" , |
22312 | bRdonly ? "r/o" : "r/w" , |
22313 | eTxn==SQLITE_TXN_NONE ? "" : |
22314 | eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn" ); |
22315 | free(azName[i*2]); |
22316 | free(azName[i*2+1]); |
22317 | } |
22318 | sqlite3_free(azName); |
22319 | }else |
22320 | |
22321 | if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbconfig" , n)==0 ){ |
22322 | static const struct DbConfigChoices { |
22323 | const char *zName; |
22324 | int op; |
22325 | } aDbConfig[] = { |
22326 | { "defensive" , SQLITE_DBCONFIG_DEFENSIVE }, |
22327 | { "dqs_ddl" , SQLITE_DBCONFIG_DQS_DDL }, |
22328 | { "dqs_dml" , SQLITE_DBCONFIG_DQS_DML }, |
22329 | { "enable_fkey" , SQLITE_DBCONFIG_ENABLE_FKEY }, |
22330 | { "enable_qpsg" , SQLITE_DBCONFIG_ENABLE_QPSG }, |
22331 | { "enable_trigger" , SQLITE_DBCONFIG_ENABLE_TRIGGER }, |
22332 | { "enable_view" , SQLITE_DBCONFIG_ENABLE_VIEW }, |
22333 | { "fts3_tokenizer" , SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, |
22334 | { "legacy_alter_table" , SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, |
22335 | { "legacy_file_format" , SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, |
22336 | { "load_extension" , SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, |
22337 | { "no_ckpt_on_close" , SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, |
22338 | { "reset_database" , SQLITE_DBCONFIG_RESET_DATABASE }, |
22339 | { "trigger_eqp" , SQLITE_DBCONFIG_TRIGGER_EQP }, |
22340 | { "trusted_schema" , SQLITE_DBCONFIG_TRUSTED_SCHEMA }, |
22341 | { "writable_schema" , SQLITE_DBCONFIG_WRITABLE_SCHEMA }, |
22342 | }; |
22343 | int ii, v; |
22344 | open_db(p, 0); |
22345 | for(ii=0; ii<ArraySize(aDbConfig); ii++){ |
22346 | if( nArg>1 && cli_strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue; |
22347 | if( nArg>=3 ){ |
22348 | sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); |
22349 | } |
22350 | sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); |
22351 | utf8_printf(p->out, "%19s %s\n" , aDbConfig[ii].zName, v ? "on" : "off" ); |
22352 | if( nArg>1 ) break; |
22353 | } |
22354 | if( nArg>1 && ii==ArraySize(aDbConfig) ){ |
22355 | utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n" , azArg[1]); |
22356 | utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n" ); |
22357 | } |
22358 | }else |
22359 | |
22360 | #if SQLITE_SHELL_HAVE_RECOVER |
22361 | if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo" , n)==0 ){ |
22362 | rc = shell_dbinfo_command(p, nArg, azArg); |
22363 | }else |
22364 | |
22365 | if( c=='r' && cli_strncmp(azArg[0], "recover" , n)==0 ){ |
22366 | open_db(p, 0); |
22367 | rc = recoverDatabaseCmd(p, nArg, azArg); |
22368 | }else |
22369 | #endif /* SQLITE_SHELL_HAVE_RECOVER */ |
22370 | |
22371 | if( c=='d' && cli_strncmp(azArg[0], "dump" , n)==0 ){ |
22372 | char *zLike = 0; |
22373 | char *zSql; |
22374 | int i; |
22375 | int = p->showHeader; |
22376 | int savedShellFlags = p->shellFlgs; |
22377 | ShellClearFlag(p, |
22378 | SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo |
22379 | |SHFLG_DumpDataOnly|SHFLG_DumpNoSys); |
22380 | for(i=1; i<nArg; i++){ |
22381 | if( azArg[i][0]=='-' ){ |
22382 | const char *z = azArg[i]+1; |
22383 | if( z[0]=='-' ) z++; |
22384 | if( cli_strcmp(z,"preserve-rowids" )==0 ){ |
22385 | #ifdef SQLITE_OMIT_VIRTUALTABLE |
22386 | raw_printf(stderr, "The --preserve-rowids option is not compatible" |
22387 | " with SQLITE_OMIT_VIRTUALTABLE\n" ); |
22388 | rc = 1; |
22389 | sqlite3_free(zLike); |
22390 | goto meta_command_exit; |
22391 | #else |
22392 | ShellSetFlag(p, SHFLG_PreserveRowid); |
22393 | #endif |
22394 | }else |
22395 | if( cli_strcmp(z,"newlines" )==0 ){ |
22396 | ShellSetFlag(p, SHFLG_Newlines); |
22397 | }else |
22398 | if( cli_strcmp(z,"data-only" )==0 ){ |
22399 | ShellSetFlag(p, SHFLG_DumpDataOnly); |
22400 | }else |
22401 | if( cli_strcmp(z,"nosys" )==0 ){ |
22402 | ShellSetFlag(p, SHFLG_DumpNoSys); |
22403 | }else |
22404 | { |
22405 | raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n" , azArg[i]); |
22406 | rc = 1; |
22407 | sqlite3_free(zLike); |
22408 | goto meta_command_exit; |
22409 | } |
22410 | }else{ |
22411 | /* azArg[i] contains a LIKE pattern. This ".dump" request should |
22412 | ** only dump data for tables for which either the table name matches |
22413 | ** the LIKE pattern, or the table appears to be a shadow table of |
22414 | ** a virtual table for which the name matches the LIKE pattern. |
22415 | */ |
22416 | char *zExpr = sqlite3_mprintf( |
22417 | "name LIKE %Q ESCAPE '\\' OR EXISTS (" |
22418 | " SELECT 1 FROM sqlite_schema WHERE " |
22419 | " name LIKE %Q ESCAPE '\\' AND" |
22420 | " sql LIKE 'CREATE VIRTUAL TABLE%%' AND" |
22421 | " substr(o.name, 1, length(name)+1) == (name||'_')" |
22422 | ")" , azArg[i], azArg[i] |
22423 | ); |
22424 | |
22425 | if( zLike ){ |
22426 | zLike = sqlite3_mprintf("%z OR %z" , zLike, zExpr); |
22427 | }else{ |
22428 | zLike = zExpr; |
22429 | } |
22430 | } |
22431 | } |
22432 | |
22433 | open_db(p, 0); |
22434 | |
22435 | if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ |
22436 | /* When playing back a "dump", the content might appear in an order |
22437 | ** which causes immediate foreign key constraints to be violated. |
22438 | ** So disable foreign-key constraint enforcement to prevent problems. */ |
22439 | raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n" ); |
22440 | raw_printf(p->out, "BEGIN TRANSACTION;\n" ); |
22441 | } |
22442 | p->writableSchema = 0; |
22443 | p->showHeader = 0; |
22444 | /* Set writable_schema=ON since doing so forces SQLite to initialize |
22445 | ** as much of the schema as it can even if the sqlite_schema table is |
22446 | ** corrupt. */ |
22447 | sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON" , 0, 0, 0); |
22448 | p->nErr = 0; |
22449 | if( zLike==0 ) zLike = sqlite3_mprintf("true" ); |
22450 | zSql = sqlite3_mprintf( |
22451 | "SELECT name, type, sql FROM sqlite_schema AS o " |
22452 | "WHERE (%s) AND type=='table'" |
22453 | " AND sql NOT NULL" |
22454 | " ORDER BY tbl_name='sqlite_sequence', rowid" , |
22455 | zLike |
22456 | ); |
22457 | run_schema_dump_query(p,zSql); |
22458 | sqlite3_free(zSql); |
22459 | if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ |
22460 | zSql = sqlite3_mprintf( |
22461 | "SELECT sql FROM sqlite_schema AS o " |
22462 | "WHERE (%s) AND sql NOT NULL" |
22463 | " AND type IN ('index','trigger','view')" , |
22464 | zLike |
22465 | ); |
22466 | run_table_dump_query(p, zSql); |
22467 | sqlite3_free(zSql); |
22468 | } |
22469 | sqlite3_free(zLike); |
22470 | if( p->writableSchema ){ |
22471 | raw_printf(p->out, "PRAGMA writable_schema=OFF;\n" ); |
22472 | p->writableSchema = 0; |
22473 | } |
22474 | sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;" , 0, 0, 0); |
22475 | sqlite3_exec(p->db, "RELEASE dump;" , 0, 0, 0); |
22476 | if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ |
22477 | raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n" :"COMMIT;\n" ); |
22478 | } |
22479 | p->showHeader = savedShowHeader; |
22480 | p->shellFlgs = savedShellFlags; |
22481 | }else |
22482 | |
22483 | if( c=='e' && cli_strncmp(azArg[0], "echo" , n)==0 ){ |
22484 | if( nArg==2 ){ |
22485 | setOrClearFlag(p, SHFLG_Echo, azArg[1]); |
22486 | }else{ |
22487 | raw_printf(stderr, "Usage: .echo on|off\n" ); |
22488 | rc = 1; |
22489 | } |
22490 | }else |
22491 | |
22492 | if( c=='e' && cli_strncmp(azArg[0], "eqp" , n)==0 ){ |
22493 | if( nArg==2 ){ |
22494 | p->autoEQPtest = 0; |
22495 | if( p->autoEQPtrace ){ |
22496 | if( p->db ) sqlite3_exec(p->db, "PRAGMA vdbe_trace=OFF;" , 0, 0, 0); |
22497 | p->autoEQPtrace = 0; |
22498 | } |
22499 | if( cli_strcmp(azArg[1],"full" )==0 ){ |
22500 | p->autoEQP = AUTOEQP_full; |
22501 | }else if( cli_strcmp(azArg[1],"trigger" )==0 ){ |
22502 | p->autoEQP = AUTOEQP_trigger; |
22503 | #ifdef SQLITE_DEBUG |
22504 | }else if( cli_strcmp(azArg[1],"test" )==0 ){ |
22505 | p->autoEQP = AUTOEQP_on; |
22506 | p->autoEQPtest = 1; |
22507 | }else if( cli_strcmp(azArg[1],"trace" )==0 ){ |
22508 | p->autoEQP = AUTOEQP_full; |
22509 | p->autoEQPtrace = 1; |
22510 | open_db(p, 0); |
22511 | sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1" , 0, 0, 0); |
22512 | sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;" , 0, 0, 0); |
22513 | #endif |
22514 | }else{ |
22515 | p->autoEQP = (u8)booleanValue(azArg[1]); |
22516 | } |
22517 | }else{ |
22518 | raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n" ); |
22519 | rc = 1; |
22520 | } |
22521 | }else |
22522 | |
22523 | #ifndef SQLITE_SHELL_FIDDLE |
22524 | if( c=='e' && cli_strncmp(azArg[0], "exit" , n)==0 ){ |
22525 | if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc); |
22526 | rc = 2; |
22527 | }else |
22528 | #endif |
22529 | |
22530 | /* The ".explain" command is automatic now. It is largely pointless. It |
22531 | ** retained purely for backwards compatibility */ |
22532 | if( c=='e' && cli_strncmp(azArg[0], "explain" , n)==0 ){ |
22533 | int val = 1; |
22534 | if( nArg>=2 ){ |
22535 | if( cli_strcmp(azArg[1],"auto" )==0 ){ |
22536 | val = 99; |
22537 | }else{ |
22538 | val = booleanValue(azArg[1]); |
22539 | } |
22540 | } |
22541 | if( val==1 && p->mode!=MODE_Explain ){ |
22542 | p->normalMode = p->mode; |
22543 | p->mode = MODE_Explain; |
22544 | p->autoExplain = 0; |
22545 | }else if( val==0 ){ |
22546 | if( p->mode==MODE_Explain ) p->mode = p->normalMode; |
22547 | p->autoExplain = 0; |
22548 | }else if( val==99 ){ |
22549 | if( p->mode==MODE_Explain ) p->mode = p->normalMode; |
22550 | p->autoExplain = 1; |
22551 | } |
22552 | }else |
22553 | |
22554 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
22555 | if( c=='e' && cli_strncmp(azArg[0], "expert" , n)==0 ){ |
22556 | if( p->bSafeMode ){ |
22557 | raw_printf(stderr, |
22558 | "Cannot run experimental commands such as \"%s\" in safe mode\n" , |
22559 | azArg[0]); |
22560 | rc = 1; |
22561 | }else{ |
22562 | open_db(p, 0); |
22563 | expertDotCommand(p, azArg, nArg); |
22564 | } |
22565 | }else |
22566 | #endif |
22567 | |
22568 | if( c=='f' && cli_strncmp(azArg[0], "filectrl" , n)==0 ){ |
22569 | static const struct { |
22570 | const char *zCtrlName; /* Name of a test-control option */ |
22571 | int ctrlCode; /* Integer code for that option */ |
22572 | const char *zUsage; /* Usage notes */ |
22573 | } aCtrl[] = { |
22574 | { "chunk_size" , SQLITE_FCNTL_CHUNK_SIZE, "SIZE" }, |
22575 | { "data_version" , SQLITE_FCNTL_DATA_VERSION, "" }, |
22576 | { "has_moved" , SQLITE_FCNTL_HAS_MOVED, "" }, |
22577 | { "lock_timeout" , SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" }, |
22578 | { "persist_wal" , SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, |
22579 | /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ |
22580 | { "psow" , SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, |
22581 | { "reserve_bytes" , SQLITE_FCNTL_RESERVE_BYTES, "[N]" }, |
22582 | { "size_limit" , SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, |
22583 | { "tempfilename" , SQLITE_FCNTL_TEMPFILENAME, "" }, |
22584 | /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ |
22585 | }; |
22586 | int filectrl = -1; |
22587 | int iCtrl = -1; |
22588 | sqlite3_int64 iRes = 0; /* Integer result to display if rc2==1 */ |
22589 | int isOk = 0; /* 0: usage 1: %lld 2: no-result */ |
22590 | int n2, i; |
22591 | const char *zCmd = 0; |
22592 | const char *zSchema = 0; |
22593 | |
22594 | open_db(p, 0); |
22595 | zCmd = nArg>=2 ? azArg[1] : "help" ; |
22596 | |
22597 | if( zCmd[0]=='-' |
22598 | && (cli_strcmp(zCmd,"--schema" )==0 || cli_strcmp(zCmd,"-schema" )==0) |
22599 | && nArg>=4 |
22600 | ){ |
22601 | zSchema = azArg[2]; |
22602 | for(i=3; i<nArg; i++) azArg[i-2] = azArg[i]; |
22603 | nArg -= 2; |
22604 | zCmd = azArg[1]; |
22605 | } |
22606 | |
22607 | /* The argument can optionally begin with "-" or "--" */ |
22608 | if( zCmd[0]=='-' && zCmd[1] ){ |
22609 | zCmd++; |
22610 | if( zCmd[0]=='-' && zCmd[1] ) zCmd++; |
22611 | } |
22612 | |
22613 | /* --help lists all file-controls */ |
22614 | if( cli_strcmp(zCmd,"help" )==0 ){ |
22615 | utf8_printf(p->out, "Available file-controls:\n" ); |
22616 | for(i=0; i<ArraySize(aCtrl); i++){ |
22617 | utf8_printf(p->out, " .filectrl %s %s\n" , |
22618 | aCtrl[i].zCtrlName, aCtrl[i].zUsage); |
22619 | } |
22620 | rc = 1; |
22621 | goto meta_command_exit; |
22622 | } |
22623 | |
22624 | /* convert filectrl text option to value. allow any unique prefix |
22625 | ** of the option name, or a numerical value. */ |
22626 | n2 = strlen30(zCmd); |
22627 | for(i=0; i<ArraySize(aCtrl); i++){ |
22628 | if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){ |
22629 | if( filectrl<0 ){ |
22630 | filectrl = aCtrl[i].ctrlCode; |
22631 | iCtrl = i; |
22632 | }else{ |
22633 | utf8_printf(stderr, "Error: ambiguous file-control: \"%s\"\n" |
22634 | "Use \".filectrl --help\" for help\n" , zCmd); |
22635 | rc = 1; |
22636 | goto meta_command_exit; |
22637 | } |
22638 | } |
22639 | } |
22640 | if( filectrl<0 ){ |
22641 | utf8_printf(stderr,"Error: unknown file-control: %s\n" |
22642 | "Use \".filectrl --help\" for help\n" , zCmd); |
22643 | }else{ |
22644 | switch(filectrl){ |
22645 | case SQLITE_FCNTL_SIZE_LIMIT: { |
22646 | if( nArg!=2 && nArg!=3 ) break; |
22647 | iRes = nArg==3 ? integerValue(azArg[2]) : -1; |
22648 | sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes); |
22649 | isOk = 1; |
22650 | break; |
22651 | } |
22652 | case SQLITE_FCNTL_LOCK_TIMEOUT: |
22653 | case SQLITE_FCNTL_CHUNK_SIZE: { |
22654 | int x; |
22655 | if( nArg!=3 ) break; |
22656 | x = (int)integerValue(azArg[2]); |
22657 | sqlite3_file_control(p->db, zSchema, filectrl, &x); |
22658 | isOk = 2; |
22659 | break; |
22660 | } |
22661 | case SQLITE_FCNTL_PERSIST_WAL: |
22662 | case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { |
22663 | int x; |
22664 | if( nArg!=2 && nArg!=3 ) break; |
22665 | x = nArg==3 ? booleanValue(azArg[2]) : -1; |
22666 | sqlite3_file_control(p->db, zSchema, filectrl, &x); |
22667 | iRes = x; |
22668 | isOk = 1; |
22669 | break; |
22670 | } |
22671 | case SQLITE_FCNTL_DATA_VERSION: |
22672 | case SQLITE_FCNTL_HAS_MOVED: { |
22673 | int x; |
22674 | if( nArg!=2 ) break; |
22675 | sqlite3_file_control(p->db, zSchema, filectrl, &x); |
22676 | iRes = x; |
22677 | isOk = 1; |
22678 | break; |
22679 | } |
22680 | case SQLITE_FCNTL_TEMPFILENAME: { |
22681 | char *z = 0; |
22682 | if( nArg!=2 ) break; |
22683 | sqlite3_file_control(p->db, zSchema, filectrl, &z); |
22684 | if( z ){ |
22685 | utf8_printf(p->out, "%s\n" , z); |
22686 | sqlite3_free(z); |
22687 | } |
22688 | isOk = 2; |
22689 | break; |
22690 | } |
22691 | case SQLITE_FCNTL_RESERVE_BYTES: { |
22692 | int x; |
22693 | if( nArg>=3 ){ |
22694 | x = atoi(azArg[2]); |
22695 | sqlite3_file_control(p->db, zSchema, filectrl, &x); |
22696 | } |
22697 | x = -1; |
22698 | sqlite3_file_control(p->db, zSchema, filectrl, &x); |
22699 | utf8_printf(p->out,"%d\n" , x); |
22700 | isOk = 2; |
22701 | break; |
22702 | } |
22703 | } |
22704 | } |
22705 | if( isOk==0 && iCtrl>=0 ){ |
22706 | utf8_printf(p->out, "Usage: .filectrl %s %s\n" , zCmd,aCtrl[iCtrl].zUsage); |
22707 | rc = 1; |
22708 | }else if( isOk==1 ){ |
22709 | char zBuf[100]; |
22710 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld" , iRes); |
22711 | raw_printf(p->out, "%s\n" , zBuf); |
22712 | } |
22713 | }else |
22714 | |
22715 | if( c=='f' && cli_strncmp(azArg[0], "fullschema" , n)==0 ){ |
22716 | ShellState data; |
22717 | int doStats = 0; |
22718 | memcpy(&data, p, sizeof(data)); |
22719 | data.showHeader = 0; |
22720 | data.cMode = data.mode = MODE_Semi; |
22721 | if( nArg==2 && optionMatch(azArg[1], "indent" ) ){ |
22722 | data.cMode = data.mode = MODE_Pretty; |
22723 | nArg = 1; |
22724 | } |
22725 | if( nArg!=1 ){ |
22726 | raw_printf(stderr, "Usage: .fullschema ?--indent?\n" ); |
22727 | rc = 1; |
22728 | goto meta_command_exit; |
22729 | } |
22730 | open_db(p, 0); |
22731 | rc = sqlite3_exec(p->db, |
22732 | "SELECT sql FROM" |
22733 | " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" |
22734 | " FROM sqlite_schema UNION ALL" |
22735 | " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) " |
22736 | "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' " |
22737 | "ORDER BY x" , |
22738 | callback, &data, 0 |
22739 | ); |
22740 | if( rc==SQLITE_OK ){ |
22741 | sqlite3_stmt *pStmt; |
22742 | rc = sqlite3_prepare_v2(p->db, |
22743 | "SELECT rowid FROM sqlite_schema" |
22744 | " WHERE name GLOB 'sqlite_stat[134]'" , |
22745 | -1, &pStmt, 0); |
22746 | doStats = sqlite3_step(pStmt)==SQLITE_ROW; |
22747 | sqlite3_finalize(pStmt); |
22748 | } |
22749 | if( doStats==0 ){ |
22750 | raw_printf(p->out, "/* No STAT tables available */\n" ); |
22751 | }else{ |
22752 | raw_printf(p->out, "ANALYZE sqlite_schema;\n" ); |
22753 | data.cMode = data.mode = MODE_Insert; |
22754 | data.zDestTable = "sqlite_stat1" ; |
22755 | shell_exec(&data, "SELECT * FROM sqlite_stat1" , 0); |
22756 | data.zDestTable = "sqlite_stat4" ; |
22757 | shell_exec(&data, "SELECT * FROM sqlite_stat4" , 0); |
22758 | raw_printf(p->out, "ANALYZE sqlite_schema;\n" ); |
22759 | } |
22760 | }else |
22761 | |
22762 | if( c=='h' && cli_strncmp(azArg[0], "headers" , n)==0 ){ |
22763 | if( nArg==2 ){ |
22764 | p->showHeader = booleanValue(azArg[1]); |
22765 | p->shellFlgs |= SHFLG_HeaderSet; |
22766 | }else{ |
22767 | raw_printf(stderr, "Usage: .headers on|off\n" ); |
22768 | rc = 1; |
22769 | } |
22770 | }else |
22771 | |
22772 | if( c=='h' && cli_strncmp(azArg[0], "help" , n)==0 ){ |
22773 | if( nArg>=2 ){ |
22774 | n = showHelp(p->out, azArg[1]); |
22775 | if( n==0 ){ |
22776 | utf8_printf(p->out, "Nothing matches '%s'\n" , azArg[1]); |
22777 | } |
22778 | }else{ |
22779 | showHelp(p->out, 0); |
22780 | } |
22781 | }else |
22782 | |
22783 | #ifndef SQLITE_SHELL_FIDDLE |
22784 | if( c=='i' && cli_strncmp(azArg[0], "import" , n)==0 ){ |
22785 | char *zTable = 0; /* Insert data into this table */ |
22786 | char *zSchema = 0; /* within this schema (may default to "main") */ |
22787 | char *zFile = 0; /* Name of file to extra content from */ |
22788 | sqlite3_stmt *pStmt = NULL; /* A statement */ |
22789 | int nCol; /* Number of columns in the table */ |
22790 | int nByte; /* Number of bytes in an SQL string */ |
22791 | int i, j; /* Loop counters */ |
22792 | int needCommit; /* True to COMMIT or ROLLBACK at end */ |
22793 | int nSep; /* Number of bytes in p->colSeparator[] */ |
22794 | char *zSql; /* An SQL statement */ |
22795 | char *zFullTabName; /* Table name with schema if applicable */ |
22796 | ImportCtx sCtx; /* Reader context */ |
22797 | char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ |
22798 | int eVerbose = 0; /* Larger for more console output */ |
22799 | int nSkip = 0; /* Initial lines to skip */ |
22800 | int useOutputMode = 1; /* Use output mode to determine separators */ |
22801 | char *zCreate = 0; /* CREATE TABLE statement text */ |
22802 | |
22803 | failIfSafeMode(p, "cannot run .import in safe mode" ); |
22804 | memset(&sCtx, 0, sizeof(sCtx)); |
22805 | if( p->mode==MODE_Ascii ){ |
22806 | xRead = ascii_read_one_field; |
22807 | }else{ |
22808 | xRead = csv_read_one_field; |
22809 | } |
22810 | rc = 1; |
22811 | for(i=1; i<nArg; i++){ |
22812 | char *z = azArg[i]; |
22813 | if( z[0]=='-' && z[1]=='-' ) z++; |
22814 | if( z[0]!='-' ){ |
22815 | if( zFile==0 ){ |
22816 | zFile = z; |
22817 | }else if( zTable==0 ){ |
22818 | zTable = z; |
22819 | }else{ |
22820 | utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n" , z); |
22821 | showHelp(p->out, "import" ); |
22822 | goto meta_command_exit; |
22823 | } |
22824 | }else if( cli_strcmp(z,"-v" )==0 ){ |
22825 | eVerbose++; |
22826 | }else if( cli_strcmp(z,"-schema" )==0 && i<nArg-1 ){ |
22827 | zSchema = azArg[++i]; |
22828 | }else if( cli_strcmp(z,"-skip" )==0 && i<nArg-1 ){ |
22829 | nSkip = integerValue(azArg[++i]); |
22830 | }else if( cli_strcmp(z,"-ascii" )==0 ){ |
22831 | sCtx.cColSep = SEP_Unit[0]; |
22832 | sCtx.cRowSep = SEP_Record[0]; |
22833 | xRead = ascii_read_one_field; |
22834 | useOutputMode = 0; |
22835 | }else if( cli_strcmp(z,"-csv" )==0 ){ |
22836 | sCtx.cColSep = ','; |
22837 | sCtx.cRowSep = '\n'; |
22838 | xRead = csv_read_one_field; |
22839 | useOutputMode = 0; |
22840 | }else{ |
22841 | utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n" , z); |
22842 | showHelp(p->out, "import" ); |
22843 | goto meta_command_exit; |
22844 | } |
22845 | } |
22846 | if( zTable==0 ){ |
22847 | utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n" , |
22848 | zFile==0 ? "FILE" : "TABLE" ); |
22849 | showHelp(p->out, "import" ); |
22850 | goto meta_command_exit; |
22851 | } |
22852 | seenInterrupt = 0; |
22853 | open_db(p, 0); |
22854 | if( useOutputMode ){ |
22855 | /* If neither the --csv or --ascii options are specified, then set |
22856 | ** the column and row separator characters from the output mode. */ |
22857 | nSep = strlen30(p->colSeparator); |
22858 | if( nSep==0 ){ |
22859 | raw_printf(stderr, |
22860 | "Error: non-null column separator required for import\n" ); |
22861 | goto meta_command_exit; |
22862 | } |
22863 | if( nSep>1 ){ |
22864 | raw_printf(stderr, |
22865 | "Error: multi-character column separators not allowed" |
22866 | " for import\n" ); |
22867 | goto meta_command_exit; |
22868 | } |
22869 | nSep = strlen30(p->rowSeparator); |
22870 | if( nSep==0 ){ |
22871 | raw_printf(stderr, |
22872 | "Error: non-null row separator required for import\n" ); |
22873 | goto meta_command_exit; |
22874 | } |
22875 | if( nSep==2 && p->mode==MODE_Csv |
22876 | && cli_strcmp(p->rowSeparator,SEP_CrLf)==0 |
22877 | ){ |
22878 | /* When importing CSV (only), if the row separator is set to the |
22879 | ** default output row separator, change it to the default input |
22880 | ** row separator. This avoids having to maintain different input |
22881 | ** and output row separators. */ |
22882 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
22883 | nSep = strlen30(p->rowSeparator); |
22884 | } |
22885 | if( nSep>1 ){ |
22886 | raw_printf(stderr, "Error: multi-character row separators not allowed" |
22887 | " for import\n" ); |
22888 | goto meta_command_exit; |
22889 | } |
22890 | sCtx.cColSep = p->colSeparator[0]; |
22891 | sCtx.cRowSep = p->rowSeparator[0]; |
22892 | } |
22893 | sCtx.zFile = zFile; |
22894 | sCtx.nLine = 1; |
22895 | if( sCtx.zFile[0]=='|' ){ |
22896 | #ifdef SQLITE_OMIT_POPEN |
22897 | raw_printf(stderr, "Error: pipes are not supported in this OS\n" ); |
22898 | goto meta_command_exit; |
22899 | #else |
22900 | sCtx.in = popen(sCtx.zFile+1, "r" ); |
22901 | sCtx.zFile = "<pipe>" ; |
22902 | sCtx.xCloser = pclose; |
22903 | #endif |
22904 | }else{ |
22905 | sCtx.in = fopen(sCtx.zFile, "rb" ); |
22906 | sCtx.xCloser = fclose; |
22907 | } |
22908 | if( sCtx.in==0 ){ |
22909 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , zFile); |
22910 | goto meta_command_exit; |
22911 | } |
22912 | if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){ |
22913 | char zSep[2]; |
22914 | zSep[1] = 0; |
22915 | zSep[0] = sCtx.cColSep; |
22916 | utf8_printf(p->out, "Column separator " ); |
22917 | output_c_string(p->out, zSep); |
22918 | utf8_printf(p->out, ", row separator " ); |
22919 | zSep[0] = sCtx.cRowSep; |
22920 | output_c_string(p->out, zSep); |
22921 | utf8_printf(p->out, "\n" ); |
22922 | } |
22923 | sCtx.z = sqlite3_malloc64(120); |
22924 | if( sCtx.z==0 ){ |
22925 | import_cleanup(&sCtx); |
22926 | shell_out_of_memory(); |
22927 | } |
22928 | /* Below, resources must be freed before exit. */ |
22929 | while( (nSkip--)>0 ){ |
22930 | while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){} |
22931 | } |
22932 | if( zSchema!=0 ){ |
22933 | zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"" , zSchema, zTable); |
22934 | }else{ |
22935 | zFullTabName = sqlite3_mprintf("\"%w\"" , zTable); |
22936 | } |
22937 | zSql = sqlite3_mprintf("SELECT * FROM %s" , zFullTabName); |
22938 | if( zSql==0 || zFullTabName==0 ){ |
22939 | import_cleanup(&sCtx); |
22940 | shell_out_of_memory(); |
22941 | } |
22942 | nByte = strlen30(zSql); |
22943 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
22944 | import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ |
22945 | if( rc && sqlite3_strglob("no such table: *" , sqlite3_errmsg(p->db))==0 ){ |
22946 | sqlite3 *dbCols = 0; |
22947 | char *zRenames = 0; |
22948 | char *zColDefs; |
22949 | zCreate = sqlite3_mprintf("CREATE TABLE %s" , zFullTabName); |
22950 | while( xRead(&sCtx) ){ |
22951 | zAutoColumn(sCtx.z, &dbCols, 0); |
22952 | if( sCtx.cTerm!=sCtx.cColSep ) break; |
22953 | } |
22954 | zColDefs = zAutoColumn(0, &dbCols, &zRenames); |
22955 | if( zRenames!=0 ){ |
22956 | utf8_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr, |
22957 | "Columns renamed during .import %s due to duplicates:\n" |
22958 | "%s\n" , sCtx.zFile, zRenames); |
22959 | sqlite3_free(zRenames); |
22960 | } |
22961 | assert(dbCols==0); |
22962 | if( zColDefs==0 ){ |
22963 | utf8_printf(stderr,"%s: empty file\n" , sCtx.zFile); |
22964 | import_fail: |
22965 | sqlite3_free(zCreate); |
22966 | sqlite3_free(zSql); |
22967 | sqlite3_free(zFullTabName); |
22968 | import_cleanup(&sCtx); |
22969 | rc = 1; |
22970 | goto meta_command_exit; |
22971 | } |
22972 | zCreate = sqlite3_mprintf("%z%z\n" , zCreate, zColDefs); |
22973 | if( eVerbose>=1 ){ |
22974 | utf8_printf(p->out, "%s\n" , zCreate); |
22975 | } |
22976 | rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); |
22977 | if( rc ){ |
22978 | utf8_printf(stderr, "%s failed:\n%s\n" , zCreate, sqlite3_errmsg(p->db)); |
22979 | goto import_fail; |
22980 | } |
22981 | sqlite3_free(zCreate); |
22982 | zCreate = 0; |
22983 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
22984 | } |
22985 | if( rc ){ |
22986 | if (pStmt) sqlite3_finalize(pStmt); |
22987 | utf8_printf(stderr,"Error: %s\n" , sqlite3_errmsg(p->db)); |
22988 | goto import_fail; |
22989 | } |
22990 | sqlite3_free(zSql); |
22991 | nCol = sqlite3_column_count(pStmt); |
22992 | sqlite3_finalize(pStmt); |
22993 | pStmt = 0; |
22994 | if( nCol==0 ) return 0; /* no columns, no error */ |
22995 | zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); |
22996 | if( zSql==0 ){ |
22997 | import_cleanup(&sCtx); |
22998 | shell_out_of_memory(); |
22999 | } |
23000 | sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?" , zFullTabName); |
23001 | j = strlen30(zSql); |
23002 | for(i=1; i<nCol; i++){ |
23003 | zSql[j++] = ','; |
23004 | zSql[j++] = '?'; |
23005 | } |
23006 | zSql[j++] = ')'; |
23007 | zSql[j] = 0; |
23008 | if( eVerbose>=2 ){ |
23009 | utf8_printf(p->out, "Insert using: %s\n" , zSql); |
23010 | } |
23011 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
23012 | if( rc ){ |
23013 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
23014 | if (pStmt) sqlite3_finalize(pStmt); |
23015 | goto import_fail; |
23016 | } |
23017 | sqlite3_free(zSql); |
23018 | sqlite3_free(zFullTabName); |
23019 | needCommit = sqlite3_get_autocommit(p->db); |
23020 | if( needCommit ) sqlite3_exec(p->db, "BEGIN" , 0, 0, 0); |
23021 | do{ |
23022 | int startLine = sCtx.nLine; |
23023 | for(i=0; i<nCol; i++){ |
23024 | char *z = xRead(&sCtx); |
23025 | /* |
23026 | ** Did we reach end-of-file before finding any columns? |
23027 | ** If so, stop instead of NULL filling the remaining columns. |
23028 | */ |
23029 | if( z==0 && i==0 ) break; |
23030 | /* |
23031 | ** Did we reach end-of-file OR end-of-line before finding any |
23032 | ** columns in ASCII mode? If so, stop instead of NULL filling |
23033 | ** the remaining columns. |
23034 | */ |
23035 | if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; |
23036 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
23037 | if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ |
23038 | utf8_printf(stderr, "%s:%d: expected %d columns but found %d - " |
23039 | "filling the rest with NULL\n" , |
23040 | sCtx.zFile, startLine, nCol, i+1); |
23041 | i += 2; |
23042 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
23043 | } |
23044 | } |
23045 | if( sCtx.cTerm==sCtx.cColSep ){ |
23046 | do{ |
23047 | xRead(&sCtx); |
23048 | i++; |
23049 | }while( sCtx.cTerm==sCtx.cColSep ); |
23050 | utf8_printf(stderr, "%s:%d: expected %d columns but found %d - " |
23051 | "extras ignored\n" , |
23052 | sCtx.zFile, startLine, nCol, i); |
23053 | } |
23054 | if( i>=nCol ){ |
23055 | sqlite3_step(pStmt); |
23056 | rc = sqlite3_reset(pStmt); |
23057 | if( rc!=SQLITE_OK ){ |
23058 | utf8_printf(stderr, "%s:%d: INSERT failed: %s\n" , sCtx.zFile, |
23059 | startLine, sqlite3_errmsg(p->db)); |
23060 | sCtx.nErr++; |
23061 | }else{ |
23062 | sCtx.nRow++; |
23063 | } |
23064 | } |
23065 | }while( sCtx.cTerm!=EOF ); |
23066 | |
23067 | import_cleanup(&sCtx); |
23068 | sqlite3_finalize(pStmt); |
23069 | if( needCommit ) sqlite3_exec(p->db, "COMMIT" , 0, 0, 0); |
23070 | if( eVerbose>0 ){ |
23071 | utf8_printf(p->out, |
23072 | "Added %d rows with %d errors using %d lines of input\n" , |
23073 | sCtx.nRow, sCtx.nErr, sCtx.nLine-1); |
23074 | } |
23075 | }else |
23076 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
23077 | |
23078 | #ifndef SQLITE_UNTESTABLE |
23079 | if( c=='i' && cli_strncmp(azArg[0], "imposter" , n)==0 ){ |
23080 | char *zSql; |
23081 | char *zCollist = 0; |
23082 | sqlite3_stmt *pStmt; |
23083 | int tnum = 0; |
23084 | int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */ |
23085 | int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ |
23086 | int i; |
23087 | if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off" )==0)) ){ |
23088 | utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n" |
23089 | " .imposter off\n" ); |
23090 | /* Also allowed, but not documented: |
23091 | ** |
23092 | ** .imposter TABLE IMPOSTER |
23093 | ** |
23094 | ** where TABLE is a WITHOUT ROWID table. In that case, the |
23095 | ** imposter is another WITHOUT ROWID table with the columns in |
23096 | ** storage order. */ |
23097 | rc = 1; |
23098 | goto meta_command_exit; |
23099 | } |
23100 | open_db(p, 0); |
23101 | if( nArg==2 ){ |
23102 | sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main" , 0, 1); |
23103 | goto meta_command_exit; |
23104 | } |
23105 | zSql = sqlite3_mprintf( |
23106 | "SELECT rootpage, 0 FROM sqlite_schema" |
23107 | " WHERE name='%q' AND type='index'" |
23108 | "UNION ALL " |
23109 | "SELECT rootpage, 1 FROM sqlite_schema" |
23110 | " WHERE name='%q' AND type='table'" |
23111 | " AND sql LIKE '%%without%%rowid%%'" , |
23112 | azArg[1], azArg[1] |
23113 | ); |
23114 | sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
23115 | sqlite3_free(zSql); |
23116 | if( sqlite3_step(pStmt)==SQLITE_ROW ){ |
23117 | tnum = sqlite3_column_int(pStmt, 0); |
23118 | isWO = sqlite3_column_int(pStmt, 1); |
23119 | } |
23120 | sqlite3_finalize(pStmt); |
23121 | zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'" , azArg[1]); |
23122 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
23123 | sqlite3_free(zSql); |
23124 | i = 0; |
23125 | while( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ |
23126 | char zLabel[20]; |
23127 | const char *zCol = (const char*)sqlite3_column_text(pStmt,2); |
23128 | i++; |
23129 | if( zCol==0 ){ |
23130 | if( sqlite3_column_int(pStmt,1)==-1 ){ |
23131 | zCol = "_ROWID_" ; |
23132 | }else{ |
23133 | sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d" ,i); |
23134 | zCol = zLabel; |
23135 | } |
23136 | } |
23137 | if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){ |
23138 | lenPK = (int)strlen(zCollist); |
23139 | } |
23140 | if( zCollist==0 ){ |
23141 | zCollist = sqlite3_mprintf("\"%w\"" , zCol); |
23142 | }else{ |
23143 | zCollist = sqlite3_mprintf("%z,\"%w\"" , zCollist, zCol); |
23144 | } |
23145 | } |
23146 | sqlite3_finalize(pStmt); |
23147 | if( i==0 || tnum==0 ){ |
23148 | utf8_printf(stderr, "no such index: \"%s\"\n" , azArg[1]); |
23149 | rc = 1; |
23150 | sqlite3_free(zCollist); |
23151 | goto meta_command_exit; |
23152 | } |
23153 | if( lenPK==0 ) lenPK = 100000; |
23154 | zSql = sqlite3_mprintf( |
23155 | "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID" , |
23156 | azArg[2], zCollist, lenPK, zCollist); |
23157 | sqlite3_free(zCollist); |
23158 | rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main" , 1, tnum); |
23159 | if( rc==SQLITE_OK ){ |
23160 | rc = sqlite3_exec(p->db, zSql, 0, 0, 0); |
23161 | sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main" , 0, 0); |
23162 | if( rc ){ |
23163 | utf8_printf(stderr, "Error in [%s]: %s\n" , zSql, sqlite3_errmsg(p->db)); |
23164 | }else{ |
23165 | utf8_printf(stdout, "%s;\n" , zSql); |
23166 | raw_printf(stdout, |
23167 | "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n" , |
23168 | azArg[1], isWO ? "table" : "index" |
23169 | ); |
23170 | } |
23171 | }else{ |
23172 | raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n" , rc); |
23173 | rc = 1; |
23174 | } |
23175 | sqlite3_free(zSql); |
23176 | }else |
23177 | #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ |
23178 | |
23179 | #ifdef SQLITE_ENABLE_IOTRACE |
23180 | if( c=='i' && cli_strncmp(azArg[0], "iotrace" , n)==0 ){ |
23181 | SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); |
23182 | if( iotrace && iotrace!=stdout ) fclose(iotrace); |
23183 | iotrace = 0; |
23184 | if( nArg<2 ){ |
23185 | sqlite3IoTrace = 0; |
23186 | }else if( cli_strcmp(azArg[1], "-" )==0 ){ |
23187 | sqlite3IoTrace = iotracePrintf; |
23188 | iotrace = stdout; |
23189 | }else{ |
23190 | iotrace = fopen(azArg[1], "w" ); |
23191 | if( iotrace==0 ){ |
23192 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , azArg[1]); |
23193 | sqlite3IoTrace = 0; |
23194 | rc = 1; |
23195 | }else{ |
23196 | sqlite3IoTrace = iotracePrintf; |
23197 | } |
23198 | } |
23199 | }else |
23200 | #endif |
23201 | |
23202 | if( c=='l' && n>=5 && cli_strncmp(azArg[0], "limits" , n)==0 ){ |
23203 | static const struct { |
23204 | const char *zLimitName; /* Name of a limit */ |
23205 | int limitCode; /* Integer code for that limit */ |
23206 | } aLimit[] = { |
23207 | { "length" , SQLITE_LIMIT_LENGTH }, |
23208 | { "sql_length" , SQLITE_LIMIT_SQL_LENGTH }, |
23209 | { "column" , SQLITE_LIMIT_COLUMN }, |
23210 | { "expr_depth" , SQLITE_LIMIT_EXPR_DEPTH }, |
23211 | { "compound_select" , SQLITE_LIMIT_COMPOUND_SELECT }, |
23212 | { "vdbe_op" , SQLITE_LIMIT_VDBE_OP }, |
23213 | { "function_arg" , SQLITE_LIMIT_FUNCTION_ARG }, |
23214 | { "attached" , SQLITE_LIMIT_ATTACHED }, |
23215 | { "like_pattern_length" , SQLITE_LIMIT_LIKE_PATTERN_LENGTH }, |
23216 | { "variable_number" , SQLITE_LIMIT_VARIABLE_NUMBER }, |
23217 | { "trigger_depth" , SQLITE_LIMIT_TRIGGER_DEPTH }, |
23218 | { "worker_threads" , SQLITE_LIMIT_WORKER_THREADS }, |
23219 | }; |
23220 | int i, n2; |
23221 | open_db(p, 0); |
23222 | if( nArg==1 ){ |
23223 | for(i=0; i<ArraySize(aLimit); i++){ |
23224 | printf("%20s %d\n" , aLimit[i].zLimitName, |
23225 | sqlite3_limit(p->db, aLimit[i].limitCode, -1)); |
23226 | } |
23227 | }else if( nArg>3 ){ |
23228 | raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n" ); |
23229 | rc = 1; |
23230 | goto meta_command_exit; |
23231 | }else{ |
23232 | int iLimit = -1; |
23233 | n2 = strlen30(azArg[1]); |
23234 | for(i=0; i<ArraySize(aLimit); i++){ |
23235 | if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){ |
23236 | if( iLimit<0 ){ |
23237 | iLimit = i; |
23238 | }else{ |
23239 | utf8_printf(stderr, "ambiguous limit: \"%s\"\n" , azArg[1]); |
23240 | rc = 1; |
23241 | goto meta_command_exit; |
23242 | } |
23243 | } |
23244 | } |
23245 | if( iLimit<0 ){ |
23246 | utf8_printf(stderr, "unknown limit: \"%s\"\n" |
23247 | "enter \".limits\" with no arguments for a list.\n" , |
23248 | azArg[1]); |
23249 | rc = 1; |
23250 | goto meta_command_exit; |
23251 | } |
23252 | if( nArg==3 ){ |
23253 | sqlite3_limit(p->db, aLimit[iLimit].limitCode, |
23254 | (int)integerValue(azArg[2])); |
23255 | } |
23256 | printf("%20s %d\n" , aLimit[iLimit].zLimitName, |
23257 | sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); |
23258 | } |
23259 | }else |
23260 | |
23261 | if( c=='l' && n>2 && cli_strncmp(azArg[0], "lint" , n)==0 ){ |
23262 | open_db(p, 0); |
23263 | lintDotCommand(p, azArg, nArg); |
23264 | }else |
23265 | |
23266 | #if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_FIDDLE) |
23267 | if( c=='l' && cli_strncmp(azArg[0], "load" , n)==0 ){ |
23268 | const char *zFile, *zProc; |
23269 | char *zErrMsg = 0; |
23270 | failIfSafeMode(p, "cannot run .load in safe mode" ); |
23271 | if( nArg<2 ){ |
23272 | raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n" ); |
23273 | rc = 1; |
23274 | goto meta_command_exit; |
23275 | } |
23276 | zFile = azArg[1]; |
23277 | zProc = nArg>=3 ? azArg[2] : 0; |
23278 | open_db(p, 0); |
23279 | rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); |
23280 | if( rc!=SQLITE_OK ){ |
23281 | utf8_printf(stderr, "Error: %s\n" , zErrMsg); |
23282 | sqlite3_free(zErrMsg); |
23283 | rc = 1; |
23284 | } |
23285 | }else |
23286 | #endif |
23287 | |
23288 | #ifndef SQLITE_SHELL_FIDDLE |
23289 | if( c=='l' && cli_strncmp(azArg[0], "log" , n)==0 ){ |
23290 | failIfSafeMode(p, "cannot run .log in safe mode" ); |
23291 | if( nArg!=2 ){ |
23292 | raw_printf(stderr, "Usage: .log FILENAME\n" ); |
23293 | rc = 1; |
23294 | }else{ |
23295 | const char *zFile = azArg[1]; |
23296 | output_file_close(p->pLog); |
23297 | p->pLog = output_file_open(zFile, 0); |
23298 | } |
23299 | }else |
23300 | #endif |
23301 | |
23302 | if( c=='m' && cli_strncmp(azArg[0], "mode" , n)==0 ){ |
23303 | const char *zMode = 0; |
23304 | const char *zTabname = 0; |
23305 | int i, n2; |
23306 | ColModeOpts cmOpts = ColModeOpts_default; |
23307 | for(i=1; i<nArg; i++){ |
23308 | const char *z = azArg[i]; |
23309 | if( optionMatch(z,"wrap" ) && i+1<nArg ){ |
23310 | cmOpts.iWrap = integerValue(azArg[++i]); |
23311 | }else if( optionMatch(z,"ww" ) ){ |
23312 | cmOpts.bWordWrap = 1; |
23313 | }else if( optionMatch(z,"wordwrap" ) && i+1<nArg ){ |
23314 | cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]); |
23315 | }else if( optionMatch(z,"quote" ) ){ |
23316 | cmOpts.bQuote = 1; |
23317 | }else if( optionMatch(z,"noquote" ) ){ |
23318 | cmOpts.bQuote = 0; |
23319 | }else if( zMode==0 ){ |
23320 | zMode = z; |
23321 | /* Apply defaults for qbox pseudo-mode. If that |
23322 | * overwrites already-set values, user was informed of this. |
23323 | */ |
23324 | if( cli_strcmp(z, "qbox" )==0 ){ |
23325 | ColModeOpts cmo = ColModeOpts_default_qbox; |
23326 | zMode = "box" ; |
23327 | cmOpts = cmo; |
23328 | } |
23329 | }else if( zTabname==0 ){ |
23330 | zTabname = z; |
23331 | }else if( z[0]=='-' ){ |
23332 | utf8_printf(stderr, "unknown option: %s\n" , z); |
23333 | utf8_printf(stderr, "options:\n" |
23334 | " --noquote\n" |
23335 | " --quote\n" |
23336 | " --wordwrap on/off\n" |
23337 | " --wrap N\n" |
23338 | " --ww\n" ); |
23339 | rc = 1; |
23340 | goto meta_command_exit; |
23341 | }else{ |
23342 | utf8_printf(stderr, "extra argument: \"%s\"\n" , z); |
23343 | rc = 1; |
23344 | goto meta_command_exit; |
23345 | } |
23346 | } |
23347 | if( zMode==0 ){ |
23348 | if( p->mode==MODE_Column |
23349 | || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) |
23350 | ){ |
23351 | raw_printf |
23352 | (p->out, |
23353 | "current output mode: %s --wrap %d --wordwrap %s --%squote\n" , |
23354 | modeDescr[p->mode], p->cmOpts.iWrap, |
23355 | p->cmOpts.bWordWrap ? "on" : "off" , |
23356 | p->cmOpts.bQuote ? "" : "no" ); |
23357 | }else{ |
23358 | raw_printf(p->out, "current output mode: %s\n" , modeDescr[p->mode]); |
23359 | } |
23360 | zMode = modeDescr[p->mode]; |
23361 | } |
23362 | n2 = strlen30(zMode); |
23363 | if( cli_strncmp(zMode,"lines" ,n2)==0 ){ |
23364 | p->mode = MODE_Line; |
23365 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
23366 | }else if( cli_strncmp(zMode,"columns" ,n2)==0 ){ |
23367 | p->mode = MODE_Column; |
23368 | if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){ |
23369 | p->showHeader = 1; |
23370 | } |
23371 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
23372 | p->cmOpts = cmOpts; |
23373 | }else if( cli_strncmp(zMode,"list" ,n2)==0 ){ |
23374 | p->mode = MODE_List; |
23375 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column); |
23376 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
23377 | }else if( cli_strncmp(zMode,"html" ,n2)==0 ){ |
23378 | p->mode = MODE_Html; |
23379 | }else if( cli_strncmp(zMode,"tcl" ,n2)==0 ){ |
23380 | p->mode = MODE_Tcl; |
23381 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); |
23382 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
23383 | }else if( cli_strncmp(zMode,"csv" ,n2)==0 ){ |
23384 | p->mode = MODE_Csv; |
23385 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); |
23386 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); |
23387 | }else if( cli_strncmp(zMode,"tabs" ,n2)==0 ){ |
23388 | p->mode = MODE_List; |
23389 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); |
23390 | }else if( cli_strncmp(zMode,"insert" ,n2)==0 ){ |
23391 | p->mode = MODE_Insert; |
23392 | set_table_name(p, zTabname ? zTabname : "table" ); |
23393 | }else if( cli_strncmp(zMode,"quote" ,n2)==0 ){ |
23394 | p->mode = MODE_Quote; |
23395 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); |
23396 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
23397 | }else if( cli_strncmp(zMode,"ascii" ,n2)==0 ){ |
23398 | p->mode = MODE_Ascii; |
23399 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); |
23400 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); |
23401 | }else if( cli_strncmp(zMode,"markdown" ,n2)==0 ){ |
23402 | p->mode = MODE_Markdown; |
23403 | p->cmOpts = cmOpts; |
23404 | }else if( cli_strncmp(zMode,"table" ,n2)==0 ){ |
23405 | p->mode = MODE_Table; |
23406 | p->cmOpts = cmOpts; |
23407 | }else if( cli_strncmp(zMode,"box" ,n2)==0 ){ |
23408 | p->mode = MODE_Box; |
23409 | p->cmOpts = cmOpts; |
23410 | }else if( cli_strncmp(zMode,"count" ,n2)==0 ){ |
23411 | p->mode = MODE_Count; |
23412 | }else if( cli_strncmp(zMode,"off" ,n2)==0 ){ |
23413 | p->mode = MODE_Off; |
23414 | }else if( cli_strncmp(zMode,"json" ,n2)==0 ){ |
23415 | p->mode = MODE_Json; |
23416 | }else{ |
23417 | raw_printf(stderr, "Error: mode should be one of: " |
23418 | "ascii box column csv html insert json line list markdown " |
23419 | "qbox quote table tabs tcl\n" ); |
23420 | rc = 1; |
23421 | } |
23422 | p->cMode = p->mode; |
23423 | }else |
23424 | |
23425 | #ifndef SQLITE_SHELL_FIDDLE |
23426 | if( c=='n' && cli_strcmp(azArg[0], "nonce" )==0 ){ |
23427 | if( nArg!=2 ){ |
23428 | raw_printf(stderr, "Usage: .nonce NONCE\n" ); |
23429 | rc = 1; |
23430 | }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){ |
23431 | raw_printf(stderr, "line %d: incorrect nonce: \"%s\"\n" , |
23432 | p->lineno, azArg[1]); |
23433 | exit(1); |
23434 | }else{ |
23435 | p->bSafeMode = 0; |
23436 | return 0; /* Return immediately to bypass the safe mode reset |
23437 | ** at the end of this procedure */ |
23438 | } |
23439 | }else |
23440 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
23441 | |
23442 | if( c=='n' && cli_strncmp(azArg[0], "nullvalue" , n)==0 ){ |
23443 | if( nArg==2 ){ |
23444 | sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, |
23445 | "%.*s" , (int)ArraySize(p->nullValue)-1, azArg[1]); |
23446 | }else{ |
23447 | raw_printf(stderr, "Usage: .nullvalue STRING\n" ); |
23448 | rc = 1; |
23449 | } |
23450 | }else |
23451 | |
23452 | if( c=='o' && cli_strncmp(azArg[0], "open" , n)==0 && n>=2 ){ |
23453 | const char *zFN = 0; /* Pointer to constant filename */ |
23454 | char *zNewFilename = 0; /* Name of the database file to open */ |
23455 | int iName = 1; /* Index in azArg[] of the filename */ |
23456 | int newFlag = 0; /* True to delete file before opening */ |
23457 | int openMode = SHELL_OPEN_UNSPEC; |
23458 | |
23459 | /* Check for command-line arguments */ |
23460 | for(iName=1; iName<nArg; iName++){ |
23461 | const char *z = azArg[iName]; |
23462 | #ifndef SQLITE_SHELL_FIDDLE |
23463 | if( optionMatch(z,"new" ) ){ |
23464 | newFlag = 1; |
23465 | #ifdef SQLITE_HAVE_ZLIB |
23466 | }else if( optionMatch(z, "zip" ) ){ |
23467 | openMode = SHELL_OPEN_ZIPFILE; |
23468 | #endif |
23469 | }else if( optionMatch(z, "append" ) ){ |
23470 | openMode = SHELL_OPEN_APPENDVFS; |
23471 | }else if( optionMatch(z, "readonly" ) ){ |
23472 | openMode = SHELL_OPEN_READONLY; |
23473 | }else if( optionMatch(z, "nofollow" ) ){ |
23474 | p->openFlags |= SQLITE_OPEN_NOFOLLOW; |
23475 | #ifndef SQLITE_OMIT_DESERIALIZE |
23476 | }else if( optionMatch(z, "deserialize" ) ){ |
23477 | openMode = SHELL_OPEN_DESERIALIZE; |
23478 | }else if( optionMatch(z, "hexdb" ) ){ |
23479 | openMode = SHELL_OPEN_HEXDB; |
23480 | }else if( optionMatch(z, "maxsize" ) && iName+1<nArg ){ |
23481 | p->szMax = integerValue(azArg[++iName]); |
23482 | #endif /* SQLITE_OMIT_DESERIALIZE */ |
23483 | }else |
23484 | #endif /* !SQLITE_SHELL_FIDDLE */ |
23485 | if( z[0]=='-' ){ |
23486 | utf8_printf(stderr, "unknown option: %s\n" , z); |
23487 | rc = 1; |
23488 | goto meta_command_exit; |
23489 | }else if( zFN ){ |
23490 | utf8_printf(stderr, "extra argument: \"%s\"\n" , z); |
23491 | rc = 1; |
23492 | goto meta_command_exit; |
23493 | }else{ |
23494 | zFN = z; |
23495 | } |
23496 | } |
23497 | |
23498 | /* Close the existing database */ |
23499 | session_close_all(p, -1); |
23500 | close_db(p->db); |
23501 | p->db = 0; |
23502 | p->pAuxDb->zDbFilename = 0; |
23503 | sqlite3_free(p->pAuxDb->zFreeOnClose); |
23504 | p->pAuxDb->zFreeOnClose = 0; |
23505 | p->openMode = openMode; |
23506 | p->openFlags = 0; |
23507 | p->szMax = 0; |
23508 | |
23509 | /* If a filename is specified, try to open it first */ |
23510 | if( zFN || p->openMode==SHELL_OPEN_HEXDB ){ |
23511 | if( newFlag && zFN && !p->bSafeMode ) shellDeleteFile(zFN); |
23512 | #ifndef SQLITE_SHELL_FIDDLE |
23513 | if( p->bSafeMode |
23514 | && p->openMode!=SHELL_OPEN_HEXDB |
23515 | && zFN |
23516 | && cli_strcmp(zFN,":memory:" )!=0 |
23517 | ){ |
23518 | failIfSafeMode(p, "cannot open disk-based database files in safe mode" ); |
23519 | } |
23520 | #else |
23521 | /* WASM mode has its own sandboxed pseudo-filesystem. */ |
23522 | #endif |
23523 | if( zFN ){ |
23524 | zNewFilename = sqlite3_mprintf("%s" , zFN); |
23525 | shell_check_oom(zNewFilename); |
23526 | }else{ |
23527 | zNewFilename = 0; |
23528 | } |
23529 | p->pAuxDb->zDbFilename = zNewFilename; |
23530 | open_db(p, OPEN_DB_KEEPALIVE); |
23531 | if( p->db==0 ){ |
23532 | utf8_printf(stderr, "Error: cannot open '%s'\n" , zNewFilename); |
23533 | sqlite3_free(zNewFilename); |
23534 | }else{ |
23535 | p->pAuxDb->zFreeOnClose = zNewFilename; |
23536 | } |
23537 | } |
23538 | if( p->db==0 ){ |
23539 | /* As a fall-back open a TEMP database */ |
23540 | p->pAuxDb->zDbFilename = 0; |
23541 | open_db(p, 0); |
23542 | } |
23543 | }else |
23544 | |
23545 | #ifndef SQLITE_SHELL_FIDDLE |
23546 | if( (c=='o' |
23547 | && (cli_strncmp(azArg[0], "output" , n)==0 |
23548 | || cli_strncmp(azArg[0], "once" , n)==0)) |
23549 | || (c=='e' && n==5 && cli_strcmp(azArg[0],"excel" )==0) |
23550 | ){ |
23551 | char *zFile = 0; |
23552 | int bTxtMode = 0; |
23553 | int i; |
23554 | int eMode = 0; |
23555 | int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */ |
23556 | unsigned char zBOM[4]; /* Byte-order mark to using if --bom is present */ |
23557 | |
23558 | zBOM[0] = 0; |
23559 | failIfSafeMode(p, "cannot run .%s in safe mode" , azArg[0]); |
23560 | if( c=='e' ){ |
23561 | eMode = 'x'; |
23562 | bOnce = 2; |
23563 | }else if( cli_strncmp(azArg[0],"once" ,n)==0 ){ |
23564 | bOnce = 1; |
23565 | } |
23566 | for(i=1; i<nArg; i++){ |
23567 | char *z = azArg[i]; |
23568 | if( z[0]=='-' ){ |
23569 | if( z[1]=='-' ) z++; |
23570 | if( cli_strcmp(z,"-bom" )==0 ){ |
23571 | zBOM[0] = 0xef; |
23572 | zBOM[1] = 0xbb; |
23573 | zBOM[2] = 0xbf; |
23574 | zBOM[3] = 0; |
23575 | }else if( c!='e' && cli_strcmp(z,"-x" )==0 ){ |
23576 | eMode = 'x'; /* spreadsheet */ |
23577 | }else if( c!='e' && cli_strcmp(z,"-e" )==0 ){ |
23578 | eMode = 'e'; /* text editor */ |
23579 | }else{ |
23580 | utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n" , |
23581 | azArg[i]); |
23582 | showHelp(p->out, azArg[0]); |
23583 | rc = 1; |
23584 | goto meta_command_exit; |
23585 | } |
23586 | }else if( zFile==0 && eMode!='e' && eMode!='x' ){ |
23587 | zFile = sqlite3_mprintf("%s" , z); |
23588 | if( zFile && zFile[0]=='|' ){ |
23589 | while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s" , zFile, azArg[++i]); |
23590 | break; |
23591 | } |
23592 | }else{ |
23593 | utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n" , |
23594 | azArg[i]); |
23595 | showHelp(p->out, azArg[0]); |
23596 | rc = 1; |
23597 | sqlite3_free(zFile); |
23598 | goto meta_command_exit; |
23599 | } |
23600 | } |
23601 | if( zFile==0 ){ |
23602 | zFile = sqlite3_mprintf("stdout" ); |
23603 | } |
23604 | if( bOnce ){ |
23605 | p->outCount = 2; |
23606 | }else{ |
23607 | p->outCount = 0; |
23608 | } |
23609 | output_reset(p); |
23610 | #ifndef SQLITE_NOHAVE_SYSTEM |
23611 | if( eMode=='e' || eMode=='x' ){ |
23612 | p->doXdgOpen = 1; |
23613 | outputModePush(p); |
23614 | if( eMode=='x' ){ |
23615 | /* spreadsheet mode. Output as CSV. */ |
23616 | newTempFile(p, "csv" ); |
23617 | ShellClearFlag(p, SHFLG_Echo); |
23618 | p->mode = MODE_Csv; |
23619 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); |
23620 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); |
23621 | }else{ |
23622 | /* text editor mode */ |
23623 | newTempFile(p, "txt" ); |
23624 | bTxtMode = 1; |
23625 | } |
23626 | sqlite3_free(zFile); |
23627 | zFile = sqlite3_mprintf("%s" , p->zTempFile); |
23628 | } |
23629 | #endif /* SQLITE_NOHAVE_SYSTEM */ |
23630 | shell_check_oom(zFile); |
23631 | if( zFile[0]=='|' ){ |
23632 | #ifdef SQLITE_OMIT_POPEN |
23633 | raw_printf(stderr, "Error: pipes are not supported in this OS\n" ); |
23634 | rc = 1; |
23635 | p->out = stdout; |
23636 | #else |
23637 | p->out = popen(zFile + 1, "w" ); |
23638 | if( p->out==0 ){ |
23639 | utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n" , zFile + 1); |
23640 | p->out = stdout; |
23641 | rc = 1; |
23642 | }else{ |
23643 | if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out); |
23644 | sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s" , zFile); |
23645 | } |
23646 | #endif |
23647 | }else{ |
23648 | p->out = output_file_open(zFile, bTxtMode); |
23649 | if( p->out==0 ){ |
23650 | if( cli_strcmp(zFile,"off" )!=0 ){ |
23651 | utf8_printf(stderr,"Error: cannot write to \"%s\"\n" , zFile); |
23652 | } |
23653 | p->out = stdout; |
23654 | rc = 1; |
23655 | } else { |
23656 | if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out); |
23657 | sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s" , zFile); |
23658 | } |
23659 | } |
23660 | sqlite3_free(zFile); |
23661 | }else |
23662 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
23663 | |
23664 | if( c=='p' && n>=3 && cli_strncmp(azArg[0], "parameter" , n)==0 ){ |
23665 | open_db(p,0); |
23666 | if( nArg<=1 ) goto parameter_syntax_error; |
23667 | |
23668 | /* .parameter clear |
23669 | ** Clear all bind parameters by dropping the TEMP table that holds them. |
23670 | */ |
23671 | if( nArg==2 && cli_strcmp(azArg[1],"clear" )==0 ){ |
23672 | sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;" , |
23673 | 0, 0, 0); |
23674 | }else |
23675 | |
23676 | /* .parameter list |
23677 | ** List all bind parameters. |
23678 | */ |
23679 | if( nArg==2 && cli_strcmp(azArg[1],"list" )==0 ){ |
23680 | sqlite3_stmt *pStmt = 0; |
23681 | int rx; |
23682 | int len = 0; |
23683 | rx = sqlite3_prepare_v2(p->db, |
23684 | "SELECT max(length(key)) " |
23685 | "FROM temp.sqlite_parameters;" , -1, &pStmt, 0); |
23686 | if( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ |
23687 | len = sqlite3_column_int(pStmt, 0); |
23688 | if( len>40 ) len = 40; |
23689 | } |
23690 | sqlite3_finalize(pStmt); |
23691 | pStmt = 0; |
23692 | if( len ){ |
23693 | rx = sqlite3_prepare_v2(p->db, |
23694 | "SELECT key, quote(value) " |
23695 | "FROM temp.sqlite_parameters;" , -1, &pStmt, 0); |
23696 | while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ |
23697 | utf8_printf(p->out, "%-*s %s\n" , len, sqlite3_column_text(pStmt,0), |
23698 | sqlite3_column_text(pStmt,1)); |
23699 | } |
23700 | sqlite3_finalize(pStmt); |
23701 | } |
23702 | }else |
23703 | |
23704 | /* .parameter init |
23705 | ** Make sure the TEMP table used to hold bind parameters exists. |
23706 | ** Create it if necessary. |
23707 | */ |
23708 | if( nArg==2 && cli_strcmp(azArg[1],"init" )==0 ){ |
23709 | bind_table_init(p); |
23710 | }else |
23711 | |
23712 | /* .parameter set NAME VALUE |
23713 | ** Set or reset a bind parameter. NAME should be the full parameter |
23714 | ** name exactly as it appears in the query. (ex: $abc, @def). The |
23715 | ** VALUE can be in either SQL literal notation, or if not it will be |
23716 | ** understood to be a text string. |
23717 | */ |
23718 | if( nArg==4 && cli_strcmp(azArg[1],"set" )==0 ){ |
23719 | int rx; |
23720 | char *zSql; |
23721 | sqlite3_stmt *pStmt; |
23722 | const char *zKey = azArg[2]; |
23723 | const char *zValue = azArg[3]; |
23724 | bind_table_init(p); |
23725 | zSql = sqlite3_mprintf( |
23726 | "REPLACE INTO temp.sqlite_parameters(key,value)" |
23727 | "VALUES(%Q,%s);" , zKey, zValue); |
23728 | shell_check_oom(zSql); |
23729 | pStmt = 0; |
23730 | rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
23731 | sqlite3_free(zSql); |
23732 | if( rx!=SQLITE_OK ){ |
23733 | sqlite3_finalize(pStmt); |
23734 | pStmt = 0; |
23735 | zSql = sqlite3_mprintf( |
23736 | "REPLACE INTO temp.sqlite_parameters(key,value)" |
23737 | "VALUES(%Q,%Q);" , zKey, zValue); |
23738 | shell_check_oom(zSql); |
23739 | rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
23740 | sqlite3_free(zSql); |
23741 | if( rx!=SQLITE_OK ){ |
23742 | utf8_printf(p->out, "Error: %s\n" , sqlite3_errmsg(p->db)); |
23743 | sqlite3_finalize(pStmt); |
23744 | pStmt = 0; |
23745 | rc = 1; |
23746 | } |
23747 | } |
23748 | sqlite3_step(pStmt); |
23749 | sqlite3_finalize(pStmt); |
23750 | }else |
23751 | |
23752 | /* .parameter unset NAME |
23753 | ** Remove the NAME binding from the parameter binding table, if it |
23754 | ** exists. |
23755 | */ |
23756 | if( nArg==3 && cli_strcmp(azArg[1],"unset" )==0 ){ |
23757 | char *zSql = sqlite3_mprintf( |
23758 | "DELETE FROM temp.sqlite_parameters WHERE key=%Q" , azArg[2]); |
23759 | shell_check_oom(zSql); |
23760 | sqlite3_exec(p->db, zSql, 0, 0, 0); |
23761 | sqlite3_free(zSql); |
23762 | }else |
23763 | /* If no command name matches, show a syntax error */ |
23764 | parameter_syntax_error: |
23765 | showHelp(p->out, "parameter" ); |
23766 | }else |
23767 | |
23768 | if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print" , n)==0 ){ |
23769 | int i; |
23770 | for(i=1; i<nArg; i++){ |
23771 | if( i>1 ) raw_printf(p->out, " " ); |
23772 | utf8_printf(p->out, "%s" , azArg[i]); |
23773 | } |
23774 | raw_printf(p->out, "\n" ); |
23775 | }else |
23776 | |
23777 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
23778 | if( c=='p' && n>=3 && cli_strncmp(azArg[0], "progress" , n)==0 ){ |
23779 | int i; |
23780 | int nn = 0; |
23781 | p->flgProgress = 0; |
23782 | p->mxProgress = 0; |
23783 | p->nProgress = 0; |
23784 | for(i=1; i<nArg; i++){ |
23785 | const char *z = azArg[i]; |
23786 | if( z[0]=='-' ){ |
23787 | z++; |
23788 | if( z[0]=='-' ) z++; |
23789 | if( cli_strcmp(z,"quiet" )==0 || cli_strcmp(z,"q" )==0 ){ |
23790 | p->flgProgress |= SHELL_PROGRESS_QUIET; |
23791 | continue; |
23792 | } |
23793 | if( cli_strcmp(z,"reset" )==0 ){ |
23794 | p->flgProgress |= SHELL_PROGRESS_RESET; |
23795 | continue; |
23796 | } |
23797 | if( cli_strcmp(z,"once" )==0 ){ |
23798 | p->flgProgress |= SHELL_PROGRESS_ONCE; |
23799 | continue; |
23800 | } |
23801 | if( cli_strcmp(z,"limit" )==0 ){ |
23802 | if( i+1>=nArg ){ |
23803 | utf8_printf(stderr, "Error: missing argument on --limit\n" ); |
23804 | rc = 1; |
23805 | goto meta_command_exit; |
23806 | }else{ |
23807 | p->mxProgress = (int)integerValue(azArg[++i]); |
23808 | } |
23809 | continue; |
23810 | } |
23811 | utf8_printf(stderr, "Error: unknown option: \"%s\"\n" , azArg[i]); |
23812 | rc = 1; |
23813 | goto meta_command_exit; |
23814 | }else{ |
23815 | nn = (int)integerValue(z); |
23816 | } |
23817 | } |
23818 | open_db(p, 0); |
23819 | sqlite3_progress_handler(p->db, nn, progress_handler, p); |
23820 | }else |
23821 | #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */ |
23822 | |
23823 | if( c=='p' && cli_strncmp(azArg[0], "prompt" , n)==0 ){ |
23824 | if( nArg >= 2) { |
23825 | strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); |
23826 | } |
23827 | if( nArg >= 3) { |
23828 | strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); |
23829 | } |
23830 | }else |
23831 | |
23832 | #ifndef SQLITE_SHELL_FIDDLE |
23833 | if( c=='q' && cli_strncmp(azArg[0], "quit" , n)==0 ){ |
23834 | rc = 2; |
23835 | }else |
23836 | #endif |
23837 | |
23838 | #ifndef SQLITE_SHELL_FIDDLE |
23839 | if( c=='r' && n>=3 && cli_strncmp(azArg[0], "read" , n)==0 ){ |
23840 | FILE *inSaved = p->in; |
23841 | int savedLineno = p->lineno; |
23842 | failIfSafeMode(p, "cannot run .read in safe mode" ); |
23843 | if( nArg!=2 ){ |
23844 | raw_printf(stderr, "Usage: .read FILE\n" ); |
23845 | rc = 1; |
23846 | goto meta_command_exit; |
23847 | } |
23848 | if( azArg[1][0]=='|' ){ |
23849 | #ifdef SQLITE_OMIT_POPEN |
23850 | raw_printf(stderr, "Error: pipes are not supported in this OS\n" ); |
23851 | rc = 1; |
23852 | p->out = stdout; |
23853 | #else |
23854 | p->in = popen(azArg[1]+1, "r" ); |
23855 | if( p->in==0 ){ |
23856 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , azArg[1]); |
23857 | rc = 1; |
23858 | }else{ |
23859 | rc = process_input(p); |
23860 | pclose(p->in); |
23861 | } |
23862 | #endif |
23863 | }else if( (p->in = openChrSource(azArg[1]))==0 ){ |
23864 | utf8_printf(stderr,"Error: cannot open \"%s\"\n" , azArg[1]); |
23865 | rc = 1; |
23866 | }else{ |
23867 | rc = process_input(p); |
23868 | fclose(p->in); |
23869 | } |
23870 | p->in = inSaved; |
23871 | p->lineno = savedLineno; |
23872 | }else |
23873 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
23874 | |
23875 | #ifndef SQLITE_SHELL_FIDDLE |
23876 | if( c=='r' && n>=3 && cli_strncmp(azArg[0], "restore" , n)==0 ){ |
23877 | const char *zSrcFile; |
23878 | const char *zDb; |
23879 | sqlite3 *pSrc; |
23880 | sqlite3_backup *pBackup; |
23881 | int nTimeout = 0; |
23882 | |
23883 | failIfSafeMode(p, "cannot run .restore in safe mode" ); |
23884 | if( nArg==2 ){ |
23885 | zSrcFile = azArg[1]; |
23886 | zDb = "main" ; |
23887 | }else if( nArg==3 ){ |
23888 | zSrcFile = azArg[2]; |
23889 | zDb = azArg[1]; |
23890 | }else{ |
23891 | raw_printf(stderr, "Usage: .restore ?DB? FILE\n" ); |
23892 | rc = 1; |
23893 | goto meta_command_exit; |
23894 | } |
23895 | rc = sqlite3_open(zSrcFile, &pSrc); |
23896 | if( rc!=SQLITE_OK ){ |
23897 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , zSrcFile); |
23898 | close_db(pSrc); |
23899 | return 1; |
23900 | } |
23901 | open_db(p, 0); |
23902 | pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main" ); |
23903 | if( pBackup==0 ){ |
23904 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
23905 | close_db(pSrc); |
23906 | return 1; |
23907 | } |
23908 | while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK |
23909 | || rc==SQLITE_BUSY ){ |
23910 | if( rc==SQLITE_BUSY ){ |
23911 | if( nTimeout++ >= 3 ) break; |
23912 | sqlite3_sleep(100); |
23913 | } |
23914 | } |
23915 | sqlite3_backup_finish(pBackup); |
23916 | if( rc==SQLITE_DONE ){ |
23917 | rc = 0; |
23918 | }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ |
23919 | raw_printf(stderr, "Error: source database is busy\n" ); |
23920 | rc = 1; |
23921 | }else{ |
23922 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
23923 | rc = 1; |
23924 | } |
23925 | close_db(pSrc); |
23926 | }else |
23927 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
23928 | |
23929 | if( c=='s' && cli_strncmp(azArg[0], "scanstats" , n)==0 ){ |
23930 | if( nArg==2 ){ |
23931 | p->scanstatsOn = (u8)booleanValue(azArg[1]); |
23932 | #ifndef SQLITE_ENABLE_STMT_SCANSTATUS |
23933 | raw_printf(stderr, "Warning: .scanstats not available in this build.\n" ); |
23934 | #endif |
23935 | }else{ |
23936 | raw_printf(stderr, "Usage: .scanstats on|off\n" ); |
23937 | rc = 1; |
23938 | } |
23939 | }else |
23940 | |
23941 | if( c=='s' && cli_strncmp(azArg[0], "schema" , n)==0 ){ |
23942 | ShellText sSelect; |
23943 | ShellState data; |
23944 | char *zErrMsg = 0; |
23945 | const char *zDiv = "(" ; |
23946 | const char *zName = 0; |
23947 | int iSchema = 0; |
23948 | int bDebug = 0; |
23949 | int bNoSystemTabs = 0; |
23950 | int ii; |
23951 | |
23952 | open_db(p, 0); |
23953 | memcpy(&data, p, sizeof(data)); |
23954 | data.showHeader = 0; |
23955 | data.cMode = data.mode = MODE_Semi; |
23956 | initText(&sSelect); |
23957 | for(ii=1; ii<nArg; ii++){ |
23958 | if( optionMatch(azArg[ii],"indent" ) ){ |
23959 | data.cMode = data.mode = MODE_Pretty; |
23960 | }else if( optionMatch(azArg[ii],"debug" ) ){ |
23961 | bDebug = 1; |
23962 | }else if( optionMatch(azArg[ii],"nosys" ) ){ |
23963 | bNoSystemTabs = 1; |
23964 | }else if( azArg[ii][0]=='-' ){ |
23965 | utf8_printf(stderr, "Unknown option: \"%s\"\n" , azArg[ii]); |
23966 | rc = 1; |
23967 | goto meta_command_exit; |
23968 | }else if( zName==0 ){ |
23969 | zName = azArg[ii]; |
23970 | }else{ |
23971 | raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n" ); |
23972 | rc = 1; |
23973 | goto meta_command_exit; |
23974 | } |
23975 | } |
23976 | if( zName!=0 ){ |
23977 | int isSchema = sqlite3_strlike(zName, "sqlite_master" , '\\')==0 |
23978 | || sqlite3_strlike(zName, "sqlite_schema" , '\\')==0 |
23979 | || sqlite3_strlike(zName,"sqlite_temp_master" , '\\')==0 |
23980 | || sqlite3_strlike(zName,"sqlite_temp_schema" , '\\')==0; |
23981 | if( isSchema ){ |
23982 | char *new_argv[2], *new_colv[2]; |
23983 | new_argv[0] = sqlite3_mprintf( |
23984 | "CREATE TABLE %s (\n" |
23985 | " type text,\n" |
23986 | " name text,\n" |
23987 | " tbl_name text,\n" |
23988 | " rootpage integer,\n" |
23989 | " sql text\n" |
23990 | ")" , zName); |
23991 | shell_check_oom(new_argv[0]); |
23992 | new_argv[1] = 0; |
23993 | new_colv[0] = "sql" ; |
23994 | new_colv[1] = 0; |
23995 | callback(&data, 1, new_argv, new_colv); |
23996 | sqlite3_free(new_argv[0]); |
23997 | } |
23998 | } |
23999 | if( zDiv ){ |
24000 | sqlite3_stmt *pStmt = 0; |
24001 | rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list" , |
24002 | -1, &pStmt, 0); |
24003 | if( rc ){ |
24004 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
24005 | sqlite3_finalize(pStmt); |
24006 | rc = 1; |
24007 | goto meta_command_exit; |
24008 | } |
24009 | appendText(&sSelect, "SELECT sql FROM" , 0); |
24010 | iSchema = 0; |
24011 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
24012 | const char *zDb = (const char*)sqlite3_column_text(pStmt, 0); |
24013 | char zScNum[30]; |
24014 | sqlite3_snprintf(sizeof(zScNum), zScNum, "%d" , ++iSchema); |
24015 | appendText(&sSelect, zDiv, 0); |
24016 | zDiv = " UNION ALL " ; |
24017 | appendText(&sSelect, "SELECT shell_add_schema(sql," , 0); |
24018 | if( sqlite3_stricmp(zDb, "main" )!=0 ){ |
24019 | appendText(&sSelect, zDb, '\''); |
24020 | }else{ |
24021 | appendText(&sSelect, "NULL" , 0); |
24022 | } |
24023 | appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid," , 0); |
24024 | appendText(&sSelect, zScNum, 0); |
24025 | appendText(&sSelect, " AS snum, " , 0); |
24026 | appendText(&sSelect, zDb, '\''); |
24027 | appendText(&sSelect, " AS sname FROM " , 0); |
24028 | appendText(&sSelect, zDb, quoteChar(zDb)); |
24029 | appendText(&sSelect, ".sqlite_schema" , 0); |
24030 | } |
24031 | sqlite3_finalize(pStmt); |
24032 | #ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS |
24033 | if( zName ){ |
24034 | appendText(&sSelect, |
24035 | " UNION ALL SELECT shell_module_schema(name)," |
24036 | " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list" , |
24037 | 0); |
24038 | } |
24039 | #endif |
24040 | appendText(&sSelect, ") WHERE " , 0); |
24041 | if( zName ){ |
24042 | char *zQarg = sqlite3_mprintf("%Q" , zName); |
24043 | int bGlob; |
24044 | shell_check_oom(zQarg); |
24045 | bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 || |
24046 | strchr(zName, '[') != 0; |
24047 | if( strchr(zName, '.') ){ |
24048 | appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))" , 0); |
24049 | }else{ |
24050 | appendText(&sSelect, "lower(tbl_name)" , 0); |
24051 | } |
24052 | appendText(&sSelect, bGlob ? " GLOB " : " LIKE " , 0); |
24053 | appendText(&sSelect, zQarg, 0); |
24054 | if( !bGlob ){ |
24055 | appendText(&sSelect, " ESCAPE '\\' " , 0); |
24056 | } |
24057 | appendText(&sSelect, " AND " , 0); |
24058 | sqlite3_free(zQarg); |
24059 | } |
24060 | if( bNoSystemTabs ){ |
24061 | appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND " , 0); |
24062 | } |
24063 | appendText(&sSelect, "sql IS NOT NULL" |
24064 | " ORDER BY snum, rowid" , 0); |
24065 | if( bDebug ){ |
24066 | utf8_printf(p->out, "SQL: %s;\n" , sSelect.z); |
24067 | }else{ |
24068 | rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); |
24069 | } |
24070 | freeText(&sSelect); |
24071 | } |
24072 | if( zErrMsg ){ |
24073 | utf8_printf(stderr,"Error: %s\n" , zErrMsg); |
24074 | sqlite3_free(zErrMsg); |
24075 | rc = 1; |
24076 | }else if( rc != SQLITE_OK ){ |
24077 | raw_printf(stderr,"Error: querying schema information\n" ); |
24078 | rc = 1; |
24079 | }else{ |
24080 | rc = 0; |
24081 | } |
24082 | }else |
24083 | |
24084 | if( (c=='s' && n==11 && cli_strncmp(azArg[0], "selecttrace" , n)==0) |
24085 | || (c=='t' && n==9 && cli_strncmp(azArg[0], "treetrace" , n)==0) |
24086 | ){ |
24087 | unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; |
24088 | sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); |
24089 | }else |
24090 | |
24091 | #if defined(SQLITE_ENABLE_SESSION) |
24092 | if( c=='s' && cli_strncmp(azArg[0],"session" ,n)==0 && n>=3 ){ |
24093 | struct AuxDb *pAuxDb = p->pAuxDb; |
24094 | OpenSession *pSession = &pAuxDb->aSession[0]; |
24095 | char **azCmd = &azArg[1]; |
24096 | int iSes = 0; |
24097 | int nCmd = nArg - 1; |
24098 | int i; |
24099 | if( nArg<=1 ) goto session_syntax_error; |
24100 | open_db(p, 0); |
24101 | if( nArg>=3 ){ |
24102 | for(iSes=0; iSes<pAuxDb->nSession; iSes++){ |
24103 | if( cli_strcmp(pAuxDb->aSession[iSes].zName, azArg[1])==0 ) break; |
24104 | } |
24105 | if( iSes<pAuxDb->nSession ){ |
24106 | pSession = &pAuxDb->aSession[iSes]; |
24107 | azCmd++; |
24108 | nCmd--; |
24109 | }else{ |
24110 | pSession = &pAuxDb->aSession[0]; |
24111 | iSes = 0; |
24112 | } |
24113 | } |
24114 | |
24115 | /* .session attach TABLE |
24116 | ** Invoke the sqlite3session_attach() interface to attach a particular |
24117 | ** table so that it is never filtered. |
24118 | */ |
24119 | if( cli_strcmp(azCmd[0],"attach" )==0 ){ |
24120 | if( nCmd!=2 ) goto session_syntax_error; |
24121 | if( pSession->p==0 ){ |
24122 | session_not_open: |
24123 | raw_printf(stderr, "ERROR: No sessions are open\n" ); |
24124 | }else{ |
24125 | rc = sqlite3session_attach(pSession->p, azCmd[1]); |
24126 | if( rc ){ |
24127 | raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n" , rc); |
24128 | rc = 0; |
24129 | } |
24130 | } |
24131 | }else |
24132 | |
24133 | /* .session changeset FILE |
24134 | ** .session patchset FILE |
24135 | ** Write a changeset or patchset into a file. The file is overwritten. |
24136 | */ |
24137 | if( cli_strcmp(azCmd[0],"changeset" )==0 |
24138 | || cli_strcmp(azCmd[0],"patchset" )==0 |
24139 | ){ |
24140 | FILE *out = 0; |
24141 | failIfSafeMode(p, "cannot run \".session %s\" in safe mode" , azCmd[0]); |
24142 | if( nCmd!=2 ) goto session_syntax_error; |
24143 | if( pSession->p==0 ) goto session_not_open; |
24144 | out = fopen(azCmd[1], "wb" ); |
24145 | if( out==0 ){ |
24146 | utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n" , |
24147 | azCmd[1]); |
24148 | }else{ |
24149 | int szChng; |
24150 | void *pChng; |
24151 | if( azCmd[0][0]=='c' ){ |
24152 | rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); |
24153 | }else{ |
24154 | rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); |
24155 | } |
24156 | if( rc ){ |
24157 | printf("Error: error code %d\n" , rc); |
24158 | rc = 0; |
24159 | } |
24160 | if( pChng |
24161 | && fwrite(pChng, szChng, 1, out)!=1 ){ |
24162 | raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n" , |
24163 | szChng); |
24164 | } |
24165 | sqlite3_free(pChng); |
24166 | fclose(out); |
24167 | } |
24168 | }else |
24169 | |
24170 | /* .session close |
24171 | ** Close the identified session |
24172 | */ |
24173 | if( cli_strcmp(azCmd[0], "close" )==0 ){ |
24174 | if( nCmd!=1 ) goto session_syntax_error; |
24175 | if( pAuxDb->nSession ){ |
24176 | session_close(pSession); |
24177 | pAuxDb->aSession[iSes] = pAuxDb->aSession[--pAuxDb->nSession]; |
24178 | } |
24179 | }else |
24180 | |
24181 | /* .session enable ?BOOLEAN? |
24182 | ** Query or set the enable flag |
24183 | */ |
24184 | if( cli_strcmp(azCmd[0], "enable" )==0 ){ |
24185 | int ii; |
24186 | if( nCmd>2 ) goto session_syntax_error; |
24187 | ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); |
24188 | if( pAuxDb->nSession ){ |
24189 | ii = sqlite3session_enable(pSession->p, ii); |
24190 | utf8_printf(p->out, "session %s enable flag = %d\n" , |
24191 | pSession->zName, ii); |
24192 | } |
24193 | }else |
24194 | |
24195 | /* .session filter GLOB .... |
24196 | ** Set a list of GLOB patterns of table names to be excluded. |
24197 | */ |
24198 | if( cli_strcmp(azCmd[0], "filter" )==0 ){ |
24199 | int ii, nByte; |
24200 | if( nCmd<2 ) goto session_syntax_error; |
24201 | if( pAuxDb->nSession ){ |
24202 | for(ii=0; ii<pSession->nFilter; ii++){ |
24203 | sqlite3_free(pSession->azFilter[ii]); |
24204 | } |
24205 | sqlite3_free(pSession->azFilter); |
24206 | nByte = sizeof(pSession->azFilter[0])*(nCmd-1); |
24207 | pSession->azFilter = sqlite3_malloc( nByte ); |
24208 | if( pSession->azFilter==0 ){ |
24209 | raw_printf(stderr, "Error: out or memory\n" ); |
24210 | exit(1); |
24211 | } |
24212 | for(ii=1; ii<nCmd; ii++){ |
24213 | char *x = pSession->azFilter[ii-1] = sqlite3_mprintf("%s" , azCmd[ii]); |
24214 | shell_check_oom(x); |
24215 | } |
24216 | pSession->nFilter = ii-1; |
24217 | } |
24218 | }else |
24219 | |
24220 | /* .session indirect ?BOOLEAN? |
24221 | ** Query or set the indirect flag |
24222 | */ |
24223 | if( cli_strcmp(azCmd[0], "indirect" )==0 ){ |
24224 | int ii; |
24225 | if( nCmd>2 ) goto session_syntax_error; |
24226 | ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); |
24227 | if( pAuxDb->nSession ){ |
24228 | ii = sqlite3session_indirect(pSession->p, ii); |
24229 | utf8_printf(p->out, "session %s indirect flag = %d\n" , |
24230 | pSession->zName, ii); |
24231 | } |
24232 | }else |
24233 | |
24234 | /* .session isempty |
24235 | ** Determine if the session is empty |
24236 | */ |
24237 | if( cli_strcmp(azCmd[0], "isempty" )==0 ){ |
24238 | int ii; |
24239 | if( nCmd!=1 ) goto session_syntax_error; |
24240 | if( pAuxDb->nSession ){ |
24241 | ii = sqlite3session_isempty(pSession->p); |
24242 | utf8_printf(p->out, "session %s isempty flag = %d\n" , |
24243 | pSession->zName, ii); |
24244 | } |
24245 | }else |
24246 | |
24247 | /* .session list |
24248 | ** List all currently open sessions |
24249 | */ |
24250 | if( cli_strcmp(azCmd[0],"list" )==0 ){ |
24251 | for(i=0; i<pAuxDb->nSession; i++){ |
24252 | utf8_printf(p->out, "%d %s\n" , i, pAuxDb->aSession[i].zName); |
24253 | } |
24254 | }else |
24255 | |
24256 | /* .session open DB NAME |
24257 | ** Open a new session called NAME on the attached database DB. |
24258 | ** DB is normally "main". |
24259 | */ |
24260 | if( cli_strcmp(azCmd[0],"open" )==0 ){ |
24261 | char *zName; |
24262 | if( nCmd!=3 ) goto session_syntax_error; |
24263 | zName = azCmd[2]; |
24264 | if( zName[0]==0 ) goto session_syntax_error; |
24265 | for(i=0; i<pAuxDb->nSession; i++){ |
24266 | if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){ |
24267 | utf8_printf(stderr, "Session \"%s\" already exists\n" , zName); |
24268 | goto meta_command_exit; |
24269 | } |
24270 | } |
24271 | if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){ |
24272 | raw_printf(stderr, "Maximum of %d sessions\n" , ArraySize(pAuxDb->aSession)); |
24273 | goto meta_command_exit; |
24274 | } |
24275 | pSession = &pAuxDb->aSession[pAuxDb->nSession]; |
24276 | rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); |
24277 | if( rc ){ |
24278 | raw_printf(stderr, "Cannot open session: error code=%d\n" , rc); |
24279 | rc = 0; |
24280 | goto meta_command_exit; |
24281 | } |
24282 | pSession->nFilter = 0; |
24283 | sqlite3session_table_filter(pSession->p, session_filter, pSession); |
24284 | pAuxDb->nSession++; |
24285 | pSession->zName = sqlite3_mprintf("%s" , zName); |
24286 | shell_check_oom(pSession->zName); |
24287 | }else |
24288 | /* If no command name matches, show a syntax error */ |
24289 | session_syntax_error: |
24290 | showHelp(p->out, "session" ); |
24291 | }else |
24292 | #endif |
24293 | |
24294 | #ifdef SQLITE_DEBUG |
24295 | /* Undocumented commands for internal testing. Subject to change |
24296 | ** without notice. */ |
24297 | if( c=='s' && n>=10 && cli_strncmp(azArg[0], "selftest-" , 9)==0 ){ |
24298 | if( cli_strncmp(azArg[0]+9, "boolean" , n-9)==0 ){ |
24299 | int i, v; |
24300 | for(i=1; i<nArg; i++){ |
24301 | v = booleanValue(azArg[i]); |
24302 | utf8_printf(p->out, "%s: %d 0x%x\n" , azArg[i], v, v); |
24303 | } |
24304 | } |
24305 | if( cli_strncmp(azArg[0]+9, "integer" , n-9)==0 ){ |
24306 | int i; sqlite3_int64 v; |
24307 | for(i=1; i<nArg; i++){ |
24308 | char zBuf[200]; |
24309 | v = integerValue(azArg[i]); |
24310 | sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n" , azArg[i],v,v); |
24311 | utf8_printf(p->out, "%s" , zBuf); |
24312 | } |
24313 | } |
24314 | }else |
24315 | #endif |
24316 | |
24317 | if( c=='s' && n>=4 && cli_strncmp(azArg[0],"selftest" ,n)==0 ){ |
24318 | int bIsInit = 0; /* True to initialize the SELFTEST table */ |
24319 | int bVerbose = 0; /* Verbose output */ |
24320 | int bSelftestExists; /* True if SELFTEST already exists */ |
24321 | int i, k; /* Loop counters */ |
24322 | int nTest = 0; /* Number of tests runs */ |
24323 | int nErr = 0; /* Number of errors seen */ |
24324 | ShellText str; /* Answer for a query */ |
24325 | sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */ |
24326 | |
24327 | open_db(p,0); |
24328 | for(i=1; i<nArg; i++){ |
24329 | const char *z = azArg[i]; |
24330 | if( z[0]=='-' && z[1]=='-' ) z++; |
24331 | if( cli_strcmp(z,"-init" )==0 ){ |
24332 | bIsInit = 1; |
24333 | }else |
24334 | if( cli_strcmp(z,"-v" )==0 ){ |
24335 | bVerbose++; |
24336 | }else |
24337 | { |
24338 | utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n" , |
24339 | azArg[i], azArg[0]); |
24340 | raw_printf(stderr, "Should be one of: --init -v\n" ); |
24341 | rc = 1; |
24342 | goto meta_command_exit; |
24343 | } |
24344 | } |
24345 | if( sqlite3_table_column_metadata(p->db,"main" ,"selftest" ,0,0,0,0,0,0) |
24346 | != SQLITE_OK ){ |
24347 | bSelftestExists = 0; |
24348 | }else{ |
24349 | bSelftestExists = 1; |
24350 | } |
24351 | if( bIsInit ){ |
24352 | createSelftestTable(p); |
24353 | bSelftestExists = 1; |
24354 | } |
24355 | initText(&str); |
24356 | appendText(&str, "x" , 0); |
24357 | for(k=bSelftestExists; k>=0; k--){ |
24358 | if( k==1 ){ |
24359 | rc = sqlite3_prepare_v2(p->db, |
24360 | "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno" , |
24361 | -1, &pStmt, 0); |
24362 | }else{ |
24363 | rc = sqlite3_prepare_v2(p->db, |
24364 | "VALUES(0,'memo','Missing SELFTEST table - default checks only','')," |
24365 | " (1,'run','PRAGMA integrity_check','ok')" , |
24366 | -1, &pStmt, 0); |
24367 | } |
24368 | if( rc ){ |
24369 | raw_printf(stderr, "Error querying the selftest table\n" ); |
24370 | rc = 1; |
24371 | sqlite3_finalize(pStmt); |
24372 | goto meta_command_exit; |
24373 | } |
24374 | for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){ |
24375 | int tno = sqlite3_column_int(pStmt, 0); |
24376 | const char *zOp = (const char*)sqlite3_column_text(pStmt, 1); |
24377 | const char *zSql = (const char*)sqlite3_column_text(pStmt, 2); |
24378 | const char *zAns = (const char*)sqlite3_column_text(pStmt, 3); |
24379 | |
24380 | if( zOp==0 ) continue; |
24381 | if( zSql==0 ) continue; |
24382 | if( zAns==0 ) continue; |
24383 | k = 0; |
24384 | if( bVerbose>0 ){ |
24385 | printf("%d: %s %s\n" , tno, zOp, zSql); |
24386 | } |
24387 | if( cli_strcmp(zOp,"memo" )==0 ){ |
24388 | utf8_printf(p->out, "%s\n" , zSql); |
24389 | }else |
24390 | if( cli_strcmp(zOp,"run" )==0 ){ |
24391 | char *zErrMsg = 0; |
24392 | str.n = 0; |
24393 | str.z[0] = 0; |
24394 | rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); |
24395 | nTest++; |
24396 | if( bVerbose ){ |
24397 | utf8_printf(p->out, "Result: %s\n" , str.z); |
24398 | } |
24399 | if( rc || zErrMsg ){ |
24400 | nErr++; |
24401 | rc = 1; |
24402 | utf8_printf(p->out, "%d: error-code-%d: %s\n" , tno, rc, zErrMsg); |
24403 | sqlite3_free(zErrMsg); |
24404 | }else if( cli_strcmp(zAns,str.z)!=0 ){ |
24405 | nErr++; |
24406 | rc = 1; |
24407 | utf8_printf(p->out, "%d: Expected: [%s]\n" , tno, zAns); |
24408 | utf8_printf(p->out, "%d: Got: [%s]\n" , tno, str.z); |
24409 | } |
24410 | }else |
24411 | { |
24412 | utf8_printf(stderr, |
24413 | "Unknown operation \"%s\" on selftest line %d\n" , zOp, tno); |
24414 | rc = 1; |
24415 | break; |
24416 | } |
24417 | } /* End loop over rows of content from SELFTEST */ |
24418 | sqlite3_finalize(pStmt); |
24419 | } /* End loop over k */ |
24420 | freeText(&str); |
24421 | utf8_printf(p->out, "%d errors out of %d tests\n" , nErr, nTest); |
24422 | }else |
24423 | |
24424 | if( c=='s' && cli_strncmp(azArg[0], "separator" , n)==0 ){ |
24425 | if( nArg<2 || nArg>3 ){ |
24426 | raw_printf(stderr, "Usage: .separator COL ?ROW?\n" ); |
24427 | rc = 1; |
24428 | } |
24429 | if( nArg>=2 ){ |
24430 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, |
24431 | "%.*s" , (int)ArraySize(p->colSeparator)-1, azArg[1]); |
24432 | } |
24433 | if( nArg>=3 ){ |
24434 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, |
24435 | "%.*s" , (int)ArraySize(p->rowSeparator)-1, azArg[2]); |
24436 | } |
24437 | }else |
24438 | |
24439 | if( c=='s' && n>=4 && cli_strncmp(azArg[0],"sha3sum" ,n)==0 ){ |
24440 | const char *zLike = 0; /* Which table to checksum. 0 means everything */ |
24441 | int i; /* Loop counter */ |
24442 | int bSchema = 0; /* Also hash the schema */ |
24443 | int bSeparate = 0; /* Hash each table separately */ |
24444 | int iSize = 224; /* Hash algorithm to use */ |
24445 | int bDebug = 0; /* Only show the query that would have run */ |
24446 | sqlite3_stmt *pStmt; /* For querying tables names */ |
24447 | char *zSql; /* SQL to be run */ |
24448 | char *zSep; /* Separator */ |
24449 | ShellText sSql; /* Complete SQL for the query to run the hash */ |
24450 | ShellText sQuery; /* Set of queries used to read all content */ |
24451 | open_db(p, 0); |
24452 | for(i=1; i<nArg; i++){ |
24453 | const char *z = azArg[i]; |
24454 | if( z[0]=='-' ){ |
24455 | z++; |
24456 | if( z[0]=='-' ) z++; |
24457 | if( cli_strcmp(z,"schema" )==0 ){ |
24458 | bSchema = 1; |
24459 | }else |
24460 | if( cli_strcmp(z,"sha3-224" )==0 || cli_strcmp(z,"sha3-256" )==0 |
24461 | || cli_strcmp(z,"sha3-384" )==0 || cli_strcmp(z,"sha3-512" )==0 |
24462 | ){ |
24463 | iSize = atoi(&z[5]); |
24464 | }else |
24465 | if( cli_strcmp(z,"debug" )==0 ){ |
24466 | bDebug = 1; |
24467 | }else |
24468 | { |
24469 | utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n" , |
24470 | azArg[i], azArg[0]); |
24471 | showHelp(p->out, azArg[0]); |
24472 | rc = 1; |
24473 | goto meta_command_exit; |
24474 | } |
24475 | }else if( zLike ){ |
24476 | raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n" ); |
24477 | rc = 1; |
24478 | goto meta_command_exit; |
24479 | }else{ |
24480 | zLike = z; |
24481 | bSeparate = 1; |
24482 | if( sqlite3_strlike("sqlite\\_%" , zLike, '\\')==0 ) bSchema = 1; |
24483 | } |
24484 | } |
24485 | if( bSchema ){ |
24486 | zSql = "SELECT lower(name) FROM sqlite_schema" |
24487 | " WHERE type='table' AND coalesce(rootpage,0)>1" |
24488 | " UNION ALL SELECT 'sqlite_schema'" |
24489 | " ORDER BY 1 collate nocase" ; |
24490 | }else{ |
24491 | zSql = "SELECT lower(name) FROM sqlite_schema" |
24492 | " WHERE type='table' AND coalesce(rootpage,0)>1" |
24493 | " AND name NOT LIKE 'sqlite_%'" |
24494 | " ORDER BY 1 collate nocase" ; |
24495 | } |
24496 | sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
24497 | initText(&sQuery); |
24498 | initText(&sSql); |
24499 | appendText(&sSql, "WITH [sha3sum$query](a,b) AS(" ,0); |
24500 | zSep = "VALUES(" ; |
24501 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ |
24502 | const char *zTab = (const char*)sqlite3_column_text(pStmt,0); |
24503 | if( zTab==0 ) continue; |
24504 | if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue; |
24505 | if( cli_strncmp(zTab, "sqlite_" ,7)!=0 ){ |
24506 | appendText(&sQuery,"SELECT * FROM " , 0); |
24507 | appendText(&sQuery,zTab,'"'); |
24508 | appendText(&sQuery," NOT INDEXED;" , 0); |
24509 | }else if( cli_strcmp(zTab, "sqlite_schema" )==0 ){ |
24510 | appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_schema" |
24511 | " ORDER BY name;" , 0); |
24512 | }else if( cli_strcmp(zTab, "sqlite_sequence" )==0 ){ |
24513 | appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence" |
24514 | " ORDER BY name;" , 0); |
24515 | }else if( cli_strcmp(zTab, "sqlite_stat1" )==0 ){ |
24516 | appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1" |
24517 | " ORDER BY tbl,idx;" , 0); |
24518 | }else if( cli_strcmp(zTab, "sqlite_stat4" )==0 ){ |
24519 | appendText(&sQuery, "SELECT * FROM " , 0); |
24520 | appendText(&sQuery, zTab, 0); |
24521 | appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n" , 0); |
24522 | } |
24523 | appendText(&sSql, zSep, 0); |
24524 | appendText(&sSql, sQuery.z, '\''); |
24525 | sQuery.n = 0; |
24526 | appendText(&sSql, "," , 0); |
24527 | appendText(&sSql, zTab, '\''); |
24528 | zSep = "),(" ; |
24529 | } |
24530 | sqlite3_finalize(pStmt); |
24531 | if( bSeparate ){ |
24532 | zSql = sqlite3_mprintf( |
24533 | "%s))" |
24534 | " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" |
24535 | " FROM [sha3sum$query]" , |
24536 | sSql.z, iSize); |
24537 | }else{ |
24538 | zSql = sqlite3_mprintf( |
24539 | "%s))" |
24540 | " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" |
24541 | " FROM [sha3sum$query]" , |
24542 | sSql.z, iSize); |
24543 | } |
24544 | shell_check_oom(zSql); |
24545 | freeText(&sQuery); |
24546 | freeText(&sSql); |
24547 | if( bDebug ){ |
24548 | utf8_printf(p->out, "%s\n" , zSql); |
24549 | }else{ |
24550 | shell_exec(p, zSql, 0); |
24551 | } |
24552 | sqlite3_free(zSql); |
24553 | }else |
24554 | |
24555 | #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) |
24556 | if( c=='s' |
24557 | && (cli_strncmp(azArg[0], "shell" , n)==0 |
24558 | || cli_strncmp(azArg[0],"system" ,n)==0) |
24559 | ){ |
24560 | char *zCmd; |
24561 | int i, x; |
24562 | failIfSafeMode(p, "cannot run .%s in safe mode" , azArg[0]); |
24563 | if( nArg<2 ){ |
24564 | raw_printf(stderr, "Usage: .system COMMAND\n" ); |
24565 | rc = 1; |
24566 | goto meta_command_exit; |
24567 | } |
24568 | zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s" :"\"%s\"" , azArg[1]); |
24569 | for(i=2; i<nArg && zCmd!=0; i++){ |
24570 | zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s" :"%z \"%s\"" , |
24571 | zCmd, azArg[i]); |
24572 | } |
24573 | x = zCmd!=0 ? system(zCmd) : 1; |
24574 | sqlite3_free(zCmd); |
24575 | if( x ) raw_printf(stderr, "System command returns %d\n" , x); |
24576 | }else |
24577 | #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */ |
24578 | |
24579 | if( c=='s' && cli_strncmp(azArg[0], "show" , n)==0 ){ |
24580 | static const char *azBool[] = { "off" , "on" , "trigger" , "full" }; |
24581 | const char *zOut; |
24582 | int i; |
24583 | if( nArg!=1 ){ |
24584 | raw_printf(stderr, "Usage: .show\n" ); |
24585 | rc = 1; |
24586 | goto meta_command_exit; |
24587 | } |
24588 | utf8_printf(p->out, "%12.12s: %s\n" ,"echo" , |
24589 | azBool[ShellHasFlag(p, SHFLG_Echo)]); |
24590 | utf8_printf(p->out, "%12.12s: %s\n" ,"eqp" , azBool[p->autoEQP&3]); |
24591 | utf8_printf(p->out, "%12.12s: %s\n" ,"explain" , |
24592 | p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off" ); |
24593 | utf8_printf(p->out,"%12.12s: %s\n" ,"headers" , azBool[p->showHeader!=0]); |
24594 | if( p->mode==MODE_Column |
24595 | || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) |
24596 | ){ |
24597 | utf8_printf |
24598 | (p->out, "%12.12s: %s --wrap %d --wordwrap %s --%squote\n" , "mode" , |
24599 | modeDescr[p->mode], p->cmOpts.iWrap, |
24600 | p->cmOpts.bWordWrap ? "on" : "off" , |
24601 | p->cmOpts.bQuote ? "" : "no" ); |
24602 | }else{ |
24603 | utf8_printf(p->out, "%12.12s: %s\n" ,"mode" , modeDescr[p->mode]); |
24604 | } |
24605 | utf8_printf(p->out, "%12.12s: " , "nullvalue" ); |
24606 | output_c_string(p->out, p->nullValue); |
24607 | raw_printf(p->out, "\n" ); |
24608 | utf8_printf(p->out,"%12.12s: %s\n" ,"output" , |
24609 | strlen30(p->outfile) ? p->outfile : "stdout" ); |
24610 | utf8_printf(p->out,"%12.12s: " , "colseparator" ); |
24611 | output_c_string(p->out, p->colSeparator); |
24612 | raw_printf(p->out, "\n" ); |
24613 | utf8_printf(p->out,"%12.12s: " , "rowseparator" ); |
24614 | output_c_string(p->out, p->rowSeparator); |
24615 | raw_printf(p->out, "\n" ); |
24616 | switch( p->statsOn ){ |
24617 | case 0: zOut = "off" ; break; |
24618 | default: zOut = "on" ; break; |
24619 | case 2: zOut = "stmt" ; break; |
24620 | case 3: zOut = "vmstep" ; break; |
24621 | } |
24622 | utf8_printf(p->out, "%12.12s: %s\n" ,"stats" , zOut); |
24623 | utf8_printf(p->out, "%12.12s: " , "width" ); |
24624 | for (i=0;i<p->nWidth;i++) { |
24625 | raw_printf(p->out, "%d " , p->colWidth[i]); |
24626 | } |
24627 | raw_printf(p->out, "\n" ); |
24628 | utf8_printf(p->out, "%12.12s: %s\n" , "filename" , |
24629 | p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : "" ); |
24630 | }else |
24631 | |
24632 | if( c=='s' && cli_strncmp(azArg[0], "stats" , n)==0 ){ |
24633 | if( nArg==2 ){ |
24634 | if( cli_strcmp(azArg[1],"stmt" )==0 ){ |
24635 | p->statsOn = 2; |
24636 | }else if( cli_strcmp(azArg[1],"vmstep" )==0 ){ |
24637 | p->statsOn = 3; |
24638 | }else{ |
24639 | p->statsOn = (u8)booleanValue(azArg[1]); |
24640 | } |
24641 | }else if( nArg==1 ){ |
24642 | display_stats(p->db, p, 0); |
24643 | }else{ |
24644 | raw_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n" ); |
24645 | rc = 1; |
24646 | } |
24647 | }else |
24648 | |
24649 | if( (c=='t' && n>1 && cli_strncmp(azArg[0], "tables" , n)==0) |
24650 | || (c=='i' && (cli_strncmp(azArg[0], "indices" , n)==0 |
24651 | || cli_strncmp(azArg[0], "indexes" , n)==0) ) |
24652 | ){ |
24653 | sqlite3_stmt *pStmt; |
24654 | char **azResult; |
24655 | int nRow, nAlloc; |
24656 | int ii; |
24657 | ShellText s; |
24658 | initText(&s); |
24659 | open_db(p, 0); |
24660 | rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list" , -1, &pStmt, 0); |
24661 | if( rc ){ |
24662 | sqlite3_finalize(pStmt); |
24663 | return shellDatabaseError(p->db); |
24664 | } |
24665 | |
24666 | if( nArg>2 && c=='i' ){ |
24667 | /* It is an historical accident that the .indexes command shows an error |
24668 | ** when called with the wrong number of arguments whereas the .tables |
24669 | ** command does not. */ |
24670 | raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n" ); |
24671 | rc = 1; |
24672 | sqlite3_finalize(pStmt); |
24673 | goto meta_command_exit; |
24674 | } |
24675 | for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ |
24676 | const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); |
24677 | if( zDbName==0 ) continue; |
24678 | if( s.z && s.z[0] ) appendText(&s, " UNION ALL " , 0); |
24679 | if( sqlite3_stricmp(zDbName, "main" )==0 ){ |
24680 | appendText(&s, "SELECT name FROM " , 0); |
24681 | }else{ |
24682 | appendText(&s, "SELECT " , 0); |
24683 | appendText(&s, zDbName, '\''); |
24684 | appendText(&s, "||'.'||name FROM " , 0); |
24685 | } |
24686 | appendText(&s, zDbName, '"'); |
24687 | appendText(&s, ".sqlite_schema " , 0); |
24688 | if( c=='t' ){ |
24689 | appendText(&s," WHERE type IN ('table','view')" |
24690 | " AND name NOT LIKE 'sqlite_%'" |
24691 | " AND name LIKE ?1" , 0); |
24692 | }else{ |
24693 | appendText(&s," WHERE type='index'" |
24694 | " AND tbl_name LIKE ?1" , 0); |
24695 | } |
24696 | } |
24697 | rc = sqlite3_finalize(pStmt); |
24698 | if( rc==SQLITE_OK ){ |
24699 | appendText(&s, " ORDER BY 1" , 0); |
24700 | rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0); |
24701 | } |
24702 | freeText(&s); |
24703 | if( rc ) return shellDatabaseError(p->db); |
24704 | |
24705 | /* Run the SQL statement prepared by the above block. Store the results |
24706 | ** as an array of nul-terminated strings in azResult[]. */ |
24707 | nRow = nAlloc = 0; |
24708 | azResult = 0; |
24709 | if( nArg>1 ){ |
24710 | sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); |
24711 | }else{ |
24712 | sqlite3_bind_text(pStmt, 1, "%" , -1, SQLITE_STATIC); |
24713 | } |
24714 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
24715 | if( nRow>=nAlloc ){ |
24716 | char **azNew; |
24717 | int n2 = nAlloc*2 + 10; |
24718 | azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); |
24719 | shell_check_oom(azNew); |
24720 | nAlloc = n2; |
24721 | azResult = azNew; |
24722 | } |
24723 | azResult[nRow] = sqlite3_mprintf("%s" , sqlite3_column_text(pStmt, 0)); |
24724 | shell_check_oom(azResult[nRow]); |
24725 | nRow++; |
24726 | } |
24727 | if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ |
24728 | rc = shellDatabaseError(p->db); |
24729 | } |
24730 | |
24731 | /* Pretty-print the contents of array azResult[] to the output */ |
24732 | if( rc==0 && nRow>0 ){ |
24733 | int len, maxlen = 0; |
24734 | int i, j; |
24735 | int nPrintCol, nPrintRow; |
24736 | for(i=0; i<nRow; i++){ |
24737 | len = strlen30(azResult[i]); |
24738 | if( len>maxlen ) maxlen = len; |
24739 | } |
24740 | nPrintCol = 80/(maxlen+2); |
24741 | if( nPrintCol<1 ) nPrintCol = 1; |
24742 | nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; |
24743 | for(i=0; i<nPrintRow; i++){ |
24744 | for(j=i; j<nRow; j+=nPrintRow){ |
24745 | char *zSp = j<nPrintRow ? "" : " " ; |
24746 | utf8_printf(p->out, "%s%-*s" , zSp, maxlen, |
24747 | azResult[j] ? azResult[j]:"" ); |
24748 | } |
24749 | raw_printf(p->out, "\n" ); |
24750 | } |
24751 | } |
24752 | |
24753 | for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]); |
24754 | sqlite3_free(azResult); |
24755 | }else |
24756 | |
24757 | #ifndef SQLITE_SHELL_FIDDLE |
24758 | /* Begin redirecting output to the file "testcase-out.txt" */ |
24759 | if( c=='t' && cli_strcmp(azArg[0],"testcase" )==0 ){ |
24760 | output_reset(p); |
24761 | p->out = output_file_open("testcase-out.txt" , 0); |
24762 | if( p->out==0 ){ |
24763 | raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n" ); |
24764 | } |
24765 | if( nArg>=2 ){ |
24766 | sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s" , azArg[1]); |
24767 | }else{ |
24768 | sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?" ); |
24769 | } |
24770 | }else |
24771 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
24772 | |
24773 | #ifndef SQLITE_UNTESTABLE |
24774 | if( c=='t' && n>=8 && cli_strncmp(azArg[0], "testctrl" , n)==0 ){ |
24775 | static const struct { |
24776 | const char *zCtrlName; /* Name of a test-control option */ |
24777 | int ctrlCode; /* Integer code for that option */ |
24778 | int unSafe; /* Not valid for --safe mode */ |
24779 | const char *zUsage; /* Usage notes */ |
24780 | } aCtrl[] = { |
24781 | { "always" , SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, |
24782 | { "assert" , SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" }, |
24783 | /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/ |
24784 | /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/ |
24785 | { "byteorder" , SQLITE_TESTCTRL_BYTEORDER, 0, "" }, |
24786 | { "extra_schema_checks" ,SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, |
24787 | /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/ |
24788 | { "imposter" , SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE" }, |
24789 | { "internal_functions" , SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" }, |
24790 | { "localtime_fault" , SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" }, |
24791 | { "never_corrupt" , SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" }, |
24792 | { "optimizations" , SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" }, |
24793 | #ifdef YYCOVERAGE |
24794 | { "parser_coverage" , SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" }, |
24795 | #endif |
24796 | { "pending_byte" , SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " }, |
24797 | { "prng_restore" , SQLITE_TESTCTRL_PRNG_RESTORE,0, "" }, |
24798 | { "prng_save" , SQLITE_TESTCTRL_PRNG_SAVE, 0, "" }, |
24799 | { "prng_seed" , SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" }, |
24800 | { "seek_count" , SQLITE_TESTCTRL_SEEK_COUNT, 0, "" }, |
24801 | { "sorter_mmap" , SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" }, |
24802 | { "tune" , SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" }, |
24803 | }; |
24804 | int testctrl = -1; |
24805 | int iCtrl = -1; |
24806 | int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */ |
24807 | int isOk = 0; |
24808 | int i, n2; |
24809 | const char *zCmd = 0; |
24810 | |
24811 | open_db(p, 0); |
24812 | zCmd = nArg>=2 ? azArg[1] : "help" ; |
24813 | |
24814 | /* The argument can optionally begin with "-" or "--" */ |
24815 | if( zCmd[0]=='-' && zCmd[1] ){ |
24816 | zCmd++; |
24817 | if( zCmd[0]=='-' && zCmd[1] ) zCmd++; |
24818 | } |
24819 | |
24820 | /* --help lists all test-controls */ |
24821 | if( cli_strcmp(zCmd,"help" )==0 ){ |
24822 | utf8_printf(p->out, "Available test-controls:\n" ); |
24823 | for(i=0; i<ArraySize(aCtrl); i++){ |
24824 | utf8_printf(p->out, " .testctrl %s %s\n" , |
24825 | aCtrl[i].zCtrlName, aCtrl[i].zUsage); |
24826 | } |
24827 | rc = 1; |
24828 | goto meta_command_exit; |
24829 | } |
24830 | |
24831 | /* convert testctrl text option to value. allow any unique prefix |
24832 | ** of the option name, or a numerical value. */ |
24833 | n2 = strlen30(zCmd); |
24834 | for(i=0; i<ArraySize(aCtrl); i++){ |
24835 | if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){ |
24836 | if( testctrl<0 ){ |
24837 | testctrl = aCtrl[i].ctrlCode; |
24838 | iCtrl = i; |
24839 | }else{ |
24840 | utf8_printf(stderr, "Error: ambiguous test-control: \"%s\"\n" |
24841 | "Use \".testctrl --help\" for help\n" , zCmd); |
24842 | rc = 1; |
24843 | goto meta_command_exit; |
24844 | } |
24845 | } |
24846 | } |
24847 | if( testctrl<0 ){ |
24848 | utf8_printf(stderr,"Error: unknown test-control: %s\n" |
24849 | "Use \".testctrl --help\" for help\n" , zCmd); |
24850 | }else if( aCtrl[iCtrl].unSafe && p->bSafeMode ){ |
24851 | utf8_printf(stderr, |
24852 | "line %d: \".testctrl %s\" may not be used in safe mode\n" , |
24853 | p->lineno, aCtrl[iCtrl].zCtrlName); |
24854 | exit(1); |
24855 | }else{ |
24856 | switch(testctrl){ |
24857 | |
24858 | /* sqlite3_test_control(int, db, int) */ |
24859 | case SQLITE_TESTCTRL_OPTIMIZATIONS: |
24860 | if( nArg==3 ){ |
24861 | unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); |
24862 | rc2 = sqlite3_test_control(testctrl, p->db, opt); |
24863 | isOk = 3; |
24864 | } |
24865 | break; |
24866 | |
24867 | /* sqlite3_test_control(int) */ |
24868 | case SQLITE_TESTCTRL_PRNG_SAVE: |
24869 | case SQLITE_TESTCTRL_PRNG_RESTORE: |
24870 | case SQLITE_TESTCTRL_BYTEORDER: |
24871 | if( nArg==2 ){ |
24872 | rc2 = sqlite3_test_control(testctrl); |
24873 | isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3; |
24874 | } |
24875 | break; |
24876 | |
24877 | /* sqlite3_test_control(int, uint) */ |
24878 | case SQLITE_TESTCTRL_PENDING_BYTE: |
24879 | if( nArg==3 ){ |
24880 | unsigned int opt = (unsigned int)integerValue(azArg[2]); |
24881 | rc2 = sqlite3_test_control(testctrl, opt); |
24882 | isOk = 3; |
24883 | } |
24884 | break; |
24885 | |
24886 | /* sqlite3_test_control(int, int, sqlite3*) */ |
24887 | case SQLITE_TESTCTRL_PRNG_SEED: |
24888 | if( nArg==3 || nArg==4 ){ |
24889 | int ii = (int)integerValue(azArg[2]); |
24890 | sqlite3 *db; |
24891 | if( ii==0 && cli_strcmp(azArg[2],"random" )==0 ){ |
24892 | sqlite3_randomness(sizeof(ii),&ii); |
24893 | printf("-- random seed: %d\n" , ii); |
24894 | } |
24895 | if( nArg==3 ){ |
24896 | db = 0; |
24897 | }else{ |
24898 | db = p->db; |
24899 | /* Make sure the schema has been loaded */ |
24900 | sqlite3_table_column_metadata(db, 0, "x" , 0, 0, 0, 0, 0, 0); |
24901 | } |
24902 | rc2 = sqlite3_test_control(testctrl, ii, db); |
24903 | isOk = 3; |
24904 | } |
24905 | break; |
24906 | |
24907 | /* sqlite3_test_control(int, int) */ |
24908 | case SQLITE_TESTCTRL_ASSERT: |
24909 | case SQLITE_TESTCTRL_ALWAYS: |
24910 | if( nArg==3 ){ |
24911 | int opt = booleanValue(azArg[2]); |
24912 | rc2 = sqlite3_test_control(testctrl, opt); |
24913 | isOk = 1; |
24914 | } |
24915 | break; |
24916 | |
24917 | /* sqlite3_test_control(int, int) */ |
24918 | case SQLITE_TESTCTRL_LOCALTIME_FAULT: |
24919 | case SQLITE_TESTCTRL_NEVER_CORRUPT: |
24920 | if( nArg==3 ){ |
24921 | int opt = booleanValue(azArg[2]); |
24922 | rc2 = sqlite3_test_control(testctrl, opt); |
24923 | isOk = 3; |
24924 | } |
24925 | break; |
24926 | |
24927 | /* sqlite3_test_control(sqlite3*) */ |
24928 | case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: |
24929 | rc2 = sqlite3_test_control(testctrl, p->db); |
24930 | isOk = 3; |
24931 | break; |
24932 | |
24933 | case SQLITE_TESTCTRL_IMPOSTER: |
24934 | if( nArg==5 ){ |
24935 | rc2 = sqlite3_test_control(testctrl, p->db, |
24936 | azArg[2], |
24937 | integerValue(azArg[3]), |
24938 | integerValue(azArg[4])); |
24939 | isOk = 3; |
24940 | } |
24941 | break; |
24942 | |
24943 | case SQLITE_TESTCTRL_SEEK_COUNT: { |
24944 | u64 x = 0; |
24945 | rc2 = sqlite3_test_control(testctrl, p->db, &x); |
24946 | utf8_printf(p->out, "%llu\n" , x); |
24947 | isOk = 3; |
24948 | break; |
24949 | } |
24950 | |
24951 | #ifdef YYCOVERAGE |
24952 | case SQLITE_TESTCTRL_PARSER_COVERAGE: { |
24953 | if( nArg==2 ){ |
24954 | sqlite3_test_control(testctrl, p->out); |
24955 | isOk = 3; |
24956 | } |
24957 | break; |
24958 | } |
24959 | #endif |
24960 | #ifdef SQLITE_DEBUG |
24961 | case SQLITE_TESTCTRL_TUNE: { |
24962 | if( nArg==4 ){ |
24963 | int id = (int)integerValue(azArg[2]); |
24964 | int val = (int)integerValue(azArg[3]); |
24965 | sqlite3_test_control(testctrl, id, &val); |
24966 | isOk = 3; |
24967 | }else if( nArg==3 ){ |
24968 | int id = (int)integerValue(azArg[2]); |
24969 | sqlite3_test_control(testctrl, -id, &rc2); |
24970 | isOk = 1; |
24971 | }else if( nArg==2 ){ |
24972 | int id = 1; |
24973 | while(1){ |
24974 | int val = 0; |
24975 | rc2 = sqlite3_test_control(testctrl, -id, &val); |
24976 | if( rc2!=SQLITE_OK ) break; |
24977 | if( id>1 ) utf8_printf(p->out, " " ); |
24978 | utf8_printf(p->out, "%d: %d" , id, val); |
24979 | id++; |
24980 | } |
24981 | if( id>1 ) utf8_printf(p->out, "\n" ); |
24982 | isOk = 3; |
24983 | } |
24984 | break; |
24985 | } |
24986 | #endif |
24987 | case SQLITE_TESTCTRL_SORTER_MMAP: |
24988 | if( nArg==3 ){ |
24989 | int opt = (unsigned int)integerValue(azArg[2]); |
24990 | rc2 = sqlite3_test_control(testctrl, p->db, opt); |
24991 | isOk = 3; |
24992 | } |
24993 | break; |
24994 | } |
24995 | } |
24996 | if( isOk==0 && iCtrl>=0 ){ |
24997 | utf8_printf(p->out, "Usage: .testctrl %s %s\n" , zCmd,aCtrl[iCtrl].zUsage); |
24998 | rc = 1; |
24999 | }else if( isOk==1 ){ |
25000 | raw_printf(p->out, "%d\n" , rc2); |
25001 | }else if( isOk==2 ){ |
25002 | raw_printf(p->out, "0x%08x\n" , rc2); |
25003 | } |
25004 | }else |
25005 | #endif /* !defined(SQLITE_UNTESTABLE) */ |
25006 | |
25007 | if( c=='t' && n>4 && cli_strncmp(azArg[0], "timeout" , n)==0 ){ |
25008 | open_db(p, 0); |
25009 | sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); |
25010 | }else |
25011 | |
25012 | if( c=='t' && n>=5 && cli_strncmp(azArg[0], "timer" , n)==0 ){ |
25013 | if( nArg==2 ){ |
25014 | enableTimer = booleanValue(azArg[1]); |
25015 | if( enableTimer && !HAS_TIMER ){ |
25016 | raw_printf(stderr, "Error: timer not available on this system.\n" ); |
25017 | enableTimer = 0; |
25018 | } |
25019 | }else{ |
25020 | raw_printf(stderr, "Usage: .timer on|off\n" ); |
25021 | rc = 1; |
25022 | } |
25023 | }else |
25024 | |
25025 | #ifndef SQLITE_OMIT_TRACE |
25026 | if( c=='t' && cli_strncmp(azArg[0], "trace" , n)==0 ){ |
25027 | int mType = 0; |
25028 | int jj; |
25029 | open_db(p, 0); |
25030 | for(jj=1; jj<nArg; jj++){ |
25031 | const char *z = azArg[jj]; |
25032 | if( z[0]=='-' ){ |
25033 | if( optionMatch(z, "expanded" ) ){ |
25034 | p->eTraceType = SHELL_TRACE_EXPANDED; |
25035 | } |
25036 | #ifdef SQLITE_ENABLE_NORMALIZE |
25037 | else if( optionMatch(z, "normalized" ) ){ |
25038 | p->eTraceType = SHELL_TRACE_NORMALIZED; |
25039 | } |
25040 | #endif |
25041 | else if( optionMatch(z, "plain" ) ){ |
25042 | p->eTraceType = SHELL_TRACE_PLAIN; |
25043 | } |
25044 | else if( optionMatch(z, "profile" ) ){ |
25045 | mType |= SQLITE_TRACE_PROFILE; |
25046 | } |
25047 | else if( optionMatch(z, "row" ) ){ |
25048 | mType |= SQLITE_TRACE_ROW; |
25049 | } |
25050 | else if( optionMatch(z, "stmt" ) ){ |
25051 | mType |= SQLITE_TRACE_STMT; |
25052 | } |
25053 | else if( optionMatch(z, "close" ) ){ |
25054 | mType |= SQLITE_TRACE_CLOSE; |
25055 | } |
25056 | else { |
25057 | raw_printf(stderr, "Unknown option \"%s\" on \".trace\"\n" , z); |
25058 | rc = 1; |
25059 | goto meta_command_exit; |
25060 | } |
25061 | }else{ |
25062 | output_file_close(p->traceOut); |
25063 | p->traceOut = output_file_open(azArg[1], 0); |
25064 | } |
25065 | } |
25066 | if( p->traceOut==0 ){ |
25067 | sqlite3_trace_v2(p->db, 0, 0, 0); |
25068 | }else{ |
25069 | if( mType==0 ) mType = SQLITE_TRACE_STMT; |
25070 | sqlite3_trace_v2(p->db, mType, sql_trace_callback, p); |
25071 | } |
25072 | }else |
25073 | #endif /* !defined(SQLITE_OMIT_TRACE) */ |
25074 | |
25075 | #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE) |
25076 | if( c=='u' && cli_strncmp(azArg[0], "unmodule" , n)==0 ){ |
25077 | int ii; |
25078 | int lenOpt; |
25079 | char *zOpt; |
25080 | if( nArg<2 ){ |
25081 | raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n" ); |
25082 | rc = 1; |
25083 | goto meta_command_exit; |
25084 | } |
25085 | open_db(p, 0); |
25086 | zOpt = azArg[1]; |
25087 | if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++; |
25088 | lenOpt = (int)strlen(zOpt); |
25089 | if( lenOpt>=3 && cli_strncmp(zOpt, "-allexcept" ,lenOpt)==0 ){ |
25090 | assert( azArg[nArg]==0 ); |
25091 | sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0); |
25092 | }else{ |
25093 | for(ii=1; ii<nArg; ii++){ |
25094 | sqlite3_create_module(p->db, azArg[ii], 0, 0); |
25095 | } |
25096 | } |
25097 | }else |
25098 | #endif |
25099 | |
25100 | #if SQLITE_USER_AUTHENTICATION |
25101 | if( c=='u' && cli_strncmp(azArg[0], "user" , n)==0 ){ |
25102 | if( nArg<2 ){ |
25103 | raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n" ); |
25104 | rc = 1; |
25105 | goto meta_command_exit; |
25106 | } |
25107 | open_db(p, 0); |
25108 | if( cli_strcmp(azArg[1],"login" )==0 ){ |
25109 | if( nArg!=4 ){ |
25110 | raw_printf(stderr, "Usage: .user login USER PASSWORD\n" ); |
25111 | rc = 1; |
25112 | goto meta_command_exit; |
25113 | } |
25114 | rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], |
25115 | strlen30(azArg[3])); |
25116 | if( rc ){ |
25117 | utf8_printf(stderr, "Authentication failed for user %s\n" , azArg[2]); |
25118 | rc = 1; |
25119 | } |
25120 | }else if( cli_strcmp(azArg[1],"add" )==0 ){ |
25121 | if( nArg!=5 ){ |
25122 | raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n" ); |
25123 | rc = 1; |
25124 | goto meta_command_exit; |
25125 | } |
25126 | rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]), |
25127 | booleanValue(azArg[4])); |
25128 | if( rc ){ |
25129 | raw_printf(stderr, "User-Add failed: %d\n" , rc); |
25130 | rc = 1; |
25131 | } |
25132 | }else if( cli_strcmp(azArg[1],"edit" )==0 ){ |
25133 | if( nArg!=5 ){ |
25134 | raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n" ); |
25135 | rc = 1; |
25136 | goto meta_command_exit; |
25137 | } |
25138 | rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]), |
25139 | booleanValue(azArg[4])); |
25140 | if( rc ){ |
25141 | raw_printf(stderr, "User-Edit failed: %d\n" , rc); |
25142 | rc = 1; |
25143 | } |
25144 | }else if( cli_strcmp(azArg[1],"delete" )==0 ){ |
25145 | if( nArg!=3 ){ |
25146 | raw_printf(stderr, "Usage: .user delete USER\n" ); |
25147 | rc = 1; |
25148 | goto meta_command_exit; |
25149 | } |
25150 | rc = sqlite3_user_delete(p->db, azArg[2]); |
25151 | if( rc ){ |
25152 | raw_printf(stderr, "User-Delete failed: %d\n" , rc); |
25153 | rc = 1; |
25154 | } |
25155 | }else{ |
25156 | raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n" ); |
25157 | rc = 1; |
25158 | goto meta_command_exit; |
25159 | } |
25160 | }else |
25161 | #endif /* SQLITE_USER_AUTHENTICATION */ |
25162 | |
25163 | if( c=='v' && cli_strncmp(azArg[0], "version" , n)==0 ){ |
25164 | utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, |
25165 | sqlite3_libversion(), sqlite3_sourceid()); |
25166 | #if SQLITE_HAVE_ZLIB |
25167 | utf8_printf(p->out, "zlib version %s\n" , zlibVersion()); |
25168 | #endif |
25169 | #define CTIMEOPT_VAL_(opt) #opt |
25170 | #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) |
25171 | #if defined(__clang__) && defined(__clang_major__) |
25172 | utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." |
25173 | CTIMEOPT_VAL(__clang_minor__) "." |
25174 | CTIMEOPT_VAL(__clang_patchlevel__) "\n" ); |
25175 | #elif defined(_MSC_VER) |
25176 | utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n" ); |
25177 | #elif defined(__GNUC__) && defined(__VERSION__) |
25178 | utf8_printf(p->out, "gcc-" __VERSION__ "\n" ); |
25179 | #endif |
25180 | }else |
25181 | |
25182 | if( c=='v' && cli_strncmp(azArg[0], "vfsinfo" , n)==0 ){ |
25183 | const char *zDbName = nArg==2 ? azArg[1] : "main" ; |
25184 | sqlite3_vfs *pVfs = 0; |
25185 | if( p->db ){ |
25186 | sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); |
25187 | if( pVfs ){ |
25188 | utf8_printf(p->out, "vfs.zName = \"%s\"\n" , pVfs->zName); |
25189 | raw_printf(p->out, "vfs.iVersion = %d\n" , pVfs->iVersion); |
25190 | raw_printf(p->out, "vfs.szOsFile = %d\n" , pVfs->szOsFile); |
25191 | raw_printf(p->out, "vfs.mxPathname = %d\n" , pVfs->mxPathname); |
25192 | } |
25193 | } |
25194 | }else |
25195 | |
25196 | if( c=='v' && cli_strncmp(azArg[0], "vfslist" , n)==0 ){ |
25197 | sqlite3_vfs *pVfs; |
25198 | sqlite3_vfs *pCurrent = 0; |
25199 | if( p->db ){ |
25200 | sqlite3_file_control(p->db, "main" , SQLITE_FCNTL_VFS_POINTER, &pCurrent); |
25201 | } |
25202 | for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ |
25203 | utf8_printf(p->out, "vfs.zName = \"%s\"%s\n" , pVfs->zName, |
25204 | pVfs==pCurrent ? " <--- CURRENT" : "" ); |
25205 | raw_printf(p->out, "vfs.iVersion = %d\n" , pVfs->iVersion); |
25206 | raw_printf(p->out, "vfs.szOsFile = %d\n" , pVfs->szOsFile); |
25207 | raw_printf(p->out, "vfs.mxPathname = %d\n" , pVfs->mxPathname); |
25208 | if( pVfs->pNext ){ |
25209 | raw_printf(p->out, "-----------------------------------\n" ); |
25210 | } |
25211 | } |
25212 | }else |
25213 | |
25214 | if( c=='v' && cli_strncmp(azArg[0], "vfsname" , n)==0 ){ |
25215 | const char *zDbName = nArg==2 ? azArg[1] : "main" ; |
25216 | char *zVfsName = 0; |
25217 | if( p->db ){ |
25218 | sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); |
25219 | if( zVfsName ){ |
25220 | utf8_printf(p->out, "%s\n" , zVfsName); |
25221 | sqlite3_free(zVfsName); |
25222 | } |
25223 | } |
25224 | }else |
25225 | |
25226 | if( c=='w' && cli_strncmp(azArg[0], "wheretrace" , n)==0 ){ |
25227 | unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; |
25228 | sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x); |
25229 | }else |
25230 | |
25231 | if( c=='w' && cli_strncmp(azArg[0], "width" , n)==0 ){ |
25232 | int j; |
25233 | assert( nArg<=ArraySize(azArg) ); |
25234 | p->nWidth = nArg-1; |
25235 | p->colWidth = realloc(p->colWidth, (p->nWidth+1)*sizeof(int)*2); |
25236 | if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory(); |
25237 | if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth]; |
25238 | for(j=1; j<nArg; j++){ |
25239 | p->colWidth[j-1] = (int)integerValue(azArg[j]); |
25240 | } |
25241 | }else |
25242 | |
25243 | { |
25244 | utf8_printf(stderr, "Error: unknown command or invalid arguments: " |
25245 | " \"%s\". Enter \".help\" for help\n" , azArg[0]); |
25246 | rc = 1; |
25247 | } |
25248 | |
25249 | meta_command_exit: |
25250 | if( p->outCount ){ |
25251 | p->outCount--; |
25252 | if( p->outCount==0 ) output_reset(p); |
25253 | } |
25254 | p->bSafeMode = p->bSafeModePersist; |
25255 | return rc; |
25256 | } |
25257 | |
25258 | /* Line scan result and intermediate states (supporting scan resumption) |
25259 | */ |
25260 | #ifndef CHAR_BIT |
25261 | # define CHAR_BIT 8 |
25262 | #endif |
25263 | typedef enum { |
25264 | QSS_HasDark = 1<<CHAR_BIT, QSS_EndingSemi = 2<<CHAR_BIT, |
25265 | QSS_CharMask = (1<<CHAR_BIT)-1, QSS_ScanMask = 3<<CHAR_BIT, |
25266 | QSS_Start = 0 |
25267 | } QuickScanState; |
25268 | #define QSS_SETV(qss, newst) ((newst) | ((qss) & QSS_ScanMask)) |
25269 | #define QSS_INPLAIN(qss) (((qss)&QSS_CharMask)==QSS_Start) |
25270 | #define QSS_PLAINWHITE(qss) (((qss)&~QSS_EndingSemi)==QSS_Start) |
25271 | #define QSS_PLAINDARK(qss) (((qss)&~QSS_EndingSemi)==QSS_HasDark) |
25272 | #define QSS_SEMITERM(qss) (((qss)&~QSS_HasDark)==QSS_EndingSemi) |
25273 | |
25274 | /* |
25275 | ** Scan line for classification to guide shell's handling. |
25276 | ** The scan is resumable for subsequent lines when prior |
25277 | ** return values are passed as the 2nd argument. |
25278 | */ |
25279 | static QuickScanState quickscan(char *zLine, QuickScanState qss){ |
25280 | char cin; |
25281 | char cWait = (char)qss; /* intentional narrowing loss */ |
25282 | if( cWait==0 ){ |
25283 | PlainScan: |
25284 | assert( cWait==0 ); |
25285 | while( (cin = *zLine++)!=0 ){ |
25286 | if( IsSpace(cin) ) |
25287 | continue; |
25288 | switch (cin){ |
25289 | case '-': |
25290 | if( *zLine!='-' ) |
25291 | break; |
25292 | while((cin = *++zLine)!=0 ) |
25293 | if( cin=='\n') |
25294 | goto PlainScan; |
25295 | return qss; |
25296 | case ';': |
25297 | qss |= QSS_EndingSemi; |
25298 | continue; |
25299 | case '/': |
25300 | if( *zLine=='*' ){ |
25301 | ++zLine; |
25302 | cWait = '*'; |
25303 | qss = QSS_SETV(qss, cWait); |
25304 | goto TermScan; |
25305 | } |
25306 | break; |
25307 | case '[': |
25308 | cin = ']'; |
25309 | /* fall thru */ |
25310 | case '`': case '\'': case '"': |
25311 | cWait = cin; |
25312 | qss = QSS_HasDark | cWait; |
25313 | goto TermScan; |
25314 | default: |
25315 | break; |
25316 | } |
25317 | qss = (qss & ~QSS_EndingSemi) | QSS_HasDark; |
25318 | } |
25319 | }else{ |
25320 | TermScan: |
25321 | while( (cin = *zLine++)!=0 ){ |
25322 | if( cin==cWait ){ |
25323 | switch( cWait ){ |
25324 | case '*': |
25325 | if( *zLine != '/' ) |
25326 | continue; |
25327 | ++zLine; |
25328 | cWait = 0; |
25329 | qss = QSS_SETV(qss, 0); |
25330 | goto PlainScan; |
25331 | case '`': case '\'': case '"': |
25332 | if(*zLine==cWait){ |
25333 | ++zLine; |
25334 | continue; |
25335 | } |
25336 | /* fall thru */ |
25337 | case ']': |
25338 | cWait = 0; |
25339 | qss = QSS_SETV(qss, 0); |
25340 | goto PlainScan; |
25341 | default: assert(0); |
25342 | } |
25343 | } |
25344 | } |
25345 | } |
25346 | return qss; |
25347 | } |
25348 | |
25349 | /* |
25350 | ** Return TRUE if the line typed in is an SQL command terminator other |
25351 | ** than a semi-colon. The SQL Server style "go" command is understood |
25352 | ** as is the Oracle "/". |
25353 | */ |
25354 | static int line_is_command_terminator(char *zLine){ |
25355 | while( IsSpace(zLine[0]) ){ zLine++; }; |
25356 | if( zLine[0]=='/' ) |
25357 | zLine += 1; /* Oracle */ |
25358 | else if ( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' ) |
25359 | zLine += 2; /* SQL Server */ |
25360 | else |
25361 | return 0; |
25362 | return quickscan(zLine, QSS_Start)==QSS_Start; |
25363 | } |
25364 | |
25365 | /* |
25366 | ** We need a default sqlite3_complete() implementation to use in case |
25367 | ** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes |
25368 | ** any arbitrary text is a complete SQL statement. This is not very |
25369 | ** user-friendly, but it does seem to work. |
25370 | */ |
25371 | #ifdef SQLITE_OMIT_COMPLETE |
25372 | #define sqlite3_complete(x) 1 |
25373 | #endif |
25374 | |
25375 | /* |
25376 | ** Return true if zSql is a complete SQL statement. Return false if it |
25377 | ** ends in the middle of a string literal or C-style comment. |
25378 | */ |
25379 | static int line_is_complete(char *zSql, int nSql){ |
25380 | int rc; |
25381 | if( zSql==0 ) return 1; |
25382 | zSql[nSql] = ';'; |
25383 | zSql[nSql+1] = 0; |
25384 | rc = sqlite3_complete(zSql); |
25385 | zSql[nSql] = 0; |
25386 | return rc; |
25387 | } |
25388 | |
25389 | /* |
25390 | ** Run a single line of SQL. Return the number of errors. |
25391 | */ |
25392 | static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ |
25393 | int rc; |
25394 | char *zErrMsg = 0; |
25395 | |
25396 | open_db(p, 0); |
25397 | if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql); |
25398 | if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; |
25399 | BEGIN_TIMER; |
25400 | rc = shell_exec(p, zSql, &zErrMsg); |
25401 | END_TIMER; |
25402 | if( rc || zErrMsg ){ |
25403 | char zPrefix[100]; |
25404 | const char *zErrorTail; |
25405 | const char *zErrorType; |
25406 | if( zErrMsg==0 ){ |
25407 | zErrorType = "Error" ; |
25408 | zErrorTail = sqlite3_errmsg(p->db); |
25409 | }else if( cli_strncmp(zErrMsg, "in prepare, " ,12)==0 ){ |
25410 | zErrorType = "Parse error" ; |
25411 | zErrorTail = &zErrMsg[12]; |
25412 | }else if( cli_strncmp(zErrMsg, "stepping, " , 10)==0 ){ |
25413 | zErrorType = "Runtime error" ; |
25414 | zErrorTail = &zErrMsg[10]; |
25415 | }else{ |
25416 | zErrorType = "Error" ; |
25417 | zErrorTail = zErrMsg; |
25418 | } |
25419 | if( in!=0 || !stdin_is_interactive ){ |
25420 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
25421 | "%s near line %d:" , zErrorType, startline); |
25422 | }else{ |
25423 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:" , zErrorType); |
25424 | } |
25425 | utf8_printf(stderr, "%s %s\n" , zPrefix, zErrorTail); |
25426 | sqlite3_free(zErrMsg); |
25427 | zErrMsg = 0; |
25428 | return 1; |
25429 | }else if( ShellHasFlag(p, SHFLG_CountChanges) ){ |
25430 | char zLineBuf[2000]; |
25431 | sqlite3_snprintf(sizeof(zLineBuf), zLineBuf, |
25432 | "changes: %lld total_changes: %lld" , |
25433 | sqlite3_changes64(p->db), sqlite3_total_changes64(p->db)); |
25434 | raw_printf(p->out, "%s\n" , zLineBuf); |
25435 | } |
25436 | return 0; |
25437 | } |
25438 | |
25439 | static void echo_group_input(ShellState *p, const char *zDo){ |
25440 | if( ShellHasFlag(p, SHFLG_Echo) ) utf8_printf(p->out, "%s\n" , zDo); |
25441 | } |
25442 | |
25443 | #ifdef SQLITE_SHELL_FIDDLE |
25444 | /* |
25445 | ** Alternate one_input_line() impl for wasm mode. This is not in the primary impl |
25446 | ** because we need the global shellState and cannot access it from that function |
25447 | ** without moving lots of code around (creating a larger/messier diff). |
25448 | */ |
25449 | static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ |
25450 | /* Parse the next line from shellState.wasm.zInput. */ |
25451 | const char *zBegin = shellState.wasm.zPos; |
25452 | const char *z = zBegin; |
25453 | char *zLine = 0; |
25454 | i64 nZ = 0; |
25455 | |
25456 | UNUSED_PARAMETER(in); |
25457 | UNUSED_PARAMETER(isContinuation); |
25458 | if(!z || !*z){ |
25459 | return 0; |
25460 | } |
25461 | while(*z && isspace(*z)) ++z; |
25462 | zBegin = z; |
25463 | for(; *z && '\n'!=*z; ++nZ, ++z){} |
25464 | if(nZ>0 && '\r'==zBegin[nZ-1]){ |
25465 | --nZ; |
25466 | } |
25467 | shellState.wasm.zPos = z; |
25468 | zLine = realloc(zPrior, nZ+1); |
25469 | shell_check_oom(zLine); |
25470 | memcpy(zLine, zBegin, nZ); |
25471 | zLine[nZ] = 0; |
25472 | return zLine; |
25473 | } |
25474 | #endif /* SQLITE_SHELL_FIDDLE */ |
25475 | |
25476 | /* |
25477 | ** Read input from *in and process it. If *in==0 then input |
25478 | ** is interactive - the user is typing it it. Otherwise, input |
25479 | ** is coming from a file or device. A prompt is issued and history |
25480 | ** is saved only if input is interactive. An interrupt signal will |
25481 | ** cause this routine to exit immediately, unless input is interactive. |
25482 | ** |
25483 | ** Return the number of errors. |
25484 | */ |
25485 | static int process_input(ShellState *p){ |
25486 | char *zLine = 0; /* A single input line */ |
25487 | char *zSql = 0; /* Accumulated SQL text */ |
25488 | i64 nLine; /* Length of current line */ |
25489 | i64 nSql = 0; /* Bytes of zSql[] used */ |
25490 | i64 nAlloc = 0; /* Allocated zSql[] space */ |
25491 | int rc; /* Error code */ |
25492 | int errCnt = 0; /* Number of errors seen */ |
25493 | i64 startline = 0; /* Line number for start of current input */ |
25494 | QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */ |
25495 | |
25496 | if( p->inputNesting==MAX_INPUT_NESTING ){ |
25497 | /* This will be more informative in a later version. */ |
25498 | utf8_printf(stderr,"Input nesting limit (%d) reached at line %d." |
25499 | " Check recursion.\n" , MAX_INPUT_NESTING, p->lineno); |
25500 | return 1; |
25501 | } |
25502 | ++p->inputNesting; |
25503 | p->lineno = 0; |
25504 | while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){ |
25505 | fflush(p->out); |
25506 | zLine = one_input_line(p->in, zLine, nSql>0); |
25507 | if( zLine==0 ){ |
25508 | /* End of input */ |
25509 | if( p->in==0 && stdin_is_interactive ) printf("\n" ); |
25510 | break; |
25511 | } |
25512 | if( seenInterrupt ){ |
25513 | if( p->in!=0 ) break; |
25514 | seenInterrupt = 0; |
25515 | } |
25516 | p->lineno++; |
25517 | if( QSS_INPLAIN(qss) |
25518 | && line_is_command_terminator(zLine) |
25519 | && line_is_complete(zSql, nSql) ){ |
25520 | memcpy(zLine,";" ,2); |
25521 | } |
25522 | qss = quickscan(zLine, qss); |
25523 | if( QSS_PLAINWHITE(qss) && nSql==0 ){ |
25524 | /* Just swallow single-line whitespace */ |
25525 | echo_group_input(p, zLine); |
25526 | qss = QSS_Start; |
25527 | continue; |
25528 | } |
25529 | if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){ |
25530 | echo_group_input(p, zLine); |
25531 | if( zLine[0]=='.' ){ |
25532 | rc = do_meta_command(zLine, p); |
25533 | if( rc==2 ){ /* exit requested */ |
25534 | break; |
25535 | }else if( rc ){ |
25536 | errCnt++; |
25537 | } |
25538 | } |
25539 | qss = QSS_Start; |
25540 | continue; |
25541 | } |
25542 | /* No single-line dispositions remain; accumulate line(s). */ |
25543 | nLine = strlen(zLine); |
25544 | if( nSql+nLine+2>=nAlloc ){ |
25545 | /* Grow buffer by half-again increments when big. */ |
25546 | nAlloc = nSql+(nSql>>1)+nLine+100; |
25547 | zSql = realloc(zSql, nAlloc); |
25548 | shell_check_oom(zSql); |
25549 | } |
25550 | if( nSql==0 ){ |
25551 | i64 i; |
25552 | for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} |
25553 | assert( nAlloc>0 && zSql!=0 ); |
25554 | memcpy(zSql, zLine+i, nLine+1-i); |
25555 | startline = p->lineno; |
25556 | nSql = nLine-i; |
25557 | }else{ |
25558 | zSql[nSql++] = '\n'; |
25559 | memcpy(zSql+nSql, zLine, nLine+1); |
25560 | nSql += nLine; |
25561 | } |
25562 | if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){ |
25563 | echo_group_input(p, zSql); |
25564 | errCnt += runOneSqlLine(p, zSql, p->in, startline); |
25565 | nSql = 0; |
25566 | if( p->outCount ){ |
25567 | output_reset(p); |
25568 | p->outCount = 0; |
25569 | }else{ |
25570 | clearTempFile(p); |
25571 | } |
25572 | p->bSafeMode = p->bSafeModePersist; |
25573 | qss = QSS_Start; |
25574 | }else if( nSql && QSS_PLAINWHITE(qss) ){ |
25575 | echo_group_input(p, zSql); |
25576 | nSql = 0; |
25577 | qss = QSS_Start; |
25578 | } |
25579 | } |
25580 | if( nSql ){ |
25581 | /* This may be incomplete. Let the SQL parser deal with that. */ |
25582 | echo_group_input(p, zSql); |
25583 | errCnt += runOneSqlLine(p, zSql, p->in, startline); |
25584 | } |
25585 | free(zSql); |
25586 | free(zLine); |
25587 | --p->inputNesting; |
25588 | return errCnt>0; |
25589 | } |
25590 | |
25591 | /* |
25592 | ** Return a pathname which is the user's home directory. A |
25593 | ** 0 return indicates an error of some kind. |
25594 | */ |
25595 | static char *find_home_dir(int clearFlag){ |
25596 | static char *home_dir = NULL; |
25597 | if( clearFlag ){ |
25598 | free(home_dir); |
25599 | home_dir = 0; |
25600 | return 0; |
25601 | } |
25602 | if( home_dir ) return home_dir; |
25603 | |
25604 | #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \ |
25605 | && !defined(__RTP__) && !defined(_WRS_KERNEL) |
25606 | { |
25607 | struct passwd *pwent; |
25608 | uid_t uid = getuid(); |
25609 | if( (pwent=getpwuid(uid)) != NULL) { |
25610 | home_dir = pwent->pw_dir; |
25611 | } |
25612 | } |
25613 | #endif |
25614 | |
25615 | #if defined(_WIN32_WCE) |
25616 | /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() |
25617 | */ |
25618 | home_dir = "/" ; |
25619 | #else |
25620 | |
25621 | #if defined(_WIN32) || defined(WIN32) |
25622 | if (!home_dir) { |
25623 | home_dir = getenv("USERPROFILE" ); |
25624 | } |
25625 | #endif |
25626 | |
25627 | if (!home_dir) { |
25628 | home_dir = getenv("HOME" ); |
25629 | } |
25630 | |
25631 | #if defined(_WIN32) || defined(WIN32) |
25632 | if (!home_dir) { |
25633 | char *zDrive, *zPath; |
25634 | int n; |
25635 | zDrive = getenv("HOMEDRIVE" ); |
25636 | zPath = getenv("HOMEPATH" ); |
25637 | if( zDrive && zPath ){ |
25638 | n = strlen30(zDrive) + strlen30(zPath) + 1; |
25639 | home_dir = malloc( n ); |
25640 | if( home_dir==0 ) return 0; |
25641 | sqlite3_snprintf(n, home_dir, "%s%s" , zDrive, zPath); |
25642 | return home_dir; |
25643 | } |
25644 | home_dir = "c:\\" ; |
25645 | } |
25646 | #endif |
25647 | |
25648 | #endif /* !_WIN32_WCE */ |
25649 | |
25650 | if( home_dir ){ |
25651 | i64 n = strlen(home_dir) + 1; |
25652 | char *z = malloc( n ); |
25653 | if( z ) memcpy(z, home_dir, n); |
25654 | home_dir = z; |
25655 | } |
25656 | |
25657 | return home_dir; |
25658 | } |
25659 | |
25660 | /* |
25661 | ** Read input from the file given by sqliterc_override. Or if that |
25662 | ** parameter is NULL, take input from ~/.sqliterc |
25663 | ** |
25664 | ** Returns the number of errors. |
25665 | */ |
25666 | static void process_sqliterc( |
25667 | ShellState *p, /* Configuration data */ |
25668 | const char *sqliterc_override /* Name of config file. NULL to use default */ |
25669 | ){ |
25670 | char *home_dir = NULL; |
25671 | const char *sqliterc = sqliterc_override; |
25672 | char *zBuf = 0; |
25673 | FILE *inSaved = p->in; |
25674 | int savedLineno = p->lineno; |
25675 | |
25676 | if (sqliterc == NULL) { |
25677 | home_dir = find_home_dir(0); |
25678 | if( home_dir==0 ){ |
25679 | raw_printf(stderr, "-- warning: cannot find home directory;" |
25680 | " cannot read ~/.sqliterc\n" ); |
25681 | return; |
25682 | } |
25683 | zBuf = sqlite3_mprintf("%s/.sqliterc" ,home_dir); |
25684 | shell_check_oom(zBuf); |
25685 | sqliterc = zBuf; |
25686 | } |
25687 | p->in = fopen(sqliterc,"rb" ); |
25688 | if( p->in ){ |
25689 | if( stdin_is_interactive ){ |
25690 | utf8_printf(stderr,"-- Loading resources from %s\n" ,sqliterc); |
25691 | } |
25692 | if( process_input(p) && bail_on_error ) exit(1); |
25693 | fclose(p->in); |
25694 | }else if( sqliterc_override!=0 ){ |
25695 | utf8_printf(stderr,"cannot open: \"%s\"\n" , sqliterc); |
25696 | if( bail_on_error ) exit(1); |
25697 | } |
25698 | p->in = inSaved; |
25699 | p->lineno = savedLineno; |
25700 | sqlite3_free(zBuf); |
25701 | } |
25702 | |
25703 | /* |
25704 | ** Show available command line options |
25705 | */ |
25706 | static const char zOptions[] = |
25707 | #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) |
25708 | " -A ARGS... run \".archive ARGS\" and exit\n" |
25709 | #endif |
25710 | " -append append the database to the end of the file\n" |
25711 | " -ascii set output mode to 'ascii'\n" |
25712 | " -bail stop after hitting an error\n" |
25713 | " -batch force batch I/O\n" |
25714 | " -box set output mode to 'box'\n" |
25715 | " -column set output mode to 'column'\n" |
25716 | " -cmd COMMAND run \"COMMAND\" before reading stdin\n" |
25717 | " -csv set output mode to 'csv'\n" |
25718 | #if !defined(SQLITE_OMIT_DESERIALIZE) |
25719 | " -deserialize open the database using sqlite3_deserialize()\n" |
25720 | #endif |
25721 | " -echo print inputs before execution\n" |
25722 | " -init FILENAME read/process named file\n" |
25723 | " -[no]header turn headers on or off\n" |
25724 | #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) |
25725 | " -heap SIZE Size of heap for memsys3 or memsys5\n" |
25726 | #endif |
25727 | " -help show this message\n" |
25728 | " -html set output mode to HTML\n" |
25729 | " -interactive force interactive I/O\n" |
25730 | " -json set output mode to 'json'\n" |
25731 | " -line set output mode to 'line'\n" |
25732 | " -list set output mode to 'list'\n" |
25733 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
25734 | " -markdown set output mode to 'markdown'\n" |
25735 | #if !defined(SQLITE_OMIT_DESERIALIZE) |
25736 | " -maxsize N maximum size for a --deserialize database\n" |
25737 | #endif |
25738 | " -memtrace trace all memory allocations and deallocations\n" |
25739 | " -mmap N default mmap size set to N\n" |
25740 | #ifdef SQLITE_ENABLE_MULTIPLEX |
25741 | " -multiplex enable the multiplexor VFS\n" |
25742 | #endif |
25743 | " -newline SEP set output row separator. Default: '\\n'\n" |
25744 | " -nofollow refuse to open symbolic links to database files\n" |
25745 | " -nonce STRING set the safe-mode escape nonce\n" |
25746 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
25747 | " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" |
25748 | " -quote set output mode to 'quote'\n" |
25749 | " -readonly open the database read-only\n" |
25750 | " -safe enable safe-mode\n" |
25751 | " -separator SEP set output column separator. Default: '|'\n" |
25752 | #ifdef SQLITE_ENABLE_SORTER_REFERENCES |
25753 | " -sorterref SIZE sorter references threshold size\n" |
25754 | #endif |
25755 | " -stats print memory stats before each finalize\n" |
25756 | " -table set output mode to 'table'\n" |
25757 | " -tabs set output mode to 'tabs'\n" |
25758 | " -version show SQLite version\n" |
25759 | " -vfs NAME use NAME as the default VFS\n" |
25760 | #ifdef SQLITE_ENABLE_VFSTRACE |
25761 | " -vfstrace enable tracing of all VFS calls\n" |
25762 | #endif |
25763 | #ifdef SQLITE_HAVE_ZLIB |
25764 | " -zip open the file as a ZIP Archive\n" |
25765 | #endif |
25766 | ; |
25767 | static void usage(int showDetail){ |
25768 | utf8_printf(stderr, |
25769 | "Usage: %s [OPTIONS] FILENAME [SQL]\n" |
25770 | "FILENAME is the name of an SQLite database. A new database is created\n" |
25771 | "if the file does not previously exist.\n" , Argv0); |
25772 | if( showDetail ){ |
25773 | utf8_printf(stderr, "OPTIONS include:\n%s" , zOptions); |
25774 | }else{ |
25775 | raw_printf(stderr, "Use the -help option for additional information\n" ); |
25776 | } |
25777 | exit(1); |
25778 | } |
25779 | |
25780 | /* |
25781 | ** Internal check: Verify that the SQLite is uninitialized. Print a |
25782 | ** error message if it is initialized. |
25783 | */ |
25784 | static void verify_uninitialized(void){ |
25785 | if( sqlite3_config(-1)==SQLITE_MISUSE ){ |
25786 | utf8_printf(stdout, "WARNING: attempt to configure SQLite after" |
25787 | " initialization.\n" ); |
25788 | } |
25789 | } |
25790 | |
25791 | /* |
25792 | ** Initialize the state information in data |
25793 | */ |
25794 | static void main_init(ShellState *data) { |
25795 | memset(data, 0, sizeof(*data)); |
25796 | data->normalMode = data->cMode = data->mode = MODE_List; |
25797 | data->autoExplain = 1; |
25798 | data->pAuxDb = &data->aAuxDb[0]; |
25799 | memcpy(data->colSeparator,SEP_Column, 2); |
25800 | memcpy(data->rowSeparator,SEP_Row, 2); |
25801 | data->showHeader = 0; |
25802 | data->shellFlgs = SHFLG_Lookaside; |
25803 | verify_uninitialized(); |
25804 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
25805 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
25806 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
25807 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> " ); |
25808 | sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> " ); |
25809 | } |
25810 | |
25811 | /* |
25812 | ** Output text to the console in a font that attracts extra attention. |
25813 | */ |
25814 | #ifdef _WIN32 |
25815 | static void printBold(const char *zText){ |
25816 | #if !SQLITE_OS_WINRT |
25817 | HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); |
25818 | CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo; |
25819 | GetConsoleScreenBufferInfo(out, &defaultScreenInfo); |
25820 | SetConsoleTextAttribute(out, |
25821 | FOREGROUND_RED|FOREGROUND_INTENSITY |
25822 | ); |
25823 | #endif |
25824 | printf("%s" , zText); |
25825 | #if !SQLITE_OS_WINRT |
25826 | SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); |
25827 | #endif |
25828 | } |
25829 | #else |
25830 | static void printBold(const char *zText){ |
25831 | printf("\033[1m%s\033[0m" , zText); |
25832 | } |
25833 | #endif |
25834 | |
25835 | /* |
25836 | ** Get the argument to an --option. Throw an error and die if no argument |
25837 | ** is available. |
25838 | */ |
25839 | static char *cmdline_option_value(int argc, char **argv, int i){ |
25840 | if( i==argc ){ |
25841 | utf8_printf(stderr, "%s: Error: missing argument to %s\n" , |
25842 | argv[0], argv[argc-1]); |
25843 | exit(1); |
25844 | } |
25845 | return argv[i]; |
25846 | } |
25847 | |
25848 | #ifndef SQLITE_SHELL_IS_UTF8 |
25849 | # if (defined(_WIN32) || defined(WIN32)) \ |
25850 | && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__))) |
25851 | # define SQLITE_SHELL_IS_UTF8 (0) |
25852 | # else |
25853 | # define SQLITE_SHELL_IS_UTF8 (1) |
25854 | # endif |
25855 | #endif |
25856 | |
25857 | #ifdef SQLITE_SHELL_FIDDLE |
25858 | # define main fiddle_main |
25859 | #endif |
25860 | |
25861 | #if SQLITE_SHELL_IS_UTF8 |
25862 | int SQLITE_CDECL main(int argc, char **argv){ |
25863 | #else |
25864 | int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ |
25865 | char **argv; |
25866 | #endif |
25867 | #ifdef SQLITE_DEBUG |
25868 | sqlite3_int64 mem_main_enter = sqlite3_memory_used(); |
25869 | #endif |
25870 | char *zErrMsg = 0; |
25871 | #ifdef SQLITE_SHELL_FIDDLE |
25872 | # define data shellState |
25873 | #else |
25874 | ShellState data; |
25875 | #endif |
25876 | const char *zInitFile = 0; |
25877 | int i; |
25878 | int rc = 0; |
25879 | int warnInmemoryDb = 0; |
25880 | int readStdin = 1; |
25881 | int nCmd = 0; |
25882 | char **azCmd = 0; |
25883 | const char *zVfs = 0; /* Value of -vfs command-line option */ |
25884 | #if !SQLITE_SHELL_IS_UTF8 |
25885 | char **argvToFree = 0; |
25886 | int argcToFree = 0; |
25887 | #endif |
25888 | |
25889 | setBinaryMode(stdin, 0); |
25890 | setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ |
25891 | #ifdef SQLITE_SHELL_FIDDLE |
25892 | stdin_is_interactive = 0; |
25893 | stdout_is_console = 1; |
25894 | data.wasm.zDefaultDbName = "/fiddle.sqlite3" ; |
25895 | #else |
25896 | stdin_is_interactive = isatty(0); |
25897 | stdout_is_console = isatty(1); |
25898 | #endif |
25899 | |
25900 | #if !defined(_WIN32_WCE) |
25901 | if( getenv("SQLITE_DEBUG_BREAK" ) ){ |
25902 | if( isatty(0) && isatty(2) ){ |
25903 | fprintf(stderr, |
25904 | "attach debugger to process %d and press any key to continue.\n" , |
25905 | GETPID()); |
25906 | fgetc(stdin); |
25907 | }else{ |
25908 | #if defined(_WIN32) || defined(WIN32) |
25909 | #if SQLITE_OS_WINRT |
25910 | __debugbreak(); |
25911 | #else |
25912 | DebugBreak(); |
25913 | #endif |
25914 | #elif defined(SIGTRAP) |
25915 | raise(SIGTRAP); |
25916 | #endif |
25917 | } |
25918 | } |
25919 | #endif |
25920 | |
25921 | #if USE_SYSTEM_SQLITE+0!=1 |
25922 | if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ |
25923 | utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n" , |
25924 | sqlite3_sourceid(), SQLITE_SOURCE_ID); |
25925 | exit(1); |
25926 | } |
25927 | #endif |
25928 | main_init(&data); |
25929 | |
25930 | /* On Windows, we must translate command-line arguments into UTF-8. |
25931 | ** The SQLite memory allocator subsystem has to be enabled in order to |
25932 | ** do this. But we want to run an sqlite3_shutdown() afterwards so that |
25933 | ** subsequent sqlite3_config() calls will work. So copy all results into |
25934 | ** memory that does not come from the SQLite memory allocator. |
25935 | */ |
25936 | #if !SQLITE_SHELL_IS_UTF8 |
25937 | sqlite3_initialize(); |
25938 | argvToFree = malloc(sizeof(argv[0])*argc*2); |
25939 | shell_check_oom(argvToFree); |
25940 | argcToFree = argc; |
25941 | argv = argvToFree + argc; |
25942 | for(i=0; i<argc; i++){ |
25943 | char *z = sqlite3_win32_unicode_to_utf8(wargv[i]); |
25944 | i64 n; |
25945 | shell_check_oom(z); |
25946 | n = strlen(z); |
25947 | argv[i] = malloc( n+1 ); |
25948 | shell_check_oom(argv[i]); |
25949 | memcpy(argv[i], z, n+1); |
25950 | argvToFree[i] = argv[i]; |
25951 | sqlite3_free(z); |
25952 | } |
25953 | sqlite3_shutdown(); |
25954 | #endif |
25955 | |
25956 | assert( argc>=1 && argv && argv[0] ); |
25957 | Argv0 = argv[0]; |
25958 | |
25959 | /* Make sure we have a valid signal handler early, before anything |
25960 | ** else is done. |
25961 | */ |
25962 | #ifdef SIGINT |
25963 | signal(SIGINT, interrupt_handler); |
25964 | #elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) |
25965 | SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE); |
25966 | #endif |
25967 | |
25968 | #ifdef SQLITE_SHELL_DBNAME_PROC |
25969 | { |
25970 | /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name |
25971 | ** of a C-function that will provide the name of the database file. Use |
25972 | ** this compile-time option to embed this shell program in larger |
25973 | ** applications. */ |
25974 | extern void SQLITE_SHELL_DBNAME_PROC(const char**); |
25975 | SQLITE_SHELL_DBNAME_PROC(&data.pAuxDb->zDbFilename); |
25976 | warnInmemoryDb = 0; |
25977 | } |
25978 | #endif |
25979 | |
25980 | /* Do an initial pass through the command-line argument to locate |
25981 | ** the name of the database file, the name of the initialization file, |
25982 | ** the size of the alternative malloc heap, |
25983 | ** and the first command to execute. |
25984 | */ |
25985 | verify_uninitialized(); |
25986 | for(i=1; i<argc; i++){ |
25987 | char *z; |
25988 | z = argv[i]; |
25989 | if( z[0]!='-' ){ |
25990 | if( data.aAuxDb->zDbFilename==0 ){ |
25991 | data.aAuxDb->zDbFilename = z; |
25992 | }else{ |
25993 | /* Excesss arguments are interpreted as SQL (or dot-commands) and |
25994 | ** mean that nothing is read from stdin */ |
25995 | readStdin = 0; |
25996 | nCmd++; |
25997 | azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd); |
25998 | shell_check_oom(azCmd); |
25999 | azCmd[nCmd-1] = z; |
26000 | } |
26001 | } |
26002 | if( z[1]=='-' ) z++; |
26003 | if( cli_strcmp(z,"-separator" )==0 |
26004 | || cli_strcmp(z,"-nullvalue" )==0 |
26005 | || cli_strcmp(z,"-newline" )==0 |
26006 | || cli_strcmp(z,"-cmd" )==0 |
26007 | ){ |
26008 | (void)cmdline_option_value(argc, argv, ++i); |
26009 | }else if( cli_strcmp(z,"-init" )==0 ){ |
26010 | zInitFile = cmdline_option_value(argc, argv, ++i); |
26011 | }else if( cli_strcmp(z,"-batch" )==0 ){ |
26012 | /* Need to check for batch mode here to so we can avoid printing |
26013 | ** informational messages (like from process_sqliterc) before |
26014 | ** we do the actual processing of arguments later in a second pass. |
26015 | */ |
26016 | stdin_is_interactive = 0; |
26017 | }else if( cli_strcmp(z,"-heap" )==0 ){ |
26018 | #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) |
26019 | const char *zSize; |
26020 | sqlite3_int64 szHeap; |
26021 | |
26022 | zSize = cmdline_option_value(argc, argv, ++i); |
26023 | szHeap = integerValue(zSize); |
26024 | if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; |
26025 | sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); |
26026 | #else |
26027 | (void)cmdline_option_value(argc, argv, ++i); |
26028 | #endif |
26029 | }else if( cli_strcmp(z,"-pagecache" )==0 ){ |
26030 | sqlite3_int64 n, sz; |
26031 | sz = integerValue(cmdline_option_value(argc,argv,++i)); |
26032 | if( sz>70000 ) sz = 70000; |
26033 | if( sz<0 ) sz = 0; |
26034 | n = integerValue(cmdline_option_value(argc,argv,++i)); |
26035 | if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){ |
26036 | n = 0xffffffffffffLL/sz; |
26037 | } |
26038 | sqlite3_config(SQLITE_CONFIG_PAGECACHE, |
26039 | (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); |
26040 | data.shellFlgs |= SHFLG_Pagecache; |
26041 | }else if( cli_strcmp(z,"-lookaside" )==0 ){ |
26042 | int n, sz; |
26043 | sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
26044 | if( sz<0 ) sz = 0; |
26045 | n = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
26046 | if( n<0 ) n = 0; |
26047 | sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); |
26048 | if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; |
26049 | }else if( cli_strcmp(z,"-threadsafe" )==0 ){ |
26050 | int n; |
26051 | n = (int)integerValue(cmdline_option_value(argc,argv,++i)); |
26052 | switch( n ){ |
26053 | case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break; |
26054 | case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break; |
26055 | default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break; |
26056 | } |
26057 | #ifdef SQLITE_ENABLE_VFSTRACE |
26058 | }else if( cli_strcmp(z,"-vfstrace" )==0 ){ |
26059 | extern int vfstrace_register( |
26060 | const char *zTraceName, |
26061 | const char *zOldVfsName, |
26062 | int (*xOut)(const char*,void*), |
26063 | void *pOutArg, |
26064 | int makeDefault |
26065 | ); |
26066 | vfstrace_register("trace" ,0,(int(*)(const char*,void*))fputs,stderr,1); |
26067 | #endif |
26068 | #ifdef SQLITE_ENABLE_MULTIPLEX |
26069 | }else if( cli_strcmp(z,"-multiplex" )==0 ){ |
26070 | extern int sqlite3_multiple_initialize(const char*,int); |
26071 | sqlite3_multiplex_initialize(0, 1); |
26072 | #endif |
26073 | }else if( cli_strcmp(z,"-mmap" )==0 ){ |
26074 | sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); |
26075 | sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); |
26076 | #ifdef SQLITE_ENABLE_SORTER_REFERENCES |
26077 | }else if( cli_strcmp(z,"-sorterref" )==0 ){ |
26078 | sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); |
26079 | sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz); |
26080 | #endif |
26081 | }else if( cli_strcmp(z,"-vfs" )==0 ){ |
26082 | zVfs = cmdline_option_value(argc, argv, ++i); |
26083 | #ifdef SQLITE_HAVE_ZLIB |
26084 | }else if( cli_strcmp(z,"-zip" )==0 ){ |
26085 | data.openMode = SHELL_OPEN_ZIPFILE; |
26086 | #endif |
26087 | }else if( cli_strcmp(z,"-append" )==0 ){ |
26088 | data.openMode = SHELL_OPEN_APPENDVFS; |
26089 | #ifndef SQLITE_OMIT_DESERIALIZE |
26090 | }else if( cli_strcmp(z,"-deserialize" )==0 ){ |
26091 | data.openMode = SHELL_OPEN_DESERIALIZE; |
26092 | }else if( cli_strcmp(z,"-maxsize" )==0 && i+1<argc ){ |
26093 | data.szMax = integerValue(argv[++i]); |
26094 | #endif |
26095 | }else if( cli_strcmp(z,"-readonly" )==0 ){ |
26096 | data.openMode = SHELL_OPEN_READONLY; |
26097 | }else if( cli_strcmp(z,"-nofollow" )==0 ){ |
26098 | data.openFlags = SQLITE_OPEN_NOFOLLOW; |
26099 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
26100 | }else if( cli_strncmp(z, "-A" ,2)==0 ){ |
26101 | /* All remaining command-line arguments are passed to the ".archive" |
26102 | ** command, so ignore them */ |
26103 | break; |
26104 | #endif |
26105 | }else if( cli_strcmp(z, "-memtrace" )==0 ){ |
26106 | sqlite3MemTraceActivate(stderr); |
26107 | }else if( cli_strcmp(z,"-bail" )==0 ){ |
26108 | bail_on_error = 1; |
26109 | }else if( cli_strcmp(z,"-nonce" )==0 ){ |
26110 | free(data.zNonce); |
26111 | data.zNonce = strdup(argv[++i]); |
26112 | }else if( cli_strcmp(z,"-safe" )==0 ){ |
26113 | /* no-op - catch this on the second pass */ |
26114 | } |
26115 | } |
26116 | verify_uninitialized(); |
26117 | |
26118 | |
26119 | #ifdef SQLITE_SHELL_INIT_PROC |
26120 | { |
26121 | /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name |
26122 | ** of a C-function that will perform initialization actions on SQLite that |
26123 | ** occur just before or after sqlite3_initialize(). Use this compile-time |
26124 | ** option to embed this shell program in larger applications. */ |
26125 | extern void SQLITE_SHELL_INIT_PROC(void); |
26126 | SQLITE_SHELL_INIT_PROC(); |
26127 | } |
26128 | #else |
26129 | /* All the sqlite3_config() calls have now been made. So it is safe |
26130 | ** to call sqlite3_initialize() and process any command line -vfs option. */ |
26131 | sqlite3_initialize(); |
26132 | #endif |
26133 | |
26134 | if( zVfs ){ |
26135 | sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs); |
26136 | if( pVfs ){ |
26137 | sqlite3_vfs_register(pVfs, 1); |
26138 | }else{ |
26139 | utf8_printf(stderr, "no such VFS: \"%s\"\n" , zVfs); |
26140 | exit(1); |
26141 | } |
26142 | } |
26143 | |
26144 | if( data.pAuxDb->zDbFilename==0 ){ |
26145 | #ifndef SQLITE_OMIT_MEMORYDB |
26146 | data.pAuxDb->zDbFilename = ":memory:" ; |
26147 | warnInmemoryDb = argc==1; |
26148 | #else |
26149 | utf8_printf(stderr,"%s: Error: no database filename specified\n" , Argv0); |
26150 | return 1; |
26151 | #endif |
26152 | } |
26153 | data.out = stdout; |
26154 | #ifndef SQLITE_SHELL_FIDDLE |
26155 | sqlite3_appendvfs_init(0,0,0); |
26156 | #endif |
26157 | |
26158 | /* Go ahead and open the database file if it already exists. If the |
26159 | ** file does not exist, delay opening it. This prevents empty database |
26160 | ** files from being created if a user mistypes the database name argument |
26161 | ** to the sqlite command-line tool. |
26162 | */ |
26163 | if( access(data.pAuxDb->zDbFilename, 0)==0 ){ |
26164 | open_db(&data, 0); |
26165 | } |
26166 | |
26167 | /* Process the initialization file if there is one. If no -init option |
26168 | ** is given on the command line, look for a file named ~/.sqliterc and |
26169 | ** try to process it. |
26170 | */ |
26171 | process_sqliterc(&data,zInitFile); |
26172 | |
26173 | /* Make a second pass through the command-line argument and set |
26174 | ** options. This second pass is delayed until after the initialization |
26175 | ** file is processed so that the command-line arguments will override |
26176 | ** settings in the initialization file. |
26177 | */ |
26178 | for(i=1; i<argc; i++){ |
26179 | char *z = argv[i]; |
26180 | if( z[0]!='-' ) continue; |
26181 | if( z[1]=='-' ){ z++; } |
26182 | if( cli_strcmp(z,"-init" )==0 ){ |
26183 | i++; |
26184 | }else if( cli_strcmp(z,"-html" )==0 ){ |
26185 | data.mode = MODE_Html; |
26186 | }else if( cli_strcmp(z,"-list" )==0 ){ |
26187 | data.mode = MODE_List; |
26188 | }else if( cli_strcmp(z,"-quote" )==0 ){ |
26189 | data.mode = MODE_Quote; |
26190 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma); |
26191 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row); |
26192 | }else if( cli_strcmp(z,"-line" )==0 ){ |
26193 | data.mode = MODE_Line; |
26194 | }else if( cli_strcmp(z,"-column" )==0 ){ |
26195 | data.mode = MODE_Column; |
26196 | }else if( cli_strcmp(z,"-json" )==0 ){ |
26197 | data.mode = MODE_Json; |
26198 | }else if( cli_strcmp(z,"-markdown" )==0 ){ |
26199 | data.mode = MODE_Markdown; |
26200 | }else if( cli_strcmp(z,"-table" )==0 ){ |
26201 | data.mode = MODE_Table; |
26202 | }else if( cli_strcmp(z,"-box" )==0 ){ |
26203 | data.mode = MODE_Box; |
26204 | }else if( cli_strcmp(z,"-csv" )==0 ){ |
26205 | data.mode = MODE_Csv; |
26206 | memcpy(data.colSeparator,"," ,2); |
26207 | #ifdef SQLITE_HAVE_ZLIB |
26208 | }else if( cli_strcmp(z,"-zip" )==0 ){ |
26209 | data.openMode = SHELL_OPEN_ZIPFILE; |
26210 | #endif |
26211 | }else if( cli_strcmp(z,"-append" )==0 ){ |
26212 | data.openMode = SHELL_OPEN_APPENDVFS; |
26213 | #ifndef SQLITE_OMIT_DESERIALIZE |
26214 | }else if( cli_strcmp(z,"-deserialize" )==0 ){ |
26215 | data.openMode = SHELL_OPEN_DESERIALIZE; |
26216 | }else if( cli_strcmp(z,"-maxsize" )==0 && i+1<argc ){ |
26217 | data.szMax = integerValue(argv[++i]); |
26218 | #endif |
26219 | }else if( cli_strcmp(z,"-readonly" )==0 ){ |
26220 | data.openMode = SHELL_OPEN_READONLY; |
26221 | }else if( cli_strcmp(z,"-nofollow" )==0 ){ |
26222 | data.openFlags |= SQLITE_OPEN_NOFOLLOW; |
26223 | }else if( cli_strcmp(z,"-ascii" )==0 ){ |
26224 | data.mode = MODE_Ascii; |
26225 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit); |
26226 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record); |
26227 | }else if( cli_strcmp(z,"-tabs" )==0 ){ |
26228 | data.mode = MODE_List; |
26229 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Tab); |
26230 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row); |
26231 | }else if( cli_strcmp(z,"-separator" )==0 ){ |
26232 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, |
26233 | "%s" ,cmdline_option_value(argc,argv,++i)); |
26234 | }else if( cli_strcmp(z,"-newline" )==0 ){ |
26235 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, |
26236 | "%s" ,cmdline_option_value(argc,argv,++i)); |
26237 | }else if( cli_strcmp(z,"-nullvalue" )==0 ){ |
26238 | sqlite3_snprintf(sizeof(data.nullValue), data.nullValue, |
26239 | "%s" ,cmdline_option_value(argc,argv,++i)); |
26240 | }else if( cli_strcmp(z,"-header" )==0 ){ |
26241 | data.showHeader = 1; |
26242 | ShellSetFlag(&data, SHFLG_HeaderSet); |
26243 | }else if( cli_strcmp(z,"-noheader" )==0 ){ |
26244 | data.showHeader = 0; |
26245 | ShellSetFlag(&data, SHFLG_HeaderSet); |
26246 | }else if( cli_strcmp(z,"-echo" )==0 ){ |
26247 | ShellSetFlag(&data, SHFLG_Echo); |
26248 | }else if( cli_strcmp(z,"-eqp" )==0 ){ |
26249 | data.autoEQP = AUTOEQP_on; |
26250 | }else if( cli_strcmp(z,"-eqpfull" )==0 ){ |
26251 | data.autoEQP = AUTOEQP_full; |
26252 | }else if( cli_strcmp(z,"-stats" )==0 ){ |
26253 | data.statsOn = 1; |
26254 | }else if( cli_strcmp(z,"-scanstats" )==0 ){ |
26255 | data.scanstatsOn = 1; |
26256 | }else if( cli_strcmp(z,"-backslash" )==0 ){ |
26257 | /* Undocumented command-line option: -backslash |
26258 | ** Causes C-style backslash escapes to be evaluated in SQL statements |
26259 | ** prior to sending the SQL into SQLite. Useful for injecting |
26260 | ** crazy bytes in the middle of SQL statements for testing and debugging. |
26261 | */ |
26262 | ShellSetFlag(&data, SHFLG_Backslash); |
26263 | }else if( cli_strcmp(z,"-bail" )==0 ){ |
26264 | /* No-op. The bail_on_error flag should already be set. */ |
26265 | }else if( cli_strcmp(z,"-version" )==0 ){ |
26266 | printf("%s %s\n" , sqlite3_libversion(), sqlite3_sourceid()); |
26267 | return 0; |
26268 | }else if( cli_strcmp(z,"-interactive" )==0 ){ |
26269 | stdin_is_interactive = 1; |
26270 | }else if( cli_strcmp(z,"-batch" )==0 ){ |
26271 | stdin_is_interactive = 0; |
26272 | }else if( cli_strcmp(z,"-heap" )==0 ){ |
26273 | i++; |
26274 | }else if( cli_strcmp(z,"-pagecache" )==0 ){ |
26275 | i+=2; |
26276 | }else if( cli_strcmp(z,"-lookaside" )==0 ){ |
26277 | i+=2; |
26278 | }else if( cli_strcmp(z,"-threadsafe" )==0 ){ |
26279 | i+=2; |
26280 | }else if( cli_strcmp(z,"-nonce" )==0 ){ |
26281 | i += 2; |
26282 | }else if( cli_strcmp(z,"-mmap" )==0 ){ |
26283 | i++; |
26284 | }else if( cli_strcmp(z,"-memtrace" )==0 ){ |
26285 | i++; |
26286 | #ifdef SQLITE_ENABLE_SORTER_REFERENCES |
26287 | }else if( cli_strcmp(z,"-sorterref" )==0 ){ |
26288 | i++; |
26289 | #endif |
26290 | }else if( cli_strcmp(z,"-vfs" )==0 ){ |
26291 | i++; |
26292 | #ifdef SQLITE_ENABLE_VFSTRACE |
26293 | }else if( cli_strcmp(z,"-vfstrace" )==0 ){ |
26294 | i++; |
26295 | #endif |
26296 | #ifdef SQLITE_ENABLE_MULTIPLEX |
26297 | }else if( cli_strcmp(z,"-multiplex" )==0 ){ |
26298 | i++; |
26299 | #endif |
26300 | }else if( cli_strcmp(z,"-help" )==0 ){ |
26301 | usage(1); |
26302 | }else if( cli_strcmp(z,"-cmd" )==0 ){ |
26303 | /* Run commands that follow -cmd first and separately from commands |
26304 | ** that simply appear on the command-line. This seems goofy. It would |
26305 | ** be better if all commands ran in the order that they appear. But |
26306 | ** we retain the goofy behavior for historical compatibility. */ |
26307 | if( i==argc-1 ) break; |
26308 | z = cmdline_option_value(argc,argv,++i); |
26309 | if( z[0]=='.' ){ |
26310 | rc = do_meta_command(z, &data); |
26311 | if( rc && bail_on_error ) return rc==2 ? 0 : rc; |
26312 | }else{ |
26313 | open_db(&data, 0); |
26314 | rc = shell_exec(&data, z, &zErrMsg); |
26315 | if( zErrMsg!=0 ){ |
26316 | utf8_printf(stderr,"Error: %s\n" , zErrMsg); |
26317 | if( bail_on_error ) return rc!=0 ? rc : 1; |
26318 | }else if( rc!=0 ){ |
26319 | utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n" , z); |
26320 | if( bail_on_error ) return rc; |
26321 | } |
26322 | } |
26323 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
26324 | }else if( cli_strncmp(z, "-A" , 2)==0 ){ |
26325 | if( nCmd>0 ){ |
26326 | utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands" |
26327 | " with \"%s\"\n" , z); |
26328 | return 1; |
26329 | } |
26330 | open_db(&data, OPEN_DB_ZIPFILE); |
26331 | if( z[2] ){ |
26332 | argv[i] = &z[2]; |
26333 | arDotCommand(&data, 1, argv+(i-1), argc-(i-1)); |
26334 | }else{ |
26335 | arDotCommand(&data, 1, argv+i, argc-i); |
26336 | } |
26337 | readStdin = 0; |
26338 | break; |
26339 | #endif |
26340 | }else if( cli_strcmp(z,"-safe" )==0 ){ |
26341 | data.bSafeMode = data.bSafeModePersist = 1; |
26342 | }else{ |
26343 | utf8_printf(stderr,"%s: Error: unknown option: %s\n" , Argv0, z); |
26344 | raw_printf(stderr,"Use -help for a list of options.\n" ); |
26345 | return 1; |
26346 | } |
26347 | data.cMode = data.mode; |
26348 | } |
26349 | |
26350 | if( !readStdin ){ |
26351 | /* Run all arguments that do not begin with '-' as if they were separate |
26352 | ** command-line inputs, except for the argToSkip argument which contains |
26353 | ** the database filename. |
26354 | */ |
26355 | for(i=0; i<nCmd; i++){ |
26356 | if( azCmd[i][0]=='.' ){ |
26357 | rc = do_meta_command(azCmd[i], &data); |
26358 | if( rc ){ |
26359 | free(azCmd); |
26360 | return rc==2 ? 0 : rc; |
26361 | } |
26362 | }else{ |
26363 | open_db(&data, 0); |
26364 | rc = shell_exec(&data, azCmd[i], &zErrMsg); |
26365 | if( zErrMsg || rc ){ |
26366 | if( zErrMsg!=0 ){ |
26367 | utf8_printf(stderr,"Error: %s\n" , zErrMsg); |
26368 | }else{ |
26369 | utf8_printf(stderr,"Error: unable to process SQL: %s\n" , azCmd[i]); |
26370 | } |
26371 | sqlite3_free(zErrMsg); |
26372 | free(azCmd); |
26373 | return rc!=0 ? rc : 1; |
26374 | } |
26375 | } |
26376 | } |
26377 | }else{ |
26378 | /* Run commands received from standard input |
26379 | */ |
26380 | if( stdin_is_interactive ){ |
26381 | char *zHome; |
26382 | char *zHistory; |
26383 | int nHistory; |
26384 | printf( |
26385 | "SQLite version %s %.19s\n" /*extra-version-info*/ |
26386 | "Enter \".help\" for usage hints.\n" , |
26387 | sqlite3_libversion(), sqlite3_sourceid() |
26388 | ); |
26389 | if( warnInmemoryDb ){ |
26390 | printf("Connected to a " ); |
26391 | printBold("transient in-memory database" ); |
26392 | printf(".\nUse \".open FILENAME\" to reopen on a " |
26393 | "persistent database.\n" ); |
26394 | } |
26395 | zHistory = getenv("SQLITE_HISTORY" ); |
26396 | if( zHistory ){ |
26397 | zHistory = strdup(zHistory); |
26398 | }else if( (zHome = find_home_dir(0))!=0 ){ |
26399 | nHistory = strlen30(zHome) + 20; |
26400 | if( (zHistory = malloc(nHistory))!=0 ){ |
26401 | sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history" , zHome); |
26402 | } |
26403 | } |
26404 | if( zHistory ){ shell_read_history(zHistory); } |
26405 | #if HAVE_READLINE || HAVE_EDITLINE |
26406 | rl_attempted_completion_function = readline_completion; |
26407 | #elif HAVE_LINENOISE |
26408 | linenoiseSetCompletionCallback(linenoise_completion); |
26409 | #endif |
26410 | data.in = 0; |
26411 | rc = process_input(&data); |
26412 | if( zHistory ){ |
26413 | shell_stifle_history(2000); |
26414 | shell_write_history(zHistory); |
26415 | free(zHistory); |
26416 | } |
26417 | }else{ |
26418 | data.in = stdin; |
26419 | rc = process_input(&data); |
26420 | } |
26421 | } |
26422 | #ifndef SQLITE_SHELL_FIDDLE |
26423 | /* In WASM mode we have to leave the db state in place so that |
26424 | ** client code can "push" SQL into it after this call returns. */ |
26425 | free(azCmd); |
26426 | set_table_name(&data, 0); |
26427 | if( data.db ){ |
26428 | session_close_all(&data, -1); |
26429 | close_db(data.db); |
26430 | } |
26431 | for(i=0; i<ArraySize(data.aAuxDb); i++){ |
26432 | sqlite3_free(data.aAuxDb[i].zFreeOnClose); |
26433 | if( data.aAuxDb[i].db ){ |
26434 | session_close_all(&data, i); |
26435 | close_db(data.aAuxDb[i].db); |
26436 | } |
26437 | } |
26438 | find_home_dir(1); |
26439 | output_reset(&data); |
26440 | data.doXdgOpen = 0; |
26441 | clearTempFile(&data); |
26442 | #if !SQLITE_SHELL_IS_UTF8 |
26443 | for(i=0; i<argcToFree; i++) free(argvToFree[i]); |
26444 | free(argvToFree); |
26445 | #endif |
26446 | free(data.colWidth); |
26447 | free(data.zNonce); |
26448 | /* Clear the global data structure so that valgrind will detect memory |
26449 | ** leaks */ |
26450 | memset(&data, 0, sizeof(data)); |
26451 | #ifdef SQLITE_DEBUG |
26452 | if( sqlite3_memory_used()>mem_main_enter ){ |
26453 | utf8_printf(stderr, "Memory leaked: %u bytes\n" , |
26454 | (unsigned int)(sqlite3_memory_used()-mem_main_enter)); |
26455 | } |
26456 | #endif |
26457 | #endif /* !SQLITE_SHELL_FIDDLE */ |
26458 | return rc; |
26459 | } |
26460 | |
26461 | |
26462 | #ifdef SQLITE_SHELL_FIDDLE |
26463 | /* Only for emcc experimentation purposes. */ |
26464 | int fiddle_experiment(int a,int b){ |
26465 | return a + b; |
26466 | } |
26467 | |
26468 | /* |
26469 | ** Returns a pointer to the current DB handle. |
26470 | */ |
26471 | sqlite3 * fiddle_db_handle(){ |
26472 | return globalDb; |
26473 | } |
26474 | |
26475 | /* |
26476 | ** Returns a pointer to the given DB name's VFS. If zDbName is 0 then |
26477 | ** "main" is assumed. Returns 0 if no db with the given name is |
26478 | ** open. |
26479 | */ |
26480 | sqlite3_vfs * fiddle_db_vfs(const char *zDbName){ |
26481 | sqlite3_vfs * pVfs = 0; |
26482 | if(globalDb){ |
26483 | sqlite3_file_control(globalDb, zDbName ? zDbName : "main" , |
26484 | SQLITE_FCNTL_VFS_POINTER, &pVfs); |
26485 | } |
26486 | return pVfs; |
26487 | } |
26488 | |
26489 | /* Only for emcc experimentation purposes. */ |
26490 | sqlite3 * fiddle_db_arg(sqlite3 *arg){ |
26491 | printf("fiddle_db_arg(%p)\n" , (const void*)arg); |
26492 | return arg; |
26493 | } |
26494 | |
26495 | /* |
26496 | ** Intended to be called via a SharedWorker() while a separate |
26497 | ** SharedWorker() (which manages the wasm module) is performing work |
26498 | ** which should be interrupted. Unfortunately, SharedWorker is not |
26499 | ** portable enough to make real use of. |
26500 | */ |
26501 | void fiddle_interrupt(void){ |
26502 | if( globalDb ) sqlite3_interrupt(globalDb); |
26503 | } |
26504 | |
26505 | /* |
26506 | ** Returns the filename of the given db name, assuming "main" if |
26507 | ** zDbName is NULL. Returns NULL if globalDb is not opened. |
26508 | */ |
26509 | const char * fiddle_db_filename(const char * zDbName){ |
26510 | return globalDb |
26511 | ? sqlite3_db_filename(globalDb, zDbName ? zDbName : "main" ) |
26512 | : NULL; |
26513 | } |
26514 | |
26515 | /* |
26516 | ** Completely wipes out the contents of the currently-opened database |
26517 | ** but leaves its storage intact for reuse. |
26518 | */ |
26519 | void fiddle_reset_db(void){ |
26520 | if( globalDb ){ |
26521 | int rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); |
26522 | if( 0==rc ) rc = sqlite3_exec(globalDb, "VACUUM" , 0, 0, 0); |
26523 | sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); |
26524 | } |
26525 | } |
26526 | |
26527 | /* |
26528 | ** Uses the current database's VFS xRead to stream the db file's |
26529 | ** contents out to the given callback. The callback gets a single |
26530 | ** chunk of size n (its 2nd argument) on each call and must return 0 |
26531 | ** on success, non-0 on error. This function returns 0 on success, |
26532 | ** SQLITE_NOTFOUND if no db is open, or propagates any other non-0 |
26533 | ** code from the callback. Note that this is not thread-friendly: it |
26534 | ** expects that it will be the only thread reading the db file and |
26535 | ** takes no measures to ensure that is the case. |
26536 | */ |
26537 | int fiddle_export_db( int (*xCallback)(unsigned const char *zOut, int n) ){ |
26538 | sqlite3_int64 nSize = 0; |
26539 | sqlite3_int64 nPos = 0; |
26540 | sqlite3_file * pFile = 0; |
26541 | unsigned char buf[1024 * 8]; |
26542 | int nBuf = (int)sizeof(buf); |
26543 | int rc = shellState.db |
26544 | ? sqlite3_file_control(shellState.db, "main" , |
26545 | SQLITE_FCNTL_FILE_POINTER, &pFile) |
26546 | : SQLITE_NOTFOUND; |
26547 | if( rc ) return rc; |
26548 | rc = pFile->pMethods->xFileSize(pFile, &nSize); |
26549 | if( rc ) return rc; |
26550 | if(nSize % nBuf){ |
26551 | /* DB size is not an even multiple of the buffer size. Reduce |
26552 | ** buffer size so that we do not unduly inflate the db size when |
26553 | ** exporting. */ |
26554 | if(0 == nSize % 4096) nBuf = 4096; |
26555 | else if(0 == nSize % 2048) nBuf = 2048; |
26556 | else if(0 == nSize % 1024) nBuf = 1024; |
26557 | else nBuf = 512; |
26558 | } |
26559 | for( ; 0==rc && nPos<nSize; nPos += nBuf ){ |
26560 | rc = pFile->pMethods->xRead(pFile, buf, nBuf, nPos); |
26561 | if(SQLITE_IOERR_SHORT_READ == rc){ |
26562 | rc = (nPos + nBuf) < nSize ? rc : 0/*assume EOF*/; |
26563 | } |
26564 | if( 0==rc ) rc = xCallback(buf, nBuf); |
26565 | } |
26566 | return rc; |
26567 | } |
26568 | |
26569 | /* |
26570 | ** Trivial exportable function for emscripten. It processes zSql as if |
26571 | ** it were input to the sqlite3 shell and redirects all output to the |
26572 | ** wasm binding. fiddle_main() must have been called before this |
26573 | ** is called, or results are undefined. |
26574 | */ |
26575 | void fiddle_exec(const char * zSql){ |
26576 | if(zSql && *zSql){ |
26577 | if('.'==*zSql) puts(zSql); |
26578 | shellState.wasm.zInput = zSql; |
26579 | shellState.wasm.zPos = zSql; |
26580 | process_input(&shellState); |
26581 | shellState.wasm.zInput = shellState.wasm.zPos = 0; |
26582 | } |
26583 | } |
26584 | #endif /* SQLITE_SHELL_FIDDLE */ |
26585 | |