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 | |
38 | /* |
39 | ** Warning pragmas copied from msvc.h in the core. |
40 | */ |
41 | #if defined(_MSC_VER) |
42 | #pragma warning(disable : 4054) |
43 | #pragma warning(disable : 4055) |
44 | #pragma warning(disable : 4100) |
45 | #pragma warning(disable : 4127) |
46 | #pragma warning(disable : 4130) |
47 | #pragma warning(disable : 4152) |
48 | #pragma warning(disable : 4189) |
49 | #pragma warning(disable : 4206) |
50 | #pragma warning(disable : 4210) |
51 | #pragma warning(disable : 4232) |
52 | #pragma warning(disable : 4244) |
53 | #pragma warning(disable : 4305) |
54 | #pragma warning(disable : 4306) |
55 | #pragma warning(disable : 4702) |
56 | #pragma warning(disable : 4706) |
57 | #endif /* defined(_MSC_VER) */ |
58 | |
59 | /* |
60 | ** No support for loadable extensions in VxWorks. |
61 | */ |
62 | #if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION |
63 | #define SQLITE_OMIT_LOAD_EXTENSION 1 |
64 | #endif |
65 | |
66 | /* |
67 | ** Enable large-file support for fopen() and friends on unix. |
68 | */ |
69 | #ifndef SQLITE_DISABLE_LFS |
70 | #define _LARGE_FILE 1 |
71 | #ifndef _FILE_OFFSET_BITS |
72 | #define _FILE_OFFSET_BITS 64 |
73 | #endif |
74 | #define _LARGEFILE_SOURCE 1 |
75 | #endif |
76 | |
77 | #include <stdlib.h> |
78 | #include <string.h> |
79 | #include <stdio.h> |
80 | #include <assert.h> |
81 | #include "sqlite3.h" |
82 | typedef sqlite3_int64 i64; |
83 | typedef sqlite3_uint64 u64; |
84 | typedef unsigned char u8; |
85 | #if SQLITE_USER_AUTHENTICATION |
86 | #include "sqlite3userauth.h" |
87 | #endif |
88 | #include <ctype.h> |
89 | #include <stdarg.h> |
90 | |
91 | #if !defined(_WIN32) && !defined(WIN32) |
92 | #include <signal.h> |
93 | #if !defined(__RTP__) && !defined(_WRS_KERNEL) |
94 | #include <pwd.h> |
95 | #endif |
96 | #endif |
97 | #if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__) |
98 | #include <unistd.h> |
99 | #include <dirent.h> |
100 | #if defined(__MINGW32__) |
101 | #define DIRENT dirent |
102 | #ifndef S_ISLNK |
103 | #define S_ISLNK(mode) (0) |
104 | #endif |
105 | #endif |
106 | #endif |
107 | #include <sys/types.h> |
108 | #include <sys/stat.h> |
109 | |
110 | #if HAVE_READLINE |
111 | #include <readline/readline.h> |
112 | #include <readline/history.h> |
113 | #endif |
114 | |
115 | #if HAVE_EDITLINE |
116 | #include <editline/readline.h> |
117 | #endif |
118 | |
119 | #if HAVE_EDITLINE || HAVE_READLINE |
120 | |
121 | #define shell_add_history(X) add_history(X) |
122 | #define shell_read_history(X) read_history(X) |
123 | #define shell_write_history(X) write_history(X) |
124 | #define shell_stifle_history(X) stifle_history(X) |
125 | #define shell_readline(X) readline(X) |
126 | |
127 | #elif HAVE_LINENOISE |
128 | |
129 | #include "linenoise.h" |
130 | #define shell_add_history(X) linenoiseHistoryAdd(X) |
131 | #define shell_read_history(X) linenoiseHistoryLoad(X) |
132 | #define shell_write_history(X) linenoiseHistorySave(X) |
133 | #define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) |
134 | #define shell_readline(X) linenoise(X) |
135 | |
136 | #else |
137 | |
138 | #define shell_read_history(X) |
139 | #define shell_write_history(X) |
140 | #define shell_stifle_history(X) |
141 | |
142 | #define SHELL_USE_LOCAL_GETLINE 1 |
143 | #endif |
144 | |
145 | #if defined(_WIN32) || defined(WIN32) |
146 | #include <io.h> |
147 | #include <fcntl.h> |
148 | #define isatty(h) _isatty(h) |
149 | #ifndef access |
150 | #define access(f, m) _access((f), (m)) |
151 | #endif |
152 | #ifndef unlink |
153 | #define unlink _unlink |
154 | #endif |
155 | #undef popen |
156 | #define popen _popen |
157 | #undef pclose |
158 | #define pclose _pclose |
159 | #else |
160 | /* Make sure isatty() has a prototype. */ |
161 | extern int isatty(int); |
162 | |
163 | #if !defined(__RTP__) && !defined(_WRS_KERNEL) |
164 | /* popen and pclose are not C89 functions and so are |
165 | ** sometimes omitted from the <stdio.h> header */ |
166 | extern FILE *popen(const char *, const char *); |
167 | extern int pclose(FILE *); |
168 | #else |
169 | #define SQLITE_OMIT_POPEN 1 |
170 | #endif |
171 | #endif |
172 | |
173 | #if defined(_WIN32_WCE) |
174 | /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() |
175 | * thus we always assume that we have a console. That can be |
176 | * overridden with the -batch command line option. |
177 | */ |
178 | #define isatty(x) 1 |
179 | #endif |
180 | |
181 | /* ctype macros that work with signed characters */ |
182 | #define IsSpace(X) isspace((unsigned char)X) |
183 | #define IsDigit(X) isdigit((unsigned char)X) |
184 | #define ToLower(X) (char)tolower((unsigned char)X) |
185 | |
186 | #if defined(_WIN32) || defined(WIN32) |
187 | #include <windows.h> |
188 | |
189 | /* string conversion routines only needed on Win32 */ |
190 | extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); |
191 | extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); |
192 | extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); |
193 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); |
194 | #endif |
195 | |
196 | /* On Windows, we normally run with output mode of TEXT so that \n characters |
197 | ** are automatically translated into \r\n. However, this behavior needs |
198 | ** to be disabled in some cases (ex: when generating CSV output and when |
199 | ** rendering quoted strings that contain \n characters). The following |
200 | ** routines take care of that. |
201 | */ |
202 | #if defined(_WIN32) || defined(WIN32) |
203 | static void setBinaryMode(FILE *file, int isOutput) { |
204 | if (isOutput) |
205 | fflush(file); |
206 | _setmode(_fileno(file), _O_BINARY); |
207 | } |
208 | static void setTextMode(FILE *file, int isOutput) { |
209 | if (isOutput) |
210 | fflush(file); |
211 | _setmode(_fileno(file), _O_TEXT); |
212 | } |
213 | #else |
214 | #define setBinaryMode(X, Y) |
215 | #define setTextMode(X, Y) |
216 | #endif |
217 | |
218 | /* True if the timer is enabled */ |
219 | static int enableTimer = 0; |
220 | |
221 | /* Return the current wall-clock time */ |
222 | static sqlite3_int64 timeOfDay(void) { |
223 | static sqlite3_vfs *clockVfs = 0; |
224 | sqlite3_int64 t; |
225 | if (clockVfs == 0) |
226 | clockVfs = sqlite3_vfs_find(0); |
227 | if (clockVfs->iVersion >= 2 && clockVfs->xCurrentTimeInt64 != 0) { |
228 | clockVfs->xCurrentTimeInt64(clockVfs, &t); |
229 | } else { |
230 | double r; |
231 | clockVfs->xCurrentTime(clockVfs, &r); |
232 | t = (sqlite3_int64)(r * 86400000.0); |
233 | } |
234 | return t; |
235 | } |
236 | |
237 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) |
238 | #include <sys/time.h> |
239 | #include <sys/resource.h> |
240 | |
241 | /* VxWorks does not support getrusage() as far as we can determine */ |
242 | #if defined(_WRS_KERNEL) || defined(__RTP__) |
243 | struct rusage { |
244 | struct timeval ru_utime; /* user CPU time used */ |
245 | struct timeval ru_stime; /* system CPU time used */ |
246 | }; |
247 | #define getrusage(A, B) memset(B, 0, sizeof(*B)) |
248 | #endif |
249 | |
250 | /* Saved resource information for the beginning of an operation */ |
251 | static struct rusage sBegin; /* CPU time at start */ |
252 | static sqlite3_int64 iBegin; /* Wall-clock time at start */ |
253 | |
254 | /* |
255 | ** Begin timing an operation |
256 | */ |
257 | static void beginTimer(void) { |
258 | if (enableTimer) { |
259 | getrusage(RUSAGE_SELF, &sBegin); |
260 | iBegin = timeOfDay(); |
261 | } |
262 | } |
263 | |
264 | /* Return the difference of two time_structs in seconds */ |
265 | static double timeDiff(struct timeval *pStart, struct timeval *pEnd) { |
266 | return (pEnd->tv_usec - pStart->tv_usec) * 0.000001 + (double)(pEnd->tv_sec - pStart->tv_sec); |
267 | } |
268 | |
269 | /* |
270 | ** Print the timing results. |
271 | */ |
272 | static void endTimer(void) { |
273 | if (enableTimer) { |
274 | sqlite3_int64 iEnd = timeOfDay(); |
275 | struct rusage sEnd; |
276 | getrusage(RUSAGE_SELF, &sEnd); |
277 | printf("Run Time: real %.3f user %f sys %f\n" , (iEnd - iBegin) * 0.001, |
278 | timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); |
279 | } |
280 | } |
281 | |
282 | #define BEGIN_TIMER beginTimer() |
283 | #define END_TIMER endTimer() |
284 | #define HAS_TIMER 1 |
285 | |
286 | #elif (defined(_WIN32) || defined(WIN32)) |
287 | |
288 | /* Saved resource information for the beginning of an operation */ |
289 | static HANDLE hProcess; |
290 | static FILETIME ftKernelBegin; |
291 | static FILETIME ftUserBegin; |
292 | static sqlite3_int64 ftWallBegin; |
293 | typedef BOOL(WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); |
294 | static GETPROCTIMES getProcessTimesAddr = NULL; |
295 | |
296 | /* |
297 | ** Check to see if we have timer support. Return 1 if necessary |
298 | ** support found (or found previously). |
299 | */ |
300 | static int hasTimer(void) { |
301 | if (getProcessTimesAddr) { |
302 | return 1; |
303 | } else { |
304 | /* GetProcessTimes() isn't supported in WIN95 and some other Windows |
305 | ** versions. See if the version we are running on has it, and if it |
306 | ** does, save off a pointer to it and the current process handle. |
307 | */ |
308 | hProcess = GetCurrentProcess(); |
309 | if (hProcess) { |
310 | HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll" )); |
311 | if (NULL != hinstLib) { |
312 | getProcessTimesAddr = (GETPROCTIMES)GetProcAddress(hinstLib, "GetProcessTimes" ); |
313 | if (NULL != getProcessTimesAddr) { |
314 | return 1; |
315 | } |
316 | FreeLibrary(hinstLib); |
317 | } |
318 | } |
319 | } |
320 | return 0; |
321 | } |
322 | |
323 | /* |
324 | ** Begin timing an operation |
325 | */ |
326 | static void beginTimer(void) { |
327 | if (enableTimer && getProcessTimesAddr) { |
328 | FILETIME ftCreation, ftExit; |
329 | getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin); |
330 | ftWallBegin = timeOfDay(); |
331 | } |
332 | } |
333 | |
334 | /* Return the difference of two FILETIME structs in seconds */ |
335 | static double timeDiff(FILETIME *pStart, FILETIME *pEnd) { |
336 | sqlite_int64 i64Start = *((sqlite_int64 *)pStart); |
337 | sqlite_int64 i64End = *((sqlite_int64 *)pEnd); |
338 | return (double)((i64End - i64Start) / 10000000.0); |
339 | } |
340 | |
341 | /* |
342 | ** Print the timing results. |
343 | */ |
344 | static void endTimer(void) { |
345 | if (enableTimer && getProcessTimesAddr) { |
346 | FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; |
347 | sqlite3_int64 ftWallEnd = timeOfDay(); |
348 | getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd); |
349 | printf("Run Time: real %.3f user %f sys %f\n" , (ftWallEnd - ftWallBegin) * 0.001, |
350 | timeDiff(&ftUserBegin, &ftUserEnd), timeDiff(&ftKernelBegin, &ftKernelEnd)); |
351 | } |
352 | } |
353 | |
354 | #define BEGIN_TIMER beginTimer() |
355 | #define END_TIMER endTimer() |
356 | #define HAS_TIMER hasTimer() |
357 | |
358 | #else |
359 | #define BEGIN_TIMER |
360 | #define END_TIMER |
361 | #define HAS_TIMER 0 |
362 | #endif |
363 | |
364 | /* |
365 | ** Used to prevent warnings about unused parameters |
366 | */ |
367 | #define UNUSED_PARAMETER(x) (void)(x) |
368 | |
369 | /* |
370 | ** Number of elements in an array |
371 | */ |
372 | #define ArraySize(X) (int)(sizeof(X) / sizeof(X[0])) |
373 | |
374 | /* |
375 | ** If the following flag is set, then command execution stops |
376 | ** at an error if we are not interactive. |
377 | */ |
378 | static int bail_on_error = 0; |
379 | |
380 | /* |
381 | ** Threat stdin as an interactive input if the following variable |
382 | ** is true. Otherwise, assume stdin is connected to a file or pipe. |
383 | */ |
384 | static int stdin_is_interactive = 1; |
385 | |
386 | /* |
387 | ** On Windows systems we have to know if standard output is a console |
388 | ** in order to translate UTF-8 into MBCS. The following variable is |
389 | ** true if translation is required. |
390 | */ |
391 | static int stdout_is_console = 1; |
392 | |
393 | /* |
394 | ** The following is the open SQLite database. We make a pointer |
395 | ** to this database a static variable so that it can be accessed |
396 | ** by the SIGINT handler to interrupt database processing. |
397 | */ |
398 | static sqlite3 *globalDb = 0; |
399 | |
400 | /* |
401 | ** True if an interrupt (Control-C) has been received. |
402 | */ |
403 | static volatile int seenInterrupt = 0; |
404 | |
405 | /* |
406 | ** This is the name of our program. It is set in main(), used |
407 | ** in a number of other places, mostly for error messages. |
408 | */ |
409 | static char *Argv0; |
410 | |
411 | /* |
412 | ** Prompt strings. Initialized in main. Settable with |
413 | ** .prompt main continue |
414 | */ |
415 | static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ |
416 | static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ |
417 | |
418 | /* |
419 | ** Render output like fprintf(). Except, if the output is going to the |
420 | ** console and if this is running on a Windows machine, translate the |
421 | ** output from UTF-8 into MBCS. |
422 | */ |
423 | #if defined(_WIN32) || defined(WIN32) |
424 | void utf8_printf(FILE *out, const char *zFormat, ...) { |
425 | va_list ap; |
426 | va_start(ap, zFormat); |
427 | if (stdout_is_console && (out == stdout || out == stderr)) { |
428 | char *z1 = sqlite3_vmprintf(zFormat, ap); |
429 | char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); |
430 | sqlite3_free(z1); |
431 | fputs(z2, out); |
432 | sqlite3_free(z2); |
433 | } else { |
434 | vfprintf(out, zFormat, ap); |
435 | } |
436 | va_end(ap); |
437 | } |
438 | #elif !defined(utf8_printf) |
439 | #define utf8_printf fprintf |
440 | #endif |
441 | |
442 | /* |
443 | ** Render output like fprintf(). This should not be used on anything that |
444 | ** includes string formatting (e.g. "%s"). |
445 | */ |
446 | #if !defined(raw_printf) |
447 | #define raw_printf fprintf |
448 | #endif |
449 | |
450 | /* |
451 | ** Write I/O traces to the following stream. |
452 | */ |
453 | #ifdef SQLITE_ENABLE_IOTRACE |
454 | static FILE *iotrace = 0; |
455 | #endif |
456 | |
457 | /* |
458 | ** This routine works like printf in that its first argument is a |
459 | ** format string and subsequent arguments are values to be substituted |
460 | ** in place of % fields. The result of formatting this string |
461 | ** is written to iotrace. |
462 | */ |
463 | #ifdef SQLITE_ENABLE_IOTRACE |
464 | static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...) { |
465 | va_list ap; |
466 | char *z; |
467 | if (iotrace == 0) |
468 | return; |
469 | va_start(ap, zFormat); |
470 | z = sqlite3_vmprintf(zFormat, ap); |
471 | va_end(ap); |
472 | utf8_printf(iotrace, "%s" , z); |
473 | sqlite3_free(z); |
474 | } |
475 | #endif |
476 | |
477 | /* |
478 | ** Output string zUtf to stream pOut as w characters. If w is negative, |
479 | ** then right-justify the text. W is the width in UTF-8 characters, not |
480 | ** in bytes. This is different from the %*.*s specification in printf |
481 | ** since with %*.*s the width is measured in bytes, not characters. |
482 | */ |
483 | static void utf8_width_print(FILE *pOut, int w, const char *zUtf) { |
484 | int i; |
485 | int n; |
486 | int aw = w < 0 ? -w : w; |
487 | char zBuf[1000]; |
488 | if (aw > (int)sizeof(zBuf) / 3) |
489 | aw = (int)sizeof(zBuf) / 3; |
490 | for (i = n = 0; zUtf[i]; i++) { |
491 | if ((zUtf[i] & 0xc0) != 0x80) { |
492 | n++; |
493 | if (n == aw) { |
494 | do { |
495 | i++; |
496 | } while ((zUtf[i] & 0xc0) == 0x80); |
497 | break; |
498 | } |
499 | } |
500 | } |
501 | if (n >= aw) { |
502 | utf8_printf(pOut, "%.*s" , i, zUtf); |
503 | } else if (w < 0) { |
504 | utf8_printf(pOut, "%*s%s" , aw - n, "" , zUtf); |
505 | } else { |
506 | utf8_printf(pOut, "%s%*s" , zUtf, aw - n, "" ); |
507 | } |
508 | } |
509 | |
510 | /* |
511 | ** Determines if a string is a number of not. |
512 | */ |
513 | static int isNumber(const char *z, int *realnum) { |
514 | if (*z == '-' || *z == '+') |
515 | z++; |
516 | if (!IsDigit(*z)) { |
517 | return 0; |
518 | } |
519 | z++; |
520 | if (realnum) |
521 | *realnum = 0; |
522 | while (IsDigit(*z)) { |
523 | z++; |
524 | } |
525 | if (*z == '.') { |
526 | z++; |
527 | if (!IsDigit(*z)) |
528 | return 0; |
529 | while (IsDigit(*z)) { |
530 | z++; |
531 | } |
532 | if (realnum) |
533 | *realnum = 1; |
534 | } |
535 | if (*z == 'e' || *z == 'E') { |
536 | z++; |
537 | if (*z == '+' || *z == '-') |
538 | z++; |
539 | if (!IsDigit(*z)) |
540 | return 0; |
541 | while (IsDigit(*z)) { |
542 | z++; |
543 | } |
544 | if (realnum) |
545 | *realnum = 1; |
546 | } |
547 | return *z == 0; |
548 | } |
549 | |
550 | /* |
551 | ** Compute a string length that is limited to what can be stored in |
552 | ** lower 30 bits of a 32-bit signed integer. |
553 | */ |
554 | static int strlen30(const char *z) { |
555 | const char *z2 = z; |
556 | while (*z2) { |
557 | z2++; |
558 | } |
559 | return 0x3fffffff & (int)(z2 - z); |
560 | } |
561 | |
562 | /* |
563 | ** Return the length of a string in characters. Multibyte UTF8 characters |
564 | ** count as a single character. |
565 | */ |
566 | static int strlenChar(const char *z) { |
567 | int n = 0; |
568 | while (*z) { |
569 | if ((0xc0 & *(z++)) != 0x80) |
570 | n++; |
571 | } |
572 | return n; |
573 | } |
574 | |
575 | /* |
576 | ** This routine reads a line of text from FILE in, stores |
577 | ** the text in memory obtained from malloc() and returns a pointer |
578 | ** to the text. NULL is returned at end of file, or if malloc() |
579 | ** fails. |
580 | ** |
581 | ** If zLine is not NULL then it is a malloced buffer returned from |
582 | ** a previous call to this routine that may be reused. |
583 | */ |
584 | static char *local_getline(char *zLine, FILE *in) { |
585 | int nLine = zLine == 0 ? 0 : 100; |
586 | int n = 0; |
587 | |
588 | while (1) { |
589 | if (n + 100 > nLine) { |
590 | nLine = nLine * 2 + 100; |
591 | zLine = realloc(zLine, nLine); |
592 | if (zLine == 0) |
593 | return 0; |
594 | } |
595 | if (fgets(&zLine[n], nLine - n, in) == 0) { |
596 | if (n == 0) { |
597 | free(zLine); |
598 | return 0; |
599 | } |
600 | zLine[n] = 0; |
601 | break; |
602 | } |
603 | while (zLine[n]) |
604 | n++; |
605 | if (n > 0 && zLine[n - 1] == '\n') { |
606 | n--; |
607 | if (n > 0 && zLine[n - 1] == '\r') |
608 | n--; |
609 | zLine[n] = 0; |
610 | break; |
611 | } |
612 | } |
613 | #if defined(_WIN32) || defined(WIN32) |
614 | /* For interactive input on Windows systems, translate the |
615 | ** multi-byte characterset characters into UTF-8. */ |
616 | if (stdin_is_interactive && in == stdin) { |
617 | char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); |
618 | if (zTrans) { |
619 | int nTrans = strlen30(zTrans) + 1; |
620 | if (nTrans > nLine) { |
621 | zLine = realloc(zLine, nTrans); |
622 | if (zLine == 0) { |
623 | sqlite3_free(zTrans); |
624 | return 0; |
625 | } |
626 | } |
627 | memcpy(zLine, zTrans, nTrans); |
628 | sqlite3_free(zTrans); |
629 | } |
630 | } |
631 | #endif /* defined(_WIN32) || defined(WIN32) */ |
632 | return zLine; |
633 | } |
634 | |
635 | /* |
636 | ** Retrieve a single line of input text. |
637 | ** |
638 | ** If in==0 then read from standard input and prompt before each line. |
639 | ** If isContinuation is true, then a continuation prompt is appropriate. |
640 | ** If isContinuation is zero, then the main prompt should be used. |
641 | ** |
642 | ** If zPrior is not NULL then it is a buffer from a prior call to this |
643 | ** routine that can be reused. |
644 | ** |
645 | ** The result is stored in space obtained from malloc() and must either |
646 | ** be freed by the caller or else passed back into this routine via the |
647 | ** zPrior argument for reuse. |
648 | */ |
649 | static char *one_input_line(FILE *in, char *zPrior, int isContinuation) { |
650 | char *zPrompt; |
651 | char *zResult; |
652 | if (in != 0) { |
653 | zResult = local_getline(zPrior, in); |
654 | } else { |
655 | zPrompt = isContinuation ? continuePrompt : mainPrompt; |
656 | #if SHELL_USE_LOCAL_GETLINE |
657 | printf("%s" , zPrompt); |
658 | fflush(stdout); |
659 | zResult = local_getline(zPrior, stdin); |
660 | #else |
661 | free(zPrior); |
662 | zResult = shell_readline(zPrompt); |
663 | if (zResult && *zResult) |
664 | shell_add_history(zResult); |
665 | #endif |
666 | } |
667 | return zResult; |
668 | } |
669 | |
670 | /* |
671 | ** Return the value of a hexadecimal digit. Return -1 if the input |
672 | ** is not a hex digit. |
673 | */ |
674 | static int hexDigitValue(char c) { |
675 | if (c >= '0' && c <= '9') |
676 | return c - '0'; |
677 | if (c >= 'a' && c <= 'f') |
678 | return c - 'a' + 10; |
679 | if (c >= 'A' && c <= 'F') |
680 | return c - 'A' + 10; |
681 | return -1; |
682 | } |
683 | |
684 | /* |
685 | ** Interpret zArg as an integer value, possibly with suffixes. |
686 | */ |
687 | static sqlite3_int64 integerValue(const char *zArg) { |
688 | sqlite3_int64 v = 0; |
689 | static const struct { |
690 | char *zSuffix; |
691 | int iMult; |
692 | } aMult[] = { |
693 | {"KiB" , 1024}, {"MiB" , 1024 * 1024}, {"GiB" , 1024 * 1024 * 1024}, |
694 | {"KB" , 1000}, {"MB" , 1000000}, {"GB" , 1000000000}, |
695 | {"K" , 1000}, {"M" , 1000000}, {"G" , 1000000000}, |
696 | }; |
697 | int i; |
698 | int isNeg = 0; |
699 | if (zArg[0] == '-') { |
700 | isNeg = 1; |
701 | zArg++; |
702 | } else if (zArg[0] == '+') { |
703 | zArg++; |
704 | } |
705 | if (zArg[0] == '0' && zArg[1] == 'x') { |
706 | int x; |
707 | zArg += 2; |
708 | while ((x = hexDigitValue(zArg[0])) >= 0) { |
709 | v = (v << 4) + x; |
710 | zArg++; |
711 | } |
712 | } else { |
713 | while (IsDigit(zArg[0])) { |
714 | v = v * 10 + zArg[0] - '0'; |
715 | zArg++; |
716 | } |
717 | } |
718 | for (i = 0; i < ArraySize(aMult); i++) { |
719 | if (sqlite3_stricmp(aMult[i].zSuffix, zArg) == 0) { |
720 | v *= aMult[i].iMult; |
721 | break; |
722 | } |
723 | } |
724 | return isNeg ? -v : v; |
725 | } |
726 | |
727 | /* |
728 | ** A variable length string to which one can append text. |
729 | */ |
730 | typedef struct ShellText ShellText; |
731 | struct ShellText { |
732 | char *z; |
733 | int n; |
734 | int nAlloc; |
735 | }; |
736 | |
737 | /* |
738 | ** Initialize and destroy a ShellText object |
739 | */ |
740 | static void initText(ShellText *p) { |
741 | memset(p, 0, sizeof(*p)); |
742 | } |
743 | static void freeText(ShellText *p) { |
744 | free(p->z); |
745 | initText(p); |
746 | } |
747 | |
748 | /* zIn is either a pointer to a NULL-terminated string in memory obtained |
749 | ** from malloc(), or a NULL pointer. The string pointed to by zAppend is |
750 | ** added to zIn, and the result returned in memory obtained from malloc(). |
751 | ** zIn, if it was not NULL, is freed. |
752 | ** |
753 | ** If the third argument, quote, is not '\0', then it is used as a |
754 | ** quote character for zAppend. |
755 | */ |
756 | static void appendText(ShellText *p, char const *zAppend, char quote) { |
757 | int len; |
758 | int i; |
759 | int nAppend = strlen30(zAppend); |
760 | |
761 | len = nAppend + p->n + 1; |
762 | if (quote) { |
763 | len += 2; |
764 | for (i = 0; i < nAppend; i++) { |
765 | if (zAppend[i] == quote) |
766 | len++; |
767 | } |
768 | } |
769 | |
770 | if (p->n + len >= p->nAlloc) { |
771 | p->nAlloc = p->nAlloc * 2 + len + 20; |
772 | p->z = realloc(p->z, p->nAlloc); |
773 | if (p->z == 0) { |
774 | memset(p, 0, sizeof(*p)); |
775 | return; |
776 | } |
777 | } |
778 | |
779 | if (quote) { |
780 | char *zCsr = p->z + p->n; |
781 | *zCsr++ = quote; |
782 | for (i = 0; i < nAppend; i++) { |
783 | *zCsr++ = zAppend[i]; |
784 | if (zAppend[i] == quote) |
785 | *zCsr++ = quote; |
786 | } |
787 | *zCsr++ = quote; |
788 | p->n = (int)(zCsr - p->z); |
789 | *zCsr = '\0'; |
790 | } else { |
791 | memcpy(p->z + p->n, zAppend, nAppend); |
792 | p->n += nAppend; |
793 | p->z[p->n] = '\0'; |
794 | } |
795 | } |
796 | |
797 | /* |
798 | ** Attempt to determine if identifier zName needs to be quoted, either |
799 | ** because it contains non-alphanumeric characters, or because it is an |
800 | ** SQLite keyword. Be conservative in this estimate: When in doubt assume |
801 | ** that quoting is required. |
802 | ** |
803 | ** Return '"' if quoting is required. Return 0 if no quoting is required. |
804 | */ |
805 | static char quoteChar(const char *zName) { |
806 | /* All SQLite keywords, in alphabetical order */ |
807 | static const char *azKeywords[] = { |
808 | "ABORT" , "ACTION" , "ADD" , "AFTER" , "ALL" , "ALTER" , |
809 | "ANALYZE" , "AND" , "AS" , "ASC" , "ATTACH" , "AUTOINCREMENT" , |
810 | "BEFORE" , "BEGIN" , "BETWEEN" , "BY" , "CASCADE" , "CASE" , |
811 | "CAST" , "CHECK" , "COLLATE" , "COLUMN" , "COMMIT" , "CONFLICT" , |
812 | "CONSTRAINT" , "CREATE" , "CROSS" , "CURRENT_DATE" , "CURRENT_TIME" , "CURRENT_TIMESTAMP" , |
813 | "DATABASE" , "DEFAULT" , "DEFERRABLE" , "DEFERRED" , "DELETE" , "DESC" , |
814 | "DETACH" , "DISTINCT" , "DROP" , "EACH" , "ELSE" , "END" , |
815 | "ESCAPE" , "EXCEPT" , "EXCLUSIVE" , "EXISTS" , "EXPLAIN" , "FAIL" , |
816 | "FOR" , "FOREIGN" , "FROM" , "FULL" , "GLOB" , "GROUP" , |
817 | "HAVING" , "IF" , "IGNORE" , "IMMEDIATE" , "IN" , "INDEX" , |
818 | "INDEXED" , "INITIALLY" , "INNER" , "INSERT" , "INSTEAD" , "INTERSECT" , |
819 | "INTO" , "IS" , "ISNULL" , "JOIN" , "KEY" , "LEFT" , |
820 | "LIKE" , "LIMIT" , "MATCH" , "NATURAL" , "NO" , "NOT" , |
821 | "NOTNULL" , "NULL" , "OF" , "OFFSET" , "ON" , "OR" , |
822 | "ORDER" , "OUTER" , "PLAN" , "PRAGMA" , "PRIMARY" , "QUERY" , |
823 | "RAISE" , "RECURSIVE" , "REFERENCES" , "REGEXP" , "REINDEX" , "RELEASE" , |
824 | "RENAME" , "REPLACE" , "RESTRICT" , "RIGHT" , "ROLLBACK" , "ROW" , |
825 | "SAVEPOINT" , "SELECT" , "SET" , "TABLE" , "TEMP" , "TEMPORARY" , |
826 | "THEN" , "TO" , "TRANSACTION" , "TRIGGER" , "UNION" , "UNIQUE" , |
827 | "UPDATE" , "USING" , "VACUUM" , "VALUES" , "VIEW" , "VIRTUAL" , |
828 | "WHEN" , "WHERE" , "WITH" , "WITHOUT" , |
829 | }; |
830 | int i, lwr, upr, mid, c; |
831 | if (!isalpha((unsigned char)zName[0]) && zName[0] != '_') |
832 | return '"'; |
833 | for (i = 0; zName[i]; i++) { |
834 | if (!isalnum((unsigned char)zName[i]) && zName[i] != '_') |
835 | return '"'; |
836 | } |
837 | lwr = 0; |
838 | upr = sizeof(azKeywords) / sizeof(azKeywords[0]) - 1; |
839 | while (lwr <= upr) { |
840 | mid = (lwr + upr) / 2; |
841 | c = sqlite3_stricmp(azKeywords[mid], zName); |
842 | if (c == 0) |
843 | return '"'; |
844 | if (c < 0) { |
845 | lwr = mid + 1; |
846 | } else { |
847 | upr = mid - 1; |
848 | } |
849 | } |
850 | return 0; |
851 | } |
852 | |
853 | /* |
854 | ** Construct a fake object name and column list to describe the structure |
855 | ** of the view, virtual table, or table valued function zSchema.zName. |
856 | */ |
857 | static char *shellFakeSchema(sqlite3 *db, /* The database connection containing the vtab */ |
858 | const char *zSchema, /* Schema of the database holding the vtab */ |
859 | const char *zName /* The name of the virtual table */ |
860 | ) { |
861 | sqlite3_stmt *pStmt = 0; |
862 | char *zSql; |
863 | ShellText s; |
864 | char cQuote; |
865 | char *zDiv = "(" ; |
866 | int nRow = 0; |
867 | |
868 | zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;" , zSchema ? zSchema : "main" , zName); |
869 | sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
870 | sqlite3_free(zSql); |
871 | initText(&s); |
872 | if (zSchema) { |
873 | cQuote = quoteChar(zSchema); |
874 | if (cQuote && sqlite3_stricmp(zSchema, "temp" ) == 0) |
875 | cQuote = 0; |
876 | appendText(&s, zSchema, cQuote); |
877 | appendText(&s, "." , 0); |
878 | } |
879 | cQuote = quoteChar(zName); |
880 | appendText(&s, zName, cQuote); |
881 | while (sqlite3_step(pStmt) == SQLITE_ROW) { |
882 | const char *zCol = (const char *)sqlite3_column_text(pStmt, 1); |
883 | nRow++; |
884 | appendText(&s, zDiv, 0); |
885 | zDiv = "," ; |
886 | cQuote = quoteChar(zCol); |
887 | appendText(&s, zCol, cQuote); |
888 | } |
889 | appendText(&s, ")" , 0); |
890 | sqlite3_finalize(pStmt); |
891 | if (nRow == 0) { |
892 | freeText(&s); |
893 | s.z = 0; |
894 | } |
895 | return s.z; |
896 | } |
897 | |
898 | /* |
899 | ** SQL function: shell_module_schema(X) |
900 | ** |
901 | ** Return a fake schema for the table-valued function or eponymous virtual |
902 | ** table X. |
903 | */ |
904 | static void shellModuleSchema(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal) { |
905 | const char *zName = (const char *)sqlite3_value_text(apVal[0]); |
906 | char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName); |
907 | UNUSED_PARAMETER(nVal); |
908 | if (zFake) { |
909 | sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */" , zFake), -1, sqlite3_free); |
910 | free(zFake); |
911 | } |
912 | } |
913 | |
914 | /* |
915 | ** SQL function: shell_add_schema(S,X) |
916 | ** |
917 | ** Add the schema name X to the CREATE statement in S and return the result. |
918 | ** Examples: |
919 | ** |
920 | ** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x); |
921 | ** |
922 | ** Also works on |
923 | ** |
924 | ** CREATE INDEX |
925 | ** CREATE UNIQUE INDEX |
926 | ** CREATE VIEW |
927 | ** CREATE TRIGGER |
928 | ** CREATE VIRTUAL TABLE |
929 | ** |
930 | ** This UDF is used by the .schema command to insert the schema name of |
931 | ** attached databases into the middle of the sqlite_master.sql field. |
932 | */ |
933 | static void shellAddSchemaName(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal) { |
934 | static const char *aPrefix[] = {"TABLE" , "INDEX" , "UNIQUE INDEX" , "VIEW" , "TRIGGER" , "VIRTUAL TABLE" }; |
935 | int i = 0; |
936 | const char *zIn = (const char *)sqlite3_value_text(apVal[0]); |
937 | const char *zSchema = (const char *)sqlite3_value_text(apVal[1]); |
938 | const char *zName = (const char *)sqlite3_value_text(apVal[2]); |
939 | sqlite3 *db = sqlite3_context_db_handle(pCtx); |
940 | UNUSED_PARAMETER(nVal); |
941 | if (zIn != 0 && strncmp(zIn, "CREATE " , 7) == 0) { |
942 | for (i = 0; i < (int)(sizeof(aPrefix) / sizeof(aPrefix[0])); i++) { |
943 | int n = strlen30(aPrefix[i]); |
944 | if (strncmp(zIn + 7, aPrefix[i], n) == 0 && zIn[n + 7] == ' ') { |
945 | char *z = 0; |
946 | char *zFake = 0; |
947 | if (zSchema) { |
948 | char cQuote = quoteChar(zSchema); |
949 | if (cQuote && sqlite3_stricmp(zSchema, "temp" ) != 0) { |
950 | z = sqlite3_mprintf("%.*s \"%w\".%s" , n + 7, zIn, zSchema, zIn + n + 8); |
951 | } else { |
952 | z = sqlite3_mprintf("%.*s %s.%s" , n + 7, zIn, zSchema, zIn + n + 8); |
953 | } |
954 | } |
955 | if (zName && aPrefix[i][0] == 'V' && (zFake = shellFakeSchema(db, zSchema, zName)) != 0) { |
956 | if (z == 0) { |
957 | z = sqlite3_mprintf("%s\n/* %s */" , zIn, zFake); |
958 | } else { |
959 | z = sqlite3_mprintf("%z\n/* %s */" , z, zFake); |
960 | } |
961 | free(zFake); |
962 | } |
963 | if (z) { |
964 | sqlite3_result_text(pCtx, z, -1, sqlite3_free); |
965 | return; |
966 | } |
967 | } |
968 | } |
969 | } |
970 | sqlite3_result_value(pCtx, apVal[0]); |
971 | } |
972 | |
973 | /* |
974 | ** The source code for several run-time loadable extensions is inserted |
975 | ** below by the ../tool/mkshellc.tcl script. Before processing that included |
976 | ** code, we need to override some macros to make the included program code |
977 | ** work here in the middle of this regular program. |
978 | */ |
979 | #define SQLITE_EXTENSION_INIT1 |
980 | #define SQLITE_EXTENSION_INIT2(X) (void)(X) |
981 | |
982 | #if defined(_WIN32) && defined(_MSC_VER) |
983 | /************************* Begin test_windirent.h ******************/ |
984 | /* |
985 | ** 2015 November 30 |
986 | ** |
987 | ** The author disclaims copyright to this source code. In place of |
988 | ** a legal notice, here is a blessing: |
989 | ** |
990 | ** May you do good and not evil. |
991 | ** May you find forgiveness for yourself and forgive others. |
992 | ** May you share freely, never taking more than you give. |
993 | ** |
994 | ************************************************************************* |
995 | ** This file contains declarations for most of the opendir() family of |
996 | ** POSIX functions on Win32 using the MSVCRT. |
997 | */ |
998 | |
999 | #if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H) |
1000 | #define SQLITE_WINDIRENT_H |
1001 | |
1002 | /* |
1003 | ** We need several data types from the Windows SDK header. |
1004 | */ |
1005 | |
1006 | #ifndef WIN32_LEAN_AND_MEAN |
1007 | #define WIN32_LEAN_AND_MEAN |
1008 | #endif |
1009 | |
1010 | #include "windows.h" |
1011 | |
1012 | /* |
1013 | ** We need several support functions from the SQLite core. |
1014 | */ |
1015 | |
1016 | /* |
1017 | ** We need several things from the ANSI and MSVCRT headers. |
1018 | */ |
1019 | |
1020 | #include <stdio.h> |
1021 | #include <stdlib.h> |
1022 | #include <errno.h> |
1023 | #include <io.h> |
1024 | #include <limits.h> |
1025 | #include <sys/types.h> |
1026 | #include <sys/stat.h> |
1027 | |
1028 | /* |
1029 | ** We may need several defines that should have been in "sys/stat.h". |
1030 | */ |
1031 | |
1032 | #ifndef S_ISREG |
1033 | #define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) |
1034 | #endif |
1035 | |
1036 | #ifndef S_ISDIR |
1037 | #define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) |
1038 | #endif |
1039 | |
1040 | #ifndef S_ISLNK |
1041 | #define S_ISLNK(mode) (0) |
1042 | #endif |
1043 | |
1044 | /* |
1045 | ** We may need to provide the "mode_t" type. |
1046 | */ |
1047 | |
1048 | #ifndef MODE_T_DEFINED |
1049 | #define MODE_T_DEFINED |
1050 | typedef unsigned short mode_t; |
1051 | #endif |
1052 | |
1053 | /* |
1054 | ** We may need to provide the "ino_t" type. |
1055 | */ |
1056 | |
1057 | #ifndef INO_T_DEFINED |
1058 | #define INO_T_DEFINED |
1059 | typedef unsigned short ino_t; |
1060 | #endif |
1061 | |
1062 | /* |
1063 | ** We need to define "NAME_MAX" if it was not present in "limits.h". |
1064 | */ |
1065 | |
1066 | #ifndef NAME_MAX |
1067 | #ifdef FILENAME_MAX |
1068 | #define NAME_MAX (FILENAME_MAX) |
1069 | #else |
1070 | #define NAME_MAX (260) |
1071 | #endif |
1072 | #endif |
1073 | |
1074 | /* |
1075 | ** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T". |
1076 | */ |
1077 | |
1078 | #ifndef NULL_INTPTR_T |
1079 | #define NULL_INTPTR_T ((intptr_t)(0)) |
1080 | #endif |
1081 | |
1082 | #ifndef BAD_INTPTR_T |
1083 | #define BAD_INTPTR_T ((intptr_t)(-1)) |
1084 | #endif |
1085 | |
1086 | /* |
1087 | ** We need to provide the necessary structures and related types. |
1088 | */ |
1089 | |
1090 | #ifndef DIRENT_DEFINED |
1091 | #define DIRENT_DEFINED |
1092 | typedef struct DIRENT DIRENT; |
1093 | typedef DIRENT *LPDIRENT; |
1094 | struct DIRENT { |
1095 | ino_t d_ino; /* Sequence number, do not use. */ |
1096 | unsigned d_attributes; /* Win32 file attributes. */ |
1097 | char d_name[NAME_MAX + 1]; /* Name within the directory. */ |
1098 | }; |
1099 | #endif |
1100 | |
1101 | #ifndef DIR_DEFINED |
1102 | #define DIR_DEFINED |
1103 | typedef struct DIR DIR; |
1104 | typedef DIR *LPDIR; |
1105 | struct DIR { |
1106 | intptr_t d_handle; /* Value returned by "_findfirst". */ |
1107 | DIRENT d_first; /* DIRENT constructed based on "_findfirst". */ |
1108 | DIRENT d_next; /* DIRENT constructed based on "_findnext". */ |
1109 | }; |
1110 | #endif |
1111 | |
1112 | /* |
1113 | ** Provide a macro, for use by the implementation, to determine if a |
1114 | ** particular directory entry should be skipped over when searching for |
1115 | ** the next directory entry that should be returned by the readdir() or |
1116 | ** readdir_r() functions. |
1117 | */ |
1118 | |
1119 | #ifndef is_filtered |
1120 | #define is_filtered(a) ((((a).attrib) & _A_HIDDEN) || (((a).attrib) & _A_SYSTEM)) |
1121 | #endif |
1122 | |
1123 | /* |
1124 | ** Provide the function prototype for the POSIX compatiable getenv() |
1125 | ** function. This function is not thread-safe. |
1126 | */ |
1127 | |
1128 | extern const char *windirent_getenv(const char *name); |
1129 | |
1130 | /* |
1131 | ** Finally, we can provide the function prototypes for the opendir(), |
1132 | ** readdir(), readdir_r(), and closedir() POSIX functions. |
1133 | */ |
1134 | |
1135 | extern LPDIR opendir(const char *dirname); |
1136 | extern LPDIRENT readdir(LPDIR dirp); |
1137 | extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result); |
1138 | extern INT closedir(LPDIR dirp); |
1139 | |
1140 | #endif /* defined(WIN32) && defined(_MSC_VER) */ |
1141 | |
1142 | /************************* End test_windirent.h ********************/ |
1143 | /************************* Begin test_windirent.c ******************/ |
1144 | /* |
1145 | ** 2015 November 30 |
1146 | ** |
1147 | ** The author disclaims copyright to this source code. In place of |
1148 | ** a legal notice, here is a blessing: |
1149 | ** |
1150 | ** May you do good and not evil. |
1151 | ** May you find forgiveness for yourself and forgive others. |
1152 | ** May you share freely, never taking more than you give. |
1153 | ** |
1154 | ************************************************************************* |
1155 | ** This file contains code to implement most of the opendir() family of |
1156 | ** POSIX functions on Win32 using the MSVCRT. |
1157 | */ |
1158 | |
1159 | #if defined(_WIN32) && defined(_MSC_VER) |
1160 | /* #include "test_windirent.h" */ |
1161 | |
1162 | /* |
1163 | ** Implementation of the POSIX getenv() function using the Win32 API. |
1164 | ** This function is not thread-safe. |
1165 | */ |
1166 | const char *windirent_getenv(const char *name) { |
1167 | static char value[32768]; /* Maximum length, per MSDN */ |
1168 | DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */ |
1169 | DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */ |
1170 | |
1171 | memset(value, 0, sizeof(value)); |
1172 | dwRet = GetEnvironmentVariableA(name, value, dwSize); |
1173 | if (dwRet == 0 || dwRet > dwSize) { |
1174 | /* |
1175 | ** The function call to GetEnvironmentVariableA() failed -OR- |
1176 | ** the buffer is not large enough. Either way, return NULL. |
1177 | */ |
1178 | return 0; |
1179 | } else { |
1180 | /* |
1181 | ** The function call to GetEnvironmentVariableA() succeeded |
1182 | ** -AND- the buffer contains the entire value. |
1183 | */ |
1184 | return value; |
1185 | } |
1186 | } |
1187 | |
1188 | /* |
1189 | ** Implementation of the POSIX opendir() function using the MSVCRT. |
1190 | */ |
1191 | LPDIR opendir(const char *dirname) { |
1192 | struct _finddata_t data; |
1193 | LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR)); |
1194 | SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]); |
1195 | |
1196 | if (dirp == NULL) |
1197 | return NULL; |
1198 | memset(dirp, 0, sizeof(DIR)); |
1199 | |
1200 | /* TODO: Remove this if Unix-style root paths are not used. */ |
1201 | if (sqlite3_stricmp(dirname, "/" ) == 0) { |
1202 | dirname = windirent_getenv("SystemDrive" ); |
1203 | } |
1204 | |
1205 | memset(&data, 0, sizeof(struct _finddata_t)); |
1206 | _snprintf(data.name, namesize, "%s\\*" , dirname); |
1207 | dirp->d_handle = _findfirst(data.name, &data); |
1208 | |
1209 | if (dirp->d_handle == BAD_INTPTR_T) { |
1210 | closedir(dirp); |
1211 | return NULL; |
1212 | } |
1213 | |
1214 | /* TODO: Remove this block to allow hidden and/or system files. */ |
1215 | if (is_filtered(data)) { |
1216 | next: |
1217 | |
1218 | memset(&data, 0, sizeof(struct _finddata_t)); |
1219 | if (_findnext(dirp->d_handle, &data) == -1) { |
1220 | closedir(dirp); |
1221 | return NULL; |
1222 | } |
1223 | |
1224 | /* TODO: Remove this block to allow hidden and/or system files. */ |
1225 | if (is_filtered(data)) |
1226 | goto next; |
1227 | } |
1228 | |
1229 | dirp->d_first.d_attributes = data.attrib; |
1230 | strncpy(dirp->d_first.d_name, data.name, NAME_MAX); |
1231 | dirp->d_first.d_name[NAME_MAX] = '\0'; |
1232 | |
1233 | return dirp; |
1234 | } |
1235 | |
1236 | /* |
1237 | ** Implementation of the POSIX readdir() function using the MSVCRT. |
1238 | */ |
1239 | LPDIRENT readdir(LPDIR dirp) { |
1240 | struct _finddata_t data; |
1241 | |
1242 | if (dirp == NULL) |
1243 | return NULL; |
1244 | |
1245 | if (dirp->d_first.d_ino == 0) { |
1246 | dirp->d_first.d_ino++; |
1247 | dirp->d_next.d_ino++; |
1248 | |
1249 | return &dirp->d_first; |
1250 | } |
1251 | |
1252 | next: |
1253 | |
1254 | memset(&data, 0, sizeof(struct _finddata_t)); |
1255 | if (_findnext(dirp->d_handle, &data) == -1) |
1256 | return NULL; |
1257 | |
1258 | /* TODO: Remove this block to allow hidden and/or system files. */ |
1259 | if (is_filtered(data)) |
1260 | goto next; |
1261 | |
1262 | dirp->d_next.d_ino++; |
1263 | dirp->d_next.d_attributes = data.attrib; |
1264 | strncpy(dirp->d_next.d_name, data.name, NAME_MAX); |
1265 | dirp->d_next.d_name[NAME_MAX] = '\0'; |
1266 | |
1267 | return &dirp->d_next; |
1268 | } |
1269 | |
1270 | /* |
1271 | ** Implementation of the POSIX readdir_r() function using the MSVCRT. |
1272 | */ |
1273 | INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result) { |
1274 | struct _finddata_t data; |
1275 | |
1276 | if (dirp == NULL) |
1277 | return EBADF; |
1278 | |
1279 | if (dirp->d_first.d_ino == 0) { |
1280 | dirp->d_first.d_ino++; |
1281 | dirp->d_next.d_ino++; |
1282 | |
1283 | entry->d_ino = dirp->d_first.d_ino; |
1284 | entry->d_attributes = dirp->d_first.d_attributes; |
1285 | strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX); |
1286 | entry->d_name[NAME_MAX] = '\0'; |
1287 | |
1288 | *result = entry; |
1289 | return 0; |
1290 | } |
1291 | |
1292 | next: |
1293 | |
1294 | memset(&data, 0, sizeof(struct _finddata_t)); |
1295 | if (_findnext(dirp->d_handle, &data) == -1) { |
1296 | *result = NULL; |
1297 | return ENOENT; |
1298 | } |
1299 | |
1300 | /* TODO: Remove this block to allow hidden and/or system files. */ |
1301 | if (is_filtered(data)) |
1302 | goto next; |
1303 | |
1304 | entry->d_ino = (ino_t)-1; /* not available */ |
1305 | entry->d_attributes = data.attrib; |
1306 | strncpy(entry->d_name, data.name, NAME_MAX); |
1307 | entry->d_name[NAME_MAX] = '\0'; |
1308 | |
1309 | *result = entry; |
1310 | return 0; |
1311 | } |
1312 | |
1313 | /* |
1314 | ** Implementation of the POSIX closedir() function using the MSVCRT. |
1315 | */ |
1316 | INT closedir(LPDIR dirp) { |
1317 | INT result = 0; |
1318 | |
1319 | if (dirp == NULL) |
1320 | return EINVAL; |
1321 | |
1322 | if (dirp->d_handle != NULL_INTPTR_T && dirp->d_handle != BAD_INTPTR_T) { |
1323 | result = _findclose(dirp->d_handle); |
1324 | } |
1325 | |
1326 | sqlite3_free(dirp); |
1327 | return result; |
1328 | } |
1329 | |
1330 | #endif /* defined(WIN32) && defined(_MSC_VER) */ |
1331 | |
1332 | /************************* End test_windirent.c ********************/ |
1333 | #define dirent DIRENT |
1334 | #endif |
1335 | /************************* Begin ../ext/misc/shathree.c ******************/ |
1336 | /* |
1337 | ** 2017-03-08 |
1338 | ** |
1339 | ** The author disclaims copyright to this source code. In place of |
1340 | ** a legal notice, here is a blessing: |
1341 | ** |
1342 | ** May you do good and not evil. |
1343 | ** May you find forgiveness for yourself and forgive others. |
1344 | ** May you share freely, never taking more than you give. |
1345 | ** |
1346 | ****************************************************************************** |
1347 | ** |
1348 | ** This SQLite extension implements a functions that compute SHA1 hashes. |
1349 | ** Two SQL functions are implemented: |
1350 | ** |
1351 | ** sha3(X,SIZE) |
1352 | ** sha3_query(Y,SIZE) |
1353 | ** |
1354 | ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if |
1355 | ** X is NULL. |
1356 | ** |
1357 | ** The sha3_query(Y) function evalutes all queries in the SQL statements of Y |
1358 | ** and returns a hash of their results. |
1359 | ** |
1360 | ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm |
1361 | ** is used. If SIZE is included it must be one of the integers 224, 256, |
1362 | ** 384, or 512, to determine SHA3 hash variant that is computed. |
1363 | */ |
1364 | SQLITE_EXTENSION_INIT1 |
1365 | #include <assert.h> |
1366 | #include <string.h> |
1367 | #include <stdarg.h> |
1368 | /* typedef sqlite3_uint64 u64; */ |
1369 | |
1370 | /****************************************************************************** |
1371 | ** The Hash Engine |
1372 | */ |
1373 | /* |
1374 | ** Macros to determine whether the machine is big or little endian, |
1375 | ** and whether or not that determination is run-time or compile-time. |
1376 | ** |
1377 | ** For best performance, an attempt is made to guess at the byte-order |
1378 | ** using C-preprocessor macros. If that is unsuccessful, or if |
1379 | ** -DSHA3_BYTEORDER=0 is set, then byte-order is determined |
1380 | ** at run-time. |
1381 | */ |
1382 | #ifndef SHA3_BYTEORDER |
1383 | #if defined(i386) || defined(__i386__) || defined(_M_IX86) || defined(__x86_64) || defined(__x86_64__) || \ |
1384 | defined(_M_X64) || defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || defined(__arm__) |
1385 | #define SHA3_BYTEORDER 1234 |
1386 | #elif defined(sparc) || defined(__ppc__) |
1387 | #define SHA3_BYTEORDER 4321 |
1388 | #else |
1389 | #define SHA3_BYTEORDER 0 |
1390 | #endif |
1391 | #endif |
1392 | |
1393 | /* |
1394 | ** State structure for a SHA3 hash in progress |
1395 | */ |
1396 | typedef struct SHA3Context SHA3Context; |
1397 | struct SHA3Context { |
1398 | union { |
1399 | u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ |
1400 | unsigned char x[1600]; /* ... or 1600 bytes */ |
1401 | } u; |
1402 | unsigned nRate; /* Bytes of input accepted per Keccak iteration */ |
1403 | unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ |
1404 | unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ |
1405 | }; |
1406 | |
1407 | /* |
1408 | ** A single step of the Keccak mixing function for a 1600-bit state |
1409 | */ |
1410 | static void KeccakF1600Step(SHA3Context *p) { |
1411 | int i; |
1412 | u64 b0, b1, b2, b3, b4; |
1413 | u64 c0, c1, c2, c3, c4; |
1414 | u64 d0, d1, d2, d3, d4; |
1415 | static const u64 RC[] = { |
1416 | 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, |
1417 | 0x000000000000808bULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, |
1418 | 0x000000000000008aULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, |
1419 | 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, |
1420 | 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800aULL, 0x800000008000000aULL, |
1421 | 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL}; |
1422 | #define a00 (p->u.s[0]) |
1423 | #define a01 (p->u.s[1]) |
1424 | #define a02 (p->u.s[2]) |
1425 | #define a03 (p->u.s[3]) |
1426 | #define a04 (p->u.s[4]) |
1427 | #define a10 (p->u.s[5]) |
1428 | #define a11 (p->u.s[6]) |
1429 | #define a12 (p->u.s[7]) |
1430 | #define a13 (p->u.s[8]) |
1431 | #define a14 (p->u.s[9]) |
1432 | #define a20 (p->u.s[10]) |
1433 | #define a21 (p->u.s[11]) |
1434 | #define a22 (p->u.s[12]) |
1435 | #define a23 (p->u.s[13]) |
1436 | #define a24 (p->u.s[14]) |
1437 | #define a30 (p->u.s[15]) |
1438 | #define a31 (p->u.s[16]) |
1439 | #define a32 (p->u.s[17]) |
1440 | #define a33 (p->u.s[18]) |
1441 | #define a34 (p->u.s[19]) |
1442 | #define a40 (p->u.s[20]) |
1443 | #define a41 (p->u.s[21]) |
1444 | #define a42 (p->u.s[22]) |
1445 | #define a43 (p->u.s[23]) |
1446 | #define a44 (p->u.s[24]) |
1447 | #define ROL64(a, x) ((a << x) | (a >> (64 - x))) |
1448 | |
1449 | for (i = 0; i < 24; i += 4) { |
1450 | c0 = a00 ^ a10 ^ a20 ^ a30 ^ a40; |
1451 | c1 = a01 ^ a11 ^ a21 ^ a31 ^ a41; |
1452 | c2 = a02 ^ a12 ^ a22 ^ a32 ^ a42; |
1453 | c3 = a03 ^ a13 ^ a23 ^ a33 ^ a43; |
1454 | c4 = a04 ^ a14 ^ a24 ^ a34 ^ a44; |
1455 | d0 = c4 ^ ROL64(c1, 1); |
1456 | d1 = c0 ^ ROL64(c2, 1); |
1457 | d2 = c1 ^ ROL64(c3, 1); |
1458 | d3 = c2 ^ ROL64(c4, 1); |
1459 | d4 = c3 ^ ROL64(c0, 1); |
1460 | |
1461 | b0 = (a00 ^ d0); |
1462 | b1 = ROL64((a11 ^ d1), 44); |
1463 | b2 = ROL64((a22 ^ d2), 43); |
1464 | b3 = ROL64((a33 ^ d3), 21); |
1465 | b4 = ROL64((a44 ^ d4), 14); |
1466 | a00 = b0 ^ ((~b1) & b2); |
1467 | a00 ^= RC[i]; |
1468 | a11 = b1 ^ ((~b2) & b3); |
1469 | a22 = b2 ^ ((~b3) & b4); |
1470 | a33 = b3 ^ ((~b4) & b0); |
1471 | a44 = b4 ^ ((~b0) & b1); |
1472 | |
1473 | b2 = ROL64((a20 ^ d0), 3); |
1474 | b3 = ROL64((a31 ^ d1), 45); |
1475 | b4 = ROL64((a42 ^ d2), 61); |
1476 | b0 = ROL64((a03 ^ d3), 28); |
1477 | b1 = ROL64((a14 ^ d4), 20); |
1478 | a20 = b0 ^ ((~b1) & b2); |
1479 | a31 = b1 ^ ((~b2) & b3); |
1480 | a42 = b2 ^ ((~b3) & b4); |
1481 | a03 = b3 ^ ((~b4) & b0); |
1482 | a14 = b4 ^ ((~b0) & b1); |
1483 | |
1484 | b4 = ROL64((a40 ^ d0), 18); |
1485 | b0 = ROL64((a01 ^ d1), 1); |
1486 | b1 = ROL64((a12 ^ d2), 6); |
1487 | b2 = ROL64((a23 ^ d3), 25); |
1488 | b3 = ROL64((a34 ^ d4), 8); |
1489 | a40 = b0 ^ ((~b1) & b2); |
1490 | a01 = b1 ^ ((~b2) & b3); |
1491 | a12 = b2 ^ ((~b3) & b4); |
1492 | a23 = b3 ^ ((~b4) & b0); |
1493 | a34 = b4 ^ ((~b0) & b1); |
1494 | |
1495 | b1 = ROL64((a10 ^ d0), 36); |
1496 | b2 = ROL64((a21 ^ d1), 10); |
1497 | b3 = ROL64((a32 ^ d2), 15); |
1498 | b4 = ROL64((a43 ^ d3), 56); |
1499 | b0 = ROL64((a04 ^ d4), 27); |
1500 | a10 = b0 ^ ((~b1) & b2); |
1501 | a21 = b1 ^ ((~b2) & b3); |
1502 | a32 = b2 ^ ((~b3) & b4); |
1503 | a43 = b3 ^ ((~b4) & b0); |
1504 | a04 = b4 ^ ((~b0) & b1); |
1505 | |
1506 | b3 = ROL64((a30 ^ d0), 41); |
1507 | b4 = ROL64((a41 ^ d1), 2); |
1508 | b0 = ROL64((a02 ^ d2), 62); |
1509 | b1 = ROL64((a13 ^ d3), 55); |
1510 | b2 = ROL64((a24 ^ d4), 39); |
1511 | a30 = b0 ^ ((~b1) & b2); |
1512 | a41 = b1 ^ ((~b2) & b3); |
1513 | a02 = b2 ^ ((~b3) & b4); |
1514 | a13 = b3 ^ ((~b4) & b0); |
1515 | a24 = b4 ^ ((~b0) & b1); |
1516 | |
1517 | c0 = a00 ^ a20 ^ a40 ^ a10 ^ a30; |
1518 | c1 = a11 ^ a31 ^ a01 ^ a21 ^ a41; |
1519 | c2 = a22 ^ a42 ^ a12 ^ a32 ^ a02; |
1520 | c3 = a33 ^ a03 ^ a23 ^ a43 ^ a13; |
1521 | c4 = a44 ^ a14 ^ a34 ^ a04 ^ a24; |
1522 | d0 = c4 ^ ROL64(c1, 1); |
1523 | d1 = c0 ^ ROL64(c2, 1); |
1524 | d2 = c1 ^ ROL64(c3, 1); |
1525 | d3 = c2 ^ ROL64(c4, 1); |
1526 | d4 = c3 ^ ROL64(c0, 1); |
1527 | |
1528 | b0 = (a00 ^ d0); |
1529 | b1 = ROL64((a31 ^ d1), 44); |
1530 | b2 = ROL64((a12 ^ d2), 43); |
1531 | b3 = ROL64((a43 ^ d3), 21); |
1532 | b4 = ROL64((a24 ^ d4), 14); |
1533 | a00 = b0 ^ ((~b1) & b2); |
1534 | a00 ^= RC[i + 1]; |
1535 | a31 = b1 ^ ((~b2) & b3); |
1536 | a12 = b2 ^ ((~b3) & b4); |
1537 | a43 = b3 ^ ((~b4) & b0); |
1538 | a24 = b4 ^ ((~b0) & b1); |
1539 | |
1540 | b2 = ROL64((a40 ^ d0), 3); |
1541 | b3 = ROL64((a21 ^ d1), 45); |
1542 | b4 = ROL64((a02 ^ d2), 61); |
1543 | b0 = ROL64((a33 ^ d3), 28); |
1544 | b1 = ROL64((a14 ^ d4), 20); |
1545 | a40 = b0 ^ ((~b1) & b2); |
1546 | a21 = b1 ^ ((~b2) & b3); |
1547 | a02 = b2 ^ ((~b3) & b4); |
1548 | a33 = b3 ^ ((~b4) & b0); |
1549 | a14 = b4 ^ ((~b0) & b1); |
1550 | |
1551 | b4 = ROL64((a30 ^ d0), 18); |
1552 | b0 = ROL64((a11 ^ d1), 1); |
1553 | b1 = ROL64((a42 ^ d2), 6); |
1554 | b2 = ROL64((a23 ^ d3), 25); |
1555 | b3 = ROL64((a04 ^ d4), 8); |
1556 | a30 = b0 ^ ((~b1) & b2); |
1557 | a11 = b1 ^ ((~b2) & b3); |
1558 | a42 = b2 ^ ((~b3) & b4); |
1559 | a23 = b3 ^ ((~b4) & b0); |
1560 | a04 = b4 ^ ((~b0) & b1); |
1561 | |
1562 | b1 = ROL64((a20 ^ d0), 36); |
1563 | b2 = ROL64((a01 ^ d1), 10); |
1564 | b3 = ROL64((a32 ^ d2), 15); |
1565 | b4 = ROL64((a13 ^ d3), 56); |
1566 | b0 = ROL64((a44 ^ d4), 27); |
1567 | a20 = b0 ^ ((~b1) & b2); |
1568 | a01 = b1 ^ ((~b2) & b3); |
1569 | a32 = b2 ^ ((~b3) & b4); |
1570 | a13 = b3 ^ ((~b4) & b0); |
1571 | a44 = b4 ^ ((~b0) & b1); |
1572 | |
1573 | b3 = ROL64((a10 ^ d0), 41); |
1574 | b4 = ROL64((a41 ^ d1), 2); |
1575 | b0 = ROL64((a22 ^ d2), 62); |
1576 | b1 = ROL64((a03 ^ d3), 55); |
1577 | b2 = ROL64((a34 ^ d4), 39); |
1578 | a10 = b0 ^ ((~b1) & b2); |
1579 | a41 = b1 ^ ((~b2) & b3); |
1580 | a22 = b2 ^ ((~b3) & b4); |
1581 | a03 = b3 ^ ((~b4) & b0); |
1582 | a34 = b4 ^ ((~b0) & b1); |
1583 | |
1584 | c0 = a00 ^ a40 ^ a30 ^ a20 ^ a10; |
1585 | c1 = a31 ^ a21 ^ a11 ^ a01 ^ a41; |
1586 | c2 = a12 ^ a02 ^ a42 ^ a32 ^ a22; |
1587 | c3 = a43 ^ a33 ^ a23 ^ a13 ^ a03; |
1588 | c4 = a24 ^ a14 ^ a04 ^ a44 ^ a34; |
1589 | d0 = c4 ^ ROL64(c1, 1); |
1590 | d1 = c0 ^ ROL64(c2, 1); |
1591 | d2 = c1 ^ ROL64(c3, 1); |
1592 | d3 = c2 ^ ROL64(c4, 1); |
1593 | d4 = c3 ^ ROL64(c0, 1); |
1594 | |
1595 | b0 = (a00 ^ d0); |
1596 | b1 = ROL64((a21 ^ d1), 44); |
1597 | b2 = ROL64((a42 ^ d2), 43); |
1598 | b3 = ROL64((a13 ^ d3), 21); |
1599 | b4 = ROL64((a34 ^ d4), 14); |
1600 | a00 = b0 ^ ((~b1) & b2); |
1601 | a00 ^= RC[i + 2]; |
1602 | a21 = b1 ^ ((~b2) & b3); |
1603 | a42 = b2 ^ ((~b3) & b4); |
1604 | a13 = b3 ^ ((~b4) & b0); |
1605 | a34 = b4 ^ ((~b0) & b1); |
1606 | |
1607 | b2 = ROL64((a30 ^ d0), 3); |
1608 | b3 = ROL64((a01 ^ d1), 45); |
1609 | b4 = ROL64((a22 ^ d2), 61); |
1610 | b0 = ROL64((a43 ^ d3), 28); |
1611 | b1 = ROL64((a14 ^ d4), 20); |
1612 | a30 = b0 ^ ((~b1) & b2); |
1613 | a01 = b1 ^ ((~b2) & b3); |
1614 | a22 = b2 ^ ((~b3) & b4); |
1615 | a43 = b3 ^ ((~b4) & b0); |
1616 | a14 = b4 ^ ((~b0) & b1); |
1617 | |
1618 | b4 = ROL64((a10 ^ d0), 18); |
1619 | b0 = ROL64((a31 ^ d1), 1); |
1620 | b1 = ROL64((a02 ^ d2), 6); |
1621 | b2 = ROL64((a23 ^ d3), 25); |
1622 | b3 = ROL64((a44 ^ d4), 8); |
1623 | a10 = b0 ^ ((~b1) & b2); |
1624 | a31 = b1 ^ ((~b2) & b3); |
1625 | a02 = b2 ^ ((~b3) & b4); |
1626 | a23 = b3 ^ ((~b4) & b0); |
1627 | a44 = b4 ^ ((~b0) & b1); |
1628 | |
1629 | b1 = ROL64((a40 ^ d0), 36); |
1630 | b2 = ROL64((a11 ^ d1), 10); |
1631 | b3 = ROL64((a32 ^ d2), 15); |
1632 | b4 = ROL64((a03 ^ d3), 56); |
1633 | b0 = ROL64((a24 ^ d4), 27); |
1634 | a40 = b0 ^ ((~b1) & b2); |
1635 | a11 = b1 ^ ((~b2) & b3); |
1636 | a32 = b2 ^ ((~b3) & b4); |
1637 | a03 = b3 ^ ((~b4) & b0); |
1638 | a24 = b4 ^ ((~b0) & b1); |
1639 | |
1640 | b3 = ROL64((a20 ^ d0), 41); |
1641 | b4 = ROL64((a41 ^ d1), 2); |
1642 | b0 = ROL64((a12 ^ d2), 62); |
1643 | b1 = ROL64((a33 ^ d3), 55); |
1644 | b2 = ROL64((a04 ^ d4), 39); |
1645 | a20 = b0 ^ ((~b1) & b2); |
1646 | a41 = b1 ^ ((~b2) & b3); |
1647 | a12 = b2 ^ ((~b3) & b4); |
1648 | a33 = b3 ^ ((~b4) & b0); |
1649 | a04 = b4 ^ ((~b0) & b1); |
1650 | |
1651 | c0 = a00 ^ a30 ^ a10 ^ a40 ^ a20; |
1652 | c1 = a21 ^ a01 ^ a31 ^ a11 ^ a41; |
1653 | c2 = a42 ^ a22 ^ a02 ^ a32 ^ a12; |
1654 | c3 = a13 ^ a43 ^ a23 ^ a03 ^ a33; |
1655 | c4 = a34 ^ a14 ^ a44 ^ a24 ^ a04; |
1656 | d0 = c4 ^ ROL64(c1, 1); |
1657 | d1 = c0 ^ ROL64(c2, 1); |
1658 | d2 = c1 ^ ROL64(c3, 1); |
1659 | d3 = c2 ^ ROL64(c4, 1); |
1660 | d4 = c3 ^ ROL64(c0, 1); |
1661 | |
1662 | b0 = (a00 ^ d0); |
1663 | b1 = ROL64((a01 ^ d1), 44); |
1664 | b2 = ROL64((a02 ^ d2), 43); |
1665 | b3 = ROL64((a03 ^ d3), 21); |
1666 | b4 = ROL64((a04 ^ d4), 14); |
1667 | a00 = b0 ^ ((~b1) & b2); |
1668 | a00 ^= RC[i + 3]; |
1669 | a01 = b1 ^ ((~b2) & b3); |
1670 | a02 = b2 ^ ((~b3) & b4); |
1671 | a03 = b3 ^ ((~b4) & b0); |
1672 | a04 = b4 ^ ((~b0) & b1); |
1673 | |
1674 | b2 = ROL64((a10 ^ d0), 3); |
1675 | b3 = ROL64((a11 ^ d1), 45); |
1676 | b4 = ROL64((a12 ^ d2), 61); |
1677 | b0 = ROL64((a13 ^ d3), 28); |
1678 | b1 = ROL64((a14 ^ d4), 20); |
1679 | a10 = b0 ^ ((~b1) & b2); |
1680 | a11 = b1 ^ ((~b2) & b3); |
1681 | a12 = b2 ^ ((~b3) & b4); |
1682 | a13 = b3 ^ ((~b4) & b0); |
1683 | a14 = b4 ^ ((~b0) & b1); |
1684 | |
1685 | b4 = ROL64((a20 ^ d0), 18); |
1686 | b0 = ROL64((a21 ^ d1), 1); |
1687 | b1 = ROL64((a22 ^ d2), 6); |
1688 | b2 = ROL64((a23 ^ d3), 25); |
1689 | b3 = ROL64((a24 ^ d4), 8); |
1690 | a20 = b0 ^ ((~b1) & b2); |
1691 | a21 = b1 ^ ((~b2) & b3); |
1692 | a22 = b2 ^ ((~b3) & b4); |
1693 | a23 = b3 ^ ((~b4) & b0); |
1694 | a24 = b4 ^ ((~b0) & b1); |
1695 | |
1696 | b1 = ROL64((a30 ^ d0), 36); |
1697 | b2 = ROL64((a31 ^ d1), 10); |
1698 | b3 = ROL64((a32 ^ d2), 15); |
1699 | b4 = ROL64((a33 ^ d3), 56); |
1700 | b0 = ROL64((a34 ^ d4), 27); |
1701 | a30 = b0 ^ ((~b1) & b2); |
1702 | a31 = b1 ^ ((~b2) & b3); |
1703 | a32 = b2 ^ ((~b3) & b4); |
1704 | a33 = b3 ^ ((~b4) & b0); |
1705 | a34 = b4 ^ ((~b0) & b1); |
1706 | |
1707 | b3 = ROL64((a40 ^ d0), 41); |
1708 | b4 = ROL64((a41 ^ d1), 2); |
1709 | b0 = ROL64((a42 ^ d2), 62); |
1710 | b1 = ROL64((a43 ^ d3), 55); |
1711 | b2 = ROL64((a44 ^ d4), 39); |
1712 | a40 = b0 ^ ((~b1) & b2); |
1713 | a41 = b1 ^ ((~b2) & b3); |
1714 | a42 = b2 ^ ((~b3) & b4); |
1715 | a43 = b3 ^ ((~b4) & b0); |
1716 | a44 = b4 ^ ((~b0) & b1); |
1717 | } |
1718 | } |
1719 | |
1720 | /* |
1721 | ** Initialize a new hash. iSize determines the size of the hash |
1722 | ** in bits and should be one of 224, 256, 384, or 512. Or iSize |
1723 | ** can be zero to use the default hash size of 256 bits. |
1724 | */ |
1725 | static void SHA3Init(SHA3Context *p, int iSize) { |
1726 | memset(p, 0, sizeof(*p)); |
1727 | if (iSize >= 128 && iSize <= 512) { |
1728 | p->nRate = (1600 - ((iSize + 31) & ~31) * 2) / 8; |
1729 | } else { |
1730 | p->nRate = (1600 - 2 * 256) / 8; |
1731 | } |
1732 | #if SHA3_BYTEORDER == 1234 |
1733 | /* Known to be little-endian at compile-time. No-op */ |
1734 | #elif SHA3_BYTEORDER == 4321 |
1735 | p->ixMask = 7; /* Big-endian */ |
1736 | #else |
1737 | { |
1738 | static unsigned int one = 1; |
1739 | if (1 == *(unsigned char *)&one) { |
1740 | /* Little endian. No byte swapping. */ |
1741 | p->ixMask = 0; |
1742 | } else { |
1743 | /* Big endian. Byte swap. */ |
1744 | p->ixMask = 7; |
1745 | } |
1746 | } |
1747 | #endif |
1748 | } |
1749 | |
1750 | /* |
1751 | ** Make consecutive calls to the SHA3Update function to add new content |
1752 | ** to the hash |
1753 | */ |
1754 | static void SHA3Update(SHA3Context *p, const unsigned char *aData, unsigned int nData) { |
1755 | unsigned int i = 0; |
1756 | #if SHA3_BYTEORDER == 1234 |
1757 | if ((p->nLoaded % 8) == 0 && ((aData - (const unsigned char *)0) & 7) == 0) { |
1758 | for (; i + 7 < nData; i += 8) { |
1759 | p->u.s[p->nLoaded / 8] ^= *(u64 *)&aData[i]; |
1760 | p->nLoaded += 8; |
1761 | if (p->nLoaded >= p->nRate) { |
1762 | KeccakF1600Step(p); |
1763 | p->nLoaded = 0; |
1764 | } |
1765 | } |
1766 | } |
1767 | #endif |
1768 | for (; i < nData; i++) { |
1769 | #if SHA3_BYTEORDER == 1234 |
1770 | p->u.x[p->nLoaded] ^= aData[i]; |
1771 | #elif SHA3_BYTEORDER == 4321 |
1772 | p->u.x[p->nLoaded ^ 0x07] ^= aData[i]; |
1773 | #else |
1774 | p->u.x[p->nLoaded ^ p->ixMask] ^= aData[i]; |
1775 | #endif |
1776 | p->nLoaded++; |
1777 | if (p->nLoaded == p->nRate) { |
1778 | KeccakF1600Step(p); |
1779 | p->nLoaded = 0; |
1780 | } |
1781 | } |
1782 | } |
1783 | |
1784 | /* |
1785 | ** After all content has been added, invoke SHA3Final() to compute |
1786 | ** the final hash. The function returns a pointer to the binary |
1787 | ** hash value. |
1788 | */ |
1789 | static unsigned char *SHA3Final(SHA3Context *p) { |
1790 | unsigned int i; |
1791 | if (p->nLoaded == p->nRate - 1) { |
1792 | const unsigned char c1 = 0x86; |
1793 | SHA3Update(p, &c1, 1); |
1794 | } else { |
1795 | const unsigned char c2 = 0x06; |
1796 | const unsigned char c3 = 0x80; |
1797 | SHA3Update(p, &c2, 1); |
1798 | p->nLoaded = p->nRate - 1; |
1799 | SHA3Update(p, &c3, 1); |
1800 | } |
1801 | for (i = 0; i < p->nRate; i++) { |
1802 | p->u.x[i + p->nRate] = p->u.x[i ^ p->ixMask]; |
1803 | } |
1804 | return &p->u.x[p->nRate]; |
1805 | } |
1806 | /* End of the hashing logic |
1807 | *****************************************************************************/ |
1808 | |
1809 | /* |
1810 | ** Implementation of the sha3(X,SIZE) function. |
1811 | ** |
1812 | ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default |
1813 | ** size is 256. If X is a BLOB, it is hashed as is. |
1814 | ** For all other non-NULL types of input, X is converted into a UTF-8 string |
1815 | ** and the string is hashed without the trailing 0x00 terminator. The hash |
1816 | ** of a NULL value is NULL. |
1817 | */ |
1818 | static void sha3Func(sqlite3_context *context, int argc, sqlite3_value **argv) { |
1819 | SHA3Context cx; |
1820 | int eType = sqlite3_value_type(argv[0]); |
1821 | int nByte = sqlite3_value_bytes(argv[0]); |
1822 | int iSize; |
1823 | if (argc == 1) { |
1824 | iSize = 256; |
1825 | } else { |
1826 | iSize = sqlite3_value_int(argv[1]); |
1827 | if (iSize != 224 && iSize != 256 && iSize != 384 && iSize != 512) { |
1828 | sqlite3_result_error(context, |
1829 | "SHA3 size should be one of: 224 256 " |
1830 | "384 512" , |
1831 | -1); |
1832 | return; |
1833 | } |
1834 | } |
1835 | if (eType == SQLITE_NULL) |
1836 | return; |
1837 | SHA3Init(&cx, iSize); |
1838 | if (eType == SQLITE_BLOB) { |
1839 | SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte); |
1840 | } else { |
1841 | SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte); |
1842 | } |
1843 | sqlite3_result_blob(context, SHA3Final(&cx), iSize / 8, SQLITE_TRANSIENT); |
1844 | } |
1845 | |
1846 | /* Compute a string using sqlite3_vsnprintf() with a maximum length |
1847 | ** of 50 bytes and add it to the hash. |
1848 | */ |
1849 | static void hash_step_vformat(SHA3Context *p, /* Add content to this context */ |
1850 | const char *zFormat, ...) { |
1851 | va_list ap; |
1852 | int n; |
1853 | char zBuf[50]; |
1854 | va_start(ap, zFormat); |
1855 | sqlite3_vsnprintf(sizeof(zBuf), zBuf, zFormat, ap); |
1856 | va_end(ap); |
1857 | n = (int)strlen(zBuf); |
1858 | SHA3Update(p, (unsigned char *)zBuf, n); |
1859 | } |
1860 | |
1861 | /* |
1862 | ** Implementation of the sha3_query(SQL,SIZE) function. |
1863 | ** |
1864 | ** This function compiles and runs the SQL statement(s) given in the |
1865 | ** argument. The results are hashed using a SIZE-bit SHA3. The default |
1866 | ** size is 256. |
1867 | ** |
1868 | ** The format of the byte stream that is hashed is summarized as follows: |
1869 | ** |
1870 | ** S<n>:<sql> |
1871 | ** R |
1872 | ** N |
1873 | ** I<int> |
1874 | ** F<ieee-float> |
1875 | ** B<size>:<bytes> |
1876 | ** T<size>:<text> |
1877 | ** |
1878 | ** <sql> is the original SQL text for each statement run and <n> is |
1879 | ** the size of that text. The SQL text is UTF-8. A single R character |
1880 | ** occurs before the start of each row. N means a NULL value. |
1881 | ** I mean an 8-byte little-endian integer <int>. F is a floating point |
1882 | ** number with an 8-byte little-endian IEEE floating point value <ieee-float>. |
1883 | ** B means blobs of <size> bytes. T means text rendered as <size> |
1884 | ** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII |
1885 | ** text integers. |
1886 | ** |
1887 | ** For each SQL statement in the X input, there is one S segment. Each |
1888 | ** S segment is followed by zero or more R segments, one for each row in the |
1889 | ** result set. After each R, there are one or more N, I, F, B, or T segments, |
1890 | ** one for each column in the result set. Segments are concatentated directly |
1891 | ** with no delimiters of any kind. |
1892 | */ |
1893 | static void sha3QueryFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { |
1894 | sqlite3 *db = sqlite3_context_db_handle(context); |
1895 | const char *zSql = (const char *)sqlite3_value_text(argv[0]); |
1896 | sqlite3_stmt *pStmt = 0; |
1897 | int nCol; /* Number of columns in the result set */ |
1898 | int i; /* Loop counter */ |
1899 | int rc; |
1900 | int n; |
1901 | const char *z; |
1902 | SHA3Context cx; |
1903 | int iSize; |
1904 | |
1905 | if (argc == 1) { |
1906 | iSize = 256; |
1907 | } else { |
1908 | iSize = sqlite3_value_int(argv[1]); |
1909 | if (iSize != 224 && iSize != 256 && iSize != 384 && iSize != 512) { |
1910 | sqlite3_result_error(context, |
1911 | "SHA3 size should be one of: 224 256 " |
1912 | "384 512" , |
1913 | -1); |
1914 | return; |
1915 | } |
1916 | } |
1917 | if (zSql == 0) |
1918 | return; |
1919 | SHA3Init(&cx, iSize); |
1920 | while (zSql[0]) { |
1921 | rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); |
1922 | if (rc) { |
1923 | char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s" , zSql, sqlite3_errmsg(db)); |
1924 | sqlite3_finalize(pStmt); |
1925 | sqlite3_result_error(context, zMsg, -1); |
1926 | sqlite3_free(zMsg); |
1927 | return; |
1928 | } |
1929 | if (!sqlite3_stmt_readonly(pStmt)) { |
1930 | char *zMsg = sqlite3_mprintf("non-query: [%s]" , sqlite3_sql(pStmt)); |
1931 | sqlite3_finalize(pStmt); |
1932 | sqlite3_result_error(context, zMsg, -1); |
1933 | sqlite3_free(zMsg); |
1934 | return; |
1935 | } |
1936 | nCol = sqlite3_column_count(pStmt); |
1937 | z = sqlite3_sql(pStmt); |
1938 | n = (int)strlen(z); |
1939 | hash_step_vformat(&cx, "S%d:" , n); |
1940 | SHA3Update(&cx, (unsigned char *)z, n); |
1941 | |
1942 | /* Compute a hash over the result of the query */ |
1943 | while (SQLITE_ROW == sqlite3_step(pStmt)) { |
1944 | SHA3Update(&cx, (const unsigned char *)"R" , 1); |
1945 | for (i = 0; i < nCol; i++) { |
1946 | switch (sqlite3_column_type(pStmt, i)) { |
1947 | case SQLITE_NULL: { |
1948 | SHA3Update(&cx, (const unsigned char *)"N" , 1); |
1949 | break; |
1950 | } |
1951 | case SQLITE_INTEGER: { |
1952 | sqlite3_uint64 u; |
1953 | int j; |
1954 | unsigned char x[9]; |
1955 | sqlite3_int64 v = sqlite3_column_int64(pStmt, i); |
1956 | memcpy(&u, &v, 8); |
1957 | for (j = 8; j >= 1; j--) { |
1958 | x[j] = u & 0xff; |
1959 | u >>= 8; |
1960 | } |
1961 | x[0] = 'I'; |
1962 | SHA3Update(&cx, x, 9); |
1963 | break; |
1964 | } |
1965 | case SQLITE_FLOAT: { |
1966 | sqlite3_uint64 u; |
1967 | int j; |
1968 | unsigned char x[9]; |
1969 | double r = sqlite3_column_double(pStmt, i); |
1970 | memcpy(&u, &r, 8); |
1971 | for (j = 8; j >= 1; j--) { |
1972 | x[j] = u & 0xff; |
1973 | u >>= 8; |
1974 | } |
1975 | x[0] = 'F'; |
1976 | SHA3Update(&cx, x, 9); |
1977 | break; |
1978 | } |
1979 | case SQLITE_TEXT: { |
1980 | int n2 = sqlite3_column_bytes(pStmt, i); |
1981 | const unsigned char *z2 = sqlite3_column_text(pStmt, i); |
1982 | hash_step_vformat(&cx, "T%d:" , n2); |
1983 | SHA3Update(&cx, z2, n2); |
1984 | break; |
1985 | } |
1986 | case SQLITE_BLOB: { |
1987 | int n2 = sqlite3_column_bytes(pStmt, i); |
1988 | const unsigned char *z2 = sqlite3_column_blob(pStmt, i); |
1989 | hash_step_vformat(&cx, "B%d:" , n2); |
1990 | SHA3Update(&cx, z2, n2); |
1991 | break; |
1992 | } |
1993 | } |
1994 | } |
1995 | } |
1996 | sqlite3_finalize(pStmt); |
1997 | } |
1998 | sqlite3_result_blob(context, SHA3Final(&cx), iSize / 8, SQLITE_TRANSIENT); |
1999 | } |
2000 | |
2001 | #ifdef _WIN32 |
2002 | |
2003 | #endif |
2004 | int sqlite3_shathree_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { |
2005 | int rc = SQLITE_OK; |
2006 | SQLITE_EXTENSION_INIT2(pApi); |
2007 | (void)pzErrMsg; /* Unused parameter */ |
2008 | rc = sqlite3_create_function(db, "sha3" , 1, SQLITE_UTF8, 0, sha3Func, 0, 0); |
2009 | if (rc == SQLITE_OK) { |
2010 | rc = sqlite3_create_function(db, "sha3" , 2, SQLITE_UTF8, 0, sha3Func, 0, 0); |
2011 | } |
2012 | if (rc == SQLITE_OK) { |
2013 | rc = sqlite3_create_function(db, "sha3_query" , 1, SQLITE_UTF8, 0, sha3QueryFunc, 0, 0); |
2014 | } |
2015 | if (rc == SQLITE_OK) { |
2016 | rc = sqlite3_create_function(db, "sha3_query" , 2, SQLITE_UTF8, 0, sha3QueryFunc, 0, 0); |
2017 | } |
2018 | return rc; |
2019 | } |
2020 | |
2021 | /************************* End ../ext/misc/shathree.c ********************/ |
2022 | /************************* Begin ../ext/misc/fileio.c ******************/ |
2023 | /* |
2024 | ** 2014-06-13 |
2025 | ** |
2026 | ** The author disclaims copyright to this source code. In place of |
2027 | ** a legal notice, here is a blessing: |
2028 | ** |
2029 | ** May you do good and not evil. |
2030 | ** May you find forgiveness for yourself and forgive others. |
2031 | ** May you share freely, never taking more than you give. |
2032 | ** |
2033 | ****************************************************************************** |
2034 | ** |
2035 | ** This SQLite extension implements SQL functions readfile() and |
2036 | ** writefile(), and eponymous virtual type "fsdir". |
2037 | ** |
2038 | ** WRITEFILE(FILE, DATA [, MODE [, MTIME]]): |
2039 | ** |
2040 | ** If neither of the optional arguments is present, then this UDF |
2041 | ** function writes blob DATA to file FILE. If successful, the number |
2042 | ** of bytes written is returned. If an error occurs, NULL is returned. |
2043 | ** |
2044 | ** If the first option argument - MODE - is present, then it must |
2045 | ** be passed an integer value that corresponds to a POSIX mode |
2046 | ** value (file type + permissions, as returned in the stat.st_mode |
2047 | ** field by the stat() system call). Three types of files may |
2048 | ** be written/created: |
2049 | ** |
2050 | ** regular files: (mode & 0170000)==0100000 |
2051 | ** symbolic links: (mode & 0170000)==0120000 |
2052 | ** directories: (mode & 0170000)==0040000 |
2053 | ** |
2054 | ** For a directory, the DATA is ignored. For a symbolic link, it is |
2055 | ** interpreted as text and used as the target of the link. For a |
2056 | ** regular file, it is interpreted as a blob and written into the |
2057 | ** named file. Regardless of the type of file, its permissions are |
2058 | ** set to (mode & 0777) before returning. |
2059 | ** |
2060 | ** If the optional MTIME argument is present, then it is interpreted |
2061 | ** as an integer - the number of seconds since the unix epoch. The |
2062 | ** modification-time of the target file is set to this value before |
2063 | ** returning. |
2064 | ** |
2065 | ** If three or more arguments are passed to this function and an |
2066 | ** error is encountered, an exception is raised. |
2067 | ** |
2068 | ** READFILE(FILE): |
2069 | ** |
2070 | ** Read and return the contents of file FILE (type blob) from disk. |
2071 | ** |
2072 | ** FSDIR: |
2073 | ** |
2074 | ** Used as follows: |
2075 | ** |
2076 | ** SELECT * FROM fsdir($path [, $dir]); |
2077 | ** |
2078 | ** Parameter $path is an absolute or relative pathname. If the file that it |
2079 | ** refers to does not exist, it is an error. If the path refers to a regular |
2080 | ** file or symbolic link, it returns a single row. Or, if the path refers |
2081 | ** to a directory, it returns one row for the directory, and one row for each |
2082 | ** file within the hierarchy rooted at $path. |
2083 | ** |
2084 | ** Each row has the following columns: |
2085 | ** |
2086 | ** name: Path to file or directory (text value). |
2087 | ** mode: Value of stat.st_mode for directory entry (an integer). |
2088 | ** mtime: Value of stat.st_mtime for directory entry (an integer). |
2089 | ** data: For a regular file, a blob containing the file data. For a |
2090 | ** symlink, a text value containing the text of the link. For a |
2091 | ** directory, NULL. |
2092 | ** |
2093 | ** If a non-NULL value is specified for the optional $dir parameter and |
2094 | ** $path is a relative path, then $path is interpreted relative to $dir. |
2095 | ** And the paths returned in the "name" column of the table are also |
2096 | ** relative to directory $dir. |
2097 | */ |
2098 | SQLITE_EXTENSION_INIT1 |
2099 | #include <stdio.h> |
2100 | #include <string.h> |
2101 | #include <assert.h> |
2102 | |
2103 | #include <sys/types.h> |
2104 | #include <sys/stat.h> |
2105 | #include <fcntl.h> |
2106 | #if !defined(_WIN32) && !defined(WIN32) |
2107 | #include <unistd.h> |
2108 | #include <dirent.h> |
2109 | #include <utime.h> |
2110 | #include <sys/time.h> |
2111 | #else |
2112 | #include "windows.h" |
2113 | #include <io.h> |
2114 | #include <direct.h> |
2115 | /* # include "test_windirent.h" */ |
2116 | #define dirent DIRENT |
2117 | #ifndef chmod |
2118 | #define chmod _chmod |
2119 | #endif |
2120 | #ifndef stat |
2121 | #define stat _stat |
2122 | #endif |
2123 | #define mkdir(path, mode) _mkdir(path) |
2124 | #define lstat(path, buf) stat(path, buf) |
2125 | #endif |
2126 | #include <time.h> |
2127 | #include <errno.h> |
2128 | |
2129 | #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)" |
2130 | |
2131 | /* |
2132 | ** Set the result stored by context ctx to a blob containing the |
2133 | ** contents of file zName. |
2134 | */ |
2135 | static void readFileContents(sqlite3_context *ctx, const char *zName) { |
2136 | FILE *in; |
2137 | long nIn; |
2138 | void *pBuf; |
2139 | |
2140 | in = fopen(zName, "rb" ); |
2141 | if (in == 0) |
2142 | return; |
2143 | fseek(in, 0, SEEK_END); |
2144 | nIn = ftell(in); |
2145 | rewind(in); |
2146 | pBuf = sqlite3_malloc(nIn); |
2147 | if (pBuf && 1 == fread(pBuf, nIn, 1, in)) { |
2148 | sqlite3_result_blob(ctx, pBuf, nIn, sqlite3_free); |
2149 | } else { |
2150 | sqlite3_free(pBuf); |
2151 | } |
2152 | fclose(in); |
2153 | } |
2154 | |
2155 | /* |
2156 | ** Implementation of the "readfile(X)" SQL function. The entire content |
2157 | ** of the file named X is read and returned as a BLOB. NULL is returned |
2158 | ** if the file does not exist or is unreadable. |
2159 | */ |
2160 | static void readfileFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { |
2161 | const char *zName; |
2162 | (void)(argc); /* Unused parameter */ |
2163 | zName = (const char *)sqlite3_value_text(argv[0]); |
2164 | if (zName == 0) |
2165 | return; |
2166 | readFileContents(context, zName); |
2167 | } |
2168 | |
2169 | /* |
2170 | ** Set the error message contained in context ctx to the results of |
2171 | ** vprintf(zFmt, ...). |
2172 | */ |
2173 | static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...) { |
2174 | char *zMsg = 0; |
2175 | va_list ap; |
2176 | va_start(ap, zFmt); |
2177 | zMsg = sqlite3_vmprintf(zFmt, ap); |
2178 | sqlite3_result_error(ctx, zMsg, -1); |
2179 | sqlite3_free(zMsg); |
2180 | va_end(ap); |
2181 | } |
2182 | |
2183 | #if defined(_WIN32) |
2184 | /* |
2185 | ** This function is designed to convert a Win32 FILETIME structure into the |
2186 | ** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC). |
2187 | */ |
2188 | static sqlite3_uint64 fileTimeToUnixTime(LPFILETIME pFileTime) { |
2189 | SYSTEMTIME epochSystemTime; |
2190 | ULARGE_INTEGER epochIntervals; |
2191 | FILETIME epochFileTime; |
2192 | ULARGE_INTEGER fileIntervals; |
2193 | |
2194 | memset(&epochSystemTime, 0, sizeof(SYSTEMTIME)); |
2195 | epochSystemTime.wYear = 1970; |
2196 | epochSystemTime.wMonth = 1; |
2197 | epochSystemTime.wDay = 1; |
2198 | SystemTimeToFileTime(&epochSystemTime, &epochFileTime); |
2199 | epochIntervals.LowPart = epochFileTime.dwLowDateTime; |
2200 | epochIntervals.HighPart = epochFileTime.dwHighDateTime; |
2201 | |
2202 | fileIntervals.LowPart = pFileTime->dwLowDateTime; |
2203 | fileIntervals.HighPart = pFileTime->dwHighDateTime; |
2204 | |
2205 | return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000; |
2206 | } |
2207 | |
2208 | /* |
2209 | ** This function attempts to normalize the time values found in the stat() |
2210 | ** buffer to UTC. This is necessary on Win32, where the runtime library |
2211 | ** appears to return these values as local times. |
2212 | */ |
2213 | static void statTimesToUtc(const char *zPath, struct stat *pStatBuf) { |
2214 | HANDLE hFindFile; |
2215 | WIN32_FIND_DATAW fd; |
2216 | LPWSTR zUnicodeName; |
2217 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *); |
2218 | zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath); |
2219 | if (zUnicodeName) { |
2220 | memset(&fd, 0, sizeof(WIN32_FIND_DATA)); |
2221 | hFindFile = FindFirstFileW(zUnicodeName, &fd); |
2222 | if (hFindFile != NULL) { |
2223 | pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime); |
2224 | pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime); |
2225 | pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime); |
2226 | FindClose(hFindFile); |
2227 | } |
2228 | sqlite3_free(zUnicodeName); |
2229 | } |
2230 | } |
2231 | #endif |
2232 | |
2233 | /* |
2234 | ** This function is used in place of stat(). On Windows, special handling |
2235 | ** is required in order for the included time to be returned as UTC. On all |
2236 | ** other systems, this function simply calls stat(). |
2237 | */ |
2238 | static int fileStat(const char *zPath, struct stat *pStatBuf) { |
2239 | #if defined(_WIN32) |
2240 | int rc = stat(zPath, pStatBuf); |
2241 | if (rc == 0) |
2242 | statTimesToUtc(zPath, pStatBuf); |
2243 | return rc; |
2244 | #else |
2245 | return stat(zPath, pStatBuf); |
2246 | #endif |
2247 | } |
2248 | |
2249 | /* |
2250 | ** This function is used in place of lstat(). On Windows, special handling |
2251 | ** is required in order for the included time to be returned as UTC. On all |
2252 | ** other systems, this function simply calls lstat(). |
2253 | */ |
2254 | static int fileLinkStat(const char *zPath, struct stat *pStatBuf) { |
2255 | #if defined(_WIN32) |
2256 | int rc = lstat(zPath, pStatBuf); |
2257 | if (rc == 0) |
2258 | statTimesToUtc(zPath, pStatBuf); |
2259 | return rc; |
2260 | #else |
2261 | return lstat(zPath, pStatBuf); |
2262 | #endif |
2263 | } |
2264 | |
2265 | /* |
2266 | ** Argument zFile is the name of a file that will be created and/or written |
2267 | ** by SQL function writefile(). This function ensures that the directory |
2268 | ** zFile will be written to exists, creating it if required. The permissions |
2269 | ** for any path components created by this function are set to (mode&0777). |
2270 | ** |
2271 | ** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise, |
2272 | ** SQLITE_OK is returned if the directory is successfully created, or |
2273 | ** SQLITE_ERROR otherwise. |
2274 | */ |
2275 | static int makeDirectory(const char *zFile, mode_t mode) { |
2276 | char *zCopy = sqlite3_mprintf("%s" , zFile); |
2277 | int rc = SQLITE_OK; |
2278 | |
2279 | if (zCopy == 0) { |
2280 | rc = SQLITE_NOMEM; |
2281 | } else { |
2282 | int nCopy = (int)strlen(zCopy); |
2283 | int i = 1; |
2284 | |
2285 | while (rc == SQLITE_OK) { |
2286 | struct stat sStat; |
2287 | int rc2; |
2288 | |
2289 | for (; zCopy[i] != '/' && i < nCopy; i++) |
2290 | ; |
2291 | if (i == nCopy) |
2292 | break; |
2293 | zCopy[i] = '\0'; |
2294 | |
2295 | rc2 = fileStat(zCopy, &sStat); |
2296 | if (rc2 != 0) { |
2297 | if (mkdir(zCopy, mode & 0777)) |
2298 | rc = SQLITE_ERROR; |
2299 | } else { |
2300 | if (!S_ISDIR(sStat.st_mode)) |
2301 | rc = SQLITE_ERROR; |
2302 | } |
2303 | zCopy[i] = '/'; |
2304 | i++; |
2305 | } |
2306 | |
2307 | sqlite3_free(zCopy); |
2308 | } |
2309 | |
2310 | return rc; |
2311 | } |
2312 | |
2313 | /* |
2314 | ** This function does the work for the writefile() UDF. Refer to |
2315 | ** header comments at the top of this file for details. |
2316 | */ |
2317 | static int writeFile(sqlite3_context *pCtx, /* Context to return bytes written in */ |
2318 | const char *zFile, /* File to write */ |
2319 | sqlite3_value *pData, /* Data to write */ |
2320 | mode_t mode, /* MODE parameter passed to writefile() */ |
2321 | sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */ |
2322 | ) { |
2323 | #if !defined(_WIN32) && !defined(WIN32) |
2324 | if (S_ISLNK(mode)) { |
2325 | const char *zTo = (const char *)sqlite3_value_text(pData); |
2326 | if (symlink(zTo, zFile) < 0) |
2327 | return 1; |
2328 | } else |
2329 | #endif |
2330 | { |
2331 | if (S_ISDIR(mode)) { |
2332 | if (mkdir(zFile, mode)) { |
2333 | /* The mkdir() call to create the directory failed. This might not |
2334 | ** be an error though - if there is already a directory at the same |
2335 | ** path and either the permissions already match or can be changed |
2336 | ** to do so using chmod(), it is not an error. */ |
2337 | struct stat sStat; |
2338 | if (errno != EEXIST || 0 != fileStat(zFile, &sStat) || !S_ISDIR(sStat.st_mode) || |
2339 | ((sStat.st_mode & 0777) != (mode & 0777) && 0 != chmod(zFile, mode & 0777))) { |
2340 | return 1; |
2341 | } |
2342 | } |
2343 | } else { |
2344 | sqlite3_int64 nWrite = 0; |
2345 | const char *z; |
2346 | int rc = 0; |
2347 | FILE *out = fopen(zFile, "wb" ); |
2348 | if (out == 0) |
2349 | return 1; |
2350 | z = (const char *)sqlite3_value_blob(pData); |
2351 | if (z) { |
2352 | sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out); |
2353 | nWrite = sqlite3_value_bytes(pData); |
2354 | if (nWrite != n) { |
2355 | rc = 1; |
2356 | } |
2357 | } |
2358 | fclose(out); |
2359 | if (rc == 0 && mode && chmod(zFile, mode & 0777)) { |
2360 | rc = 1; |
2361 | } |
2362 | if (rc) |
2363 | return 2; |
2364 | sqlite3_result_int64(pCtx, nWrite); |
2365 | } |
2366 | } |
2367 | |
2368 | if (mtime >= 0) { |
2369 | #if defined(_WIN32) |
2370 | /* Windows */ |
2371 | FILETIME lastAccess; |
2372 | FILETIME lastWrite; |
2373 | SYSTEMTIME currentTime; |
2374 | LONGLONG intervals; |
2375 | HANDLE hFile; |
2376 | LPWSTR zUnicodeName; |
2377 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *); |
2378 | |
2379 | GetSystemTime(¤tTime); |
2380 | SystemTimeToFileTime(¤tTime, &lastAccess); |
2381 | intervals = Int32x32To64(mtime, 10000000) + 116444736000000000; |
2382 | lastWrite.dwLowDateTime = (DWORD)intervals; |
2383 | lastWrite.dwHighDateTime = intervals >> 32; |
2384 | zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); |
2385 | if (zUnicodeName == 0) { |
2386 | return 1; |
2387 | } |
2388 | hFile = |
2389 | CreateFileW(zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
2390 | sqlite3_free(zUnicodeName); |
2391 | if (hFile != INVALID_HANDLE_VALUE) { |
2392 | BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite); |
2393 | CloseHandle(hFile); |
2394 | return !bResult; |
2395 | } else { |
2396 | return 1; |
2397 | } |
2398 | #elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */ |
2399 | /* Recent unix */ |
2400 | struct timespec times[2]; |
2401 | times[0].tv_nsec = times[1].tv_nsec = 0; |
2402 | times[0].tv_sec = time(0); |
2403 | times[1].tv_sec = mtime; |
2404 | if (utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW)) { |
2405 | return 1; |
2406 | } |
2407 | #else |
2408 | /* Legacy unix */ |
2409 | struct timeval times[2]; |
2410 | times[0].tv_usec = times[1].tv_usec = 0; |
2411 | times[0].tv_sec = time(0); |
2412 | times[1].tv_sec = mtime; |
2413 | if (utimes(zFile, times)) { |
2414 | return 1; |
2415 | } |
2416 | #endif |
2417 | } |
2418 | |
2419 | return 0; |
2420 | } |
2421 | |
2422 | /* |
2423 | ** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. |
2424 | ** Refer to header comments at the top of this file for details. |
2425 | */ |
2426 | static void writefileFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { |
2427 | const char *zFile; |
2428 | mode_t mode = 0; |
2429 | int res; |
2430 | sqlite3_int64 mtime = -1; |
2431 | |
2432 | if (argc < 2 || argc > 4) { |
2433 | sqlite3_result_error(context, "wrong number of arguments to function writefile()" , -1); |
2434 | return; |
2435 | } |
2436 | |
2437 | zFile = (const char *)sqlite3_value_text(argv[0]); |
2438 | if (zFile == 0) |
2439 | return; |
2440 | if (argc >= 3) { |
2441 | mode = (mode_t)sqlite3_value_int(argv[2]); |
2442 | } |
2443 | if (argc == 4) { |
2444 | mtime = sqlite3_value_int64(argv[3]); |
2445 | } |
2446 | |
2447 | res = writeFile(context, zFile, argv[1], mode, mtime); |
2448 | if (res == 1 && errno == ENOENT) { |
2449 | if (makeDirectory(zFile, mode) == SQLITE_OK) { |
2450 | res = writeFile(context, zFile, argv[1], mode, mtime); |
2451 | } |
2452 | } |
2453 | |
2454 | if (argc > 2 && res != 0) { |
2455 | if (S_ISLNK(mode)) { |
2456 | ctxErrorMsg(context, "failed to create symlink: %s" , zFile); |
2457 | } else if (S_ISDIR(mode)) { |
2458 | ctxErrorMsg(context, "failed to create directory: %s" , zFile); |
2459 | } else { |
2460 | ctxErrorMsg(context, "failed to write file: %s" , zFile); |
2461 | } |
2462 | } |
2463 | } |
2464 | |
2465 | /* |
2466 | ** SQL function: lsmode(MODE) |
2467 | ** |
2468 | ** Given a numberic st_mode from stat(), convert it into a human-readable |
2469 | ** text string in the style of "ls -l". |
2470 | */ |
2471 | static void lsModeFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { |
2472 | int i; |
2473 | int iMode = sqlite3_value_int(argv[0]); |
2474 | char z[16]; |
2475 | (void)argc; |
2476 | if (S_ISLNK(iMode)) { |
2477 | z[0] = 'l'; |
2478 | } else if (S_ISREG(iMode)) { |
2479 | z[0] = '-'; |
2480 | } else if (S_ISDIR(iMode)) { |
2481 | z[0] = 'd'; |
2482 | } else { |
2483 | z[0] = '?'; |
2484 | } |
2485 | for (i = 0; i < 3; i++) { |
2486 | int m = (iMode >> ((2 - i) * 3)); |
2487 | char *a = &z[1 + i * 3]; |
2488 | a[0] = (m & 0x4) ? 'r' : '-'; |
2489 | a[1] = (m & 0x2) ? 'w' : '-'; |
2490 | a[2] = (m & 0x1) ? 'x' : '-'; |
2491 | } |
2492 | z[10] = '\0'; |
2493 | sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); |
2494 | } |
2495 | |
2496 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
2497 | |
2498 | /* |
2499 | ** Cursor type for recursively iterating through a directory structure. |
2500 | */ |
2501 | typedef struct fsdir_cursor fsdir_cursor; |
2502 | typedef struct FsdirLevel FsdirLevel; |
2503 | |
2504 | struct FsdirLevel { |
2505 | DIR *pDir; /* From opendir() */ |
2506 | char *zDir; /* Name of directory (nul-terminated) */ |
2507 | }; |
2508 | |
2509 | struct fsdir_cursor { |
2510 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
2511 | |
2512 | int nLvl; /* Number of entries in aLvl[] array */ |
2513 | int iLvl; /* Index of current entry */ |
2514 | FsdirLevel *aLvl; /* Hierarchy of directories being traversed */ |
2515 | |
2516 | const char *zBase; |
2517 | int nBase; |
2518 | |
2519 | struct stat sStat; /* Current lstat() results */ |
2520 | char *zPath; /* Path to current entry */ |
2521 | sqlite3_int64 iRowid; /* Current rowid */ |
2522 | }; |
2523 | |
2524 | typedef struct fsdir_tab fsdir_tab; |
2525 | struct fsdir_tab { |
2526 | sqlite3_vtab base; /* Base class - must be first */ |
2527 | }; |
2528 | |
2529 | /* |
2530 | ** Construct a new fsdir virtual table object. |
2531 | */ |
2532 | static int fsdirConnect(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, |
2533 | char **pzErr) { |
2534 | fsdir_tab *pNew = 0; |
2535 | int rc; |
2536 | (void)pAux; |
2537 | (void)argc; |
2538 | (void)argv; |
2539 | (void)pzErr; |
2540 | rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA); |
2541 | if (rc == SQLITE_OK) { |
2542 | pNew = (fsdir_tab *)sqlite3_malloc(sizeof(*pNew)); |
2543 | if (pNew == 0) |
2544 | return SQLITE_NOMEM; |
2545 | memset(pNew, 0, sizeof(*pNew)); |
2546 | } |
2547 | *ppVtab = (sqlite3_vtab *)pNew; |
2548 | return rc; |
2549 | } |
2550 | |
2551 | /* |
2552 | ** This method is the destructor for fsdir vtab objects. |
2553 | */ |
2554 | static int fsdirDisconnect(sqlite3_vtab *pVtab) { |
2555 | sqlite3_free(pVtab); |
2556 | return SQLITE_OK; |
2557 | } |
2558 | |
2559 | /* |
2560 | ** Constructor for a new fsdir_cursor object. |
2561 | */ |
2562 | static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor) { |
2563 | fsdir_cursor *pCur; |
2564 | (void)p; |
2565 | pCur = sqlite3_malloc(sizeof(*pCur)); |
2566 | if (pCur == 0) |
2567 | return SQLITE_NOMEM; |
2568 | memset(pCur, 0, sizeof(*pCur)); |
2569 | pCur->iLvl = -1; |
2570 | *ppCursor = &pCur->base; |
2571 | return SQLITE_OK; |
2572 | } |
2573 | |
2574 | /* |
2575 | ** Reset a cursor back to the state it was in when first returned |
2576 | ** by fsdirOpen(). |
2577 | */ |
2578 | static void fsdirResetCursor(fsdir_cursor *pCur) { |
2579 | int i; |
2580 | for (i = 0; i <= pCur->iLvl; i++) { |
2581 | FsdirLevel *pLvl = &pCur->aLvl[i]; |
2582 | if (pLvl->pDir) |
2583 | closedir(pLvl->pDir); |
2584 | sqlite3_free(pLvl->zDir); |
2585 | } |
2586 | sqlite3_free(pCur->zPath); |
2587 | sqlite3_free(pCur->aLvl); |
2588 | pCur->aLvl = 0; |
2589 | pCur->zPath = 0; |
2590 | pCur->zBase = 0; |
2591 | pCur->nBase = 0; |
2592 | pCur->nLvl = 0; |
2593 | pCur->iLvl = -1; |
2594 | pCur->iRowid = 1; |
2595 | } |
2596 | |
2597 | /* |
2598 | ** Destructor for an fsdir_cursor. |
2599 | */ |
2600 | static int fsdirClose(sqlite3_vtab_cursor *cur) { |
2601 | fsdir_cursor *pCur = (fsdir_cursor *)cur; |
2602 | |
2603 | fsdirResetCursor(pCur); |
2604 | sqlite3_free(pCur); |
2605 | return SQLITE_OK; |
2606 | } |
2607 | |
2608 | /* |
2609 | ** Set the error message for the virtual table associated with cursor |
2610 | ** pCur to the results of vprintf(zFmt, ...). |
2611 | */ |
2612 | static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...) { |
2613 | va_list ap; |
2614 | va_start(ap, zFmt); |
2615 | pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); |
2616 | va_end(ap); |
2617 | } |
2618 | |
2619 | /* |
2620 | ** Advance an fsdir_cursor to its next row of output. |
2621 | */ |
2622 | static int fsdirNext(sqlite3_vtab_cursor *cur) { |
2623 | fsdir_cursor *pCur = (fsdir_cursor *)cur; |
2624 | mode_t m = pCur->sStat.st_mode; |
2625 | |
2626 | pCur->iRowid++; |
2627 | if (S_ISDIR(m)) { |
2628 | /* Descend into this directory */ |
2629 | int iNew = pCur->iLvl + 1; |
2630 | FsdirLevel *pLvl; |
2631 | if (iNew >= pCur->nLvl) { |
2632 | int nNew = iNew + 1; |
2633 | int nByte = nNew * sizeof(FsdirLevel); |
2634 | FsdirLevel *aNew = (FsdirLevel *)sqlite3_realloc(pCur->aLvl, nByte); |
2635 | if (aNew == 0) |
2636 | return SQLITE_NOMEM; |
2637 | memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel) * (nNew - pCur->nLvl)); |
2638 | pCur->aLvl = aNew; |
2639 | pCur->nLvl = nNew; |
2640 | } |
2641 | pCur->iLvl = iNew; |
2642 | pLvl = &pCur->aLvl[iNew]; |
2643 | |
2644 | pLvl->zDir = pCur->zPath; |
2645 | pCur->zPath = 0; |
2646 | pLvl->pDir = opendir(pLvl->zDir); |
2647 | if (pLvl->pDir == 0) { |
2648 | fsdirSetErrmsg(pCur, "cannot read directory: %s" , pCur->zPath); |
2649 | return SQLITE_ERROR; |
2650 | } |
2651 | } |
2652 | |
2653 | while (pCur->iLvl >= 0) { |
2654 | FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl]; |
2655 | struct dirent *pEntry = readdir(pLvl->pDir); |
2656 | if (pEntry) { |
2657 | if (pEntry->d_name[0] == '.') { |
2658 | if (pEntry->d_name[1] == '.' && pEntry->d_name[2] == '\0') |
2659 | continue; |
2660 | if (pEntry->d_name[1] == '\0') |
2661 | continue; |
2662 | } |
2663 | sqlite3_free(pCur->zPath); |
2664 | pCur->zPath = sqlite3_mprintf("%s/%s" , pLvl->zDir, pEntry->d_name); |
2665 | if (pCur->zPath == 0) |
2666 | return SQLITE_NOMEM; |
2667 | if (fileLinkStat(pCur->zPath, &pCur->sStat)) { |
2668 | fsdirSetErrmsg(pCur, "cannot stat file: %s" , pCur->zPath); |
2669 | return SQLITE_ERROR; |
2670 | } |
2671 | return SQLITE_OK; |
2672 | } |
2673 | closedir(pLvl->pDir); |
2674 | sqlite3_free(pLvl->zDir); |
2675 | pLvl->pDir = 0; |
2676 | pLvl->zDir = 0; |
2677 | pCur->iLvl--; |
2678 | } |
2679 | |
2680 | /* EOF */ |
2681 | sqlite3_free(pCur->zPath); |
2682 | pCur->zPath = 0; |
2683 | return SQLITE_OK; |
2684 | } |
2685 | |
2686 | /* |
2687 | ** Return values of columns for the row at which the series_cursor |
2688 | ** is currently pointing. |
2689 | */ |
2690 | static int fsdirColumn(sqlite3_vtab_cursor *cur, /* The cursor */ |
2691 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
2692 | int i /* Which column to return */ |
2693 | ) { |
2694 | fsdir_cursor *pCur = (fsdir_cursor *)cur; |
2695 | switch (i) { |
2696 | case 0: { /* name */ |
2697 | sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT); |
2698 | break; |
2699 | } |
2700 | |
2701 | case 1: /* mode */ |
2702 | sqlite3_result_int64(ctx, pCur->sStat.st_mode); |
2703 | break; |
2704 | |
2705 | case 2: /* mtime */ |
2706 | sqlite3_result_int64(ctx, pCur->sStat.st_mtime); |
2707 | break; |
2708 | |
2709 | case 3: { /* data */ |
2710 | mode_t m = pCur->sStat.st_mode; |
2711 | if (S_ISDIR(m)) { |
2712 | sqlite3_result_null(ctx); |
2713 | #if !defined(_WIN32) && !defined(WIN32) |
2714 | } else if (S_ISLNK(m)) { |
2715 | char aStatic[64]; |
2716 | char *aBuf = aStatic; |
2717 | int nBuf = 64; |
2718 | int n; |
2719 | |
2720 | while (1) { |
2721 | n = readlink(pCur->zPath, aBuf, nBuf); |
2722 | if (n < nBuf) |
2723 | break; |
2724 | if (aBuf != aStatic) |
2725 | sqlite3_free(aBuf); |
2726 | nBuf = nBuf * 2; |
2727 | aBuf = sqlite3_malloc(nBuf); |
2728 | if (aBuf == 0) { |
2729 | sqlite3_result_error_nomem(ctx); |
2730 | return SQLITE_NOMEM; |
2731 | } |
2732 | } |
2733 | |
2734 | sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT); |
2735 | if (aBuf != aStatic) |
2736 | sqlite3_free(aBuf); |
2737 | #endif |
2738 | } else { |
2739 | readFileContents(ctx, pCur->zPath); |
2740 | } |
2741 | } |
2742 | } |
2743 | return SQLITE_OK; |
2744 | } |
2745 | |
2746 | /* |
2747 | ** Return the rowid for the current row. In this implementation, the |
2748 | ** first row returned is assigned rowid value 1, and each subsequent |
2749 | ** row a value 1 more than that of the previous. |
2750 | */ |
2751 | static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid) { |
2752 | fsdir_cursor *pCur = (fsdir_cursor *)cur; |
2753 | *pRowid = pCur->iRowid; |
2754 | return SQLITE_OK; |
2755 | } |
2756 | |
2757 | /* |
2758 | ** Return TRUE if the cursor has been moved off of the last |
2759 | ** row of output. |
2760 | */ |
2761 | static int fsdirEof(sqlite3_vtab_cursor *cur) { |
2762 | fsdir_cursor *pCur = (fsdir_cursor *)cur; |
2763 | return (pCur->zPath == 0); |
2764 | } |
2765 | |
2766 | /* |
2767 | ** xFilter callback. |
2768 | */ |
2769 | static int fsdirFilter(sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) { |
2770 | const char *zDir = 0; |
2771 | fsdir_cursor *pCur = (fsdir_cursor *)cur; |
2772 | (void)idxStr; |
2773 | fsdirResetCursor(pCur); |
2774 | |
2775 | if (idxNum == 0) { |
2776 | fsdirSetErrmsg(pCur, "table function fsdir requires an argument" ); |
2777 | return SQLITE_ERROR; |
2778 | } |
2779 | |
2780 | assert(argc == idxNum && (argc == 1 || argc == 2)); |
2781 | zDir = (const char *)sqlite3_value_text(argv[0]); |
2782 | if (zDir == 0) { |
2783 | fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument" ); |
2784 | return SQLITE_ERROR; |
2785 | } |
2786 | if (argc == 2) { |
2787 | pCur->zBase = (const char *)sqlite3_value_text(argv[1]); |
2788 | } |
2789 | if (pCur->zBase) { |
2790 | pCur->nBase = (int)strlen(pCur->zBase) + 1; |
2791 | pCur->zPath = sqlite3_mprintf("%s/%s" , pCur->zBase, zDir); |
2792 | } else { |
2793 | pCur->zPath = sqlite3_mprintf("%s" , zDir); |
2794 | } |
2795 | |
2796 | if (pCur->zPath == 0) { |
2797 | return SQLITE_NOMEM; |
2798 | } |
2799 | if (fileLinkStat(pCur->zPath, &pCur->sStat)) { |
2800 | fsdirSetErrmsg(pCur, "cannot stat file: %s" , pCur->zPath); |
2801 | return SQLITE_ERROR; |
2802 | } |
2803 | |
2804 | return SQLITE_OK; |
2805 | } |
2806 | |
2807 | /* |
2808 | ** SQLite will invoke this method one or more times while planning a query |
2809 | ** that uses the generate_series virtual table. This routine needs to create |
2810 | ** a query plan for each invocation and compute an estimated cost for that |
2811 | ** plan. |
2812 | ** |
2813 | ** In this implementation idxNum is used to represent the |
2814 | ** query plan. idxStr is unused. |
2815 | ** |
2816 | ** The query plan is represented by bits in idxNum: |
2817 | ** |
2818 | ** (1) start = $value -- constraint exists |
2819 | ** (2) stop = $value -- constraint exists |
2820 | ** (4) step = $value -- constraint exists |
2821 | ** (8) output in descending order |
2822 | */ |
2823 | static int fsdirBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo) { |
2824 | int i; /* Loop over constraints */ |
2825 | int idx4 = -1; |
2826 | int idx5 = -1; |
2827 | const struct sqlite3_index_constraint *pConstraint; |
2828 | |
2829 | (void)tab; |
2830 | pConstraint = pIdxInfo->aConstraint; |
2831 | for (i = 0; i < pIdxInfo->nConstraint; i++, pConstraint++) { |
2832 | if (pConstraint->usable == 0) |
2833 | continue; |
2834 | if (pConstraint->op != SQLITE_INDEX_CONSTRAINT_EQ) |
2835 | continue; |
2836 | if (pConstraint->iColumn == 4) |
2837 | idx4 = i; |
2838 | if (pConstraint->iColumn == 5) |
2839 | idx5 = i; |
2840 | } |
2841 | |
2842 | if (idx4 < 0) { |
2843 | pIdxInfo->idxNum = 0; |
2844 | pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50); |
2845 | } else { |
2846 | pIdxInfo->aConstraintUsage[idx4].omit = 1; |
2847 | pIdxInfo->aConstraintUsage[idx4].argvIndex = 1; |
2848 | if (idx5 >= 0) { |
2849 | pIdxInfo->aConstraintUsage[idx5].omit = 1; |
2850 | pIdxInfo->aConstraintUsage[idx5].argvIndex = 2; |
2851 | pIdxInfo->idxNum = 2; |
2852 | pIdxInfo->estimatedCost = 10.0; |
2853 | } else { |
2854 | pIdxInfo->idxNum = 1; |
2855 | pIdxInfo->estimatedCost = 100.0; |
2856 | } |
2857 | } |
2858 | |
2859 | return SQLITE_OK; |
2860 | } |
2861 | |
2862 | /* |
2863 | ** Register the "fsdir" virtual table. |
2864 | */ |
2865 | static int fsdirRegister(sqlite3 *db) { |
2866 | static sqlite3_module fsdirModule = { |
2867 | 0, /* iVersion */ |
2868 | 0, /* xCreate */ |
2869 | fsdirConnect, /* xConnect */ |
2870 | fsdirBestIndex, /* xBestIndex */ |
2871 | fsdirDisconnect, /* xDisconnect */ |
2872 | 0, /* xDestroy */ |
2873 | fsdirOpen, /* xOpen - open a cursor */ |
2874 | fsdirClose, /* xClose - close a cursor */ |
2875 | fsdirFilter, /* xFilter - configure scan constraints */ |
2876 | fsdirNext, /* xNext - advance a cursor */ |
2877 | fsdirEof, /* xEof - check for end of scan */ |
2878 | fsdirColumn, /* xColumn - read data */ |
2879 | fsdirRowid, /* xRowid - read data */ |
2880 | 0, /* xUpdate */ |
2881 | 0, /* xBegin */ |
2882 | 0, /* xSync */ |
2883 | 0, /* xCommit */ |
2884 | 0, /* xRollback */ |
2885 | 0, /* xFindMethod */ |
2886 | 0, /* xRename */ |
2887 | 0, /* xSavepoint */ |
2888 | 0, /* xRelease */ |
2889 | 0 /* xRollbackTo */ |
2890 | }; |
2891 | |
2892 | int rc = sqlite3_create_module(db, "fsdir" , &fsdirModule, 0); |
2893 | return rc; |
2894 | } |
2895 | #else /* SQLITE_OMIT_VIRTUALTABLE */ |
2896 | #define fsdirRegister(x) SQLITE_OK |
2897 | #endif |
2898 | |
2899 | #ifdef _WIN32 |
2900 | |
2901 | #endif |
2902 | int sqlite3_fileio_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { |
2903 | int rc = SQLITE_OK; |
2904 | SQLITE_EXTENSION_INIT2(pApi); |
2905 | (void)pzErrMsg; /* Unused parameter */ |
2906 | rc = sqlite3_create_function(db, "readfile" , 1, SQLITE_UTF8, 0, readfileFunc, 0, 0); |
2907 | if (rc == SQLITE_OK) { |
2908 | rc = sqlite3_create_function(db, "writefile" , -1, SQLITE_UTF8, 0, writefileFunc, 0, 0); |
2909 | } |
2910 | if (rc == SQLITE_OK) { |
2911 | rc = sqlite3_create_function(db, "lsmode" , 1, SQLITE_UTF8, 0, lsModeFunc, 0, 0); |
2912 | } |
2913 | if (rc == SQLITE_OK) { |
2914 | rc = fsdirRegister(db); |
2915 | } |
2916 | return rc; |
2917 | } |
2918 | |
2919 | /************************* End ../ext/misc/fileio.c ********************/ |
2920 | /************************* Begin ../ext/misc/completion.c ******************/ |
2921 | /* |
2922 | ** 2017-07-10 |
2923 | ** |
2924 | ** The author disclaims copyright to this source code. In place of |
2925 | ** a legal notice, here is a blessing: |
2926 | ** |
2927 | ** May you do good and not evil. |
2928 | ** May you find forgiveness for yourself and forgive others. |
2929 | ** May you share freely, never taking more than you give. |
2930 | ** |
2931 | ************************************************************************* |
2932 | ** |
2933 | ** This file implements an eponymous virtual table that returns suggested |
2934 | ** completions for a partial SQL input. |
2935 | ** |
2936 | ** Suggested usage: |
2937 | ** |
2938 | ** SELECT DISTINCT candidate COLLATE nocase |
2939 | ** FROM completion($prefix,$wholeline) |
2940 | ** ORDER BY 1; |
2941 | ** |
2942 | ** The two query parameters are optional. $prefix is the text of the |
2943 | ** current word being typed and that is to be completed. $wholeline is |
2944 | ** the complete input line, used for context. |
2945 | ** |
2946 | ** The raw completion() table might return the same candidate multiple |
2947 | ** times, for example if the same column name is used to two or more |
2948 | ** tables. And the candidates are returned in an arbitrary order. Hence, |
2949 | ** the DISTINCT and ORDER BY are recommended. |
2950 | ** |
2951 | ** This virtual table operates at the speed of human typing, and so there |
2952 | ** is no attempt to make it fast. Even a slow implementation will be much |
2953 | ** faster than any human can type. |
2954 | ** |
2955 | */ |
2956 | SQLITE_EXTENSION_INIT1 |
2957 | #include <assert.h> |
2958 | #include <string.h> |
2959 | #include <ctype.h> |
2960 | |
2961 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
2962 | |
2963 | /* completion_vtab is a subclass of sqlite3_vtab which will |
2964 | ** serve as the underlying representation of a completion virtual table |
2965 | */ |
2966 | typedef struct completion_vtab completion_vtab; |
2967 | struct completion_vtab { |
2968 | sqlite3_vtab base; /* Base class - must be first */ |
2969 | sqlite3 *db; /* Database connection for this completion vtab */ |
2970 | }; |
2971 | |
2972 | /* completion_cursor is a subclass of sqlite3_vtab_cursor which will |
2973 | ** serve as the underlying representation of a cursor that scans |
2974 | ** over rows of the result |
2975 | */ |
2976 | typedef struct completion_cursor completion_cursor; |
2977 | struct completion_cursor { |
2978 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
2979 | sqlite3 *db; /* Database connection for this cursor */ |
2980 | int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */ |
2981 | char *zPrefix; /* The prefix for the word we want to complete */ |
2982 | char *zLine; /* The whole that we want to complete */ |
2983 | const char *zCurrentRow; /* Current output row */ |
2984 | sqlite3_stmt *pStmt; /* Current statement */ |
2985 | sqlite3_int64 iRowid; /* The rowid */ |
2986 | int ePhase; /* Current phase */ |
2987 | int j; /* inter-phase counter */ |
2988 | }; |
2989 | |
2990 | /* Values for ePhase: |
2991 | */ |
2992 | #define COMPLETION_FIRST_PHASE 1 |
2993 | #define COMPLETION_KEYWORDS 1 |
2994 | #define COMPLETION_PRAGMAS 2 |
2995 | #define COMPLETION_FUNCTIONS 3 |
2996 | #define COMPLETION_COLLATIONS 4 |
2997 | #define COMPLETION_INDEXES 5 |
2998 | #define COMPLETION_TRIGGERS 6 |
2999 | #define COMPLETION_DATABASES 7 |
3000 | #define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */ |
3001 | #define COMPLETION_COLUMNS 9 |
3002 | #define COMPLETION_MODULES 10 |
3003 | #define COMPLETION_EOF 11 |
3004 | |
3005 | /* |
3006 | ** The completionConnect() method is invoked to create a new |
3007 | ** completion_vtab that describes the completion virtual table. |
3008 | ** |
3009 | ** Think of this routine as the constructor for completion_vtab objects. |
3010 | ** |
3011 | ** All this routine needs to do is: |
3012 | ** |
3013 | ** (1) Allocate the completion_vtab object and initialize all fields. |
3014 | ** |
3015 | ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the |
3016 | ** result set of queries against completion will look like. |
3017 | */ |
3018 | static int completionConnect(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, |
3019 | char **pzErr) { |
3020 | completion_vtab *pNew; |
3021 | int rc; |
3022 | |
3023 | (void)(pAux); /* Unused parameter */ |
3024 | (void)(argc); /* Unused parameter */ |
3025 | (void)(argv); /* Unused parameter */ |
3026 | (void)(pzErr); /* Unused parameter */ |
3027 | |
3028 | /* Column numbers */ |
3029 | #define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */ |
3030 | #define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */ |
3031 | #define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */ |
3032 | #define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */ |
3033 | |
3034 | rc = sqlite3_declare_vtab(db, "CREATE TABLE x(" |
3035 | " candidate TEXT," |
3036 | " prefix TEXT HIDDEN," |
3037 | " wholeline TEXT HIDDEN," |
3038 | " phase INT HIDDEN" /* Used for debugging only */ |
3039 | ")" ); |
3040 | if (rc == SQLITE_OK) { |
3041 | pNew = sqlite3_malloc(sizeof(*pNew)); |
3042 | *ppVtab = (sqlite3_vtab *)pNew; |
3043 | if (pNew == 0) |
3044 | return SQLITE_NOMEM; |
3045 | memset(pNew, 0, sizeof(*pNew)); |
3046 | pNew->db = db; |
3047 | } |
3048 | return rc; |
3049 | } |
3050 | |
3051 | /* |
3052 | ** This method is the destructor for completion_cursor objects. |
3053 | */ |
3054 | static int completionDisconnect(sqlite3_vtab *pVtab) { |
3055 | sqlite3_free(pVtab); |
3056 | return SQLITE_OK; |
3057 | } |
3058 | |
3059 | /* |
3060 | ** Constructor for a new completion_cursor object. |
3061 | */ |
3062 | static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor) { |
3063 | completion_cursor *pCur; |
3064 | pCur = sqlite3_malloc(sizeof(*pCur)); |
3065 | if (pCur == 0) |
3066 | return SQLITE_NOMEM; |
3067 | memset(pCur, 0, sizeof(*pCur)); |
3068 | pCur->db = ((completion_vtab *)p)->db; |
3069 | *ppCursor = &pCur->base; |
3070 | return SQLITE_OK; |
3071 | } |
3072 | |
3073 | /* |
3074 | ** Reset the completion_cursor. |
3075 | */ |
3076 | static void completionCursorReset(completion_cursor *pCur) { |
3077 | sqlite3_free(pCur->zPrefix); |
3078 | pCur->zPrefix = 0; |
3079 | pCur->nPrefix = 0; |
3080 | sqlite3_free(pCur->zLine); |
3081 | pCur->zLine = 0; |
3082 | pCur->nLine = 0; |
3083 | sqlite3_finalize(pCur->pStmt); |
3084 | pCur->pStmt = 0; |
3085 | pCur->j = 0; |
3086 | } |
3087 | |
3088 | /* |
3089 | ** Destructor for a completion_cursor. |
3090 | */ |
3091 | static int completionClose(sqlite3_vtab_cursor *cur) { |
3092 | completionCursorReset((completion_cursor *)cur); |
3093 | sqlite3_free(cur); |
3094 | return SQLITE_OK; |
3095 | } |
3096 | |
3097 | /* |
3098 | ** All SQL keywords understood by SQLite |
3099 | */ |
3100 | static const char *completionKwrds[] = { |
3101 | "ABORT" , "ACTION" , "ADD" , "AFTER" , "ALL" , "ALTER" , |
3102 | "ANALYZE" , "AND" , "AS" , "ASC" , "ATTACH" , "AUTOINCREMENT" , |
3103 | "BEFORE" , "BEGIN" , "BETWEEN" , "BY" , "CASCADE" , "CASE" , |
3104 | "CAST" , "CHECK" , "COLLATE" , "COLUMN" , "COMMIT" , "CONFLICT" , |
3105 | "CONSTRAINT" , "CREATE" , "CROSS" , "CURRENT_DATE" , "CURRENT_TIME" , "CURRENT_TIMESTAMP" , |
3106 | "DATABASE" , "DEFAULT" , "DEFERRABLE" , "DEFERRED" , "DELETE" , "DESC" , |
3107 | "DETACH" , "DISTINCT" , "DROP" , "EACH" , "ELSE" , "END" , |
3108 | "ESCAPE" , "EXCEPT" , "EXCLUSIVE" , "EXISTS" , "EXPLAIN" , "FAIL" , |
3109 | "FOR" , "FOREIGN" , "FROM" , "FULL" , "GLOB" , "GROUP" , |
3110 | "HAVING" , "IF" , "IGNORE" , "IMMEDIATE" , "IN" , "INDEX" , |
3111 | "INDEXED" , "INITIALLY" , "INNER" , "INSERT" , "INSTEAD" , "INTERSECT" , |
3112 | "INTO" , "IS" , "ISNULL" , "JOIN" , "KEY" , "LEFT" , |
3113 | "LIKE" , "LIMIT" , "MATCH" , "NATURAL" , "NO" , "NOT" , |
3114 | "NOTNULL" , "NULL" , "OF" , "OFFSET" , "ON" , "OR" , |
3115 | "ORDER" , "OUTER" , "PLAN" , "PRAGMA" , "PRIMARY" , "QUERY" , |
3116 | "RAISE" , "RECURSIVE" , "REFERENCES" , "REGEXP" , "REINDEX" , "RELEASE" , |
3117 | "RENAME" , "REPLACE" , "RESTRICT" , "RIGHT" , "ROLLBACK" , "ROW" , |
3118 | "SAVEPOINT" , "SELECT" , "SET" , "TABLE" , "TEMP" , "TEMPORARY" , |
3119 | "THEN" , "TO" , "TRANSACTION" , "TRIGGER" , "UNION" , "UNIQUE" , |
3120 | "UPDATE" , "USING" , "VACUUM" , "VALUES" , "VIEW" , "VIRTUAL" , |
3121 | "WHEN" , "WHERE" , "WITH" , "WITHOUT" , |
3122 | }; |
3123 | #define completionKwCount (int)(sizeof(completionKwrds) / sizeof(completionKwrds[0])) |
3124 | |
3125 | /* |
3126 | ** Advance a completion_cursor to its next row of output. |
3127 | ** |
3128 | ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object |
3129 | ** record the current state of the scan. This routine sets ->zCurrentRow |
3130 | ** to the current row of output and then returns. If no more rows remain, |
3131 | ** then ->ePhase is set to COMPLETION_EOF which will signal the virtual |
3132 | ** table that has reached the end of its scan. |
3133 | ** |
3134 | ** The current implementation just lists potential identifiers and |
3135 | ** keywords and filters them by zPrefix. Future enhancements should |
3136 | ** take zLine into account to try to restrict the set of identifiers and |
3137 | ** keywords based on what would be legal at the current point of input. |
3138 | */ |
3139 | static int completionNext(sqlite3_vtab_cursor *cur) { |
3140 | completion_cursor *pCur = (completion_cursor *)cur; |
3141 | int eNextPhase = 0; /* Next phase to try if current phase reaches end */ |
3142 | int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */ |
3143 | pCur->iRowid++; |
3144 | while (pCur->ePhase != COMPLETION_EOF) { |
3145 | switch (pCur->ePhase) { |
3146 | case COMPLETION_KEYWORDS: { |
3147 | if (pCur->j >= completionKwCount) { |
3148 | pCur->zCurrentRow = 0; |
3149 | pCur->ePhase = COMPLETION_DATABASES; |
3150 | } else { |
3151 | pCur->zCurrentRow = completionKwrds[pCur->j++]; |
3152 | } |
3153 | iCol = -1; |
3154 | break; |
3155 | } |
3156 | case COMPLETION_DATABASES: { |
3157 | if (pCur->pStmt == 0) { |
3158 | sqlite3_prepare_v2(pCur->db, "PRAGMA database_list" , -1, &pCur->pStmt, 0); |
3159 | } |
3160 | iCol = 1; |
3161 | eNextPhase = COMPLETION_TABLES; |
3162 | break; |
3163 | } |
3164 | case COMPLETION_TABLES: { |
3165 | if (pCur->pStmt == 0) { |
3166 | sqlite3_stmt *pS2; |
3167 | char *zSql = 0; |
3168 | const char *zSep = "" ; |
3169 | sqlite3_prepare_v2(pCur->db, "PRAGMA database_list" , -1, &pS2, 0); |
3170 | while (sqlite3_step(pS2) == SQLITE_ROW) { |
3171 | const char *zDb = (const char *)sqlite3_column_text(pS2, 1); |
3172 | zSql = sqlite3_mprintf("%z%s" |
3173 | "SELECT name FROM \"%w\".sqlite_master" , |
3174 | zSql, zSep, zDb); |
3175 | if (zSql == 0) |
3176 | return SQLITE_NOMEM; |
3177 | zSep = " UNION " ; |
3178 | } |
3179 | sqlite3_finalize(pS2); |
3180 | sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); |
3181 | sqlite3_free(zSql); |
3182 | } |
3183 | iCol = 0; |
3184 | eNextPhase = COMPLETION_COLUMNS; |
3185 | break; |
3186 | } |
3187 | case COMPLETION_COLUMNS: { |
3188 | if (pCur->pStmt == 0) { |
3189 | sqlite3_stmt *pS2; |
3190 | char *zSql = 0; |
3191 | const char *zSep = "" ; |
3192 | sqlite3_prepare_v2(pCur->db, "PRAGMA database_list" , -1, &pS2, 0); |
3193 | while (sqlite3_step(pS2) == SQLITE_ROW) { |
3194 | const char *zDb = (const char *)sqlite3_column_text(pS2, 1); |
3195 | zSql = sqlite3_mprintf("%z%s" |
3196 | "SELECT pti.name FROM \"%w\".sqlite_master AS sm" |
3197 | " JOIN pragma_table_info(sm.name,%Q) AS pti" |
3198 | " WHERE sm.type='table'" , |
3199 | zSql, zSep, zDb, zDb); |
3200 | if (zSql == 0) |
3201 | return SQLITE_NOMEM; |
3202 | zSep = " UNION " ; |
3203 | } |
3204 | sqlite3_finalize(pS2); |
3205 | sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); |
3206 | sqlite3_free(zSql); |
3207 | } |
3208 | iCol = 0; |
3209 | eNextPhase = COMPLETION_EOF; |
3210 | break; |
3211 | } |
3212 | } |
3213 | if (iCol < 0) { |
3214 | /* This case is when the phase presets zCurrentRow */ |
3215 | if (pCur->zCurrentRow == 0) |
3216 | continue; |
3217 | } else { |
3218 | if (sqlite3_step(pCur->pStmt) == SQLITE_ROW) { |
3219 | /* Extract the next row of content */ |
3220 | pCur->zCurrentRow = (const char *)sqlite3_column_text(pCur->pStmt, iCol); |
3221 | } else { |
3222 | /* When all rows are finished, advance to the next phase */ |
3223 | sqlite3_finalize(pCur->pStmt); |
3224 | pCur->pStmt = 0; |
3225 | pCur->ePhase = eNextPhase; |
3226 | continue; |
3227 | } |
3228 | } |
3229 | if (pCur->nPrefix == 0) |
3230 | break; |
3231 | if (sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix) == 0) { |
3232 | break; |
3233 | } |
3234 | } |
3235 | |
3236 | return SQLITE_OK; |
3237 | } |
3238 | |
3239 | /* |
3240 | ** Return values of columns for the row at which the completion_cursor |
3241 | ** is currently pointing. |
3242 | */ |
3243 | static int completionColumn(sqlite3_vtab_cursor *cur, /* The cursor */ |
3244 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
3245 | int i /* Which column to return */ |
3246 | ) { |
3247 | completion_cursor *pCur = (completion_cursor *)cur; |
3248 | switch (i) { |
3249 | case COMPLETION_COLUMN_CANDIDATE: { |
3250 | sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT); |
3251 | break; |
3252 | } |
3253 | case COMPLETION_COLUMN_PREFIX: { |
3254 | sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT); |
3255 | break; |
3256 | } |
3257 | case COMPLETION_COLUMN_WHOLELINE: { |
3258 | sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT); |
3259 | break; |
3260 | } |
3261 | case COMPLETION_COLUMN_PHASE: { |
3262 | sqlite3_result_int(ctx, pCur->ePhase); |
3263 | break; |
3264 | } |
3265 | } |
3266 | return SQLITE_OK; |
3267 | } |
3268 | |
3269 | /* |
3270 | ** Return the rowid for the current row. In this implementation, the |
3271 | ** rowid is the same as the output value. |
3272 | */ |
3273 | static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid) { |
3274 | completion_cursor *pCur = (completion_cursor *)cur; |
3275 | *pRowid = pCur->iRowid; |
3276 | return SQLITE_OK; |
3277 | } |
3278 | |
3279 | /* |
3280 | ** Return TRUE if the cursor has been moved off of the last |
3281 | ** row of output. |
3282 | */ |
3283 | static int completionEof(sqlite3_vtab_cursor *cur) { |
3284 | completion_cursor *pCur = (completion_cursor *)cur; |
3285 | return pCur->ePhase >= COMPLETION_EOF; |
3286 | } |
3287 | |
3288 | /* |
3289 | ** This method is called to "rewind" the completion_cursor object back |
3290 | ** to the first row of output. This method is always called at least |
3291 | ** once prior to any call to completionColumn() or completionRowid() or |
3292 | ** completionEof(). |
3293 | */ |
3294 | static int completionFilter(sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, |
3295 | sqlite3_value **argv) { |
3296 | completion_cursor *pCur = (completion_cursor *)pVtabCursor; |
3297 | int iArg = 0; |
3298 | (void)(idxStr); /* Unused parameter */ |
3299 | (void)(argc); /* Unused parameter */ |
3300 | completionCursorReset(pCur); |
3301 | if (idxNum & 1) { |
3302 | pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); |
3303 | if (pCur->nPrefix > 0) { |
3304 | pCur->zPrefix = sqlite3_mprintf("%s" , sqlite3_value_text(argv[iArg])); |
3305 | if (pCur->zPrefix == 0) |
3306 | return SQLITE_NOMEM; |
3307 | } |
3308 | iArg++; |
3309 | } |
3310 | if (idxNum & 2) { |
3311 | pCur->nLine = sqlite3_value_bytes(argv[iArg]); |
3312 | if (pCur->nLine > 0) { |
3313 | pCur->zLine = sqlite3_mprintf("%s" , sqlite3_value_text(argv[iArg])); |
3314 | if (pCur->zLine == 0) |
3315 | return SQLITE_NOMEM; |
3316 | } |
3317 | iArg++; |
3318 | } |
3319 | if (pCur->zLine != 0 && pCur->zPrefix == 0) { |
3320 | int i = pCur->nLine; |
3321 | while (i > 0 && (isalnum(pCur->zLine[i - 1]) || pCur->zLine[i - 1] == '_')) { |
3322 | i--; |
3323 | } |
3324 | pCur->nPrefix = pCur->nLine - i; |
3325 | if (pCur->nPrefix > 0) { |
3326 | pCur->zPrefix = sqlite3_mprintf("%.*s" , pCur->nPrefix, pCur->zLine + i); |
3327 | if (pCur->zPrefix == 0) |
3328 | return SQLITE_NOMEM; |
3329 | } |
3330 | } |
3331 | pCur->iRowid = 0; |
3332 | pCur->ePhase = COMPLETION_FIRST_PHASE; |
3333 | return completionNext(pVtabCursor); |
3334 | } |
3335 | |
3336 | /* |
3337 | ** SQLite will invoke this method one or more times while planning a query |
3338 | ** that uses the completion virtual table. This routine needs to create |
3339 | ** a query plan for each invocation and compute an estimated cost for that |
3340 | ** plan. |
3341 | ** |
3342 | ** There are two hidden parameters that act as arguments to the table-valued |
3343 | ** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix" |
3344 | ** is available and bit 1 is set if "wholeline" is available. |
3345 | */ |
3346 | static int completionBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo) { |
3347 | int i; /* Loop over constraints */ |
3348 | int idxNum = 0; /* The query plan bitmask */ |
3349 | int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */ |
3350 | int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */ |
3351 | int nArg = 0; /* Number of arguments that completeFilter() expects */ |
3352 | const struct sqlite3_index_constraint *pConstraint; |
3353 | |
3354 | (void)(tab); /* Unused parameter */ |
3355 | pConstraint = pIdxInfo->aConstraint; |
3356 | for (i = 0; i < pIdxInfo->nConstraint; i++, pConstraint++) { |
3357 | if (pConstraint->usable == 0) |
3358 | continue; |
3359 | if (pConstraint->op != SQLITE_INDEX_CONSTRAINT_EQ) |
3360 | continue; |
3361 | switch (pConstraint->iColumn) { |
3362 | case COMPLETION_COLUMN_PREFIX: |
3363 | prefixIdx = i; |
3364 | idxNum |= 1; |
3365 | break; |
3366 | case COMPLETION_COLUMN_WHOLELINE: |
3367 | wholelineIdx = i; |
3368 | idxNum |= 2; |
3369 | break; |
3370 | } |
3371 | } |
3372 | if (prefixIdx >= 0) { |
3373 | pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg; |
3374 | pIdxInfo->aConstraintUsage[prefixIdx].omit = 1; |
3375 | } |
3376 | if (wholelineIdx >= 0) { |
3377 | pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg; |
3378 | pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1; |
3379 | } |
3380 | pIdxInfo->idxNum = idxNum; |
3381 | pIdxInfo->estimatedCost = (double)5000 - 1000 * nArg; |
3382 | pIdxInfo->estimatedRows = 500 - 100 * nArg; |
3383 | return SQLITE_OK; |
3384 | } |
3385 | |
3386 | /* |
3387 | ** This following structure defines all the methods for the |
3388 | ** completion virtual table. |
3389 | */ |
3390 | static sqlite3_module completionModule = { |
3391 | 0, /* iVersion */ |
3392 | 0, /* xCreate */ |
3393 | completionConnect, /* xConnect */ |
3394 | completionBestIndex, /* xBestIndex */ |
3395 | completionDisconnect, /* xDisconnect */ |
3396 | 0, /* xDestroy */ |
3397 | completionOpen, /* xOpen - open a cursor */ |
3398 | completionClose, /* xClose - close a cursor */ |
3399 | completionFilter, /* xFilter - configure scan constraints */ |
3400 | completionNext, /* xNext - advance a cursor */ |
3401 | completionEof, /* xEof - check for end of scan */ |
3402 | completionColumn, /* xColumn - read data */ |
3403 | completionRowid, /* xRowid - read data */ |
3404 | 0, /* xUpdate */ |
3405 | 0, /* xBegin */ |
3406 | 0, /* xSync */ |
3407 | 0, /* xCommit */ |
3408 | 0, /* xRollback */ |
3409 | 0, /* xFindMethod */ |
3410 | 0, /* xRename */ |
3411 | 0, /* xSavepoint */ |
3412 | 0, /* xRelease */ |
3413 | 0 /* xRollbackTo */ |
3414 | }; |
3415 | |
3416 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
3417 | |
3418 | int sqlite3CompletionVtabInit(sqlite3 *db) { |
3419 | int rc = SQLITE_OK; |
3420 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
3421 | rc = sqlite3_create_module(db, "completion" , &completionModule, 0); |
3422 | #endif |
3423 | return rc; |
3424 | } |
3425 | |
3426 | #ifdef _WIN32 |
3427 | |
3428 | #endif |
3429 | int sqlite3_completion_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { |
3430 | int rc = SQLITE_OK; |
3431 | SQLITE_EXTENSION_INIT2(pApi); |
3432 | (void)(pzErrMsg); /* Unused parameter */ |
3433 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
3434 | rc = sqlite3CompletionVtabInit(db); |
3435 | #endif |
3436 | return rc; |
3437 | } |
3438 | |
3439 | /************************* End ../ext/misc/completion.c ********************/ |
3440 | /************************* Begin ../ext/misc/appendvfs.c ******************/ |
3441 | /* |
3442 | ** 2017-10-20 |
3443 | ** |
3444 | ** The author disclaims copyright to this source code. In place of |
3445 | ** a legal notice, here is a blessing: |
3446 | ** |
3447 | ** May you do good and not evil. |
3448 | ** May you find forgiveness for yourself and forgive others. |
3449 | ** May you share freely, never taking more than you give. |
3450 | ** |
3451 | ****************************************************************************** |
3452 | ** |
3453 | ** This file implements a VFS shim that allows an SQLite database to be |
3454 | ** appended onto the end of some other file, such as an executable. |
3455 | ** |
3456 | ** A special record must appear at the end of the file that identifies the |
3457 | ** file as an appended database and provides an offset to page 1. For |
3458 | ** best performance page 1 should be located at a disk page boundary, though |
3459 | ** that is not required. |
3460 | ** |
3461 | ** When opening a database using this VFS, the connection might treat |
3462 | ** the file as an ordinary SQLite database, or it might treat is as a |
3463 | ** database appended onto some other file. Here are the rules: |
3464 | ** |
3465 | ** (1) When opening a new empty file, that file is treated as an ordinary |
3466 | ** database. |
3467 | ** |
3468 | ** (2) When opening a file that begins with the standard SQLite prefix |
3469 | ** string "SQLite format 3", that file is treated as an ordinary |
3470 | ** database. |
3471 | ** |
3472 | ** (3) When opening a file that ends with the appendvfs trailer string |
3473 | ** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended |
3474 | ** database. |
3475 | ** |
3476 | ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is |
3477 | ** set, then a new database is appended to the already existing file. |
3478 | ** |
3479 | ** (5) Otherwise, SQLITE_CANTOPEN is returned. |
3480 | ** |
3481 | ** To avoid unnecessary complications with the PENDING_BYTE, the size of |
3482 | ** the file containing the database is limited to 1GB. This VFS will refuse |
3483 | ** to read or write past the 1GB mark. This restriction might be lifted in |
3484 | ** future versions. For now, if you need a large database, then keep the |
3485 | ** database in a separate file. |
3486 | ** |
3487 | ** If the file being opened is not an appended database, then this shim is |
3488 | ** a pass-through into the default underlying VFS. |
3489 | **/ |
3490 | SQLITE_EXTENSION_INIT1 |
3491 | #include <string.h> |
3492 | #include <assert.h> |
3493 | |
3494 | /* The append mark at the end of the database is: |
3495 | ** |
3496 | ** Start-Of-SQLite3-NNNNNNNN |
3497 | ** 123456789 123456789 12345 |
3498 | ** |
3499 | ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is |
3500 | ** the offset to page 1. |
3501 | */ |
3502 | #define APND_MARK_PREFIX "Start-Of-SQLite3-" |
3503 | #define APND_MARK_PREFIX_SZ 17 |
3504 | #define APND_MARK_SIZE 25 |
3505 | |
3506 | /* |
3507 | ** Maximum size of the combined prefix + database + append-mark. This |
3508 | ** must be less than 0x40000000 to avoid locking issues on Windows. |
3509 | */ |
3510 | #define APND_MAX_SIZE (65536 * 15259) |
3511 | |
3512 | /* |
3513 | ** Forward declaration of objects used by this utility |
3514 | */ |
3515 | typedef struct sqlite3_vfs ApndVfs; |
3516 | typedef struct ApndFile ApndFile; |
3517 | |
3518 | /* Access to a lower-level VFS that (might) implement dynamic loading, |
3519 | ** access to randomness, etc. |
3520 | */ |
3521 | #define ORIGVFS(p) ((sqlite3_vfs *)((p)->pAppData)) |
3522 | #define ORIGFILE(p) ((sqlite3_file *)(((ApndFile *)(p)) + 1)) |
3523 | |
3524 | /* An open file */ |
3525 | struct ApndFile { |
3526 | sqlite3_file base; /* IO methods */ |
3527 | sqlite3_int64 iPgOne; /* File offset to page 1 */ |
3528 | sqlite3_int64 iMark; /* Start of the append-mark */ |
3529 | }; |
3530 | |
3531 | /* |
3532 | ** Methods for ApndFile |
3533 | */ |
3534 | static int apndClose(sqlite3_file *); |
3535 | static int apndRead(sqlite3_file *, void *, int iAmt, sqlite3_int64 iOfst); |
3536 | static int apndWrite(sqlite3_file *, const void *, int iAmt, sqlite3_int64 iOfst); |
3537 | static int apndTruncate(sqlite3_file *, sqlite3_int64 size); |
3538 | static int apndSync(sqlite3_file *, int flags); |
3539 | static int apndFileSize(sqlite3_file *, sqlite3_int64 *pSize); |
3540 | static int apndLock(sqlite3_file *, int); |
3541 | static int apndUnlock(sqlite3_file *, int); |
3542 | static int apndCheckReservedLock(sqlite3_file *, int *pResOut); |
3543 | static int apndFileControl(sqlite3_file *, int op, void *pArg); |
3544 | static int apndSectorSize(sqlite3_file *); |
3545 | static int apndDeviceCharacteristics(sqlite3_file *); |
3546 | static int apndShmMap(sqlite3_file *, int iPg, int pgsz, int, void volatile **); |
3547 | static int apndShmLock(sqlite3_file *, int offset, int n, int flags); |
3548 | static void apndShmBarrier(sqlite3_file *); |
3549 | static int apndShmUnmap(sqlite3_file *, int deleteFlag); |
3550 | static int apndFetch(sqlite3_file *, sqlite3_int64 iOfst, int iAmt, void **pp); |
3551 | static int apndUnfetch(sqlite3_file *, sqlite3_int64 iOfst, void *p); |
3552 | |
3553 | /* |
3554 | ** Methods for ApndVfs |
3555 | */ |
3556 | static int apndOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int *); |
3557 | static int apndDelete(sqlite3_vfs *, const char *zName, int syncDir); |
3558 | static int apndAccess(sqlite3_vfs *, const char *zName, int flags, int *); |
3559 | static int apndFullPathname(sqlite3_vfs *, const char *zName, int, char *zOut); |
3560 | static void *apndDlOpen(sqlite3_vfs *, const char *zFilename); |
3561 | static void apndDlError(sqlite3_vfs *, int nByte, char *zErrMsg); |
3562 | static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void); |
3563 | static void apndDlClose(sqlite3_vfs *, void *); |
3564 | static int apndRandomness(sqlite3_vfs *, int nByte, char *zOut); |
3565 | static int apndSleep(sqlite3_vfs *, int microseconds); |
3566 | static int apndCurrentTime(sqlite3_vfs *, double *); |
3567 | static int apndGetLastError(sqlite3_vfs *, int, char *); |
3568 | static int apndCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64 *); |
3569 | static int apndSetSystemCall(sqlite3_vfs *, const char *, sqlite3_syscall_ptr); |
3570 | static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs *, const char *z); |
3571 | static const char *apndNextSystemCall(sqlite3_vfs *, const char *zName); |
3572 | |
3573 | static sqlite3_vfs apnd_vfs = { |
3574 | 3, /* iVersion (set when registered) */ |
3575 | 0, /* szOsFile (set when registered) */ |
3576 | 1024, /* mxPathname */ |
3577 | 0, /* pNext */ |
3578 | "apndvfs" , /* zName */ |
3579 | 0, /* pAppData (set when registered) */ |
3580 | apndOpen, /* xOpen */ |
3581 | apndDelete, /* xDelete */ |
3582 | apndAccess, /* xAccess */ |
3583 | apndFullPathname, /* xFullPathname */ |
3584 | apndDlOpen, /* xDlOpen */ |
3585 | apndDlError, /* xDlError */ |
3586 | apndDlSym, /* xDlSym */ |
3587 | apndDlClose, /* xDlClose */ |
3588 | apndRandomness, /* xRandomness */ |
3589 | apndSleep, /* xSleep */ |
3590 | apndCurrentTime, /* xCurrentTime */ |
3591 | apndGetLastError, /* xGetLastError */ |
3592 | apndCurrentTimeInt64, /* xCurrentTimeInt64 */ |
3593 | apndSetSystemCall, /* xSetSystemCall */ |
3594 | apndGetSystemCall, /* xGetSystemCall */ |
3595 | apndNextSystemCall /* xNextSystemCall */ |
3596 | }; |
3597 | |
3598 | static const sqlite3_io_methods apnd_io_methods = { |
3599 | 3, /* iVersion */ |
3600 | apndClose, /* xClose */ |
3601 | apndRead, /* xRead */ |
3602 | apndWrite, /* xWrite */ |
3603 | apndTruncate, /* xTruncate */ |
3604 | apndSync, /* xSync */ |
3605 | apndFileSize, /* xFileSize */ |
3606 | apndLock, /* xLock */ |
3607 | apndUnlock, /* xUnlock */ |
3608 | apndCheckReservedLock, /* xCheckReservedLock */ |
3609 | apndFileControl, /* xFileControl */ |
3610 | apndSectorSize, /* xSectorSize */ |
3611 | apndDeviceCharacteristics, /* xDeviceCharacteristics */ |
3612 | apndShmMap, /* xShmMap */ |
3613 | apndShmLock, /* xShmLock */ |
3614 | apndShmBarrier, /* xShmBarrier */ |
3615 | apndShmUnmap, /* xShmUnmap */ |
3616 | apndFetch, /* xFetch */ |
3617 | apndUnfetch /* xUnfetch */ |
3618 | }; |
3619 | |
3620 | /* |
3621 | ** Close an apnd-file. |
3622 | */ |
3623 | static int apndClose(sqlite3_file *pFile) { |
3624 | pFile = ORIGFILE(pFile); |
3625 | return pFile->pMethods->xClose(pFile); |
3626 | } |
3627 | |
3628 | /* |
3629 | ** Read data from an apnd-file. |
3630 | */ |
3631 | static int apndRead(sqlite3_file *pFile, void *zBuf, int iAmt, sqlite_int64 iOfst) { |
3632 | ApndFile *p = (ApndFile *)pFile; |
3633 | pFile = ORIGFILE(pFile); |
3634 | return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst + p->iPgOne); |
3635 | } |
3636 | |
3637 | /* |
3638 | ** Add the append-mark onto the end of the file. |
3639 | */ |
3640 | static int apndWriteMark(ApndFile *p, sqlite3_file *pFile) { |
3641 | int i; |
3642 | unsigned char a[APND_MARK_SIZE]; |
3643 | memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ); |
3644 | for (i = 0; i < 8; i++) { |
3645 | a[APND_MARK_PREFIX_SZ + i] = (p->iPgOne >> (56 - i * 8)) & 0xff; |
3646 | } |
3647 | return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark); |
3648 | } |
3649 | |
3650 | /* |
3651 | ** Write data to an apnd-file. |
3652 | */ |
3653 | static int apndWrite(sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst) { |
3654 | int rc; |
3655 | ApndFile *p = (ApndFile *)pFile; |
3656 | pFile = ORIGFILE(pFile); |
3657 | if (iOfst + iAmt >= APND_MAX_SIZE) |
3658 | return SQLITE_FULL; |
3659 | rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst + p->iPgOne); |
3660 | if (rc == SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark) { |
3661 | sqlite3_int64 sz = 0; |
3662 | rc = pFile->pMethods->xFileSize(pFile, &sz); |
3663 | if (rc == SQLITE_OK) { |
3664 | p->iMark = sz - APND_MARK_SIZE; |
3665 | if (iOfst + iAmt + p->iPgOne > p->iMark) { |
3666 | p->iMark = p->iPgOne + iOfst + iAmt; |
3667 | rc = apndWriteMark(p, pFile); |
3668 | } |
3669 | } |
3670 | } |
3671 | return rc; |
3672 | } |
3673 | |
3674 | /* |
3675 | ** Truncate an apnd-file. |
3676 | */ |
3677 | static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size) { |
3678 | int rc; |
3679 | ApndFile *p = (ApndFile *)pFile; |
3680 | pFile = ORIGFILE(pFile); |
3681 | rc = pFile->pMethods->xTruncate(pFile, size + p->iPgOne + APND_MARK_SIZE); |
3682 | if (rc == SQLITE_OK) { |
3683 | p->iMark = p->iPgOne + size; |
3684 | rc = apndWriteMark(p, pFile); |
3685 | } |
3686 | return rc; |
3687 | } |
3688 | |
3689 | /* |
3690 | ** Sync an apnd-file. |
3691 | */ |
3692 | static int apndSync(sqlite3_file *pFile, int flags) { |
3693 | pFile = ORIGFILE(pFile); |
3694 | return pFile->pMethods->xSync(pFile, flags); |
3695 | } |
3696 | |
3697 | /* |
3698 | ** Return the current file-size of an apnd-file. |
3699 | */ |
3700 | static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize) { |
3701 | ApndFile *p = (ApndFile *)pFile; |
3702 | int rc; |
3703 | pFile = ORIGFILE(p); |
3704 | rc = pFile->pMethods->xFileSize(pFile, pSize); |
3705 | if (rc == SQLITE_OK && p->iPgOne) { |
3706 | *pSize -= p->iPgOne + APND_MARK_SIZE; |
3707 | } |
3708 | return rc; |
3709 | } |
3710 | |
3711 | /* |
3712 | ** Lock an apnd-file. |
3713 | */ |
3714 | static int apndLock(sqlite3_file *pFile, int eLock) { |
3715 | pFile = ORIGFILE(pFile); |
3716 | return pFile->pMethods->xLock(pFile, eLock); |
3717 | } |
3718 | |
3719 | /* |
3720 | ** Unlock an apnd-file. |
3721 | */ |
3722 | static int apndUnlock(sqlite3_file *pFile, int eLock) { |
3723 | pFile = ORIGFILE(pFile); |
3724 | return pFile->pMethods->xUnlock(pFile, eLock); |
3725 | } |
3726 | |
3727 | /* |
3728 | ** Check if another file-handle holds a RESERVED lock on an apnd-file. |
3729 | */ |
3730 | static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut) { |
3731 | pFile = ORIGFILE(pFile); |
3732 | return pFile->pMethods->xCheckReservedLock(pFile, pResOut); |
3733 | } |
3734 | |
3735 | /* |
3736 | ** File control method. For custom operations on an apnd-file. |
3737 | */ |
3738 | static int apndFileControl(sqlite3_file *pFile, int op, void *pArg) { |
3739 | ApndFile *p = (ApndFile *)pFile; |
3740 | int rc; |
3741 | pFile = ORIGFILE(pFile); |
3742 | rc = pFile->pMethods->xFileControl(pFile, op, pArg); |
3743 | if (rc == SQLITE_OK && op == SQLITE_FCNTL_VFSNAME) { |
3744 | *(char **)pArg = sqlite3_mprintf("apnd(%lld)/%z" , p->iPgOne, *(char **)pArg); |
3745 | } |
3746 | return rc; |
3747 | } |
3748 | |
3749 | /* |
3750 | ** Return the sector-size in bytes for an apnd-file. |
3751 | */ |
3752 | static int apndSectorSize(sqlite3_file *pFile) { |
3753 | pFile = ORIGFILE(pFile); |
3754 | return pFile->pMethods->xSectorSize(pFile); |
3755 | } |
3756 | |
3757 | /* |
3758 | ** Return the device characteristic flags supported by an apnd-file. |
3759 | */ |
3760 | static int apndDeviceCharacteristics(sqlite3_file *pFile) { |
3761 | pFile = ORIGFILE(pFile); |
3762 | return pFile->pMethods->xDeviceCharacteristics(pFile); |
3763 | } |
3764 | |
3765 | /* Create a shared memory file mapping */ |
3766 | static int apndShmMap(sqlite3_file *pFile, int iPg, int pgsz, int bExtend, void volatile **pp) { |
3767 | pFile = ORIGFILE(pFile); |
3768 | return pFile->pMethods->xShmMap(pFile, iPg, pgsz, bExtend, pp); |
3769 | } |
3770 | |
3771 | /* Perform locking on a shared-memory segment */ |
3772 | static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags) { |
3773 | pFile = ORIGFILE(pFile); |
3774 | return pFile->pMethods->xShmLock(pFile, offset, n, flags); |
3775 | } |
3776 | |
3777 | /* Memory barrier operation on shared memory */ |
3778 | static void apndShmBarrier(sqlite3_file *pFile) { |
3779 | pFile = ORIGFILE(pFile); |
3780 | pFile->pMethods->xShmBarrier(pFile); |
3781 | } |
3782 | |
3783 | /* Unmap a shared memory segment */ |
3784 | static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag) { |
3785 | pFile = ORIGFILE(pFile); |
3786 | return pFile->pMethods->xShmUnmap(pFile, deleteFlag); |
3787 | } |
3788 | |
3789 | /* Fetch a page of a memory-mapped file */ |
3790 | static int apndFetch(sqlite3_file *pFile, sqlite3_int64 iOfst, int iAmt, void **pp) { |
3791 | ApndFile *p = (ApndFile *)pFile; |
3792 | pFile = ORIGFILE(pFile); |
3793 | return pFile->pMethods->xFetch(pFile, iOfst + p->iPgOne, iAmt, pp); |
3794 | } |
3795 | |
3796 | /* Release a memory-mapped page */ |
3797 | static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage) { |
3798 | ApndFile *p = (ApndFile *)pFile; |
3799 | pFile = ORIGFILE(pFile); |
3800 | return pFile->pMethods->xUnfetch(pFile, iOfst + p->iPgOne, pPage); |
3801 | } |
3802 | |
3803 | /* |
3804 | ** Check to see if the file is an ordinary SQLite database file. |
3805 | */ |
3806 | static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile) { |
3807 | int rc; |
3808 | char zHdr[16]; |
3809 | static const char aSqliteHdr[] = "SQLite format 3" ; |
3810 | if (sz < 512) |
3811 | return 0; |
3812 | rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0); |
3813 | if (rc) |
3814 | return 0; |
3815 | return memcmp(zHdr, aSqliteHdr, sizeof(zHdr)) == 0; |
3816 | } |
3817 | |
3818 | /* |
3819 | ** Try to read the append-mark off the end of a file. Return the |
3820 | ** start of the appended database if the append-mark is present. If |
3821 | ** there is no append-mark, return -1; |
3822 | */ |
3823 | static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile) { |
3824 | int rc, i; |
3825 | sqlite3_int64 iMark; |
3826 | unsigned char a[APND_MARK_SIZE]; |
3827 | |
3828 | if (sz <= APND_MARK_SIZE) |
3829 | return -1; |
3830 | rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz - APND_MARK_SIZE); |
3831 | if (rc) |
3832 | return -1; |
3833 | if (memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ) != 0) |
3834 | return -1; |
3835 | iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << 56; |
3836 | for (i = 1; i < 8; i++) { |
3837 | iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ + i] << (56 - 8 * i); |
3838 | } |
3839 | return iMark; |
3840 | } |
3841 | |
3842 | /* |
3843 | ** Open an apnd file handle. |
3844 | */ |
3845 | static int apndOpen(sqlite3_vfs *pVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags) { |
3846 | ApndFile *p; |
3847 | sqlite3_file *pSubFile; |
3848 | sqlite3_vfs *pSubVfs; |
3849 | int rc; |
3850 | sqlite3_int64 sz; |
3851 | pSubVfs = ORIGVFS(pVfs); |
3852 | if ((flags & SQLITE_OPEN_MAIN_DB) == 0) { |
3853 | return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags); |
3854 | } |
3855 | p = (ApndFile *)pFile; |
3856 | memset(p, 0, sizeof(*p)); |
3857 | pSubFile = ORIGFILE(pFile); |
3858 | p->base.pMethods = &apnd_io_methods; |
3859 | rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags); |
3860 | if (rc) |
3861 | goto apnd_open_done; |
3862 | rc = pSubFile->pMethods->xFileSize(pSubFile, &sz); |
3863 | if (rc) { |
3864 | pSubFile->pMethods->xClose(pSubFile); |
3865 | goto apnd_open_done; |
3866 | } |
3867 | if (apndIsOrdinaryDatabaseFile(sz, pSubFile)) { |
3868 | memmove(pFile, pSubFile, pSubVfs->szOsFile); |
3869 | return SQLITE_OK; |
3870 | } |
3871 | p->iMark = 0; |
3872 | p->iPgOne = apndReadMark(sz, pFile); |
3873 | if (p->iPgOne > 0) { |
3874 | return SQLITE_OK; |
3875 | } |
3876 | if ((flags & SQLITE_OPEN_CREATE) == 0) { |
3877 | pSubFile->pMethods->xClose(pSubFile); |
3878 | rc = SQLITE_CANTOPEN; |
3879 | } |
3880 | p->iPgOne = (sz + 0xfff) & ~(sqlite3_int64)0xfff; |
3881 | apnd_open_done: |
3882 | if (rc) |
3883 | pFile->pMethods = 0; |
3884 | return rc; |
3885 | } |
3886 | |
3887 | /* |
3888 | ** All other VFS methods are pass-thrus. |
3889 | */ |
3890 | static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync) { |
3891 | return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync); |
3892 | } |
3893 | static int apndAccess(sqlite3_vfs *pVfs, const char *zPath, int flags, int *pResOut) { |
3894 | return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut); |
3895 | } |
3896 | static int apndFullPathname(sqlite3_vfs *pVfs, const char *zPath, int nOut, char *zOut) { |
3897 | return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs), zPath, nOut, zOut); |
3898 | } |
3899 | static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath) { |
3900 | return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); |
3901 | } |
3902 | static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg) { |
3903 | ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); |
3904 | } |
3905 | static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void) { |
3906 | return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); |
3907 | } |
3908 | static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle) { |
3909 | ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); |
3910 | } |
3911 | static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut) { |
3912 | return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); |
3913 | } |
3914 | static int apndSleep(sqlite3_vfs *pVfs, int nMicro) { |
3915 | return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); |
3916 | } |
3917 | static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut) { |
3918 | return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); |
3919 | } |
3920 | static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b) { |
3921 | return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); |
3922 | } |
3923 | static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p) { |
3924 | return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); |
3925 | } |
3926 | static int apndSetSystemCall(sqlite3_vfs *pVfs, const char *zName, sqlite3_syscall_ptr pCall) { |
3927 | return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs), zName, pCall); |
3928 | } |
3929 | static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs *pVfs, const char *zName) { |
3930 | return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs), zName); |
3931 | } |
3932 | static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName) { |
3933 | return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName); |
3934 | } |
3935 | |
3936 | #ifdef _WIN32 |
3937 | |
3938 | #endif |
3939 | /* |
3940 | ** This routine is called when the extension is loaded. |
3941 | ** Register the new VFS. |
3942 | */ |
3943 | int sqlite3_appendvfs_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { |
3944 | int rc = SQLITE_OK; |
3945 | sqlite3_vfs *pOrig; |
3946 | SQLITE_EXTENSION_INIT2(pApi); |
3947 | (void)pzErrMsg; |
3948 | (void)db; |
3949 | pOrig = sqlite3_vfs_find(0); |
3950 | apnd_vfs.iVersion = pOrig->iVersion; |
3951 | apnd_vfs.pAppData = pOrig; |
3952 | apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile); |
3953 | rc = sqlite3_vfs_register(&apnd_vfs, 0); |
3954 | #ifdef APPENDVFS_TEST |
3955 | if (rc == SQLITE_OK) { |
3956 | rc = sqlite3_auto_extension((void (*)(void))apndvfsRegister); |
3957 | } |
3958 | #endif |
3959 | if (rc == SQLITE_OK) |
3960 | rc = SQLITE_OK_LOAD_PERMANENTLY; |
3961 | return rc; |
3962 | } |
3963 | |
3964 | /************************* End ../ext/misc/appendvfs.c ********************/ |
3965 | #ifdef SQLITE_HAVE_ZLIB |
3966 | /************************* Begin ../ext/misc/zipfile.c ******************/ |
3967 | /* |
3968 | ** 2017-12-26 |
3969 | ** |
3970 | ** The author disclaims copyright to this source code. In place of |
3971 | ** a legal notice, here is a blessing: |
3972 | ** |
3973 | ** May you do good and not evil. |
3974 | ** May you find forgiveness for yourself and forgive others. |
3975 | ** May you share freely, never taking more than you give. |
3976 | ** |
3977 | ****************************************************************************** |
3978 | ** |
3979 | ** This file implements a virtual table for reading and writing ZIP archive |
3980 | ** files. |
3981 | ** |
3982 | ** Usage example: |
3983 | ** |
3984 | ** SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename); |
3985 | ** |
3986 | ** Current limitations: |
3987 | ** |
3988 | ** * No support for encryption |
3989 | ** * No support for ZIP archives spanning multiple files |
3990 | ** * No support for zip64 extensions |
3991 | ** * Only the "inflate/deflate" (zlib) compression method is supported |
3992 | */ |
3993 | SQLITE_EXTENSION_INIT1 |
3994 | #include <stdio.h> |
3995 | #include <string.h> |
3996 | #include <assert.h> |
3997 | |
3998 | #include <zlib.h> |
3999 | |
4000 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
4001 | |
4002 | #ifndef SQLITE_AMALGAMATION |
4003 | |
4004 | /* typedef sqlite3_int64 i64; */ |
4005 | /* typedef unsigned char u8; */ |
4006 | typedef unsigned short u16; |
4007 | typedef unsigned long u32; |
4008 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
4009 | |
4010 | #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) |
4011 | #define ALWAYS(X) (1) |
4012 | #define NEVER(X) (0) |
4013 | #elif !defined(NDEBUG) |
4014 | #define ALWAYS(X) ((X) ? 1 : (assert(0), 0)) |
4015 | #define NEVER(X) ((X) ? (assert(0), 1) : 0) |
4016 | #else |
4017 | #define ALWAYS(X) (X) |
4018 | #define NEVER(X) (X) |
4019 | #endif |
4020 | |
4021 | #endif /* SQLITE_AMALGAMATION */ |
4022 | |
4023 | /* |
4024 | ** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK. |
4025 | ** |
4026 | ** In some ways it would be better to obtain these values from system |
4027 | ** header files. But, the dependency is undesirable and (a) these |
4028 | ** have been stable for decades, (b) the values are part of POSIX and |
4029 | ** are also made explicit in [man stat], and (c) are part of the |
4030 | ** file format for zip archives. |
4031 | */ |
4032 | #ifndef S_IFDIR |
4033 | #define S_IFDIR 0040000 |
4034 | #endif |
4035 | #ifndef S_IFREG |
4036 | #define S_IFREG 0100000 |
4037 | #endif |
4038 | #ifndef S_IFLNK |
4039 | #define S_IFLNK 0120000 |
4040 | #endif |
4041 | |
4042 | static const char ZIPFILE_SCHEMA[] = "CREATE TABLE y(" |
4043 | "name PRIMARY KEY," /* 0: Name of file in zip archive */ |
4044 | "mode," /* 1: POSIX mode for file */ |
4045 | "mtime," /* 2: Last modification time (secs since 1970)*/ |
4046 | "sz," /* 3: Size of object */ |
4047 | "rawdata," /* 4: Raw data */ |
4048 | "data," /* 5: Uncompressed data */ |
4049 | "method," /* 6: Compression method (integer) */ |
4050 | "z HIDDEN" /* 7: Name of zip file */ |
4051 | ") WITHOUT ROWID;" ; |
4052 | |
4053 | #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ |
4054 | #define ZIPFILE_BUFFER_SIZE (64 * 1024) |
4055 | |
4056 | /* |
4057 | ** Magic numbers used to read and write zip files. |
4058 | ** |
4059 | ** ZIPFILE_NEWENTRY_MADEBY: |
4060 | ** Use this value for the "version-made-by" field in new zip file |
4061 | ** entries. The upper byte indicates "unix", and the lower byte |
4062 | ** indicates that the zip file matches pkzip specification 3.0. |
4063 | ** This is what info-zip seems to do. |
4064 | ** |
4065 | ** ZIPFILE_NEWENTRY_REQUIRED: |
4066 | ** Value for "version-required-to-extract" field of new entries. |
4067 | ** Version 2.0 is required to support folders and deflate compression. |
4068 | ** |
4069 | ** ZIPFILE_NEWENTRY_FLAGS: |
4070 | ** Value for "general-purpose-bit-flags" field of new entries. Bit |
4071 | ** 11 means "utf-8 filename and comment". |
4072 | ** |
4073 | ** ZIPFILE_SIGNATURE_CDS: |
4074 | ** First 4 bytes of a valid CDS record. |
4075 | ** |
4076 | ** ZIPFILE_SIGNATURE_LFH: |
4077 | ** First 4 bytes of a valid LFH record. |
4078 | ** |
4079 | ** ZIPFILE_SIGNATURE_EOCD |
4080 | ** First 4 bytes of a valid EOCD record. |
4081 | */ |
4082 | #define ZIPFILE_EXTRA_TIMESTAMP 0x5455 |
4083 | #define ZIPFILE_NEWENTRY_MADEBY ((3 << 8) + 30) |
4084 | #define ZIPFILE_NEWENTRY_REQUIRED 20 |
4085 | #define ZIPFILE_NEWENTRY_FLAGS 0x800 |
4086 | #define ZIPFILE_SIGNATURE_CDS 0x02014b50 |
4087 | #define ZIPFILE_SIGNATURE_LFH 0x04034b50 |
4088 | #define ZIPFILE_SIGNATURE_EOCD 0x06054b50 |
4089 | |
4090 | /* |
4091 | ** The sizes of the fixed-size part of each of the three main data |
4092 | ** structures in a zip archive. |
4093 | */ |
4094 | #define ZIPFILE_LFH_FIXED_SZ 30 |
4095 | #define ZIPFILE_EOCD_FIXED_SZ 22 |
4096 | #define ZIPFILE_CDS_FIXED_SZ 46 |
4097 | |
4098 | /* |
4099 | *** 4.3.16 End of central directory record: |
4100 | *** |
4101 | *** end of central dir signature 4 bytes (0x06054b50) |
4102 | *** number of this disk 2 bytes |
4103 | *** number of the disk with the |
4104 | *** start of the central directory 2 bytes |
4105 | *** total number of entries in the |
4106 | *** central directory on this disk 2 bytes |
4107 | *** total number of entries in |
4108 | *** the central directory 2 bytes |
4109 | *** size of the central directory 4 bytes |
4110 | *** offset of start of central |
4111 | *** directory with respect to |
4112 | *** the starting disk number 4 bytes |
4113 | *** .ZIP file comment length 2 bytes |
4114 | *** .ZIP file comment (variable size) |
4115 | */ |
4116 | typedef struct ZipfileEOCD ZipfileEOCD; |
4117 | struct ZipfileEOCD { |
4118 | u16 iDisk; |
4119 | u16 iFirstDisk; |
4120 | u16 nEntry; |
4121 | u16 nEntryTotal; |
4122 | u32 nSize; |
4123 | u32 iOffset; |
4124 | }; |
4125 | |
4126 | /* |
4127 | *** 4.3.12 Central directory structure: |
4128 | *** |
4129 | *** ... |
4130 | *** |
4131 | *** central file header signature 4 bytes (0x02014b50) |
4132 | *** version made by 2 bytes |
4133 | *** version needed to extract 2 bytes |
4134 | *** general purpose bit flag 2 bytes |
4135 | *** compression method 2 bytes |
4136 | *** last mod file time 2 bytes |
4137 | *** last mod file date 2 bytes |
4138 | *** crc-32 4 bytes |
4139 | *** compressed size 4 bytes |
4140 | *** uncompressed size 4 bytes |
4141 | *** file name length 2 bytes |
4142 | *** extra field length 2 bytes |
4143 | *** file comment length 2 bytes |
4144 | *** disk number start 2 bytes |
4145 | *** internal file attributes 2 bytes |
4146 | *** external file attributes 4 bytes |
4147 | *** relative offset of local header 4 bytes |
4148 | */ |
4149 | typedef struct ZipfileCDS ZipfileCDS; |
4150 | struct ZipfileCDS { |
4151 | u16 iVersionMadeBy; |
4152 | u16 iVersionExtract; |
4153 | u16 flags; |
4154 | u16 iCompression; |
4155 | u16 mTime; |
4156 | u16 mDate; |
4157 | u32 crc32; |
4158 | u32 szCompressed; |
4159 | u32 szUncompressed; |
4160 | u16 nFile; |
4161 | u16 nExtra; |
4162 | u16 nComment; |
4163 | u16 iDiskStart; |
4164 | u16 iInternalAttr; |
4165 | u32 iExternalAttr; |
4166 | u32 iOffset; |
4167 | char *zFile; /* Filename (sqlite3_malloc()) */ |
4168 | }; |
4169 | |
4170 | /* |
4171 | *** 4.3.7 Local file header: |
4172 | *** |
4173 | *** local file header signature 4 bytes (0x04034b50) |
4174 | *** version needed to extract 2 bytes |
4175 | *** general purpose bit flag 2 bytes |
4176 | *** compression method 2 bytes |
4177 | *** last mod file time 2 bytes |
4178 | *** last mod file date 2 bytes |
4179 | *** crc-32 4 bytes |
4180 | *** compressed size 4 bytes |
4181 | *** uncompressed size 4 bytes |
4182 | *** file name length 2 bytes |
4183 | *** extra field length 2 bytes |
4184 | *** |
4185 | */ |
4186 | typedef struct ZipfileLFH ZipfileLFH; |
4187 | struct ZipfileLFH { |
4188 | u16 iVersionExtract; |
4189 | u16 flags; |
4190 | u16 iCompression; |
4191 | u16 mTime; |
4192 | u16 mDate; |
4193 | u32 crc32; |
4194 | u32 szCompressed; |
4195 | u32 szUncompressed; |
4196 | u16 nFile; |
4197 | u16 nExtra; |
4198 | }; |
4199 | |
4200 | typedef struct ZipfileEntry ZipfileEntry; |
4201 | struct ZipfileEntry { |
4202 | ZipfileCDS cds; /* Parsed CDS record */ |
4203 | u32 mUnixTime; /* Modification time, in UNIX format */ |
4204 | u8 *aExtra; /* cds.nExtra+cds.nComment bytes of extra data */ |
4205 | i64 iDataOff; /* Offset to data in file (if aData==0) */ |
4206 | u8 *aData; /* cds.szCompressed bytes of compressed data */ |
4207 | ZipfileEntry *pNext; /* Next element in in-memory CDS */ |
4208 | }; |
4209 | |
4210 | /* |
4211 | ** Cursor type for zipfile tables. |
4212 | */ |
4213 | typedef struct ZipfileCsr ZipfileCsr; |
4214 | struct ZipfileCsr { |
4215 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
4216 | i64 iId; /* Cursor ID */ |
4217 | u8 bEof; /* True when at EOF */ |
4218 | u8 bNoop; /* If next xNext() call is no-op */ |
4219 | |
4220 | /* Used outside of write transactions */ |
4221 | FILE *pFile; /* Zip file */ |
4222 | i64 iNextOff; /* Offset of next record in central directory */ |
4223 | ZipfileEOCD eocd; /* Parse of central directory record */ |
4224 | |
4225 | ZipfileEntry *pFreeEntry; /* Free this list when cursor is closed or reset */ |
4226 | ZipfileEntry *pCurrent; /* Current entry */ |
4227 | ZipfileCsr *pCsrNext; /* Next cursor on same virtual table */ |
4228 | }; |
4229 | |
4230 | typedef struct ZipfileTab ZipfileTab; |
4231 | struct ZipfileTab { |
4232 | sqlite3_vtab base; /* Base class - must be first */ |
4233 | char *zFile; /* Zip file this table accesses (may be NULL) */ |
4234 | sqlite3 *db; /* Host database connection */ |
4235 | u8 *aBuffer; /* Temporary buffer used for various tasks */ |
4236 | |
4237 | ZipfileCsr *pCsrList; /* List of cursors */ |
4238 | i64 iNextCsrid; |
4239 | |
4240 | /* The following are used by write transactions only */ |
4241 | ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */ |
4242 | ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */ |
4243 | FILE *pWriteFd; /* File handle open on zip archive */ |
4244 | i64 szCurrent; /* Current size of zip archive */ |
4245 | i64 szOrig; /* Size of archive at start of transaction */ |
4246 | }; |
4247 | |
4248 | /* |
4249 | ** Set the error message contained in context ctx to the results of |
4250 | ** vprintf(zFmt, ...). |
4251 | */ |
4252 | static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...) { |
4253 | char *zMsg = 0; |
4254 | va_list ap; |
4255 | va_start(ap, zFmt); |
4256 | zMsg = sqlite3_vmprintf(zFmt, ap); |
4257 | sqlite3_result_error(ctx, zMsg, -1); |
4258 | sqlite3_free(zMsg); |
4259 | va_end(ap); |
4260 | } |
4261 | |
4262 | /* |
4263 | ** If string zIn is quoted, dequote it in place. Otherwise, if the string |
4264 | ** is not quoted, do nothing. |
4265 | */ |
4266 | static void zipfileDequote(char *zIn) { |
4267 | char q = zIn[0]; |
4268 | if (q == '"' || q == '\'' || q == '`' || q == '[') { |
4269 | int iIn = 1; |
4270 | int iOut = 0; |
4271 | if (q == '[') |
4272 | q = ']'; |
4273 | while (ALWAYS(zIn[iIn])) { |
4274 | char c = zIn[iIn++]; |
4275 | if (c == q && zIn[iIn++] != q) |
4276 | break; |
4277 | zIn[iOut++] = c; |
4278 | } |
4279 | zIn[iOut] = '\0'; |
4280 | } |
4281 | } |
4282 | |
4283 | /* |
4284 | ** Construct a new ZipfileTab virtual table object. |
4285 | ** |
4286 | ** argv[0] -> module name ("zipfile") |
4287 | ** argv[1] -> database name |
4288 | ** argv[2] -> table name |
4289 | ** argv[...] -> "column name" and other module argument fields. |
4290 | */ |
4291 | static int zipfileConnect(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, |
4292 | char **pzErr) { |
4293 | int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE; |
4294 | int nFile = 0; |
4295 | const char *zFile = 0; |
4296 | ZipfileTab *pNew = 0; |
4297 | int rc; |
4298 | |
4299 | /* If the table name is not "zipfile", require that the argument be |
4300 | ** specified. This stops zipfile tables from being created as: |
4301 | ** |
4302 | ** CREATE VIRTUAL TABLE zzz USING zipfile(); |
4303 | ** |
4304 | ** It does not prevent: |
4305 | ** |
4306 | ** CREATE VIRTUAL TABLE zipfile USING zipfile(); |
4307 | */ |
4308 | assert(0 == sqlite3_stricmp(argv[0], "zipfile" )); |
4309 | if ((0 != sqlite3_stricmp(argv[2], "zipfile" ) && argc < 4) || argc > 4) { |
4310 | *pzErr = sqlite3_mprintf("zipfile constructor requires one argument" ); |
4311 | return SQLITE_ERROR; |
4312 | } |
4313 | |
4314 | if (argc > 3) { |
4315 | zFile = argv[3]; |
4316 | nFile = (int)strlen(zFile) + 1; |
4317 | } |
4318 | |
4319 | rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA); |
4320 | if (rc == SQLITE_OK) { |
4321 | pNew = (ZipfileTab *)sqlite3_malloc(nByte + nFile); |
4322 | if (pNew == 0) |
4323 | return SQLITE_NOMEM; |
4324 | memset(pNew, 0, nByte + nFile); |
4325 | pNew->db = db; |
4326 | pNew->aBuffer = (u8 *)&pNew[1]; |
4327 | if (zFile) { |
4328 | pNew->zFile = (char *)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE]; |
4329 | memcpy(pNew->zFile, zFile, nFile); |
4330 | zipfileDequote(pNew->zFile); |
4331 | } |
4332 | } |
4333 | *ppVtab = (sqlite3_vtab *)pNew; |
4334 | return rc; |
4335 | } |
4336 | |
4337 | /* |
4338 | ** Free the ZipfileEntry structure indicated by the only argument. |
4339 | */ |
4340 | static void zipfileEntryFree(ZipfileEntry *p) { |
4341 | if (p) { |
4342 | sqlite3_free(p->cds.zFile); |
4343 | sqlite3_free(p); |
4344 | } |
4345 | } |
4346 | |
4347 | /* |
4348 | ** Release resources that should be freed at the end of a write |
4349 | ** transaction. |
4350 | */ |
4351 | static void zipfileCleanupTransaction(ZipfileTab *pTab) { |
4352 | ZipfileEntry *pEntry; |
4353 | ZipfileEntry *pNext; |
4354 | |
4355 | if (pTab->pWriteFd) { |
4356 | fclose(pTab->pWriteFd); |
4357 | pTab->pWriteFd = 0; |
4358 | } |
4359 | for (pEntry = pTab->pFirstEntry; pEntry; pEntry = pNext) { |
4360 | pNext = pEntry->pNext; |
4361 | zipfileEntryFree(pEntry); |
4362 | } |
4363 | pTab->pFirstEntry = 0; |
4364 | pTab->pLastEntry = 0; |
4365 | pTab->szCurrent = 0; |
4366 | pTab->szOrig = 0; |
4367 | } |
4368 | |
4369 | /* |
4370 | ** This method is the destructor for zipfile vtab objects. |
4371 | */ |
4372 | static int zipfileDisconnect(sqlite3_vtab *pVtab) { |
4373 | zipfileCleanupTransaction((ZipfileTab *)pVtab); |
4374 | sqlite3_free(pVtab); |
4375 | return SQLITE_OK; |
4376 | } |
4377 | |
4378 | /* |
4379 | ** Constructor for a new ZipfileCsr object. |
4380 | */ |
4381 | static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr) { |
4382 | ZipfileTab *pTab = (ZipfileTab *)p; |
4383 | ZipfileCsr *pCsr; |
4384 | pCsr = sqlite3_malloc(sizeof(*pCsr)); |
4385 | *ppCsr = (sqlite3_vtab_cursor *)pCsr; |
4386 | if (pCsr == 0) { |
4387 | return SQLITE_NOMEM; |
4388 | } |
4389 | memset(pCsr, 0, sizeof(*pCsr)); |
4390 | pCsr->iId = ++pTab->iNextCsrid; |
4391 | pCsr->pCsrNext = pTab->pCsrList; |
4392 | pTab->pCsrList = pCsr; |
4393 | return SQLITE_OK; |
4394 | } |
4395 | |
4396 | /* |
4397 | ** Reset a cursor back to the state it was in when first returned |
4398 | ** by zipfileOpen(). |
4399 | */ |
4400 | static void zipfileResetCursor(ZipfileCsr *pCsr) { |
4401 | ZipfileEntry *p; |
4402 | ZipfileEntry *pNext; |
4403 | |
4404 | pCsr->bEof = 0; |
4405 | if (pCsr->pFile) { |
4406 | fclose(pCsr->pFile); |
4407 | pCsr->pFile = 0; |
4408 | zipfileEntryFree(pCsr->pCurrent); |
4409 | pCsr->pCurrent = 0; |
4410 | } |
4411 | |
4412 | for (p = pCsr->pFreeEntry; p; p = pNext) { |
4413 | pNext = p->pNext; |
4414 | zipfileEntryFree(p); |
4415 | } |
4416 | } |
4417 | |
4418 | /* |
4419 | ** Destructor for an ZipfileCsr. |
4420 | */ |
4421 | static int zipfileClose(sqlite3_vtab_cursor *cur) { |
4422 | ZipfileCsr *pCsr = (ZipfileCsr *)cur; |
4423 | ZipfileTab *pTab = (ZipfileTab *)(pCsr->base.pVtab); |
4424 | ZipfileCsr **pp; |
4425 | zipfileResetCursor(pCsr); |
4426 | |
4427 | /* Remove this cursor from the ZipfileTab.pCsrList list. */ |
4428 | for (pp = &pTab->pCsrList; *pp != pCsr; pp = &((*pp)->pCsrNext)) |
4429 | ; |
4430 | *pp = pCsr->pCsrNext; |
4431 | |
4432 | sqlite3_free(pCsr); |
4433 | return SQLITE_OK; |
4434 | } |
4435 | |
4436 | /* |
4437 | ** Set the error message for the virtual table associated with cursor |
4438 | ** pCsr to the results of vprintf(zFmt, ...). |
4439 | */ |
4440 | static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...) { |
4441 | va_list ap; |
4442 | va_start(ap, zFmt); |
4443 | sqlite3_free(pTab->base.zErrMsg); |
4444 | pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap); |
4445 | va_end(ap); |
4446 | } |
4447 | static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...) { |
4448 | va_list ap; |
4449 | va_start(ap, zFmt); |
4450 | sqlite3_free(pCsr->base.pVtab->zErrMsg); |
4451 | pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); |
4452 | va_end(ap); |
4453 | } |
4454 | |
4455 | /* |
4456 | ** Read nRead bytes of data from offset iOff of file pFile into buffer |
4457 | ** aRead[]. Return SQLITE_OK if successful, or an SQLite error code |
4458 | ** otherwise. |
4459 | ** |
4460 | ** If an error does occur, output variable (*pzErrmsg) may be set to point |
4461 | ** to an English language error message. It is the responsibility of the |
4462 | ** caller to eventually free this buffer using |
4463 | ** sqlite3_free(). |
4464 | */ |
4465 | static int zipfileReadData(FILE *pFile, /* Read from this file */ |
4466 | u8 *aRead, /* Read into this buffer */ |
4467 | int nRead, /* Number of bytes to read */ |
4468 | i64 iOff, /* Offset to read from */ |
4469 | char **pzErrmsg /* OUT: Error message (from sqlite3_malloc) */ |
4470 | ) { |
4471 | size_t n; |
4472 | fseek(pFile, (long)iOff, SEEK_SET); |
4473 | n = fread(aRead, 1, nRead, pFile); |
4474 | if ((int)n != nRead) { |
4475 | *pzErrmsg = sqlite3_mprintf("error in fread()" ); |
4476 | return SQLITE_ERROR; |
4477 | } |
4478 | return SQLITE_OK; |
4479 | } |
4480 | |
4481 | static int zipfileAppendData(ZipfileTab *pTab, const u8 *aWrite, int nWrite) { |
4482 | size_t n; |
4483 | fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET); |
4484 | n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd); |
4485 | if ((int)n != nWrite) { |
4486 | pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()" ); |
4487 | return SQLITE_ERROR; |
4488 | } |
4489 | pTab->szCurrent += nWrite; |
4490 | return SQLITE_OK; |
4491 | } |
4492 | |
4493 | /* |
4494 | ** Read and return a 16-bit little-endian unsigned integer from buffer aBuf. |
4495 | */ |
4496 | static u16 zipfileGetU16(const u8 *aBuf) { |
4497 | return (aBuf[1] << 8) + aBuf[0]; |
4498 | } |
4499 | |
4500 | /* |
4501 | ** Read and return a 32-bit little-endian unsigned integer from buffer aBuf. |
4502 | */ |
4503 | static u32 zipfileGetU32(const u8 *aBuf) { |
4504 | return ((u32)(aBuf[3]) << 24) + ((u32)(aBuf[2]) << 16) + ((u32)(aBuf[1]) << 8) + ((u32)(aBuf[0]) << 0); |
4505 | } |
4506 | |
4507 | /* |
4508 | ** Write a 16-bit little endiate integer into buffer aBuf. |
4509 | */ |
4510 | static void zipfilePutU16(u8 *aBuf, u16 val) { |
4511 | aBuf[0] = val & 0xFF; |
4512 | aBuf[1] = (val >> 8) & 0xFF; |
4513 | } |
4514 | |
4515 | /* |
4516 | ** Write a 32-bit little endiate integer into buffer aBuf. |
4517 | */ |
4518 | static void zipfilePutU32(u8 *aBuf, u32 val) { |
4519 | aBuf[0] = val & 0xFF; |
4520 | aBuf[1] = (val >> 8) & 0xFF; |
4521 | aBuf[2] = (val >> 16) & 0xFF; |
4522 | aBuf[3] = (val >> 24) & 0xFF; |
4523 | } |
4524 | |
4525 | #define zipfileRead32(aBuf) (aBuf += 4, zipfileGetU32(aBuf - 4)) |
4526 | #define zipfileRead16(aBuf) (aBuf += 2, zipfileGetU16(aBuf - 2)) |
4527 | |
4528 | #define zipfileWrite32(aBuf, val) \ |
4529 | { \ |
4530 | zipfilePutU32(aBuf, val); \ |
4531 | aBuf += 4; \ |
4532 | } |
4533 | #define zipfileWrite16(aBuf, val) \ |
4534 | { \ |
4535 | zipfilePutU16(aBuf, val); \ |
4536 | aBuf += 2; \ |
4537 | } |
4538 | |
4539 | /* |
4540 | ** Magic numbers used to read CDS records. |
4541 | */ |
4542 | #define ZIPFILE_CDS_NFILE_OFF 28 |
4543 | #define ZIPFILE_CDS_SZCOMPRESSED_OFF 20 |
4544 | |
4545 | /* |
4546 | ** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR |
4547 | ** if the record is not well-formed, or SQLITE_OK otherwise. |
4548 | */ |
4549 | static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS) { |
4550 | u8 *aRead = aBuf; |
4551 | u32 sig = zipfileRead32(aRead); |
4552 | int rc = SQLITE_OK; |
4553 | if (sig != ZIPFILE_SIGNATURE_CDS) { |
4554 | rc = SQLITE_ERROR; |
4555 | } else { |
4556 | pCDS->iVersionMadeBy = zipfileRead16(aRead); |
4557 | pCDS->iVersionExtract = zipfileRead16(aRead); |
4558 | pCDS->flags = zipfileRead16(aRead); |
4559 | pCDS->iCompression = zipfileRead16(aRead); |
4560 | pCDS->mTime = zipfileRead16(aRead); |
4561 | pCDS->mDate = zipfileRead16(aRead); |
4562 | pCDS->crc32 = zipfileRead32(aRead); |
4563 | pCDS->szCompressed = zipfileRead32(aRead); |
4564 | pCDS->szUncompressed = zipfileRead32(aRead); |
4565 | assert(aRead == &aBuf[ZIPFILE_CDS_NFILE_OFF]); |
4566 | pCDS->nFile = zipfileRead16(aRead); |
4567 | pCDS->nExtra = zipfileRead16(aRead); |
4568 | pCDS->nComment = zipfileRead16(aRead); |
4569 | pCDS->iDiskStart = zipfileRead16(aRead); |
4570 | pCDS->iInternalAttr = zipfileRead16(aRead); |
4571 | pCDS->iExternalAttr = zipfileRead32(aRead); |
4572 | pCDS->iOffset = zipfileRead32(aRead); |
4573 | assert(aRead == &aBuf[ZIPFILE_CDS_FIXED_SZ]); |
4574 | } |
4575 | |
4576 | return rc; |
4577 | } |
4578 | |
4579 | /* |
4580 | ** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR |
4581 | ** if the record is not well-formed, or SQLITE_OK otherwise. |
4582 | */ |
4583 | static int zipfileReadLFH(u8 *aBuffer, ZipfileLFH *pLFH) { |
4584 | u8 *aRead = aBuffer; |
4585 | int rc = SQLITE_OK; |
4586 | |
4587 | u32 sig = zipfileRead32(aRead); |
4588 | if (sig != ZIPFILE_SIGNATURE_LFH) { |
4589 | rc = SQLITE_ERROR; |
4590 | } else { |
4591 | pLFH->iVersionExtract = zipfileRead16(aRead); |
4592 | pLFH->flags = zipfileRead16(aRead); |
4593 | pLFH->iCompression = zipfileRead16(aRead); |
4594 | pLFH->mTime = zipfileRead16(aRead); |
4595 | pLFH->mDate = zipfileRead16(aRead); |
4596 | pLFH->crc32 = zipfileRead32(aRead); |
4597 | pLFH->szCompressed = zipfileRead32(aRead); |
4598 | pLFH->szUncompressed = zipfileRead32(aRead); |
4599 | pLFH->nFile = zipfileRead16(aRead); |
4600 | pLFH->nExtra = zipfileRead16(aRead); |
4601 | } |
4602 | return rc; |
4603 | } |
4604 | |
4605 | /* |
4606 | ** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields. |
4607 | ** Scan through this buffer to find an "extra-timestamp" field. If one |
4608 | ** exists, extract the 32-bit modification-timestamp from it and store |
4609 | ** the value in output parameter *pmTime. |
4610 | ** |
4611 | ** Zero is returned if no extra-timestamp record could be found (and so |
4612 | ** *pmTime is left unchanged), or non-zero otherwise. |
4613 | ** |
4614 | ** The general format of an extra field is: |
4615 | ** |
4616 | ** Header ID 2 bytes |
4617 | ** Data Size 2 bytes |
4618 | ** Data N bytes |
4619 | */ |
4620 | static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime) { |
4621 | int ret = 0; |
4622 | u8 *p = aExtra; |
4623 | u8 *pEnd = &aExtra[nExtra]; |
4624 | |
4625 | while (p < pEnd) { |
4626 | u16 id = zipfileRead16(p); |
4627 | u16 nByte = zipfileRead16(p); |
4628 | |
4629 | switch (id) { |
4630 | case ZIPFILE_EXTRA_TIMESTAMP: { |
4631 | u8 b = p[0]; |
4632 | if (b & 0x01) { /* 0x01 -> modtime is present */ |
4633 | *pmTime = zipfileGetU32(&p[1]); |
4634 | ret = 1; |
4635 | } |
4636 | break; |
4637 | } |
4638 | } |
4639 | |
4640 | p += nByte; |
4641 | } |
4642 | return ret; |
4643 | } |
4644 | |
4645 | /* |
4646 | ** Convert the standard MS-DOS timestamp stored in the mTime and mDate |
4647 | ** fields of the CDS structure passed as the only argument to a 32-bit |
4648 | ** UNIX seconds-since-the-epoch timestamp. Return the result. |
4649 | ** |
4650 | ** "Standard" MS-DOS time format: |
4651 | ** |
4652 | ** File modification time: |
4653 | ** Bits 00-04: seconds divided by 2 |
4654 | ** Bits 05-10: minute |
4655 | ** Bits 11-15: hour |
4656 | ** File modification date: |
4657 | ** Bits 00-04: day |
4658 | ** Bits 05-08: month (1-12) |
4659 | ** Bits 09-15: years from 1980 |
4660 | ** |
4661 | ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx |
4662 | */ |
4663 | static u32 zipfileMtime(ZipfileCDS *pCDS) { |
4664 | int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F)); |
4665 | int M = ((pCDS->mDate >> 5) & 0x0F); |
4666 | int D = (pCDS->mDate & 0x1F); |
4667 | int B = -13; |
4668 | |
4669 | int sec = (pCDS->mTime & 0x1F) * 2; |
4670 | int min = (pCDS->mTime >> 5) & 0x3F; |
4671 | int hr = (pCDS->mTime >> 11) & 0x1F; |
4672 | i64 JD; |
4673 | |
4674 | /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */ |
4675 | |
4676 | /* Calculate the JD in seconds for noon on the day in question */ |
4677 | if (M < 3) { |
4678 | Y = Y - 1; |
4679 | M = M + 12; |
4680 | } |
4681 | JD = (i64)(24 * 60 * 60) * ((int)(365.25 * (Y + 4716)) + (int)(30.6001 * (M + 1)) + D + B - 1524); |
4682 | |
4683 | /* Correct the JD for the time within the day */ |
4684 | JD += (hr - 12) * 3600 + min * 60 + sec; |
4685 | |
4686 | /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */ |
4687 | return (u32)(JD - (i64)(24405875) * 24 * 60 * 6); |
4688 | } |
4689 | |
4690 | /* |
4691 | ** The opposite of zipfileMtime(). This function populates the mTime and |
4692 | ** mDate fields of the CDS structure passed as the first argument according |
4693 | ** to the UNIX timestamp value passed as the second. |
4694 | */ |
4695 | static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime) { |
4696 | /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */ |
4697 | i64 JD = (i64)2440588 + mUnixTime / (24 * 60 * 60); |
4698 | |
4699 | int A, B, C, D, E; |
4700 | int yr, mon, day; |
4701 | int hr, min, sec; |
4702 | |
4703 | A = (int)((JD - 1867216.25) / 36524.25); |
4704 | A = (int)(JD + 1 + A - (A / 4)); |
4705 | B = A + 1524; |
4706 | C = (int)((B - 122.1) / 365.25); |
4707 | D = (36525 * (C & 32767)) / 100; |
4708 | E = (int)((B - D) / 30.6001); |
4709 | |
4710 | day = B - D - (int)(30.6001 * E); |
4711 | mon = (E < 14 ? E - 1 : E - 13); |
4712 | yr = mon > 2 ? C - 4716 : C - 4715; |
4713 | |
4714 | hr = (mUnixTime % (24 * 60 * 60)) / (60 * 60); |
4715 | min = (mUnixTime % (60 * 60)) / 60; |
4716 | sec = (mUnixTime % 60); |
4717 | |
4718 | if (yr >= 1980) { |
4719 | pCds->mDate = (u16)(day + (mon << 5) + ((yr - 1980) << 9)); |
4720 | pCds->mTime = (u16)(sec / 2 + (min << 5) + (hr << 11)); |
4721 | } else { |
4722 | pCds->mDate = pCds->mTime = 0; |
4723 | } |
4724 | |
4725 | assert(mUnixTime < 315507600 || mUnixTime == zipfileMtime(pCds) || |
4726 | ((mUnixTime % 2) && mUnixTime - 1 == zipfileMtime(pCds)) |
4727 | /* || (mUnixTime % 2) */ |
4728 | ); |
4729 | } |
4730 | |
4731 | /* |
4732 | ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in |
4733 | ** size) containing an entire zip archive image. Or, if aBlob is NULL, |
4734 | ** then pFile is a file-handle open on a zip file. In either case, this |
4735 | ** function creates a ZipfileEntry object based on the zip archive entry |
4736 | ** for which the CDS record is at offset iOff. |
4737 | ** |
4738 | ** If successful, SQLITE_OK is returned and (*ppEntry) set to point to |
4739 | ** the new object. Otherwise, an SQLite error code is returned and the |
4740 | ** final value of (*ppEntry) undefined. |
4741 | */ |
4742 | static int zipfileGetEntry(ZipfileTab *pTab, /* Store any error message here */ |
4743 | const u8 *aBlob, /* Pointer to in-memory file image */ |
4744 | int nBlob, /* Size of aBlob[] in bytes */ |
4745 | FILE *pFile, /* If aBlob==0, read from this file */ |
4746 | i64 iOff, /* Offset of CDS record */ |
4747 | ZipfileEntry **ppEntry /* OUT: Pointer to new object */ |
4748 | ) { |
4749 | u8 *aRead; |
4750 | char **pzErr = &pTab->base.zErrMsg; |
4751 | int rc = SQLITE_OK; |
4752 | |
4753 | if (aBlob == 0) { |
4754 | aRead = pTab->aBuffer; |
4755 | rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); |
4756 | } else { |
4757 | aRead = (u8 *)&aBlob[iOff]; |
4758 | } |
4759 | |
4760 | if (rc == SQLITE_OK) { |
4761 | int nAlloc; |
4762 | ZipfileEntry *pNew; |
4763 | |
4764 | int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]); |
4765 | int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF + 2]); |
4766 | nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF + 4]); |
4767 | |
4768 | nAlloc = sizeof(ZipfileEntry) + nExtra; |
4769 | if (aBlob) { |
4770 | nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]); |
4771 | } |
4772 | |
4773 | pNew = (ZipfileEntry *)sqlite3_malloc(nAlloc); |
4774 | if (pNew == 0) { |
4775 | rc = SQLITE_NOMEM; |
4776 | } else { |
4777 | memset(pNew, 0, sizeof(ZipfileEntry)); |
4778 | rc = zipfileReadCDS(aRead, &pNew->cds); |
4779 | if (rc != SQLITE_OK) { |
4780 | *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld" , iOff); |
4781 | } else if (aBlob == 0) { |
4782 | rc = zipfileReadData(pFile, aRead, nExtra + nFile, iOff + ZIPFILE_CDS_FIXED_SZ, pzErr); |
4783 | } else { |
4784 | aRead = (u8 *)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; |
4785 | } |
4786 | } |
4787 | |
4788 | if (rc == SQLITE_OK) { |
4789 | u32 *pt = &pNew->mUnixTime; |
4790 | pNew->cds.zFile = sqlite3_mprintf("%.*s" , nFile, aRead); |
4791 | pNew->aExtra = (u8 *)&pNew[1]; |
4792 | memcpy(pNew->aExtra, &aRead[nFile], nExtra); |
4793 | if (pNew->cds.zFile == 0) { |
4794 | rc = SQLITE_NOMEM; |
4795 | } else if (0 == zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt)) { |
4796 | pNew->mUnixTime = zipfileMtime(&pNew->cds); |
4797 | } |
4798 | } |
4799 | |
4800 | if (rc == SQLITE_OK) { |
4801 | static const int szFix = ZIPFILE_LFH_FIXED_SZ; |
4802 | ZipfileLFH lfh; |
4803 | if (pFile) { |
4804 | rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); |
4805 | } else { |
4806 | aRead = (u8 *)&aBlob[pNew->cds.iOffset]; |
4807 | } |
4808 | |
4809 | rc = zipfileReadLFH(aRead, &lfh); |
4810 | if (rc == SQLITE_OK) { |
4811 | pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; |
4812 | pNew->iDataOff += lfh.nFile + lfh.nExtra; |
4813 | if (aBlob && pNew->cds.szCompressed) { |
4814 | pNew->aData = &pNew->aExtra[nExtra]; |
4815 | memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); |
4816 | } |
4817 | } else { |
4818 | *pzErr = sqlite3_mprintf("failed to read LFH at offset %d" , (int)pNew->cds.iOffset); |
4819 | } |
4820 | } |
4821 | |
4822 | if (rc != SQLITE_OK) { |
4823 | zipfileEntryFree(pNew); |
4824 | } else { |
4825 | *ppEntry = pNew; |
4826 | } |
4827 | } |
4828 | |
4829 | return rc; |
4830 | } |
4831 | |
4832 | /* |
4833 | ** Advance an ZipfileCsr to its next row of output. |
4834 | */ |
4835 | static int zipfileNext(sqlite3_vtab_cursor *cur) { |
4836 | ZipfileCsr *pCsr = (ZipfileCsr *)cur; |
4837 | int rc = SQLITE_OK; |
4838 | |
4839 | if (pCsr->pFile) { |
4840 | i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize; |
4841 | zipfileEntryFree(pCsr->pCurrent); |
4842 | pCsr->pCurrent = 0; |
4843 | if (pCsr->iNextOff >= iEof) { |
4844 | pCsr->bEof = 1; |
4845 | } else { |
4846 | ZipfileEntry *p = 0; |
4847 | ZipfileTab *pTab = (ZipfileTab *)(cur->pVtab); |
4848 | rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p); |
4849 | if (rc == SQLITE_OK) { |
4850 | pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ; |
4851 | pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment; |
4852 | } |
4853 | pCsr->pCurrent = p; |
4854 | } |
4855 | } else { |
4856 | if (!pCsr->bNoop) { |
4857 | pCsr->pCurrent = pCsr->pCurrent->pNext; |
4858 | } |
4859 | if (pCsr->pCurrent == 0) { |
4860 | pCsr->bEof = 1; |
4861 | } |
4862 | } |
4863 | |
4864 | pCsr->bNoop = 0; |
4865 | return rc; |
4866 | } |
4867 | |
4868 | static void zipfileFree(void *p) { |
4869 | sqlite3_free(p); |
4870 | } |
4871 | |
4872 | /* |
4873 | ** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the |
4874 | ** size is nOut bytes. This function uncompresses the data and sets the |
4875 | ** return value in context pCtx to the result (a blob). |
4876 | ** |
4877 | ** If an error occurs, an error code is left in pCtx instead. |
4878 | */ |
4879 | static void zipfileInflate(sqlite3_context *pCtx, /* Store result here */ |
4880 | const u8 *aIn, /* Compressed data */ |
4881 | int nIn, /* Size of buffer aIn[] in bytes */ |
4882 | int nOut /* Expected output size */ |
4883 | ) { |
4884 | u8 *aRes = sqlite3_malloc(nOut); |
4885 | if (aRes == 0) { |
4886 | sqlite3_result_error_nomem(pCtx); |
4887 | } else { |
4888 | int err; |
4889 | z_stream str; |
4890 | memset(&str, 0, sizeof(str)); |
4891 | |
4892 | str.next_in = (Byte *)aIn; |
4893 | str.avail_in = nIn; |
4894 | str.next_out = (Byte *)aRes; |
4895 | str.avail_out = nOut; |
4896 | |
4897 | err = inflateInit2(&str, -15); |
4898 | if (err != Z_OK) { |
4899 | zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)" , err); |
4900 | } else { |
4901 | err = inflate(&str, Z_NO_FLUSH); |
4902 | if (err != Z_STREAM_END) { |
4903 | zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)" , err); |
4904 | } else { |
4905 | sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree); |
4906 | aRes = 0; |
4907 | } |
4908 | } |
4909 | sqlite3_free(aRes); |
4910 | inflateEnd(&str); |
4911 | } |
4912 | } |
4913 | |
4914 | /* |
4915 | ** Buffer aIn (size nIn bytes) contains uncompressed data. This function |
4916 | ** compresses it and sets (*ppOut) to point to a buffer containing the |
4917 | ** compressed data. The caller is responsible for eventually calling |
4918 | ** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) |
4919 | ** is set to the size of buffer (*ppOut) in bytes. |
4920 | ** |
4921 | ** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error |
4922 | ** code is returned and an error message left in virtual-table handle |
4923 | ** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this |
4924 | ** case. |
4925 | */ |
4926 | static int zipfileDeflate(const u8 *aIn, int nIn, /* Input */ |
4927 | u8 **ppOut, int *pnOut, /* Output */ |
4928 | char **pzErr /* OUT: Error message */ |
4929 | ) { |
4930 | int nAlloc = (int)compressBound(nIn); |
4931 | u8 *aOut; |
4932 | int rc = SQLITE_OK; |
4933 | |
4934 | aOut = (u8 *)sqlite3_malloc(nAlloc); |
4935 | if (aOut == 0) { |
4936 | rc = SQLITE_NOMEM; |
4937 | } else { |
4938 | int res; |
4939 | z_stream str; |
4940 | memset(&str, 0, sizeof(str)); |
4941 | str.next_in = (Bytef *)aIn; |
4942 | str.avail_in = nIn; |
4943 | str.next_out = aOut; |
4944 | str.avail_out = nAlloc; |
4945 | |
4946 | deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); |
4947 | res = deflate(&str, Z_FINISH); |
4948 | |
4949 | if (res == Z_STREAM_END) { |
4950 | *ppOut = aOut; |
4951 | *pnOut = (int)str.total_out; |
4952 | } else { |
4953 | sqlite3_free(aOut); |
4954 | *pzErr = sqlite3_mprintf("zipfile: deflate() error" ); |
4955 | rc = SQLITE_ERROR; |
4956 | } |
4957 | deflateEnd(&str); |
4958 | } |
4959 | |
4960 | return rc; |
4961 | } |
4962 | |
4963 | /* |
4964 | ** Return values of columns for the row at which the series_cursor |
4965 | ** is currently pointing. |
4966 | */ |
4967 | static int zipfileColumn(sqlite3_vtab_cursor *cur, /* The cursor */ |
4968 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ |
4969 | int i /* Which column to return */ |
4970 | ) { |
4971 | ZipfileCsr *pCsr = (ZipfileCsr *)cur; |
4972 | ZipfileCDS *pCDS = &pCsr->pCurrent->cds; |
4973 | int rc = SQLITE_OK; |
4974 | switch (i) { |
4975 | case 0: /* name */ |
4976 | sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT); |
4977 | break; |
4978 | case 1: /* mode */ |
4979 | /* TODO: Whether or not the following is correct surely depends on |
4980 | ** the platform on which the archive was created. */ |
4981 | sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16); |
4982 | break; |
4983 | case 2: { /* mtime */ |
4984 | sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime); |
4985 | break; |
4986 | } |
4987 | case 3: { /* sz */ |
4988 | if (sqlite3_vtab_nochange(ctx) == 0) { |
4989 | sqlite3_result_int64(ctx, pCDS->szUncompressed); |
4990 | } |
4991 | break; |
4992 | } |
4993 | case 4: /* rawdata */ |
4994 | if (sqlite3_vtab_nochange(ctx)) |
4995 | break; |
4996 | case 5: { /* data */ |
4997 | if (i == 4 || pCDS->iCompression == 0 || pCDS->iCompression == 8) { |
4998 | int sz = pCDS->szCompressed; |
4999 | int szFinal = pCDS->szUncompressed; |
5000 | if (szFinal > 0) { |
5001 | u8 *aBuf; |
5002 | u8 *aFree = 0; |
5003 | if (pCsr->pCurrent->aData) { |
5004 | aBuf = pCsr->pCurrent->aData; |
5005 | } else { |
5006 | aBuf = aFree = sqlite3_malloc(sz); |
5007 | if (aBuf == 0) { |
5008 | rc = SQLITE_NOMEM; |
5009 | } else { |
5010 | FILE *pFile = pCsr->pFile; |
5011 | if (pFile == 0) { |
5012 | pFile = ((ZipfileTab *)(pCsr->base.pVtab))->pWriteFd; |
5013 | } |
5014 | rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff, &pCsr->base.pVtab->zErrMsg); |
5015 | } |
5016 | } |
5017 | if (rc == SQLITE_OK) { |
5018 | if (i == 5 && pCDS->iCompression) { |
5019 | zipfileInflate(ctx, aBuf, sz, szFinal); |
5020 | } else { |
5021 | sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT); |
5022 | } |
5023 | } |
5024 | sqlite3_free(aFree); |
5025 | } else { |
5026 | /* Figure out if this is a directory or a zero-sized file. Consider |
5027 | ** it to be a directory either if the mode suggests so, or if |
5028 | ** the final character in the name is '/'. */ |
5029 | u32 mode = pCDS->iExternalAttr >> 16; |
5030 | if (!(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile - 1] != '/') { |
5031 | sqlite3_result_blob(ctx, "" , 0, SQLITE_STATIC); |
5032 | } |
5033 | } |
5034 | } |
5035 | break; |
5036 | } |
5037 | case 6: /* method */ |
5038 | sqlite3_result_int(ctx, pCDS->iCompression); |
5039 | break; |
5040 | default: /* z */ |
5041 | assert(i == 7); |
5042 | sqlite3_result_int64(ctx, pCsr->iId); |
5043 | break; |
5044 | } |
5045 | |
5046 | return rc; |
5047 | } |
5048 | |
5049 | /* |
5050 | ** Return TRUE if the cursor is at EOF. |
5051 | */ |
5052 | static int zipfileEof(sqlite3_vtab_cursor *cur) { |
5053 | ZipfileCsr *pCsr = (ZipfileCsr *)cur; |
5054 | return pCsr->bEof; |
5055 | } |
5056 | |
5057 | /* |
5058 | ** If aBlob is not NULL, then it points to a buffer nBlob bytes in size |
5059 | ** containing an entire zip archive image. Or, if aBlob is NULL, then pFile |
5060 | ** is guaranteed to be a file-handle open on a zip file. |
5061 | ** |
5062 | ** This function attempts to locate the EOCD record within the zip archive |
5063 | ** and populate *pEOCD with the results of decoding it. SQLITE_OK is |
5064 | ** returned if successful. Otherwise, an SQLite error code is returned and |
5065 | ** an English language error message may be left in virtual-table pTab. |
5066 | */ |
5067 | static int zipfileReadEOCD(ZipfileTab *pTab, /* Return errors here */ |
5068 | const u8 *aBlob, /* Pointer to in-memory file image */ |
5069 | int nBlob, /* Size of aBlob[] in bytes */ |
5070 | FILE *pFile, /* Read from this file if aBlob==0 */ |
5071 | ZipfileEOCD *pEOCD /* Object to populate */ |
5072 | ) { |
5073 | u8 *aRead = pTab->aBuffer; /* Temporary buffer */ |
5074 | int nRead; /* Bytes to read from file */ |
5075 | int rc = SQLITE_OK; |
5076 | |
5077 | if (aBlob == 0) { |
5078 | i64 iOff; /* Offset to read from */ |
5079 | i64 szFile; /* Total size of file in bytes */ |
5080 | fseek(pFile, 0, SEEK_END); |
5081 | szFile = (i64)ftell(pFile); |
5082 | if (szFile == 0) { |
5083 | memset(pEOCD, 0, sizeof(ZipfileEOCD)); |
5084 | return SQLITE_OK; |
5085 | } |
5086 | nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE)); |
5087 | iOff = szFile - nRead; |
5088 | rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg); |
5089 | } else { |
5090 | nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE)); |
5091 | aRead = (u8 *)&aBlob[nBlob - nRead]; |
5092 | } |
5093 | |
5094 | if (rc == SQLITE_OK) { |
5095 | int i; |
5096 | |
5097 | /* Scan backwards looking for the signature bytes */ |
5098 | for (i = nRead - 20; i >= 0; i--) { |
5099 | if (aRead[i] == 0x50 && aRead[i + 1] == 0x4b && aRead[i + 2] == 0x05 && aRead[i + 3] == 0x06) { |
5100 | break; |
5101 | } |
5102 | } |
5103 | if (i < 0) { |
5104 | pTab->base.zErrMsg = sqlite3_mprintf("cannot find end of central directory record" ); |
5105 | return SQLITE_ERROR; |
5106 | } |
5107 | |
5108 | aRead += i + 4; |
5109 | pEOCD->iDisk = zipfileRead16(aRead); |
5110 | pEOCD->iFirstDisk = zipfileRead16(aRead); |
5111 | pEOCD->nEntry = zipfileRead16(aRead); |
5112 | pEOCD->nEntryTotal = zipfileRead16(aRead); |
5113 | pEOCD->nSize = zipfileRead32(aRead); |
5114 | pEOCD->iOffset = zipfileRead32(aRead); |
5115 | } |
5116 | |
5117 | return rc; |
5118 | } |
5119 | |
5120 | /* |
5121 | ** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry |
5122 | ** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added |
5123 | ** to the end of the list. Otherwise, it is added to the list immediately |
5124 | ** before pBefore (which is guaranteed to be a part of said list). |
5125 | */ |
5126 | static void zipfileAddEntry(ZipfileTab *pTab, ZipfileEntry *pBefore, ZipfileEntry *pNew) { |
5127 | assert((pTab->pFirstEntry == 0) == (pTab->pLastEntry == 0)); |
5128 | assert(pNew->pNext == 0); |
5129 | if (pBefore == 0) { |
5130 | if (pTab->pFirstEntry == 0) { |
5131 | pTab->pFirstEntry = pTab->pLastEntry = pNew; |
5132 | } else { |
5133 | assert(pTab->pLastEntry->pNext == 0); |
5134 | pTab->pLastEntry->pNext = pNew; |
5135 | pTab->pLastEntry = pNew; |
5136 | } |
5137 | } else { |
5138 | ZipfileEntry **pp; |
5139 | for (pp = &pTab->pFirstEntry; *pp != pBefore; pp = &((*pp)->pNext)) |
5140 | ; |
5141 | pNew->pNext = pBefore; |
5142 | *pp = pNew; |
5143 | } |
5144 | } |
5145 | |
5146 | static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob) { |
5147 | ZipfileEOCD eocd; |
5148 | int rc; |
5149 | int i; |
5150 | i64 iOff; |
5151 | |
5152 | rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd); |
5153 | iOff = eocd.iOffset; |
5154 | for (i = 0; rc == SQLITE_OK && i < eocd.nEntry; i++) { |
5155 | ZipfileEntry *pNew = 0; |
5156 | rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew); |
5157 | |
5158 | if (rc == SQLITE_OK) { |
5159 | zipfileAddEntry(pTab, 0, pNew); |
5160 | iOff += ZIPFILE_CDS_FIXED_SZ; |
5161 | iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment; |
5162 | } |
5163 | } |
5164 | return rc; |
5165 | } |
5166 | |
5167 | /* |
5168 | ** xFilter callback. |
5169 | */ |
5170 | static int zipfileFilter(sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) { |
5171 | ZipfileTab *pTab = (ZipfileTab *)cur->pVtab; |
5172 | ZipfileCsr *pCsr = (ZipfileCsr *)cur; |
5173 | const char *zFile = 0; /* Zip file to scan */ |
5174 | int rc = SQLITE_OK; /* Return Code */ |
5175 | int bInMemory = 0; /* True for an in-memory zipfile */ |
5176 | |
5177 | zipfileResetCursor(pCsr); |
5178 | |
5179 | if (pTab->zFile) { |
5180 | zFile = pTab->zFile; |
5181 | } else if (idxNum == 0) { |
5182 | zipfileCursorErr(pCsr, "zipfile() function requires an argument" ); |
5183 | return SQLITE_ERROR; |
5184 | } else if (sqlite3_value_type(argv[0]) == SQLITE_BLOB) { |
5185 | const u8 *aBlob = (const u8 *)sqlite3_value_blob(argv[0]); |
5186 | int nBlob = sqlite3_value_bytes(argv[0]); |
5187 | assert(pTab->pFirstEntry == 0); |
5188 | rc = zipfileLoadDirectory(pTab, aBlob, nBlob); |
5189 | pCsr->pFreeEntry = pTab->pFirstEntry; |
5190 | pTab->pFirstEntry = pTab->pLastEntry = 0; |
5191 | if (rc != SQLITE_OK) |
5192 | return rc; |
5193 | bInMemory = 1; |
5194 | } else { |
5195 | zFile = (const char *)sqlite3_value_text(argv[0]); |
5196 | } |
5197 | |
5198 | if (0 == pTab->pWriteFd && 0 == bInMemory) { |
5199 | pCsr->pFile = fopen(zFile, "rb" ); |
5200 | if (pCsr->pFile == 0) { |
5201 | zipfileCursorErr(pCsr, "cannot open file: %s" , zFile); |
5202 | rc = SQLITE_ERROR; |
5203 | } else { |
5204 | rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd); |
5205 | if (rc == SQLITE_OK) { |
5206 | if (pCsr->eocd.nEntry == 0) { |
5207 | pCsr->bEof = 1; |
5208 | } else { |
5209 | pCsr->iNextOff = pCsr->eocd.iOffset; |
5210 | rc = zipfileNext(cur); |
5211 | } |
5212 | } |
5213 | } |
5214 | } else { |
5215 | pCsr->bNoop = 1; |
5216 | pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry; |
5217 | rc = zipfileNext(cur); |
5218 | } |
5219 | |
5220 | return rc; |
5221 | } |
5222 | |
5223 | /* |
5224 | ** xBestIndex callback. |
5225 | */ |
5226 | static int zipfileBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo) { |
5227 | int i; |
5228 | |
5229 | for (i = 0; i < pIdxInfo->nConstraint; i++) { |
5230 | const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; |
5231 | if (pCons->usable == 0) |
5232 | continue; |
5233 | if (pCons->op != SQLITE_INDEX_CONSTRAINT_EQ) |
5234 | continue; |
5235 | if (pCons->iColumn != ZIPFILE_F_COLUMN_IDX) |
5236 | continue; |
5237 | break; |
5238 | } |
5239 | |
5240 | if (i < pIdxInfo->nConstraint) { |
5241 | pIdxInfo->aConstraintUsage[i].argvIndex = 1; |
5242 | pIdxInfo->aConstraintUsage[i].omit = 1; |
5243 | pIdxInfo->estimatedCost = 1000.0; |
5244 | pIdxInfo->idxNum = 1; |
5245 | } else { |
5246 | pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50); |
5247 | pIdxInfo->idxNum = 0; |
5248 | } |
5249 | |
5250 | return SQLITE_OK; |
5251 | } |
5252 | |
5253 | static ZipfileEntry *zipfileNewEntry(const char *zPath) { |
5254 | ZipfileEntry *pNew; |
5255 | pNew = sqlite3_malloc(sizeof(ZipfileEntry)); |
5256 | if (pNew) { |
5257 | memset(pNew, 0, sizeof(ZipfileEntry)); |
5258 | pNew->cds.zFile = sqlite3_mprintf("%s" , zPath); |
5259 | if (pNew->cds.zFile == 0) { |
5260 | sqlite3_free(pNew); |
5261 | pNew = 0; |
5262 | } |
5263 | } |
5264 | return pNew; |
5265 | } |
5266 | |
5267 | static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf) { |
5268 | ZipfileCDS *pCds = &pEntry->cds; |
5269 | u8 *a = aBuf; |
5270 | |
5271 | pCds->nExtra = 9; |
5272 | |
5273 | /* Write the LFH itself */ |
5274 | zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH); |
5275 | zipfileWrite16(a, pCds->iVersionExtract); |
5276 | zipfileWrite16(a, pCds->flags); |
5277 | zipfileWrite16(a, pCds->iCompression); |
5278 | zipfileWrite16(a, pCds->mTime); |
5279 | zipfileWrite16(a, pCds->mDate); |
5280 | zipfileWrite32(a, pCds->crc32); |
5281 | zipfileWrite32(a, pCds->szCompressed); |
5282 | zipfileWrite32(a, pCds->szUncompressed); |
5283 | zipfileWrite16(a, (u16)pCds->nFile); |
5284 | zipfileWrite16(a, pCds->nExtra); |
5285 | assert(a == &aBuf[ZIPFILE_LFH_FIXED_SZ]); |
5286 | |
5287 | /* Add the file name */ |
5288 | memcpy(a, pCds->zFile, (int)pCds->nFile); |
5289 | a += (int)pCds->nFile; |
5290 | |
5291 | /* The "extra" data */ |
5292 | zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); |
5293 | zipfileWrite16(a, 5); |
5294 | *a++ = 0x01; |
5295 | zipfileWrite32(a, pEntry->mUnixTime); |
5296 | |
5297 | return a - aBuf; |
5298 | } |
5299 | |
5300 | static int zipfileAppendEntry(ZipfileTab *pTab, ZipfileEntry *pEntry, const u8 *pData, int nData) { |
5301 | u8 *aBuf = pTab->aBuffer; |
5302 | int nBuf; |
5303 | int rc; |
5304 | |
5305 | nBuf = zipfileSerializeLFH(pEntry, aBuf); |
5306 | rc = zipfileAppendData(pTab, aBuf, nBuf); |
5307 | if (rc == SQLITE_OK) { |
5308 | pEntry->iDataOff = pTab->szCurrent; |
5309 | rc = zipfileAppendData(pTab, pData, nData); |
5310 | } |
5311 | |
5312 | return rc; |
5313 | } |
5314 | |
5315 | static int zipfileGetMode(sqlite3_value *pVal, int bIsDir, /* If true, default to directory */ |
5316 | u32 *pMode, /* OUT: Mode value */ |
5317 | char **pzErr /* OUT: Error message */ |
5318 | ) { |
5319 | const char *z = (const char *)sqlite3_value_text(pVal); |
5320 | u32 mode = 0; |
5321 | if (z == 0) { |
5322 | mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644)); |
5323 | } else if (z[0] >= '0' && z[0] <= '9') { |
5324 | mode = (unsigned int)sqlite3_value_int(pVal); |
5325 | } else { |
5326 | const char zTemplate[11] = "-rwxrwxrwx" ; |
5327 | int i; |
5328 | if (strlen(z) != 10) |
5329 | goto parse_error; |
5330 | switch (z[0]) { |
5331 | case '-': |
5332 | mode |= S_IFREG; |
5333 | break; |
5334 | case 'd': |
5335 | mode |= S_IFDIR; |
5336 | break; |
5337 | case 'l': |
5338 | mode |= S_IFLNK; |
5339 | break; |
5340 | default: |
5341 | goto parse_error; |
5342 | } |
5343 | for (i = 1; i < 10; i++) { |
5344 | if (z[i] == zTemplate[i]) |
5345 | mode |= 1 << (9 - i); |
5346 | else if (z[i] != '-') |
5347 | goto parse_error; |
5348 | } |
5349 | } |
5350 | if (((mode & S_IFDIR) == 0) == bIsDir) { |
5351 | /* The "mode" attribute is a directory, but data has been specified. |
5352 | ** Or vice-versa - no data but "mode" is a file or symlink. */ |
5353 | *pzErr = sqlite3_mprintf("zipfile: mode does not match data" ); |
5354 | return SQLITE_CONSTRAINT; |
5355 | } |
5356 | *pMode = mode; |
5357 | return SQLITE_OK; |
5358 | |
5359 | parse_error: |
5360 | *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s" , z); |
5361 | return SQLITE_ERROR; |
5362 | } |
5363 | |
5364 | /* |
5365 | ** Both (const char*) arguments point to nul-terminated strings. Argument |
5366 | ** nB is the value of strlen(zB). This function returns 0 if the strings are |
5367 | ** identical, ignoring any trailing '/' character in either path. */ |
5368 | static int zipfileComparePath(const char *zA, const char *zB, int nB) { |
5369 | int nA = (int)strlen(zA); |
5370 | if (zA[nA - 1] == '/') |
5371 | nA--; |
5372 | if (zB[nB - 1] == '/') |
5373 | nB--; |
5374 | if (nA == nB && memcmp(zA, zB, nA) == 0) |
5375 | return 0; |
5376 | return 1; |
5377 | } |
5378 | |
5379 | static int zipfileBegin(sqlite3_vtab *pVtab) { |
5380 | ZipfileTab *pTab = (ZipfileTab *)pVtab; |
5381 | int rc = SQLITE_OK; |
5382 | |
5383 | assert(pTab->pWriteFd == 0); |
5384 | |
5385 | /* Open a write fd on the file. Also load the entire central directory |
5386 | ** structure into memory. During the transaction any new file data is |
5387 | ** appended to the archive file, but the central directory is accumulated |
5388 | ** in main-memory until the transaction is committed. */ |
5389 | pTab->pWriteFd = fopen(pTab->zFile, "ab+" ); |
5390 | if (pTab->pWriteFd == 0) { |
5391 | pTab->base.zErrMsg = sqlite3_mprintf("zipfile: failed to open file %s for writing" , pTab->zFile); |
5392 | rc = SQLITE_ERROR; |
5393 | } else { |
5394 | fseek(pTab->pWriteFd, 0, SEEK_END); |
5395 | pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd); |
5396 | rc = zipfileLoadDirectory(pTab, 0, 0); |
5397 | } |
5398 | |
5399 | if (rc != SQLITE_OK) { |
5400 | zipfileCleanupTransaction(pTab); |
5401 | } |
5402 | |
5403 | return rc; |
5404 | } |
5405 | |
5406 | /* |
5407 | ** Return the current time as a 32-bit timestamp in UNIX epoch format (like |
5408 | ** time(2)). |
5409 | */ |
5410 | static u32 zipfileTime(void) { |
5411 | sqlite3_vfs *pVfs = sqlite3_vfs_find(0); |
5412 | u32 ret; |
5413 | if (pVfs->iVersion >= 2 && pVfs->xCurrentTimeInt64) { |
5414 | i64 ms; |
5415 | pVfs->xCurrentTimeInt64(pVfs, &ms); |
5416 | ret = (u32)((ms / 1000) - ((i64)24405875 * 8640)); |
5417 | } else { |
5418 | double day; |
5419 | pVfs->xCurrentTime(pVfs, &day); |
5420 | ret = (u32)((day - 2440587.5) * 86400); |
5421 | } |
5422 | return ret; |
5423 | } |
5424 | |
5425 | /* |
5426 | ** Return a 32-bit timestamp in UNIX epoch format. |
5427 | ** |
5428 | ** If the value passed as the only argument is either NULL or an SQL NULL, |
5429 | ** return the current time. Otherwise, return the value stored in (*pVal) |
5430 | ** cast to a 32-bit unsigned integer. |
5431 | */ |
5432 | static u32 zipfileGetTime(sqlite3_value *pVal) { |
5433 | if (pVal == 0 || sqlite3_value_type(pVal) == SQLITE_NULL) { |
5434 | return zipfileTime(); |
5435 | } |
5436 | return (u32)sqlite3_value_int64(pVal); |
5437 | } |
5438 | |
5439 | /* |
5440 | ** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry |
5441 | ** linked list. Remove it from the list and free the object. |
5442 | */ |
5443 | static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld) { |
5444 | if (pOld) { |
5445 | ZipfileEntry **pp; |
5446 | for (pp = &pTab->pFirstEntry; (*pp) != pOld; pp = &((*pp)->pNext)) |
5447 | ; |
5448 | *pp = (*pp)->pNext; |
5449 | zipfileEntryFree(pOld); |
5450 | } |
5451 | } |
5452 | |
5453 | /* |
5454 | ** xUpdate method. |
5455 | */ |
5456 | static int zipfileUpdate(sqlite3_vtab *pVtab, int nVal, sqlite3_value **apVal, sqlite_int64 *pRowid) { |
5457 | ZipfileTab *pTab = (ZipfileTab *)pVtab; |
5458 | int rc = SQLITE_OK; /* Return Code */ |
5459 | ZipfileEntry *pNew = 0; /* New in-memory CDS entry */ |
5460 | |
5461 | u32 mode = 0; /* Mode for new entry */ |
5462 | u32 mTime = 0; /* Modification time for new entry */ |
5463 | i64 sz = 0; /* Uncompressed size */ |
5464 | const char *zPath = 0; /* Path for new entry */ |
5465 | int nPath = 0; /* strlen(zPath) */ |
5466 | const u8 *pData = 0; /* Pointer to buffer containing content */ |
5467 | int nData = 0; /* Size of pData buffer in bytes */ |
5468 | int iMethod = 0; /* Compression method for new entry */ |
5469 | u8 *pFree = 0; /* Free this */ |
5470 | char *zFree = 0; /* Also free this */ |
5471 | ZipfileEntry *pOld = 0; |
5472 | ZipfileEntry *pOld2 = 0; |
5473 | int bUpdate = 0; /* True for an update that modifies "name" */ |
5474 | int bIsDir = 0; |
5475 | u32 iCrc32 = 0; |
5476 | |
5477 | if (pTab->pWriteFd == 0) { |
5478 | rc = zipfileBegin(pVtab); |
5479 | if (rc != SQLITE_OK) |
5480 | return rc; |
5481 | } |
5482 | |
5483 | /* If this is a DELETE or UPDATE, find the archive entry to delete. */ |
5484 | if (sqlite3_value_type(apVal[0]) != SQLITE_NULL) { |
5485 | const char *zDelete = (const char *)sqlite3_value_text(apVal[0]); |
5486 | int nDelete = (int)strlen(zDelete); |
5487 | if (nVal > 1) { |
5488 | const char *zUpdate = (const char *)sqlite3_value_text(apVal[1]); |
5489 | if (zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete) != 0) { |
5490 | bUpdate = 1; |
5491 | } |
5492 | } |
5493 | for (pOld = pTab->pFirstEntry; 1; pOld = pOld->pNext) { |
5494 | if (zipfileComparePath(pOld->cds.zFile, zDelete, nDelete) == 0) { |
5495 | break; |
5496 | } |
5497 | assert(pOld->pNext); |
5498 | } |
5499 | } |
5500 | |
5501 | if (nVal > 1) { |
5502 | /* Check that "sz" and "rawdata" are both NULL: */ |
5503 | if (sqlite3_value_type(apVal[5]) != SQLITE_NULL) { |
5504 | zipfileTableErr(pTab, "sz must be NULL" ); |
5505 | rc = SQLITE_CONSTRAINT; |
5506 | } |
5507 | if (sqlite3_value_type(apVal[6]) != SQLITE_NULL) { |
5508 | zipfileTableErr(pTab, "rawdata must be NULL" ); |
5509 | rc = SQLITE_CONSTRAINT; |
5510 | } |
5511 | |
5512 | if (rc == SQLITE_OK) { |
5513 | if (sqlite3_value_type(apVal[7]) == SQLITE_NULL) { |
5514 | /* data=NULL. A directory */ |
5515 | bIsDir = 1; |
5516 | } else { |
5517 | /* Value specified for "data", and possibly "method". This must be |
5518 | ** a regular file or a symlink. */ |
5519 | const u8 *aIn = sqlite3_value_blob(apVal[7]); |
5520 | int nIn = sqlite3_value_bytes(apVal[7]); |
5521 | int bAuto = sqlite3_value_type(apVal[8]) == SQLITE_NULL; |
5522 | |
5523 | iMethod = sqlite3_value_int(apVal[8]); |
5524 | sz = nIn; |
5525 | pData = aIn; |
5526 | nData = nIn; |
5527 | if (iMethod != 0 && iMethod != 8) { |
5528 | zipfileTableErr(pTab, "unknown compression method: %d" , iMethod); |
5529 | rc = SQLITE_CONSTRAINT; |
5530 | } else { |
5531 | if (bAuto || iMethod) { |
5532 | int nCmp; |
5533 | rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg); |
5534 | if (rc == SQLITE_OK) { |
5535 | if (iMethod || nCmp < nIn) { |
5536 | iMethod = 8; |
5537 | pData = pFree; |
5538 | nData = nCmp; |
5539 | } |
5540 | } |
5541 | } |
5542 | iCrc32 = crc32(0, aIn, nIn); |
5543 | } |
5544 | } |
5545 | } |
5546 | |
5547 | if (rc == SQLITE_OK) { |
5548 | rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg); |
5549 | } |
5550 | |
5551 | if (rc == SQLITE_OK) { |
5552 | zPath = (const char *)sqlite3_value_text(apVal[2]); |
5553 | nPath = (int)strlen(zPath); |
5554 | mTime = zipfileGetTime(apVal[4]); |
5555 | } |
5556 | |
5557 | if (rc == SQLITE_OK && bIsDir) { |
5558 | /* For a directory, check that the last character in the path is a |
5559 | ** '/'. This appears to be required for compatibility with info-zip |
5560 | ** (the unzip command on unix). It does not create directories |
5561 | ** otherwise. */ |
5562 | if (zPath[nPath - 1] != '/') { |
5563 | zFree = sqlite3_mprintf("%s/" , zPath); |
5564 | if (zFree == 0) { |
5565 | rc = SQLITE_NOMEM; |
5566 | } |
5567 | zPath = (const char *)zFree; |
5568 | nPath++; |
5569 | } |
5570 | } |
5571 | |
5572 | /* Check that we're not inserting a duplicate entry -OR- updating an |
5573 | ** entry with a path, thereby making it into a duplicate. */ |
5574 | if ((pOld == 0 || bUpdate) && rc == SQLITE_OK) { |
5575 | ZipfileEntry *p; |
5576 | for (p = pTab->pFirstEntry; p; p = p->pNext) { |
5577 | if (zipfileComparePath(p->cds.zFile, zPath, nPath) == 0) { |
5578 | switch (sqlite3_vtab_on_conflict(pTab->db)) { |
5579 | case SQLITE_IGNORE: { |
5580 | goto zipfile_update_done; |
5581 | } |
5582 | case SQLITE_REPLACE: { |
5583 | pOld2 = p; |
5584 | break; |
5585 | } |
5586 | default: { |
5587 | zipfileTableErr(pTab, "duplicate name: \"%s\"" , zPath); |
5588 | rc = SQLITE_CONSTRAINT; |
5589 | break; |
5590 | } |
5591 | } |
5592 | break; |
5593 | } |
5594 | } |
5595 | } |
5596 | |
5597 | if (rc == SQLITE_OK) { |
5598 | /* Create the new CDS record. */ |
5599 | pNew = zipfileNewEntry(zPath); |
5600 | if (pNew == 0) { |
5601 | rc = SQLITE_NOMEM; |
5602 | } else { |
5603 | pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; |
5604 | pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; |
5605 | pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS; |
5606 | pNew->cds.iCompression = (u16)iMethod; |
5607 | zipfileMtimeToDos(&pNew->cds, mTime); |
5608 | pNew->cds.crc32 = iCrc32; |
5609 | pNew->cds.szCompressed = nData; |
5610 | pNew->cds.szUncompressed = (u32)sz; |
5611 | pNew->cds.iExternalAttr = (mode << 16); |
5612 | pNew->cds.iOffset = (u32)pTab->szCurrent; |
5613 | pNew->cds.nFile = (u16)nPath; |
5614 | pNew->mUnixTime = (u32)mTime; |
5615 | rc = zipfileAppendEntry(pTab, pNew, pData, nData); |
5616 | zipfileAddEntry(pTab, pOld, pNew); |
5617 | } |
5618 | } |
5619 | } |
5620 | |
5621 | if (rc == SQLITE_OK && (pOld || pOld2)) { |
5622 | ZipfileCsr *pCsr; |
5623 | for (pCsr = pTab->pCsrList; pCsr; pCsr = pCsr->pCsrNext) { |
5624 | if (pCsr->pCurrent && (pCsr->pCurrent == pOld || pCsr->pCurrent == pOld2)) { |
5625 | pCsr->pCurrent = pCsr->pCurrent->pNext; |
5626 | pCsr->bNoop = 1; |
5627 | } |
5628 | } |
5629 | |
5630 | zipfileRemoveEntryFromList(pTab, pOld); |
5631 | zipfileRemoveEntryFromList(pTab, pOld2); |
5632 | } |
5633 | |
5634 | zipfile_update_done: |
5635 | sqlite3_free(pFree); |
5636 | sqlite3_free(zFree); |
5637 | return rc; |
5638 | } |
5639 | |
5640 | static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf) { |
5641 | u8 *a = aBuf; |
5642 | zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD); |
5643 | zipfileWrite16(a, p->iDisk); |
5644 | zipfileWrite16(a, p->iFirstDisk); |
5645 | zipfileWrite16(a, p->nEntry); |
5646 | zipfileWrite16(a, p->nEntryTotal); |
5647 | zipfileWrite32(a, p->nSize); |
5648 | zipfileWrite32(a, p->iOffset); |
5649 | zipfileWrite16(a, 0); /* Size of trailing comment in bytes*/ |
5650 | |
5651 | return a - aBuf; |
5652 | } |
5653 | |
5654 | static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p) { |
5655 | int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer); |
5656 | assert(nBuf == ZIPFILE_EOCD_FIXED_SZ); |
5657 | return zipfileAppendData(pTab, pTab->aBuffer, nBuf); |
5658 | } |
5659 | |
5660 | /* |
5661 | ** Serialize the CDS structure into buffer aBuf[]. Return the number |
5662 | ** of bytes written. |
5663 | */ |
5664 | static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf) { |
5665 | u8 *a = aBuf; |
5666 | ZipfileCDS *pCDS = &pEntry->cds; |
5667 | |
5668 | if (pEntry->aExtra == 0) { |
5669 | pCDS->nExtra = 9; |
5670 | } |
5671 | |
5672 | zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS); |
5673 | zipfileWrite16(a, pCDS->iVersionMadeBy); |
5674 | zipfileWrite16(a, pCDS->iVersionExtract); |
5675 | zipfileWrite16(a, pCDS->flags); |
5676 | zipfileWrite16(a, pCDS->iCompression); |
5677 | zipfileWrite16(a, pCDS->mTime); |
5678 | zipfileWrite16(a, pCDS->mDate); |
5679 | zipfileWrite32(a, pCDS->crc32); |
5680 | zipfileWrite32(a, pCDS->szCompressed); |
5681 | zipfileWrite32(a, pCDS->szUncompressed); |
5682 | assert(a == &aBuf[ZIPFILE_CDS_NFILE_OFF]); |
5683 | zipfileWrite16(a, pCDS->nFile); |
5684 | zipfileWrite16(a, pCDS->nExtra); |
5685 | zipfileWrite16(a, pCDS->nComment); |
5686 | zipfileWrite16(a, pCDS->iDiskStart); |
5687 | zipfileWrite16(a, pCDS->iInternalAttr); |
5688 | zipfileWrite32(a, pCDS->iExternalAttr); |
5689 | zipfileWrite32(a, pCDS->iOffset); |
5690 | |
5691 | memcpy(a, pCDS->zFile, pCDS->nFile); |
5692 | a += pCDS->nFile; |
5693 | |
5694 | if (pEntry->aExtra) { |
5695 | int n = (int)pCDS->nExtra + (int)pCDS->nComment; |
5696 | memcpy(a, pEntry->aExtra, n); |
5697 | a += n; |
5698 | } else { |
5699 | assert(pCDS->nExtra == 9); |
5700 | zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); |
5701 | zipfileWrite16(a, 5); |
5702 | *a++ = 0x01; |
5703 | zipfileWrite32(a, pEntry->mUnixTime); |
5704 | } |
5705 | |
5706 | return a - aBuf; |
5707 | } |
5708 | |
5709 | static int zipfileCommit(sqlite3_vtab *pVtab) { |
5710 | ZipfileTab *pTab = (ZipfileTab *)pVtab; |
5711 | int rc = SQLITE_OK; |
5712 | if (pTab->pWriteFd) { |
5713 | i64 iOffset = pTab->szCurrent; |
5714 | ZipfileEntry *p; |
5715 | ZipfileEOCD eocd; |
5716 | int nEntry = 0; |
5717 | |
5718 | /* Write out all entries */ |
5719 | for (p = pTab->pFirstEntry; rc == SQLITE_OK && p; p = p->pNext) { |
5720 | int n = zipfileSerializeCDS(p, pTab->aBuffer); |
5721 | rc = zipfileAppendData(pTab, pTab->aBuffer, n); |
5722 | nEntry++; |
5723 | } |
5724 | |
5725 | /* Write out the EOCD record */ |
5726 | eocd.iDisk = 0; |
5727 | eocd.iFirstDisk = 0; |
5728 | eocd.nEntry = (u16)nEntry; |
5729 | eocd.nEntryTotal = (u16)nEntry; |
5730 | eocd.nSize = (u32)(pTab->szCurrent - iOffset); |
5731 | eocd.iOffset = (u32)iOffset; |
5732 | rc = zipfileAppendEOCD(pTab, &eocd); |
5733 | |
5734 | zipfileCleanupTransaction(pTab); |
5735 | } |
5736 | return rc; |
5737 | } |
5738 | |
5739 | static int zipfileRollback(sqlite3_vtab *pVtab) { |
5740 | return zipfileCommit(pVtab); |
5741 | } |
5742 | |
5743 | static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId) { |
5744 | ZipfileCsr *pCsr; |
5745 | for (pCsr = pTab->pCsrList; pCsr; pCsr = pCsr->pCsrNext) { |
5746 | if (iId == pCsr->iId) |
5747 | break; |
5748 | } |
5749 | return pCsr; |
5750 | } |
5751 | |
5752 | static void zipfileFunctionCds(sqlite3_context *context, int argc, sqlite3_value **argv) { |
5753 | ZipfileCsr *pCsr; |
5754 | ZipfileTab *pTab = (ZipfileTab *)sqlite3_user_data(context); |
5755 | assert(argc > 0); |
5756 | |
5757 | pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0])); |
5758 | if (pCsr) { |
5759 | ZipfileCDS *p = &pCsr->pCurrent->cds; |
5760 | char *zRes = sqlite3_mprintf( |
5761 | "{" |
5762 | "\"version-made-by\" : %u, " |
5763 | "\"version-to-extract\" : %u, " |
5764 | "\"flags\" : %u, " |
5765 | "\"compression\" : %u, " |
5766 | "\"time\" : %u, " |
5767 | "\"date\" : %u, " |
5768 | "\"crc32\" : %u, " |
5769 | "\"compressed-size\" : %u, " |
5770 | "\"uncompressed-size\" : %u, " |
5771 | "\"file-name-length\" : %u, " |
5772 | "\"extra-field-length\" : %u, " |
5773 | "\"file-comment-length\" : %u, " |
5774 | "\"disk-number-start\" : %u, " |
5775 | "\"internal-attr\" : %u, " |
5776 | "\"external-attr\" : %u, " |
5777 | "\"offset\" : %u }" , |
5778 | (u32)p->iVersionMadeBy, (u32)p->iVersionExtract, (u32)p->flags, (u32)p->iCompression, (u32)p->mTime, |
5779 | (u32)p->mDate, (u32)p->crc32, (u32)p->szCompressed, (u32)p->szUncompressed, (u32)p->nFile, (u32)p->nExtra, |
5780 | (u32)p->nComment, (u32)p->iDiskStart, (u32)p->iInternalAttr, (u32)p->iExternalAttr, (u32)p->iOffset); |
5781 | |
5782 | if (zRes == 0) { |
5783 | sqlite3_result_error_nomem(context); |
5784 | } else { |
5785 | sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); |
5786 | sqlite3_free(zRes); |
5787 | } |
5788 | } |
5789 | } |
5790 | |
5791 | /* |
5792 | ** xFindFunction method. |
5793 | */ |
5794 | static int zipfileFindFunction(sqlite3_vtab *pVtab, /* Virtual table handle */ |
5795 | int nArg, /* Number of SQL function arguments */ |
5796 | const char *zName, /* Name of SQL function */ |
5797 | void (**pxFunc)(sqlite3_context *, int, sqlite3_value **), /* OUT: Result */ |
5798 | void **ppArg /* OUT: User data for *pxFunc */ |
5799 | ) { |
5800 | if (sqlite3_stricmp("zipfile_cds" , zName) == 0) { |
5801 | *pxFunc = zipfileFunctionCds; |
5802 | *ppArg = (void *)pVtab; |
5803 | return 1; |
5804 | } |
5805 | return 0; |
5806 | } |
5807 | |
5808 | typedef struct ZipfileBuffer ZipfileBuffer; |
5809 | struct ZipfileBuffer { |
5810 | u8 *a; /* Pointer to buffer */ |
5811 | int n; /* Size of buffer in bytes */ |
5812 | int nAlloc; /* Byte allocated at a[] */ |
5813 | }; |
5814 | |
5815 | typedef struct ZipfileCtx ZipfileCtx; |
5816 | struct ZipfileCtx { |
5817 | int nEntry; |
5818 | ZipfileBuffer body; |
5819 | ZipfileBuffer cds; |
5820 | }; |
5821 | |
5822 | static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte) { |
5823 | if (pBuf->n + nByte > pBuf->nAlloc) { |
5824 | u8 *aNew; |
5825 | int nNew = pBuf->n ? pBuf->n * 2 : 512; |
5826 | int nReq = pBuf->n + nByte; |
5827 | |
5828 | while (nNew < nReq) |
5829 | nNew = nNew * 2; |
5830 | aNew = sqlite3_realloc(pBuf->a, nNew); |
5831 | if (aNew == 0) |
5832 | return SQLITE_NOMEM; |
5833 | pBuf->a = aNew; |
5834 | pBuf->nAlloc = nNew; |
5835 | } |
5836 | return SQLITE_OK; |
5837 | } |
5838 | |
5839 | /* |
5840 | ** xStep() callback for the zipfile() aggregate. This can be called in |
5841 | ** any of the following ways: |
5842 | ** |
5843 | ** SELECT zipfile(name,data) ... |
5844 | ** SELECT zipfile(name,mode,mtime,data) ... |
5845 | ** SELECT zipfile(name,mode,mtime,data,method) ... |
5846 | */ |
5847 | void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal) { |
5848 | ZipfileCtx *p; /* Aggregate function context */ |
5849 | ZipfileEntry e; /* New entry to add to zip archive */ |
5850 | |
5851 | sqlite3_value *pName = 0; |
5852 | sqlite3_value *pMode = 0; |
5853 | sqlite3_value *pMtime = 0; |
5854 | sqlite3_value *pData = 0; |
5855 | sqlite3_value *pMethod = 0; |
5856 | |
5857 | int bIsDir = 0; |
5858 | u32 mode; |
5859 | int rc = SQLITE_OK; |
5860 | char *zErr = 0; |
5861 | |
5862 | int iMethod = -1; /* Compression method to use (0 or 8) */ |
5863 | |
5864 | const u8 *aData = 0; /* Possibly compressed data for new entry */ |
5865 | int nData = 0; /* Size of aData[] in bytes */ |
5866 | int szUncompressed = 0; /* Size of data before compression */ |
5867 | u8 *aFree = 0; /* Free this before returning */ |
5868 | u32 iCrc32 = 0; /* crc32 of uncompressed data */ |
5869 | |
5870 | char *zName = 0; /* Path (name) of new entry */ |
5871 | int nName = 0; /* Size of zName in bytes */ |
5872 | char *zFree = 0; /* Free this before returning */ |
5873 | int nByte; |
5874 | |
5875 | memset(&e, 0, sizeof(e)); |
5876 | p = (ZipfileCtx *)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); |
5877 | if (p == 0) |
5878 | return; |
5879 | |
5880 | /* Martial the arguments into stack variables */ |
5881 | if (nVal != 2 && nVal != 4 && nVal != 5) { |
5882 | zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()" ); |
5883 | rc = SQLITE_ERROR; |
5884 | goto zipfile_step_out; |
5885 | } |
5886 | pName = apVal[0]; |
5887 | if (nVal == 2) { |
5888 | pData = apVal[1]; |
5889 | } else { |
5890 | pMode = apVal[1]; |
5891 | pMtime = apVal[2]; |
5892 | pData = apVal[3]; |
5893 | if (nVal == 5) { |
5894 | pMethod = apVal[4]; |
5895 | } |
5896 | } |
5897 | |
5898 | /* Check that the 'name' parameter looks ok. */ |
5899 | zName = (char *)sqlite3_value_text(pName); |
5900 | nName = sqlite3_value_bytes(pName); |
5901 | if (zName == 0) { |
5902 | zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL" ); |
5903 | rc = SQLITE_ERROR; |
5904 | goto zipfile_step_out; |
5905 | } |
5906 | |
5907 | /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use |
5908 | ** deflate compression) or NULL (choose automatically). */ |
5909 | if (pMethod && SQLITE_NULL != sqlite3_value_type(pMethod)) { |
5910 | iMethod = (int)sqlite3_value_int64(pMethod); |
5911 | if (iMethod != 0 && iMethod != 8) { |
5912 | zErr = sqlite3_mprintf("illegal method value: %d" , iMethod); |
5913 | rc = SQLITE_ERROR; |
5914 | goto zipfile_step_out; |
5915 | } |
5916 | } |
5917 | |
5918 | /* Now inspect the data. If this is NULL, then the new entry must be a |
5919 | ** directory. Otherwise, figure out whether or not the data should |
5920 | ** be deflated or simply stored in the zip archive. */ |
5921 | if (sqlite3_value_type(pData) == SQLITE_NULL) { |
5922 | bIsDir = 1; |
5923 | iMethod = 0; |
5924 | } else { |
5925 | aData = sqlite3_value_blob(pData); |
5926 | szUncompressed = nData = sqlite3_value_bytes(pData); |
5927 | iCrc32 = crc32(0, aData, nData); |
5928 | if (iMethod < 0 || iMethod == 8) { |
5929 | int nOut = 0; |
5930 | rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr); |
5931 | if (rc != SQLITE_OK) { |
5932 | goto zipfile_step_out; |
5933 | } |
5934 | if (iMethod == 8 || nOut < nData) { |
5935 | aData = aFree; |
5936 | nData = nOut; |
5937 | iMethod = 8; |
5938 | } else { |
5939 | iMethod = 0; |
5940 | } |
5941 | } |
5942 | } |
5943 | |
5944 | /* Decode the "mode" argument. */ |
5945 | rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr); |
5946 | if (rc) |
5947 | goto zipfile_step_out; |
5948 | |
5949 | /* Decode the "mtime" argument. */ |
5950 | e.mUnixTime = zipfileGetTime(pMtime); |
5951 | |
5952 | /* If this is a directory entry, ensure that there is exactly one '/' |
5953 | ** at the end of the path. Or, if this is not a directory and the path |
5954 | ** ends in '/' it is an error. */ |
5955 | if (bIsDir == 0) { |
5956 | if (zName[nName - 1] == '/') { |
5957 | zErr = sqlite3_mprintf("non-directory name must not end with /" ); |
5958 | rc = SQLITE_ERROR; |
5959 | goto zipfile_step_out; |
5960 | } |
5961 | } else { |
5962 | if (zName[nName - 1] != '/') { |
5963 | zName = zFree = sqlite3_mprintf("%s/" , zName); |
5964 | nName++; |
5965 | if (zName == 0) { |
5966 | rc = SQLITE_NOMEM; |
5967 | goto zipfile_step_out; |
5968 | } |
5969 | } else { |
5970 | while (nName > 1 && zName[nName - 2] == '/') |
5971 | nName--; |
5972 | } |
5973 | } |
5974 | |
5975 | /* Assemble the ZipfileEntry object for the new zip archive entry */ |
5976 | e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; |
5977 | e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; |
5978 | e.cds.flags = ZIPFILE_NEWENTRY_FLAGS; |
5979 | e.cds.iCompression = (u16)iMethod; |
5980 | zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime); |
5981 | e.cds.crc32 = iCrc32; |
5982 | e.cds.szCompressed = nData; |
5983 | e.cds.szUncompressed = szUncompressed; |
5984 | e.cds.iExternalAttr = (mode << 16); |
5985 | e.cds.iOffset = p->body.n; |
5986 | e.cds.nFile = (u16)nName; |
5987 | e.cds.zFile = zName; |
5988 | |
5989 | /* Append the LFH to the body of the new archive */ |
5990 | nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9; |
5991 | if ((rc = zipfileBufferGrow(&p->body, nByte))) |
5992 | goto zipfile_step_out; |
5993 | p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]); |
5994 | |
5995 | /* Append the data to the body of the new archive */ |
5996 | if (nData > 0) { |
5997 | if ((rc = zipfileBufferGrow(&p->body, nData))) |
5998 | goto zipfile_step_out; |
5999 | memcpy(&p->body.a[p->body.n], aData, nData); |
6000 | p->body.n += nData; |
6001 | } |
6002 | |
6003 | /* Append the CDS record to the directory of the new archive */ |
6004 | nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9; |
6005 | if ((rc = zipfileBufferGrow(&p->cds, nByte))) |
6006 | goto zipfile_step_out; |
6007 | p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]); |
6008 | |
6009 | /* Increment the count of entries in the archive */ |
6010 | p->nEntry++; |
6011 | |
6012 | zipfile_step_out: |
6013 | sqlite3_free(aFree); |
6014 | sqlite3_free(zFree); |
6015 | if (rc) { |
6016 | if (zErr) { |
6017 | sqlite3_result_error(pCtx, zErr, -1); |
6018 | } else { |
6019 | sqlite3_result_error_code(pCtx, rc); |
6020 | } |
6021 | } |
6022 | sqlite3_free(zErr); |
6023 | } |
6024 | |
6025 | /* |
6026 | ** xFinalize() callback for zipfile aggregate function. |
6027 | */ |
6028 | void zipfileFinal(sqlite3_context *pCtx) { |
6029 | ZipfileCtx *p; |
6030 | ZipfileEOCD eocd; |
6031 | int nZip; |
6032 | u8 *aZip; |
6033 | |
6034 | p = (ZipfileCtx *)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); |
6035 | if (p == 0) |
6036 | return; |
6037 | if (p->nEntry > 0) { |
6038 | memset(&eocd, 0, sizeof(eocd)); |
6039 | eocd.nEntry = (u16)p->nEntry; |
6040 | eocd.nEntryTotal = (u16)p->nEntry; |
6041 | eocd.nSize = p->cds.n; |
6042 | eocd.iOffset = p->body.n; |
6043 | |
6044 | nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ; |
6045 | aZip = (u8 *)sqlite3_malloc(nZip); |
6046 | if (aZip == 0) { |
6047 | sqlite3_result_error_nomem(pCtx); |
6048 | } else { |
6049 | memcpy(aZip, p->body.a, p->body.n); |
6050 | memcpy(&aZip[p->body.n], p->cds.a, p->cds.n); |
6051 | zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]); |
6052 | sqlite3_result_blob(pCtx, aZip, nZip, zipfileFree); |
6053 | } |
6054 | } |
6055 | |
6056 | sqlite3_free(p->body.a); |
6057 | sqlite3_free(p->cds.a); |
6058 | } |
6059 | |
6060 | /* |
6061 | ** Register the "zipfile" virtual table. |
6062 | */ |
6063 | static int zipfileRegister(sqlite3 *db) { |
6064 | static sqlite3_module zipfileModule = { |
6065 | 1, /* iVersion */ |
6066 | zipfileConnect, /* xCreate */ |
6067 | zipfileConnect, /* xConnect */ |
6068 | zipfileBestIndex, /* xBestIndex */ |
6069 | zipfileDisconnect, /* xDisconnect */ |
6070 | zipfileDisconnect, /* xDestroy */ |
6071 | zipfileOpen, /* xOpen - open a cursor */ |
6072 | zipfileClose, /* xClose - close a cursor */ |
6073 | zipfileFilter, /* xFilter - configure scan constraints */ |
6074 | zipfileNext, /* xNext - advance a cursor */ |
6075 | zipfileEof, /* xEof - check for end of scan */ |
6076 | zipfileColumn, /* xColumn - read data */ |
6077 | 0, /* xRowid - read data */ |
6078 | zipfileUpdate, /* xUpdate */ |
6079 | zipfileBegin, /* xBegin */ |
6080 | 0, /* xSync */ |
6081 | zipfileCommit, /* xCommit */ |
6082 | zipfileRollback, /* xRollback */ |
6083 | zipfileFindFunction, /* xFindMethod */ |
6084 | 0, /* xRename */ |
6085 | }; |
6086 | |
6087 | int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0); |
6088 | if (rc == SQLITE_OK) |
6089 | rc = sqlite3_overload_function(db, "zipfile_cds" , -1); |
6090 | if (rc == SQLITE_OK) { |
6091 | rc = sqlite3_create_function(db, "zipfile" , -1, SQLITE_UTF8, 0, 0, zipfileStep, zipfileFinal); |
6092 | } |
6093 | return rc; |
6094 | } |
6095 | #else /* SQLITE_OMIT_VIRTUALTABLE */ |
6096 | #define zipfileRegister(x) SQLITE_OK |
6097 | #endif |
6098 | |
6099 | #ifdef _WIN32 |
6100 | |
6101 | #endif |
6102 | int sqlite3_zipfile_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { |
6103 | SQLITE_EXTENSION_INIT2(pApi); |
6104 | (void)pzErrMsg; /* Unused parameter */ |
6105 | return zipfileRegister(db); |
6106 | } |
6107 | |
6108 | /************************* End ../ext/misc/zipfile.c ********************/ |
6109 | /************************* Begin ../ext/misc/sqlar.c ******************/ |
6110 | /* |
6111 | ** 2017-12-17 |
6112 | ** |
6113 | ** The author disclaims copyright to this source code. In place of |
6114 | ** a legal notice, here is a blessing: |
6115 | ** |
6116 | ** May you do good and not evil. |
6117 | ** May you find forgiveness for yourself and forgive others. |
6118 | ** May you share freely, never taking more than you give. |
6119 | ** |
6120 | ****************************************************************************** |
6121 | ** |
6122 | ** Utility functions sqlar_compress() and sqlar_uncompress(). Useful |
6123 | ** for working with sqlar archives and used by the shell tool's built-in |
6124 | ** sqlar support. |
6125 | */ |
6126 | SQLITE_EXTENSION_INIT1 |
6127 | #include <zlib.h> |
6128 | |
6129 | /* |
6130 | ** Implementation of the "sqlar_compress(X)" SQL function. |
6131 | ** |
6132 | ** If the type of X is SQLITE_BLOB, and compressing that blob using |
6133 | ** zlib utility function compress() yields a smaller blob, return the |
6134 | ** compressed blob. Otherwise, return a copy of X. |
6135 | ** |
6136 | ** SQLar uses the "zlib format" for compressed content. The zlib format |
6137 | ** contains a two-byte identification header and a four-byte checksum at |
6138 | ** the end. This is different from ZIP which uses the raw deflate format. |
6139 | ** |
6140 | ** Future enhancements to SQLar might add support for new compression formats. |
6141 | ** If so, those new formats will be identified by alternative headers in the |
6142 | ** compressed data. |
6143 | */ |
6144 | static void sqlarCompressFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { |
6145 | assert(argc == 1); |
6146 | if (sqlite3_value_type(argv[0]) == SQLITE_BLOB) { |
6147 | const Bytef *pData = sqlite3_value_blob(argv[0]); |
6148 | uLong nData = sqlite3_value_bytes(argv[0]); |
6149 | uLongf nOut = compressBound(nData); |
6150 | Bytef *pOut; |
6151 | |
6152 | pOut = (Bytef *)sqlite3_malloc(nOut); |
6153 | if (pOut == 0) { |
6154 | sqlite3_result_error_nomem(context); |
6155 | return; |
6156 | } else { |
6157 | if (Z_OK != compress(pOut, &nOut, pData, nData)) { |
6158 | sqlite3_result_error(context, "error in compress()" , -1); |
6159 | } else if (nOut < nData) { |
6160 | sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT); |
6161 | } else { |
6162 | sqlite3_result_value(context, argv[0]); |
6163 | } |
6164 | sqlite3_free(pOut); |
6165 | } |
6166 | } else { |
6167 | sqlite3_result_value(context, argv[0]); |
6168 | } |
6169 | } |
6170 | |
6171 | /* |
6172 | ** Implementation of the "sqlar_uncompress(X,SZ)" SQL function |
6173 | ** |
6174 | ** Parameter SZ is interpreted as an integer. If it is less than or |
6175 | ** equal to zero, then this function returns a copy of X. Or, if |
6176 | ** SZ is equal to the size of X when interpreted as a blob, also |
6177 | ** return a copy of X. Otherwise, decompress blob X using zlib |
6178 | ** utility function uncompress() and return the results (another |
6179 | ** blob). |
6180 | */ |
6181 | static void sqlarUncompressFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { |
6182 | uLong nData; |
6183 | uLongf sz; |
6184 | |
6185 | assert(argc == 2); |
6186 | sz = sqlite3_value_int(argv[1]); |
6187 | |
6188 | if (sz <= 0 || sz == (nData = sqlite3_value_bytes(argv[0]))) { |
6189 | sqlite3_result_value(context, argv[0]); |
6190 | } else { |
6191 | const Bytef *pData = sqlite3_value_blob(argv[0]); |
6192 | Bytef *pOut = sqlite3_malloc(sz); |
6193 | if (Z_OK != uncompress(pOut, &sz, pData, nData)) { |
6194 | sqlite3_result_error(context, "error in uncompress()" , -1); |
6195 | } else { |
6196 | sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT); |
6197 | } |
6198 | sqlite3_free(pOut); |
6199 | } |
6200 | } |
6201 | |
6202 | #ifdef _WIN32 |
6203 | |
6204 | #endif |
6205 | int sqlite3_sqlar_init(sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) { |
6206 | int rc = SQLITE_OK; |
6207 | SQLITE_EXTENSION_INIT2(pApi); |
6208 | (void)pzErrMsg; /* Unused parameter */ |
6209 | rc = sqlite3_create_function(db, "sqlar_compress" , 1, SQLITE_UTF8, 0, sqlarCompressFunc, 0, 0); |
6210 | if (rc == SQLITE_OK) { |
6211 | rc = sqlite3_create_function(db, "sqlar_uncompress" , 2, SQLITE_UTF8, 0, sqlarUncompressFunc, 0, 0); |
6212 | } |
6213 | return rc; |
6214 | } |
6215 | |
6216 | /************************* End ../ext/misc/sqlar.c ********************/ |
6217 | #endif |
6218 | /************************* Begin ../ext/expert/sqlite3expert.h ******************/ |
6219 | /* |
6220 | ** 2017 April 07 |
6221 | ** |
6222 | ** The author disclaims copyright to this source code. In place of |
6223 | ** a legal notice, here is a blessing: |
6224 | ** |
6225 | ** May you do good and not evil. |
6226 | ** May you find forgiveness for yourself and forgive others. |
6227 | ** May you share freely, never taking more than you give. |
6228 | ** |
6229 | ************************************************************************* |
6230 | */ |
6231 | |
6232 | typedef struct sqlite3expert sqlite3expert; |
6233 | |
6234 | /* |
6235 | ** Create a new sqlite3expert object. |
6236 | ** |
6237 | ** If successful, a pointer to the new object is returned and (*pzErr) set |
6238 | ** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to |
6239 | ** an English-language error message. In this case it is the responsibility |
6240 | ** of the caller to eventually free the error message buffer using |
6241 | ** sqlite3_free(). |
6242 | */ |
6243 | sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr); |
6244 | |
6245 | /* |
6246 | ** Configure an sqlite3expert object. |
6247 | ** |
6248 | ** EXPERT_CONFIG_SAMPLE: |
6249 | ** By default, sqlite3_expert_analyze() generates sqlite_stat1 data for |
6250 | ** each candidate index. This involves scanning and sorting the entire |
6251 | ** contents of each user database table once for each candidate index |
6252 | ** associated with the table. For large databases, this can be |
6253 | ** prohibitively slow. This option allows the sqlite3expert object to |
6254 | ** be configured so that sqlite_stat1 data is instead generated based on a |
6255 | ** subset of each table, or so that no sqlite_stat1 data is used at all. |
6256 | ** |
6257 | ** A single integer argument is passed to this option. If the value is less |
6258 | ** than or equal to zero, then no sqlite_stat1 data is generated or used by |
6259 | ** the analysis - indexes are recommended based on the database schema only. |
6260 | ** Or, if the value is 100 or greater, complete sqlite_stat1 data is |
6261 | ** generated for each candidate index (this is the default). Finally, if the |
6262 | ** value falls between 0 and 100, then it represents the percentage of user |
6263 | ** table rows that should be considered when generating sqlite_stat1 data. |
6264 | ** |
6265 | ** Examples: |
6266 | ** |
6267 | ** // Do not generate any sqlite_stat1 data |
6268 | ** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0); |
6269 | ** |
6270 | ** // Generate sqlite_stat1 data based on 10% of the rows in each table. |
6271 | ** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10); |
6272 | */ |
6273 | int sqlite3_expert_config(sqlite3expert *p, int op, ...); |
6274 | |
6275 | #define EXPERT_CONFIG_SAMPLE 1 /* int */ |
6276 | |
6277 | /* |
6278 | ** Specify zero or more SQL statements to be included in the analysis. |
6279 | ** |
6280 | ** Buffer zSql must contain zero or more complete SQL statements. This |
6281 | ** function parses all statements contained in the buffer and adds them |
6282 | ** to the internal list of statements to analyze. If successful, SQLITE_OK |
6283 | ** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example |
6284 | ** due to a error in the SQL - an SQLite error code is returned and (*pzErr) |
6285 | ** may be set to point to an English language error message. In this case |
6286 | ** the caller is responsible for eventually freeing the error message buffer |
6287 | ** using sqlite3_free(). |
6288 | ** |
6289 | ** If an error does occur while processing one of the statements in the |
6290 | ** buffer passed as the second argument, none of the statements in the |
6291 | ** buffer are added to the analysis. |
6292 | ** |
6293 | ** This function must be called before sqlite3_expert_analyze(). If a call |
6294 | ** to this function is made on an sqlite3expert object that has already |
6295 | ** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned |
6296 | ** immediately and no statements are added to the analysis. |
6297 | */ |
6298 | int sqlite3_expert_sql(sqlite3expert *p, /* From a successful sqlite3_expert_new() */ |
6299 | const char *zSql, /* SQL statement(s) to add */ |
6300 | char **pzErr /* OUT: Error message (if any) */ |
6301 | ); |
6302 | |
6303 | /* |
6304 | ** This function is called after the sqlite3expert object has been configured |
6305 | ** with all SQL statements using sqlite3_expert_sql() to actually perform |
6306 | ** the analysis. Once this function has been called, it is not possible to |
6307 | ** add further SQL statements to the analysis. |
6308 | ** |
6309 | ** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if |
6310 | ** an error occurs, an SQLite error code is returned and (*pzErr) set to |
6311 | ** point to a buffer containing an English language error message. In this |
6312 | ** case it is the responsibility of the caller to eventually free the buffer |
6313 | ** using sqlite3_free(). |
6314 | ** |
6315 | ** If an error does occur within this function, the sqlite3expert object |
6316 | ** is no longer useful for any purpose. At that point it is no longer |
6317 | ** possible to add further SQL statements to the object or to re-attempt |
6318 | ** the analysis. The sqlite3expert object must still be freed using a call |
6319 | ** sqlite3_expert_destroy(). |
6320 | */ |
6321 | int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr); |
6322 | |
6323 | /* |
6324 | ** Return the total number of statements loaded using sqlite3_expert_sql(). |
6325 | ** The total number of SQL statements may be different from the total number |
6326 | ** to calls to sqlite3_expert_sql(). |
6327 | */ |
6328 | int sqlite3_expert_count(sqlite3expert *); |
6329 | |
6330 | /* |
6331 | ** Return a component of the report. |
6332 | ** |
6333 | ** This function is called after sqlite3_expert_analyze() to extract the |
6334 | ** results of the analysis. Each call to this function returns either a |
6335 | ** NULL pointer or a pointer to a buffer containing a nul-terminated string. |
6336 | ** The value passed as the third argument must be one of the EXPERT_REPORT_* |
6337 | ** #define constants defined below. |
6338 | ** |
6339 | ** For some EXPERT_REPORT_* parameters, the buffer returned contains |
6340 | ** information relating to a specific SQL statement. In these cases that |
6341 | ** SQL statement is identified by the value passed as the second argument. |
6342 | ** SQL statements are numbered from 0 in the order in which they are parsed. |
6343 | ** If an out-of-range value (less than zero or equal to or greater than the |
6344 | ** value returned by sqlite3_expert_count()) is passed as the second argument |
6345 | ** along with such an EXPERT_REPORT_* parameter, NULL is always returned. |
6346 | ** |
6347 | ** EXPERT_REPORT_SQL: |
6348 | ** Return the text of SQL statement iStmt. |
6349 | ** |
6350 | ** EXPERT_REPORT_INDEXES: |
6351 | ** Return a buffer containing the CREATE INDEX statements for all recommended |
6352 | ** indexes for statement iStmt. If there are no new recommeded indexes, NULL |
6353 | ** is returned. |
6354 | ** |
6355 | ** EXPERT_REPORT_PLAN: |
6356 | ** Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query |
6357 | ** iStmt after the proposed indexes have been added to the database schema. |
6358 | ** |
6359 | ** EXPERT_REPORT_CANDIDATES: |
6360 | ** Return a pointer to a buffer containing the CREATE INDEX statements |
6361 | ** for all indexes that were tested (for all SQL statements). The iStmt |
6362 | ** parameter is ignored for EXPERT_REPORT_CANDIDATES calls. |
6363 | */ |
6364 | const char *sqlite3_expert_report(sqlite3expert *, int iStmt, int eReport); |
6365 | |
6366 | /* |
6367 | ** Values for the third argument passed to sqlite3_expert_report(). |
6368 | */ |
6369 | #define EXPERT_REPORT_SQL 1 |
6370 | #define EXPERT_REPORT_INDEXES 2 |
6371 | #define EXPERT_REPORT_PLAN 3 |
6372 | #define EXPERT_REPORT_CANDIDATES 4 |
6373 | |
6374 | /* |
6375 | ** Free an (sqlite3expert*) handle and all associated resources. There |
6376 | ** should be one call to this function for each successful call to |
6377 | ** sqlite3-expert_new(). |
6378 | */ |
6379 | void sqlite3_expert_destroy(sqlite3expert *); |
6380 | |
6381 | /************************* End ../ext/expert/sqlite3expert.h ********************/ |
6382 | /************************* Begin ../ext/expert/sqlite3expert.c ******************/ |
6383 | /* |
6384 | ** 2017 April 09 |
6385 | ** |
6386 | ** The author disclaims copyright to this source code. In place of |
6387 | ** a legal notice, here is a blessing: |
6388 | ** |
6389 | ** May you do good and not evil. |
6390 | ** May you find forgiveness for yourself and forgive others. |
6391 | ** May you share freely, never taking more than you give. |
6392 | ** |
6393 | ************************************************************************* |
6394 | */ |
6395 | #include <assert.h> |
6396 | #include <string.h> |
6397 | #include <stdio.h> |
6398 | |
6399 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
6400 | |
6401 | /* typedef sqlite3_int64 i64; */ |
6402 | /* typedef sqlite3_uint64 u64; */ |
6403 | |
6404 | typedef struct IdxColumn IdxColumn; |
6405 | typedef struct IdxConstraint IdxConstraint; |
6406 | typedef struct IdxScan IdxScan; |
6407 | typedef struct IdxStatement IdxStatement; |
6408 | typedef struct IdxTable IdxTable; |
6409 | typedef struct IdxWrite IdxWrite; |
6410 | |
6411 | #define STRLEN (int)strlen |
6412 | |
6413 | /* |
6414 | ** A temp table name that we assume no user database will actually use. |
6415 | ** If this assumption proves incorrect triggers on the table with the |
6416 | ** conflicting name will be ignored. |
6417 | */ |
6418 | #define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776" |
6419 | |
6420 | /* |
6421 | ** A single constraint. Equivalent to either "col = ?" or "col < ?" (or |
6422 | ** any other type of single-ended range constraint on a column). |
6423 | ** |
6424 | ** pLink: |
6425 | ** Used to temporarily link IdxConstraint objects into lists while |
6426 | ** creating candidate indexes. |
6427 | */ |
6428 | struct IdxConstraint { |
6429 | char *zColl; /* Collation sequence */ |
6430 | int bRange; /* True for range, false for eq */ |
6431 | int iCol; /* Constrained table column */ |
6432 | int bFlag; /* Used by idxFindCompatible() */ |
6433 | int bDesc; /* True if ORDER BY <expr> DESC */ |
6434 | IdxConstraint *pNext; /* Next constraint in pEq or pRange list */ |
6435 | IdxConstraint *pLink; /* See above */ |
6436 | }; |
6437 | |
6438 | /* |
6439 | ** A single scan of a single table. |
6440 | */ |
6441 | struct IdxScan { |
6442 | IdxTable *pTab; /* Associated table object */ |
6443 | int iDb; /* Database containing table zTable */ |
6444 | i64 covering; /* Mask of columns required for cov. index */ |
6445 | IdxConstraint *pOrder; /* ORDER BY columns */ |
6446 | IdxConstraint *pEq; /* List of == constraints */ |
6447 | IdxConstraint *pRange; /* List of < constraints */ |
6448 | IdxScan *pNextScan; /* Next IdxScan object for same analysis */ |
6449 | }; |
6450 | |
6451 | /* |
6452 | ** Information regarding a single database table. Extracted from |
6453 | ** "PRAGMA table_info" by function idxGetTableInfo(). |
6454 | */ |
6455 | struct IdxColumn { |
6456 | char *zName; |
6457 | char *zColl; |
6458 | int iPk; |
6459 | }; |
6460 | struct IdxTable { |
6461 | int nCol; |
6462 | char *zName; /* Table name */ |
6463 | IdxColumn *aCol; |
6464 | IdxTable *pNext; /* Next table in linked list of all tables */ |
6465 | }; |
6466 | |
6467 | /* |
6468 | ** An object of the following type is created for each unique table/write-op |
6469 | ** seen. The objects are stored in a singly-linked list beginning at |
6470 | ** sqlite3expert.pWrite. |
6471 | */ |
6472 | struct IdxWrite { |
6473 | IdxTable *pTab; |
6474 | int eOp; /* SQLITE_UPDATE, DELETE or INSERT */ |
6475 | IdxWrite *pNext; |
6476 | }; |
6477 | |
6478 | /* |
6479 | ** Each statement being analyzed is represented by an instance of this |
6480 | ** structure. |
6481 | */ |
6482 | struct IdxStatement { |
6483 | int iId; /* Statement number */ |
6484 | char *zSql; /* SQL statement */ |
6485 | char *zIdx; /* Indexes */ |
6486 | char *zEQP; /* Plan */ |
6487 | IdxStatement *pNext; |
6488 | }; |
6489 | |
6490 | /* |
6491 | ** A hash table for storing strings. With space for a payload string |
6492 | ** with each entry. Methods are: |
6493 | ** |
6494 | ** idxHashInit() |
6495 | ** idxHashClear() |
6496 | ** idxHashAdd() |
6497 | ** idxHashSearch() |
6498 | */ |
6499 | #define IDX_HASH_SIZE 1023 |
6500 | typedef struct IdxHashEntry IdxHashEntry; |
6501 | typedef struct IdxHash IdxHash; |
6502 | struct IdxHashEntry { |
6503 | char *zKey; /* nul-terminated key */ |
6504 | char *zVal; /* nul-terminated value string */ |
6505 | char *zVal2; /* nul-terminated value string 2 */ |
6506 | IdxHashEntry *pHashNext; /* Next entry in same hash bucket */ |
6507 | IdxHashEntry *pNext; /* Next entry in hash */ |
6508 | }; |
6509 | struct IdxHash { |
6510 | IdxHashEntry *pFirst; |
6511 | IdxHashEntry *aHash[IDX_HASH_SIZE]; |
6512 | }; |
6513 | |
6514 | /* |
6515 | ** sqlite3expert object. |
6516 | */ |
6517 | struct sqlite3expert { |
6518 | int iSample; /* Percentage of tables to sample for stat1 */ |
6519 | sqlite3 *db; /* User database */ |
6520 | sqlite3 *dbm; /* In-memory db for this analysis */ |
6521 | sqlite3 *dbv; /* Vtab schema for this analysis */ |
6522 | IdxTable *pTable; /* List of all IdxTable objects */ |
6523 | IdxScan *pScan; /* List of scan objects */ |
6524 | IdxWrite *pWrite; /* List of write objects */ |
6525 | IdxStatement *pStatement; /* List of IdxStatement objects */ |
6526 | int bRun; /* True once analysis has run */ |
6527 | char **pzErrmsg; |
6528 | int rc; /* Error code from whereinfo hook */ |
6529 | IdxHash hIdx; /* Hash containing all candidate indexes */ |
6530 | char *zCandidates; /* For EXPERT_REPORT_CANDIDATES */ |
6531 | }; |
6532 | |
6533 | /* |
6534 | ** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). |
6535 | ** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL. |
6536 | */ |
6537 | static void *idxMalloc(int *pRc, int nByte) { |
6538 | void *pRet; |
6539 | assert(*pRc == SQLITE_OK); |
6540 | assert(nByte > 0); |
6541 | pRet = sqlite3_malloc(nByte); |
6542 | if (pRet) { |
6543 | memset(pRet, 0, nByte); |
6544 | } else { |
6545 | *pRc = SQLITE_NOMEM; |
6546 | } |
6547 | return pRet; |
6548 | } |
6549 | |
6550 | /* |
6551 | ** Initialize an IdxHash hash table. |
6552 | */ |
6553 | static void idxHashInit(IdxHash *pHash) { |
6554 | memset(pHash, 0, sizeof(IdxHash)); |
6555 | } |
6556 | |
6557 | /* |
6558 | ** Reset an IdxHash hash table. |
6559 | */ |
6560 | static void idxHashClear(IdxHash *pHash) { |
6561 | int i; |
6562 | for (i = 0; i < IDX_HASH_SIZE; i++) { |
6563 | IdxHashEntry *pEntry; |
6564 | IdxHashEntry *pNext; |
6565 | for (pEntry = pHash->aHash[i]; pEntry; pEntry = pNext) { |
6566 | pNext = pEntry->pHashNext; |
6567 | sqlite3_free(pEntry->zVal2); |
6568 | sqlite3_free(pEntry); |
6569 | } |
6570 | } |
6571 | memset(pHash, 0, sizeof(IdxHash)); |
6572 | } |
6573 | |
6574 | /* |
6575 | ** Return the index of the hash bucket that the string specified by the |
6576 | ** arguments to this function belongs. |
6577 | */ |
6578 | static int idxHashString(const char *z, int n) { |
6579 | unsigned int ret = 0; |
6580 | int i; |
6581 | for (i = 0; i < n; i++) { |
6582 | ret += (ret << 3) + (unsigned char)(z[i]); |
6583 | } |
6584 | return (int)(ret % IDX_HASH_SIZE); |
6585 | } |
6586 | |
6587 | /* |
6588 | ** If zKey is already present in the hash table, return non-zero and do |
6589 | ** nothing. Otherwise, add an entry with key zKey and payload string zVal to |
6590 | ** the hash table passed as the second argument. |
6591 | */ |
6592 | static int idxHashAdd(int *pRc, IdxHash *pHash, const char *zKey, const char *zVal) { |
6593 | int nKey = STRLEN(zKey); |
6594 | int iHash = idxHashString(zKey, nKey); |
6595 | int nVal = (zVal ? STRLEN(zVal) : 0); |
6596 | IdxHashEntry *pEntry; |
6597 | assert(iHash >= 0); |
6598 | for (pEntry = pHash->aHash[iHash]; pEntry; pEntry = pEntry->pHashNext) { |
6599 | if (STRLEN(pEntry->zKey) == nKey && 0 == memcmp(pEntry->zKey, zKey, nKey)) { |
6600 | return 1; |
6601 | } |
6602 | } |
6603 | pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey + 1 + nVal + 1); |
6604 | if (pEntry) { |
6605 | pEntry->zKey = (char *)&pEntry[1]; |
6606 | memcpy(pEntry->zKey, zKey, nKey); |
6607 | if (zVal) { |
6608 | pEntry->zVal = &pEntry->zKey[nKey + 1]; |
6609 | memcpy(pEntry->zVal, zVal, nVal); |
6610 | } |
6611 | pEntry->pHashNext = pHash->aHash[iHash]; |
6612 | pHash->aHash[iHash] = pEntry; |
6613 | |
6614 | pEntry->pNext = pHash->pFirst; |
6615 | pHash->pFirst = pEntry; |
6616 | } |
6617 | return 0; |
6618 | } |
6619 | |
6620 | /* |
6621 | ** If zKey/nKey is present in the hash table, return a pointer to the |
6622 | ** hash-entry object. |
6623 | */ |
6624 | static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey) { |
6625 | int iHash; |
6626 | IdxHashEntry *pEntry; |
6627 | if (nKey < 0) |
6628 | nKey = STRLEN(zKey); |
6629 | iHash = idxHashString(zKey, nKey); |
6630 | assert(iHash >= 0); |
6631 | for (pEntry = pHash->aHash[iHash]; pEntry; pEntry = pEntry->pHashNext) { |
6632 | if (STRLEN(pEntry->zKey) == nKey && 0 == memcmp(pEntry->zKey, zKey, nKey)) { |
6633 | return pEntry; |
6634 | } |
6635 | } |
6636 | return 0; |
6637 | } |
6638 | |
6639 | /* |
6640 | ** If the hash table contains an entry with a key equal to the string |
6641 | ** passed as the final two arguments to this function, return a pointer |
6642 | ** to the payload string. Otherwise, if zKey/nKey is not present in the |
6643 | ** hash table, return NULL. |
6644 | */ |
6645 | static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey) { |
6646 | IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey); |
6647 | if (pEntry) |
6648 | return pEntry->zVal; |
6649 | return 0; |
6650 | } |
6651 | |
6652 | /* |
6653 | ** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl |
6654 | ** variable to point to a copy of nul-terminated string zColl. |
6655 | */ |
6656 | static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl) { |
6657 | IdxConstraint *pNew; |
6658 | int nColl = STRLEN(zColl); |
6659 | |
6660 | assert(*pRc == SQLITE_OK); |
6661 | pNew = (IdxConstraint *)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1); |
6662 | if (pNew) { |
6663 | pNew->zColl = (char *)&pNew[1]; |
6664 | memcpy(pNew->zColl, zColl, nColl + 1); |
6665 | } |
6666 | return pNew; |
6667 | } |
6668 | |
6669 | /* |
6670 | ** An error associated with database handle db has just occurred. Pass |
6671 | ** the error message to callback function xOut. |
6672 | */ |
6673 | static void idxDatabaseError(sqlite3 *db, /* Database handle */ |
6674 | char **pzErrmsg /* Write error here */ |
6675 | ) { |
6676 | *pzErrmsg = sqlite3_mprintf("%s" , sqlite3_errmsg(db)); |
6677 | } |
6678 | |
6679 | /* |
6680 | ** Prepare an SQL statement. |
6681 | */ |
6682 | static int idxPrepareStmt(sqlite3 *db, /* Database handle to compile against */ |
6683 | sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ |
6684 | char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ |
6685 | const char *zSql /* SQL statement to compile */ |
6686 | ) { |
6687 | int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); |
6688 | if (rc != SQLITE_OK) { |
6689 | *ppStmt = 0; |
6690 | idxDatabaseError(db, pzErrmsg); |
6691 | } |
6692 | return rc; |
6693 | } |
6694 | |
6695 | /* |
6696 | ** Prepare an SQL statement using the results of a printf() formatting. |
6697 | */ |
6698 | static int idxPrintfPrepareStmt(sqlite3 *db, /* Database handle to compile against */ |
6699 | sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ |
6700 | char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ |
6701 | const char *zFmt, /* printf() format of SQL statement */ |
6702 | ... /* Trailing printf() arguments */ |
6703 | ) { |
6704 | va_list ap; |
6705 | int rc; |
6706 | char *zSql; |
6707 | va_start(ap, zFmt); |
6708 | zSql = sqlite3_vmprintf(zFmt, ap); |
6709 | if (zSql == 0) { |
6710 | rc = SQLITE_NOMEM; |
6711 | } else { |
6712 | rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql); |
6713 | sqlite3_free(zSql); |
6714 | } |
6715 | va_end(ap); |
6716 | return rc; |
6717 | } |
6718 | |
6719 | /************************************************************************* |
6720 | ** Beginning of virtual table implementation. |
6721 | */ |
6722 | typedef struct ExpertVtab ExpertVtab; |
6723 | struct ExpertVtab { |
6724 | sqlite3_vtab base; |
6725 | IdxTable *pTab; |
6726 | sqlite3expert *pExpert; |
6727 | }; |
6728 | |
6729 | typedef struct ExpertCsr ExpertCsr; |
6730 | struct ExpertCsr { |
6731 | sqlite3_vtab_cursor base; |
6732 | sqlite3_stmt *pData; |
6733 | }; |
6734 | |
6735 | static char *expertDequote(const char *zIn) { |
6736 | int n = STRLEN(zIn); |
6737 | char *zRet = sqlite3_malloc(n); |
6738 | |
6739 | assert(zIn[0] == '\''); |
6740 | assert(zIn[n - 1] == '\''); |
6741 | |
6742 | if (zRet) { |
6743 | int iOut = 0; |
6744 | int iIn = 0; |
6745 | for (iIn = 1; iIn < (n - 1); iIn++) { |
6746 | if (zIn[iIn] == '\'') { |
6747 | assert(zIn[iIn + 1] == '\''); |
6748 | iIn++; |
6749 | } |
6750 | zRet[iOut++] = zIn[iIn]; |
6751 | } |
6752 | zRet[iOut] = '\0'; |
6753 | } |
6754 | |
6755 | return zRet; |
6756 | } |
6757 | |
6758 | /* |
6759 | ** This function is the implementation of both the xConnect and xCreate |
6760 | ** methods of the r-tree virtual table. |
6761 | ** |
6762 | ** argv[0] -> module name |
6763 | ** argv[1] -> database name |
6764 | ** argv[2] -> table name |
6765 | ** argv[...] -> column names... |
6766 | */ |
6767 | static int expertConnect(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, |
6768 | char **pzErr) { |
6769 | sqlite3expert *pExpert = (sqlite3expert *)pAux; |
6770 | ExpertVtab *p = 0; |
6771 | int rc; |
6772 | |
6773 | if (argc != 4) { |
6774 | *pzErr = sqlite3_mprintf("internal error!" ); |
6775 | rc = SQLITE_ERROR; |
6776 | } else { |
6777 | char *zCreateTable = expertDequote(argv[3]); |
6778 | if (zCreateTable) { |
6779 | rc = sqlite3_declare_vtab(db, zCreateTable); |
6780 | if (rc == SQLITE_OK) { |
6781 | p = idxMalloc(&rc, sizeof(ExpertVtab)); |
6782 | } |
6783 | if (rc == SQLITE_OK) { |
6784 | p->pExpert = pExpert; |
6785 | p->pTab = pExpert->pTable; |
6786 | assert(sqlite3_stricmp(p->pTab->zName, argv[2]) == 0); |
6787 | } |
6788 | sqlite3_free(zCreateTable); |
6789 | } else { |
6790 | rc = SQLITE_NOMEM; |
6791 | } |
6792 | } |
6793 | |
6794 | *ppVtab = (sqlite3_vtab *)p; |
6795 | return rc; |
6796 | } |
6797 | |
6798 | static int expertDisconnect(sqlite3_vtab *pVtab) { |
6799 | ExpertVtab *p = (ExpertVtab *)pVtab; |
6800 | sqlite3_free(p); |
6801 | return SQLITE_OK; |
6802 | } |
6803 | |
6804 | static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo) { |
6805 | ExpertVtab *p = (ExpertVtab *)pVtab; |
6806 | int rc = SQLITE_OK; |
6807 | int n = 0; |
6808 | IdxScan *pScan; |
6809 | const int opmask = SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT | SQLITE_INDEX_CONSTRAINT_LT | |
6810 | SQLITE_INDEX_CONSTRAINT_GE | SQLITE_INDEX_CONSTRAINT_LE; |
6811 | |
6812 | pScan = idxMalloc(&rc, sizeof(IdxScan)); |
6813 | if (pScan) { |
6814 | int i; |
6815 | |
6816 | /* Link the new scan object into the list */ |
6817 | pScan->pTab = p->pTab; |
6818 | pScan->pNextScan = p->pExpert->pScan; |
6819 | p->pExpert->pScan = pScan; |
6820 | |
6821 | /* Add the constraints to the IdxScan object */ |
6822 | for (i = 0; i < pIdxInfo->nConstraint; i++) { |
6823 | struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; |
6824 | if (pCons->usable && pCons->iColumn >= 0 && p->pTab->aCol[pCons->iColumn].iPk == 0 && |
6825 | (pCons->op & opmask)) { |
6826 | IdxConstraint *pNew; |
6827 | const char *zColl = sqlite3_vtab_collation(pIdxInfo, i); |
6828 | pNew = idxNewConstraint(&rc, zColl); |
6829 | if (pNew) { |
6830 | pNew->iCol = pCons->iColumn; |
6831 | if (pCons->op == SQLITE_INDEX_CONSTRAINT_EQ) { |
6832 | pNew->pNext = pScan->pEq; |
6833 | pScan->pEq = pNew; |
6834 | } else { |
6835 | pNew->bRange = 1; |
6836 | pNew->pNext = pScan->pRange; |
6837 | pScan->pRange = pNew; |
6838 | } |
6839 | } |
6840 | n++; |
6841 | pIdxInfo->aConstraintUsage[i].argvIndex = n; |
6842 | } |
6843 | } |
6844 | |
6845 | /* Add the ORDER BY to the IdxScan object */ |
6846 | for (i = pIdxInfo->nOrderBy - 1; i >= 0; i--) { |
6847 | int iCol = pIdxInfo->aOrderBy[i].iColumn; |
6848 | if (iCol >= 0) { |
6849 | IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl); |
6850 | if (pNew) { |
6851 | pNew->iCol = iCol; |
6852 | pNew->bDesc = pIdxInfo->aOrderBy[i].desc; |
6853 | pNew->pNext = pScan->pOrder; |
6854 | pNew->pLink = pScan->pOrder; |
6855 | pScan->pOrder = pNew; |
6856 | n++; |
6857 | } |
6858 | } |
6859 | } |
6860 | } |
6861 | |
6862 | pIdxInfo->estimatedCost = 1000000.0 / (n + 1); |
6863 | return rc; |
6864 | } |
6865 | |
6866 | static int expertUpdate(sqlite3_vtab *pVtab, int nData, sqlite3_value **azData, sqlite_int64 *pRowid) { |
6867 | (void)pVtab; |
6868 | (void)nData; |
6869 | (void)azData; |
6870 | (void)pRowid; |
6871 | return SQLITE_OK; |
6872 | } |
6873 | |
6874 | /* |
6875 | ** Virtual table module xOpen method. |
6876 | */ |
6877 | static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) { |
6878 | int rc = SQLITE_OK; |
6879 | ExpertCsr *pCsr; |
6880 | (void)pVTab; |
6881 | pCsr = idxMalloc(&rc, sizeof(ExpertCsr)); |
6882 | *ppCursor = (sqlite3_vtab_cursor *)pCsr; |
6883 | return rc; |
6884 | } |
6885 | |
6886 | /* |
6887 | ** Virtual table module xClose method. |
6888 | */ |
6889 | static int expertClose(sqlite3_vtab_cursor *cur) { |
6890 | ExpertCsr *pCsr = (ExpertCsr *)cur; |
6891 | sqlite3_finalize(pCsr->pData); |
6892 | sqlite3_free(pCsr); |
6893 | return SQLITE_OK; |
6894 | } |
6895 | |
6896 | /* |
6897 | ** Virtual table module xEof method. |
6898 | ** |
6899 | ** Return non-zero if the cursor does not currently point to a valid |
6900 | ** record (i.e if the scan has finished), or zero otherwise. |
6901 | */ |
6902 | static int expertEof(sqlite3_vtab_cursor *cur) { |
6903 | ExpertCsr *pCsr = (ExpertCsr *)cur; |
6904 | return pCsr->pData == 0; |
6905 | } |
6906 | |
6907 | /* |
6908 | ** Virtual table module xNext method. |
6909 | */ |
6910 | static int expertNext(sqlite3_vtab_cursor *cur) { |
6911 | ExpertCsr *pCsr = (ExpertCsr *)cur; |
6912 | int rc = SQLITE_OK; |
6913 | |
6914 | assert(pCsr->pData); |
6915 | rc = sqlite3_step(pCsr->pData); |
6916 | if (rc != SQLITE_ROW) { |
6917 | rc = sqlite3_finalize(pCsr->pData); |
6918 | pCsr->pData = 0; |
6919 | } else { |
6920 | rc = SQLITE_OK; |
6921 | } |
6922 | |
6923 | return rc; |
6924 | } |
6925 | |
6926 | /* |
6927 | ** Virtual table module xRowid method. |
6928 | */ |
6929 | static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid) { |
6930 | (void)cur; |
6931 | *pRowid = 0; |
6932 | return SQLITE_OK; |
6933 | } |
6934 | |
6935 | /* |
6936 | ** Virtual table module xColumn method. |
6937 | */ |
6938 | static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i) { |
6939 | ExpertCsr *pCsr = (ExpertCsr *)cur; |
6940 | sqlite3_value *pVal; |
6941 | pVal = sqlite3_column_value(pCsr->pData, i); |
6942 | if (pVal) { |
6943 | sqlite3_result_value(ctx, pVal); |
6944 | } |
6945 | return SQLITE_OK; |
6946 | } |
6947 | |
6948 | /* |
6949 | ** Virtual table module xFilter method. |
6950 | */ |
6951 | static int expertFilter(sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) { |
6952 | ExpertCsr *pCsr = (ExpertCsr *)cur; |
6953 | ExpertVtab *pVtab = (ExpertVtab *)(cur->pVtab); |
6954 | sqlite3expert *pExpert = pVtab->pExpert; |
6955 | int rc; |
6956 | |
6957 | (void)idxNum; |
6958 | (void)idxStr; |
6959 | (void)argc; |
6960 | (void)argv; |
6961 | rc = sqlite3_finalize(pCsr->pData); |
6962 | pCsr->pData = 0; |
6963 | if (rc == SQLITE_OK) { |
6964 | rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, |
6965 | "SELECT * FROM main.%Q WHERE sample()" , pVtab->pTab->zName); |
6966 | } |
6967 | |
6968 | if (rc == SQLITE_OK) { |
6969 | rc = expertNext(cur); |
6970 | } |
6971 | return rc; |
6972 | } |
6973 | |
6974 | static int idxRegisterVtab(sqlite3expert *p) { |
6975 | static sqlite3_module expertModule = { |
6976 | 2, /* iVersion */ |
6977 | expertConnect, /* xCreate - create a table */ |
6978 | expertConnect, /* xConnect - connect to an existing table */ |
6979 | expertBestIndex, /* xBestIndex - Determine search strategy */ |
6980 | expertDisconnect, /* xDisconnect - Disconnect from a table */ |
6981 | expertDisconnect, /* xDestroy - Drop a table */ |
6982 | expertOpen, /* xOpen - open a cursor */ |
6983 | expertClose, /* xClose - close a cursor */ |
6984 | expertFilter, /* xFilter - configure scan constraints */ |
6985 | expertNext, /* xNext - advance a cursor */ |
6986 | expertEof, /* xEof */ |
6987 | expertColumn, /* xColumn - read data */ |
6988 | expertRowid, /* xRowid - read data */ |
6989 | expertUpdate, /* xUpdate - write data */ |
6990 | 0, /* xBegin - begin transaction */ |
6991 | 0, /* xSync - sync transaction */ |
6992 | 0, /* xCommit - commit transaction */ |
6993 | 0, /* xRollback - rollback transaction */ |
6994 | 0, /* xFindFunction - function overloading */ |
6995 | 0, /* xRename - rename the table */ |
6996 | 0, /* xSavepoint */ |
6997 | 0, /* xRelease */ |
6998 | 0, /* xRollbackTo */ |
6999 | }; |
7000 | |
7001 | return sqlite3_create_module(p->dbv, "expert" , &expertModule, (void *)p); |
7002 | } |
7003 | /* |
7004 | ** End of virtual table implementation. |
7005 | *************************************************************************/ |
7006 | /* |
7007 | ** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function |
7008 | ** is called, set it to the return value of sqlite3_finalize() before |
7009 | ** returning. Otherwise, discard the sqlite3_finalize() return value. |
7010 | */ |
7011 | static void idxFinalize(int *pRc, sqlite3_stmt *pStmt) { |
7012 | int rc = sqlite3_finalize(pStmt); |
7013 | if (*pRc == SQLITE_OK) |
7014 | *pRc = rc; |
7015 | } |
7016 | |
7017 | /* |
7018 | ** Attempt to allocate an IdxTable structure corresponding to table zTab |
7019 | ** in the main database of connection db. If successful, set (*ppOut) to |
7020 | ** point to the new object and return SQLITE_OK. Otherwise, return an |
7021 | ** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be |
7022 | ** set to point to an error string. |
7023 | ** |
7024 | ** It is the responsibility of the caller to eventually free either the |
7025 | ** IdxTable object or error message using sqlite3_free(). |
7026 | */ |
7027 | static int idxGetTableInfo(sqlite3 *db, /* Database connection to read details from */ |
7028 | const char *zTab, /* Table name */ |
7029 | IdxTable **ppOut, /* OUT: New object (if successful) */ |
7030 | char **pzErrmsg /* OUT: Error message (if not) */ |
7031 | ) { |
7032 | sqlite3_stmt *p1 = 0; |
7033 | int nCol = 0; |
7034 | int nTab = STRLEN(zTab); |
7035 | int nByte = sizeof(IdxTable) + nTab + 1; |
7036 | IdxTable *pNew = 0; |
7037 | int rc, rc2; |
7038 | char *pCsr = 0; |
7039 | |
7040 | rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q" , zTab); |
7041 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(p1)) { |
7042 | const char *zCol = (const char *)sqlite3_column_text(p1, 1); |
7043 | nByte += 1 + STRLEN(zCol); |
7044 | rc = sqlite3_table_column_metadata(db, "main" , zTab, zCol, 0, &zCol, 0, 0, 0); |
7045 | nByte += 1 + STRLEN(zCol); |
7046 | nCol++; |
7047 | } |
7048 | rc2 = sqlite3_reset(p1); |
7049 | if (rc == SQLITE_OK) |
7050 | rc = rc2; |
7051 | |
7052 | nByte += sizeof(IdxColumn) * nCol; |
7053 | if (rc == SQLITE_OK) { |
7054 | pNew = idxMalloc(&rc, nByte); |
7055 | } |
7056 | if (rc == SQLITE_OK) { |
7057 | pNew->aCol = (IdxColumn *)&pNew[1]; |
7058 | pNew->nCol = nCol; |
7059 | pCsr = (char *)&pNew->aCol[nCol]; |
7060 | } |
7061 | |
7062 | nCol = 0; |
7063 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(p1)) { |
7064 | const char *zCol = (const char *)sqlite3_column_text(p1, 1); |
7065 | int nCopy = STRLEN(zCol) + 1; |
7066 | pNew->aCol[nCol].zName = pCsr; |
7067 | pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5); |
7068 | memcpy(pCsr, zCol, nCopy); |
7069 | pCsr += nCopy; |
7070 | |
7071 | rc = sqlite3_table_column_metadata(db, "main" , zTab, zCol, 0, &zCol, 0, 0, 0); |
7072 | if (rc == SQLITE_OK) { |
7073 | nCopy = STRLEN(zCol) + 1; |
7074 | pNew->aCol[nCol].zColl = pCsr; |
7075 | memcpy(pCsr, zCol, nCopy); |
7076 | pCsr += nCopy; |
7077 | } |
7078 | |
7079 | nCol++; |
7080 | } |
7081 | idxFinalize(&rc, p1); |
7082 | |
7083 | if (rc != SQLITE_OK) { |
7084 | sqlite3_free(pNew); |
7085 | pNew = 0; |
7086 | } else { |
7087 | pNew->zName = pCsr; |
7088 | memcpy(pNew->zName, zTab, nTab + 1); |
7089 | } |
7090 | |
7091 | *ppOut = pNew; |
7092 | return rc; |
7093 | } |
7094 | |
7095 | /* |
7096 | ** This function is a no-op if *pRc is set to anything other than |
7097 | ** SQLITE_OK when it is called. |
7098 | ** |
7099 | ** If *pRc is initially set to SQLITE_OK, then the text specified by |
7100 | ** the printf() style arguments is appended to zIn and the result returned |
7101 | ** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on |
7102 | ** zIn before returning. |
7103 | */ |
7104 | static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...) { |
7105 | va_list ap; |
7106 | char *zAppend = 0; |
7107 | char *zRet = 0; |
7108 | int nIn = zIn ? STRLEN(zIn) : 0; |
7109 | int nAppend = 0; |
7110 | va_start(ap, zFmt); |
7111 | if (*pRc == SQLITE_OK) { |
7112 | zAppend = sqlite3_vmprintf(zFmt, ap); |
7113 | if (zAppend) { |
7114 | nAppend = STRLEN(zAppend); |
7115 | zRet = (char *)sqlite3_malloc(nIn + nAppend + 1); |
7116 | } |
7117 | if (zAppend && zRet) { |
7118 | if (nIn) |
7119 | memcpy(zRet, zIn, nIn); |
7120 | memcpy(&zRet[nIn], zAppend, nAppend + 1); |
7121 | } else { |
7122 | sqlite3_free(zRet); |
7123 | zRet = 0; |
7124 | *pRc = SQLITE_NOMEM; |
7125 | } |
7126 | sqlite3_free(zAppend); |
7127 | sqlite3_free(zIn); |
7128 | } |
7129 | va_end(ap); |
7130 | return zRet; |
7131 | } |
7132 | |
7133 | /* |
7134 | ** Return true if zId must be quoted in order to use it as an SQL |
7135 | ** identifier, or false otherwise. |
7136 | */ |
7137 | static int idxIdentifierRequiresQuotes(const char *zId) { |
7138 | int i; |
7139 | for (i = 0; zId[i]; i++) { |
7140 | if (!(zId[i] == '_') && !(zId[i] >= '0' && zId[i] <= '9') && !(zId[i] >= 'a' && zId[i] <= 'z') && |
7141 | !(zId[i] >= 'A' && zId[i] <= 'Z')) { |
7142 | return 1; |
7143 | } |
7144 | } |
7145 | return 0; |
7146 | } |
7147 | |
7148 | /* |
7149 | ** This function appends an index column definition suitable for constraint |
7150 | ** pCons to the string passed as zIn and returns the result. |
7151 | */ |
7152 | static char *idxAppendColDefn(int *pRc, /* IN/OUT: Error code */ |
7153 | char *zIn, /* Column defn accumulated so far */ |
7154 | IdxTable *pTab, /* Table index will be created on */ |
7155 | IdxConstraint *pCons) { |
7156 | char *zRet = zIn; |
7157 | IdxColumn *p = &pTab->aCol[pCons->iCol]; |
7158 | if (zRet) |
7159 | zRet = idxAppendText(pRc, zRet, ", " ); |
7160 | |
7161 | if (idxIdentifierRequiresQuotes(p->zName)) { |
7162 | zRet = idxAppendText(pRc, zRet, "%Q" , p->zName); |
7163 | } else { |
7164 | zRet = idxAppendText(pRc, zRet, "%s" , p->zName); |
7165 | } |
7166 | |
7167 | if (sqlite3_stricmp(p->zColl, pCons->zColl)) { |
7168 | if (idxIdentifierRequiresQuotes(pCons->zColl)) { |
7169 | zRet = idxAppendText(pRc, zRet, " COLLATE %Q" , pCons->zColl); |
7170 | } else { |
7171 | zRet = idxAppendText(pRc, zRet, " COLLATE %s" , pCons->zColl); |
7172 | } |
7173 | } |
7174 | |
7175 | if (pCons->bDesc) { |
7176 | zRet = idxAppendText(pRc, zRet, " DESC" ); |
7177 | } |
7178 | return zRet; |
7179 | } |
7180 | |
7181 | /* |
7182 | ** Search database dbm for an index compatible with the one idxCreateFromCons() |
7183 | ** would create from arguments pScan, pEq and pTail. If no error occurs and |
7184 | ** such an index is found, return non-zero. Or, if no such index is found, |
7185 | ** return zero. |
7186 | ** |
7187 | ** If an error occurs, set *pRc to an SQLite error code and return zero. |
7188 | */ |
7189 | static int idxFindCompatible(int *pRc, /* OUT: Error code */ |
7190 | sqlite3 *dbm, /* Database to search */ |
7191 | IdxScan *pScan, /* Scan for table to search for index on */ |
7192 | IdxConstraint *pEq, /* List of == constraints */ |
7193 | IdxConstraint *pTail /* List of range constraints */ |
7194 | ) { |
7195 | const char *zTbl = pScan->pTab->zName; |
7196 | sqlite3_stmt *pIdxList = 0; |
7197 | IdxConstraint *pIter; |
7198 | int nEq = 0; /* Number of elements in pEq */ |
7199 | int rc; |
7200 | |
7201 | /* Count the elements in list pEq */ |
7202 | for (pIter = pEq; pIter; pIter = pIter->pLink) |
7203 | nEq++; |
7204 | |
7205 | rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q" , zTbl); |
7206 | while (rc == SQLITE_OK && sqlite3_step(pIdxList) == SQLITE_ROW) { |
7207 | int bMatch = 1; |
7208 | IdxConstraint *pT = pTail; |
7209 | sqlite3_stmt *pInfo = 0; |
7210 | const char *zIdx = (const char *)sqlite3_column_text(pIdxList, 1); |
7211 | |
7212 | /* Zero the IdxConstraint.bFlag values in the pEq list */ |
7213 | for (pIter = pEq; pIter; pIter = pIter->pLink) |
7214 | pIter->bFlag = 0; |
7215 | |
7216 | rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q" , zIdx); |
7217 | while (rc == SQLITE_OK && sqlite3_step(pInfo) == SQLITE_ROW) { |
7218 | int iIdx = sqlite3_column_int(pInfo, 0); |
7219 | int iCol = sqlite3_column_int(pInfo, 1); |
7220 | const char *zColl = (const char *)sqlite3_column_text(pInfo, 4); |
7221 | |
7222 | if (iIdx < nEq) { |
7223 | for (pIter = pEq; pIter; pIter = pIter->pLink) { |
7224 | if (pIter->bFlag) |
7225 | continue; |
7226 | if (pIter->iCol != iCol) |
7227 | continue; |
7228 | if (sqlite3_stricmp(pIter->zColl, zColl)) |
7229 | continue; |
7230 | pIter->bFlag = 1; |
7231 | break; |
7232 | } |
7233 | if (pIter == 0) { |
7234 | bMatch = 0; |
7235 | break; |
7236 | } |
7237 | } else { |
7238 | if (pT) { |
7239 | if (pT->iCol != iCol || sqlite3_stricmp(pT->zColl, zColl)) { |
7240 | bMatch = 0; |
7241 | break; |
7242 | } |
7243 | pT = pT->pLink; |
7244 | } |
7245 | } |
7246 | } |
7247 | idxFinalize(&rc, pInfo); |
7248 | |
7249 | if (rc == SQLITE_OK && bMatch) { |
7250 | sqlite3_finalize(pIdxList); |
7251 | return 1; |
7252 | } |
7253 | } |
7254 | idxFinalize(&rc, pIdxList); |
7255 | |
7256 | *pRc = rc; |
7257 | return 0; |
7258 | } |
7259 | |
7260 | static int idxCreateFromCons(sqlite3expert *p, IdxScan *pScan, IdxConstraint *pEq, IdxConstraint *pTail) { |
7261 | sqlite3 *dbm = p->dbm; |
7262 | int rc = SQLITE_OK; |
7263 | if ((pEq || pTail) && 0 == idxFindCompatible(&rc, dbm, pScan, pEq, pTail)) { |
7264 | IdxTable *pTab = pScan->pTab; |
7265 | char *zCols = 0; |
7266 | char *zIdx = 0; |
7267 | IdxConstraint *pCons; |
7268 | unsigned int h = 0; |
7269 | const char *zFmt; |
7270 | |
7271 | for (pCons = pEq; pCons; pCons = pCons->pLink) { |
7272 | zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); |
7273 | } |
7274 | for (pCons = pTail; pCons; pCons = pCons->pLink) { |
7275 | zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); |
7276 | } |
7277 | |
7278 | if (rc == SQLITE_OK) { |
7279 | /* Hash the list of columns to come up with a name for the index */ |
7280 | const char *zTable = pScan->pTab->zName; |
7281 | char *zName; /* Index name */ |
7282 | int i; |
7283 | for (i = 0; zCols[i]; i++) { |
7284 | h += ((h << 3) + zCols[i]); |
7285 | } |
7286 | zName = sqlite3_mprintf("%s_idx_%08x" , zTable, h); |
7287 | if (zName == 0) { |
7288 | rc = SQLITE_NOMEM; |
7289 | } else { |
7290 | if (idxIdentifierRequiresQuotes(zTable)) { |
7291 | zFmt = "CREATE INDEX '%q' ON %Q(%s)" ; |
7292 | } else { |
7293 | zFmt = "CREATE INDEX %s ON %s(%s)" ; |
7294 | } |
7295 | zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols); |
7296 | if (!zIdx) { |
7297 | rc = SQLITE_NOMEM; |
7298 | } else { |
7299 | rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg); |
7300 | idxHashAdd(&rc, &p->hIdx, zName, zIdx); |
7301 | } |
7302 | sqlite3_free(zName); |
7303 | sqlite3_free(zIdx); |
7304 | } |
7305 | } |
7306 | |
7307 | sqlite3_free(zCols); |
7308 | } |
7309 | return rc; |
7310 | } |
7311 | |
7312 | /* |
7313 | ** Return true if list pList (linked by IdxConstraint.pLink) contains |
7314 | ** a constraint compatible with *p. Otherwise return false. |
7315 | */ |
7316 | static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p) { |
7317 | IdxConstraint *pCmp; |
7318 | for (pCmp = pList; pCmp; pCmp = pCmp->pLink) { |
7319 | if (p->iCol == pCmp->iCol) |
7320 | return 1; |
7321 | } |
7322 | return 0; |
7323 | } |
7324 | |
7325 | static int idxCreateFromWhere(sqlite3expert *p, IdxScan *pScan, /* Create indexes for this scan */ |
7326 | IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */ |
7327 | ) { |
7328 | IdxConstraint *p1 = 0; |
7329 | IdxConstraint *pCon; |
7330 | int rc; |
7331 | |
7332 | /* Gather up all the == constraints. */ |
7333 | for (pCon = pScan->pEq; pCon; pCon = pCon->pNext) { |
7334 | if (!idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon)) { |
7335 | pCon->pLink = p1; |
7336 | p1 = pCon; |
7337 | } |
7338 | } |
7339 | |
7340 | /* Create an index using the == constraints collected above. And the |
7341 | ** range constraint/ORDER BY terms passed in by the caller, if any. */ |
7342 | rc = idxCreateFromCons(p, pScan, p1, pTail); |
7343 | |
7344 | /* If no range/ORDER BY passed by the caller, create a version of the |
7345 | ** index for each range constraint. */ |
7346 | if (pTail == 0) { |
7347 | for (pCon = pScan->pRange; rc == SQLITE_OK && pCon; pCon = pCon->pNext) { |
7348 | assert(pCon->pLink == 0); |
7349 | if (!idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon)) { |
7350 | rc = idxCreateFromCons(p, pScan, p1, pCon); |
7351 | } |
7352 | } |
7353 | } |
7354 | |
7355 | return rc; |
7356 | } |
7357 | |
7358 | /* |
7359 | ** Create candidate indexes in database [dbm] based on the data in |
7360 | ** linked-list pScan. |
7361 | */ |
7362 | static int idxCreateCandidates(sqlite3expert *p) { |
7363 | int rc = SQLITE_OK; |
7364 | IdxScan *pIter; |
7365 | |
7366 | for (pIter = p->pScan; pIter && rc == SQLITE_OK; pIter = pIter->pNextScan) { |
7367 | rc = idxCreateFromWhere(p, pIter, 0); |
7368 | if (rc == SQLITE_OK && pIter->pOrder) { |
7369 | rc = idxCreateFromWhere(p, pIter, pIter->pOrder); |
7370 | } |
7371 | } |
7372 | |
7373 | return rc; |
7374 | } |
7375 | |
7376 | /* |
7377 | ** Free all elements of the linked list starting at pConstraint. |
7378 | */ |
7379 | static void idxConstraintFree(IdxConstraint *pConstraint) { |
7380 | IdxConstraint *pNext; |
7381 | IdxConstraint *p; |
7382 | |
7383 | for (p = pConstraint; p; p = pNext) { |
7384 | pNext = p->pNext; |
7385 | sqlite3_free(p); |
7386 | } |
7387 | } |
7388 | |
7389 | /* |
7390 | ** Free all elements of the linked list starting from pScan up until pLast |
7391 | ** (pLast is not freed). |
7392 | */ |
7393 | static void idxScanFree(IdxScan *pScan, IdxScan *pLast) { |
7394 | IdxScan *p; |
7395 | IdxScan *pNext; |
7396 | for (p = pScan; p != pLast; p = pNext) { |
7397 | pNext = p->pNextScan; |
7398 | idxConstraintFree(p->pOrder); |
7399 | idxConstraintFree(p->pEq); |
7400 | idxConstraintFree(p->pRange); |
7401 | sqlite3_free(p); |
7402 | } |
7403 | } |
7404 | |
7405 | /* |
7406 | ** Free all elements of the linked list starting from pStatement up |
7407 | ** until pLast (pLast is not freed). |
7408 | */ |
7409 | static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast) { |
7410 | IdxStatement *p; |
7411 | IdxStatement *pNext; |
7412 | for (p = pStatement; p != pLast; p = pNext) { |
7413 | pNext = p->pNext; |
7414 | sqlite3_free(p->zEQP); |
7415 | sqlite3_free(p->zIdx); |
7416 | sqlite3_free(p); |
7417 | } |
7418 | } |
7419 | |
7420 | /* |
7421 | ** Free the linked list of IdxTable objects starting at pTab. |
7422 | */ |
7423 | static void idxTableFree(IdxTable *pTab) { |
7424 | IdxTable *pIter; |
7425 | IdxTable *pNext; |
7426 | for (pIter = pTab; pIter; pIter = pNext) { |
7427 | pNext = pIter->pNext; |
7428 | sqlite3_free(pIter); |
7429 | } |
7430 | } |
7431 | |
7432 | /* |
7433 | ** Free the linked list of IdxWrite objects starting at pTab. |
7434 | */ |
7435 | static void idxWriteFree(IdxWrite *pTab) { |
7436 | IdxWrite *pIter; |
7437 | IdxWrite *pNext; |
7438 | for (pIter = pTab; pIter; pIter = pNext) { |
7439 | pNext = pIter->pNext; |
7440 | sqlite3_free(pIter); |
7441 | } |
7442 | } |
7443 | |
7444 | /* |
7445 | ** This function is called after candidate indexes have been created. It |
7446 | ** runs all the queries to see which indexes they prefer, and populates |
7447 | ** IdxStatement.zIdx and IdxStatement.zEQP with the results. |
7448 | */ |
7449 | int idxFindIndexes(sqlite3expert *p, char **pzErr /* OUT: Error message (sqlite3_malloc) */ |
7450 | ) { |
7451 | IdxStatement *pStmt; |
7452 | sqlite3 *dbm = p->dbm; |
7453 | int rc = SQLITE_OK; |
7454 | |
7455 | IdxHash hIdx; |
7456 | idxHashInit(&hIdx); |
7457 | |
7458 | for (pStmt = p->pStatement; rc == SQLITE_OK && pStmt; pStmt = pStmt->pNext) { |
7459 | IdxHashEntry *pEntry; |
7460 | sqlite3_stmt *pExplain = 0; |
7461 | idxHashClear(&hIdx); |
7462 | rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr, "EXPLAIN QUERY PLAN %s" , pStmt->zSql); |
7463 | while (rc == SQLITE_OK && sqlite3_step(pExplain) == SQLITE_ROW) { |
7464 | int iSelectid = sqlite3_column_int(pExplain, 0); |
7465 | int iOrder = sqlite3_column_int(pExplain, 1); |
7466 | int iFrom = sqlite3_column_int(pExplain, 2); |
7467 | const char *zDetail = (const char *)sqlite3_column_text(pExplain, 3); |
7468 | int nDetail = STRLEN(zDetail); |
7469 | int i; |
7470 | |
7471 | for (i = 0; i < nDetail; i++) { |
7472 | const char *zIdx = 0; |
7473 | if (memcmp(&zDetail[i], " USING INDEX " , 13) == 0) { |
7474 | zIdx = &zDetail[i + 13]; |
7475 | } else if (memcmp(&zDetail[i], " USING COVERING INDEX " , 22) == 0) { |
7476 | zIdx = &zDetail[i + 22]; |
7477 | } |
7478 | if (zIdx) { |
7479 | const char *zSql; |
7480 | int nIdx = 0; |
7481 | while (zIdx[nIdx] != '\0' && (zIdx[nIdx] != ' ' || zIdx[nIdx + 1] != '(')) { |
7482 | nIdx++; |
7483 | } |
7484 | zSql = idxHashSearch(&p->hIdx, zIdx, nIdx); |
7485 | if (zSql) { |
7486 | idxHashAdd(&rc, &hIdx, zSql, 0); |
7487 | if (rc) |
7488 | goto find_indexes_out; |
7489 | } |
7490 | break; |
7491 | } |
7492 | } |
7493 | |
7494 | pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%d|%d|%d|%s\n" , iSelectid, iOrder, iFrom, zDetail); |
7495 | } |
7496 | |
7497 | for (pEntry = hIdx.pFirst; pEntry; pEntry = pEntry->pNext) { |
7498 | pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n" , pEntry->zKey); |
7499 | } |
7500 | |
7501 | idxFinalize(&rc, pExplain); |
7502 | } |
7503 | |
7504 | find_indexes_out: |
7505 | idxHashClear(&hIdx); |
7506 | return rc; |
7507 | } |
7508 | |
7509 | static int idxAuthCallback(void *pCtx, int eOp, const char *z3, const char *z4, const char *zDb, const char *zTrigger) { |
7510 | int rc = SQLITE_OK; |
7511 | (void)z4; |
7512 | (void)zTrigger; |
7513 | if (eOp == SQLITE_INSERT || eOp == SQLITE_UPDATE || eOp == SQLITE_DELETE) { |
7514 | if (sqlite3_stricmp(zDb, "main" ) == 0) { |
7515 | sqlite3expert *p = (sqlite3expert *)pCtx; |
7516 | IdxTable *pTab; |
7517 | for (pTab = p->pTable; pTab; pTab = pTab->pNext) { |
7518 | if (0 == sqlite3_stricmp(z3, pTab->zName)) |
7519 | break; |
7520 | } |
7521 | if (pTab) { |
7522 | IdxWrite *pWrite; |
7523 | for (pWrite = p->pWrite; pWrite; pWrite = pWrite->pNext) { |
7524 | if (pWrite->pTab == pTab && pWrite->eOp == eOp) |
7525 | break; |
7526 | } |
7527 | if (pWrite == 0) { |
7528 | pWrite = idxMalloc(&rc, sizeof(IdxWrite)); |
7529 | if (rc == SQLITE_OK) { |
7530 | pWrite->pTab = pTab; |
7531 | pWrite->eOp = eOp; |
7532 | pWrite->pNext = p->pWrite; |
7533 | p->pWrite = pWrite; |
7534 | } |
7535 | } |
7536 | } |
7537 | } |
7538 | } |
7539 | return rc; |
7540 | } |
7541 | |
7542 | static int idxProcessOneTrigger(sqlite3expert *p, IdxWrite *pWrite, char **pzErr) { |
7543 | static const char *zInt = UNIQUE_TABLE_NAME; |
7544 | static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME; |
7545 | IdxTable *pTab = pWrite->pTab; |
7546 | const char *zTab = pTab->zName; |
7547 | const char *zSql = "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master " |
7548 | "WHERE tbl_name = %Q AND type IN ('table', 'trigger') " |
7549 | "ORDER BY type;" ; |
7550 | sqlite3_stmt *pSelect = 0; |
7551 | int rc = SQLITE_OK; |
7552 | char *zWrite = 0; |
7553 | |
7554 | /* Create the table and its triggers in the temp schema */ |
7555 | rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab); |
7556 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pSelect)) { |
7557 | const char *zCreate = (const char *)sqlite3_column_text(pSelect, 0); |
7558 | rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr); |
7559 | } |
7560 | idxFinalize(&rc, pSelect); |
7561 | |
7562 | /* Rename the table in the temp schema to zInt */ |
7563 | if (rc == SQLITE_OK) { |
7564 | char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q" , zTab, zInt); |
7565 | if (z == 0) { |
7566 | rc = SQLITE_NOMEM; |
7567 | } else { |
7568 | rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr); |
7569 | sqlite3_free(z); |
7570 | } |
7571 | } |
7572 | |
7573 | switch (pWrite->eOp) { |
7574 | case SQLITE_INSERT: { |
7575 | int i; |
7576 | zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(" , zInt); |
7577 | for (i = 0; i < pTab->nCol; i++) { |
7578 | zWrite = idxAppendText(&rc, zWrite, "%s?" , i == 0 ? "" : ", " ); |
7579 | } |
7580 | zWrite = idxAppendText(&rc, zWrite, ")" ); |
7581 | break; |
7582 | } |
7583 | case SQLITE_UPDATE: { |
7584 | int i; |
7585 | zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET " , zInt); |
7586 | for (i = 0; i < pTab->nCol; i++) { |
7587 | zWrite = idxAppendText(&rc, zWrite, "%s%Q=?" , i == 0 ? "" : ", " , pTab->aCol[i].zName); |
7588 | } |
7589 | break; |
7590 | } |
7591 | default: { |
7592 | assert(pWrite->eOp == SQLITE_DELETE); |
7593 | if (rc == SQLITE_OK) { |
7594 | zWrite = sqlite3_mprintf("DELETE FROM %Q" , zInt); |
7595 | if (zWrite == 0) |
7596 | rc = SQLITE_NOMEM; |
7597 | } |
7598 | } |
7599 | } |
7600 | |
7601 | if (rc == SQLITE_OK) { |
7602 | sqlite3_stmt *pX = 0; |
7603 | rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0); |
7604 | idxFinalize(&rc, pX); |
7605 | if (rc != SQLITE_OK) { |
7606 | idxDatabaseError(p->dbv, pzErr); |
7607 | } |
7608 | } |
7609 | sqlite3_free(zWrite); |
7610 | |
7611 | if (rc == SQLITE_OK) { |
7612 | rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr); |
7613 | } |
7614 | |
7615 | return rc; |
7616 | } |
7617 | |
7618 | static int idxProcessTriggers(sqlite3expert *p, char **pzErr) { |
7619 | int rc = SQLITE_OK; |
7620 | IdxWrite *pEnd = 0; |
7621 | IdxWrite *pFirst = p->pWrite; |
7622 | |
7623 | while (rc == SQLITE_OK && pFirst != pEnd) { |
7624 | IdxWrite *pIter; |
7625 | for (pIter = pFirst; rc == SQLITE_OK && pIter != pEnd; pIter = pIter->pNext) { |
7626 | rc = idxProcessOneTrigger(p, pIter, pzErr); |
7627 | } |
7628 | pEnd = pFirst; |
7629 | pFirst = p->pWrite; |
7630 | } |
7631 | |
7632 | return rc; |
7633 | } |
7634 | |
7635 | static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg) { |
7636 | int rc = idxRegisterVtab(p); |
7637 | sqlite3_stmt *pSchema = 0; |
7638 | |
7639 | /* For each table in the main db schema: |
7640 | ** |
7641 | ** 1) Add an entry to the p->pTable list, and |
7642 | ** 2) Create the equivalent virtual table in dbv. |
7643 | */ |
7644 | rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg, |
7645 | "SELECT type, name, sql, 1 FROM sqlite_master " |
7646 | "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' " |
7647 | " UNION ALL " |
7648 | "SELECT type, name, sql, 2 FROM sqlite_master " |
7649 | "WHERE type = 'trigger'" |
7650 | " AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') " |
7651 | "ORDER BY 4, 1" ); |
7652 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pSchema)) { |
7653 | const char *zType = (const char *)sqlite3_column_text(pSchema, 0); |
7654 | const char *zName = (const char *)sqlite3_column_text(pSchema, 1); |
7655 | const char *zSql = (const char *)sqlite3_column_text(pSchema, 2); |
7656 | |
7657 | if (zType[0] == 'v' || zType[1] == 'r') { |
7658 | rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg); |
7659 | } else { |
7660 | IdxTable *pTab; |
7661 | rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg); |
7662 | if (rc == SQLITE_OK) { |
7663 | int i; |
7664 | char *zInner = 0; |
7665 | char *zOuter = 0; |
7666 | pTab->pNext = p->pTable; |
7667 | p->pTable = pTab; |
7668 | |
7669 | /* The statement the vtab will pass to sqlite3_declare_vtab() */ |
7670 | zInner = idxAppendText(&rc, 0, "CREATE TABLE x(" ); |
7671 | for (i = 0; i < pTab->nCol; i++) { |
7672 | zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s" , (i == 0 ? "" : ", " ), pTab->aCol[i].zName, |
7673 | pTab->aCol[i].zColl); |
7674 | } |
7675 | zInner = idxAppendText(&rc, zInner, ")" ); |
7676 | |
7677 | /* The CVT statement to create the vtab */ |
7678 | zOuter = idxAppendText(&rc, 0, "CREATE VIRTUAL TABLE %Q USING expert(%Q)" , zName, zInner); |
7679 | if (rc == SQLITE_OK) { |
7680 | rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg); |
7681 | } |
7682 | sqlite3_free(zInner); |
7683 | sqlite3_free(zOuter); |
7684 | } |
7685 | } |
7686 | } |
7687 | idxFinalize(&rc, pSchema); |
7688 | return rc; |
7689 | } |
7690 | |
7691 | struct IdxSampleCtx { |
7692 | int iTarget; |
7693 | double target; /* Target nRet/nRow value */ |
7694 | double nRow; /* Number of rows seen */ |
7695 | double nRet; /* Number of rows returned */ |
7696 | }; |
7697 | |
7698 | static void idxSampleFunc(sqlite3_context *pCtx, int argc, sqlite3_value **argv) { |
7699 | struct IdxSampleCtx *p = (struct IdxSampleCtx *)sqlite3_user_data(pCtx); |
7700 | int bRet; |
7701 | |
7702 | (void)argv; |
7703 | assert(argc == 0); |
7704 | if (p->nRow == 0.0) { |
7705 | bRet = 1; |
7706 | } else { |
7707 | bRet = (p->nRet / p->nRow) <= p->target; |
7708 | if (bRet == 0) { |
7709 | unsigned short rnd; |
7710 | sqlite3_randomness(2, (void *)&rnd); |
7711 | bRet = ((int)rnd % 100) <= p->iTarget; |
7712 | } |
7713 | } |
7714 | |
7715 | sqlite3_result_int(pCtx, bRet); |
7716 | p->nRow += 1.0; |
7717 | p->nRet += (double)bRet; |
7718 | } |
7719 | |
7720 | struct IdxRemCtx { |
7721 | int nSlot; |
7722 | struct IdxRemSlot { |
7723 | int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */ |
7724 | i64 iVal; /* SQLITE_INTEGER value */ |
7725 | double rVal; /* SQLITE_FLOAT value */ |
7726 | int nByte; /* Bytes of space allocated at z */ |
7727 | int n; /* Size of buffer z */ |
7728 | char *z; /* SQLITE_TEXT/BLOB value */ |
7729 | } aSlot[1]; |
7730 | }; |
7731 | |
7732 | /* |
7733 | ** Implementation of scalar function rem(). |
7734 | */ |
7735 | static void idxRemFunc(sqlite3_context *pCtx, int argc, sqlite3_value **argv) { |
7736 | struct IdxRemCtx *p = (struct IdxRemCtx *)sqlite3_user_data(pCtx); |
7737 | struct IdxRemSlot *pSlot; |
7738 | int iSlot; |
7739 | assert(argc == 2); |
7740 | |
7741 | iSlot = sqlite3_value_int(argv[0]); |
7742 | assert(iSlot <= p->nSlot); |
7743 | pSlot = &p->aSlot[iSlot]; |
7744 | |
7745 | switch (pSlot->eType) { |
7746 | case SQLITE_NULL: |
7747 | /* no-op */ |
7748 | break; |
7749 | |
7750 | case SQLITE_INTEGER: |
7751 | sqlite3_result_int64(pCtx, pSlot->iVal); |
7752 | break; |
7753 | |
7754 | case SQLITE_FLOAT: |
7755 | sqlite3_result_double(pCtx, pSlot->rVal); |
7756 | break; |
7757 | |
7758 | case SQLITE_BLOB: |
7759 | sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); |
7760 | break; |
7761 | |
7762 | case SQLITE_TEXT: |
7763 | sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT); |
7764 | break; |
7765 | } |
7766 | |
7767 | pSlot->eType = sqlite3_value_type(argv[1]); |
7768 | switch (pSlot->eType) { |
7769 | case SQLITE_NULL: |
7770 | /* no-op */ |
7771 | break; |
7772 | |
7773 | case SQLITE_INTEGER: |
7774 | pSlot->iVal = sqlite3_value_int64(argv[1]); |
7775 | break; |
7776 | |
7777 | case SQLITE_FLOAT: |
7778 | pSlot->rVal = sqlite3_value_double(argv[1]); |
7779 | break; |
7780 | |
7781 | case SQLITE_BLOB: |
7782 | case SQLITE_TEXT: { |
7783 | int nByte = sqlite3_value_bytes(argv[1]); |
7784 | if (nByte > pSlot->nByte) { |
7785 | char *zNew = (char *)sqlite3_realloc(pSlot->z, nByte * 2); |
7786 | if (zNew == 0) { |
7787 | sqlite3_result_error_nomem(pCtx); |
7788 | return; |
7789 | } |
7790 | pSlot->nByte = nByte * 2; |
7791 | pSlot->z = zNew; |
7792 | } |
7793 | pSlot->n = nByte; |
7794 | if (pSlot->eType == SQLITE_BLOB) { |
7795 | memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte); |
7796 | } else { |
7797 | memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte); |
7798 | } |
7799 | break; |
7800 | } |
7801 | } |
7802 | } |
7803 | |
7804 | static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr) { |
7805 | int rc = SQLITE_OK; |
7806 | const char *zMax = "SELECT max(i.seqno) FROM " |
7807 | " sqlite_master AS s, " |
7808 | " pragma_index_list(s.name) AS l, " |
7809 | " pragma_index_info(l.name) AS i " |
7810 | "WHERE s.type = 'table'" ; |
7811 | sqlite3_stmt *pMax = 0; |
7812 | |
7813 | *pnMax = 0; |
7814 | rc = idxPrepareStmt(db, &pMax, pzErr, zMax); |
7815 | if (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pMax)) { |
7816 | *pnMax = sqlite3_column_int(pMax, 0) + 1; |
7817 | } |
7818 | idxFinalize(&rc, pMax); |
7819 | |
7820 | return rc; |
7821 | } |
7822 | |
7823 | static int idxPopulateOneStat1(sqlite3expert *p, sqlite3_stmt *pIndexXInfo, sqlite3_stmt *pWriteStat, const char *zTab, |
7824 | const char *zIdx, char **pzErr) { |
7825 | char *zCols = 0; |
7826 | char *zOrder = 0; |
7827 | char *zQuery = 0; |
7828 | int nCol = 0; |
7829 | int i; |
7830 | sqlite3_stmt *pQuery = 0; |
7831 | int *aStat = 0; |
7832 | int rc = SQLITE_OK; |
7833 | |
7834 | assert(p->iSample > 0); |
7835 | |
7836 | /* Formulate the query text */ |
7837 | sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); |
7838 | while (SQLITE_OK == rc && SQLITE_ROW == sqlite3_step(pIndexXInfo)) { |
7839 | const char *zComma = zCols == 0 ? "" : ", " ; |
7840 | const char *zName = (const char *)sqlite3_column_text(pIndexXInfo, 0); |
7841 | const char *zColl = (const char *)sqlite3_column_text(pIndexXInfo, 1); |
7842 | zCols = idxAppendText(&rc, zCols, "%sx.%Q IS rem(%d, x.%Q) COLLATE %s" , zComma, zName, nCol, zName, zColl); |
7843 | zOrder = idxAppendText(&rc, zOrder, "%s%d" , zComma, ++nCol); |
7844 | } |
7845 | sqlite3_reset(pIndexXInfo); |
7846 | if (rc == SQLITE_OK) { |
7847 | if (p->iSample == 100) { |
7848 | zQuery = sqlite3_mprintf("SELECT %s FROM %Q x ORDER BY %s" , zCols, zTab, zOrder); |
7849 | } else { |
7850 | zQuery = sqlite3_mprintf("SELECT %s FROM temp." UNIQUE_TABLE_NAME " x ORDER BY %s" , zCols, zOrder); |
7851 | } |
7852 | } |
7853 | sqlite3_free(zCols); |
7854 | sqlite3_free(zOrder); |
7855 | |
7856 | /* Formulate the query text */ |
7857 | if (rc == SQLITE_OK) { |
7858 | sqlite3 *dbrem = (p->iSample == 100 ? p->db : p->dbv); |
7859 | rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery); |
7860 | } |
7861 | sqlite3_free(zQuery); |
7862 | |
7863 | if (rc == SQLITE_OK) { |
7864 | aStat = (int *)idxMalloc(&rc, sizeof(int) * (nCol + 1)); |
7865 | } |
7866 | if (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pQuery)) { |
7867 | IdxHashEntry *pEntry; |
7868 | char *zStat = 0; |
7869 | for (i = 0; i <= nCol; i++) |
7870 | aStat[i] = 1; |
7871 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pQuery)) { |
7872 | aStat[0]++; |
7873 | for (i = 0; i < nCol; i++) { |
7874 | if (sqlite3_column_int(pQuery, i) == 0) |
7875 | break; |
7876 | } |
7877 | for (/*no-op*/; i < nCol; i++) { |
7878 | aStat[i + 1]++; |
7879 | } |
7880 | } |
7881 | |
7882 | if (rc == SQLITE_OK) { |
7883 | int s0 = aStat[0]; |
7884 | zStat = sqlite3_mprintf("%d" , s0); |
7885 | if (zStat == 0) |
7886 | rc = SQLITE_NOMEM; |
7887 | for (i = 1; rc == SQLITE_OK && i <= nCol; i++) { |
7888 | zStat = idxAppendText(&rc, zStat, " %d" , (s0 + aStat[i] / 2) / aStat[i]); |
7889 | } |
7890 | } |
7891 | |
7892 | if (rc == SQLITE_OK) { |
7893 | sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC); |
7894 | sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC); |
7895 | sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC); |
7896 | sqlite3_step(pWriteStat); |
7897 | rc = sqlite3_reset(pWriteStat); |
7898 | } |
7899 | |
7900 | pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx)); |
7901 | if (pEntry) { |
7902 | assert(pEntry->zVal2 == 0); |
7903 | pEntry->zVal2 = zStat; |
7904 | } else { |
7905 | sqlite3_free(zStat); |
7906 | } |
7907 | } |
7908 | sqlite3_free(aStat); |
7909 | idxFinalize(&rc, pQuery); |
7910 | |
7911 | return rc; |
7912 | } |
7913 | |
7914 | static int idxBuildSampleTable(sqlite3expert *p, const char *zTab) { |
7915 | int rc; |
7916 | char *zSql; |
7917 | |
7918 | rc = sqlite3_exec(p->dbv, "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0, 0, 0); |
7919 | if (rc != SQLITE_OK) |
7920 | return rc; |
7921 | |
7922 | zSql = sqlite3_mprintf("CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q" , zTab); |
7923 | if (zSql == 0) |
7924 | return SQLITE_NOMEM; |
7925 | rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0); |
7926 | sqlite3_free(zSql); |
7927 | |
7928 | return rc; |
7929 | } |
7930 | |
7931 | /* |
7932 | ** This function is called as part of sqlite3_expert_analyze(). Candidate |
7933 | ** indexes have already been created in database sqlite3expert.dbm, this |
7934 | ** function populates sqlite_stat1 table in the same database. |
7935 | ** |
7936 | ** The stat1 data is generated by querying the |
7937 | */ |
7938 | static int idxPopulateStat1(sqlite3expert *p, char **pzErr) { |
7939 | int rc = SQLITE_OK; |
7940 | int nMax = 0; |
7941 | struct IdxRemCtx *pCtx = 0; |
7942 | struct IdxSampleCtx samplectx; |
7943 | int i; |
7944 | i64 iPrev = -100000; |
7945 | sqlite3_stmt *pAllIndex = 0; |
7946 | sqlite3_stmt *pIndexXInfo = 0; |
7947 | sqlite3_stmt *pWrite = 0; |
7948 | |
7949 | const char *zAllIndex = "SELECT s.rowid, s.name, l.name FROM " |
7950 | " sqlite_master AS s, " |
7951 | " pragma_index_list(s.name) AS l " |
7952 | "WHERE s.type = 'table'" ; |
7953 | const char *zIndexXInfo = "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key" ; |
7954 | const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)" ; |
7955 | |
7956 | /* If iSample==0, no sqlite_stat1 data is required. */ |
7957 | if (p->iSample == 0) |
7958 | return SQLITE_OK; |
7959 | |
7960 | rc = idxLargestIndex(p->dbm, &nMax, pzErr); |
7961 | if (nMax <= 0 || rc != SQLITE_OK) |
7962 | return rc; |
7963 | |
7964 | rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1" , 0, 0, 0); |
7965 | |
7966 | if (rc == SQLITE_OK) { |
7967 | int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax); |
7968 | pCtx = (struct IdxRemCtx *)idxMalloc(&rc, nByte); |
7969 | } |
7970 | |
7971 | if (rc == SQLITE_OK) { |
7972 | sqlite3 *dbrem = (p->iSample == 100 ? p->db : p->dbv); |
7973 | rc = sqlite3_create_function(dbrem, "rem" , 2, SQLITE_UTF8, (void *)pCtx, idxRemFunc, 0, 0); |
7974 | } |
7975 | if (rc == SQLITE_OK) { |
7976 | rc = sqlite3_create_function(p->db, "sample" , 0, SQLITE_UTF8, (void *)&samplectx, idxSampleFunc, 0, 0); |
7977 | } |
7978 | |
7979 | if (rc == SQLITE_OK) { |
7980 | pCtx->nSlot = nMax + 1; |
7981 | rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex); |
7982 | } |
7983 | if (rc == SQLITE_OK) { |
7984 | rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo); |
7985 | } |
7986 | if (rc == SQLITE_OK) { |
7987 | rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite); |
7988 | } |
7989 | |
7990 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pAllIndex)) { |
7991 | i64 iRowid = sqlite3_column_int64(pAllIndex, 0); |
7992 | const char *zTab = (const char *)sqlite3_column_text(pAllIndex, 1); |
7993 | const char *zIdx = (const char *)sqlite3_column_text(pAllIndex, 2); |
7994 | if (p->iSample < 100 && iPrev != iRowid) { |
7995 | samplectx.target = (double)p->iSample / 100.0; |
7996 | samplectx.iTarget = p->iSample; |
7997 | samplectx.nRow = 0.0; |
7998 | samplectx.nRet = 0.0; |
7999 | rc = idxBuildSampleTable(p, zTab); |
8000 | if (rc != SQLITE_OK) |
8001 | break; |
8002 | } |
8003 | rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr); |
8004 | iPrev = iRowid; |
8005 | } |
8006 | if (rc == SQLITE_OK && p->iSample < 100) { |
8007 | rc = sqlite3_exec(p->dbv, "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0, 0, 0); |
8008 | } |
8009 | |
8010 | idxFinalize(&rc, pAllIndex); |
8011 | idxFinalize(&rc, pIndexXInfo); |
8012 | idxFinalize(&rc, pWrite); |
8013 | |
8014 | for (i = 0; i < pCtx->nSlot; i++) { |
8015 | sqlite3_free(pCtx->aSlot[i].z); |
8016 | } |
8017 | sqlite3_free(pCtx); |
8018 | |
8019 | if (rc == SQLITE_OK) { |
8020 | rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master" , 0, 0, 0); |
8021 | } |
8022 | |
8023 | sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0, 0, 0); |
8024 | return rc; |
8025 | } |
8026 | |
8027 | /* |
8028 | ** Allocate a new sqlite3expert object. |
8029 | */ |
8030 | sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg) { |
8031 | int rc = SQLITE_OK; |
8032 | sqlite3expert *pNew; |
8033 | |
8034 | pNew = (sqlite3expert *)idxMalloc(&rc, sizeof(sqlite3expert)); |
8035 | |
8036 | /* Open two in-memory databases to work with. The "vtab database" (dbv) |
8037 | ** will contain a virtual table corresponding to each real table in |
8038 | ** the user database schema, and a copy of each view. It is used to |
8039 | ** collect information regarding the WHERE, ORDER BY and other clauses |
8040 | ** of the user's query. |
8041 | */ |
8042 | if (rc == SQLITE_OK) { |
8043 | pNew->db = db; |
8044 | pNew->iSample = 100; |
8045 | rc = sqlite3_open(":memory:" , &pNew->dbv); |
8046 | } |
8047 | if (rc == SQLITE_OK) { |
8048 | rc = sqlite3_open(":memory:" , &pNew->dbm); |
8049 | if (rc == SQLITE_OK) { |
8050 | sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int *)0); |
8051 | } |
8052 | } |
8053 | |
8054 | /* Copy the entire schema of database [db] into [dbm]. */ |
8055 | if (rc == SQLITE_OK) { |
8056 | sqlite3_stmt *pSql; |
8057 | rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, |
8058 | "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'" |
8059 | " AND sql NOT LIKE 'CREATE VIRTUAL %%'" ); |
8060 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pSql)) { |
8061 | const char *zSql = (const char *)sqlite3_column_text(pSql, 0); |
8062 | rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg); |
8063 | } |
8064 | idxFinalize(&rc, pSql); |
8065 | } |
8066 | |
8067 | /* Create the vtab schema */ |
8068 | if (rc == SQLITE_OK) { |
8069 | rc = idxCreateVtabSchema(pNew, pzErrmsg); |
8070 | } |
8071 | |
8072 | /* Register the auth callback with dbv */ |
8073 | if (rc == SQLITE_OK) { |
8074 | sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void *)pNew); |
8075 | } |
8076 | |
8077 | /* If an error has occurred, free the new object and reutrn NULL. Otherwise, |
8078 | ** return the new sqlite3expert handle. */ |
8079 | if (rc != SQLITE_OK) { |
8080 | sqlite3_expert_destroy(pNew); |
8081 | pNew = 0; |
8082 | } |
8083 | return pNew; |
8084 | } |
8085 | |
8086 | /* |
8087 | ** Configure an sqlite3expert object. |
8088 | */ |
8089 | int sqlite3_expert_config(sqlite3expert *p, int op, ...) { |
8090 | int rc = SQLITE_OK; |
8091 | va_list ap; |
8092 | va_start(ap, op); |
8093 | switch (op) { |
8094 | case EXPERT_CONFIG_SAMPLE: { |
8095 | int iVal = va_arg(ap, int); |
8096 | if (iVal < 0) |
8097 | iVal = 0; |
8098 | if (iVal > 100) |
8099 | iVal = 100; |
8100 | p->iSample = iVal; |
8101 | break; |
8102 | } |
8103 | default: |
8104 | rc = SQLITE_NOTFOUND; |
8105 | break; |
8106 | } |
8107 | |
8108 | va_end(ap); |
8109 | return rc; |
8110 | } |
8111 | |
8112 | /* |
8113 | ** Add an SQL statement to the analysis. |
8114 | */ |
8115 | int sqlite3_expert_sql(sqlite3expert *p, /* From sqlite3_expert_new() */ |
8116 | const char *zSql, /* SQL statement to add */ |
8117 | char **pzErr /* OUT: Error message (if any) */ |
8118 | ) { |
8119 | IdxScan *pScanOrig = p->pScan; |
8120 | IdxStatement *pStmtOrig = p->pStatement; |
8121 | int rc = SQLITE_OK; |
8122 | const char *zStmt = zSql; |
8123 | |
8124 | if (p->bRun) |
8125 | return SQLITE_MISUSE; |
8126 | |
8127 | while (rc == SQLITE_OK && zStmt && zStmt[0]) { |
8128 | sqlite3_stmt *pStmt = 0; |
8129 | rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); |
8130 | if (rc == SQLITE_OK) { |
8131 | if (pStmt) { |
8132 | IdxStatement *pNew; |
8133 | const char *z = sqlite3_sql(pStmt); |
8134 | int n = STRLEN(z); |
8135 | pNew = (IdxStatement *)idxMalloc(&rc, sizeof(IdxStatement) + n + 1); |
8136 | if (rc == SQLITE_OK) { |
8137 | pNew->zSql = (char *)&pNew[1]; |
8138 | memcpy(pNew->zSql, z, n + 1); |
8139 | pNew->pNext = p->pStatement; |
8140 | if (p->pStatement) |
8141 | pNew->iId = p->pStatement->iId + 1; |
8142 | p->pStatement = pNew; |
8143 | } |
8144 | sqlite3_finalize(pStmt); |
8145 | } |
8146 | } else { |
8147 | idxDatabaseError(p->dbv, pzErr); |
8148 | } |
8149 | } |
8150 | |
8151 | if (rc != SQLITE_OK) { |
8152 | idxScanFree(p->pScan, pScanOrig); |
8153 | idxStatementFree(p->pStatement, pStmtOrig); |
8154 | p->pScan = pScanOrig; |
8155 | p->pStatement = pStmtOrig; |
8156 | } |
8157 | |
8158 | return rc; |
8159 | } |
8160 | |
8161 | int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr) { |
8162 | int rc; |
8163 | IdxHashEntry *pEntry; |
8164 | |
8165 | /* Do trigger processing to collect any extra IdxScan structures */ |
8166 | rc = idxProcessTriggers(p, pzErr); |
8167 | |
8168 | /* Create candidate indexes within the in-memory database file */ |
8169 | if (rc == SQLITE_OK) { |
8170 | rc = idxCreateCandidates(p); |
8171 | } |
8172 | |
8173 | /* Generate the stat1 data */ |
8174 | if (rc == SQLITE_OK) { |
8175 | rc = idxPopulateStat1(p, pzErr); |
8176 | } |
8177 | |
8178 | /* Formulate the EXPERT_REPORT_CANDIDATES text */ |
8179 | for (pEntry = p->hIdx.pFirst; pEntry; pEntry = pEntry->pNext) { |
8180 | p->zCandidates = idxAppendText(&rc, p->zCandidates, "%s;%s%s\n" , pEntry->zVal, |
8181 | pEntry->zVal2 ? " -- stat1: " : "" , pEntry->zVal2); |
8182 | } |
8183 | |
8184 | /* Figure out which of the candidate indexes are preferred by the query |
8185 | ** planner and report the results to the user. */ |
8186 | if (rc == SQLITE_OK) { |
8187 | rc = idxFindIndexes(p, pzErr); |
8188 | } |
8189 | |
8190 | if (rc == SQLITE_OK) { |
8191 | p->bRun = 1; |
8192 | } |
8193 | return rc; |
8194 | } |
8195 | |
8196 | /* |
8197 | ** Return the total number of statements that have been added to this |
8198 | ** sqlite3expert using sqlite3_expert_sql(). |
8199 | */ |
8200 | int sqlite3_expert_count(sqlite3expert *p) { |
8201 | int nRet = 0; |
8202 | if (p->pStatement) |
8203 | nRet = p->pStatement->iId + 1; |
8204 | return nRet; |
8205 | } |
8206 | |
8207 | /* |
8208 | ** Return a component of the report. |
8209 | */ |
8210 | const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport) { |
8211 | const char *zRet = 0; |
8212 | IdxStatement *pStmt; |
8213 | |
8214 | if (p->bRun == 0) |
8215 | return 0; |
8216 | for (pStmt = p->pStatement; pStmt && pStmt->iId != iStmt; pStmt = pStmt->pNext) |
8217 | ; |
8218 | switch (eReport) { |
8219 | case EXPERT_REPORT_SQL: |
8220 | if (pStmt) |
8221 | zRet = pStmt->zSql; |
8222 | break; |
8223 | case EXPERT_REPORT_INDEXES: |
8224 | if (pStmt) |
8225 | zRet = pStmt->zIdx; |
8226 | break; |
8227 | case EXPERT_REPORT_PLAN: |
8228 | if (pStmt) |
8229 | zRet = pStmt->zEQP; |
8230 | break; |
8231 | case EXPERT_REPORT_CANDIDATES: |
8232 | zRet = p->zCandidates; |
8233 | break; |
8234 | } |
8235 | return zRet; |
8236 | } |
8237 | |
8238 | /* |
8239 | ** Free an sqlite3expert object. |
8240 | */ |
8241 | void sqlite3_expert_destroy(sqlite3expert *p) { |
8242 | if (p) { |
8243 | sqlite3_close(p->dbm); |
8244 | sqlite3_close(p->dbv); |
8245 | idxScanFree(p->pScan, 0); |
8246 | idxStatementFree(p->pStatement, 0); |
8247 | idxTableFree(p->pTable); |
8248 | idxWriteFree(p->pWrite); |
8249 | idxHashClear(&p->hIdx); |
8250 | sqlite3_free(p->zCandidates); |
8251 | sqlite3_free(p); |
8252 | } |
8253 | } |
8254 | |
8255 | #endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */ |
8256 | |
8257 | /************************* End ../ext/expert/sqlite3expert.c ********************/ |
8258 | |
8259 | #if defined(SQLITE_ENABLE_SESSION) |
8260 | /* |
8261 | ** State information for a single open session |
8262 | */ |
8263 | typedef struct OpenSession OpenSession; |
8264 | struct OpenSession { |
8265 | char *zName; /* Symbolic name for this session */ |
8266 | int nFilter; /* Number of xFilter rejection GLOB patterns */ |
8267 | char **azFilter; /* Array of xFilter rejection GLOB patterns */ |
8268 | sqlite3_session *p; /* The open session */ |
8269 | }; |
8270 | #endif |
8271 | |
8272 | /* |
8273 | ** Shell output mode information from before ".explain on", |
8274 | ** saved so that it can be restored by ".explain off" |
8275 | */ |
8276 | typedef struct SavedModeInfo SavedModeInfo; |
8277 | struct SavedModeInfo { |
8278 | int valid; /* Is there legit data in here? */ |
8279 | int mode; /* Mode prior to ".explain on" */ |
8280 | int ; /* The ".header" setting prior to ".explain on" */ |
8281 | int colWidth[100]; /* Column widths prior to ".explain on" */ |
8282 | }; |
8283 | |
8284 | typedef struct ExpertInfo ExpertInfo; |
8285 | struct ExpertInfo { |
8286 | sqlite3expert *pExpert; |
8287 | int bVerbose; |
8288 | }; |
8289 | |
8290 | /* |
8291 | ** State information about the database connection is contained in an |
8292 | ** instance of the following structure. |
8293 | */ |
8294 | typedef struct ShellState ShellState; |
8295 | struct ShellState { |
8296 | sqlite3 *db; /* The database */ |
8297 | u8 autoExplain; /* Automatically turn on .explain mode */ |
8298 | u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ |
8299 | u8 statsOn; /* True to display memory stats before each finalize */ |
8300 | u8 scanstatsOn; /* True to display scan stats before each finalize */ |
8301 | u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ |
8302 | u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ |
8303 | int outCount; /* Revert to stdout when reaching zero */ |
8304 | int cnt; /* Number of records displayed so far */ |
8305 | FILE *out; /* Write results here */ |
8306 | FILE *traceOut; /* Output for sqlite3_trace() */ |
8307 | int nErr; /* Number of errors seen */ |
8308 | int mode; /* An output mode setting */ |
8309 | int modePrior; /* Saved mode */ |
8310 | int cMode; /* temporary output mode for the current query */ |
8311 | int normalMode; /* Output mode before ".explain on" */ |
8312 | int writableSchema; /* True if PRAGMA writable_schema=ON */ |
8313 | int ; /* True to show column names in List or Column mode */ |
8314 | int nCheck; /* Number of ".check" commands run */ |
8315 | unsigned shellFlgs; /* Various flags */ |
8316 | char *zDestTable; /* Name of destination table when MODE_Insert */ |
8317 | char *zTempFile; /* Temporary file that might need deleting */ |
8318 | char zTestcase[30]; /* Name of current test case */ |
8319 | char colSeparator[20]; /* Column separator character for several modes */ |
8320 | char rowSeparator[20]; /* Row separator character for MODE_Ascii */ |
8321 | char colSepPrior[20]; /* Saved column separator */ |
8322 | char rowSepPrior[20]; /* Saved row separator */ |
8323 | int colWidth[100]; /* Requested width of each column when in column mode*/ |
8324 | int actualWidth[100]; /* Actual width of each column */ |
8325 | char nullValue[20]; /* The text to print when a NULL comes back from |
8326 | ** the database */ |
8327 | char outfile[FILENAME_MAX]; /* Filename for *out */ |
8328 | const char *zDbFilename; /* name of the database file */ |
8329 | char *zFreeOnClose; /* Filename to free when closing */ |
8330 | const char *zVfs; /* Name of VFS to use */ |
8331 | sqlite3_stmt *pStmt; /* Current statement if any. */ |
8332 | FILE *pLog; /* Write log output here */ |
8333 | int *aiIndent; /* Array of indents used in MODE_Explain */ |
8334 | int nIndent; /* Size of array aiIndent[] */ |
8335 | int iIndent; /* Index of current op in aiIndent[] */ |
8336 | #if defined(SQLITE_ENABLE_SESSION) |
8337 | int nSession; /* Number of active sessions */ |
8338 | OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ |
8339 | #endif |
8340 | ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ |
8341 | }; |
8342 | |
8343 | /* Allowed values for ShellState.autoEQP |
8344 | */ |
8345 | #define AUTOEQP_off 0 |
8346 | #define AUTOEQP_on 1 |
8347 | #define AUTOEQP_trigger 2 |
8348 | #define AUTOEQP_full 3 |
8349 | |
8350 | /* Allowed values for ShellState.openMode |
8351 | */ |
8352 | #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ |
8353 | #define SHELL_OPEN_NORMAL 1 /* Normal database file */ |
8354 | #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ |
8355 | #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ |
8356 | #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ |
8357 | |
8358 | /* |
8359 | ** These are the allowed shellFlgs values |
8360 | */ |
8361 | #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */ |
8362 | #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */ |
8363 | #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */ |
8364 | #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */ |
8365 | #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ |
8366 | #define SHFLG_CountChanges 0x00000020 /* .changes setting */ |
8367 | #define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ |
8368 | |
8369 | /* |
8370 | ** Macros for testing and setting shellFlgs |
8371 | */ |
8372 | #define ShellHasFlag(P, X) (((P)->shellFlgs & (X)) != 0) |
8373 | #define ShellSetFlag(P, X) ((P)->shellFlgs |= (X)) |
8374 | #define ShellClearFlag(P, X) ((P)->shellFlgs &= (~(X))) |
8375 | |
8376 | /* |
8377 | ** These are the allowed modes. |
8378 | */ |
8379 | #define MODE_Line 0 /* One column per line. Blank line between records */ |
8380 | #define MODE_Column 1 /* One record per line in neat columns */ |
8381 | #define MODE_List 2 /* One record per line with a separator */ |
8382 | #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ |
8383 | #define MODE_Html 4 /* Generate an XHTML table */ |
8384 | #define MODE_Insert 5 /* Generate SQL "insert" statements */ |
8385 | #define MODE_Quote 6 /* Quote values as for SQL */ |
8386 | #define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */ |
8387 | #define MODE_Csv 8 /* Quote strings, numbers are plain */ |
8388 | #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ |
8389 | #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ |
8390 | #define MODE_Pretty 11 /* Pretty-print schemas */ |
8391 | |
8392 | static const char *modeDescr[] = { |
8393 | "line" , "column" , "list" , "semi" , "html" , "insert" , "quote" , "tcl" , "csv" , "explain" , "ascii" , "prettyprint" , |
8394 | }; |
8395 | |
8396 | /* |
8397 | ** These are the column/row/line separators used by the various |
8398 | ** import/export modes. |
8399 | */ |
8400 | #define SEP_Column "|" |
8401 | #define SEP_Row "\n" |
8402 | #define SEP_Tab "\t" |
8403 | #define SEP_Space " " |
8404 | #define SEP_Comma "," |
8405 | #define SEP_CrLf "\r\n" |
8406 | #define SEP_Unit "\x1F" |
8407 | #define SEP_Record "\x1E" |
8408 | |
8409 | /* |
8410 | ** A callback for the sqlite3_log() interface. |
8411 | */ |
8412 | static void shellLog(void *pArg, int iErrCode, const char *zMsg) { |
8413 | ShellState *p = (ShellState *)pArg; |
8414 | if (p->pLog == 0) |
8415 | return; |
8416 | utf8_printf(p->pLog, "(%d) %s\n" , iErrCode, zMsg); |
8417 | fflush(p->pLog); |
8418 | } |
8419 | |
8420 | /* |
8421 | ** SQL function: shell_putsnl(X) |
8422 | ** |
8423 | ** Write the text X to the screen (or whatever output is being directed) |
8424 | ** adding a newline at the end, and then return X. |
8425 | */ |
8426 | static void shellPutsFunc(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal) { |
8427 | ShellState *p = (ShellState *)sqlite3_user_data(pCtx); |
8428 | (void)nVal; |
8429 | utf8_printf(p->out, "%s\n" , sqlite3_value_text(apVal[0])); |
8430 | sqlite3_result_value(pCtx, apVal[0]); |
8431 | } |
8432 | |
8433 | /* |
8434 | ** SQL function: edit(VALUE) |
8435 | ** edit(VALUE,EDITOR) |
8436 | ** |
8437 | ** These steps: |
8438 | ** |
8439 | ** (1) Write VALUE into a temporary file. |
8440 | ** (2) Run program EDITOR on that temporary file. |
8441 | ** (3) Read the temporary file back and return its content as the result. |
8442 | ** (4) Delete the temporary file |
8443 | ** |
8444 | ** If the EDITOR argument is omitted, use the value in the VISUAL |
8445 | ** environment variable. If still there is no EDITOR, through an error. |
8446 | ** |
8447 | ** Also throw an error if the EDITOR program returns a non-zero exit code. |
8448 | */ |
8449 | #ifndef SQLITE_NOHAVE_SYSTEM |
8450 | static void editFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { |
8451 | const char *zEditor; |
8452 | char *zTempFile = 0; |
8453 | sqlite3 *db; |
8454 | char *zCmd = 0; |
8455 | int bBin; |
8456 | int rc; |
8457 | FILE *f = 0; |
8458 | sqlite3_int64 sz; |
8459 | sqlite3_int64 x; |
8460 | unsigned char *p = 0; |
8461 | |
8462 | if (argc == 2) { |
8463 | zEditor = (const char *)sqlite3_value_text(argv[1]); |
8464 | } else { |
8465 | zEditor = getenv("VISUAL" ); |
8466 | } |
8467 | if (zEditor == 0) { |
8468 | sqlite3_result_error(context, "no editor for edit()" , -1); |
8469 | return; |
8470 | } |
8471 | if (sqlite3_value_type(argv[0]) == SQLITE_NULL) { |
8472 | sqlite3_result_error(context, "NULL input to edit()" , -1); |
8473 | return; |
8474 | } |
8475 | db = sqlite3_context_db_handle(context); |
8476 | zTempFile = 0; |
8477 | sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile); |
8478 | if (zTempFile == 0) { |
8479 | sqlite3_uint64 r = 0; |
8480 | sqlite3_randomness(sizeof(r), &r); |
8481 | zTempFile = sqlite3_mprintf("temp%llx" , r); |
8482 | if (zTempFile == 0) { |
8483 | sqlite3_result_error_nomem(context); |
8484 | return; |
8485 | } |
8486 | } |
8487 | bBin = sqlite3_value_type(argv[0]) == SQLITE_BLOB; |
8488 | f = fopen(zTempFile, bBin ? "wb" : "w" ); |
8489 | if (f == 0) { |
8490 | sqlite3_result_error(context, "edit() cannot open temp file" , -1); |
8491 | goto edit_func_end; |
8492 | } |
8493 | sz = sqlite3_value_bytes(argv[0]); |
8494 | if (bBin) { |
8495 | x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f); |
8496 | } else { |
8497 | x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f); |
8498 | } |
8499 | fclose(f); |
8500 | f = 0; |
8501 | if (x != sz) { |
8502 | sqlite3_result_error(context, "edit() could not write the whole file" , -1); |
8503 | goto edit_func_end; |
8504 | } |
8505 | zCmd = sqlite3_mprintf("%s \"%s\"" , zEditor, zTempFile); |
8506 | if (zCmd == 0) { |
8507 | sqlite3_result_error_nomem(context); |
8508 | goto edit_func_end; |
8509 | } |
8510 | rc = system(zCmd); |
8511 | sqlite3_free(zCmd); |
8512 | if (rc) { |
8513 | sqlite3_result_error(context, "EDITOR returned non-zero" , -1); |
8514 | goto edit_func_end; |
8515 | } |
8516 | f = fopen(zTempFile, bBin ? "rb" : "r" ); |
8517 | if (f == 0) { |
8518 | sqlite3_result_error(context, "edit() cannot reopen temp file after edit" , -1); |
8519 | goto edit_func_end; |
8520 | } |
8521 | fseek(f, 0, SEEK_END); |
8522 | sz = ftell(f); |
8523 | rewind(f); |
8524 | p = sqlite3_malloc64(sz + (bBin == 0)); |
8525 | if (p == 0) { |
8526 | sqlite3_result_error_nomem(context); |
8527 | goto edit_func_end; |
8528 | } |
8529 | if (bBin) { |
8530 | x = fread(p, 1, sz, f); |
8531 | } else { |
8532 | x = fread(p, 1, sz, f); |
8533 | p[sz] = 0; |
8534 | } |
8535 | fclose(f); |
8536 | f = 0; |
8537 | if (x != sz) { |
8538 | sqlite3_result_error(context, "could not read back the whole file" , -1); |
8539 | goto edit_func_end; |
8540 | } |
8541 | if (bBin) { |
8542 | sqlite3_result_blob64(context, p, sz, sqlite3_free); |
8543 | } else { |
8544 | sqlite3_result_text64(context, (const char *)p, sz, sqlite3_free, SQLITE_UTF8); |
8545 | } |
8546 | p = 0; |
8547 | |
8548 | edit_func_end: |
8549 | if (f) |
8550 | fclose(f); |
8551 | unlink(zTempFile); |
8552 | sqlite3_free(zTempFile); |
8553 | sqlite3_free(p); |
8554 | } |
8555 | #endif /* SQLITE_NOHAVE_SYSTEM */ |
8556 | |
8557 | /* |
8558 | ** Save or restore the current output mode |
8559 | */ |
8560 | static void outputModePush(ShellState *p) { |
8561 | p->modePrior = p->mode; |
8562 | memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator)); |
8563 | memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator)); |
8564 | } |
8565 | static void outputModePop(ShellState *p) { |
8566 | p->mode = p->modePrior; |
8567 | memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator)); |
8568 | memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator)); |
8569 | } |
8570 | |
8571 | /* |
8572 | ** Output the given string as a hex-encoded blob (eg. X'1234' ) |
8573 | */ |
8574 | static void output_hex_blob(FILE *out, const void *pBlob, int nBlob) { |
8575 | int i; |
8576 | char *zBlob = (char *)pBlob; |
8577 | raw_printf(out, "X'" ); |
8578 | for (i = 0; i < nBlob; i++) { |
8579 | raw_printf(out, "%02x" , zBlob[i] & 0xff); |
8580 | } |
8581 | raw_printf(out, "'" ); |
8582 | } |
8583 | |
8584 | /* |
8585 | ** Find a string that is not found anywhere in z[]. Return a pointer |
8586 | ** to that string. |
8587 | ** |
8588 | ** Try to use zA and zB first. If both of those are already found in z[] |
8589 | ** then make up some string and store it in the buffer zBuf. |
8590 | */ |
8591 | static const char *unused_string(const char *z, /* Result must not appear anywhere in z */ |
8592 | const char *zA, const char *zB, /* Try these first */ |
8593 | char *zBuf /* Space to store a generated string */ |
8594 | ) { |
8595 | unsigned i = 0; |
8596 | if (strstr(z, zA) == 0) |
8597 | return zA; |
8598 | if (strstr(z, zB) == 0) |
8599 | return zB; |
8600 | do { |
8601 | sqlite3_snprintf(20, zBuf, "(%s%u)" , zA, i++); |
8602 | } while (strstr(z, zBuf) != 0); |
8603 | return zBuf; |
8604 | } |
8605 | |
8606 | /* |
8607 | ** Output the given string as a quoted string using SQL quoting conventions. |
8608 | ** |
8609 | ** See also: output_quoted_escaped_string() |
8610 | */ |
8611 | static void output_quoted_string(FILE *out, const char *z) { |
8612 | int i; |
8613 | char c; |
8614 | setBinaryMode(out, 1); |
8615 | for (i = 0; (c = z[i]) != 0 && c != '\''; i++) { |
8616 | } |
8617 | if (c == 0) { |
8618 | utf8_printf(out, "'%s'" , z); |
8619 | } else { |
8620 | raw_printf(out, "'" ); |
8621 | while (*z) { |
8622 | for (i = 0; (c = z[i]) != 0 && c != '\''; i++) { |
8623 | } |
8624 | if (c == '\'') |
8625 | i++; |
8626 | if (i) { |
8627 | utf8_printf(out, "%.*s" , i, z); |
8628 | z += i; |
8629 | } |
8630 | if (c == '\'') { |
8631 | raw_printf(out, "'" ); |
8632 | continue; |
8633 | } |
8634 | if (c == 0) { |
8635 | break; |
8636 | } |
8637 | z++; |
8638 | } |
8639 | raw_printf(out, "'" ); |
8640 | } |
8641 | setTextMode(out, 1); |
8642 | } |
8643 | |
8644 | /* |
8645 | ** Output the given string as a quoted string using SQL quoting conventions. |
8646 | ** Additionallly , escape the "\n" and "\r" characters so that they do not |
8647 | ** get corrupted by end-of-line translation facilities in some operating |
8648 | ** systems. |
8649 | ** |
8650 | ** This is like output_quoted_string() but with the addition of the \r\n |
8651 | ** escape mechanism. |
8652 | */ |
8653 | static void output_quoted_escaped_string(FILE *out, const char *z) { |
8654 | int i; |
8655 | char c; |
8656 | setBinaryMode(out, 1); |
8657 | for (i = 0; (c = z[i]) != 0 && c != '\'' && c != '\n' && c != '\r'; i++) { |
8658 | } |
8659 | if (c == 0) { |
8660 | utf8_printf(out, "'%s'" , z); |
8661 | } else { |
8662 | const char *zNL = 0; |
8663 | const char *zCR = 0; |
8664 | int nNL = 0; |
8665 | int nCR = 0; |
8666 | char zBuf1[20], zBuf2[20]; |
8667 | for (i = 0; z[i]; i++) { |
8668 | if (z[i] == '\n') |
8669 | nNL++; |
8670 | if (z[i] == '\r') |
8671 | nCR++; |
8672 | } |
8673 | if (nNL) { |
8674 | raw_printf(out, "replace(" ); |
8675 | zNL = unused_string(z, "\\n" , "\\012" , zBuf1); |
8676 | } |
8677 | if (nCR) { |
8678 | raw_printf(out, "replace(" ); |
8679 | zCR = unused_string(z, "\\r" , "\\015" , zBuf2); |
8680 | } |
8681 | raw_printf(out, "'" ); |
8682 | while (*z) { |
8683 | for (i = 0; (c = z[i]) != 0 && c != '\n' && c != '\r' && c != '\''; i++) { |
8684 | } |
8685 | if (c == '\'') |
8686 | i++; |
8687 | if (i) { |
8688 | utf8_printf(out, "%.*s" , i, z); |
8689 | z += i; |
8690 | } |
8691 | if (c == '\'') { |
8692 | raw_printf(out, "'" ); |
8693 | continue; |
8694 | } |
8695 | if (c == 0) { |
8696 | break; |
8697 | } |
8698 | z++; |
8699 | if (c == '\n') { |
8700 | raw_printf(out, "%s" , zNL); |
8701 | continue; |
8702 | } |
8703 | raw_printf(out, "%s" , zCR); |
8704 | } |
8705 | raw_printf(out, "'" ); |
8706 | if (nCR) { |
8707 | raw_printf(out, ",'%s',char(13))" , zCR); |
8708 | } |
8709 | if (nNL) { |
8710 | raw_printf(out, ",'%s',char(10))" , zNL); |
8711 | } |
8712 | } |
8713 | setTextMode(out, 1); |
8714 | } |
8715 | |
8716 | /* |
8717 | ** Output the given string as a quoted according to C or TCL quoting rules. |
8718 | */ |
8719 | static void output_c_string(FILE *out, const char *z) { |
8720 | unsigned int c; |
8721 | fputc('"', out); |
8722 | while ((c = *(z++)) != 0) { |
8723 | if (c == '\\') { |
8724 | fputc(c, out); |
8725 | fputc(c, out); |
8726 | } else if (c == '"') { |
8727 | fputc('\\', out); |
8728 | fputc('"', out); |
8729 | } else if (c == '\t') { |
8730 | fputc('\\', out); |
8731 | fputc('t', out); |
8732 | } else if (c == '\n') { |
8733 | fputc('\\', out); |
8734 | fputc('n', out); |
8735 | } else if (c == '\r') { |
8736 | fputc('\\', out); |
8737 | fputc('r', out); |
8738 | } else if (!isprint(c & 0xff)) { |
8739 | raw_printf(out, "\\%03o" , c & 0xff); |
8740 | } else { |
8741 | fputc(c, out); |
8742 | } |
8743 | } |
8744 | fputc('"', out); |
8745 | } |
8746 | |
8747 | /* |
8748 | ** Output the given string with characters that are special to |
8749 | ** HTML escaped. |
8750 | */ |
8751 | static void output_html_string(FILE *out, const char *z) { |
8752 | int i; |
8753 | if (z == 0) |
8754 | z = "" ; |
8755 | while (*z) { |
8756 | for (i = 0; z[i] && z[i] != '<' && z[i] != '&' && z[i] != '>' && z[i] != '\"' && z[i] != '\''; i++) { |
8757 | } |
8758 | if (i > 0) { |
8759 | utf8_printf(out, "%.*s" , i, z); |
8760 | } |
8761 | if (z[i] == '<') { |
8762 | raw_printf(out, "<" ); |
8763 | } else if (z[i] == '&') { |
8764 | raw_printf(out, "&" ); |
8765 | } else if (z[i] == '>') { |
8766 | raw_printf(out, ">" ); |
8767 | } else if (z[i] == '\"') { |
8768 | raw_printf(out, """ ); |
8769 | } else if (z[i] == '\'') { |
8770 | raw_printf(out, "'" ); |
8771 | } else { |
8772 | break; |
8773 | } |
8774 | z += i + 1; |
8775 | } |
8776 | } |
8777 | |
8778 | /* |
8779 | ** If a field contains any character identified by a 1 in the following |
8780 | ** array, then the string must be quoted for CSV. |
8781 | */ |
8782 | static const char needCsvQuote[] = { |
8783 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, |
8784 | 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
8785 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
8786 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
8787 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
8788 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
8789 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
8790 | }; |
8791 | |
8792 | /* |
8793 | ** Output a single term of CSV. Actually, p->colSeparator is used for |
8794 | ** the separator, which may or may not be a comma. p->nullValue is |
8795 | ** the null value. Strings are quoted if necessary. The separator |
8796 | ** is only issued if bSep is true. |
8797 | */ |
8798 | static void output_csv(ShellState *p, const char *z, int bSep) { |
8799 | FILE *out = p->out; |
8800 | if (z == 0) { |
8801 | utf8_printf(out, "%s" , p->nullValue); |
8802 | } else { |
8803 | int i; |
8804 | int nSep = strlen30(p->colSeparator); |
8805 | for (i = 0; z[i]; i++) { |
8806 | if (needCsvQuote[((unsigned char *)z)[i]] || |
8807 | (z[i] == p->colSeparator[0] && (nSep == 1 || memcmp(z, p->colSeparator, nSep) == 0))) { |
8808 | i = 0; |
8809 | break; |
8810 | } |
8811 | } |
8812 | if (i == 0) { |
8813 | char *zQuoted = sqlite3_mprintf("\"%w\"" , z); |
8814 | utf8_printf(out, "%s" , zQuoted); |
8815 | sqlite3_free(zQuoted); |
8816 | } else { |
8817 | utf8_printf(out, "%s" , z); |
8818 | } |
8819 | } |
8820 | if (bSep) { |
8821 | utf8_printf(p->out, "%s" , p->colSeparator); |
8822 | } |
8823 | } |
8824 | |
8825 | /* |
8826 | ** This routine runs when the user presses Ctrl-C |
8827 | */ |
8828 | static void interrupt_handler(int NotUsed) { |
8829 | UNUSED_PARAMETER(NotUsed); |
8830 | seenInterrupt++; |
8831 | if (seenInterrupt > 2) |
8832 | exit(1); |
8833 | if (globalDb) |
8834 | sqlite3_interrupt(globalDb); |
8835 | } |
8836 | |
8837 | #if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) |
8838 | /* |
8839 | ** This routine runs for console events (e.g. Ctrl-C) on Win32 |
8840 | */ |
8841 | static BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */ |
8842 | ) { |
8843 | if (dwCtrlType == CTRL_C_EVENT) { |
8844 | interrupt_handler(0); |
8845 | return TRUE; |
8846 | } |
8847 | return FALSE; |
8848 | } |
8849 | #endif |
8850 | |
8851 | #ifndef SQLITE_OMIT_AUTHORIZATION |
8852 | /* |
8853 | ** When the ".auth ON" is set, the following authorizer callback is |
8854 | ** invoked. It always returns SQLITE_OK. |
8855 | */ |
8856 | static int shellAuth(void *pClientData, int op, const char *zA1, const char *zA2, const char *zA3, const char *zA4) { |
8857 | ShellState *p = (ShellState *)pClientData; |
8858 | static const char *azAction[] = {0, |
8859 | "CREATE_INDEX" , |
8860 | "CREATE_TABLE" , |
8861 | "CREATE_TEMP_INDEX" , |
8862 | "CREATE_TEMP_TABLE" , |
8863 | "CREATE_TEMP_TRIGGER" , |
8864 | "CREATE_TEMP_VIEW" , |
8865 | "CREATE_TRIGGER" , |
8866 | "CREATE_VIEW" , |
8867 | "DELETE" , |
8868 | "DROP_INDEX" , |
8869 | "DROP_TABLE" , |
8870 | "DROP_TEMP_INDEX" , |
8871 | "DROP_TEMP_TABLE" , |
8872 | "DROP_TEMP_TRIGGER" , |
8873 | "DROP_TEMP_VIEW" , |
8874 | "DROP_TRIGGER" , |
8875 | "DROP_VIEW" , |
8876 | "INSERT" , |
8877 | "PRAGMA" , |
8878 | "READ" , |
8879 | "SELECT" , |
8880 | "TRANSACTION" , |
8881 | "UPDATE" , |
8882 | "ATTACH" , |
8883 | "DETACH" , |
8884 | "ALTER_TABLE" , |
8885 | "REINDEX" , |
8886 | "ANALYZE" , |
8887 | "CREATE_VTABLE" , |
8888 | "DROP_VTABLE" , |
8889 | "FUNCTION" , |
8890 | "SAVEPOINT" , |
8891 | "RECURSIVE" }; |
8892 | int i; |
8893 | const char *az[4]; |
8894 | az[0] = zA1; |
8895 | az[1] = zA2; |
8896 | az[2] = zA3; |
8897 | az[3] = zA4; |
8898 | utf8_printf(p->out, "authorizer: %s" , azAction[op]); |
8899 | for (i = 0; i < 4; i++) { |
8900 | raw_printf(p->out, " " ); |
8901 | if (az[i]) { |
8902 | output_c_string(p->out, az[i]); |
8903 | } else { |
8904 | raw_printf(p->out, "NULL" ); |
8905 | } |
8906 | } |
8907 | raw_printf(p->out, "\n" ); |
8908 | return SQLITE_OK; |
8909 | } |
8910 | #endif |
8911 | |
8912 | /* |
8913 | ** Print a schema statement. Part of MODE_Semi and MODE_Pretty output. |
8914 | ** |
8915 | ** This routine converts some CREATE TABLE statements for shadow tables |
8916 | ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements. |
8917 | */ |
8918 | static void printSchemaLine(FILE *out, const char *z, const char *zTail) { |
8919 | if (sqlite3_strglob("CREATE TABLE ['\"]*" , z) == 0) { |
8920 | utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s" , z + 13, zTail); |
8921 | } else { |
8922 | utf8_printf(out, "%s%s" , z, zTail); |
8923 | } |
8924 | } |
8925 | static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail) { |
8926 | char c = z[n]; |
8927 | z[n] = 0; |
8928 | printSchemaLine(out, z, zTail); |
8929 | z[n] = c; |
8930 | } |
8931 | |
8932 | /* |
8933 | ** Return true if string z[] has nothing but whitespace and comments to the |
8934 | ** end of the first line. |
8935 | */ |
8936 | static int wsToEol(const char *z) { |
8937 | int i; |
8938 | for (i = 0; z[i]; i++) { |
8939 | if (z[i] == '\n') |
8940 | return 1; |
8941 | if (IsSpace(z[i])) |
8942 | continue; |
8943 | if (z[i] == '-' && z[i + 1] == '-') |
8944 | return 1; |
8945 | return 0; |
8946 | } |
8947 | return 1; |
8948 | } |
8949 | |
8950 | /* |
8951 | ** This is the callback routine that the shell |
8952 | ** invokes for each row of a query result. |
8953 | */ |
8954 | static int shell_callback(void *pArg, int nArg, /* Number of result columns */ |
8955 | char **azArg, /* Text of each result column */ |
8956 | char **azCol, /* Column names */ |
8957 | int *aiType /* Column types */ |
8958 | ) { |
8959 | int i; |
8960 | ShellState *p = (ShellState *)pArg; |
8961 | |
8962 | if (azArg == 0) |
8963 | return 0; |
8964 | switch (p->cMode) { |
8965 | case MODE_Line: { |
8966 | int w = 5; |
8967 | if (azArg == 0) |
8968 | break; |
8969 | for (i = 0; i < nArg; i++) { |
8970 | int len = strlen30(azCol[i] ? azCol[i] : "" ); |
8971 | if (len > w) |
8972 | w = len; |
8973 | } |
8974 | if (p->cnt++ > 0) |
8975 | utf8_printf(p->out, "%s" , p->rowSeparator); |
8976 | for (i = 0; i < nArg; i++) { |
8977 | utf8_printf(p->out, "%*s = %s%s" , w, azCol[i], azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); |
8978 | } |
8979 | break; |
8980 | } |
8981 | case MODE_Explain: |
8982 | case MODE_Column: { |
8983 | static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13}; |
8984 | const int *colWidth; |
8985 | int showHdr; |
8986 | char *rowSep; |
8987 | if (p->cMode == MODE_Column) { |
8988 | colWidth = p->colWidth; |
8989 | showHdr = p->showHeader; |
8990 | rowSep = p->rowSeparator; |
8991 | } else { |
8992 | colWidth = aExplainWidths; |
8993 | showHdr = 1; |
8994 | rowSep = SEP_Row; |
8995 | } |
8996 | if (p->cnt++ == 0) { |
8997 | for (i = 0; i < nArg; i++) { |
8998 | int w, n; |
8999 | if (i < ArraySize(p->colWidth)) { |
9000 | w = colWidth[i]; |
9001 | } else { |
9002 | w = 0; |
9003 | } |
9004 | if (w == 0) { |
9005 | w = strlenChar(azCol[i] ? azCol[i] : "" ); |
9006 | if (w < 10) |
9007 | w = 10; |
9008 | n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue); |
9009 | if (w < n) |
9010 | w = n; |
9011 | } |
9012 | if (i < ArraySize(p->actualWidth)) { |
9013 | p->actualWidth[i] = w; |
9014 | } |
9015 | if (showHdr) { |
9016 | utf8_width_print(p->out, w, azCol[i]); |
9017 | utf8_printf(p->out, "%s" , i == nArg - 1 ? rowSep : " " ); |
9018 | } |
9019 | } |
9020 | if (showHdr) { |
9021 | for (i = 0; i < nArg; i++) { |
9022 | int w; |
9023 | if (i < ArraySize(p->actualWidth)) { |
9024 | w = p->actualWidth[i]; |
9025 | if (w < 0) |
9026 | w = -w; |
9027 | } else { |
9028 | w = 10; |
9029 | } |
9030 | utf8_printf(p->out, "%-*.*s%s" , w, w, |
9031 | "----------------------------------------------------------" |
9032 | "----------------------------------------------------------" , |
9033 | i == nArg - 1 ? rowSep : " " ); |
9034 | } |
9035 | } |
9036 | } |
9037 | if (azArg == 0) |
9038 | break; |
9039 | for (i = 0; i < nArg; i++) { |
9040 | int w; |
9041 | if (i < ArraySize(p->actualWidth)) { |
9042 | w = p->actualWidth[i]; |
9043 | } else { |
9044 | w = 10; |
9045 | } |
9046 | if (p->cMode == MODE_Explain && azArg[i] && strlenChar(azArg[i]) > w) { |
9047 | w = strlenChar(azArg[i]); |
9048 | } |
9049 | if (i == 1 && p->aiIndent && p->pStmt) { |
9050 | if (p->iIndent < p->nIndent) { |
9051 | utf8_printf(p->out, "%*.s" , p->aiIndent[p->iIndent], "" ); |
9052 | } |
9053 | p->iIndent++; |
9054 | } |
9055 | utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue); |
9056 | utf8_printf(p->out, "%s" , i == nArg - 1 ? rowSep : " " ); |
9057 | } |
9058 | break; |
9059 | } |
9060 | case MODE_Semi: { /* .schema and .fullschema output */ |
9061 | printSchemaLine(p->out, azArg[0], ";\n" ); |
9062 | break; |
9063 | } |
9064 | case MODE_Pretty: { /* .schema and .fullschema with --indent */ |
9065 | char *z; |
9066 | int j; |
9067 | int nParen = 0; |
9068 | char cEnd = 0; |
9069 | char c; |
9070 | int nLine = 0; |
9071 | assert(nArg == 1); |
9072 | if (azArg[0] == 0) |
9073 | break; |
9074 | if (sqlite3_strlike("CREATE VIEW%" , azArg[0], 0) == 0 || sqlite3_strlike("CREATE TRIG%" , azArg[0], 0) == 0) { |
9075 | utf8_printf(p->out, "%s;\n" , azArg[0]); |
9076 | break; |
9077 | } |
9078 | z = sqlite3_mprintf("%s" , azArg[0]); |
9079 | j = 0; |
9080 | for (i = 0; IsSpace(z[i]); i++) { |
9081 | } |
9082 | for (; (c = z[i]) != 0; i++) { |
9083 | if (IsSpace(c)) { |
9084 | if (z[j - 1] == '\r') |
9085 | z[j - 1] = '\n'; |
9086 | if (IsSpace(z[j - 1]) || z[j - 1] == '(') |
9087 | continue; |
9088 | } else if ((c == '(' || c == ')') && j > 0 && IsSpace(z[j - 1])) { |
9089 | j--; |
9090 | } |
9091 | z[j++] = c; |
9092 | } |
9093 | while (j > 0 && IsSpace(z[j - 1])) { |
9094 | j--; |
9095 | } |
9096 | z[j] = 0; |
9097 | if (strlen30(z) >= 79) { |
9098 | for (i = j = 0; (c = z[i]) != 0; i++) { /* Copy changes from z[i] back to z[j] */ |
9099 | if (c == cEnd) { |
9100 | cEnd = 0; |
9101 | } else if (c == '"' || c == '\'' || c == '`') { |
9102 | cEnd = c; |
9103 | } else if (c == '[') { |
9104 | cEnd = ']'; |
9105 | } else if (c == '-' && z[i + 1] == '-') { |
9106 | cEnd = '\n'; |
9107 | } else if (c == '(') { |
9108 | nParen++; |
9109 | } else if (c == ')') { |
9110 | nParen--; |
9111 | if (nLine > 0 && nParen == 0 && j > 0) { |
9112 | printSchemaLineN(p->out, z, j, "\n" ); |
9113 | j = 0; |
9114 | } |
9115 | } |
9116 | z[j++] = c; |
9117 | if (nParen == 1 && cEnd == 0 && (c == '(' || c == '\n' || (c == ',' && !wsToEol(z + i + 1)))) { |
9118 | if (c == '\n') |
9119 | j--; |
9120 | printSchemaLineN(p->out, z, j, "\n " ); |
9121 | j = 0; |
9122 | nLine++; |
9123 | while (IsSpace(z[i + 1])) { |
9124 | i++; |
9125 | } |
9126 | } |
9127 | } |
9128 | z[j] = 0; |
9129 | } |
9130 | printSchemaLine(p->out, z, ";\n" ); |
9131 | sqlite3_free(z); |
9132 | break; |
9133 | } |
9134 | case MODE_List: { |
9135 | if (p->cnt++ == 0 && p->showHeader) { |
9136 | for (i = 0; i < nArg; i++) { |
9137 | utf8_printf(p->out, "%s%s" , azCol[i], i == nArg - 1 ? p->rowSeparator : p->colSeparator); |
9138 | } |
9139 | } |
9140 | if (azArg == 0) |
9141 | break; |
9142 | for (i = 0; i < nArg; i++) { |
9143 | char *z = azArg[i]; |
9144 | if (z == 0) |
9145 | z = p->nullValue; |
9146 | utf8_printf(p->out, "%s" , z); |
9147 | if (i < nArg - 1) { |
9148 | utf8_printf(p->out, "%s" , p->colSeparator); |
9149 | } else { |
9150 | utf8_printf(p->out, "%s" , p->rowSeparator); |
9151 | } |
9152 | } |
9153 | break; |
9154 | } |
9155 | case MODE_Html: { |
9156 | if (p->cnt++ == 0 && p->showHeader) { |
9157 | raw_printf(p->out, "<TR>" ); |
9158 | for (i = 0; i < nArg; i++) { |
9159 | raw_printf(p->out, "<TH>" ); |
9160 | output_html_string(p->out, azCol[i]); |
9161 | raw_printf(p->out, "</TH>\n" ); |
9162 | } |
9163 | raw_printf(p->out, "</TR>\n" ); |
9164 | } |
9165 | if (azArg == 0) |
9166 | break; |
9167 | raw_printf(p->out, "<TR>" ); |
9168 | for (i = 0; i < nArg; i++) { |
9169 | raw_printf(p->out, "<TD>" ); |
9170 | output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); |
9171 | raw_printf(p->out, "</TD>\n" ); |
9172 | } |
9173 | raw_printf(p->out, "</TR>\n" ); |
9174 | break; |
9175 | } |
9176 | case MODE_Tcl: { |
9177 | if (p->cnt++ == 0 && p->showHeader) { |
9178 | for (i = 0; i < nArg; i++) { |
9179 | output_c_string(p->out, azCol[i] ? azCol[i] : "" ); |
9180 | if (i < nArg - 1) |
9181 | utf8_printf(p->out, "%s" , p->colSeparator); |
9182 | } |
9183 | utf8_printf(p->out, "%s" , p->rowSeparator); |
9184 | } |
9185 | if (azArg == 0) |
9186 | break; |
9187 | for (i = 0; i < nArg; i++) { |
9188 | output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); |
9189 | if (i < nArg - 1) |
9190 | utf8_printf(p->out, "%s" , p->colSeparator); |
9191 | } |
9192 | utf8_printf(p->out, "%s" , p->rowSeparator); |
9193 | break; |
9194 | } |
9195 | case MODE_Csv: { |
9196 | setBinaryMode(p->out, 1); |
9197 | if (p->cnt++ == 0 && p->showHeader) { |
9198 | for (i = 0; i < nArg; i++) { |
9199 | output_csv(p, azCol[i] ? azCol[i] : "" , i < nArg - 1); |
9200 | } |
9201 | utf8_printf(p->out, "%s" , p->rowSeparator); |
9202 | } |
9203 | if (nArg > 0) { |
9204 | for (i = 0; i < nArg; i++) { |
9205 | output_csv(p, azArg[i], i < nArg - 1); |
9206 | } |
9207 | utf8_printf(p->out, "%s" , p->rowSeparator); |
9208 | } |
9209 | setTextMode(p->out, 1); |
9210 | break; |
9211 | } |
9212 | case MODE_Insert: { |
9213 | if (azArg == 0) |
9214 | break; |
9215 | utf8_printf(p->out, "INSERT INTO %s" , p->zDestTable); |
9216 | if (p->showHeader) { |
9217 | raw_printf(p->out, "(" ); |
9218 | for (i = 0; i < nArg; i++) { |
9219 | if (i > 0) |
9220 | raw_printf(p->out, "," ); |
9221 | if (quoteChar(azCol[i])) { |
9222 | char *z = sqlite3_mprintf("\"%w\"" , azCol[i]); |
9223 | utf8_printf(p->out, "%s" , z); |
9224 | sqlite3_free(z); |
9225 | } else { |
9226 | raw_printf(p->out, "%s" , azCol[i]); |
9227 | } |
9228 | } |
9229 | raw_printf(p->out, ")" ); |
9230 | } |
9231 | p->cnt++; |
9232 | for (i = 0; i < nArg; i++) { |
9233 | raw_printf(p->out, i > 0 ? "," : " VALUES(" ); |
9234 | if ((azArg[i] == 0) || (aiType && aiType[i] == SQLITE_NULL)) { |
9235 | utf8_printf(p->out, "NULL" ); |
9236 | } else if (aiType && aiType[i] == SQLITE_TEXT) { |
9237 | if (ShellHasFlag(p, SHFLG_Newlines)) { |
9238 | output_quoted_string(p->out, azArg[i]); |
9239 | } else { |
9240 | output_quoted_escaped_string(p->out, azArg[i]); |
9241 | } |
9242 | } else if (aiType && aiType[i] == SQLITE_INTEGER) { |
9243 | utf8_printf(p->out, "%s" , azArg[i]); |
9244 | } else if (aiType && aiType[i] == SQLITE_FLOAT) { |
9245 | char z[50]; |
9246 | double r = sqlite3_column_double(p->pStmt, i); |
9247 | sqlite3_snprintf(50, z, "%!.20g" , r); |
9248 | raw_printf(p->out, "%s" , z); |
9249 | } else if (aiType && aiType[i] == SQLITE_BLOB && p->pStmt) { |
9250 | const void *pBlob = sqlite3_column_blob(p->pStmt, i); |
9251 | int nBlob = sqlite3_column_bytes(p->pStmt, i); |
9252 | output_hex_blob(p->out, pBlob, nBlob); |
9253 | } else if (isNumber(azArg[i], 0)) { |
9254 | utf8_printf(p->out, "%s" , azArg[i]); |
9255 | } else if (ShellHasFlag(p, SHFLG_Newlines)) { |
9256 | output_quoted_string(p->out, azArg[i]); |
9257 | } else { |
9258 | output_quoted_escaped_string(p->out, azArg[i]); |
9259 | } |
9260 | } |
9261 | raw_printf(p->out, ");\n" ); |
9262 | break; |
9263 | } |
9264 | case MODE_Quote: { |
9265 | if (azArg == 0) |
9266 | break; |
9267 | if (p->cnt == 0 && p->showHeader) { |
9268 | for (i = 0; i < nArg; i++) { |
9269 | if (i > 0) |
9270 | raw_printf(p->out, "," ); |
9271 | output_quoted_string(p->out, azCol[i]); |
9272 | } |
9273 | raw_printf(p->out, "\n" ); |
9274 | } |
9275 | p->cnt++; |
9276 | for (i = 0; i < nArg; i++) { |
9277 | if (i > 0) |
9278 | raw_printf(p->out, "," ); |
9279 | if ((azArg[i] == 0) || (aiType && aiType[i] == SQLITE_NULL)) { |
9280 | utf8_printf(p->out, "NULL" ); |
9281 | } else if (aiType && aiType[i] == SQLITE_TEXT) { |
9282 | output_quoted_string(p->out, azArg[i]); |
9283 | } else if (aiType && aiType[i] == SQLITE_INTEGER) { |
9284 | utf8_printf(p->out, "%s" , azArg[i]); |
9285 | } else if (aiType && aiType[i] == SQLITE_FLOAT) { |
9286 | char z[50]; |
9287 | double r = sqlite3_column_double(p->pStmt, i); |
9288 | sqlite3_snprintf(50, z, "%!.20g" , r); |
9289 | raw_printf(p->out, "%s" , z); |
9290 | } else if (aiType && aiType[i] == SQLITE_BLOB && p->pStmt) { |
9291 | const void *pBlob = sqlite3_column_blob(p->pStmt, i); |
9292 | int nBlob = sqlite3_column_bytes(p->pStmt, i); |
9293 | output_hex_blob(p->out, pBlob, nBlob); |
9294 | } else if (isNumber(azArg[i], 0)) { |
9295 | utf8_printf(p->out, "%s" , azArg[i]); |
9296 | } else { |
9297 | output_quoted_string(p->out, azArg[i]); |
9298 | } |
9299 | } |
9300 | raw_printf(p->out, "\n" ); |
9301 | break; |
9302 | } |
9303 | case MODE_Ascii: { |
9304 | if (p->cnt++ == 0 && p->showHeader) { |
9305 | for (i = 0; i < nArg; i++) { |
9306 | if (i > 0) |
9307 | utf8_printf(p->out, "%s" , p->colSeparator); |
9308 | utf8_printf(p->out, "%s" , azCol[i] ? azCol[i] : "" ); |
9309 | } |
9310 | utf8_printf(p->out, "%s" , p->rowSeparator); |
9311 | } |
9312 | if (azArg == 0) |
9313 | break; |
9314 | for (i = 0; i < nArg; i++) { |
9315 | if (i > 0) |
9316 | utf8_printf(p->out, "%s" , p->colSeparator); |
9317 | utf8_printf(p->out, "%s" , azArg[i] ? azArg[i] : p->nullValue); |
9318 | } |
9319 | utf8_printf(p->out, "%s" , p->rowSeparator); |
9320 | break; |
9321 | } |
9322 | } |
9323 | return 0; |
9324 | } |
9325 | |
9326 | /* |
9327 | ** This is the callback routine that the SQLite library |
9328 | ** invokes for each row of a query result. |
9329 | */ |
9330 | static int callback(void *pArg, int nArg, char **azArg, char **azCol) { |
9331 | /* since we don't have type info, call the shell_callback with a NULL value */ |
9332 | return shell_callback(pArg, nArg, azArg, azCol, NULL); |
9333 | } |
9334 | |
9335 | /* |
9336 | ** This is the callback routine from sqlite3_exec() that appends all |
9337 | ** output onto the end of a ShellText object. |
9338 | */ |
9339 | static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az) { |
9340 | ShellText *p = (ShellText *)pArg; |
9341 | int i; |
9342 | UNUSED_PARAMETER(az); |
9343 | if (azArg == 0) |
9344 | return 0; |
9345 | if (p->n) |
9346 | appendText(p, "|" , 0); |
9347 | for (i = 0; i < nArg; i++) { |
9348 | if (i) |
9349 | appendText(p, "," , 0); |
9350 | if (azArg[i]) |
9351 | appendText(p, azArg[i], 0); |
9352 | } |
9353 | return 0; |
9354 | } |
9355 | |
9356 | /* |
9357 | ** Generate an appropriate SELFTEST table in the main database. |
9358 | */ |
9359 | static void createSelftestTable(ShellState *p) { |
9360 | char *zErrMsg = 0; |
9361 | sqlite3_exec(p->db, |
9362 | "SAVEPOINT selftest_init;\n" |
9363 | "CREATE TABLE IF NOT EXISTS selftest(\n" |
9364 | " tno INTEGER PRIMARY KEY,\n" /* Test number */ |
9365 | " op TEXT,\n" /* Operator: memo run */ |
9366 | " cmd TEXT,\n" /* Command text */ |
9367 | " ans TEXT\n" /* Desired answer */ |
9368 | ");" |
9369 | "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n" |
9370 | "INSERT INTO [_shell$self](rowid,op,cmd)\n" |
9371 | " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n" |
9372 | " 'memo','Tests generated by --init');\n" |
9373 | "INSERT INTO [_shell$self]\n" |
9374 | " SELECT 'run',\n" |
9375 | " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql " |
9376 | "FROM sqlite_master ORDER BY 2'',224))',\n" |
9377 | " hex(sha3_query('SELECT type,name,tbl_name,sql " |
9378 | "FROM sqlite_master ORDER BY 2',224));\n" |
9379 | "INSERT INTO [_shell$self]\n" |
9380 | " SELECT 'run'," |
9381 | " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||" |
9382 | " printf('%w',name) || '\" NOT INDEXED'',224))',\n" |
9383 | " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n" |
9384 | " FROM (\n" |
9385 | " SELECT name FROM sqlite_master\n" |
9386 | " WHERE type='table'\n" |
9387 | " AND name<>'selftest'\n" |
9388 | " AND coalesce(rootpage,0)>0\n" |
9389 | " )\n" |
9390 | " ORDER BY name;\n" |
9391 | "INSERT INTO [_shell$self]\n" |
9392 | " VALUES('run','PRAGMA integrity_check','ok');\n" |
9393 | "INSERT INTO selftest(tno,op,cmd,ans)" |
9394 | " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n" |
9395 | "DROP TABLE [_shell$self];" , |
9396 | 0, 0, &zErrMsg); |
9397 | if (zErrMsg) { |
9398 | utf8_printf(stderr, "SELFTEST initialization failure: %s\n" , zErrMsg); |
9399 | sqlite3_free(zErrMsg); |
9400 | } |
9401 | sqlite3_exec(p->db, "RELEASE selftest_init" , 0, 0, 0); |
9402 | } |
9403 | |
9404 | /* |
9405 | ** Set the destination table field of the ShellState structure to |
9406 | ** the name of the table given. Escape any quote characters in the |
9407 | ** table name. |
9408 | */ |
9409 | static void set_table_name(ShellState *p, const char *zName) { |
9410 | int i, n; |
9411 | char cQuote; |
9412 | char *z; |
9413 | |
9414 | if (p->zDestTable) { |
9415 | free(p->zDestTable); |
9416 | p->zDestTable = 0; |
9417 | } |
9418 | if (zName == 0) |
9419 | return; |
9420 | cQuote = quoteChar(zName); |
9421 | n = strlen30(zName); |
9422 | if (cQuote) |
9423 | n += n + 2; |
9424 | z = p->zDestTable = malloc(n + 1); |
9425 | if (z == 0) { |
9426 | raw_printf(stderr, "Error: out of memory\n" ); |
9427 | exit(1); |
9428 | } |
9429 | n = 0; |
9430 | if (cQuote) |
9431 | z[n++] = cQuote; |
9432 | for (i = 0; zName[i]; i++) { |
9433 | z[n++] = zName[i]; |
9434 | if (zName[i] == cQuote) |
9435 | z[n++] = cQuote; |
9436 | } |
9437 | if (cQuote) |
9438 | z[n++] = cQuote; |
9439 | z[n] = 0; |
9440 | } |
9441 | |
9442 | /* |
9443 | ** Execute a query statement that will generate SQL output. Print |
9444 | ** the result columns, comma-separated, on a line and then add a |
9445 | ** semicolon terminator to the end of that line. |
9446 | ** |
9447 | ** If the number of columns is 1 and that column contains text "--" |
9448 | ** then write the semicolon on a separate line. That way, if a |
9449 | ** "--" comment occurs at the end of the statement, the comment |
9450 | ** won't consume the semicolon terminator. |
9451 | */ |
9452 | static int run_table_dump_query(ShellState *p, /* Query context */ |
9453 | const char *zSelect, /* SELECT statement to extract content */ |
9454 | const char *zFirstRow /* Print before first row, if not NULL */ |
9455 | ) { |
9456 | sqlite3_stmt *pSelect; |
9457 | int rc; |
9458 | int nResult; |
9459 | int i; |
9460 | const char *z; |
9461 | rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); |
9462 | if (rc != SQLITE_OK || !pSelect) { |
9463 | utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n" , rc, sqlite3_errmsg(p->db)); |
9464 | if ((rc & 0xff) != SQLITE_CORRUPT) |
9465 | p->nErr++; |
9466 | return rc; |
9467 | } |
9468 | rc = sqlite3_step(pSelect); |
9469 | nResult = sqlite3_column_count(pSelect); |
9470 | while (rc == SQLITE_ROW) { |
9471 | if (zFirstRow) { |
9472 | utf8_printf(p->out, "%s" , zFirstRow); |
9473 | zFirstRow = 0; |
9474 | } |
9475 | z = (const char *)sqlite3_column_text(pSelect, 0); |
9476 | utf8_printf(p->out, "%s" , z); |
9477 | for (i = 1; i < nResult; i++) { |
9478 | utf8_printf(p->out, ",%s" , sqlite3_column_text(pSelect, i)); |
9479 | } |
9480 | if (z == 0) |
9481 | z = "" ; |
9482 | while (z[0] && (z[0] != '-' || z[1] != '-')) |
9483 | z++; |
9484 | if (z[0]) { |
9485 | raw_printf(p->out, "\n;\n" ); |
9486 | } else { |
9487 | raw_printf(p->out, ";\n" ); |
9488 | } |
9489 | rc = sqlite3_step(pSelect); |
9490 | } |
9491 | rc = sqlite3_finalize(pSelect); |
9492 | if (rc != SQLITE_OK) { |
9493 | utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n" , rc, sqlite3_errmsg(p->db)); |
9494 | if ((rc & 0xff) != SQLITE_CORRUPT) |
9495 | p->nErr++; |
9496 | } |
9497 | return rc; |
9498 | } |
9499 | |
9500 | /* |
9501 | ** Allocate space and save off current error string. |
9502 | */ |
9503 | static char *save_err_msg(sqlite3 *db /* Database to query */ |
9504 | ) { |
9505 | int nErrMsg = 1 + strlen30(sqlite3_errmsg(db)); |
9506 | char *zErrMsg = sqlite3_malloc64(nErrMsg); |
9507 | if (zErrMsg) { |
9508 | memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); |
9509 | } |
9510 | return zErrMsg; |
9511 | } |
9512 | |
9513 | #ifdef __linux__ |
9514 | /* |
9515 | ** Attempt to display I/O stats on Linux using /proc/PID/io |
9516 | */ |
9517 | static void displayLinuxIoStats(FILE *out) { |
9518 | FILE *in; |
9519 | char z[200]; |
9520 | sqlite3_snprintf(sizeof(z), z, "/proc/%d/io" , getpid()); |
9521 | in = fopen(z, "rb" ); |
9522 | if (in == 0) |
9523 | return; |
9524 | while (fgets(z, sizeof(z), in) != 0) { |
9525 | static const struct { |
9526 | const char *zPattern; |
9527 | const char *zDesc; |
9528 | } aTrans[] = { |
9529 | {"rchar: " , "Bytes received by read():" }, |
9530 | {"wchar: " , "Bytes sent to write():" }, |
9531 | {"syscr: " , "Read() system calls:" }, |
9532 | {"syscw: " , "Write() system calls:" }, |
9533 | {"read_bytes: " , "Bytes read from storage:" }, |
9534 | {"write_bytes: " , "Bytes written to storage:" }, |
9535 | {"cancelled_write_bytes: " , "Cancelled write bytes:" }, |
9536 | }; |
9537 | int i; |
9538 | for (i = 0; i < ArraySize(aTrans); i++) { |
9539 | int n = strlen30(aTrans[i].zPattern); |
9540 | if (strncmp(aTrans[i].zPattern, z, n) == 0) { |
9541 | utf8_printf(out, "%-36s %s" , aTrans[i].zDesc, &z[n]); |
9542 | break; |
9543 | } |
9544 | } |
9545 | } |
9546 | fclose(in); |
9547 | } |
9548 | #endif |
9549 | |
9550 | /* |
9551 | ** Display a single line of status using 64-bit values. |
9552 | */ |
9553 | static void displayStatLine(ShellState *p, /* The shell context */ |
9554 | char *zLabel, /* Label for this one line */ |
9555 | char *zFormat, /* Format for the result */ |
9556 | int iStatusCtrl, /* Which status to display */ |
9557 | int bReset /* True to reset the stats */ |
9558 | ) { |
9559 | sqlite3_int64 iCur = -1; |
9560 | sqlite3_int64 iHiwtr = -1; |
9561 | int i, nPercent; |
9562 | char zLine[200]; |
9563 | sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset); |
9564 | for (i = 0, nPercent = 0; zFormat[i]; i++) { |
9565 | if (zFormat[i] == '%') |
9566 | nPercent++; |
9567 | } |
9568 | if (nPercent > 1) { |
9569 | sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr); |
9570 | } else { |
9571 | sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr); |
9572 | } |
9573 | raw_printf(p->out, "%-36s %s\n" , zLabel, zLine); |
9574 | } |
9575 | |
9576 | /* |
9577 | ** Display memory stats. |
9578 | */ |
9579 | static int display_stats(sqlite3 *db, /* Database to query */ |
9580 | ShellState *pArg, /* Pointer to ShellState */ |
9581 | int bReset /* True to reset the stats */ |
9582 | ) { |
9583 | int iCur; |
9584 | int iHiwtr; |
9585 | FILE *out; |
9586 | if (pArg == 0 || pArg->out == 0) |
9587 | return 0; |
9588 | out = pArg->out; |
9589 | |
9590 | if (pArg->pStmt && (pArg->statsOn & 2)) { |
9591 | int nCol, i, x; |
9592 | sqlite3_stmt *pStmt = pArg->pStmt; |
9593 | char z[100]; |
9594 | nCol = sqlite3_column_count(pStmt); |
9595 | raw_printf(out, "%-36s %d\n" , "Number of output columns:" , nCol); |
9596 | for (i = 0; i < nCol; i++) { |
9597 | sqlite3_snprintf(sizeof(z), z, "Column %d %nname:" , i, &x); |
9598 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_name(pStmt, i)); |
9599 | #ifndef SQLITE_OMIT_DECLTYPE |
9600 | sqlite3_snprintf(30, z + x, "declared type:" ); |
9601 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_decltype(pStmt, i)); |
9602 | #endif |
9603 | #ifdef SQLITE_ENABLE_COLUMN_METADATA |
9604 | sqlite3_snprintf(30, z + x, "database name:" ); |
9605 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_database_name(pStmt, i)); |
9606 | sqlite3_snprintf(30, z + x, "table name:" ); |
9607 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_table_name(pStmt, i)); |
9608 | sqlite3_snprintf(30, z + x, "origin name:" ); |
9609 | utf8_printf(out, "%-36s %s\n" , z, sqlite3_column_origin_name(pStmt, i)); |
9610 | #endif |
9611 | } |
9612 | } |
9613 | |
9614 | displayStatLine(pArg, "Memory Used:" , "%lld (max %lld) bytes" , SQLITE_STATUS_MEMORY_USED, bReset); |
9615 | displayStatLine(pArg, "Number of Outstanding Allocations:" , "%lld (max %lld)" , SQLITE_STATUS_MALLOC_COUNT, bReset); |
9616 | if (pArg->shellFlgs & SHFLG_Pagecache) { |
9617 | displayStatLine(pArg, "Number of Pcache Pages Used:" , "%lld (max %lld) pages" , SQLITE_STATUS_PAGECACHE_USED, |
9618 | bReset); |
9619 | } |
9620 | displayStatLine(pArg, "Number of Pcache Overflow Bytes:" , "%lld (max %lld) bytes" , SQLITE_STATUS_PAGECACHE_OVERFLOW, |
9621 | bReset); |
9622 | displayStatLine(pArg, "Largest Allocation:" , "%lld bytes" , SQLITE_STATUS_MALLOC_SIZE, bReset); |
9623 | displayStatLine(pArg, "Largest Pcache Allocation:" , "%lld bytes" , SQLITE_STATUS_PAGECACHE_SIZE, bReset); |
9624 | #ifdef YYTRACKMAXSTACKDEPTH |
9625 | displayStatLine(pArg, "Deepest Parser Stack:" , "%lld (max %lld)" , SQLITE_STATUS_PARSER_STACK, bReset); |
9626 | #endif |
9627 | |
9628 | if (db) { |
9629 | if (pArg->shellFlgs & SHFLG_Lookaside) { |
9630 | iHiwtr = iCur = -1; |
9631 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset); |
9632 | raw_printf(pArg->out, "Lookaside Slots Used: %d (max %d)\n" , iCur, iHiwtr); |
9633 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset); |
9634 | raw_printf(pArg->out, "Successful lookaside attempts: %d\n" , iHiwtr); |
9635 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset); |
9636 | raw_printf(pArg->out, "Lookaside failures due to size: %d\n" , iHiwtr); |
9637 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset); |
9638 | raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n" , iHiwtr); |
9639 | } |
9640 | iHiwtr = iCur = -1; |
9641 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); |
9642 | raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n" , iCur); |
9643 | iHiwtr = iCur = -1; |
9644 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); |
9645 | raw_printf(pArg->out, "Page cache hits: %d\n" , iCur); |
9646 | iHiwtr = iCur = -1; |
9647 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); |
9648 | raw_printf(pArg->out, "Page cache misses: %d\n" , iCur); |
9649 | iHiwtr = iCur = -1; |
9650 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); |
9651 | raw_printf(pArg->out, "Page cache writes: %d\n" , iCur); |
9652 | iHiwtr = iCur = -1; |
9653 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); |
9654 | raw_printf(pArg->out, "Page cache spills: %d\n" , iCur); |
9655 | iHiwtr = iCur = -1; |
9656 | sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); |
9657 | raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n" , iCur); |
9658 | iHiwtr = iCur = -1; |
9659 | sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); |
9660 | raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n" , iCur); |
9661 | } |
9662 | |
9663 | if (pArg->pStmt) { |
9664 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset); |
9665 | raw_printf(pArg->out, "Fullscan Steps: %d\n" , iCur); |
9666 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); |
9667 | raw_printf(pArg->out, "Sort Operations: %d\n" , iCur); |
9668 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset); |
9669 | raw_printf(pArg->out, "Autoindex Inserts: %d\n" , iCur); |
9670 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); |
9671 | raw_printf(pArg->out, "Virtual Machine Steps: %d\n" , iCur); |
9672 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset); |
9673 | raw_printf(pArg->out, "Reprepare operations: %d\n" , iCur); |
9674 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); |
9675 | raw_printf(pArg->out, "Number of times run: %d\n" , iCur); |
9676 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset); |
9677 | raw_printf(pArg->out, "Memory used by prepared stmt: %d\n" , iCur); |
9678 | } |
9679 | |
9680 | #ifdef __linux__ |
9681 | displayLinuxIoStats(pArg->out); |
9682 | #endif |
9683 | |
9684 | /* Do not remove this machine readable comment: extra-stats-output-here */ |
9685 | |
9686 | return 0; |
9687 | } |
9688 | |
9689 | /* |
9690 | ** Display scan stats. |
9691 | */ |
9692 | static void display_scanstats(sqlite3 *db, /* Database to query */ |
9693 | ShellState *pArg /* Pointer to ShellState */ |
9694 | ) { |
9695 | #ifndef SQLITE_ENABLE_STMT_SCANSTATUS |
9696 | UNUSED_PARAMETER(db); |
9697 | UNUSED_PARAMETER(pArg); |
9698 | #else |
9699 | int i, k, n, mx; |
9700 | raw_printf(pArg->out, "-------- scanstats --------\n" ); |
9701 | mx = 0; |
9702 | for (k = 0; k <= mx; k++) { |
9703 | double rEstLoop = 1.0; |
9704 | for (i = n = 0; 1; i++) { |
9705 | sqlite3_stmt *p = pArg->pStmt; |
9706 | sqlite3_int64 nLoop, nVisit; |
9707 | double rEst; |
9708 | int iSid; |
9709 | const char *zExplain; |
9710 | if (sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void *)&nLoop)) { |
9711 | break; |
9712 | } |
9713 | sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void *)&iSid); |
9714 | if (iSid > mx) |
9715 | mx = iSid; |
9716 | if (iSid != k) |
9717 | continue; |
9718 | if (n == 0) { |
9719 | rEstLoop = (double)nLoop; |
9720 | if (k > 0) |
9721 | raw_printf(pArg->out, "-------- subquery %d -------\n" , k); |
9722 | } |
9723 | n++; |
9724 | sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void *)&nVisit); |
9725 | sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void *)&rEst); |
9726 | sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void *)&zExplain); |
9727 | utf8_printf(pArg->out, "Loop %2d: %s\n" , n, zExplain); |
9728 | rEstLoop *= rEst; |
9729 | raw_printf(pArg->out, " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n" , nLoop, nVisit, |
9730 | (sqlite3_int64)(rEstLoop + 0.5), rEst); |
9731 | } |
9732 | } |
9733 | raw_printf(pArg->out, "---------------------------\n" ); |
9734 | #endif |
9735 | } |
9736 | |
9737 | /* |
9738 | ** Parameter azArray points to a zero-terminated array of strings. zStr |
9739 | ** points to a single nul-terminated string. Return non-zero if zStr |
9740 | ** is equal, according to strcmp(), to any of the strings in the array. |
9741 | ** Otherwise, return zero. |
9742 | */ |
9743 | static int str_in_array(const char *zStr, const char **azArray) { |
9744 | int i; |
9745 | for (i = 0; azArray[i]; i++) { |
9746 | if (0 == strcmp(zStr, azArray[i])) |
9747 | return 1; |
9748 | } |
9749 | return 0; |
9750 | } |
9751 | |
9752 | /* |
9753 | ** If compiled statement pSql appears to be an EXPLAIN statement, allocate |
9754 | ** and populate the ShellState.aiIndent[] array with the number of |
9755 | ** spaces each opcode should be indented before it is output. |
9756 | ** |
9757 | ** The indenting rules are: |
9758 | ** |
9759 | ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent |
9760 | ** all opcodes that occur between the p2 jump destination and the opcode |
9761 | ** itself by 2 spaces. |
9762 | ** |
9763 | ** * For each "Goto", if the jump destination is earlier in the program |
9764 | ** and ends on one of: |
9765 | ** Yield SeekGt SeekLt RowSetRead Rewind |
9766 | ** or if the P1 parameter is one instead of zero, |
9767 | ** then indent all opcodes between the earlier instruction |
9768 | ** and "Goto" by 2 spaces. |
9769 | */ |
9770 | static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql) { |
9771 | const char *zSql; /* The text of the SQL statement */ |
9772 | const char *z; /* Used to check if this is an EXPLAIN */ |
9773 | int *abYield = 0; /* True if op is an OP_Yield */ |
9774 | int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ |
9775 | int iOp; /* Index of operation in p->aiIndent[] */ |
9776 | |
9777 | const char *azNext[] = {"Next" , "Prev" , "VPrev" , "VNext" , "SorterNext" , "NextIfOpen" , "PrevIfOpen" , 0}; |
9778 | const char *azYield[] = {"Yield" , "SeekLT" , "SeekGT" , "RowSetRead" , "Rewind" , 0}; |
9779 | const char *azGoto[] = {"Goto" , 0}; |
9780 | |
9781 | /* Try to figure out if this is really an EXPLAIN statement. If this |
9782 | ** cannot be verified, return early. */ |
9783 | if (sqlite3_column_count(pSql) != 8) { |
9784 | p->cMode = p->mode; |
9785 | return; |
9786 | } |
9787 | zSql = sqlite3_sql(pSql); |
9788 | if (zSql == 0) |
9789 | return; |
9790 | for (z = zSql; *z == ' ' || *z == '\t' || *z == '\n' || *z == '\f' || *z == '\r'; z++) |
9791 | ; |
9792 | if (sqlite3_strnicmp(z, "explain" , 7)) { |
9793 | p->cMode = p->mode; |
9794 | return; |
9795 | } |
9796 | |
9797 | for (iOp = 0; SQLITE_ROW == sqlite3_step(pSql); iOp++) { |
9798 | int i; |
9799 | int iAddr = sqlite3_column_int(pSql, 0); |
9800 | const char *zOp = (const char *)sqlite3_column_text(pSql, 1); |
9801 | |
9802 | /* Set p2 to the P2 field of the current opcode. Then, assuming that |
9803 | ** p2 is an instruction address, set variable p2op to the index of that |
9804 | ** instruction in the aiIndent[] array. p2 and p2op may be different if |
9805 | ** the current instruction is part of a sub-program generated by an |
9806 | ** SQL trigger or foreign key. */ |
9807 | int p2 = sqlite3_column_int(pSql, 3); |
9808 | int p2op = (p2 + (iOp - iAddr)); |
9809 | |
9810 | /* Grow the p->aiIndent array as required */ |
9811 | if (iOp >= nAlloc) { |
9812 | if (iOp == 0) { |
9813 | /* Do further verfication that this is explain output. Abort if |
9814 | ** it is not */ |
9815 | static const char *explainCols[] = {"addr" , "opcode" , "p1" , "p2" , "p3" , "p4" , "p5" , "comment" }; |
9816 | int jj; |
9817 | for (jj = 0; jj < ArraySize(explainCols); jj++) { |
9818 | if (strcmp(sqlite3_column_name(pSql, jj), explainCols[jj]) != 0) { |
9819 | p->cMode = p->mode; |
9820 | sqlite3_reset(pSql); |
9821 | return; |
9822 | } |
9823 | } |
9824 | } |
9825 | nAlloc += 100; |
9826 | p->aiIndent = (int *)sqlite3_realloc64(p->aiIndent, nAlloc * sizeof(int)); |
9827 | abYield = (int *)sqlite3_realloc64(abYield, nAlloc * sizeof(int)); |
9828 | } |
9829 | abYield[iOp] = str_in_array(zOp, azYield); |
9830 | p->aiIndent[iOp] = 0; |
9831 | p->nIndent = iOp + 1; |
9832 | |
9833 | if (str_in_array(zOp, azNext)) { |
9834 | for (i = p2op; i < iOp; i++) |
9835 | p->aiIndent[i] += 2; |
9836 | } |
9837 | if (str_in_array(zOp, azGoto) && p2op < p->nIndent && (abYield[p2op] || sqlite3_column_int(pSql, 2))) { |
9838 | for (i = p2op; i < iOp; i++) |
9839 | p->aiIndent[i] += 2; |
9840 | } |
9841 | } |
9842 | |
9843 | p->iIndent = 0; |
9844 | sqlite3_free(abYield); |
9845 | sqlite3_reset(pSql); |
9846 | } |
9847 | |
9848 | /* |
9849 | ** Free the array allocated by explain_data_prepare(). |
9850 | */ |
9851 | static void explain_data_delete(ShellState *p) { |
9852 | sqlite3_free(p->aiIndent); |
9853 | p->aiIndent = 0; |
9854 | p->nIndent = 0; |
9855 | p->iIndent = 0; |
9856 | } |
9857 | |
9858 | /* |
9859 | ** Disable and restore .wheretrace and .selecttrace settings. |
9860 | */ |
9861 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) |
9862 | extern int sqlite3SelectTrace; |
9863 | static int savedSelectTrace; |
9864 | #endif |
9865 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) |
9866 | extern int sqlite3WhereTrace; |
9867 | static int savedWhereTrace; |
9868 | #endif |
9869 | static void disable_debug_trace_modes(void) { |
9870 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) |
9871 | savedSelectTrace = sqlite3SelectTrace; |
9872 | sqlite3SelectTrace = 0; |
9873 | #endif |
9874 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) |
9875 | savedWhereTrace = sqlite3WhereTrace; |
9876 | sqlite3WhereTrace = 0; |
9877 | #endif |
9878 | } |
9879 | static void restore_debug_trace_modes(void) { |
9880 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) |
9881 | sqlite3SelectTrace = savedSelectTrace; |
9882 | #endif |
9883 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) |
9884 | sqlite3WhereTrace = savedWhereTrace; |
9885 | #endif |
9886 | } |
9887 | |
9888 | /* |
9889 | ** Run a prepared statement |
9890 | */ |
9891 | static void exec_prepared_stmt(ShellState *pArg, /* Pointer to ShellState */ |
9892 | sqlite3_stmt *pStmt /* Statment to run */ |
9893 | ) { |
9894 | int rc; |
9895 | |
9896 | /* perform the first step. this will tell us if we |
9897 | ** have a result set or not and how wide it is. |
9898 | */ |
9899 | rc = sqlite3_step(pStmt); |
9900 | /* if we have a result set... */ |
9901 | if (SQLITE_ROW == rc) { |
9902 | /* allocate space for col name ptr, value ptr, and type */ |
9903 | int nCol = sqlite3_column_count(pStmt); |
9904 | void *pData = sqlite3_malloc64(3 * nCol * sizeof(const char *) + 1); |
9905 | if (!pData) { |
9906 | rc = SQLITE_NOMEM; |
9907 | } else { |
9908 | char **azCols = (char **)pData; /* Names of result columns */ |
9909 | char **azVals = &azCols[nCol]; /* Results */ |
9910 | int *aiTypes = (int *)&azVals[nCol]; /* Result types */ |
9911 | int i, x; |
9912 | assert(sizeof(int) <= sizeof(char *)); |
9913 | /* save off ptrs to column names */ |
9914 | for (i = 0; i < nCol; i++) { |
9915 | azCols[i] = (char *)sqlite3_column_name(pStmt, i); |
9916 | } |
9917 | do { |
9918 | /* extract the data and data types */ |
9919 | for (i = 0; i < nCol; i++) { |
9920 | aiTypes[i] = x = sqlite3_column_type(pStmt, i); |
9921 | if (x == SQLITE_BLOB && pArg && pArg->cMode == MODE_Insert) { |
9922 | azVals[i] = "" ; |
9923 | } else { |
9924 | azVals[i] = (char *)sqlite3_column_text(pStmt, i); |
9925 | } |
9926 | if (!azVals[i] && (aiTypes[i] != SQLITE_NULL)) { |
9927 | rc = SQLITE_NOMEM; |
9928 | break; /* from for */ |
9929 | } |
9930 | } /* end for */ |
9931 | |
9932 | /* if data and types extracted successfully... */ |
9933 | if (SQLITE_ROW == rc) { |
9934 | /* call the supplied callback with the result row data */ |
9935 | if (shell_callback(pArg, nCol, azVals, azCols, aiTypes)) { |
9936 | rc = SQLITE_ABORT; |
9937 | } else { |
9938 | rc = sqlite3_step(pStmt); |
9939 | } |
9940 | } |
9941 | } while (SQLITE_ROW == rc); |
9942 | sqlite3_free(pData); |
9943 | } |
9944 | } |
9945 | } |
9946 | |
9947 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
9948 | /* |
9949 | ** This function is called to process SQL if the previous shell command |
9950 | ** was ".expert". It passes the SQL in the second argument directly to |
9951 | ** the sqlite3expert object. |
9952 | ** |
9953 | ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error |
9954 | ** code. In this case, (*pzErr) may be set to point to a buffer containing |
9955 | ** an English language error message. It is the responsibility of the |
9956 | ** caller to eventually free this buffer using sqlite3_free(). |
9957 | */ |
9958 | static int expertHandleSQL(ShellState *pState, const char *zSql, char **pzErr) { |
9959 | assert(pState->expert.pExpert); |
9960 | assert(pzErr == 0 || *pzErr == 0); |
9961 | return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr); |
9962 | } |
9963 | |
9964 | /* |
9965 | ** This function is called either to silently clean up the object |
9966 | ** created by the ".expert" command (if bCancel==1), or to generate a |
9967 | ** report from it and then clean it up (if bCancel==0). |
9968 | ** |
9969 | ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error |
9970 | ** code. In this case, (*pzErr) may be set to point to a buffer containing |
9971 | ** an English language error message. It is the responsibility of the |
9972 | ** caller to eventually free this buffer using sqlite3_free(). |
9973 | */ |
9974 | static int expertFinish(ShellState *pState, int bCancel, char **pzErr) { |
9975 | int rc = SQLITE_OK; |
9976 | sqlite3expert *p = pState->expert.pExpert; |
9977 | assert(p); |
9978 | assert(bCancel || pzErr == 0 || *pzErr == 0); |
9979 | if (bCancel == 0) { |
9980 | FILE *out = pState->out; |
9981 | int bVerbose = pState->expert.bVerbose; |
9982 | |
9983 | rc = sqlite3_expert_analyze(p, pzErr); |
9984 | if (rc == SQLITE_OK) { |
9985 | int nQuery = sqlite3_expert_count(p); |
9986 | int i; |
9987 | |
9988 | if (bVerbose) { |
9989 | const char *zCand = sqlite3_expert_report(p, 0, EXPERT_REPORT_CANDIDATES); |
9990 | raw_printf(out, "-- Candidates -----------------------------\n" ); |
9991 | raw_printf(out, "%s\n" , zCand); |
9992 | } |
9993 | for (i = 0; i < nQuery; i++) { |
9994 | const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL); |
9995 | const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES); |
9996 | const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN); |
9997 | if (zIdx == 0) |
9998 | zIdx = "(no new indexes)\n" ; |
9999 | if (bVerbose) { |
10000 | raw_printf(out, "-- Query %d --------------------------------\n" , i + 1); |
10001 | raw_printf(out, "%s\n\n" , zSql); |
10002 | } |
10003 | raw_printf(out, "%s\n" , zIdx); |
10004 | raw_printf(out, "%s\n" , zEQP); |
10005 | } |
10006 | } |
10007 | } |
10008 | sqlite3_expert_destroy(p); |
10009 | pState->expert.pExpert = 0; |
10010 | return rc; |
10011 | } |
10012 | |
10013 | /* |
10014 | ** Implementation of ".expert" dot command. |
10015 | */ |
10016 | static int expertDotCommand(ShellState *pState, /* Current shell tool state */ |
10017 | char **azArg, /* Array of arguments passed to dot command */ |
10018 | int nArg /* Number of entries in azArg[] */ |
10019 | ) { |
10020 | int rc = SQLITE_OK; |
10021 | char *zErr = 0; |
10022 | int i; |
10023 | int iSample = 0; |
10024 | |
10025 | assert(pState->expert.pExpert == 0); |
10026 | memset(&pState->expert, 0, sizeof(ExpertInfo)); |
10027 | |
10028 | for (i = 1; rc == SQLITE_OK && i < nArg; i++) { |
10029 | char *z = azArg[i]; |
10030 | int n; |
10031 | if (z[0] == '-' && z[1] == '-') |
10032 | z++; |
10033 | n = strlen30(z); |
10034 | if (n >= 2 && 0 == strncmp(z, "-verbose" , n)) { |
10035 | pState->expert.bVerbose = 1; |
10036 | } else if (n >= 2 && 0 == strncmp(z, "-sample" , n)) { |
10037 | if (i == (nArg - 1)) { |
10038 | raw_printf(stderr, "option requires an argument: %s\n" , z); |
10039 | rc = SQLITE_ERROR; |
10040 | } else { |
10041 | iSample = (int)integerValue(azArg[++i]); |
10042 | if (iSample < 0 || iSample > 100) { |
10043 | raw_printf(stderr, "value out of range: %s\n" , azArg[i]); |
10044 | rc = SQLITE_ERROR; |
10045 | } |
10046 | } |
10047 | } else { |
10048 | raw_printf(stderr, "unknown option: %s\n" , z); |
10049 | rc = SQLITE_ERROR; |
10050 | } |
10051 | } |
10052 | |
10053 | if (rc == SQLITE_OK) { |
10054 | pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); |
10055 | if (pState->expert.pExpert == 0) { |
10056 | raw_printf(stderr, "sqlite3_expert_new: %s\n" , zErr); |
10057 | rc = SQLITE_ERROR; |
10058 | } else { |
10059 | sqlite3_expert_config(pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample); |
10060 | } |
10061 | } |
10062 | |
10063 | return rc; |
10064 | } |
10065 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
10066 | |
10067 | /* |
10068 | ** Execute a statement or set of statements. Print |
10069 | ** any result rows/columns depending on the current mode |
10070 | ** set via the supplied callback. |
10071 | ** |
10072 | ** This is very similar to SQLite's built-in sqlite3_exec() |
10073 | ** function except it takes a slightly different callback |
10074 | ** and callback data argument. |
10075 | */ |
10076 | static int shell_exec(ShellState *pArg, /* Pointer to ShellState */ |
10077 | const char *zSql, /* SQL to be evaluated */ |
10078 | char **pzErrMsg /* Error msg written here */ |
10079 | ) { |
10080 | sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ |
10081 | int rc = SQLITE_OK; /* Return Code */ |
10082 | int rc2; |
10083 | const char *zLeftover; /* Tail of unprocessed SQL */ |
10084 | sqlite3 *db = pArg->db; |
10085 | |
10086 | if (pzErrMsg) { |
10087 | *pzErrMsg = NULL; |
10088 | } |
10089 | |
10090 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
10091 | if (pArg->expert.pExpert) { |
10092 | rc = expertHandleSQL(pArg, zSql, pzErrMsg); |
10093 | return expertFinish(pArg, (rc != SQLITE_OK), pzErrMsg); |
10094 | } |
10095 | #endif |
10096 | |
10097 | while (zSql[0] && (SQLITE_OK == rc)) { |
10098 | static const char *zStmtSql; |
10099 | rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); |
10100 | if (SQLITE_OK != rc) { |
10101 | if (pzErrMsg) { |
10102 | *pzErrMsg = save_err_msg(db); |
10103 | } |
10104 | } else { |
10105 | if (!pStmt) { |
10106 | /* this happens for a comment or white-space */ |
10107 | zSql = zLeftover; |
10108 | while (IsSpace(zSql[0])) |
10109 | zSql++; |
10110 | continue; |
10111 | } |
10112 | zStmtSql = sqlite3_sql(pStmt); |
10113 | if (zStmtSql == 0) |
10114 | zStmtSql = "" ; |
10115 | while (IsSpace(zStmtSql[0])) |
10116 | zStmtSql++; |
10117 | |
10118 | /* save off the prepared statment handle and reset row count */ |
10119 | if (pArg) { |
10120 | pArg->pStmt = pStmt; |
10121 | pArg->cnt = 0; |
10122 | } |
10123 | |
10124 | /* echo the sql statement if echo on */ |
10125 | if (pArg && ShellHasFlag(pArg, SHFLG_Echo)) { |
10126 | utf8_printf(pArg->out, "%s\n" , zStmtSql ? zStmtSql : zSql); |
10127 | } |
10128 | |
10129 | /* Show the EXPLAIN QUERY PLAN if .eqp is on */ |
10130 | if (pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%" , zStmtSql, 0) != 0) { |
10131 | sqlite3_stmt *pExplain; |
10132 | char *zEQP; |
10133 | int triggerEQP = 0; |
10134 | disable_debug_trace_modes(); |
10135 | sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP); |
10136 | if (pArg->autoEQP >= AUTOEQP_trigger) { |
10137 | sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0); |
10138 | } |
10139 | zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s" , zStmtSql); |
10140 | rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); |
10141 | if (rc == SQLITE_OK) { |
10142 | while (sqlite3_step(pExplain) == SQLITE_ROW) { |
10143 | raw_printf(pArg->out, "--EQP-- %d," , sqlite3_column_int(pExplain, 0)); |
10144 | raw_printf(pArg->out, "%d," , sqlite3_column_int(pExplain, 1)); |
10145 | raw_printf(pArg->out, "%d," , sqlite3_column_int(pExplain, 2)); |
10146 | utf8_printf(pArg->out, "%s\n" , sqlite3_column_text(pExplain, 3)); |
10147 | } |
10148 | } |
10149 | sqlite3_finalize(pExplain); |
10150 | sqlite3_free(zEQP); |
10151 | if (pArg->autoEQP >= AUTOEQP_full) { |
10152 | /* Also do an EXPLAIN for ".eqp full" mode */ |
10153 | zEQP = sqlite3_mprintf("EXPLAIN %s" , zStmtSql); |
10154 | rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); |
10155 | if (rc == SQLITE_OK) { |
10156 | pArg->cMode = MODE_Explain; |
10157 | explain_data_prepare(pArg, pExplain); |
10158 | exec_prepared_stmt(pArg, pExplain); |
10159 | explain_data_delete(pArg); |
10160 | } |
10161 | sqlite3_finalize(pExplain); |
10162 | sqlite3_free(zEQP); |
10163 | } |
10164 | if (pArg->autoEQP >= AUTOEQP_trigger && triggerEQP == 0) { |
10165 | sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); |
10166 | /* Reprepare pStmt before reactiving trace modes */ |
10167 | sqlite3_finalize(pStmt); |
10168 | sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
10169 | } |
10170 | restore_debug_trace_modes(); |
10171 | } |
10172 | |
10173 | if (pArg) { |
10174 | pArg->cMode = pArg->mode; |
10175 | if (pArg->autoExplain && sqlite3_column_count(pStmt) == 8 && |
10176 | sqlite3_strlike("EXPLAIN%" , zStmtSql, 0) == 0) { |
10177 | pArg->cMode = MODE_Explain; |
10178 | } |
10179 | |
10180 | /* If the shell is currently in ".explain" mode, gather the extra |
10181 | ** data required to add indents to the output.*/ |
10182 | if (pArg->cMode == MODE_Explain) { |
10183 | explain_data_prepare(pArg, pStmt); |
10184 | } |
10185 | } |
10186 | |
10187 | exec_prepared_stmt(pArg, pStmt); |
10188 | explain_data_delete(pArg); |
10189 | |
10190 | /* print usage stats if stats on */ |
10191 | if (pArg && pArg->statsOn) { |
10192 | display_stats(db, pArg, 0); |
10193 | } |
10194 | |
10195 | /* print loop-counters if required */ |
10196 | if (pArg && pArg->scanstatsOn) { |
10197 | display_scanstats(db, pArg); |
10198 | } |
10199 | |
10200 | /* Finalize the statement just executed. If this fails, save a |
10201 | ** copy of the error message. Otherwise, set zSql to point to the |
10202 | ** next statement to execute. */ |
10203 | rc2 = sqlite3_finalize(pStmt); |
10204 | if (rc != SQLITE_NOMEM) |
10205 | rc = rc2; |
10206 | if (rc == SQLITE_OK) { |
10207 | zSql = zLeftover; |
10208 | while (IsSpace(zSql[0])) |
10209 | zSql++; |
10210 | } else if (pzErrMsg) { |
10211 | *pzErrMsg = save_err_msg(db); |
10212 | } |
10213 | |
10214 | /* clear saved stmt handle */ |
10215 | if (pArg) { |
10216 | pArg->pStmt = NULL; |
10217 | } |
10218 | } |
10219 | } /* end while */ |
10220 | |
10221 | return rc; |
10222 | } |
10223 | |
10224 | /* |
10225 | ** Release memory previously allocated by tableColumnList(). |
10226 | */ |
10227 | static void freeColumnList(char **azCol) { |
10228 | int i; |
10229 | for (i = 1; azCol[i]; i++) { |
10230 | sqlite3_free(azCol[i]); |
10231 | } |
10232 | /* azCol[0] is a static string */ |
10233 | sqlite3_free(azCol); |
10234 | } |
10235 | |
10236 | /* |
10237 | ** Return a list of pointers to strings which are the names of all |
10238 | ** columns in table zTab. The memory to hold the names is dynamically |
10239 | ** allocated and must be released by the caller using a subsequent call |
10240 | ** to freeColumnList(). |
10241 | ** |
10242 | ** The azCol[0] entry is usually NULL. However, if zTab contains a rowid |
10243 | ** value that needs to be preserved, then azCol[0] is filled in with the |
10244 | ** name of the rowid column. |
10245 | ** |
10246 | ** The first regular column in the table is azCol[1]. The list is terminated |
10247 | ** by an entry with azCol[i]==0. |
10248 | */ |
10249 | static char **tableColumnList(ShellState *p, const char *zTab) { |
10250 | char **azCol = 0; |
10251 | sqlite3_stmt *pStmt; |
10252 | char *zSql; |
10253 | int nCol = 0; |
10254 | int nAlloc = 0; |
10255 | int nPK = 0; /* Number of PRIMARY KEY columns seen */ |
10256 | int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ |
10257 | int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); |
10258 | int rc; |
10259 | |
10260 | zSql = sqlite3_mprintf("PRAGMA table_info=%Q" , zTab); |
10261 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
10262 | sqlite3_free(zSql); |
10263 | if (rc) |
10264 | return 0; |
10265 | while (sqlite3_step(pStmt) == SQLITE_ROW) { |
10266 | if (nCol >= nAlloc - 2) { |
10267 | nAlloc = nAlloc * 2 + nCol + 10; |
10268 | azCol = sqlite3_realloc(azCol, nAlloc * sizeof(azCol[0])); |
10269 | if (azCol == 0) { |
10270 | raw_printf(stderr, "Error: out of memory\n" ); |
10271 | exit(1); |
10272 | } |
10273 | } |
10274 | azCol[++nCol] = sqlite3_mprintf("%s" , sqlite3_column_text(pStmt, 1)); |
10275 | if (sqlite3_column_int(pStmt, 5)) { |
10276 | nPK++; |
10277 | if (nPK == 1 && sqlite3_stricmp((const char *)sqlite3_column_text(pStmt, 2), "INTEGER" ) == 0) { |
10278 | isIPK = 1; |
10279 | } else { |
10280 | isIPK = 0; |
10281 | } |
10282 | } |
10283 | } |
10284 | sqlite3_finalize(pStmt); |
10285 | if (azCol == 0) |
10286 | return 0; |
10287 | azCol[0] = 0; |
10288 | azCol[nCol + 1] = 0; |
10289 | |
10290 | /* The decision of whether or not a rowid really needs to be preserved |
10291 | ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table |
10292 | ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve |
10293 | ** rowids on tables where the rowid is inaccessible because there are other |
10294 | ** columns in the table named "rowid", "_rowid_", and "oid". |
10295 | */ |
10296 | if (preserveRowid && isIPK) { |
10297 | /* If a single PRIMARY KEY column with type INTEGER was seen, then it |
10298 | ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID |
10299 | ** table or a INTEGER PRIMARY KEY DESC column, neither of which are |
10300 | ** ROWID aliases. To distinguish these cases, check to see if |
10301 | ** there is a "pk" entry in "PRAGMA index_list". There will be |
10302 | ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. |
10303 | */ |
10304 | zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" |
10305 | " WHERE origin='pk'" , |
10306 | zTab); |
10307 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
10308 | sqlite3_free(zSql); |
10309 | if (rc) { |
10310 | freeColumnList(azCol); |
10311 | return 0; |
10312 | } |
10313 | rc = sqlite3_step(pStmt); |
10314 | sqlite3_finalize(pStmt); |
10315 | preserveRowid = rc == SQLITE_ROW; |
10316 | } |
10317 | if (preserveRowid) { |
10318 | /* Only preserve the rowid if we can find a name to use for the |
10319 | ** rowid */ |
10320 | static char *azRowid[] = {"rowid" , "_rowid_" , "oid" }; |
10321 | int i, j; |
10322 | for (j = 0; j < 3; j++) { |
10323 | for (i = 1; i <= nCol; i++) { |
10324 | if (sqlite3_stricmp(azRowid[j], azCol[i]) == 0) |
10325 | break; |
10326 | } |
10327 | if (i > nCol) { |
10328 | /* At this point, we know that azRowid[j] is not the name of any |
10329 | ** ordinary column in the table. Verify that azRowid[j] is a valid |
10330 | ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID |
10331 | ** tables will fail this last check */ |
10332 | rc = sqlite3_table_column_metadata(p->db, 0, zTab, azRowid[j], 0, 0, 0, 0, 0); |
10333 | if (rc == SQLITE_OK) |
10334 | azCol[0] = azRowid[j]; |
10335 | break; |
10336 | } |
10337 | } |
10338 | } |
10339 | return azCol; |
10340 | } |
10341 | |
10342 | /* |
10343 | ** Toggle the reverse_unordered_selects setting. |
10344 | */ |
10345 | static void toggleSelectOrder(sqlite3 *db) { |
10346 | sqlite3_stmt *pStmt = 0; |
10347 | int iSetting = 0; |
10348 | char zStmt[100]; |
10349 | sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects" , -1, &pStmt, 0); |
10350 | if (sqlite3_step(pStmt) == SQLITE_ROW) { |
10351 | iSetting = sqlite3_column_int(pStmt, 0); |
10352 | } |
10353 | sqlite3_finalize(pStmt); |
10354 | sqlite3_snprintf(sizeof(zStmt), zStmt, "PRAGMA reverse_unordered_selects(%d)" , !iSetting); |
10355 | sqlite3_exec(db, zStmt, 0, 0, 0); |
10356 | } |
10357 | |
10358 | /* |
10359 | ** This is a different callback routine used for dumping the database. |
10360 | ** Each row received by this callback consists of a table name, |
10361 | ** the table type ("index" or "table") and SQL to create the table. |
10362 | ** This routine should print text sufficient to recreate the table. |
10363 | */ |
10364 | static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed) { |
10365 | int rc; |
10366 | const char *zTable; |
10367 | const char *zType; |
10368 | const char *zSql; |
10369 | ShellState *p = (ShellState *)pArg; |
10370 | |
10371 | UNUSED_PARAMETER(azNotUsed); |
10372 | if (nArg != 3 || azArg == 0) |
10373 | return 0; |
10374 | zTable = azArg[0]; |
10375 | zType = azArg[1]; |
10376 | zSql = azArg[2]; |
10377 | |
10378 | if (strcmp(zTable, "sqlite_sequence" ) == 0) { |
10379 | raw_printf(p->out, "DELETE FROM sqlite_sequence;\n" ); |
10380 | } else if (sqlite3_strglob("sqlite_stat?" , zTable) == 0) { |
10381 | raw_printf(p->out, "ANALYZE sqlite_master;\n" ); |
10382 | } else if (strncmp(zTable, "sqlite_" , 7) == 0) { |
10383 | return 0; |
10384 | } else if (strncmp(zSql, "CREATE VIRTUAL TABLE" , 20) == 0) { |
10385 | char *zIns; |
10386 | if (!p->writableSchema) { |
10387 | raw_printf(p->out, "PRAGMA writable_schema=ON;\n" ); |
10388 | p->writableSchema = 1; |
10389 | } |
10390 | zIns = sqlite3_mprintf("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" |
10391 | "VALUES('table','%q','%q',0,'%q');" , |
10392 | zTable, zTable, zSql); |
10393 | utf8_printf(p->out, "%s\n" , zIns); |
10394 | sqlite3_free(zIns); |
10395 | return 0; |
10396 | } else { |
10397 | printSchemaLine(p->out, zSql, ";\n" ); |
10398 | } |
10399 | |
10400 | if (strcmp(zType, "table" ) == 0) { |
10401 | ShellText sSelect; |
10402 | ShellText sTable; |
10403 | char **azCol; |
10404 | int i; |
10405 | char *savedDestTable; |
10406 | int savedMode; |
10407 | |
10408 | azCol = tableColumnList(p, zTable); |
10409 | if (azCol == 0) { |
10410 | p->nErr++; |
10411 | return 0; |
10412 | } |
10413 | |
10414 | /* Always quote the table name, even if it appears to be pure ascii, |
10415 | ** in case it is a keyword. Ex: INSERT INTO "table" ... */ |
10416 | initText(&sTable); |
10417 | appendText(&sTable, zTable, quoteChar(zTable)); |
10418 | /* If preserving the rowid, add a column list after the table name. |
10419 | ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" |
10420 | ** instead of the usual "INSERT INTO tab VALUES(...)". |
10421 | */ |
10422 | if (azCol[0]) { |
10423 | appendText(&sTable, "(" , 0); |
10424 | appendText(&sTable, azCol[0], 0); |
10425 | for (i = 1; azCol[i]; i++) { |
10426 | appendText(&sTable, "," , 0); |
10427 | appendText(&sTable, azCol[i], quoteChar(azCol[i])); |
10428 | } |
10429 | appendText(&sTable, ")" , 0); |
10430 | } |
10431 | |
10432 | /* Build an appropriate SELECT statement */ |
10433 | initText(&sSelect); |
10434 | appendText(&sSelect, "SELECT " , 0); |
10435 | if (azCol[0]) { |
10436 | appendText(&sSelect, azCol[0], 0); |
10437 | appendText(&sSelect, "," , 0); |
10438 | } |
10439 | for (i = 1; azCol[i]; i++) { |
10440 | appendText(&sSelect, azCol[i], quoteChar(azCol[i])); |
10441 | if (azCol[i + 1]) { |
10442 | appendText(&sSelect, "," , 0); |
10443 | } |
10444 | } |
10445 | freeColumnList(azCol); |
10446 | appendText(&sSelect, " FROM " , 0); |
10447 | appendText(&sSelect, zTable, quoteChar(zTable)); |
10448 | |
10449 | savedDestTable = p->zDestTable; |
10450 | savedMode = p->mode; |
10451 | p->zDestTable = sTable.z; |
10452 | p->mode = p->cMode = MODE_Insert; |
10453 | rc = shell_exec(p, sSelect.z, 0); |
10454 | if ((rc & 0xff) == SQLITE_CORRUPT) { |
10455 | raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n" ); |
10456 | toggleSelectOrder(p->db); |
10457 | shell_exec(p, sSelect.z, 0); |
10458 | toggleSelectOrder(p->db); |
10459 | } |
10460 | p->zDestTable = savedDestTable; |
10461 | p->mode = savedMode; |
10462 | freeText(&sTable); |
10463 | freeText(&sSelect); |
10464 | if (rc) |
10465 | p->nErr++; |
10466 | } |
10467 | return 0; |
10468 | } |
10469 | |
10470 | /* |
10471 | ** Run zQuery. Use dump_callback() as the callback routine so that |
10472 | ** the contents of the query are output as SQL statements. |
10473 | ** |
10474 | ** If we get a SQLITE_CORRUPT error, rerun the query after appending |
10475 | ** "ORDER BY rowid DESC" to the end. |
10476 | */ |
10477 | static int run_schema_dump_query(ShellState *p, const char *zQuery) { |
10478 | int rc; |
10479 | char *zErr = 0; |
10480 | rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); |
10481 | if (rc == SQLITE_CORRUPT) { |
10482 | char *zQ2; |
10483 | int len = strlen30(zQuery); |
10484 | raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n" ); |
10485 | if (zErr) { |
10486 | utf8_printf(p->out, "/****** %s ******/\n" , zErr); |
10487 | sqlite3_free(zErr); |
10488 | zErr = 0; |
10489 | } |
10490 | zQ2 = malloc(len + 100); |
10491 | if (zQ2 == 0) |
10492 | return rc; |
10493 | sqlite3_snprintf(len + 100, zQ2, "%s ORDER BY rowid DESC" , zQuery); |
10494 | rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); |
10495 | if (rc) { |
10496 | utf8_printf(p->out, "/****** ERROR: %s ******/\n" , zErr); |
10497 | } else { |
10498 | rc = SQLITE_CORRUPT; |
10499 | } |
10500 | sqlite3_free(zErr); |
10501 | free(zQ2); |
10502 | } |
10503 | return rc; |
10504 | } |
10505 | |
10506 | /* |
10507 | ** Text of a help message |
10508 | */ |
10509 | static char zHelp[] = |
10510 | #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) |
10511 | ".archive ... Manage SQL archives: \".archive --help\" for details\n" |
10512 | #endif |
10513 | #ifndef SQLITE_OMIT_AUTHORIZATION |
10514 | ".auth ON|OFF Show authorizer callbacks\n" |
10515 | #endif |
10516 | ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" |
10517 | ".bail on|off Stop after hitting an error. Default OFF\n" |
10518 | ".binary on|off Turn binary output on or off. Default OFF\n" |
10519 | ".cd DIRECTORY Change the working directory to DIRECTORY\n" |
10520 | ".changes on|off Show number of rows changed by SQL\n" |
10521 | ".check GLOB Fail if output since .testcase does not match\n" |
10522 | ".clone NEWDB Clone data into NEWDB from the existing database\n" |
10523 | ".databases List names and files of attached databases\n" |
10524 | ".dbinfo ?DB? Show status information about the database\n" |
10525 | ".dump ?TABLE? ... Dump the database in an SQL text format\n" |
10526 | " If TABLE specified, only dump tables matching\n" |
10527 | " LIKE pattern TABLE.\n" |
10528 | ".echo on|off Turn command echo on or off\n" |
10529 | ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" |
10530 | ".excel Display the output of next command in a spreadsheet\n" |
10531 | ".exit Exit this program\n" |
10532 | ".expert EXPERIMENTAL. Suggest indexes for specified queries\n" |
10533 | /* Because explain mode comes on automatically now, the ".explain" mode |
10534 | ** is removed from the help screen. It is still supported for legacy, however */ |
10535 | /*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/ |
10536 | ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" |
10537 | ".headers on|off Turn display of headers on or off\n" |
10538 | ".help Show this message\n" |
10539 | ".import FILE TABLE Import data from FILE into TABLE\n" |
10540 | #ifndef SQLITE_OMIT_TEST_CONTROL |
10541 | ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n" |
10542 | #endif |
10543 | ".indexes ?TABLE? Show names of all indexes\n" |
10544 | " If TABLE specified, only show indexes for tables\n" |
10545 | " matching LIKE pattern TABLE.\n" |
10546 | #ifdef SQLITE_ENABLE_IOTRACE |
10547 | ".iotrace FILE Enable I/O diagnostic logging to FILE\n" |
10548 | #endif |
10549 | ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" |
10550 | ".lint OPTIONS Report potential schema issues. Options:\n" |
10551 | " fkey-indexes Find missing foreign key indexes\n" |
10552 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
10553 | ".load FILE ?ENTRY? Load an extension library\n" |
10554 | #endif |
10555 | ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" |
10556 | ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" |
10557 | " ascii Columns/rows delimited by 0x1F and 0x1E\n" |
10558 | " csv Comma-separated values\n" |
10559 | " column Left-aligned columns. (See .width)\n" |
10560 | " html HTML <table> code\n" |
10561 | " insert SQL insert statements for TABLE\n" |
10562 | " line One value per line\n" |
10563 | " list Values delimited by \"|\"\n" |
10564 | " quote Escape answers as for SQL\n" |
10565 | " tabs Tab-separated values\n" |
10566 | " tcl TCL list elements\n" |
10567 | ".nullvalue STRING Use STRING in place of NULL values\n" |
10568 | ".once (-e|-x|FILE) Output for the next SQL command only to FILE\n" |
10569 | " or invoke system text editor (-e) or spreadsheet (-x)\n" |
10570 | " on the output.\n" |
10571 | ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n" |
10572 | " The --new option starts with an empty file\n" |
10573 | " Other options: --readonly --append --zip\n" |
10574 | ".output ?FILE? Send output to FILE or stdout\n" |
10575 | ".print STRING... Print literal STRING\n" |
10576 | ".prompt MAIN CONTINUE Replace the standard prompts\n" |
10577 | ".quit Exit this program\n" |
10578 | ".read FILENAME Execute SQL in FILENAME\n" |
10579 | ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" |
10580 | ".save FILE Write in-memory database into FILE\n" |
10581 | ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" |
10582 | ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" |
10583 | " Add --indent for pretty-printing\n" |
10584 | ".selftest ?--init? Run tests defined in the SELFTEST table\n" |
10585 | ".separator COL ?ROW? Change the column separator and optionally the row\n" |
10586 | " separator for both the output mode and .import\n" |
10587 | #if defined(SQLITE_ENABLE_SESSION) |
10588 | ".session CMD ... Create or control sessions\n" |
10589 | #endif |
10590 | ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n" |
10591 | #ifndef SQLITE_NOHAVE_SYSTEM |
10592 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
10593 | #endif |
10594 | ".show Show the current values for various settings\n" |
10595 | ".stats ?on|off? Show stats or turn stats on or off\n" |
10596 | #ifndef SQLITE_NOHAVE_SYSTEM |
10597 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
10598 | #endif |
10599 | ".tables ?TABLE? List names of tables\n" |
10600 | " If TABLE specified, only list tables matching\n" |
10601 | " LIKE pattern TABLE.\n" |
10602 | ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n" |
10603 | ".timeout MS Try opening locked tables for MS milliseconds\n" |
10604 | ".timer on|off Turn SQL timer on or off\n" |
10605 | ".trace FILE|off Output each SQL statement as it is run\n" |
10606 | ".vfsinfo ?AUX? Information about the top-level VFS\n" |
10607 | ".vfslist List all available VFSes\n" |
10608 | ".vfsname ?AUX? Print the name of the VFS stack\n" |
10609 | ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" |
10610 | " Negative values right-justify\n" ; |
10611 | |
10612 | #if defined(SQLITE_ENABLE_SESSION) |
10613 | /* |
10614 | ** Print help information for the ".sessions" command |
10615 | */ |
10616 | void session_help(ShellState *p) { |
10617 | raw_printf(p->out, ".session ?NAME? SUBCOMMAND ?ARGS...?\n" |
10618 | "If ?NAME? is omitted, the first defined session is used.\n" |
10619 | "Subcommands:\n" |
10620 | " attach TABLE Attach TABLE\n" |
10621 | " changeset FILE Write a changeset into FILE\n" |
10622 | " close Close one session\n" |
10623 | " enable ?BOOLEAN? Set or query the enable bit\n" |
10624 | " filter GLOB... Reject tables matching GLOBs\n" |
10625 | " indirect ?BOOLEAN? Mark or query the indirect status\n" |
10626 | " isempty Query whether the session is empty\n" |
10627 | " list List currently open session names\n" |
10628 | " open DB NAME Open a new session on DB\n" |
10629 | " patchset FILE Write a patchset into FILE\n" ); |
10630 | } |
10631 | #endif |
10632 | |
10633 | /* Forward reference */ |
10634 | static int process_input(ShellState *p, FILE *in); |
10635 | |
10636 | /* |
10637 | ** Read the content of file zName into memory obtained from sqlite3_malloc64() |
10638 | ** and return a pointer to the buffer. The caller is responsible for freeing |
10639 | ** the memory. |
10640 | ** |
10641 | ** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes |
10642 | ** read. |
10643 | ** |
10644 | ** For convenience, a nul-terminator byte is always appended to the data read |
10645 | ** from the file before the buffer is returned. This byte is not included in |
10646 | ** the final value of (*pnByte), if applicable. |
10647 | ** |
10648 | ** NULL is returned if any error is encountered. The final value of *pnByte |
10649 | ** is undefined in this case. |
10650 | */ |
10651 | static char *readFile(const char *zName, int *pnByte) { |
10652 | FILE *in = fopen(zName, "rb" ); |
10653 | long nIn; |
10654 | size_t nRead; |
10655 | char *pBuf; |
10656 | if (in == 0) |
10657 | return 0; |
10658 | fseek(in, 0, SEEK_END); |
10659 | nIn = ftell(in); |
10660 | rewind(in); |
10661 | pBuf = sqlite3_malloc64(nIn + 1); |
10662 | if (pBuf == 0) |
10663 | return 0; |
10664 | nRead = fread(pBuf, nIn, 1, in); |
10665 | fclose(in); |
10666 | if (nRead != 1) { |
10667 | sqlite3_free(pBuf); |
10668 | return 0; |
10669 | } |
10670 | pBuf[nIn] = 0; |
10671 | if (pnByte) |
10672 | *pnByte = nIn; |
10673 | return pBuf; |
10674 | } |
10675 | |
10676 | #if defined(SQLITE_ENABLE_SESSION) |
10677 | /* |
10678 | ** Close a single OpenSession object and release all of its associated |
10679 | ** resources. |
10680 | */ |
10681 | static void session_close(OpenSession *pSession) { |
10682 | int i; |
10683 | sqlite3session_delete(pSession->p); |
10684 | sqlite3_free(pSession->zName); |
10685 | for (i = 0; i < pSession->nFilter; i++) { |
10686 | sqlite3_free(pSession->azFilter[i]); |
10687 | } |
10688 | sqlite3_free(pSession->azFilter); |
10689 | memset(pSession, 0, sizeof(OpenSession)); |
10690 | } |
10691 | #endif |
10692 | |
10693 | /* |
10694 | ** Close all OpenSession objects and release all associated resources. |
10695 | */ |
10696 | #if defined(SQLITE_ENABLE_SESSION) |
10697 | static void session_close_all(ShellState *p) { |
10698 | int i; |
10699 | for (i = 0; i < p->nSession; i++) { |
10700 | session_close(&p->aSession[i]); |
10701 | } |
10702 | p->nSession = 0; |
10703 | } |
10704 | #else |
10705 | #define session_close_all(X) |
10706 | #endif |
10707 | |
10708 | /* |
10709 | ** Implementation of the xFilter function for an open session. Omit |
10710 | ** any tables named by ".session filter" but let all other table through. |
10711 | */ |
10712 | #if defined(SQLITE_ENABLE_SESSION) |
10713 | static int session_filter(void *pCtx, const char *zTab) { |
10714 | OpenSession *pSession = (OpenSession *)pCtx; |
10715 | int i; |
10716 | for (i = 0; i < pSession->nFilter; i++) { |
10717 | if (sqlite3_strglob(pSession->azFilter[i], zTab) == 0) |
10718 | return 0; |
10719 | } |
10720 | return 1; |
10721 | } |
10722 | #endif |
10723 | |
10724 | /* |
10725 | ** Try to deduce the type of file for zName based on its content. Return |
10726 | ** one of the SHELL_OPEN_* constants. |
10727 | ** |
10728 | ** If the file does not exist or is empty but its name looks like a ZIP |
10729 | ** archive and the dfltZip flag is true, then assume it is a ZIP archive. |
10730 | ** Otherwise, assume an ordinary database regardless of the filename if |
10731 | ** the type cannot be determined from content. |
10732 | */ |
10733 | static int deduceDatabaseType(const char *zName, int dfltZip) { |
10734 | FILE *f = fopen(zName, "rb" ); |
10735 | size_t n; |
10736 | int rc = SHELL_OPEN_UNSPEC; |
10737 | char zBuf[100]; |
10738 | if (f == 0) { |
10739 | if (dfltZip && sqlite3_strlike("%.zip" , zName, 0) == 0) |
10740 | return SHELL_OPEN_ZIPFILE; |
10741 | return SHELL_OPEN_NORMAL; |
10742 | } |
10743 | fseek(f, -25, SEEK_END); |
10744 | n = fread(zBuf, 25, 1, f); |
10745 | if (n == 1 && memcmp(zBuf, "Start-Of-SQLite3-" , 17) == 0) { |
10746 | rc = SHELL_OPEN_APPENDVFS; |
10747 | } else { |
10748 | fseek(f, -22, SEEK_END); |
10749 | n = fread(zBuf, 22, 1, f); |
10750 | if (n == 1 && zBuf[0] == 0x50 && zBuf[1] == 0x4b && zBuf[2] == 0x05 && zBuf[3] == 0x06) { |
10751 | rc = SHELL_OPEN_ZIPFILE; |
10752 | } else if (n == 0 && dfltZip && sqlite3_strlike("%.zip" , zName, 0) == 0) { |
10753 | return SHELL_OPEN_ZIPFILE; |
10754 | } |
10755 | } |
10756 | fclose(f); |
10757 | return rc; |
10758 | } |
10759 | |
10760 | /* |
10761 | ** Make sure the database is open. If it is not, then open it. If |
10762 | ** the database fails to open, print an error message and exit. |
10763 | */ |
10764 | static void open_db(ShellState *p, int keepAlive) { |
10765 | if (p->db == 0) { |
10766 | sqlite3_initialize(); |
10767 | if (p->openMode == SHELL_OPEN_UNSPEC && access(p->zDbFilename, 0) == 0) { |
10768 | p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 0); |
10769 | } |
10770 | switch (p->openMode) { |
10771 | case SHELL_OPEN_APPENDVFS: { |
10772 | sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "apndvfs" ); |
10773 | break; |
10774 | } |
10775 | case SHELL_OPEN_ZIPFILE: { |
10776 | sqlite3_open(":memory:" , &p->db); |
10777 | break; |
10778 | } |
10779 | case SHELL_OPEN_READONLY: { |
10780 | sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0); |
10781 | break; |
10782 | } |
10783 | case SHELL_OPEN_UNSPEC: |
10784 | case SHELL_OPEN_NORMAL: { |
10785 | sqlite3_open(p->zDbFilename, &p->db); |
10786 | break; |
10787 | } |
10788 | } |
10789 | globalDb = p->db; |
10790 | if (p->db == 0 || SQLITE_OK != sqlite3_errcode(p->db)) { |
10791 | utf8_printf(stderr, "Error: unable to open database \"%s\": %s\n" , p->zDbFilename, sqlite3_errmsg(p->db)); |
10792 | if (keepAlive) |
10793 | return; |
10794 | exit(1); |
10795 | } |
10796 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
10797 | sqlite3_enable_load_extension(p->db, 1); |
10798 | #endif |
10799 | sqlite3_fileio_init(p->db, 0, 0); |
10800 | sqlite3_shathree_init(p->db, 0, 0); |
10801 | sqlite3_completion_init(p->db, 0, 0); |
10802 | #ifdef SQLITE_HAVE_ZLIB |
10803 | sqlite3_zipfile_init(p->db, 0, 0); |
10804 | sqlite3_sqlar_init(p->db, 0, 0); |
10805 | #endif |
10806 | sqlite3_create_function(p->db, "shell_add_schema" , 3, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); |
10807 | sqlite3_create_function(p->db, "shell_module_schema" , 1, SQLITE_UTF8, 0, shellModuleSchema, 0, 0); |
10808 | sqlite3_create_function(p->db, "shell_putsnl" , 1, SQLITE_UTF8, p, shellPutsFunc, 0, 0); |
10809 | #ifndef SQLITE_NOHAVE_SYSTEM |
10810 | sqlite3_create_function(p->db, "edit" , 1, SQLITE_UTF8, 0, editFunc, 0, 0); |
10811 | sqlite3_create_function(p->db, "edit" , 2, SQLITE_UTF8, 0, editFunc, 0, 0); |
10812 | #endif |
10813 | if (p->openMode == SHELL_OPEN_ZIPFILE) { |
10814 | char *zSql = sqlite3_mprintf("CREATE VIRTUAL TABLE zip USING zipfile(%Q);" , p->zDbFilename); |
10815 | sqlite3_exec(p->db, zSql, 0, 0, 0); |
10816 | sqlite3_free(zSql); |
10817 | } |
10818 | } |
10819 | } |
10820 | |
10821 | #if HAVE_READLINE || HAVE_EDITLINE |
10822 | /* |
10823 | ** Readline completion callbacks |
10824 | */ |
10825 | static char *readline_completion_generator(const char *text, int state) { |
10826 | static sqlite3_stmt *pStmt = 0; |
10827 | char *zRet; |
10828 | if (state == 0) { |
10829 | char *zSql; |
10830 | sqlite3_finalize(pStmt); |
10831 | zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" |
10832 | " FROM completion(%Q) ORDER BY 1" , |
10833 | text); |
10834 | sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); |
10835 | sqlite3_free(zSql); |
10836 | } |
10837 | if (sqlite3_step(pStmt) == SQLITE_ROW) { |
10838 | zRet = strdup((const char *)sqlite3_column_text(pStmt, 0)); |
10839 | } else { |
10840 | sqlite3_finalize(pStmt); |
10841 | pStmt = 0; |
10842 | zRet = 0; |
10843 | } |
10844 | return zRet; |
10845 | } |
10846 | static char **readline_completion(const char *zText, int iStart, int iEnd) { |
10847 | rl_attempted_completion_over = 1; |
10848 | return rl_completion_matches(zText, readline_completion_generator); |
10849 | } |
10850 | |
10851 | #elif HAVE_LINENOISE |
10852 | /* |
10853 | ** Linenoise completion callback |
10854 | */ |
10855 | static void linenoise_completion(const char *zLine, linenoiseCompletions *lc) { |
10856 | int nLine = strlen30(zLine); |
10857 | int i, iStart; |
10858 | sqlite3_stmt *pStmt = 0; |
10859 | char *zSql; |
10860 | char zBuf[1000]; |
10861 | |
10862 | if (nLine > sizeof(zBuf) - 30) |
10863 | return; |
10864 | if (zLine[0] == '.') |
10865 | return; |
10866 | for (i = nLine - 1; i >= 0 && (isalnum(zLine[i]) || zLine[i] == '_'); i--) { |
10867 | } |
10868 | if (i == nLine - 1) |
10869 | return; |
10870 | iStart = i + 1; |
10871 | memcpy(zBuf, zLine, iStart); |
10872 | zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" |
10873 | " FROM completion(%Q,%Q) ORDER BY 1" , |
10874 | &zLine[iStart], zLine); |
10875 | sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); |
10876 | sqlite3_free(zSql); |
10877 | sqlite3_exec(globalDb, "PRAGMA page_count" , 0, 0, 0); /* Load the schema */ |
10878 | while (sqlite3_step(pStmt) == SQLITE_ROW) { |
10879 | const char *zCompletion = (const char *)sqlite3_column_text(pStmt, 0); |
10880 | int nCompletion = sqlite3_column_bytes(pStmt, 0); |
10881 | if (iStart + nCompletion < sizeof(zBuf) - 1) { |
10882 | memcpy(zBuf + iStart, zCompletion, nCompletion + 1); |
10883 | linenoiseAddCompletion(lc, zBuf); |
10884 | } |
10885 | } |
10886 | sqlite3_finalize(pStmt); |
10887 | } |
10888 | #endif |
10889 | |
10890 | /* |
10891 | ** Do C-language style dequoting. |
10892 | ** |
10893 | ** \a -> alarm |
10894 | ** \b -> backspace |
10895 | ** \t -> tab |
10896 | ** \n -> newline |
10897 | ** \v -> vertical tab |
10898 | ** \f -> form feed |
10899 | ** \r -> carriage return |
10900 | ** \s -> space |
10901 | ** \" -> " |
10902 | ** \' -> ' |
10903 | ** \\ -> backslash |
10904 | ** \NNN -> ascii character NNN in octal |
10905 | */ |
10906 | static void resolve_backslashes(char *z) { |
10907 | int i, j; |
10908 | char c; |
10909 | while (*z && *z != '\\') |
10910 | z++; |
10911 | for (i = j = 0; (c = z[i]) != 0; i++, j++) { |
10912 | if (c == '\\' && z[i + 1] != 0) { |
10913 | c = z[++i]; |
10914 | if (c == 'a') { |
10915 | c = '\a'; |
10916 | } else if (c == 'b') { |
10917 | c = '\b'; |
10918 | } else if (c == 't') { |
10919 | c = '\t'; |
10920 | } else if (c == 'n') { |
10921 | c = '\n'; |
10922 | } else if (c == 'v') { |
10923 | c = '\v'; |
10924 | } else if (c == 'f') { |
10925 | c = '\f'; |
10926 | } else if (c == 'r') { |
10927 | c = '\r'; |
10928 | } else if (c == '"') { |
10929 | c = '"'; |
10930 | } else if (c == '\'') { |
10931 | c = '\''; |
10932 | } else if (c == '\\') { |
10933 | c = '\\'; |
10934 | } else if (c >= '0' && c <= '7') { |
10935 | c -= '0'; |
10936 | if (z[i + 1] >= '0' && z[i + 1] <= '7') { |
10937 | i++; |
10938 | c = (c << 3) + z[i] - '0'; |
10939 | if (z[i + 1] >= '0' && z[i + 1] <= '7') { |
10940 | i++; |
10941 | c = (c << 3) + z[i] - '0'; |
10942 | } |
10943 | } |
10944 | } |
10945 | } |
10946 | z[j] = c; |
10947 | } |
10948 | if (j < i) |
10949 | z[j] = 0; |
10950 | } |
10951 | |
10952 | /* |
10953 | ** Interpret zArg as either an integer or a boolean value. Return 1 or 0 |
10954 | ** for TRUE and FALSE. Return the integer value if appropriate. |
10955 | */ |
10956 | static int booleanValue(const char *zArg) { |
10957 | int i; |
10958 | if (zArg[0] == '0' && zArg[1] == 'x') { |
10959 | for (i = 2; hexDigitValue(zArg[i]) >= 0; i++) { |
10960 | } |
10961 | } else { |
10962 | for (i = 0; zArg[i] >= '0' && zArg[i] <= '9'; i++) { |
10963 | } |
10964 | } |
10965 | if (i > 0 && zArg[i] == 0) |
10966 | return (int)(integerValue(zArg) & 0xffffffff); |
10967 | if (sqlite3_stricmp(zArg, "on" ) == 0 || sqlite3_stricmp(zArg, "yes" ) == 0) { |
10968 | return 1; |
10969 | } |
10970 | if (sqlite3_stricmp(zArg, "off" ) == 0 || sqlite3_stricmp(zArg, "no" ) == 0) { |
10971 | return 0; |
10972 | } |
10973 | utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n" , zArg); |
10974 | return 0; |
10975 | } |
10976 | |
10977 | /* |
10978 | ** Set or clear a shell flag according to a boolean value. |
10979 | */ |
10980 | static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg) { |
10981 | if (booleanValue(zArg)) { |
10982 | ShellSetFlag(p, mFlag); |
10983 | } else { |
10984 | ShellClearFlag(p, mFlag); |
10985 | } |
10986 | } |
10987 | |
10988 | /* |
10989 | ** Close an output file, assuming it is not stderr or stdout |
10990 | */ |
10991 | static void output_file_close(FILE *f) { |
10992 | if (f && f != stdout && f != stderr) |
10993 | fclose(f); |
10994 | } |
10995 | |
10996 | /* |
10997 | ** Try to open an output file. The names "stdout" and "stderr" are |
10998 | ** recognized and do the right thing. NULL is returned if the output |
10999 | ** filename is "off". |
11000 | */ |
11001 | static FILE *output_file_open(const char *zFile, int bTextMode) { |
11002 | FILE *f; |
11003 | if (strcmp(zFile, "stdout" ) == 0) { |
11004 | f = stdout; |
11005 | } else if (strcmp(zFile, "stderr" ) == 0) { |
11006 | f = stderr; |
11007 | } else if (strcmp(zFile, "off" ) == 0) { |
11008 | f = 0; |
11009 | } else { |
11010 | f = fopen(zFile, bTextMode ? "w" : "wb" ); |
11011 | if (f == 0) { |
11012 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , zFile); |
11013 | } |
11014 | } |
11015 | return f; |
11016 | } |
11017 | |
11018 | #if !defined(SQLITE_UNTESTABLE) |
11019 | #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) |
11020 | /* |
11021 | ** A routine for handling output from sqlite3_trace(). |
11022 | */ |
11023 | static int sql_trace_callback(unsigned mType, void *pArg, void *pP, void *pX) { |
11024 | FILE *f = (FILE *)pArg; |
11025 | UNUSED_PARAMETER(mType); |
11026 | UNUSED_PARAMETER(pP); |
11027 | if (f) { |
11028 | const char *z = (const char *)pX; |
11029 | int i = strlen30(z); |
11030 | while (i > 0 && z[i - 1] == ';') { |
11031 | i--; |
11032 | } |
11033 | utf8_printf(f, "%.*s;\n" , i, z); |
11034 | } |
11035 | return 0; |
11036 | } |
11037 | #endif |
11038 | #endif |
11039 | |
11040 | /* |
11041 | ** A no-op routine that runs with the ".breakpoint" doc-command. This is |
11042 | ** a useful spot to set a debugger breakpoint. |
11043 | */ |
11044 | static void test_breakpoint(void) { |
11045 | static int nCall = 0; |
11046 | nCall++; |
11047 | } |
11048 | |
11049 | /* |
11050 | ** An object used to read a CSV and other files for import. |
11051 | */ |
11052 | typedef struct ImportCtx ImportCtx; |
11053 | struct ImportCtx { |
11054 | const char *zFile; /* Name of the input file */ |
11055 | FILE *in; /* Read the CSV text from this input stream */ |
11056 | char *z; /* Accumulated text for a field */ |
11057 | int n; /* Number of bytes in z */ |
11058 | int nAlloc; /* Space allocated for z[] */ |
11059 | int nLine; /* Current line number */ |
11060 | int bNotFirst; /* True if one or more bytes already read */ |
11061 | int cTerm; /* Character that terminated the most recent field */ |
11062 | int cColSep; /* The column separator character. (Usually ",") */ |
11063 | int cRowSep; /* The row separator character. (Usually "\n") */ |
11064 | }; |
11065 | |
11066 | /* Append a single byte to z[] */ |
11067 | static void import_append_char(ImportCtx *p, int c) { |
11068 | if (p->n + 1 >= p->nAlloc) { |
11069 | p->nAlloc += p->nAlloc + 100; |
11070 | p->z = sqlite3_realloc64(p->z, p->nAlloc); |
11071 | if (p->z == 0) { |
11072 | raw_printf(stderr, "out of memory\n" ); |
11073 | exit(1); |
11074 | } |
11075 | } |
11076 | p->z[p->n++] = (char)c; |
11077 | } |
11078 | |
11079 | /* Read a single field of CSV text. Compatible with rfc4180 and extended |
11080 | ** with the option of having a separator other than ",". |
11081 | ** |
11082 | ** + Input comes from p->in. |
11083 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
11084 | ** from sqlite3_malloc64(). |
11085 | ** + Use p->cSep as the column separator. The default is ",". |
11086 | ** + Use p->rSep as the row separator. The default is "\n". |
11087 | ** + Keep track of the line number in p->nLine. |
11088 | ** + Store the character that terminates the field in p->cTerm. Store |
11089 | ** EOF on end-of-file. |
11090 | ** + Report syntax errors on stderr |
11091 | */ |
11092 | static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p) { |
11093 | int c; |
11094 | int cSep = p->cColSep; |
11095 | int rSep = p->cRowSep; |
11096 | p->n = 0; |
11097 | c = fgetc(p->in); |
11098 | if (c == EOF || seenInterrupt) { |
11099 | p->cTerm = EOF; |
11100 | return 0; |
11101 | } |
11102 | if (c == '"') { |
11103 | int pc, ppc; |
11104 | int startLine = p->nLine; |
11105 | int cQuote = c; |
11106 | pc = ppc = 0; |
11107 | while (1) { |
11108 | c = fgetc(p->in); |
11109 | if (c == rSep) |
11110 | p->nLine++; |
11111 | if (c == cQuote) { |
11112 | if (pc == cQuote) { |
11113 | pc = 0; |
11114 | continue; |
11115 | } |
11116 | } |
11117 | if ((c == cSep && pc == cQuote) || (c == rSep && pc == cQuote) || |
11118 | (c == rSep && pc == '\r' && ppc == cQuote) || (c == EOF && pc == cQuote)) { |
11119 | do { |
11120 | p->n--; |
11121 | } while (p->z[p->n] != cQuote); |
11122 | p->cTerm = c; |
11123 | break; |
11124 | } |
11125 | if (pc == cQuote && c != '\r') { |
11126 | utf8_printf(stderr, "%s:%d: unescaped %c character\n" , p->zFile, p->nLine, cQuote); |
11127 | } |
11128 | if (c == EOF) { |
11129 | utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n" , p->zFile, startLine, cQuote); |
11130 | p->cTerm = c; |
11131 | break; |
11132 | } |
11133 | import_append_char(p, c); |
11134 | ppc = pc; |
11135 | pc = c; |
11136 | } |
11137 | } else { |
11138 | /* If this is the first field being parsed and it begins with the |
11139 | ** UTF-8 BOM (0xEF BB BF) then skip the BOM */ |
11140 | if ((c & 0xff) == 0xef && p->bNotFirst == 0) { |
11141 | import_append_char(p, c); |
11142 | c = fgetc(p->in); |
11143 | if ((c & 0xff) == 0xbb) { |
11144 | import_append_char(p, c); |
11145 | c = fgetc(p->in); |
11146 | if ((c & 0xff) == 0xbf) { |
11147 | p->bNotFirst = 1; |
11148 | p->n = 0; |
11149 | return csv_read_one_field(p); |
11150 | } |
11151 | } |
11152 | } |
11153 | while (c != EOF && c != cSep && c != rSep) { |
11154 | import_append_char(p, c); |
11155 | c = fgetc(p->in); |
11156 | } |
11157 | if (c == rSep) { |
11158 | p->nLine++; |
11159 | if (p->n > 0 && p->z[p->n - 1] == '\r') |
11160 | p->n--; |
11161 | } |
11162 | p->cTerm = c; |
11163 | } |
11164 | if (p->z) |
11165 | p->z[p->n] = 0; |
11166 | p->bNotFirst = 1; |
11167 | return p->z; |
11168 | } |
11169 | |
11170 | /* Read a single field of ASCII delimited text. |
11171 | ** |
11172 | ** + Input comes from p->in. |
11173 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
11174 | ** from sqlite3_malloc64(). |
11175 | ** + Use p->cSep as the column separator. The default is "\x1F". |
11176 | ** + Use p->rSep as the row separator. The default is "\x1E". |
11177 | ** + Keep track of the row number in p->nLine. |
11178 | ** + Store the character that terminates the field in p->cTerm. Store |
11179 | ** EOF on end-of-file. |
11180 | ** + Report syntax errors on stderr |
11181 | */ |
11182 | static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p) { |
11183 | int c; |
11184 | int cSep = p->cColSep; |
11185 | int rSep = p->cRowSep; |
11186 | p->n = 0; |
11187 | c = fgetc(p->in); |
11188 | if (c == EOF || seenInterrupt) { |
11189 | p->cTerm = EOF; |
11190 | return 0; |
11191 | } |
11192 | while (c != EOF && c != cSep && c != rSep) { |
11193 | import_append_char(p, c); |
11194 | c = fgetc(p->in); |
11195 | } |
11196 | if (c == rSep) { |
11197 | p->nLine++; |
11198 | } |
11199 | p->cTerm = c; |
11200 | if (p->z) |
11201 | p->z[p->n] = 0; |
11202 | return p->z; |
11203 | } |
11204 | |
11205 | /* |
11206 | ** Try to transfer data for table zTable. If an error is seen while |
11207 | ** moving forward, try to go backwards. The backwards movement won't |
11208 | ** work for WITHOUT ROWID tables. |
11209 | */ |
11210 | static void tryToCloneData(ShellState *p, sqlite3 *newDb, const char *zTable) { |
11211 | sqlite3_stmt *pQuery = 0; |
11212 | sqlite3_stmt *pInsert = 0; |
11213 | char *zQuery = 0; |
11214 | char *zInsert = 0; |
11215 | int rc; |
11216 | int i, j, n; |
11217 | int nTable = strlen30(zTable); |
11218 | int k = 0; |
11219 | int cnt = 0; |
11220 | const int spinRate = 10000; |
11221 | |
11222 | zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"" , zTable); |
11223 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
11224 | if (rc) { |
11225 | utf8_printf(stderr, "Error %d: %s on [%s]\n" , sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); |
11226 | goto end_data_xfer; |
11227 | } |
11228 | n = sqlite3_column_count(pQuery); |
11229 | zInsert = sqlite3_malloc64(200 + nTable + n * 3); |
11230 | if (zInsert == 0) { |
11231 | raw_printf(stderr, "out of memory\n" ); |
11232 | goto end_data_xfer; |
11233 | } |
11234 | sqlite3_snprintf(200 + nTable, zInsert, "INSERT OR IGNORE INTO \"%s\" VALUES(?" , zTable); |
11235 | i = strlen30(zInsert); |
11236 | for (j = 1; j < n; j++) { |
11237 | memcpy(zInsert + i, ",?" , 2); |
11238 | i += 2; |
11239 | } |
11240 | memcpy(zInsert + i, ");" , 3); |
11241 | rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); |
11242 | if (rc) { |
11243 | utf8_printf(stderr, "Error %d: %s on [%s]\n" , sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zQuery); |
11244 | goto end_data_xfer; |
11245 | } |
11246 | for (k = 0; k < 2; k++) { |
11247 | while ((rc = sqlite3_step(pQuery)) == SQLITE_ROW) { |
11248 | for (i = 0; i < n; i++) { |
11249 | switch (sqlite3_column_type(pQuery, i)) { |
11250 | case SQLITE_NULL: { |
11251 | sqlite3_bind_null(pInsert, i + 1); |
11252 | break; |
11253 | } |
11254 | case SQLITE_INTEGER: { |
11255 | sqlite3_bind_int64(pInsert, i + 1, sqlite3_column_int64(pQuery, i)); |
11256 | break; |
11257 | } |
11258 | case SQLITE_FLOAT: { |
11259 | sqlite3_bind_double(pInsert, i + 1, sqlite3_column_double(pQuery, i)); |
11260 | break; |
11261 | } |
11262 | case SQLITE_TEXT: { |
11263 | sqlite3_bind_text(pInsert, i + 1, (const char *)sqlite3_column_text(pQuery, i), -1, SQLITE_STATIC); |
11264 | break; |
11265 | } |
11266 | case SQLITE_BLOB: { |
11267 | sqlite3_bind_blob(pInsert, i + 1, sqlite3_column_blob(pQuery, i), sqlite3_column_bytes(pQuery, i), |
11268 | SQLITE_STATIC); |
11269 | break; |
11270 | } |
11271 | } |
11272 | } /* End for */ |
11273 | rc = sqlite3_step(pInsert); |
11274 | if (rc != SQLITE_OK && rc != SQLITE_ROW && rc != SQLITE_DONE) { |
11275 | utf8_printf(stderr, "Error %d: %s\n" , sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb)); |
11276 | } |
11277 | sqlite3_reset(pInsert); |
11278 | cnt++; |
11279 | if ((cnt % spinRate) == 0) { |
11280 | printf("%c\b" , "|/-\\" [(cnt / spinRate) % 4]); |
11281 | fflush(stdout); |
11282 | } |
11283 | } /* End while */ |
11284 | if (rc == SQLITE_DONE) |
11285 | break; |
11286 | sqlite3_finalize(pQuery); |
11287 | sqlite3_free(zQuery); |
11288 | zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;" , zTable); |
11289 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
11290 | if (rc) { |
11291 | utf8_printf(stderr, "Warning: cannot step \"%s\" backwards" , zTable); |
11292 | break; |
11293 | } |
11294 | } /* End for(k=0...) */ |
11295 | |
11296 | end_data_xfer: |
11297 | sqlite3_finalize(pQuery); |
11298 | sqlite3_finalize(pInsert); |
11299 | sqlite3_free(zQuery); |
11300 | sqlite3_free(zInsert); |
11301 | } |
11302 | |
11303 | /* |
11304 | ** Try to transfer all rows of the schema that match zWhere. For |
11305 | ** each row, invoke xForEach() on the object defined by that row. |
11306 | ** If an error is encountered while moving forward through the |
11307 | ** sqlite_master table, try again moving backwards. |
11308 | */ |
11309 | static void tryToCloneSchema(ShellState *p, sqlite3 *newDb, const char *zWhere, |
11310 | void (*xForEach)(ShellState *, sqlite3 *, const char *)) { |
11311 | sqlite3_stmt *pQuery = 0; |
11312 | char *zQuery = 0; |
11313 | int rc; |
11314 | const unsigned char *zName; |
11315 | const unsigned char *zSql; |
11316 | char *zErrMsg = 0; |
11317 | |
11318 | zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" |
11319 | " WHERE %s" , |
11320 | zWhere); |
11321 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
11322 | if (rc) { |
11323 | utf8_printf(stderr, "Error: (%d) %s on [%s]\n" , sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); |
11324 | goto end_schema_xfer; |
11325 | } |
11326 | while ((rc = sqlite3_step(pQuery)) == SQLITE_ROW) { |
11327 | zName = sqlite3_column_text(pQuery, 0); |
11328 | zSql = sqlite3_column_text(pQuery, 1); |
11329 | printf("%s... " , zName); |
11330 | fflush(stdout); |
11331 | sqlite3_exec(newDb, (const char *)zSql, 0, 0, &zErrMsg); |
11332 | if (zErrMsg) { |
11333 | utf8_printf(stderr, "Error: %s\nSQL: [%s]\n" , zErrMsg, zSql); |
11334 | sqlite3_free(zErrMsg); |
11335 | zErrMsg = 0; |
11336 | } |
11337 | if (xForEach) { |
11338 | xForEach(p, newDb, (const char *)zName); |
11339 | } |
11340 | printf("done\n" ); |
11341 | } |
11342 | if (rc != SQLITE_DONE) { |
11343 | sqlite3_finalize(pQuery); |
11344 | sqlite3_free(zQuery); |
11345 | zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" |
11346 | " WHERE %s ORDER BY rowid DESC" , |
11347 | zWhere); |
11348 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
11349 | if (rc) { |
11350 | utf8_printf(stderr, "Error: (%d) %s on [%s]\n" , sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), |
11351 | zQuery); |
11352 | goto end_schema_xfer; |
11353 | } |
11354 | while ((rc = sqlite3_step(pQuery)) == SQLITE_ROW) { |
11355 | zName = sqlite3_column_text(pQuery, 0); |
11356 | zSql = sqlite3_column_text(pQuery, 1); |
11357 | printf("%s... " , zName); |
11358 | fflush(stdout); |
11359 | sqlite3_exec(newDb, (const char *)zSql, 0, 0, &zErrMsg); |
11360 | if (zErrMsg) { |
11361 | utf8_printf(stderr, "Error: %s\nSQL: [%s]\n" , zErrMsg, zSql); |
11362 | sqlite3_free(zErrMsg); |
11363 | zErrMsg = 0; |
11364 | } |
11365 | if (xForEach) { |
11366 | xForEach(p, newDb, (const char *)zName); |
11367 | } |
11368 | printf("done\n" ); |
11369 | } |
11370 | } |
11371 | end_schema_xfer: |
11372 | sqlite3_finalize(pQuery); |
11373 | sqlite3_free(zQuery); |
11374 | } |
11375 | |
11376 | /* |
11377 | ** Open a new database file named "zNewDb". Try to recover as much information |
11378 | ** as possible out of the main database (which might be corrupt) and write it |
11379 | ** into zNewDb. |
11380 | */ |
11381 | static void tryToClone(ShellState *p, const char *zNewDb) { |
11382 | int rc; |
11383 | sqlite3 *newDb = 0; |
11384 | if (access(zNewDb, 0) == 0) { |
11385 | utf8_printf(stderr, "File \"%s\" already exists.\n" , zNewDb); |
11386 | return; |
11387 | } |
11388 | rc = sqlite3_open(zNewDb, &newDb); |
11389 | if (rc) { |
11390 | utf8_printf(stderr, "Cannot create output database: %s\n" , sqlite3_errmsg(newDb)); |
11391 | } else { |
11392 | sqlite3_exec(p->db, "PRAGMA writable_schema=ON;" , 0, 0, 0); |
11393 | sqlite3_exec(newDb, "BEGIN EXCLUSIVE;" , 0, 0, 0); |
11394 | tryToCloneSchema(p, newDb, "type='table'" , tryToCloneData); |
11395 | tryToCloneSchema(p, newDb, "type!='table'" , 0); |
11396 | sqlite3_exec(newDb, "COMMIT;" , 0, 0, 0); |
11397 | sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;" , 0, 0, 0); |
11398 | } |
11399 | sqlite3_close(newDb); |
11400 | } |
11401 | |
11402 | /* |
11403 | ** Change the output file back to stdout. |
11404 | ** |
11405 | ** If the p->doXdgOpen flag is set, that means the output was being |
11406 | ** redirected to a temporary file named by p->zTempFile. In that case, |
11407 | ** launch start/open/xdg-open on that temporary file. |
11408 | */ |
11409 | static void output_reset(ShellState *p) { |
11410 | if (p->outfile[0] == '|') { |
11411 | #ifndef SQLITE_OMIT_POPEN |
11412 | pclose(p->out); |
11413 | #endif |
11414 | } else { |
11415 | output_file_close(p->out); |
11416 | #ifndef SQLITE_NOHAVE_SYSTEM |
11417 | if (p->doXdgOpen) { |
11418 | const char *zXdgOpenCmd = |
11419 | #if defined(_WIN32) |
11420 | "start" ; |
11421 | #elif defined(__APPLE__) |
11422 | "open" ; |
11423 | #else |
11424 | "xdg-open" ; |
11425 | #endif |
11426 | char *zCmd; |
11427 | zCmd = sqlite3_mprintf("%s %s" , zXdgOpenCmd, p->zTempFile); |
11428 | if (system(zCmd)) { |
11429 | utf8_printf(stderr, "Failed: [%s]\n" , zCmd); |
11430 | } |
11431 | sqlite3_free(zCmd); |
11432 | outputModePop(p); |
11433 | p->doXdgOpen = 0; |
11434 | } |
11435 | #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ |
11436 | } |
11437 | p->outfile[0] = 0; |
11438 | p->out = stdout; |
11439 | } |
11440 | |
11441 | /* |
11442 | ** Run an SQL command and return the single integer result. |
11443 | */ |
11444 | static int db_int(ShellState *p, const char *zSql) { |
11445 | sqlite3_stmt *pStmt; |
11446 | int res = 0; |
11447 | sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
11448 | if (pStmt && sqlite3_step(pStmt) == SQLITE_ROW) { |
11449 | res = sqlite3_column_int(pStmt, 0); |
11450 | } |
11451 | sqlite3_finalize(pStmt); |
11452 | return res; |
11453 | } |
11454 | |
11455 | /* |
11456 | ** Convert a 2-byte or 4-byte big-endian integer into a native integer |
11457 | */ |
11458 | static unsigned int get2byteInt(unsigned char *a) { |
11459 | return (a[0] << 8) + a[1]; |
11460 | } |
11461 | static unsigned int get4byteInt(unsigned char *a) { |
11462 | return (a[0] << 24) + (a[1] << 16) + (a[2] << 8) + a[3]; |
11463 | } |
11464 | |
11465 | /* |
11466 | ** Implementation of the ".info" command. |
11467 | ** |
11468 | ** Return 1 on error, 2 to exit, and 0 otherwise. |
11469 | */ |
11470 | static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg) { |
11471 | static const struct { |
11472 | const char *zName; |
11473 | int ofst; |
11474 | } aField[] = { |
11475 | {"file change counter:" , 24}, {"database page count:" , 28}, {"freelist page count:" , 36}, |
11476 | {"schema cookie:" , 40}, {"schema format:" , 44}, {"default cache size:" , 48}, |
11477 | {"autovacuum top root:" , 52}, {"incremental vacuum:" , 64}, {"text encoding:" , 56}, |
11478 | {"user version:" , 60}, {"application id:" , 68}, {"software version:" , 96}, |
11479 | }; |
11480 | static const struct { |
11481 | const char *zName; |
11482 | const char *zSql; |
11483 | } aQuery[] = { |
11484 | {"number of tables:" , "SELECT count(*) FROM %s WHERE type='table'" }, |
11485 | {"number of indexes:" , "SELECT count(*) FROM %s WHERE type='index'" }, |
11486 | {"number of triggers:" , "SELECT count(*) FROM %s WHERE type='trigger'" }, |
11487 | {"number of views:" , "SELECT count(*) FROM %s WHERE type='view'" }, |
11488 | {"schema size:" , "SELECT total(length(sql)) FROM %s" }, |
11489 | }; |
11490 | int i; |
11491 | char *zSchemaTab; |
11492 | char *zDb = nArg >= 2 ? azArg[1] : "main" ; |
11493 | sqlite3_stmt *pStmt = 0; |
11494 | unsigned char aHdr[100]; |
11495 | open_db(p, 0); |
11496 | if (p->db == 0) |
11497 | return 1; |
11498 | sqlite3_prepare_v2(p->db, "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1" , -1, &pStmt, 0); |
11499 | sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC); |
11500 | if (sqlite3_step(pStmt) == SQLITE_ROW && sqlite3_column_bytes(pStmt, 0) > 100) { |
11501 | memcpy(aHdr, sqlite3_column_blob(pStmt, 0), 100); |
11502 | sqlite3_finalize(pStmt); |
11503 | } else { |
11504 | raw_printf(stderr, "unable to read database header\n" ); |
11505 | sqlite3_finalize(pStmt); |
11506 | return 1; |
11507 | } |
11508 | i = get2byteInt(aHdr + 16); |
11509 | if (i == 1) |
11510 | i = 65536; |
11511 | utf8_printf(p->out, "%-20s %d\n" , "database page size:" , i); |
11512 | utf8_printf(p->out, "%-20s %d\n" , "write format:" , aHdr[18]); |
11513 | utf8_printf(p->out, "%-20s %d\n" , "read format:" , aHdr[19]); |
11514 | utf8_printf(p->out, "%-20s %d\n" , "reserved bytes:" , aHdr[20]); |
11515 | for (i = 0; i < ArraySize(aField); i++) { |
11516 | int ofst = aField[i].ofst; |
11517 | unsigned int val = get4byteInt(aHdr + ofst); |
11518 | utf8_printf(p->out, "%-20s %u" , aField[i].zName, val); |
11519 | switch (ofst) { |
11520 | case 56: { |
11521 | if (val == 1) |
11522 | raw_printf(p->out, " (utf8)" ); |
11523 | if (val == 2) |
11524 | raw_printf(p->out, " (utf16le)" ); |
11525 | if (val == 3) |
11526 | raw_printf(p->out, " (utf16be)" ); |
11527 | } |
11528 | } |
11529 | raw_printf(p->out, "\n" ); |
11530 | } |
11531 | if (zDb == 0) { |
11532 | zSchemaTab = sqlite3_mprintf("main.sqlite_master" ); |
11533 | } else if (strcmp(zDb, "temp" ) == 0) { |
11534 | zSchemaTab = sqlite3_mprintf("%s" , "sqlite_temp_master" ); |
11535 | } else { |
11536 | zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master" , zDb); |
11537 | } |
11538 | for (i = 0; i < ArraySize(aQuery); i++) { |
11539 | char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); |
11540 | int val = db_int(p, zSql); |
11541 | sqlite3_free(zSql); |
11542 | utf8_printf(p->out, "%-20s %d\n" , aQuery[i].zName, val); |
11543 | } |
11544 | sqlite3_free(zSchemaTab); |
11545 | return 0; |
11546 | } |
11547 | |
11548 | /* |
11549 | ** Print the current sqlite3_errmsg() value to stderr and return 1. |
11550 | */ |
11551 | static int shellDatabaseError(sqlite3 *db) { |
11552 | const char *zErr = sqlite3_errmsg(db); |
11553 | utf8_printf(stderr, "Error: %s\n" , zErr); |
11554 | return 1; |
11555 | } |
11556 | |
11557 | /* |
11558 | ** Print an out-of-memory message to stderr and return 1. |
11559 | */ |
11560 | static int shellNomemError(void) { |
11561 | raw_printf(stderr, "Error: out of memory\n" ); |
11562 | return 1; |
11563 | } |
11564 | |
11565 | /* |
11566 | ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE |
11567 | ** if they match and FALSE (0) if they do not match. |
11568 | ** |
11569 | ** Globbing rules: |
11570 | ** |
11571 | ** '*' Matches any sequence of zero or more characters. |
11572 | ** |
11573 | ** '?' Matches exactly one character. |
11574 | ** |
11575 | ** [...] Matches one character from the enclosed list of |
11576 | ** characters. |
11577 | ** |
11578 | ** [^...] Matches one character not in the enclosed list. |
11579 | ** |
11580 | ** '#' Matches any sequence of one or more digits with an |
11581 | ** optional + or - sign in front |
11582 | ** |
11583 | ** ' ' Any span of whitespace matches any other span of |
11584 | ** whitespace. |
11585 | ** |
11586 | ** Extra whitespace at the end of z[] is ignored. |
11587 | */ |
11588 | static int testcase_glob(const char *zGlob, const char *z) { |
11589 | int c, c2; |
11590 | int invert; |
11591 | int seen; |
11592 | |
11593 | while ((c = (*(zGlob++))) != 0) { |
11594 | if (IsSpace(c)) { |
11595 | if (!IsSpace(*z)) |
11596 | return 0; |
11597 | while (IsSpace(*zGlob)) |
11598 | zGlob++; |
11599 | while (IsSpace(*z)) |
11600 | z++; |
11601 | } else if (c == '*') { |
11602 | while ((c = (*(zGlob++))) == '*' || c == '?') { |
11603 | if (c == '?' && (*(z++)) == 0) |
11604 | return 0; |
11605 | } |
11606 | if (c == 0) { |
11607 | return 1; |
11608 | } else if (c == '[') { |
11609 | while (*z && testcase_glob(zGlob - 1, z) == 0) { |
11610 | z++; |
11611 | } |
11612 | return (*z) != 0; |
11613 | } |
11614 | while ((c2 = (*(z++))) != 0) { |
11615 | while (c2 != c) { |
11616 | c2 = *(z++); |
11617 | if (c2 == 0) |
11618 | return 0; |
11619 | } |
11620 | if (testcase_glob(zGlob, z)) |
11621 | return 1; |
11622 | } |
11623 | return 0; |
11624 | } else if (c == '?') { |
11625 | if ((*(z++)) == 0) |
11626 | return 0; |
11627 | } else if (c == '[') { |
11628 | int prior_c = 0; |
11629 | seen = 0; |
11630 | invert = 0; |
11631 | c = *(z++); |
11632 | if (c == 0) |
11633 | return 0; |
11634 | c2 = *(zGlob++); |
11635 | if (c2 == '^') { |
11636 | invert = 1; |
11637 | c2 = *(zGlob++); |
11638 | } |
11639 | if (c2 == ']') { |
11640 | if (c == ']') |
11641 | seen = 1; |
11642 | c2 = *(zGlob++); |
11643 | } |
11644 | while (c2 && c2 != ']') { |
11645 | if (c2 == '-' && zGlob[0] != ']' && zGlob[0] != 0 && prior_c > 0) { |
11646 | c2 = *(zGlob++); |
11647 | if (c >= prior_c && c <= c2) |
11648 | seen = 1; |
11649 | prior_c = 0; |
11650 | } else { |
11651 | if (c == c2) { |
11652 | seen = 1; |
11653 | } |
11654 | prior_c = c2; |
11655 | } |
11656 | c2 = *(zGlob++); |
11657 | } |
11658 | if (c2 == 0 || (seen ^ invert) == 0) |
11659 | return 0; |
11660 | } else if (c == '#') { |
11661 | if ((z[0] == '-' || z[0] == '+') && IsDigit(z[1])) |
11662 | z++; |
11663 | if (!IsDigit(z[0])) |
11664 | return 0; |
11665 | z++; |
11666 | while (IsDigit(z[0])) { |
11667 | z++; |
11668 | } |
11669 | } else { |
11670 | if (c != (*(z++))) |
11671 | return 0; |
11672 | } |
11673 | } |
11674 | while (IsSpace(*z)) { |
11675 | z++; |
11676 | } |
11677 | return *z == 0; |
11678 | } |
11679 | |
11680 | /* |
11681 | ** Compare the string as a command-line option with either one or two |
11682 | ** initial "-" characters. |
11683 | */ |
11684 | static int optionMatch(const char *zStr, const char *zOpt) { |
11685 | if (zStr[0] != '-') |
11686 | return 0; |
11687 | zStr++; |
11688 | if (zStr[0] == '-') |
11689 | zStr++; |
11690 | return strcmp(zStr, zOpt) == 0; |
11691 | } |
11692 | |
11693 | /* |
11694 | ** Delete a file. |
11695 | */ |
11696 | int shellDeleteFile(const char *zFilename) { |
11697 | int rc; |
11698 | #ifdef _WIN32 |
11699 | wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename); |
11700 | rc = _wunlink(z); |
11701 | sqlite3_free(z); |
11702 | #else |
11703 | rc = unlink(zFilename); |
11704 | #endif |
11705 | return rc; |
11706 | } |
11707 | |
11708 | /* |
11709 | ** Try to delete the temporary file (if there is one) and free the |
11710 | ** memory used to hold the name of the temp file. |
11711 | */ |
11712 | static void clearTempFile(ShellState *p) { |
11713 | if (p->zTempFile == 0) |
11714 | return; |
11715 | if (p->doXdgOpen) |
11716 | return; |
11717 | if (shellDeleteFile(p->zTempFile)) |
11718 | return; |
11719 | sqlite3_free(p->zTempFile); |
11720 | p->zTempFile = 0; |
11721 | } |
11722 | |
11723 | /* |
11724 | ** Create a new temp file name with the given suffix. |
11725 | */ |
11726 | static void newTempFile(ShellState *p, const char *zSuffix) { |
11727 | clearTempFile(p); |
11728 | sqlite3_free(p->zTempFile); |
11729 | p->zTempFile = 0; |
11730 | if (p->db) { |
11731 | sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile); |
11732 | } |
11733 | if (p->zTempFile == 0) { |
11734 | sqlite3_uint64 r; |
11735 | sqlite3_randomness(sizeof(r), &r); |
11736 | p->zTempFile = sqlite3_mprintf("temp%llx.%s" , r, zSuffix); |
11737 | } else { |
11738 | p->zTempFile = sqlite3_mprintf("%z.%s" , p->zTempFile, zSuffix); |
11739 | } |
11740 | if (p->zTempFile == 0) { |
11741 | raw_printf(stderr, "out of memory\n" ); |
11742 | exit(1); |
11743 | } |
11744 | } |
11745 | |
11746 | /* |
11747 | ** The implementation of SQL scalar function fkey_collate_clause(), used |
11748 | ** by the ".lint fkey-indexes" command. This scalar function is always |
11749 | ** called with four arguments - the parent table name, the parent column name, |
11750 | ** the child table name and the child column name. |
11751 | ** |
11752 | ** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col') |
11753 | ** |
11754 | ** If either of the named tables or columns do not exist, this function |
11755 | ** returns an empty string. An empty string is also returned if both tables |
11756 | ** and columns exist but have the same default collation sequence. Or, |
11757 | ** if both exist but the default collation sequences are different, this |
11758 | ** function returns the string " COLLATE <parent-collation>", where |
11759 | ** <parent-collation> is the default collation sequence of the parent column. |
11760 | */ |
11761 | static void shellFkeyCollateClause(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal) { |
11762 | sqlite3 *db = sqlite3_context_db_handle(pCtx); |
11763 | const char *zParent; |
11764 | const char *zParentCol; |
11765 | const char *zParentSeq; |
11766 | const char *zChild; |
11767 | const char *zChildCol; |
11768 | const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */ |
11769 | int rc; |
11770 | |
11771 | assert(nVal == 4); |
11772 | zParent = (const char *)sqlite3_value_text(apVal[0]); |
11773 | zParentCol = (const char *)sqlite3_value_text(apVal[1]); |
11774 | zChild = (const char *)sqlite3_value_text(apVal[2]); |
11775 | zChildCol = (const char *)sqlite3_value_text(apVal[3]); |
11776 | |
11777 | sqlite3_result_text(pCtx, "" , -1, SQLITE_STATIC); |
11778 | rc = sqlite3_table_column_metadata(db, "main" , zParent, zParentCol, 0, &zParentSeq, 0, 0, 0); |
11779 | if (rc == SQLITE_OK) { |
11780 | rc = sqlite3_table_column_metadata(db, "main" , zChild, zChildCol, 0, &zChildSeq, 0, 0, 0); |
11781 | } |
11782 | |
11783 | if (rc == SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq)) { |
11784 | char *z = sqlite3_mprintf(" COLLATE %s" , zParentSeq); |
11785 | sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); |
11786 | sqlite3_free(z); |
11787 | } |
11788 | } |
11789 | |
11790 | /* |
11791 | ** The implementation of dot-command ".lint fkey-indexes". |
11792 | */ |
11793 | static int lintFkeyIndexes(ShellState *pState, /* Current shell tool state */ |
11794 | char **azArg, /* Array of arguments passed to dot command */ |
11795 | int nArg /* Number of entries in azArg[] */ |
11796 | ) { |
11797 | sqlite3 *db = pState->db; /* Database handle to query "main" db of */ |
11798 | FILE *out = pState->out; /* Stream to write non-error output to */ |
11799 | int bVerbose = 0; /* If -verbose is present */ |
11800 | int bGroupByParent = 0; /* If -groupbyparent is present */ |
11801 | int i; /* To iterate through azArg[] */ |
11802 | const char *zIndent = "" ; /* How much to indent CREATE INDEX by */ |
11803 | int rc; /* Return code */ |
11804 | sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ |
11805 | |
11806 | /* |
11807 | ** This SELECT statement returns one row for each foreign key constraint |
11808 | ** in the schema of the main database. The column values are: |
11809 | ** |
11810 | ** 0. The text of an SQL statement similar to: |
11811 | ** |
11812 | ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?" |
11813 | ** |
11814 | ** This SELECT is similar to the one that the foreign keys implementation |
11815 | ** needs to run internally on child tables. If there is an index that can |
11816 | ** be used to optimize this query, then it can also be used by the FK |
11817 | ** implementation to optimize DELETE or UPDATE statements on the parent |
11818 | ** table. |
11819 | ** |
11820 | ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by |
11821 | ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema |
11822 | ** contains an index that can be used to optimize the query. |
11823 | ** |
11824 | ** 2. Human readable text that describes the child table and columns. e.g. |
11825 | ** |
11826 | ** "child_table(child_key1, child_key2)" |
11827 | ** |
11828 | ** 3. Human readable text that describes the parent table and columns. e.g. |
11829 | ** |
11830 | ** "parent_table(parent_key1, parent_key2)" |
11831 | ** |
11832 | ** 4. A full CREATE INDEX statement for an index that could be used to |
11833 | ** optimize DELETE or UPDATE statements on the parent table. e.g. |
11834 | ** |
11835 | ** "CREATE INDEX child_table_child_key ON child_table(child_key)" |
11836 | ** |
11837 | ** 5. The name of the parent table. |
11838 | ** |
11839 | ** These six values are used by the C logic below to generate the report. |
11840 | */ |
11841 | const char *zSql = "SELECT " |
11842 | " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '" |
11843 | " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " |
11844 | " || fkey_collate_clause(" |
11845 | " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" |
11846 | ", " |
11847 | " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('" |
11848 | " || group_concat('*=?', ' AND ') || ')'" |
11849 | ", " |
11850 | " s.name || '(' || group_concat(f.[from], ', ') || ')'" |
11851 | ", " |
11852 | " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'" |
11853 | ", " |
11854 | " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))" |
11855 | " || ' ON ' || quote(s.name) || '('" |
11856 | " || group_concat(quote(f.[from]) ||" |
11857 | " fkey_collate_clause(" |
11858 | " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')" |
11859 | " || ');'" |
11860 | ", " |
11861 | " f.[table] " |
11862 | "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f " |
11863 | "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) " |
11864 | "GROUP BY s.name, f.id " |
11865 | "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" ; |
11866 | const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)" ; |
11867 | |
11868 | for (i = 2; i < nArg; i++) { |
11869 | int n = strlen30(azArg[i]); |
11870 | if (n > 1 && sqlite3_strnicmp("-verbose" , azArg[i], n) == 0) { |
11871 | bVerbose = 1; |
11872 | } else if (n > 1 && sqlite3_strnicmp("-groupbyparent" , azArg[i], n) == 0) { |
11873 | bGroupByParent = 1; |
11874 | zIndent = " " ; |
11875 | } else { |
11876 | raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n" , azArg[0], azArg[1]); |
11877 | return SQLITE_ERROR; |
11878 | } |
11879 | } |
11880 | |
11881 | /* Register the fkey_collate_clause() SQL function */ |
11882 | rc = sqlite3_create_function(db, "fkey_collate_clause" , 4, SQLITE_UTF8, 0, shellFkeyCollateClause, 0, 0); |
11883 | |
11884 | if (rc == SQLITE_OK) { |
11885 | rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); |
11886 | } |
11887 | if (rc == SQLITE_OK) { |
11888 | sqlite3_bind_int(pSql, 1, bGroupByParent); |
11889 | } |
11890 | |
11891 | if (rc == SQLITE_OK) { |
11892 | int rc2; |
11893 | char *zPrev = 0; |
11894 | while (SQLITE_ROW == sqlite3_step(pSql)) { |
11895 | int res = -1; |
11896 | sqlite3_stmt *pExplain = 0; |
11897 | const char *zEQP = (const char *)sqlite3_column_text(pSql, 0); |
11898 | const char *zGlob = (const char *)sqlite3_column_text(pSql, 1); |
11899 | const char *zFrom = (const char *)sqlite3_column_text(pSql, 2); |
11900 | const char *zTarget = (const char *)sqlite3_column_text(pSql, 3); |
11901 | const char *zCI = (const char *)sqlite3_column_text(pSql, 4); |
11902 | const char *zParent = (const char *)sqlite3_column_text(pSql, 5); |
11903 | |
11904 | rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); |
11905 | if (rc != SQLITE_OK) |
11906 | break; |
11907 | if (SQLITE_ROW == sqlite3_step(pExplain)) { |
11908 | const char *zPlan = (const char *)sqlite3_column_text(pExplain, 3); |
11909 | res = (0 == sqlite3_strglob(zGlob, zPlan) || 0 == sqlite3_strglob(zGlobIPK, zPlan)); |
11910 | } |
11911 | rc = sqlite3_finalize(pExplain); |
11912 | if (rc != SQLITE_OK) |
11913 | break; |
11914 | |
11915 | if (res < 0) { |
11916 | raw_printf(stderr, "Error: internal error" ); |
11917 | break; |
11918 | } else { |
11919 | if (bGroupByParent && (bVerbose || res == 0) && (zPrev == 0 || sqlite3_stricmp(zParent, zPrev))) { |
11920 | raw_printf(out, "-- Parent table %s\n" , zParent); |
11921 | sqlite3_free(zPrev); |
11922 | zPrev = sqlite3_mprintf("%s" , zParent); |
11923 | } |
11924 | |
11925 | if (res == 0) { |
11926 | raw_printf(out, "%s%s --> %s\n" , zIndent, zCI, zTarget); |
11927 | } else if (bVerbose) { |
11928 | raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n" , zIndent, zFrom, zTarget); |
11929 | } |
11930 | } |
11931 | } |
11932 | sqlite3_free(zPrev); |
11933 | |
11934 | if (rc != SQLITE_OK) { |
11935 | raw_printf(stderr, "%s\n" , sqlite3_errmsg(db)); |
11936 | } |
11937 | |
11938 | rc2 = sqlite3_finalize(pSql); |
11939 | if (rc == SQLITE_OK && rc2 != SQLITE_OK) { |
11940 | rc = rc2; |
11941 | raw_printf(stderr, "%s\n" , sqlite3_errmsg(db)); |
11942 | } |
11943 | } else { |
11944 | raw_printf(stderr, "%s\n" , sqlite3_errmsg(db)); |
11945 | } |
11946 | |
11947 | return rc; |
11948 | } |
11949 | |
11950 | /* |
11951 | ** Implementation of ".lint" dot command. |
11952 | */ |
11953 | static int lintDotCommand(ShellState *pState, /* Current shell tool state */ |
11954 | char **azArg, /* Array of arguments passed to dot command */ |
11955 | int nArg /* Number of entries in azArg[] */ |
11956 | ) { |
11957 | int n; |
11958 | n = (nArg >= 2 ? strlen30(azArg[1]) : 0); |
11959 | if (n < 1 || sqlite3_strnicmp(azArg[1], "fkey-indexes" , n)) |
11960 | goto usage; |
11961 | return lintFkeyIndexes(pState, azArg, nArg); |
11962 | |
11963 | usage: |
11964 | raw_printf(stderr, "Usage %s sub-command ?switches...?\n" , azArg[0]); |
11965 | raw_printf(stderr, "Where sub-commands are:\n" ); |
11966 | raw_printf(stderr, " fkey-indexes\n" ); |
11967 | return SQLITE_ERROR; |
11968 | } |
11969 | |
11970 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
11971 | /********************************************************************************* |
11972 | ** The ".archive" or ".ar" command. |
11973 | */ |
11974 | static void shellPrepare(sqlite3 *db, int *pRc, const char *zSql, sqlite3_stmt **ppStmt) { |
11975 | *ppStmt = 0; |
11976 | if (*pRc == SQLITE_OK) { |
11977 | int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); |
11978 | if (rc != SQLITE_OK) { |
11979 | raw_printf(stderr, "sql error: %s (%d)\n" , sqlite3_errmsg(db), sqlite3_errcode(db)); |
11980 | *pRc = rc; |
11981 | } |
11982 | } |
11983 | } |
11984 | |
11985 | static void shellPreparePrintf(sqlite3 *db, int *pRc, sqlite3_stmt **ppStmt, const char *zFmt, ...) { |
11986 | *ppStmt = 0; |
11987 | if (*pRc == SQLITE_OK) { |
11988 | va_list ap; |
11989 | char *z; |
11990 | va_start(ap, zFmt); |
11991 | z = sqlite3_vmprintf(zFmt, ap); |
11992 | if (z == 0) { |
11993 | *pRc = SQLITE_NOMEM; |
11994 | } else { |
11995 | shellPrepare(db, pRc, z, ppStmt); |
11996 | sqlite3_free(z); |
11997 | } |
11998 | } |
11999 | } |
12000 | |
12001 | static void shellFinalize(int *pRc, sqlite3_stmt *pStmt) { |
12002 | if (pStmt) { |
12003 | sqlite3 *db = sqlite3_db_handle(pStmt); |
12004 | int rc = sqlite3_finalize(pStmt); |
12005 | if (*pRc == SQLITE_OK) { |
12006 | if (rc != SQLITE_OK) { |
12007 | raw_printf(stderr, "SQL error: %s\n" , sqlite3_errmsg(db)); |
12008 | } |
12009 | *pRc = rc; |
12010 | } |
12011 | } |
12012 | } |
12013 | |
12014 | static void shellReset(int *pRc, sqlite3_stmt *pStmt) { |
12015 | int rc = sqlite3_reset(pStmt); |
12016 | if (*pRc == SQLITE_OK) { |
12017 | if (rc != SQLITE_OK) { |
12018 | sqlite3 *db = sqlite3_db_handle(pStmt); |
12019 | raw_printf(stderr, "SQL error: %s\n" , sqlite3_errmsg(db)); |
12020 | } |
12021 | *pRc = rc; |
12022 | } |
12023 | } |
12024 | /* |
12025 | ** Structure representing a single ".ar" command. |
12026 | */ |
12027 | typedef struct ArCommand ArCommand; |
12028 | struct ArCommand { |
12029 | u8 eCmd; /* An AR_CMD_* value */ |
12030 | u8 bVerbose; /* True if --verbose */ |
12031 | u8 bZip; /* True if the archive is a ZIP */ |
12032 | u8 bDryRun; /* True if --dry-run */ |
12033 | u8 bAppend; /* True if --append */ |
12034 | int nArg; /* Number of command arguments */ |
12035 | char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */ |
12036 | const char *zFile; /* --file argument, or NULL */ |
12037 | const char *zDir; /* --directory argument, or NULL */ |
12038 | char **azArg; /* Array of command arguments */ |
12039 | ShellState *p; /* Shell state */ |
12040 | sqlite3 *db; /* Database containing the archive */ |
12041 | }; |
12042 | |
12043 | /* |
12044 | ** Print a usage message for the .ar command to stderr and return SQLITE_ERROR. |
12045 | */ |
12046 | static int arUsage(FILE *f) { |
12047 | raw_printf(f, "\n" |
12048 | "Usage: .ar [OPTION...] [FILE...]\n" |
12049 | "The .ar command manages sqlar archives.\n" |
12050 | "\n" |
12051 | "Examples:\n" |
12052 | " .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar\n" |
12053 | " .ar -tf archive.sar # List members of archive.sar\n" |
12054 | " .ar -xvf archive.sar # Verbosely extract files from archive.sar\n" |
12055 | "\n" |
12056 | "Each command line must feature exactly one command option:\n" |
12057 | " -c, --create Create a new archive\n" |
12058 | " -u, --update Update or add files to an existing archive\n" |
12059 | " -t, --list List contents of archive\n" |
12060 | " -x, --extract Extract files from archive\n" |
12061 | "\n" |
12062 | "And zero or more optional options:\n" |
12063 | " -v, --verbose Print each filename as it is processed\n" |
12064 | " -f FILE, --file FILE Operate on archive FILE (default is current db)\n" |
12065 | " -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS\n" |
12066 | " -C DIR, --directory DIR Change to directory DIR to read/extract files\n" |
12067 | " -n, --dryrun Show the SQL that would have occurred\n" |
12068 | "\n" |
12069 | "See also: http://sqlite.org/cli.html#sqlar_archive_support\n" |
12070 | "\n" ); |
12071 | return SQLITE_ERROR; |
12072 | } |
12073 | |
12074 | /* |
12075 | ** Print an error message for the .ar command to stderr and return |
12076 | ** SQLITE_ERROR. |
12077 | */ |
12078 | static int arErrorMsg(const char *zFmt, ...) { |
12079 | va_list ap; |
12080 | char *z; |
12081 | va_start(ap, zFmt); |
12082 | z = sqlite3_vmprintf(zFmt, ap); |
12083 | va_end(ap); |
12084 | raw_printf(stderr, "Error: %s (try \".ar --help\")\n" , z); |
12085 | sqlite3_free(z); |
12086 | return SQLITE_ERROR; |
12087 | } |
12088 | |
12089 | /* |
12090 | ** Values for ArCommand.eCmd. |
12091 | */ |
12092 | #define AR_CMD_CREATE 1 |
12093 | #define AR_CMD_EXTRACT 2 |
12094 | #define AR_CMD_LIST 3 |
12095 | #define AR_CMD_UPDATE 4 |
12096 | #define AR_CMD_HELP 5 |
12097 | |
12098 | /* |
12099 | ** Other (non-command) switches. |
12100 | */ |
12101 | #define AR_SWITCH_VERBOSE 6 |
12102 | #define AR_SWITCH_FILE 7 |
12103 | #define AR_SWITCH_DIRECTORY 8 |
12104 | #define AR_SWITCH_APPEND 9 |
12105 | #define AR_SWITCH_DRYRUN 10 |
12106 | |
12107 | static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg) { |
12108 | switch (eSwitch) { |
12109 | case AR_CMD_CREATE: |
12110 | case AR_CMD_EXTRACT: |
12111 | case AR_CMD_LIST: |
12112 | case AR_CMD_UPDATE: |
12113 | case AR_CMD_HELP: |
12114 | if (pAr->eCmd) { |
12115 | return arErrorMsg("multiple command options" ); |
12116 | } |
12117 | pAr->eCmd = eSwitch; |
12118 | break; |
12119 | |
12120 | case AR_SWITCH_DRYRUN: |
12121 | pAr->bDryRun = 1; |
12122 | break; |
12123 | case AR_SWITCH_VERBOSE: |
12124 | pAr->bVerbose = 1; |
12125 | break; |
12126 | case AR_SWITCH_APPEND: |
12127 | pAr->bAppend = 1; |
12128 | /* Fall thru into --file */ |
12129 | case AR_SWITCH_FILE: |
12130 | pAr->zFile = zArg; |
12131 | break; |
12132 | case AR_SWITCH_DIRECTORY: |
12133 | pAr->zDir = zArg; |
12134 | break; |
12135 | } |
12136 | |
12137 | return SQLITE_OK; |
12138 | } |
12139 | |
12140 | /* |
12141 | ** Parse the command line for an ".ar" command. The results are written into |
12142 | ** structure (*pAr). SQLITE_OK is returned if the command line is parsed |
12143 | ** successfully, otherwise an error message is written to stderr and |
12144 | ** SQLITE_ERROR returned. |
12145 | */ |
12146 | static int arParseCommand(char **azArg, /* Array of arguments passed to dot command */ |
12147 | int nArg, /* Number of entries in azArg[] */ |
12148 | ArCommand *pAr /* Populate this object */ |
12149 | ) { |
12150 | struct ArSwitch { |
12151 | const char *zLong; |
12152 | char cShort; |
12153 | u8 eSwitch; |
12154 | u8 bArg; |
12155 | } aSwitch[] = { |
12156 | {"create" , 'c', AR_CMD_CREATE, 0}, |
12157 | {"extract" , 'x', AR_CMD_EXTRACT, 0}, |
12158 | {"list" , 't', AR_CMD_LIST, 0}, |
12159 | {"update" , 'u', AR_CMD_UPDATE, 0}, |
12160 | {"help" , 'h', AR_CMD_HELP, 0}, |
12161 | {"verbose" , 'v', AR_SWITCH_VERBOSE, 0}, |
12162 | {"file" , 'f', AR_SWITCH_FILE, 1}, |
12163 | {"append" , 'a', AR_SWITCH_APPEND, 1}, |
12164 | {"directory" , 'C', AR_SWITCH_DIRECTORY, 1}, |
12165 | {"dryrun" , 'n', AR_SWITCH_DRYRUN, 0}, |
12166 | }; |
12167 | int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch); |
12168 | struct ArSwitch *pEnd = &aSwitch[nSwitch]; |
12169 | |
12170 | if (nArg <= 1) { |
12171 | return arUsage(stderr); |
12172 | } else { |
12173 | char *z = azArg[1]; |
12174 | memset(pAr, 0, sizeof(ArCommand)); |
12175 | |
12176 | if (z[0] != '-') { |
12177 | /* Traditional style [tar] invocation */ |
12178 | int i; |
12179 | int iArg = 2; |
12180 | for (i = 0; z[i]; i++) { |
12181 | const char *zArg = 0; |
12182 | struct ArSwitch *pOpt; |
12183 | for (pOpt = &aSwitch[0]; pOpt < pEnd; pOpt++) { |
12184 | if (z[i] == pOpt->cShort) |
12185 | break; |
12186 | } |
12187 | if (pOpt == pEnd) { |
12188 | return arErrorMsg("unrecognized option: %c" , z[i]); |
12189 | } |
12190 | if (pOpt->bArg) { |
12191 | if (iArg >= nArg) { |
12192 | return arErrorMsg("option requires an argument: %c" , z[i]); |
12193 | } |
12194 | zArg = azArg[iArg++]; |
12195 | } |
12196 | if (arProcessSwitch(pAr, pOpt->eSwitch, zArg)) |
12197 | return SQLITE_ERROR; |
12198 | } |
12199 | pAr->nArg = nArg - iArg; |
12200 | if (pAr->nArg > 0) { |
12201 | pAr->azArg = &azArg[iArg]; |
12202 | } |
12203 | } else { |
12204 | /* Non-traditional invocation */ |
12205 | int iArg; |
12206 | for (iArg = 1; iArg < nArg; iArg++) { |
12207 | int n; |
12208 | z = azArg[iArg]; |
12209 | if (z[0] != '-') { |
12210 | /* All remaining command line words are command arguments. */ |
12211 | pAr->azArg = &azArg[iArg]; |
12212 | pAr->nArg = nArg - iArg; |
12213 | break; |
12214 | } |
12215 | n = strlen30(z); |
12216 | |
12217 | if (z[1] != '-') { |
12218 | int i; |
12219 | /* One or more short options */ |
12220 | for (i = 1; i < n; i++) { |
12221 | const char *zArg = 0; |
12222 | struct ArSwitch *pOpt; |
12223 | for (pOpt = &aSwitch[0]; pOpt < pEnd; pOpt++) { |
12224 | if (z[i] == pOpt->cShort) |
12225 | break; |
12226 | } |
12227 | if (pOpt == pEnd) { |
12228 | return arErrorMsg("unrecognized option: %c\n" , z[i]); |
12229 | } |
12230 | if (pOpt->bArg) { |
12231 | if (i < (n - 1)) { |
12232 | zArg = &z[i + 1]; |
12233 | i = n; |
12234 | } else { |
12235 | if (iArg >= (nArg - 1)) { |
12236 | return arErrorMsg("option requires an argument: %c\n" , z[i]); |
12237 | } |
12238 | zArg = azArg[++iArg]; |
12239 | } |
12240 | } |
12241 | if (arProcessSwitch(pAr, pOpt->eSwitch, zArg)) |
12242 | return SQLITE_ERROR; |
12243 | } |
12244 | } else if (z[2] == '\0') { |
12245 | /* A -- option, indicating that all remaining command line words |
12246 | ** are command arguments. */ |
12247 | pAr->azArg = &azArg[iArg + 1]; |
12248 | pAr->nArg = nArg - iArg - 1; |
12249 | break; |
12250 | } else { |
12251 | /* A long option */ |
12252 | const char *zArg = 0; /* Argument for option, if any */ |
12253 | struct ArSwitch *pMatch = 0; /* Matching option */ |
12254 | struct ArSwitch *pOpt; /* Iterator */ |
12255 | for (pOpt = &aSwitch[0]; pOpt < pEnd; pOpt++) { |
12256 | const char *zLong = pOpt->zLong; |
12257 | if ((n - 2) <= strlen30(zLong) && 0 == memcmp(&z[2], zLong, n - 2)) { |
12258 | if (pMatch) { |
12259 | return arErrorMsg("ambiguous option: %s" , z); |
12260 | } else { |
12261 | pMatch = pOpt; |
12262 | } |
12263 | } |
12264 | } |
12265 | |
12266 | if (pMatch == 0) { |
12267 | return arErrorMsg("unrecognized option: %s" , z); |
12268 | } |
12269 | if (pMatch->bArg) { |
12270 | if (iArg >= (nArg - 1)) { |
12271 | return arErrorMsg("option requires an argument: %s" , z); |
12272 | } |
12273 | zArg = azArg[++iArg]; |
12274 | } |
12275 | if (arProcessSwitch(pAr, pMatch->eSwitch, zArg)) |
12276 | return SQLITE_ERROR; |
12277 | } |
12278 | } |
12279 | } |
12280 | } |
12281 | |
12282 | return SQLITE_OK; |
12283 | } |
12284 | |
12285 | /* |
12286 | ** This function assumes that all arguments within the ArCommand.azArg[] |
12287 | ** array refer to archive members, as for the --extract or --list commands. |
12288 | ** It checks that each of them are present. If any specified file is not |
12289 | ** present in the archive, an error is printed to stderr and an error |
12290 | ** code returned. Otherwise, if all specified arguments are present in |
12291 | ** the archive, SQLITE_OK is returned. |
12292 | ** |
12293 | ** This function strips any trailing '/' characters from each argument. |
12294 | ** This is consistent with the way the [tar] command seems to work on |
12295 | ** Linux. |
12296 | */ |
12297 | static int arCheckEntries(ArCommand *pAr) { |
12298 | int rc = SQLITE_OK; |
12299 | if (pAr->nArg) { |
12300 | int i, j; |
12301 | sqlite3_stmt *pTest = 0; |
12302 | |
12303 | shellPreparePrintf(pAr->db, &rc, &pTest, "SELECT name FROM %s WHERE name=$name" , pAr->zSrcTable); |
12304 | j = sqlite3_bind_parameter_index(pTest, "$name" ); |
12305 | for (i = 0; i < pAr->nArg && rc == SQLITE_OK; i++) { |
12306 | char *z = pAr->azArg[i]; |
12307 | int n = strlen30(z); |
12308 | int bOk = 0; |
12309 | while (n > 0 && z[n - 1] == '/') |
12310 | n--; |
12311 | z[n] = '\0'; |
12312 | sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC); |
12313 | if (SQLITE_ROW == sqlite3_step(pTest)) { |
12314 | bOk = 1; |
12315 | } |
12316 | shellReset(&rc, pTest); |
12317 | if (rc == SQLITE_OK && bOk == 0) { |
12318 | utf8_printf(stderr, "not found in archive: %s\n" , z); |
12319 | rc = SQLITE_ERROR; |
12320 | } |
12321 | } |
12322 | shellFinalize(&rc, pTest); |
12323 | } |
12324 | return rc; |
12325 | } |
12326 | |
12327 | /* |
12328 | ** Format a WHERE clause that can be used against the "sqlar" table to |
12329 | ** identify all archive members that match the command arguments held |
12330 | ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning. |
12331 | ** The caller is responsible for eventually calling sqlite3_free() on |
12332 | ** any non-NULL (*pzWhere) value. |
12333 | */ |
12334 | static void arWhereClause(int *pRc, ArCommand *pAr, char **pzWhere /* OUT: New WHERE clause */ |
12335 | ) { |
12336 | char *zWhere = 0; |
12337 | if (*pRc == SQLITE_OK) { |
12338 | if (pAr->nArg == 0) { |
12339 | zWhere = sqlite3_mprintf("1" ); |
12340 | } else { |
12341 | int i; |
12342 | const char *zSep = "" ; |
12343 | for (i = 0; i < pAr->nArg; i++) { |
12344 | const char *z = pAr->azArg[i]; |
12345 | zWhere = sqlite3_mprintf("%z%s name = '%q' OR substr(name,1,%d) = '%q/'" , zWhere, zSep, z, |
12346 | strlen30(z) + 1, z); |
12347 | if (zWhere == 0) { |
12348 | *pRc = SQLITE_NOMEM; |
12349 | break; |
12350 | } |
12351 | zSep = " OR " ; |
12352 | } |
12353 | } |
12354 | } |
12355 | *pzWhere = zWhere; |
12356 | } |
12357 | |
12358 | /* |
12359 | ** Implementation of .ar "lisT" command. |
12360 | */ |
12361 | static int arListCommand(ArCommand *pAr) { |
12362 | const char *zSql = "SELECT %s FROM %s WHERE %s" ; |
12363 | const char *azCols[] = {"name" , "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name" }; |
12364 | |
12365 | char *zWhere = 0; |
12366 | sqlite3_stmt *pSql = 0; |
12367 | int rc; |
12368 | |
12369 | rc = arCheckEntries(pAr); |
12370 | arWhereClause(&rc, pAr, &zWhere); |
12371 | |
12372 | shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose], pAr->zSrcTable, zWhere); |
12373 | if (pAr->bDryRun) { |
12374 | utf8_printf(pAr->p->out, "%s\n" , sqlite3_sql(pSql)); |
12375 | } else { |
12376 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pSql)) { |
12377 | if (pAr->bVerbose) { |
12378 | utf8_printf(pAr->p->out, "%s % 10d %s %s\n" , sqlite3_column_text(pSql, 0), |
12379 | sqlite3_column_int(pSql, 1), sqlite3_column_text(pSql, 2), sqlite3_column_text(pSql, 3)); |
12380 | } else { |
12381 | utf8_printf(pAr->p->out, "%s\n" , sqlite3_column_text(pSql, 0)); |
12382 | } |
12383 | } |
12384 | } |
12385 | shellFinalize(&rc, pSql); |
12386 | return rc; |
12387 | } |
12388 | |
12389 | /* |
12390 | ** Implementation of .ar "eXtract" command. |
12391 | */ |
12392 | static int arExtractCommand(ArCommand *pAr) { |
12393 | const char *zSql1 = "SELECT " |
12394 | " ($dir || name)," |
12395 | " writefile(($dir || name), %s, mode, mtime) " |
12396 | "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)" ; |
12397 | |
12398 | const char *azExtraArg[] = {"sqlar_uncompress(data, sz)" , "data" }; |
12399 | |
12400 | sqlite3_stmt *pSql = 0; |
12401 | int rc = SQLITE_OK; |
12402 | char *zDir = 0; |
12403 | char *zWhere = 0; |
12404 | int i, j; |
12405 | |
12406 | /* If arguments are specified, check that they actually exist within |
12407 | ** the archive before proceeding. And formulate a WHERE clause to |
12408 | ** match them. */ |
12409 | rc = arCheckEntries(pAr); |
12410 | arWhereClause(&rc, pAr, &zWhere); |
12411 | |
12412 | if (rc == SQLITE_OK) { |
12413 | if (pAr->zDir) { |
12414 | zDir = sqlite3_mprintf("%s/" , pAr->zDir); |
12415 | } else { |
12416 | zDir = sqlite3_mprintf("" ); |
12417 | } |
12418 | if (zDir == 0) |
12419 | rc = SQLITE_NOMEM; |
12420 | } |
12421 | |
12422 | shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere); |
12423 | |
12424 | if (rc == SQLITE_OK) { |
12425 | j = sqlite3_bind_parameter_index(pSql, "$dir" ); |
12426 | sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC); |
12427 | |
12428 | /* Run the SELECT statement twice. The first time, writefile() is called |
12429 | ** for all archive members that should be extracted. The second time, |
12430 | ** only for the directories. This is because the timestamps for |
12431 | ** extracted directories must be reset after they are populated (as |
12432 | ** populating them changes the timestamp). */ |
12433 | for (i = 0; i < 2; i++) { |
12434 | j = sqlite3_bind_parameter_index(pSql, "$dirOnly" ); |
12435 | sqlite3_bind_int(pSql, j, i); |
12436 | if (pAr->bDryRun) { |
12437 | utf8_printf(pAr->p->out, "%s\n" , sqlite3_sql(pSql)); |
12438 | } else { |
12439 | while (rc == SQLITE_OK && SQLITE_ROW == sqlite3_step(pSql)) { |
12440 | if (i == 0 && pAr->bVerbose) { |
12441 | utf8_printf(pAr->p->out, "%s\n" , sqlite3_column_text(pSql, 0)); |
12442 | } |
12443 | } |
12444 | } |
12445 | shellReset(&rc, pSql); |
12446 | } |
12447 | shellFinalize(&rc, pSql); |
12448 | } |
12449 | |
12450 | sqlite3_free(zDir); |
12451 | sqlite3_free(zWhere); |
12452 | return rc; |
12453 | } |
12454 | |
12455 | /* |
12456 | ** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out. |
12457 | */ |
12458 | static int arExecSql(ArCommand *pAr, const char *zSql) { |
12459 | int rc; |
12460 | if (pAr->bDryRun) { |
12461 | utf8_printf(pAr->p->out, "%s\n" , zSql); |
12462 | rc = SQLITE_OK; |
12463 | } else { |
12464 | char *zErr = 0; |
12465 | rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); |
12466 | if (zErr) { |
12467 | utf8_printf(stdout, "ERROR: %s\n" , zErr); |
12468 | sqlite3_free(zErr); |
12469 | } |
12470 | } |
12471 | return rc; |
12472 | } |
12473 | |
12474 | /* |
12475 | ** Implementation of .ar "create" and "update" commands. |
12476 | ** |
12477 | ** Create the "sqlar" table in the database if it does not already exist. |
12478 | ** Then add each file in the azFile[] array to the archive. Directories |
12479 | ** are added recursively. If argument bVerbose is non-zero, a message is |
12480 | ** printed on stdout for each file archived. |
12481 | ** |
12482 | ** The create command is the same as update, except that it drops |
12483 | ** any existing "sqlar" table before beginning. |
12484 | */ |
12485 | static int arCreateOrUpdateCommand(ArCommand *pAr, /* Command arguments and options */ |
12486 | int bUpdate /* true for a --create. false for --update */ |
12487 | ) { |
12488 | const char *zCreate = "CREATE TABLE IF NOT EXISTS sqlar(\n" |
12489 | " name TEXT PRIMARY KEY, -- name of the file\n" |
12490 | " mode INT, -- access permissions\n" |
12491 | " mtime INT, -- last modification time\n" |
12492 | " sz INT, -- original file size\n" |
12493 | " data BLOB -- compressed content\n" |
12494 | ")" ; |
12495 | const char *zDrop = "DROP TABLE IF EXISTS sqlar" ; |
12496 | const char *zInsertFmt[2] = {"REPLACE INTO %s(name,mode,mtime,sz,data)\n" |
12497 | " SELECT\n" |
12498 | " %s,\n" |
12499 | " mode,\n" |
12500 | " mtime,\n" |
12501 | " CASE substr(lsmode(mode),1,1)\n" |
12502 | " WHEN '-' THEN length(data)\n" |
12503 | " WHEN 'd' THEN 0\n" |
12504 | " ELSE -1 END,\n" |
12505 | " sqlar_compress(data)\n" |
12506 | " FROM fsdir(%Q,%Q)\n" |
12507 | " WHERE lsmode(mode) NOT LIKE '?%%';" , |
12508 | "REPLACE INTO %s(name,mode,mtime,data)\n" |
12509 | " SELECT\n" |
12510 | " %s,\n" |
12511 | " mode,\n" |
12512 | " mtime,\n" |
12513 | " data\n" |
12514 | " FROM fsdir(%Q,%Q)\n" |
12515 | " WHERE lsmode(mode) NOT LIKE '?%%';" }; |
12516 | int i; /* For iterating through azFile[] */ |
12517 | int rc; /* Return code */ |
12518 | const char *zTab = 0; /* SQL table into which to insert */ |
12519 | char *zSql; |
12520 | char zTemp[50]; |
12521 | |
12522 | arExecSql(pAr, "PRAGMA page_size=512" ); |
12523 | rc = arExecSql(pAr, "SAVEPOINT ar;" ); |
12524 | if (rc != SQLITE_OK) |
12525 | return rc; |
12526 | zTemp[0] = 0; |
12527 | if (pAr->bZip) { |
12528 | /* Initialize the zipfile virtual table, if necessary */ |
12529 | if (pAr->zFile) { |
12530 | sqlite3_uint64 r; |
12531 | sqlite3_randomness(sizeof(r), &r); |
12532 | sqlite3_snprintf(sizeof(zTemp), zTemp, "zip%016llx" , r); |
12533 | zTab = zTemp; |
12534 | zSql = sqlite3_mprintf("CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)" , zTab, pAr->zFile); |
12535 | rc = arExecSql(pAr, zSql); |
12536 | sqlite3_free(zSql); |
12537 | } else { |
12538 | zTab = "zip" ; |
12539 | } |
12540 | } else { |
12541 | /* Initialize the table for an SQLAR */ |
12542 | zTab = "sqlar" ; |
12543 | if (bUpdate == 0) { |
12544 | rc = arExecSql(pAr, zDrop); |
12545 | if (rc != SQLITE_OK) |
12546 | goto end_ar_transaction; |
12547 | } |
12548 | rc = arExecSql(pAr, zCreate); |
12549 | } |
12550 | for (i = 0; i < pAr->nArg && rc == SQLITE_OK; i++) { |
12551 | char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab, pAr->bVerbose ? "shell_putsnl(name)" : "name" , |
12552 | pAr->azArg[i], pAr->zDir); |
12553 | rc = arExecSql(pAr, zSql2); |
12554 | sqlite3_free(zSql2); |
12555 | } |
12556 | end_ar_transaction: |
12557 | if (rc != SQLITE_OK) { |
12558 | arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;" ); |
12559 | } else { |
12560 | rc = arExecSql(pAr, "RELEASE ar;" ); |
12561 | if (pAr->bZip && pAr->zFile) { |
12562 | zSql = sqlite3_mprintf("DROP TABLE %s" , zTemp); |
12563 | arExecSql(pAr, zSql); |
12564 | sqlite3_free(zSql); |
12565 | } |
12566 | } |
12567 | return rc; |
12568 | } |
12569 | |
12570 | /* |
12571 | ** Implementation of ".ar" dot command. |
12572 | */ |
12573 | static int arDotCommand(ShellState *pState, /* Current shell tool state */ |
12574 | char **azArg, /* Array of arguments passed to dot command */ |
12575 | int nArg /* Number of entries in azArg[] */ |
12576 | ) { |
12577 | ArCommand cmd; |
12578 | int rc; |
12579 | memset(&cmd, 0, sizeof(cmd)); |
12580 | rc = arParseCommand(azArg, nArg, &cmd); |
12581 | if (rc == SQLITE_OK) { |
12582 | int eDbType = SHELL_OPEN_UNSPEC; |
12583 | cmd.p = pState; |
12584 | cmd.db = pState->db; |
12585 | if (cmd.zFile) { |
12586 | eDbType = deduceDatabaseType(cmd.zFile, 1); |
12587 | } else { |
12588 | eDbType = pState->openMode; |
12589 | } |
12590 | if (eDbType == SHELL_OPEN_ZIPFILE) { |
12591 | if (cmd.eCmd == AR_CMD_EXTRACT || cmd.eCmd == AR_CMD_LIST) { |
12592 | if (cmd.zFile == 0) { |
12593 | cmd.zSrcTable = sqlite3_mprintf("zip" ); |
12594 | } else { |
12595 | cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)" , cmd.zFile); |
12596 | } |
12597 | } |
12598 | cmd.bZip = 1; |
12599 | } else if (cmd.zFile) { |
12600 | int flags; |
12601 | if (cmd.bAppend) |
12602 | eDbType = SHELL_OPEN_APPENDVFS; |
12603 | if (cmd.eCmd == AR_CMD_CREATE || cmd.eCmd == AR_CMD_UPDATE) { |
12604 | flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; |
12605 | } else { |
12606 | flags = SQLITE_OPEN_READONLY; |
12607 | } |
12608 | cmd.db = 0; |
12609 | if (cmd.bDryRun) { |
12610 | utf8_printf(pState->out, "-- open database '%s'%s\n" , cmd.zFile, |
12611 | eDbType == SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "" ); |
12612 | } |
12613 | rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, eDbType == SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); |
12614 | if (rc != SQLITE_OK) { |
12615 | utf8_printf(stderr, "cannot open file: %s (%s)\n" , cmd.zFile, sqlite3_errmsg(cmd.db)); |
12616 | goto end_ar_command; |
12617 | } |
12618 | sqlite3_fileio_init(cmd.db, 0, 0); |
12619 | sqlite3_sqlar_init(cmd.db, 0, 0); |
12620 | sqlite3_create_function(cmd.db, "shell_putsnl" , 1, SQLITE_UTF8, cmd.p, shellPutsFunc, 0, 0); |
12621 | } |
12622 | if (cmd.zSrcTable == 0 && cmd.bZip == 0) { |
12623 | if (cmd.eCmd != AR_CMD_CREATE && sqlite3_table_column_metadata(cmd.db, 0, "sqlar" , "name" , 0, 0, 0, 0, 0)) { |
12624 | utf8_printf(stderr, "database does not contain an 'sqlar' table\n" ); |
12625 | rc = SQLITE_ERROR; |
12626 | goto end_ar_command; |
12627 | } |
12628 | cmd.zSrcTable = sqlite3_mprintf("sqlar" ); |
12629 | } |
12630 | |
12631 | switch (cmd.eCmd) { |
12632 | case AR_CMD_CREATE: |
12633 | rc = arCreateOrUpdateCommand(&cmd, 0); |
12634 | break; |
12635 | |
12636 | case AR_CMD_EXTRACT: |
12637 | rc = arExtractCommand(&cmd); |
12638 | break; |
12639 | |
12640 | case AR_CMD_LIST: |
12641 | rc = arListCommand(&cmd); |
12642 | break; |
12643 | |
12644 | case AR_CMD_HELP: |
12645 | arUsage(pState->out); |
12646 | break; |
12647 | |
12648 | default: |
12649 | assert(cmd.eCmd == AR_CMD_UPDATE); |
12650 | rc = arCreateOrUpdateCommand(&cmd, 1); |
12651 | break; |
12652 | } |
12653 | } |
12654 | end_ar_command: |
12655 | if (cmd.db != pState->db) { |
12656 | sqlite3_close(cmd.db); |
12657 | } |
12658 | sqlite3_free(cmd.zSrcTable); |
12659 | |
12660 | return rc; |
12661 | } |
12662 | /* End of the ".archive" or ".ar" command logic |
12663 | **********************************************************************************/ |
12664 | #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ |
12665 | |
12666 | /* |
12667 | ** If an input line begins with "." then invoke this routine to |
12668 | ** process that line. |
12669 | ** |
12670 | ** Return 1 on error, 2 to exit, and 0 otherwise. |
12671 | */ |
12672 | static int do_meta_command(char *zLine, ShellState *p) { |
12673 | int h = 1; |
12674 | int nArg = 0; |
12675 | int n, c; |
12676 | int rc = 0; |
12677 | char *azArg[50]; |
12678 | |
12679 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
12680 | if (p->expert.pExpert) { |
12681 | expertFinish(p, 1, 0); |
12682 | } |
12683 | #endif |
12684 | |
12685 | /* Parse the input line into tokens. |
12686 | */ |
12687 | while (zLine[h] && nArg < ArraySize(azArg)) { |
12688 | while (IsSpace(zLine[h])) { |
12689 | h++; |
12690 | } |
12691 | if (zLine[h] == 0) |
12692 | break; |
12693 | if (zLine[h] == '\'' || zLine[h] == '"') { |
12694 | int delim = zLine[h++]; |
12695 | azArg[nArg++] = &zLine[h]; |
12696 | while (zLine[h] && zLine[h] != delim) { |
12697 | if (zLine[h] == '\\' && delim == '"' && zLine[h + 1] != 0) |
12698 | h++; |
12699 | h++; |
12700 | } |
12701 | if (zLine[h] == delim) { |
12702 | zLine[h++] = 0; |
12703 | } |
12704 | if (delim == '"') |
12705 | resolve_backslashes(azArg[nArg - 1]); |
12706 | } else { |
12707 | azArg[nArg++] = &zLine[h]; |
12708 | while (zLine[h] && !IsSpace(zLine[h])) { |
12709 | h++; |
12710 | } |
12711 | if (zLine[h]) |
12712 | zLine[h++] = 0; |
12713 | resolve_backslashes(azArg[nArg - 1]); |
12714 | } |
12715 | } |
12716 | |
12717 | /* Process the input line. |
12718 | */ |
12719 | if (nArg == 0) |
12720 | return 0; /* no tokens, no error */ |
12721 | n = strlen30(azArg[0]); |
12722 | c = azArg[0][0]; |
12723 | clearTempFile(p); |
12724 | |
12725 | #ifndef SQLITE_OMIT_AUTHORIZATION |
12726 | if (c == 'a' && strncmp(azArg[0], "auth" , n) == 0) { |
12727 | if (nArg != 2) { |
12728 | raw_printf(stderr, "Usage: .auth ON|OFF\n" ); |
12729 | rc = 1; |
12730 | goto meta_command_exit; |
12731 | } |
12732 | open_db(p, 0); |
12733 | if (booleanValue(azArg[1])) { |
12734 | sqlite3_set_authorizer(p->db, shellAuth, p); |
12735 | } else { |
12736 | sqlite3_set_authorizer(p->db, 0, 0); |
12737 | } |
12738 | } else |
12739 | #endif |
12740 | |
12741 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
12742 | if (c == 'a' && strncmp(azArg[0], "archive" , n) == 0) { |
12743 | open_db(p, 0); |
12744 | rc = arDotCommand(p, azArg, nArg); |
12745 | } else |
12746 | #endif |
12747 | |
12748 | if ((c == 'b' && n >= 3 && strncmp(azArg[0], "backup" , n) == 0) || |
12749 | (c == 's' && n >= 3 && strncmp(azArg[0], "save" , n) == 0)) { |
12750 | const char *zDestFile = 0; |
12751 | const char *zDb = 0; |
12752 | sqlite3 *pDest; |
12753 | sqlite3_backup *pBackup; |
12754 | int j; |
12755 | for (j = 1; j < nArg; j++) { |
12756 | const char *z = azArg[j]; |
12757 | if (z[0] == '-') { |
12758 | while (z[0] == '-') |
12759 | z++; |
12760 | /* No options to process at this time */ |
12761 | { |
12762 | utf8_printf(stderr, "unknown option: %s\n" , azArg[j]); |
12763 | return 1; |
12764 | } |
12765 | } else if (zDestFile == 0) { |
12766 | zDestFile = azArg[j]; |
12767 | } else if (zDb == 0) { |
12768 | zDb = zDestFile; |
12769 | zDestFile = azArg[j]; |
12770 | } else { |
12771 | raw_printf(stderr, "too many arguments to .backup\n" ); |
12772 | return 1; |
12773 | } |
12774 | } |
12775 | if (zDestFile == 0) { |
12776 | raw_printf(stderr, "missing FILENAME argument on .backup\n" ); |
12777 | return 1; |
12778 | } |
12779 | if (zDb == 0) |
12780 | zDb = "main" ; |
12781 | rc = sqlite3_open(zDestFile, &pDest); |
12782 | if (rc != SQLITE_OK) { |
12783 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , zDestFile); |
12784 | sqlite3_close(pDest); |
12785 | return 1; |
12786 | } |
12787 | open_db(p, 0); |
12788 | pBackup = sqlite3_backup_init(pDest, "main" , p->db, zDb); |
12789 | if (pBackup == 0) { |
12790 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(pDest)); |
12791 | sqlite3_close(pDest); |
12792 | return 1; |
12793 | } |
12794 | while ((rc = sqlite3_backup_step(pBackup, 100)) == SQLITE_OK) { |
12795 | } |
12796 | sqlite3_backup_finish(pBackup); |
12797 | if (rc == SQLITE_DONE) { |
12798 | rc = 0; |
12799 | } else { |
12800 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(pDest)); |
12801 | rc = 1; |
12802 | } |
12803 | sqlite3_close(pDest); |
12804 | } else |
12805 | |
12806 | if (c == 'b' && n >= 3 && strncmp(azArg[0], "bail" , n) == 0) { |
12807 | if (nArg == 2) { |
12808 | bail_on_error = booleanValue(azArg[1]); |
12809 | } else { |
12810 | raw_printf(stderr, "Usage: .bail on|off\n" ); |
12811 | rc = 1; |
12812 | } |
12813 | } else |
12814 | |
12815 | if (c == 'b' && n >= 3 && strncmp(azArg[0], "binary" , n) == 0) { |
12816 | if (nArg == 2) { |
12817 | if (booleanValue(azArg[1])) { |
12818 | setBinaryMode(p->out, 1); |
12819 | } else { |
12820 | setTextMode(p->out, 1); |
12821 | } |
12822 | } else { |
12823 | raw_printf(stderr, "Usage: .binary on|off\n" ); |
12824 | rc = 1; |
12825 | } |
12826 | } else |
12827 | |
12828 | if (c == 'c' && strcmp(azArg[0], "cd" ) == 0) { |
12829 | if (nArg == 2) { |
12830 | #if defined(_WIN32) || defined(WIN32) |
12831 | wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]); |
12832 | rc = !SetCurrentDirectoryW(z); |
12833 | sqlite3_free(z); |
12834 | #else |
12835 | rc = chdir(azArg[1]); |
12836 | #endif |
12837 | if (rc) { |
12838 | utf8_printf(stderr, "Cannot change to directory \"%s\"\n" , azArg[1]); |
12839 | rc = 1; |
12840 | } |
12841 | } else { |
12842 | raw_printf(stderr, "Usage: .cd DIRECTORY\n" ); |
12843 | rc = 1; |
12844 | } |
12845 | } else |
12846 | |
12847 | /* The undocumented ".breakpoint" command causes a call to the no-op |
12848 | ** routine named test_breakpoint(). |
12849 | */ |
12850 | if (c == 'b' && n >= 3 && strncmp(azArg[0], "breakpoint" , n) == 0) { |
12851 | test_breakpoint(); |
12852 | } else |
12853 | |
12854 | if (c == 'c' && n >= 3 && strncmp(azArg[0], "changes" , n) == 0) { |
12855 | if (nArg == 2) { |
12856 | setOrClearFlag(p, SHFLG_CountChanges, azArg[1]); |
12857 | } else { |
12858 | raw_printf(stderr, "Usage: .changes on|off\n" ); |
12859 | rc = 1; |
12860 | } |
12861 | } else |
12862 | |
12863 | /* Cancel output redirection, if it is currently set (by .testcase) |
12864 | ** Then read the content of the testcase-out.txt file and compare against |
12865 | ** azArg[1]. If there are differences, report an error and exit. |
12866 | */ |
12867 | if (c == 'c' && n >= 3 && strncmp(azArg[0], "check" , n) == 0) { |
12868 | char *zRes = 0; |
12869 | output_reset(p); |
12870 | if (nArg != 2) { |
12871 | raw_printf(stderr, "Usage: .check GLOB-PATTERN\n" ); |
12872 | rc = 2; |
12873 | } else if ((zRes = readFile("testcase-out.txt" , 0)) == 0) { |
12874 | raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n" ); |
12875 | rc = 2; |
12876 | } else if (testcase_glob(azArg[1], zRes) == 0) { |
12877 | utf8_printf(stderr, "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n" , p->zTestcase, azArg[1], zRes); |
12878 | rc = 1; |
12879 | } else { |
12880 | utf8_printf(stdout, "testcase-%s ok\n" , p->zTestcase); |
12881 | p->nCheck++; |
12882 | } |
12883 | sqlite3_free(zRes); |
12884 | } else |
12885 | |
12886 | if (c == 'c' && strncmp(azArg[0], "clone" , n) == 0) { |
12887 | if (nArg == 2) { |
12888 | tryToClone(p, azArg[1]); |
12889 | } else { |
12890 | raw_printf(stderr, "Usage: .clone FILENAME\n" ); |
12891 | rc = 1; |
12892 | } |
12893 | } else |
12894 | |
12895 | if (c == 'd' && n > 1 && strncmp(azArg[0], "databases" , n) == 0) { |
12896 | ShellState data; |
12897 | char *zErrMsg = 0; |
12898 | open_db(p, 0); |
12899 | memcpy(&data, p, sizeof(data)); |
12900 | data.showHeader = 0; |
12901 | data.cMode = data.mode = MODE_List; |
12902 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, ": " ); |
12903 | data.cnt = 0; |
12904 | sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list" , callback, &data, &zErrMsg); |
12905 | if (zErrMsg) { |
12906 | utf8_printf(stderr, "Error: %s\n" , zErrMsg); |
12907 | sqlite3_free(zErrMsg); |
12908 | rc = 1; |
12909 | } |
12910 | } else |
12911 | |
12912 | if (c == 'd' && strncmp(azArg[0], "dbinfo" , n) == 0) { |
12913 | rc = shell_dbinfo_command(p, nArg, azArg); |
12914 | } else |
12915 | |
12916 | if (c == 'd' && strncmp(azArg[0], "dump" , n) == 0) { |
12917 | const char *zLike = 0; |
12918 | int i; |
12919 | int = p->showHeader; |
12920 | ShellClearFlag(p, SHFLG_PreserveRowid | SHFLG_Newlines); |
12921 | for (i = 1; i < nArg; i++) { |
12922 | if (azArg[i][0] == '-') { |
12923 | const char *z = azArg[i] + 1; |
12924 | if (z[0] == '-') |
12925 | z++; |
12926 | if (strcmp(z, "preserve-rowids" ) == 0) { |
12927 | #ifdef SQLITE_OMIT_VIRTUALTABLE |
12928 | raw_printf(stderr, "The --preserve-rowids option is not compatible" |
12929 | " with SQLITE_OMIT_VIRTUALTABLE\n" ); |
12930 | rc = 1; |
12931 | goto meta_command_exit; |
12932 | #else |
12933 | ShellSetFlag(p, SHFLG_PreserveRowid); |
12934 | #endif |
12935 | } else if (strcmp(z, "newlines" ) == 0) { |
12936 | ShellSetFlag(p, SHFLG_Newlines); |
12937 | } else { |
12938 | raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n" , azArg[i]); |
12939 | rc = 1; |
12940 | goto meta_command_exit; |
12941 | } |
12942 | } else if (zLike) { |
12943 | raw_printf(stderr, "Usage: .dump ?--preserve-rowids? " |
12944 | "?--newlines? ?LIKE-PATTERN?\n" ); |
12945 | rc = 1; |
12946 | goto meta_command_exit; |
12947 | } else { |
12948 | zLike = azArg[i]; |
12949 | } |
12950 | } |
12951 | open_db(p, 0); |
12952 | /* When playing back a "dump", the content might appear in an order |
12953 | ** which causes immediate foreign key constraints to be violated. |
12954 | ** So disable foreign-key constraint enforcement to prevent problems. */ |
12955 | raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n" ); |
12956 | raw_printf(p->out, "BEGIN TRANSACTION;\n" ); |
12957 | p->writableSchema = 0; |
12958 | p->showHeader = 0; |
12959 | /* Set writable_schema=ON since doing so forces SQLite to initialize |
12960 | ** as much of the schema as it can even if the sqlite_master table is |
12961 | ** corrupt. */ |
12962 | sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON" , 0, 0, 0); |
12963 | p->nErr = 0; |
12964 | if (zLike == 0) { |
12965 | run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " |
12966 | "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" ); |
12967 | run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " |
12968 | "WHERE name=='sqlite_sequence'" ); |
12969 | run_table_dump_query(p, |
12970 | "SELECT sql FROM sqlite_master " |
12971 | "WHERE sql NOT NULL AND type IN ('index','trigger','view')" , |
12972 | 0); |
12973 | } else { |
12974 | char *zSql; |
12975 | zSql = sqlite3_mprintf("SELECT name, type, sql FROM sqlite_master " |
12976 | "WHERE tbl_name LIKE %Q AND type=='table'" |
12977 | " AND sql NOT NULL" , |
12978 | zLike); |
12979 | run_schema_dump_query(p, zSql); |
12980 | sqlite3_free(zSql); |
12981 | zSql = sqlite3_mprintf("SELECT sql FROM sqlite_master " |
12982 | "WHERE sql NOT NULL" |
12983 | " AND type IN ('index','trigger','view')" |
12984 | " AND tbl_name LIKE %Q" , |
12985 | zLike); |
12986 | run_table_dump_query(p, zSql, 0); |
12987 | sqlite3_free(zSql); |
12988 | } |
12989 | if (p->writableSchema) { |
12990 | raw_printf(p->out, "PRAGMA writable_schema=OFF;\n" ); |
12991 | p->writableSchema = 0; |
12992 | } |
12993 | sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;" , 0, 0, 0); |
12994 | sqlite3_exec(p->db, "RELEASE dump;" , 0, 0, 0); |
12995 | raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n" ); |
12996 | p->showHeader = savedShowHeader; |
12997 | } else |
12998 | |
12999 | if (c == 'e' && strncmp(azArg[0], "echo" , n) == 0) { |
13000 | if (nArg == 2) { |
13001 | setOrClearFlag(p, SHFLG_Echo, azArg[1]); |
13002 | } else { |
13003 | raw_printf(stderr, "Usage: .echo on|off\n" ); |
13004 | rc = 1; |
13005 | } |
13006 | } else |
13007 | |
13008 | if (c == 'e' && strncmp(azArg[0], "eqp" , n) == 0) { |
13009 | if (nArg == 2) { |
13010 | if (strcmp(azArg[1], "full" ) == 0) { |
13011 | p->autoEQP = AUTOEQP_full; |
13012 | } else if (strcmp(azArg[1], "trigger" ) == 0) { |
13013 | p->autoEQP = AUTOEQP_trigger; |
13014 | } else { |
13015 | p->autoEQP = (u8)booleanValue(azArg[1]); |
13016 | } |
13017 | } else { |
13018 | raw_printf(stderr, "Usage: .eqp off|on|trigger|full\n" ); |
13019 | rc = 1; |
13020 | } |
13021 | } else |
13022 | |
13023 | if (c == 'e' && strncmp(azArg[0], "exit" , n) == 0) { |
13024 | if (nArg > 1 && (rc = (int)integerValue(azArg[1])) != 0) |
13025 | exit(rc); |
13026 | rc = 2; |
13027 | } else |
13028 | |
13029 | /* The ".explain" command is automatic now. It is largely pointless. It |
13030 | ** retained purely for backwards compatibility */ |
13031 | if (c == 'e' && strncmp(azArg[0], "explain" , n) == 0) { |
13032 | int val = 1; |
13033 | if (nArg >= 2) { |
13034 | if (strcmp(azArg[1], "auto" ) == 0) { |
13035 | val = 99; |
13036 | } else { |
13037 | val = booleanValue(azArg[1]); |
13038 | } |
13039 | } |
13040 | if (val == 1 && p->mode != MODE_Explain) { |
13041 | p->normalMode = p->mode; |
13042 | p->mode = MODE_Explain; |
13043 | p->autoExplain = 0; |
13044 | } else if (val == 0) { |
13045 | if (p->mode == MODE_Explain) |
13046 | p->mode = p->normalMode; |
13047 | p->autoExplain = 0; |
13048 | } else if (val == 99) { |
13049 | if (p->mode == MODE_Explain) |
13050 | p->mode = p->normalMode; |
13051 | p->autoExplain = 1; |
13052 | } |
13053 | } else |
13054 | |
13055 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
13056 | if (c == 'e' && strncmp(azArg[0], "expert" , n) == 0) { |
13057 | open_db(p, 0); |
13058 | expertDotCommand(p, azArg, nArg); |
13059 | } else |
13060 | #endif |
13061 | |
13062 | if (c == 'f' && strncmp(azArg[0], "fullschema" , n) == 0) { |
13063 | ShellState data; |
13064 | char *zErrMsg = 0; |
13065 | int doStats = 0; |
13066 | memcpy(&data, p, sizeof(data)); |
13067 | data.showHeader = 0; |
13068 | data.cMode = data.mode = MODE_Semi; |
13069 | if (nArg == 2 && optionMatch(azArg[1], "indent" )) { |
13070 | data.cMode = data.mode = MODE_Pretty; |
13071 | nArg = 1; |
13072 | } |
13073 | if (nArg != 1) { |
13074 | raw_printf(stderr, "Usage: .fullschema ?--indent?\n" ); |
13075 | rc = 1; |
13076 | goto meta_command_exit; |
13077 | } |
13078 | open_db(p, 0); |
13079 | rc = sqlite3_exec(p->db, |
13080 | "SELECT sql FROM" |
13081 | " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" |
13082 | " FROM sqlite_master UNION ALL" |
13083 | " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " |
13084 | "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' " |
13085 | "ORDER BY rowid" , |
13086 | callback, &data, &zErrMsg); |
13087 | if (rc == SQLITE_OK) { |
13088 | sqlite3_stmt *pStmt; |
13089 | rc = sqlite3_prepare_v2(p->db, |
13090 | "SELECT rowid FROM sqlite_master" |
13091 | " WHERE name GLOB 'sqlite_stat[134]'" , |
13092 | -1, &pStmt, 0); |
13093 | doStats = sqlite3_step(pStmt) == SQLITE_ROW; |
13094 | sqlite3_finalize(pStmt); |
13095 | } |
13096 | if (doStats == 0) { |
13097 | raw_printf(p->out, "/* No STAT tables available */\n" ); |
13098 | } else { |
13099 | raw_printf(p->out, "ANALYZE sqlite_master;\n" ); |
13100 | sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'" , callback, &data, &zErrMsg); |
13101 | data.cMode = data.mode = MODE_Insert; |
13102 | data.zDestTable = "sqlite_stat1" ; |
13103 | shell_exec(p, "SELECT * FROM sqlite_stat1" , &zErrMsg); |
13104 | data.zDestTable = "sqlite_stat3" ; |
13105 | shell_exec(p, "SELECT * FROM sqlite_stat3" , &zErrMsg); |
13106 | data.zDestTable = "sqlite_stat4" ; |
13107 | shell_exec(p, "SELECT * FROM sqlite_stat4" , &zErrMsg); |
13108 | raw_printf(p->out, "ANALYZE sqlite_master;\n" ); |
13109 | } |
13110 | } else |
13111 | |
13112 | if (c == 'h' && strncmp(azArg[0], "headers" , n) == 0) { |
13113 | if (nArg == 2) { |
13114 | p->showHeader = booleanValue(azArg[1]); |
13115 | } else { |
13116 | raw_printf(stderr, "Usage: .headers on|off\n" ); |
13117 | rc = 1; |
13118 | } |
13119 | } else |
13120 | |
13121 | if (c == 'h' && strncmp(azArg[0], "help" , n) == 0) { |
13122 | utf8_printf(p->out, "%s" , zHelp); |
13123 | } else |
13124 | |
13125 | if (c == 'i' && strncmp(azArg[0], "import" , n) == 0) { |
13126 | char *zTable; /* Insert data into this table */ |
13127 | char *zFile; /* Name of file to extra content from */ |
13128 | sqlite3_stmt *pStmt = NULL; /* A statement */ |
13129 | int nCol; /* Number of columns in the table */ |
13130 | int nByte; /* Number of bytes in an SQL string */ |
13131 | int i, j; /* Loop counters */ |
13132 | int needCommit; /* True to COMMIT or ROLLBACK at end */ |
13133 | int nSep; /* Number of bytes in p->colSeparator[] */ |
13134 | char *zSql; /* An SQL statement */ |
13135 | ImportCtx sCtx; /* Reader context */ |
13136 | char *(SQLITE_CDECL * xRead)(ImportCtx *); /* Func to read one value */ |
13137 | int(SQLITE_CDECL * xCloser)(FILE *); /* Func to close file */ |
13138 | |
13139 | if (nArg != 3) { |
13140 | raw_printf(stderr, "Usage: .import FILE TABLE\n" ); |
13141 | goto meta_command_exit; |
13142 | } |
13143 | zFile = azArg[1]; |
13144 | zTable = azArg[2]; |
13145 | seenInterrupt = 0; |
13146 | memset(&sCtx, 0, sizeof(sCtx)); |
13147 | open_db(p, 0); |
13148 | nSep = strlen30(p->colSeparator); |
13149 | if (nSep == 0) { |
13150 | raw_printf(stderr, "Error: non-null column separator required for import\n" ); |
13151 | return 1; |
13152 | } |
13153 | if (nSep > 1) { |
13154 | raw_printf(stderr, "Error: multi-character column separators not allowed" |
13155 | " for import\n" ); |
13156 | return 1; |
13157 | } |
13158 | nSep = strlen30(p->rowSeparator); |
13159 | if (nSep == 0) { |
13160 | raw_printf(stderr, "Error: non-null row separator required for import\n" ); |
13161 | return 1; |
13162 | } |
13163 | if (nSep == 2 && p->mode == MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf) == 0) { |
13164 | /* When importing CSV (only), if the row separator is set to the |
13165 | ** default output row separator, change it to the default input |
13166 | ** row separator. This avoids having to maintain different input |
13167 | ** and output row separators. */ |
13168 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
13169 | nSep = strlen30(p->rowSeparator); |
13170 | } |
13171 | if (nSep > 1) { |
13172 | raw_printf(stderr, "Error: multi-character row separators not allowed" |
13173 | " for import\n" ); |
13174 | return 1; |
13175 | } |
13176 | sCtx.zFile = zFile; |
13177 | sCtx.nLine = 1; |
13178 | if (sCtx.zFile[0] == '|') { |
13179 | #ifdef SQLITE_OMIT_POPEN |
13180 | raw_printf(stderr, "Error: pipes are not supported in this OS\n" ); |
13181 | return 1; |
13182 | #else |
13183 | sCtx.in = popen(sCtx.zFile + 1, "r" ); |
13184 | sCtx.zFile = "<pipe>" ; |
13185 | xCloser = pclose; |
13186 | #endif |
13187 | } else { |
13188 | sCtx.in = fopen(sCtx.zFile, "rb" ); |
13189 | xCloser = fclose; |
13190 | } |
13191 | if (p->mode == MODE_Ascii) { |
13192 | xRead = ascii_read_one_field; |
13193 | } else { |
13194 | xRead = csv_read_one_field; |
13195 | } |
13196 | if (sCtx.in == 0) { |
13197 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , zFile); |
13198 | return 1; |
13199 | } |
13200 | sCtx.cColSep = p->colSeparator[0]; |
13201 | sCtx.cRowSep = p->rowSeparator[0]; |
13202 | zSql = sqlite3_mprintf("SELECT * FROM %s" , zTable); |
13203 | if (zSql == 0) { |
13204 | raw_printf(stderr, "Error: out of memory\n" ); |
13205 | xCloser(sCtx.in); |
13206 | return 1; |
13207 | } |
13208 | nByte = strlen30(zSql); |
13209 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
13210 | import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ |
13211 | if (rc && sqlite3_strglob("no such table: *" , sqlite3_errmsg(p->db)) == 0) { |
13212 | char *zCreate = sqlite3_mprintf("CREATE TABLE %s" , zTable); |
13213 | char cSep = '('; |
13214 | while (xRead(&sCtx)) { |
13215 | zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT" , zCreate, cSep, sCtx.z); |
13216 | cSep = ','; |
13217 | if (sCtx.cTerm != sCtx.cColSep) |
13218 | break; |
13219 | } |
13220 | if (cSep == '(') { |
13221 | sqlite3_free(zCreate); |
13222 | sqlite3_free(sCtx.z); |
13223 | xCloser(sCtx.in); |
13224 | utf8_printf(stderr, "%s: empty file\n" , sCtx.zFile); |
13225 | return 1; |
13226 | } |
13227 | zCreate = sqlite3_mprintf("%z\n)" , zCreate); |
13228 | rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); |
13229 | sqlite3_free(zCreate); |
13230 | if (rc) { |
13231 | utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n" , zTable, sqlite3_errmsg(p->db)); |
13232 | sqlite3_free(sCtx.z); |
13233 | xCloser(sCtx.in); |
13234 | return 1; |
13235 | } |
13236 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
13237 | } |
13238 | sqlite3_free(zSql); |
13239 | if (rc) { |
13240 | if (pStmt) |
13241 | sqlite3_finalize(pStmt); |
13242 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
13243 | xCloser(sCtx.in); |
13244 | return 1; |
13245 | } |
13246 | nCol = sqlite3_column_count(pStmt); |
13247 | sqlite3_finalize(pStmt); |
13248 | pStmt = 0; |
13249 | if (nCol == 0) |
13250 | return 0; /* no columns, no error */ |
13251 | zSql = sqlite3_malloc64(nByte * 2 + 20 + nCol * 2); |
13252 | if (zSql == 0) { |
13253 | raw_printf(stderr, "Error: out of memory\n" ); |
13254 | xCloser(sCtx.in); |
13255 | return 1; |
13256 | } |
13257 | sqlite3_snprintf(nByte + 20, zSql, "INSERT INTO \"%w\" VALUES(?" , zTable); |
13258 | j = strlen30(zSql); |
13259 | for (i = 1; i < nCol; i++) { |
13260 | zSql[j++] = ','; |
13261 | zSql[j++] = '?'; |
13262 | } |
13263 | zSql[j++] = ')'; |
13264 | zSql[j] = 0; |
13265 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
13266 | sqlite3_free(zSql); |
13267 | if (rc) { |
13268 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
13269 | if (pStmt) |
13270 | sqlite3_finalize(pStmt); |
13271 | xCloser(sCtx.in); |
13272 | return 1; |
13273 | } |
13274 | needCommit = sqlite3_get_autocommit(p->db); |
13275 | if (needCommit) |
13276 | sqlite3_exec(p->db, "BEGIN" , 0, 0, 0); |
13277 | do { |
13278 | int startLine = sCtx.nLine; |
13279 | for (i = 0; i < nCol; i++) { |
13280 | char *z = xRead(&sCtx); |
13281 | /* |
13282 | ** Did we reach end-of-file before finding any columns? |
13283 | ** If so, stop instead of NULL filling the remaining columns. |
13284 | */ |
13285 | if (z == 0 && i == 0) |
13286 | break; |
13287 | /* |
13288 | ** Did we reach end-of-file OR end-of-line before finding any |
13289 | ** columns in ASCII mode? If so, stop instead of NULL filling |
13290 | ** the remaining columns. |
13291 | */ |
13292 | if (p->mode == MODE_Ascii && (z == 0 || z[0] == 0) && i == 0) |
13293 | break; |
13294 | sqlite3_bind_text(pStmt, i + 1, z, -1, SQLITE_TRANSIENT); |
13295 | if (i < nCol - 1 && sCtx.cTerm != sCtx.cColSep) { |
13296 | utf8_printf(stderr, |
13297 | "%s:%d: expected %d columns but found %d - " |
13298 | "filling the rest with NULL\n" , |
13299 | sCtx.zFile, startLine, nCol, i + 1); |
13300 | i += 2; |
13301 | while (i <= nCol) { |
13302 | sqlite3_bind_null(pStmt, i); |
13303 | i++; |
13304 | } |
13305 | } |
13306 | } |
13307 | if (sCtx.cTerm == sCtx.cColSep) { |
13308 | do { |
13309 | xRead(&sCtx); |
13310 | i++; |
13311 | } while (sCtx.cTerm == sCtx.cColSep); |
13312 | utf8_printf(stderr, |
13313 | "%s:%d: expected %d columns but found %d - " |
13314 | "extras ignored\n" , |
13315 | sCtx.zFile, startLine, nCol, i); |
13316 | } |
13317 | if (i >= nCol) { |
13318 | sqlite3_step(pStmt); |
13319 | rc = sqlite3_reset(pStmt); |
13320 | if (rc != SQLITE_OK) { |
13321 | utf8_printf(stderr, "%s:%d: INSERT failed: %s\n" , sCtx.zFile, startLine, sqlite3_errmsg(p->db)); |
13322 | } |
13323 | } |
13324 | } while (sCtx.cTerm != EOF); |
13325 | |
13326 | xCloser(sCtx.in); |
13327 | sqlite3_free(sCtx.z); |
13328 | sqlite3_finalize(pStmt); |
13329 | if (needCommit) |
13330 | sqlite3_exec(p->db, "COMMIT" , 0, 0, 0); |
13331 | } else |
13332 | |
13333 | #ifndef SQLITE_UNTESTABLE |
13334 | if (c == 'i' && strncmp(azArg[0], "imposter" , n) == 0) { |
13335 | char *zSql; |
13336 | char *zCollist = 0; |
13337 | sqlite3_stmt *pStmt; |
13338 | int tnum = 0; |
13339 | int i; |
13340 | if (nArg != 3) { |
13341 | utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n" ); |
13342 | rc = 1; |
13343 | goto meta_command_exit; |
13344 | } |
13345 | open_db(p, 0); |
13346 | zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master" |
13347 | " WHERE name='%q' AND type='index'" , |
13348 | azArg[1]); |
13349 | sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
13350 | sqlite3_free(zSql); |
13351 | if (sqlite3_step(pStmt) == SQLITE_ROW) { |
13352 | tnum = sqlite3_column_int(pStmt, 0); |
13353 | } |
13354 | sqlite3_finalize(pStmt); |
13355 | if (tnum == 0) { |
13356 | utf8_printf(stderr, "no such index: \"%s\"\n" , azArg[1]); |
13357 | rc = 1; |
13358 | goto meta_command_exit; |
13359 | } |
13360 | zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'" , azArg[1]); |
13361 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
13362 | sqlite3_free(zSql); |
13363 | i = 0; |
13364 | while (sqlite3_step(pStmt) == SQLITE_ROW) { |
13365 | char zLabel[20]; |
13366 | const char *zCol = (const char *)sqlite3_column_text(pStmt, 2); |
13367 | i++; |
13368 | if (zCol == 0) { |
13369 | if (sqlite3_column_int(pStmt, 1) == -1) { |
13370 | zCol = "_ROWID_" ; |
13371 | } else { |
13372 | sqlite3_snprintf(sizeof(zLabel), zLabel, "expr%d" , i); |
13373 | zCol = zLabel; |
13374 | } |
13375 | } |
13376 | if (zCollist == 0) { |
13377 | zCollist = sqlite3_mprintf("\"%w\"" , zCol); |
13378 | } else { |
13379 | zCollist = sqlite3_mprintf("%z,\"%w\"" , zCollist, zCol); |
13380 | } |
13381 | } |
13382 | sqlite3_finalize(pStmt); |
13383 | zSql = sqlite3_mprintf("CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID" , azArg[2], zCollist, zCollist); |
13384 | sqlite3_free(zCollist); |
13385 | rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main" , 1, tnum); |
13386 | if (rc == SQLITE_OK) { |
13387 | rc = sqlite3_exec(p->db, zSql, 0, 0, 0); |
13388 | sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main" , 0, 0); |
13389 | if (rc) { |
13390 | utf8_printf(stderr, "Error in [%s]: %s\n" , zSql, sqlite3_errmsg(p->db)); |
13391 | } else { |
13392 | utf8_printf(stdout, "%s;\n" , zSql); |
13393 | raw_printf(stdout, "WARNING: writing to an imposter table will corrupt the index!\n" ); |
13394 | } |
13395 | } else { |
13396 | raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n" , rc); |
13397 | rc = 1; |
13398 | } |
13399 | sqlite3_free(zSql); |
13400 | } else |
13401 | #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ |
13402 | |
13403 | #ifdef SQLITE_ENABLE_IOTRACE |
13404 | if (c == 'i' && strncmp(azArg[0], "iotrace" , n) == 0) { |
13405 | SQLITE_API extern void(SQLITE_CDECL * sqlite3IoTrace)(const char *, ...); |
13406 | if (iotrace && iotrace != stdout) |
13407 | fclose(iotrace); |
13408 | iotrace = 0; |
13409 | if (nArg < 2) { |
13410 | sqlite3IoTrace = 0; |
13411 | } else if (strcmp(azArg[1], "-" ) == 0) { |
13412 | sqlite3IoTrace = iotracePrintf; |
13413 | iotrace = stdout; |
13414 | } else { |
13415 | iotrace = fopen(azArg[1], "w" ); |
13416 | if (iotrace == 0) { |
13417 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , azArg[1]); |
13418 | sqlite3IoTrace = 0; |
13419 | rc = 1; |
13420 | } else { |
13421 | sqlite3IoTrace = iotracePrintf; |
13422 | } |
13423 | } |
13424 | } else |
13425 | #endif |
13426 | |
13427 | if (c == 'l' && n >= 5 && strncmp(azArg[0], "limits" , n) == 0) { |
13428 | static const struct { |
13429 | const char *zLimitName; /* Name of a limit */ |
13430 | int limitCode; /* Integer code for that limit */ |
13431 | } aLimit[] = { |
13432 | {"length" , SQLITE_LIMIT_LENGTH}, |
13433 | {"sql_length" , SQLITE_LIMIT_SQL_LENGTH}, |
13434 | {"column" , SQLITE_LIMIT_COLUMN}, |
13435 | {"expr_depth" , SQLITE_LIMIT_EXPR_DEPTH}, |
13436 | {"compound_select" , SQLITE_LIMIT_COMPOUND_SELECT}, |
13437 | {"vdbe_op" , SQLITE_LIMIT_VDBE_OP}, |
13438 | {"function_arg" , SQLITE_LIMIT_FUNCTION_ARG}, |
13439 | {"attached" , SQLITE_LIMIT_ATTACHED}, |
13440 | {"like_pattern_length" , SQLITE_LIMIT_LIKE_PATTERN_LENGTH}, |
13441 | {"variable_number" , SQLITE_LIMIT_VARIABLE_NUMBER}, |
13442 | {"trigger_depth" , SQLITE_LIMIT_TRIGGER_DEPTH}, |
13443 | {"worker_threads" , SQLITE_LIMIT_WORKER_THREADS}, |
13444 | }; |
13445 | int i, n2; |
13446 | open_db(p, 0); |
13447 | if (nArg == 1) { |
13448 | for (i = 0; i < ArraySize(aLimit); i++) { |
13449 | printf("%20s %d\n" , aLimit[i].zLimitName, sqlite3_limit(p->db, aLimit[i].limitCode, -1)); |
13450 | } |
13451 | } else if (nArg > 3) { |
13452 | raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n" ); |
13453 | rc = 1; |
13454 | goto meta_command_exit; |
13455 | } else { |
13456 | int iLimit = -1; |
13457 | n2 = strlen30(azArg[1]); |
13458 | for (i = 0; i < ArraySize(aLimit); i++) { |
13459 | if (sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2) == 0) { |
13460 | if (iLimit < 0) { |
13461 | iLimit = i; |
13462 | } else { |
13463 | utf8_printf(stderr, "ambiguous limit: \"%s\"\n" , azArg[1]); |
13464 | rc = 1; |
13465 | goto meta_command_exit; |
13466 | } |
13467 | } |
13468 | } |
13469 | if (iLimit < 0) { |
13470 | utf8_printf(stderr, |
13471 | "unknown limit: \"%s\"\n" |
13472 | "enter \".limits\" with no arguments for a list.\n" , |
13473 | azArg[1]); |
13474 | rc = 1; |
13475 | goto meta_command_exit; |
13476 | } |
13477 | if (nArg == 3) { |
13478 | sqlite3_limit(p->db, aLimit[iLimit].limitCode, (int)integerValue(azArg[2])); |
13479 | } |
13480 | printf("%20s %d\n" , aLimit[iLimit].zLimitName, sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); |
13481 | } |
13482 | } else |
13483 | |
13484 | if (c == 'l' && n > 2 && strncmp(azArg[0], "lint" , n) == 0) { |
13485 | open_db(p, 0); |
13486 | lintDotCommand(p, azArg, nArg); |
13487 | } else |
13488 | |
13489 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
13490 | if (c == 'l' && strncmp(azArg[0], "load" , n) == 0) { |
13491 | const char *zFile, *zProc; |
13492 | char *zErrMsg = 0; |
13493 | if (nArg < 2) { |
13494 | raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n" ); |
13495 | rc = 1; |
13496 | goto meta_command_exit; |
13497 | } |
13498 | zFile = azArg[1]; |
13499 | zProc = nArg >= 3 ? azArg[2] : 0; |
13500 | open_db(p, 0); |
13501 | rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); |
13502 | if (rc != SQLITE_OK) { |
13503 | utf8_printf(stderr, "Error: %s\n" , zErrMsg); |
13504 | sqlite3_free(zErrMsg); |
13505 | rc = 1; |
13506 | } |
13507 | } else |
13508 | #endif |
13509 | |
13510 | if (c == 'l' && strncmp(azArg[0], "log" , n) == 0) { |
13511 | if (nArg != 2) { |
13512 | raw_printf(stderr, "Usage: .log FILENAME\n" ); |
13513 | rc = 1; |
13514 | } else { |
13515 | const char *zFile = azArg[1]; |
13516 | output_file_close(p->pLog); |
13517 | p->pLog = output_file_open(zFile, 0); |
13518 | } |
13519 | } else |
13520 | |
13521 | if (c == 'm' && strncmp(azArg[0], "mode" , n) == 0) { |
13522 | const char *zMode = nArg >= 2 ? azArg[1] : "" ; |
13523 | int n2 = strlen30(zMode); |
13524 | int c2 = zMode[0]; |
13525 | if (c2 == 'l' && n2 > 2 && strncmp(azArg[1], "lines" , n2) == 0) { |
13526 | p->mode = MODE_Line; |
13527 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
13528 | } else if (c2 == 'c' && strncmp(azArg[1], "columns" , n2) == 0) { |
13529 | p->mode = MODE_Column; |
13530 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
13531 | } else if (c2 == 'l' && n2 > 2 && strncmp(azArg[1], "list" , n2) == 0) { |
13532 | p->mode = MODE_List; |
13533 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column); |
13534 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
13535 | } else if (c2 == 'h' && strncmp(azArg[1], "html" , n2) == 0) { |
13536 | p->mode = MODE_Html; |
13537 | } else if (c2 == 't' && strncmp(azArg[1], "tcl" , n2) == 0) { |
13538 | p->mode = MODE_Tcl; |
13539 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); |
13540 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
13541 | } else if (c2 == 'c' && strncmp(azArg[1], "csv" , n2) == 0) { |
13542 | p->mode = MODE_Csv; |
13543 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); |
13544 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); |
13545 | } else if (c2 == 't' && strncmp(azArg[1], "tabs" , n2) == 0) { |
13546 | p->mode = MODE_List; |
13547 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); |
13548 | } else if (c2 == 'i' && strncmp(azArg[1], "insert" , n2) == 0) { |
13549 | p->mode = MODE_Insert; |
13550 | set_table_name(p, nArg >= 3 ? azArg[2] : "table" ); |
13551 | } else if (c2 == 'q' && strncmp(azArg[1], "quote" , n2) == 0) { |
13552 | p->mode = MODE_Quote; |
13553 | } else if (c2 == 'a' && strncmp(azArg[1], "ascii" , n2) == 0) { |
13554 | p->mode = MODE_Ascii; |
13555 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); |
13556 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); |
13557 | } else if (nArg == 1) { |
13558 | raw_printf(p->out, "current output mode: %s\n" , modeDescr[p->mode]); |
13559 | } else { |
13560 | raw_printf(stderr, "Error: mode should be one of: " |
13561 | "ascii column csv html insert line list quote tabs tcl\n" ); |
13562 | rc = 1; |
13563 | } |
13564 | p->cMode = p->mode; |
13565 | } else |
13566 | |
13567 | if (c == 'n' && strncmp(azArg[0], "nullvalue" , n) == 0) { |
13568 | if (nArg == 2) { |
13569 | sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, "%.*s" , (int)ArraySize(p->nullValue) - 1, azArg[1]); |
13570 | } else { |
13571 | raw_printf(stderr, "Usage: .nullvalue STRING\n" ); |
13572 | rc = 1; |
13573 | } |
13574 | } else |
13575 | |
13576 | if (c == 'o' && strncmp(azArg[0], "open" , n) == 0 && n >= 2) { |
13577 | char *zNewFilename; /* Name of the database file to open */ |
13578 | int iName = 1; /* Index in azArg[] of the filename */ |
13579 | int newFlag = 0; /* True to delete file before opening */ |
13580 | /* Close the existing database */ |
13581 | session_close_all(p); |
13582 | sqlite3_close(p->db); |
13583 | p->db = 0; |
13584 | p->zDbFilename = 0; |
13585 | sqlite3_free(p->zFreeOnClose); |
13586 | p->zFreeOnClose = 0; |
13587 | p->openMode = SHELL_OPEN_UNSPEC; |
13588 | /* Check for command-line arguments */ |
13589 | for (iName = 1; iName < nArg && azArg[iName][0] == '-'; iName++) { |
13590 | const char *z = azArg[iName]; |
13591 | if (optionMatch(z, "new" )) { |
13592 | newFlag = 1; |
13593 | #ifdef SQLITE_HAVE_ZLIB |
13594 | } else if (optionMatch(z, "zip" )) { |
13595 | p->openMode = SHELL_OPEN_ZIPFILE; |
13596 | #endif |
13597 | } else if (optionMatch(z, "append" )) { |
13598 | p->openMode = SHELL_OPEN_APPENDVFS; |
13599 | } else if (optionMatch(z, "readonly" )) { |
13600 | p->openMode = SHELL_OPEN_READONLY; |
13601 | } else if (z[0] == '-') { |
13602 | utf8_printf(stderr, "unknown option: %s\n" , z); |
13603 | rc = 1; |
13604 | goto meta_command_exit; |
13605 | } |
13606 | } |
13607 | /* If a filename is specified, try to open it first */ |
13608 | zNewFilename = nArg > iName ? sqlite3_mprintf("%s" , azArg[iName]) : 0; |
13609 | if (zNewFilename) { |
13610 | if (newFlag) |
13611 | shellDeleteFile(zNewFilename); |
13612 | p->zDbFilename = zNewFilename; |
13613 | open_db(p, 1); |
13614 | if (p->db == 0) { |
13615 | utf8_printf(stderr, "Error: cannot open '%s'\n" , zNewFilename); |
13616 | sqlite3_free(zNewFilename); |
13617 | } else { |
13618 | p->zFreeOnClose = zNewFilename; |
13619 | } |
13620 | } |
13621 | if (p->db == 0) { |
13622 | /* As a fall-back open a TEMP database */ |
13623 | p->zDbFilename = 0; |
13624 | open_db(p, 0); |
13625 | } |
13626 | } else |
13627 | |
13628 | if ((c == 'o' && (strncmp(azArg[0], "output" , n) == 0 || strncmp(azArg[0], "once" , n) == 0)) || |
13629 | (c == 'e' && n == 5 && strcmp(azArg[0], "excel" ) == 0)) { |
13630 | const char *zFile = nArg >= 2 ? azArg[1] : "stdout" ; |
13631 | int bTxtMode = 0; |
13632 | if (azArg[0][0] == 'e') { |
13633 | /* Transform the ".excel" command into ".once -x" */ |
13634 | nArg = 2; |
13635 | azArg[0] = "once" ; |
13636 | zFile = azArg[1] = "-x" ; |
13637 | n = 4; |
13638 | } |
13639 | if (nArg > 2) { |
13640 | utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n" , azArg[0]); |
13641 | rc = 1; |
13642 | goto meta_command_exit; |
13643 | } |
13644 | if (n > 1 && strncmp(azArg[0], "once" , n) == 0) { |
13645 | if (nArg < 2) { |
13646 | raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n" ); |
13647 | rc = 1; |
13648 | goto meta_command_exit; |
13649 | } |
13650 | p->outCount = 2; |
13651 | } else { |
13652 | p->outCount = 0; |
13653 | } |
13654 | output_reset(p); |
13655 | if (zFile[0] == '-' && zFile[1] == '-') |
13656 | zFile++; |
13657 | #ifndef SQLITE_NOHAVE_SYSTEM |
13658 | if (strcmp(zFile, "-e" ) == 0 || strcmp(zFile, "-x" ) == 0) { |
13659 | p->doXdgOpen = 1; |
13660 | outputModePush(p); |
13661 | if (zFile[1] == 'x') { |
13662 | newTempFile(p, "csv" ); |
13663 | p->mode = MODE_Csv; |
13664 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); |
13665 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); |
13666 | } else { |
13667 | newTempFile(p, "txt" ); |
13668 | bTxtMode = 1; |
13669 | } |
13670 | zFile = p->zTempFile; |
13671 | } |
13672 | #endif /* SQLITE_NOHAVE_SYSTEM */ |
13673 | if (zFile[0] == '|') { |
13674 | #ifdef SQLITE_OMIT_POPEN |
13675 | raw_printf(stderr, "Error: pipes are not supported in this OS\n" ); |
13676 | rc = 1; |
13677 | p->out = stdout; |
13678 | #else |
13679 | p->out = popen(zFile + 1, "w" ); |
13680 | if (p->out == 0) { |
13681 | utf8_printf(stderr, "Error: cannot open pipe \"%s\"\n" , zFile + 1); |
13682 | p->out = stdout; |
13683 | rc = 1; |
13684 | } else { |
13685 | sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s" , zFile); |
13686 | } |
13687 | #endif |
13688 | } else { |
13689 | p->out = output_file_open(zFile, bTxtMode); |
13690 | if (p->out == 0) { |
13691 | if (strcmp(zFile, "off" ) != 0) { |
13692 | utf8_printf(stderr, "Error: cannot write to \"%s\"\n" , zFile); |
13693 | } |
13694 | p->out = stdout; |
13695 | rc = 1; |
13696 | } else { |
13697 | sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s" , zFile); |
13698 | } |
13699 | } |
13700 | } else |
13701 | |
13702 | if (c == 'p' && n >= 3 && strncmp(azArg[0], "print" , n) == 0) { |
13703 | int i; |
13704 | for (i = 1; i < nArg; i++) { |
13705 | if (i > 1) |
13706 | raw_printf(p->out, " " ); |
13707 | utf8_printf(p->out, "%s" , azArg[i]); |
13708 | } |
13709 | raw_printf(p->out, "\n" ); |
13710 | } else |
13711 | |
13712 | if (c == 'p' && strncmp(azArg[0], "prompt" , n) == 0) { |
13713 | if (nArg >= 2) { |
13714 | strncpy(mainPrompt, azArg[1], (int)ArraySize(mainPrompt) - 1); |
13715 | } |
13716 | if (nArg >= 3) { |
13717 | strncpy(continuePrompt, azArg[2], (int)ArraySize(continuePrompt) - 1); |
13718 | } |
13719 | } else |
13720 | |
13721 | if (c == 'q' && strncmp(azArg[0], "quit" , n) == 0) { |
13722 | rc = 2; |
13723 | } else |
13724 | |
13725 | if (c == 'r' && n >= 3 && strncmp(azArg[0], "read" , n) == 0) { |
13726 | FILE *alt; |
13727 | if (nArg != 2) { |
13728 | raw_printf(stderr, "Usage: .read FILE\n" ); |
13729 | rc = 1; |
13730 | goto meta_command_exit; |
13731 | } |
13732 | alt = fopen(azArg[1], "rb" ); |
13733 | if (alt == 0) { |
13734 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , azArg[1]); |
13735 | rc = 1; |
13736 | } else { |
13737 | rc = process_input(p, alt); |
13738 | fclose(alt); |
13739 | } |
13740 | } else |
13741 | |
13742 | if (c == 'r' && n >= 3 && strncmp(azArg[0], "restore" , n) == 0) { |
13743 | const char *zSrcFile; |
13744 | const char *zDb; |
13745 | sqlite3 *pSrc; |
13746 | sqlite3_backup *pBackup; |
13747 | int nTimeout = 0; |
13748 | |
13749 | if (nArg == 2) { |
13750 | zSrcFile = azArg[1]; |
13751 | zDb = "main" ; |
13752 | } else if (nArg == 3) { |
13753 | zSrcFile = azArg[2]; |
13754 | zDb = azArg[1]; |
13755 | } else { |
13756 | raw_printf(stderr, "Usage: .restore ?DB? FILE\n" ); |
13757 | rc = 1; |
13758 | goto meta_command_exit; |
13759 | } |
13760 | rc = sqlite3_open(zSrcFile, &pSrc); |
13761 | if (rc != SQLITE_OK) { |
13762 | utf8_printf(stderr, "Error: cannot open \"%s\"\n" , zSrcFile); |
13763 | sqlite3_close(pSrc); |
13764 | return 1; |
13765 | } |
13766 | open_db(p, 0); |
13767 | pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main" ); |
13768 | if (pBackup == 0) { |
13769 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
13770 | sqlite3_close(pSrc); |
13771 | return 1; |
13772 | } |
13773 | while ((rc = sqlite3_backup_step(pBackup, 100)) == SQLITE_OK || rc == SQLITE_BUSY) { |
13774 | if (rc == SQLITE_BUSY) { |
13775 | if (nTimeout++ >= 3) |
13776 | break; |
13777 | sqlite3_sleep(100); |
13778 | } |
13779 | } |
13780 | sqlite3_backup_finish(pBackup); |
13781 | if (rc == SQLITE_DONE) { |
13782 | rc = 0; |
13783 | } else if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { |
13784 | raw_printf(stderr, "Error: source database is busy\n" ); |
13785 | rc = 1; |
13786 | } else { |
13787 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
13788 | rc = 1; |
13789 | } |
13790 | sqlite3_close(pSrc); |
13791 | } else |
13792 | |
13793 | if (c == 's' && strncmp(azArg[0], "scanstats" , n) == 0) { |
13794 | if (nArg == 2) { |
13795 | p->scanstatsOn = (u8)booleanValue(azArg[1]); |
13796 | #ifndef SQLITE_ENABLE_STMT_SCANSTATUS |
13797 | raw_printf(stderr, "Warning: .scanstats not available in this build.\n" ); |
13798 | #endif |
13799 | } else { |
13800 | raw_printf(stderr, "Usage: .scanstats on|off\n" ); |
13801 | rc = 1; |
13802 | } |
13803 | } else |
13804 | |
13805 | if (c == 's' && strncmp(azArg[0], "schema" , n) == 0) { |
13806 | ShellText sSelect; |
13807 | ShellState data; |
13808 | char *zErrMsg = 0; |
13809 | const char *zDiv = "(" ; |
13810 | const char *zName = 0; |
13811 | int iSchema = 0; |
13812 | int bDebug = 0; |
13813 | int ii; |
13814 | |
13815 | open_db(p, 0); |
13816 | memcpy(&data, p, sizeof(data)); |
13817 | data.showHeader = 0; |
13818 | data.cMode = data.mode = MODE_Semi; |
13819 | initText(&sSelect); |
13820 | for (ii = 1; ii < nArg; ii++) { |
13821 | if (optionMatch(azArg[ii], "indent" )) { |
13822 | data.cMode = data.mode = MODE_Pretty; |
13823 | } else if (optionMatch(azArg[ii], "debug" )) { |
13824 | bDebug = 1; |
13825 | } else if (zName == 0) { |
13826 | zName = azArg[ii]; |
13827 | } else { |
13828 | raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n" ); |
13829 | rc = 1; |
13830 | goto meta_command_exit; |
13831 | } |
13832 | } |
13833 | if (zName != 0) { |
13834 | int isMaster = sqlite3_strlike(zName, "sqlite_master" , '\\') == 0; |
13835 | if (isMaster || sqlite3_strlike(zName, "sqlite_temp_master" , '\\') == 0) { |
13836 | char *new_argv[2], *new_colv[2]; |
13837 | new_argv[0] = sqlite3_mprintf("CREATE TABLE %s (\n" |
13838 | " type text,\n" |
13839 | " name text,\n" |
13840 | " tbl_name text,\n" |
13841 | " rootpage integer,\n" |
13842 | " sql text\n" |
13843 | ")" , |
13844 | isMaster ? "sqlite_master" : "sqlite_temp_master" ); |
13845 | new_argv[1] = 0; |
13846 | new_colv[0] = "sql" ; |
13847 | new_colv[1] = 0; |
13848 | callback(&data, 1, new_argv, new_colv); |
13849 | sqlite3_free(new_argv[0]); |
13850 | } |
13851 | } |
13852 | if (zDiv) { |
13853 | sqlite3_stmt *pStmt = 0; |
13854 | rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list" , -1, &pStmt, 0); |
13855 | if (rc) { |
13856 | utf8_printf(stderr, "Error: %s\n" , sqlite3_errmsg(p->db)); |
13857 | sqlite3_finalize(pStmt); |
13858 | rc = 1; |
13859 | goto meta_command_exit; |
13860 | } |
13861 | appendText(&sSelect, "SELECT sql FROM" , 0); |
13862 | iSchema = 0; |
13863 | while (sqlite3_step(pStmt) == SQLITE_ROW) { |
13864 | const char *zDb = (const char *)sqlite3_column_text(pStmt, 0); |
13865 | char zScNum[30]; |
13866 | sqlite3_snprintf(sizeof(zScNum), zScNum, "%d" , ++iSchema); |
13867 | appendText(&sSelect, zDiv, 0); |
13868 | zDiv = " UNION ALL " ; |
13869 | appendText(&sSelect, "SELECT shell_add_schema(sql," , 0); |
13870 | if (sqlite3_stricmp(zDb, "main" ) != 0) { |
13871 | appendText(&sSelect, zDb, '"'); |
13872 | } else { |
13873 | appendText(&sSelect, "NULL" , 0); |
13874 | } |
13875 | appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid," , 0); |
13876 | appendText(&sSelect, zScNum, 0); |
13877 | appendText(&sSelect, " AS snum, " , 0); |
13878 | appendText(&sSelect, zDb, '\''); |
13879 | appendText(&sSelect, " AS sname FROM " , 0); |
13880 | appendText(&sSelect, zDb, '"'); |
13881 | appendText(&sSelect, ".sqlite_master" , 0); |
13882 | } |
13883 | sqlite3_finalize(pStmt); |
13884 | #ifdef SQLITE_INTROSPECTION_PRAGMAS |
13885 | if (zName) { |
13886 | appendText(&sSelect, |
13887 | " UNION ALL SELECT shell_module_schema(name)," |
13888 | " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list" , |
13889 | 0); |
13890 | } |
13891 | #endif |
13892 | appendText(&sSelect, ") WHERE " , 0); |
13893 | if (zName) { |
13894 | char *zQarg = sqlite3_mprintf("%Q" , zName); |
13895 | int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 || strchr(zName, '[') != 0; |
13896 | if (strchr(zName, '.')) { |
13897 | appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))" , 0); |
13898 | } else { |
13899 | appendText(&sSelect, "lower(tbl_name)" , 0); |
13900 | } |
13901 | appendText(&sSelect, bGlob ? " GLOB " : " LIKE " , 0); |
13902 | appendText(&sSelect, zQarg, 0); |
13903 | if (!bGlob) { |
13904 | appendText(&sSelect, " ESCAPE '\\' " , 0); |
13905 | } |
13906 | appendText(&sSelect, " AND " , 0); |
13907 | sqlite3_free(zQarg); |
13908 | } |
13909 | appendText(&sSelect, |
13910 | "type!='meta' AND sql IS NOT NULL" |
13911 | " ORDER BY snum, rowid" , |
13912 | 0); |
13913 | if (bDebug) { |
13914 | utf8_printf(p->out, "SQL: %s;\n" , sSelect.z); |
13915 | } else { |
13916 | rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); |
13917 | } |
13918 | freeText(&sSelect); |
13919 | } |
13920 | if (zErrMsg) { |
13921 | utf8_printf(stderr, "Error: %s\n" , zErrMsg); |
13922 | sqlite3_free(zErrMsg); |
13923 | rc = 1; |
13924 | } else if (rc != SQLITE_OK) { |
13925 | raw_printf(stderr, "Error: querying schema information\n" ); |
13926 | rc = 1; |
13927 | } else { |
13928 | rc = 0; |
13929 | } |
13930 | } else |
13931 | |
13932 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) |
13933 | if (c == 's' && n == 11 && strncmp(azArg[0], "selecttrace" , n) == 0) { |
13934 | sqlite3SelectTrace = (int)integerValue(azArg[1]); |
13935 | } else |
13936 | #endif |
13937 | |
13938 | #if defined(SQLITE_ENABLE_SESSION) |
13939 | if (c == 's' && strncmp(azArg[0], "session" , n) == 0 && n >= 3) { |
13940 | OpenSession *pSession = &p->aSession[0]; |
13941 | char **azCmd = &azArg[1]; |
13942 | int iSes = 0; |
13943 | int nCmd = nArg - 1; |
13944 | int i; |
13945 | if (nArg <= 1) |
13946 | goto session_syntax_error; |
13947 | open_db(p, 0); |
13948 | if (nArg >= 3) { |
13949 | for (iSes = 0; iSes < p->nSession; iSes++) { |
13950 | if (strcmp(p->aSession[iSes].zName, azArg[1]) == 0) |
13951 | break; |
13952 | } |
13953 | if (iSes < p->nSession) { |
13954 | pSession = &p->aSession[iSes]; |
13955 | azCmd++; |
13956 | nCmd--; |
13957 | } else { |
13958 | pSession = &p->aSession[0]; |
13959 | iSes = 0; |
13960 | } |
13961 | } |
13962 | |
13963 | /* .session attach TABLE |
13964 | ** Invoke the sqlite3session_attach() interface to attach a particular |
13965 | ** table so that it is never filtered. |
13966 | */ |
13967 | if (strcmp(azCmd[0], "attach" ) == 0) { |
13968 | if (nCmd != 2) |
13969 | goto session_syntax_error; |
13970 | if (pSession->p == 0) { |
13971 | session_not_open: |
13972 | raw_printf(stderr, "ERROR: No sessions are open\n" ); |
13973 | } else { |
13974 | rc = sqlite3session_attach(pSession->p, azCmd[1]); |
13975 | if (rc) { |
13976 | raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n" , rc); |
13977 | rc = 0; |
13978 | } |
13979 | } |
13980 | } else |
13981 | |
13982 | /* .session changeset FILE |
13983 | ** .session patchset FILE |
13984 | ** Write a changeset or patchset into a file. The file is overwritten. |
13985 | */ |
13986 | if (strcmp(azCmd[0], "changeset" ) == 0 || strcmp(azCmd[0], "patchset" ) == 0) { |
13987 | FILE *out = 0; |
13988 | if (nCmd != 2) |
13989 | goto session_syntax_error; |
13990 | if (pSession->p == 0) |
13991 | goto session_not_open; |
13992 | out = fopen(azCmd[1], "wb" ); |
13993 | if (out == 0) { |
13994 | utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n" , azCmd[1]); |
13995 | } else { |
13996 | int szChng; |
13997 | void *pChng; |
13998 | if (azCmd[0][0] == 'c') { |
13999 | rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); |
14000 | } else { |
14001 | rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); |
14002 | } |
14003 | if (rc) { |
14004 | printf("Error: error code %d\n" , rc); |
14005 | rc = 0; |
14006 | } |
14007 | if (pChng && fwrite(pChng, szChng, 1, out) != 1) { |
14008 | raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n" , szChng); |
14009 | } |
14010 | sqlite3_free(pChng); |
14011 | fclose(out); |
14012 | } |
14013 | } else |
14014 | |
14015 | /* .session close |
14016 | ** Close the identified session |
14017 | */ |
14018 | if (strcmp(azCmd[0], "close" ) == 0) { |
14019 | if (nCmd != 1) |
14020 | goto session_syntax_error; |
14021 | if (p->nSession) { |
14022 | session_close(pSession); |
14023 | p->aSession[iSes] = p->aSession[--p->nSession]; |
14024 | } |
14025 | } else |
14026 | |
14027 | /* .session enable ?BOOLEAN? |
14028 | ** Query or set the enable flag |
14029 | */ |
14030 | if (strcmp(azCmd[0], "enable" ) == 0) { |
14031 | int ii; |
14032 | if (nCmd > 2) |
14033 | goto session_syntax_error; |
14034 | ii = nCmd == 1 ? -1 : booleanValue(azCmd[1]); |
14035 | if (p->nSession) { |
14036 | ii = sqlite3session_enable(pSession->p, ii); |
14037 | utf8_printf(p->out, "session %s enable flag = %d\n" , pSession->zName, ii); |
14038 | } |
14039 | } else |
14040 | |
14041 | /* .session filter GLOB .... |
14042 | ** Set a list of GLOB patterns of table names to be excluded. |
14043 | */ |
14044 | if (strcmp(azCmd[0], "filter" ) == 0) { |
14045 | int ii, nByte; |
14046 | if (nCmd < 2) |
14047 | goto session_syntax_error; |
14048 | if (p->nSession) { |
14049 | for (ii = 0; ii < pSession->nFilter; ii++) { |
14050 | sqlite3_free(pSession->azFilter[ii]); |
14051 | } |
14052 | sqlite3_free(pSession->azFilter); |
14053 | nByte = sizeof(pSession->azFilter[0]) * (nCmd - 1); |
14054 | pSession->azFilter = sqlite3_malloc(nByte); |
14055 | if (pSession->azFilter == 0) { |
14056 | raw_printf(stderr, "Error: out or memory\n" ); |
14057 | exit(1); |
14058 | } |
14059 | for (ii = 1; ii < nCmd; ii++) { |
14060 | pSession->azFilter[ii - 1] = sqlite3_mprintf("%s" , azCmd[ii]); |
14061 | } |
14062 | pSession->nFilter = ii - 1; |
14063 | } |
14064 | } else |
14065 | |
14066 | /* .session indirect ?BOOLEAN? |
14067 | ** Query or set the indirect flag |
14068 | */ |
14069 | if (strcmp(azCmd[0], "indirect" ) == 0) { |
14070 | int ii; |
14071 | if (nCmd > 2) |
14072 | goto session_syntax_error; |
14073 | ii = nCmd == 1 ? -1 : booleanValue(azCmd[1]); |
14074 | if (p->nSession) { |
14075 | ii = sqlite3session_indirect(pSession->p, ii); |
14076 | utf8_printf(p->out, "session %s indirect flag = %d\n" , pSession->zName, ii); |
14077 | } |
14078 | } else |
14079 | |
14080 | /* .session isempty |
14081 | ** Determine if the session is empty |
14082 | */ |
14083 | if (strcmp(azCmd[0], "isempty" ) == 0) { |
14084 | int ii; |
14085 | if (nCmd != 1) |
14086 | goto session_syntax_error; |
14087 | if (p->nSession) { |
14088 | ii = sqlite3session_isempty(pSession->p); |
14089 | utf8_printf(p->out, "session %s isempty flag = %d\n" , pSession->zName, ii); |
14090 | } |
14091 | } else |
14092 | |
14093 | /* .session list |
14094 | ** List all currently open sessions |
14095 | */ |
14096 | if (strcmp(azCmd[0], "list" ) == 0) { |
14097 | for (i = 0; i < p->nSession; i++) { |
14098 | utf8_printf(p->out, "%d %s\n" , i, p->aSession[i].zName); |
14099 | } |
14100 | } else |
14101 | |
14102 | /* .session open DB NAME |
14103 | ** Open a new session called NAME on the attached database DB. |
14104 | ** DB is normally "main". |
14105 | */ |
14106 | if (strcmp(azCmd[0], "open" ) == 0) { |
14107 | char *zName; |
14108 | if (nCmd != 3) |
14109 | goto session_syntax_error; |
14110 | zName = azCmd[2]; |
14111 | if (zName[0] == 0) |
14112 | goto session_syntax_error; |
14113 | for (i = 0; i < p->nSession; i++) { |
14114 | if (strcmp(p->aSession[i].zName, zName) == 0) { |
14115 | utf8_printf(stderr, "Session \"%s\" already exists\n" , zName); |
14116 | goto meta_command_exit; |
14117 | } |
14118 | } |
14119 | if (p->nSession >= ArraySize(p->aSession)) { |
14120 | raw_printf(stderr, "Maximum of %d sessions\n" , ArraySize(p->aSession)); |
14121 | goto meta_command_exit; |
14122 | } |
14123 | pSession = &p->aSession[p->nSession]; |
14124 | rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); |
14125 | if (rc) { |
14126 | raw_printf(stderr, "Cannot open session: error code=%d\n" , rc); |
14127 | rc = 0; |
14128 | goto meta_command_exit; |
14129 | } |
14130 | pSession->nFilter = 0; |
14131 | sqlite3session_table_filter(pSession->p, session_filter, pSession); |
14132 | p->nSession++; |
14133 | pSession->zName = sqlite3_mprintf("%s" , zName); |
14134 | } else |
14135 | /* If no command name matches, show a syntax error */ |
14136 | session_syntax_error: |
14137 | session_help(p); |
14138 | } else |
14139 | #endif |
14140 | |
14141 | #ifdef SQLITE_DEBUG |
14142 | /* Undocumented commands for internal testing. Subject to change |
14143 | ** without notice. */ |
14144 | if (c == 's' && n >= 10 && strncmp(azArg[0], "selftest-" , 9) == 0) { |
14145 | if (strncmp(azArg[0] + 9, "boolean" , n - 9) == 0) { |
14146 | int i, v; |
14147 | for (i = 1; i < nArg; i++) { |
14148 | v = booleanValue(azArg[i]); |
14149 | utf8_printf(p->out, "%s: %d 0x%x\n" , azArg[i], v, v); |
14150 | } |
14151 | } |
14152 | if (strncmp(azArg[0] + 9, "integer" , n - 9) == 0) { |
14153 | int i; |
14154 | sqlite3_int64 v; |
14155 | for (i = 1; i < nArg; i++) { |
14156 | char zBuf[200]; |
14157 | v = integerValue(azArg[i]); |
14158 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n" , azArg[i], v, v); |
14159 | utf8_printf(p->out, "%s" , zBuf); |
14160 | } |
14161 | } |
14162 | } else |
14163 | #endif |
14164 | |
14165 | if (c == 's' && n >= 4 && strncmp(azArg[0], "selftest" , n) == 0) { |
14166 | int bIsInit = 0; /* True to initialize the SELFTEST table */ |
14167 | int bVerbose = 0; /* Verbose output */ |
14168 | int bSelftestExists; /* True if SELFTEST already exists */ |
14169 | int i, k; /* Loop counters */ |
14170 | int nTest = 0; /* Number of tests runs */ |
14171 | int nErr = 0; /* Number of errors seen */ |
14172 | ShellText str; /* Answer for a query */ |
14173 | sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */ |
14174 | |
14175 | open_db(p, 0); |
14176 | for (i = 1; i < nArg; i++) { |
14177 | const char *z = azArg[i]; |
14178 | if (z[0] == '-' && z[1] == '-') |
14179 | z++; |
14180 | if (strcmp(z, "-init" ) == 0) { |
14181 | bIsInit = 1; |
14182 | } else if (strcmp(z, "-v" ) == 0) { |
14183 | bVerbose++; |
14184 | } else { |
14185 | utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n" , azArg[i], azArg[0]); |
14186 | raw_printf(stderr, "Should be one of: --init -v\n" ); |
14187 | rc = 1; |
14188 | goto meta_command_exit; |
14189 | } |
14190 | } |
14191 | if (sqlite3_table_column_metadata(p->db, "main" , "selftest" , 0, 0, 0, 0, 0, 0) != SQLITE_OK) { |
14192 | bSelftestExists = 0; |
14193 | } else { |
14194 | bSelftestExists = 1; |
14195 | } |
14196 | if (bIsInit) { |
14197 | createSelftestTable(p); |
14198 | bSelftestExists = 1; |
14199 | } |
14200 | initText(&str); |
14201 | appendText(&str, "x" , 0); |
14202 | for (k = bSelftestExists; k >= 0; k--) { |
14203 | if (k == 1) { |
14204 | rc = sqlite3_prepare_v2(p->db, "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno" , -1, &pStmt, 0); |
14205 | } else { |
14206 | rc = sqlite3_prepare_v2(p->db, |
14207 | "VALUES(0,'memo','Missing SELFTEST table - default checks only','')," |
14208 | " (1,'run','PRAGMA integrity_check','ok')" , |
14209 | -1, &pStmt, 0); |
14210 | } |
14211 | if (rc) { |
14212 | raw_printf(stderr, "Error querying the selftest table\n" ); |
14213 | rc = 1; |
14214 | sqlite3_finalize(pStmt); |
14215 | goto meta_command_exit; |
14216 | } |
14217 | for (i = 1; sqlite3_step(pStmt) == SQLITE_ROW; i++) { |
14218 | int tno = sqlite3_column_int(pStmt, 0); |
14219 | const char *zOp = (const char *)sqlite3_column_text(pStmt, 1); |
14220 | const char *zSql = (const char *)sqlite3_column_text(pStmt, 2); |
14221 | const char *zAns = (const char *)sqlite3_column_text(pStmt, 3); |
14222 | |
14223 | k = 0; |
14224 | if (bVerbose > 0) { |
14225 | char *zQuote = sqlite3_mprintf("%q" , zSql); |
14226 | printf("%d: %s %s\n" , tno, zOp, zSql); |
14227 | sqlite3_free(zQuote); |
14228 | } |
14229 | if (strcmp(zOp, "memo" ) == 0) { |
14230 | utf8_printf(p->out, "%s\n" , zSql); |
14231 | } else if (strcmp(zOp, "run" ) == 0) { |
14232 | char *zErrMsg = 0; |
14233 | str.n = 0; |
14234 | str.z[0] = 0; |
14235 | rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); |
14236 | nTest++; |
14237 | if (bVerbose) { |
14238 | utf8_printf(p->out, "Result: %s\n" , str.z); |
14239 | } |
14240 | if (rc || zErrMsg) { |
14241 | nErr++; |
14242 | rc = 1; |
14243 | utf8_printf(p->out, "%d: error-code-%d: %s\n" , tno, rc, zErrMsg); |
14244 | sqlite3_free(zErrMsg); |
14245 | } else if (strcmp(zAns, str.z) != 0) { |
14246 | nErr++; |
14247 | rc = 1; |
14248 | utf8_printf(p->out, "%d: Expected: [%s]\n" , tno, zAns); |
14249 | utf8_printf(p->out, "%d: Got: [%s]\n" , tno, str.z); |
14250 | } |
14251 | } else { |
14252 | utf8_printf(stderr, "Unknown operation \"%s\" on selftest line %d\n" , zOp, tno); |
14253 | rc = 1; |
14254 | break; |
14255 | } |
14256 | } /* End loop over rows of content from SELFTEST */ |
14257 | sqlite3_finalize(pStmt); |
14258 | } /* End loop over k */ |
14259 | freeText(&str); |
14260 | utf8_printf(p->out, "%d errors out of %d tests\n" , nErr, nTest); |
14261 | } else |
14262 | |
14263 | if (c == 's' && strncmp(azArg[0], "separator" , n) == 0) { |
14264 | if (nArg < 2 || nArg > 3) { |
14265 | raw_printf(stderr, "Usage: .separator COL ?ROW?\n" ); |
14266 | rc = 1; |
14267 | } |
14268 | if (nArg >= 2) { |
14269 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, "%.*s" , (int)ArraySize(p->colSeparator) - 1, |
14270 | azArg[1]); |
14271 | } |
14272 | if (nArg >= 3) { |
14273 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, "%.*s" , (int)ArraySize(p->rowSeparator) - 1, |
14274 | azArg[2]); |
14275 | } |
14276 | } else |
14277 | |
14278 | if (c == 's' && n >= 4 && strncmp(azArg[0], "sha3sum" , n) == 0) { |
14279 | const char *zLike = 0; /* Which table to checksum. 0 means everything */ |
14280 | int i; /* Loop counter */ |
14281 | int bSchema = 0; /* Also hash the schema */ |
14282 | int bSeparate = 0; /* Hash each table separately */ |
14283 | int iSize = 224; /* Hash algorithm to use */ |
14284 | int bDebug = 0; /* Only show the query that would have run */ |
14285 | sqlite3_stmt *pStmt; /* For querying tables names */ |
14286 | char *zSql; /* SQL to be run */ |
14287 | char *zSep; /* Separator */ |
14288 | ShellText sSql; /* Complete SQL for the query to run the hash */ |
14289 | ShellText sQuery; /* Set of queries used to read all content */ |
14290 | open_db(p, 0); |
14291 | for (i = 1; i < nArg; i++) { |
14292 | const char *z = azArg[i]; |
14293 | if (z[0] == '-') { |
14294 | z++; |
14295 | if (z[0] == '-') |
14296 | z++; |
14297 | if (strcmp(z, "schema" ) == 0) { |
14298 | bSchema = 1; |
14299 | } else if (strcmp(z, "sha3-224" ) == 0 || strcmp(z, "sha3-256" ) == 0 || strcmp(z, "sha3-384" ) == 0 || |
14300 | strcmp(z, "sha3-512" ) == 0) { |
14301 | iSize = atoi(&z[5]); |
14302 | } else if (strcmp(z, "debug" ) == 0) { |
14303 | bDebug = 1; |
14304 | } else { |
14305 | utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n" , azArg[i], azArg[0]); |
14306 | raw_printf(stderr, "Should be one of: --schema" |
14307 | " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n" ); |
14308 | rc = 1; |
14309 | goto meta_command_exit; |
14310 | } |
14311 | } else if (zLike) { |
14312 | raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n" ); |
14313 | rc = 1; |
14314 | goto meta_command_exit; |
14315 | } else { |
14316 | zLike = z; |
14317 | bSeparate = 1; |
14318 | if (sqlite3_strlike("sqlite\\_%" , zLike, '\\') == 0) |
14319 | bSchema = 1; |
14320 | } |
14321 | } |
14322 | if (bSchema) { |
14323 | zSql = "SELECT lower(name) FROM sqlite_master" |
14324 | " WHERE type='table' AND coalesce(rootpage,0)>1" |
14325 | " UNION ALL SELECT 'sqlite_master'" |
14326 | " ORDER BY 1 collate nocase" ; |
14327 | } else { |
14328 | zSql = "SELECT lower(name) FROM sqlite_master" |
14329 | " WHERE type='table' AND coalesce(rootpage,0)>1" |
14330 | " AND name NOT LIKE 'sqlite_%'" |
14331 | " ORDER BY 1 collate nocase" ; |
14332 | } |
14333 | sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
14334 | initText(&sQuery); |
14335 | initText(&sSql); |
14336 | appendText(&sSql, "WITH [sha3sum$query](a,b) AS(" , 0); |
14337 | zSep = "VALUES(" ; |
14338 | while (SQLITE_ROW == sqlite3_step(pStmt)) { |
14339 | const char *zTab = (const char *)sqlite3_column_text(pStmt, 0); |
14340 | if (zLike && sqlite3_strlike(zLike, zTab, 0) != 0) |
14341 | continue; |
14342 | if (strncmp(zTab, "sqlite_" , 7) != 0) { |
14343 | appendText(&sQuery, "SELECT * FROM " , 0); |
14344 | appendText(&sQuery, zTab, '"'); |
14345 | appendText(&sQuery, " NOT INDEXED;" , 0); |
14346 | } else if (strcmp(zTab, "sqlite_master" ) == 0) { |
14347 | appendText(&sQuery, |
14348 | "SELECT type,name,tbl_name,sql FROM sqlite_master" |
14349 | " ORDER BY name;" , |
14350 | 0); |
14351 | } else if (strcmp(zTab, "sqlite_sequence" ) == 0) { |
14352 | appendText(&sQuery, |
14353 | "SELECT name,seq FROM sqlite_sequence" |
14354 | " ORDER BY name;" , |
14355 | 0); |
14356 | } else if (strcmp(zTab, "sqlite_stat1" ) == 0) { |
14357 | appendText(&sQuery, |
14358 | "SELECT tbl,idx,stat FROM sqlite_stat1" |
14359 | " ORDER BY tbl,idx;" , |
14360 | 0); |
14361 | } else if (strcmp(zTab, "sqlite_stat3" ) == 0 || strcmp(zTab, "sqlite_stat4" ) == 0) { |
14362 | appendText(&sQuery, "SELECT * FROM " , 0); |
14363 | appendText(&sQuery, zTab, 0); |
14364 | appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n" , 0); |
14365 | } |
14366 | appendText(&sSql, zSep, 0); |
14367 | appendText(&sSql, sQuery.z, '\''); |
14368 | sQuery.n = 0; |
14369 | appendText(&sSql, "," , 0); |
14370 | appendText(&sSql, zTab, '\''); |
14371 | zSep = "),(" ; |
14372 | } |
14373 | sqlite3_finalize(pStmt); |
14374 | if (bSeparate) { |
14375 | zSql = sqlite3_mprintf("%s))" |
14376 | " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" |
14377 | " FROM [sha3sum$query]" , |
14378 | sSql.z, iSize); |
14379 | } else { |
14380 | zSql = sqlite3_mprintf("%s))" |
14381 | " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" |
14382 | " FROM [sha3sum$query]" , |
14383 | sSql.z, iSize); |
14384 | } |
14385 | freeText(&sQuery); |
14386 | freeText(&sSql); |
14387 | if (bDebug) { |
14388 | utf8_printf(p->out, "%s\n" , zSql); |
14389 | } else { |
14390 | shell_exec(p, zSql, 0); |
14391 | } |
14392 | sqlite3_free(zSql); |
14393 | } else |
14394 | |
14395 | #ifndef SQLITE_NOHAVE_SYSTEM |
14396 | if (c == 's' && (strncmp(azArg[0], "shell" , n) == 0 || strncmp(azArg[0], "system" , n) == 0)) { |
14397 | char *zCmd; |
14398 | int i, x; |
14399 | if (nArg < 2) { |
14400 | raw_printf(stderr, "Usage: .system COMMAND\n" ); |
14401 | rc = 1; |
14402 | goto meta_command_exit; |
14403 | } |
14404 | zCmd = sqlite3_mprintf(strchr(azArg[1], ' ') == 0 ? "%s" : "\"%s\"" , azArg[1]); |
14405 | for (i = 2; i < nArg; i++) { |
14406 | zCmd = sqlite3_mprintf(strchr(azArg[i], ' ') == 0 ? "%z %s" : "%z \"%s\"" , zCmd, azArg[i]); |
14407 | } |
14408 | x = system(zCmd); |
14409 | sqlite3_free(zCmd); |
14410 | if (x) |
14411 | raw_printf(stderr, "System command returns %d\n" , x); |
14412 | } else |
14413 | #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ |
14414 | |
14415 | if (c == 's' && strncmp(azArg[0], "show" , n) == 0) { |
14416 | static const char *azBool[] = {"off" , "on" , "trigger" , "full" }; |
14417 | int i; |
14418 | if (nArg != 1) { |
14419 | raw_printf(stderr, "Usage: .show\n" ); |
14420 | rc = 1; |
14421 | goto meta_command_exit; |
14422 | } |
14423 | utf8_printf(p->out, "%12.12s: %s\n" , "echo" , azBool[ShellHasFlag(p, SHFLG_Echo)]); |
14424 | utf8_printf(p->out, "%12.12s: %s\n" , "eqp" , azBool[p->autoEQP & 3]); |
14425 | utf8_printf(p->out, "%12.12s: %s\n" , "explain" , |
14426 | p->mode == MODE_Explain ? "on" : p->autoExplain ? "auto" : "off" ); |
14427 | utf8_printf(p->out, "%12.12s: %s\n" , "headers" , azBool[p->showHeader != 0]); |
14428 | utf8_printf(p->out, "%12.12s: %s\n" , "mode" , modeDescr[p->mode]); |
14429 | utf8_printf(p->out, "%12.12s: " , "nullvalue" ); |
14430 | output_c_string(p->out, p->nullValue); |
14431 | raw_printf(p->out, "\n" ); |
14432 | utf8_printf(p->out, "%12.12s: %s\n" , "output" , strlen30(p->outfile) ? p->outfile : "stdout" ); |
14433 | utf8_printf(p->out, "%12.12s: " , "colseparator" ); |
14434 | output_c_string(p->out, p->colSeparator); |
14435 | raw_printf(p->out, "\n" ); |
14436 | utf8_printf(p->out, "%12.12s: " , "rowseparator" ); |
14437 | output_c_string(p->out, p->rowSeparator); |
14438 | raw_printf(p->out, "\n" ); |
14439 | utf8_printf(p->out, "%12.12s: %s\n" , "stats" , azBool[p->statsOn != 0]); |
14440 | utf8_printf(p->out, "%12.12s: " , "width" ); |
14441 | for (i = 0; i < (int)ArraySize(p->colWidth) && p->colWidth[i] != 0; i++) { |
14442 | raw_printf(p->out, "%d " , p->colWidth[i]); |
14443 | } |
14444 | raw_printf(p->out, "\n" ); |
14445 | utf8_printf(p->out, "%12.12s: %s\n" , "filename" , p->zDbFilename ? p->zDbFilename : "" ); |
14446 | } else |
14447 | |
14448 | if (c == 's' && strncmp(azArg[0], "stats" , n) == 0) { |
14449 | if (nArg == 2) { |
14450 | p->statsOn = (u8)booleanValue(azArg[1]); |
14451 | } else if (nArg == 1) { |
14452 | display_stats(p->db, p, 0); |
14453 | } else { |
14454 | raw_printf(stderr, "Usage: .stats ?on|off?\n" ); |
14455 | rc = 1; |
14456 | } |
14457 | } else |
14458 | |
14459 | if ((c == 't' && n > 1 && strncmp(azArg[0], "tables" , n) == 0) || |
14460 | (c == 'i' && (strncmp(azArg[0], "indices" , n) == 0 || strncmp(azArg[0], "indexes" , n) == 0))) { |
14461 | sqlite3_stmt *pStmt; |
14462 | char **azResult; |
14463 | int nRow, nAlloc; |
14464 | int ii; |
14465 | ShellText s; |
14466 | initText(&s); |
14467 | open_db(p, 0); |
14468 | rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list" , -1, &pStmt, 0); |
14469 | if (rc) |
14470 | return shellDatabaseError(p->db); |
14471 | |
14472 | if (nArg > 2 && c == 'i') { |
14473 | /* It is an historical accident that the .indexes command shows an error |
14474 | ** when called with the wrong number of arguments whereas the .tables |
14475 | ** command does not. */ |
14476 | raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n" ); |
14477 | rc = 1; |
14478 | goto meta_command_exit; |
14479 | } |
14480 | for (ii = 0; sqlite3_step(pStmt) == SQLITE_ROW; ii++) { |
14481 | const char *zDbName = (const char *)sqlite3_column_text(pStmt, 1); |
14482 | if (zDbName == 0) |
14483 | continue; |
14484 | if (s.z && s.z[0]) |
14485 | appendText(&s, " UNION ALL " , 0); |
14486 | if (sqlite3_stricmp(zDbName, "main" ) == 0) { |
14487 | appendText(&s, "SELECT name FROM " , 0); |
14488 | } else { |
14489 | appendText(&s, "SELECT " , 0); |
14490 | appendText(&s, zDbName, '\''); |
14491 | appendText(&s, "||'.'||name FROM " , 0); |
14492 | } |
14493 | appendText(&s, zDbName, '"'); |
14494 | appendText(&s, ".sqlite_master " , 0); |
14495 | if (c == 't') { |
14496 | appendText(&s, |
14497 | " WHERE type IN ('table','view')" |
14498 | " AND name NOT LIKE 'sqlite_%'" |
14499 | " AND name LIKE ?1" , |
14500 | 0); |
14501 | } else { |
14502 | appendText(&s, |
14503 | " WHERE type='index'" |
14504 | " AND tbl_name LIKE ?1" , |
14505 | 0); |
14506 | } |
14507 | } |
14508 | rc = sqlite3_finalize(pStmt); |
14509 | appendText(&s, " ORDER BY 1" , 0); |
14510 | rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0); |
14511 | freeText(&s); |
14512 | if (rc) |
14513 | return shellDatabaseError(p->db); |
14514 | |
14515 | /* Run the SQL statement prepared by the above block. Store the results |
14516 | ** as an array of nul-terminated strings in azResult[]. */ |
14517 | nRow = nAlloc = 0; |
14518 | azResult = 0; |
14519 | if (nArg > 1) { |
14520 | sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); |
14521 | } else { |
14522 | sqlite3_bind_text(pStmt, 1, "%" , -1, SQLITE_STATIC); |
14523 | } |
14524 | while (sqlite3_step(pStmt) == SQLITE_ROW) { |
14525 | if (nRow >= nAlloc) { |
14526 | char **azNew; |
14527 | int n2 = nAlloc * 2 + 10; |
14528 | azNew = sqlite3_realloc64(azResult, sizeof(azResult[0]) * n2); |
14529 | if (azNew == 0) { |
14530 | rc = shellNomemError(); |
14531 | break; |
14532 | } |
14533 | nAlloc = n2; |
14534 | azResult = azNew; |
14535 | } |
14536 | azResult[nRow] = sqlite3_mprintf("%s" , sqlite3_column_text(pStmt, 0)); |
14537 | if (0 == azResult[nRow]) { |
14538 | rc = shellNomemError(); |
14539 | break; |
14540 | } |
14541 | nRow++; |
14542 | } |
14543 | if (sqlite3_finalize(pStmt) != SQLITE_OK) { |
14544 | rc = shellDatabaseError(p->db); |
14545 | } |
14546 | |
14547 | /* Pretty-print the contents of array azResult[] to the output */ |
14548 | if (rc == 0 && nRow > 0) { |
14549 | int len, maxlen = 0; |
14550 | int i, j; |
14551 | int nPrintCol, nPrintRow; |
14552 | for (i = 0; i < nRow; i++) { |
14553 | len = strlen30(azResult[i]); |
14554 | if (len > maxlen) |
14555 | maxlen = len; |
14556 | } |
14557 | nPrintCol = 80 / (maxlen + 2); |
14558 | if (nPrintCol < 1) |
14559 | nPrintCol = 1; |
14560 | nPrintRow = (nRow + nPrintCol - 1) / nPrintCol; |
14561 | for (i = 0; i < nPrintRow; i++) { |
14562 | for (j = i; j < nRow; j += nPrintRow) { |
14563 | char *zSp = j < nPrintRow ? "" : " " ; |
14564 | utf8_printf(p->out, "%s%-*s" , zSp, maxlen, azResult[j] ? azResult[j] : "" ); |
14565 | } |
14566 | raw_printf(p->out, "\n" ); |
14567 | } |
14568 | } |
14569 | |
14570 | for (ii = 0; ii < nRow; ii++) |
14571 | sqlite3_free(azResult[ii]); |
14572 | sqlite3_free(azResult); |
14573 | } else |
14574 | |
14575 | /* Begin redirecting output to the file "testcase-out.txt" */ |
14576 | if (c == 't' && strcmp(azArg[0], "testcase" ) == 0) { |
14577 | output_reset(p); |
14578 | p->out = output_file_open("testcase-out.txt" , 0); |
14579 | if (p->out == 0) { |
14580 | raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n" ); |
14581 | } |
14582 | if (nArg >= 2) { |
14583 | sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s" , azArg[1]); |
14584 | } else { |
14585 | sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?" ); |
14586 | } |
14587 | } else |
14588 | |
14589 | #ifndef SQLITE_UNTESTABLE |
14590 | if (c == 't' && n >= 8 && strncmp(azArg[0], "testctrl" , n) == 0) { |
14591 | static const struct { |
14592 | const char *zCtrlName; /* Name of a test-control option */ |
14593 | int ctrlCode; /* Integer code for that option */ |
14594 | const char *zUsage; /* Usage notes */ |
14595 | } aCtrl[] = { |
14596 | {"always" , SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" }, |
14597 | {"assert" , SQLITE_TESTCTRL_ASSERT, "BOOLEAN" }, |
14598 | /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/ |
14599 | /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/ |
14600 | {"byteorder" , SQLITE_TESTCTRL_BYTEORDER, "" }, |
14601 | /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */ |
14602 | {"imposter" , SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE" }, |
14603 | #ifdef SQLITE_N_KEYWORD |
14604 | {"iskeyword" , SQLITE_TESTCTRL_ISKEYWORD, "IDENTIFIER" }, |
14605 | #endif |
14606 | {"localtime_fault" , SQLITE_TESTCTRL_LOCALTIME_FAULT, "BOOLEAN" }, |
14607 | {"never_corrupt" , SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, |
14608 | {"optimizations" , SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, |
14609 | #ifdef YYCOVERAGE |
14610 | {"parser_coverage" , SQLITE_TESTCTRL_PARSER_COVERAGE, "" }, |
14611 | #endif |
14612 | {"pending_byte" , SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " }, |
14613 | {"prng_reset" , SQLITE_TESTCTRL_PRNG_RESET, "" }, |
14614 | {"prng_restore" , SQLITE_TESTCTRL_PRNG_RESTORE, "" }, |
14615 | {"prng_save" , SQLITE_TESTCTRL_PRNG_SAVE, "" }, |
14616 | {"reserve" , SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" }, |
14617 | }; |
14618 | int testctrl = -1; |
14619 | int iCtrl = -1; |
14620 | int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */ |
14621 | int isOk = 0; |
14622 | int i, n2; |
14623 | const char *zCmd = 0; |
14624 | |
14625 | open_db(p, 0); |
14626 | zCmd = nArg >= 2 ? azArg[1] : "help" ; |
14627 | |
14628 | /* The argument can optionally begin with "-" or "--" */ |
14629 | if (zCmd[0] == '-' && zCmd[1]) { |
14630 | zCmd++; |
14631 | if (zCmd[0] == '-' && zCmd[1]) |
14632 | zCmd++; |
14633 | } |
14634 | |
14635 | /* --help lists all test-controls */ |
14636 | if (strcmp(zCmd, "help" ) == 0) { |
14637 | utf8_printf(p->out, "Available test-controls:\n" ); |
14638 | for (i = 0; i < ArraySize(aCtrl); i++) { |
14639 | utf8_printf(p->out, " .testctrl %s %s\n" , aCtrl[i].zCtrlName, aCtrl[i].zUsage); |
14640 | } |
14641 | rc = 1; |
14642 | goto meta_command_exit; |
14643 | } |
14644 | |
14645 | /* convert testctrl text option to value. allow any unique prefix |
14646 | ** of the option name, or a numerical value. */ |
14647 | n2 = strlen30(zCmd); |
14648 | for (i = 0; i < ArraySize(aCtrl); i++) { |
14649 | if (strncmp(zCmd, aCtrl[i].zCtrlName, n2) == 0) { |
14650 | if (testctrl < 0) { |
14651 | testctrl = aCtrl[i].ctrlCode; |
14652 | iCtrl = i; |
14653 | } else { |
14654 | utf8_printf(stderr, |
14655 | "Error: ambiguous test-control: \"%s\"\n" |
14656 | "Use \".testctrl --help\" for help\n" , |
14657 | zCmd); |
14658 | rc = 1; |
14659 | goto meta_command_exit; |
14660 | } |
14661 | } |
14662 | } |
14663 | if (testctrl < 0) { |
14664 | utf8_printf(stderr, |
14665 | "Error: unknown test-control: %s\n" |
14666 | "Use \".testctrl --help\" for help\n" , |
14667 | zCmd); |
14668 | } else { |
14669 | switch (testctrl) { |
14670 | |
14671 | /* sqlite3_test_control(int, db, int) */ |
14672 | case SQLITE_TESTCTRL_OPTIMIZATIONS: |
14673 | case SQLITE_TESTCTRL_RESERVE: |
14674 | if (nArg == 3) { |
14675 | int opt = (int)strtol(azArg[2], 0, 0); |
14676 | rc2 = sqlite3_test_control(testctrl, p->db, opt); |
14677 | isOk = 3; |
14678 | } |
14679 | break; |
14680 | |
14681 | /* sqlite3_test_control(int) */ |
14682 | case SQLITE_TESTCTRL_PRNG_SAVE: |
14683 | case SQLITE_TESTCTRL_PRNG_RESTORE: |
14684 | case SQLITE_TESTCTRL_PRNG_RESET: |
14685 | case SQLITE_TESTCTRL_BYTEORDER: |
14686 | if (nArg == 2) { |
14687 | rc2 = sqlite3_test_control(testctrl); |
14688 | isOk = testctrl == SQLITE_TESTCTRL_BYTEORDER ? 1 : 3; |
14689 | } |
14690 | break; |
14691 | |
14692 | /* sqlite3_test_control(int, uint) */ |
14693 | case SQLITE_TESTCTRL_PENDING_BYTE: |
14694 | if (nArg == 3) { |
14695 | unsigned int opt = (unsigned int)integerValue(azArg[2]); |
14696 | rc2 = sqlite3_test_control(testctrl, opt); |
14697 | isOk = 3; |
14698 | } |
14699 | break; |
14700 | |
14701 | /* sqlite3_test_control(int, int) */ |
14702 | case SQLITE_TESTCTRL_ASSERT: |
14703 | case SQLITE_TESTCTRL_ALWAYS: |
14704 | if (nArg == 3) { |
14705 | int opt = booleanValue(azArg[2]); |
14706 | rc2 = sqlite3_test_control(testctrl, opt); |
14707 | isOk = 1; |
14708 | } |
14709 | break; |
14710 | |
14711 | /* sqlite3_test_control(int, int) */ |
14712 | case SQLITE_TESTCTRL_LOCALTIME_FAULT: |
14713 | case SQLITE_TESTCTRL_NEVER_CORRUPT: |
14714 | if (nArg == 3) { |
14715 | int opt = booleanValue(azArg[2]); |
14716 | rc2 = sqlite3_test_control(testctrl, opt); |
14717 | isOk = 3; |
14718 | } |
14719 | break; |
14720 | |
14721 | /* sqlite3_test_control(int, char *) */ |
14722 | #ifdef SQLITE_N_KEYWORD |
14723 | case SQLITE_TESTCTRL_ISKEYWORD: |
14724 | if (nArg == 3) { |
14725 | const char *opt = azArg[2]; |
14726 | rc2 = sqlite3_test_control(testctrl, opt); |
14727 | isOk = 1; |
14728 | } |
14729 | break; |
14730 | #endif |
14731 | |
14732 | case SQLITE_TESTCTRL_IMPOSTER: |
14733 | if (nArg == 5) { |
14734 | rc2 = |
14735 | sqlite3_test_control(testctrl, p->db, azArg[2], integerValue(azArg[3]), integerValue(azArg[4])); |
14736 | isOk = 3; |
14737 | } |
14738 | break; |
14739 | |
14740 | #ifdef YYCOVERAGE |
14741 | case SQLITE_TESTCTRL_PARSER_COVERAGE: |
14742 | if (nArg == 2) { |
14743 | sqlite3_test_control(testctrl, p->out); |
14744 | isOk = 3; |
14745 | } |
14746 | #endif |
14747 | } |
14748 | } |
14749 | if (isOk == 0 && iCtrl >= 0) { |
14750 | utf8_printf(p->out, "Usage: .testctrl %s %s\n" , zCmd, aCtrl[iCtrl].zUsage); |
14751 | rc = 1; |
14752 | } else if (isOk == 1) { |
14753 | raw_printf(p->out, "%d\n" , rc2); |
14754 | } else if (isOk == 2) { |
14755 | raw_printf(p->out, "0x%08x\n" , rc2); |
14756 | } |
14757 | } else |
14758 | #endif /* !defined(SQLITE_UNTESTABLE) */ |
14759 | |
14760 | if (c == 't' && n > 4 && strncmp(azArg[0], "timeout" , n) == 0) { |
14761 | open_db(p, 0); |
14762 | sqlite3_busy_timeout(p->db, nArg >= 2 ? (int)integerValue(azArg[1]) : 0); |
14763 | } else |
14764 | |
14765 | if (c == 't' && n >= 5 && strncmp(azArg[0], "timer" , n) == 0) { |
14766 | if (nArg == 2) { |
14767 | enableTimer = booleanValue(azArg[1]); |
14768 | if (enableTimer && !HAS_TIMER) { |
14769 | raw_printf(stderr, "Error: timer not available on this system.\n" ); |
14770 | enableTimer = 0; |
14771 | } |
14772 | } else { |
14773 | raw_printf(stderr, "Usage: .timer on|off\n" ); |
14774 | rc = 1; |
14775 | } |
14776 | } else |
14777 | |
14778 | if (c == 't' && strncmp(azArg[0], "trace" , n) == 0) { |
14779 | open_db(p, 0); |
14780 | if (nArg != 2) { |
14781 | raw_printf(stderr, "Usage: .trace FILE|off\n" ); |
14782 | rc = 1; |
14783 | goto meta_command_exit; |
14784 | } |
14785 | output_file_close(p->traceOut); |
14786 | p->traceOut = output_file_open(azArg[1], 0); |
14787 | #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) |
14788 | if (p->traceOut == 0) { |
14789 | sqlite3_trace_v2(p->db, 0, 0, 0); |
14790 | } else { |
14791 | sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback, p->traceOut); |
14792 | } |
14793 | #endif |
14794 | } else |
14795 | |
14796 | #if SQLITE_USER_AUTHENTICATION |
14797 | if (c == 'u' && strncmp(azArg[0], "user" , n) == 0) { |
14798 | if (nArg < 2) { |
14799 | raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n" ); |
14800 | rc = 1; |
14801 | goto meta_command_exit; |
14802 | } |
14803 | open_db(p, 0); |
14804 | if (strcmp(azArg[1], "login" ) == 0) { |
14805 | if (nArg != 4) { |
14806 | raw_printf(stderr, "Usage: .user login USER PASSWORD\n" ); |
14807 | rc = 1; |
14808 | goto meta_command_exit; |
14809 | } |
14810 | rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3])); |
14811 | if (rc) { |
14812 | utf8_printf(stderr, "Authentication failed for user %s\n" , azArg[2]); |
14813 | rc = 1; |
14814 | } |
14815 | } else if (strcmp(azArg[1], "add" ) == 0) { |
14816 | if (nArg != 5) { |
14817 | raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n" ); |
14818 | rc = 1; |
14819 | goto meta_command_exit; |
14820 | } |
14821 | rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]), booleanValue(azArg[4])); |
14822 | if (rc) { |
14823 | raw_printf(stderr, "User-Add failed: %d\n" , rc); |
14824 | rc = 1; |
14825 | } |
14826 | } else if (strcmp(azArg[1], "edit" ) == 0) { |
14827 | if (nArg != 5) { |
14828 | raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n" ); |
14829 | rc = 1; |
14830 | goto meta_command_exit; |
14831 | } |
14832 | rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]), booleanValue(azArg[4])); |
14833 | if (rc) { |
14834 | raw_printf(stderr, "User-Edit failed: %d\n" , rc); |
14835 | rc = 1; |
14836 | } |
14837 | } else if (strcmp(azArg[1], "delete" ) == 0) { |
14838 | if (nArg != 3) { |
14839 | raw_printf(stderr, "Usage: .user delete USER\n" ); |
14840 | rc = 1; |
14841 | goto meta_command_exit; |
14842 | } |
14843 | rc = sqlite3_user_delete(p->db, azArg[2]); |
14844 | if (rc) { |
14845 | raw_printf(stderr, "User-Delete failed: %d\n" , rc); |
14846 | rc = 1; |
14847 | } |
14848 | } else { |
14849 | raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n" ); |
14850 | rc = 1; |
14851 | goto meta_command_exit; |
14852 | } |
14853 | } else |
14854 | #endif /* SQLITE_USER_AUTHENTICATION */ |
14855 | |
14856 | if (c == 'v' && strncmp(azArg[0], "version" , n) == 0) { |
14857 | utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); |
14858 | #if SQLITE_HAVE_ZLIB |
14859 | utf8_printf(p->out, "zlib version %s\n" , zlibVersion()); |
14860 | #endif |
14861 | #define CTIMEOPT_VAL_(opt) #opt |
14862 | #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) |
14863 | #if defined(__clang__) && defined(__clang_major__) |
14864 | utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." CTIMEOPT_VAL(__clang_minor__) "." CTIMEOPT_VAL( |
14865 | __clang_patchlevel__) "\n" ); |
14866 | #elif defined(_MSC_VER) |
14867 | utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n" ); |
14868 | #elif defined(__GNUC__) && defined(__VERSION__) |
14869 | utf8_printf(p->out, "gcc-" __VERSION__ "\n" ); |
14870 | #endif |
14871 | } else |
14872 | |
14873 | if (c == 'v' && strncmp(azArg[0], "vfsinfo" , n) == 0) { |
14874 | const char *zDbName = nArg == 2 ? azArg[1] : "main" ; |
14875 | sqlite3_vfs *pVfs = 0; |
14876 | if (p->db) { |
14877 | sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); |
14878 | if (pVfs) { |
14879 | utf8_printf(p->out, "vfs.zName = \"%s\"\n" , pVfs->zName); |
14880 | raw_printf(p->out, "vfs.iVersion = %d\n" , pVfs->iVersion); |
14881 | raw_printf(p->out, "vfs.szOsFile = %d\n" , pVfs->szOsFile); |
14882 | raw_printf(p->out, "vfs.mxPathname = %d\n" , pVfs->mxPathname); |
14883 | } |
14884 | } |
14885 | } else |
14886 | |
14887 | if (c == 'v' && strncmp(azArg[0], "vfslist" , n) == 0) { |
14888 | sqlite3_vfs *pVfs; |
14889 | sqlite3_vfs *pCurrent = 0; |
14890 | if (p->db) { |
14891 | sqlite3_file_control(p->db, "main" , SQLITE_FCNTL_VFS_POINTER, &pCurrent); |
14892 | } |
14893 | for (pVfs = sqlite3_vfs_find(0); pVfs; pVfs = pVfs->pNext) { |
14894 | utf8_printf(p->out, "vfs.zName = \"%s\"%s\n" , pVfs->zName, pVfs == pCurrent ? " <--- CURRENT" : "" ); |
14895 | raw_printf(p->out, "vfs.iVersion = %d\n" , pVfs->iVersion); |
14896 | raw_printf(p->out, "vfs.szOsFile = %d\n" , pVfs->szOsFile); |
14897 | raw_printf(p->out, "vfs.mxPathname = %d\n" , pVfs->mxPathname); |
14898 | if (pVfs->pNext) { |
14899 | raw_printf(p->out, "-----------------------------------\n" ); |
14900 | } |
14901 | } |
14902 | } else |
14903 | |
14904 | if (c == 'v' && strncmp(azArg[0], "vfsname" , n) == 0) { |
14905 | const char *zDbName = nArg == 2 ? azArg[1] : "main" ; |
14906 | char *zVfsName = 0; |
14907 | if (p->db) { |
14908 | sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); |
14909 | if (zVfsName) { |
14910 | utf8_printf(p->out, "%s\n" , zVfsName); |
14911 | sqlite3_free(zVfsName); |
14912 | } |
14913 | } |
14914 | } else |
14915 | |
14916 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) |
14917 | if (c == 'w' && strncmp(azArg[0], "wheretrace" , n) == 0) { |
14918 | sqlite3WhereTrace = nArg >= 2 ? booleanValue(azArg[1]) : 0xff; |
14919 | } else |
14920 | #endif |
14921 | |
14922 | if (c == 'w' && strncmp(azArg[0], "width" , n) == 0) { |
14923 | int j; |
14924 | assert(nArg <= ArraySize(azArg)); |
14925 | for (j = 1; j < nArg && j < ArraySize(p->colWidth); j++) { |
14926 | p->colWidth[j - 1] = (int)integerValue(azArg[j]); |
14927 | } |
14928 | } else |
14929 | |
14930 | { |
14931 | utf8_printf(stderr, |
14932 | "Error: unknown command or invalid arguments: " |
14933 | " \"%s\". Enter \".help\" for help\n" , |
14934 | azArg[0]); |
14935 | rc = 1; |
14936 | } |
14937 | |
14938 | meta_command_exit: |
14939 | if (p->outCount) { |
14940 | p->outCount--; |
14941 | if (p->outCount == 0) |
14942 | output_reset(p); |
14943 | } |
14944 | return rc; |
14945 | } |
14946 | |
14947 | /* |
14948 | ** Return TRUE if a semicolon occurs anywhere in the first N characters |
14949 | ** of string z[]. |
14950 | */ |
14951 | static int line_contains_semicolon(const char *z, int N) { |
14952 | int i; |
14953 | for (i = 0; i < N; i++) { |
14954 | if (z[i] == ';') |
14955 | return 1; |
14956 | } |
14957 | return 0; |
14958 | } |
14959 | |
14960 | /* |
14961 | ** Test to see if a line consists entirely of whitespace. |
14962 | */ |
14963 | static int _all_whitespace(const char *z) { |
14964 | for (; *z; z++) { |
14965 | if (IsSpace(z[0])) |
14966 | continue; |
14967 | if (*z == '/' && z[1] == '*') { |
14968 | z += 2; |
14969 | while (*z && (*z != '*' || z[1] != '/')) { |
14970 | z++; |
14971 | } |
14972 | if (*z == 0) |
14973 | return 0; |
14974 | z++; |
14975 | continue; |
14976 | } |
14977 | if (*z == '-' && z[1] == '-') { |
14978 | z += 2; |
14979 | while (*z && *z != '\n') { |
14980 | z++; |
14981 | } |
14982 | if (*z == 0) |
14983 | return 1; |
14984 | continue; |
14985 | } |
14986 | return 0; |
14987 | } |
14988 | return 1; |
14989 | } |
14990 | |
14991 | /* |
14992 | ** Return TRUE if the line typed in is an SQL command terminator other |
14993 | ** than a semi-colon. The SQL Server style "go" command is understood |
14994 | ** as is the Oracle "/". |
14995 | */ |
14996 | static int line_is_command_terminator(const char *zLine) { |
14997 | while (IsSpace(zLine[0])) { |
14998 | zLine++; |
14999 | }; |
15000 | if (zLine[0] == '/' && _all_whitespace(&zLine[1])) { |
15001 | return 1; /* Oracle */ |
15002 | } |
15003 | if (ToLower(zLine[0]) == 'g' && ToLower(zLine[1]) == 'o' && _all_whitespace(&zLine[2])) { |
15004 | return 1; /* SQL Server */ |
15005 | } |
15006 | return 0; |
15007 | } |
15008 | |
15009 | /* |
15010 | ** We need a default sqlite3_complete() implementation to use in case |
15011 | ** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes |
15012 | ** any arbitrary text is a complete SQL statement. This is not very |
15013 | ** user-friendly, but it does seem to work. |
15014 | */ |
15015 | #ifdef SQLITE_OMIT_COMPLETE |
15016 | int sqlite3_complete(const char *zSql) { |
15017 | return 1; |
15018 | } |
15019 | #endif |
15020 | |
15021 | /* |
15022 | ** Return true if zSql is a complete SQL statement. Return false if it |
15023 | ** ends in the middle of a string literal or C-style comment. |
15024 | */ |
15025 | static int line_is_complete(char *zSql, int nSql) { |
15026 | int rc; |
15027 | if (zSql == 0) |
15028 | return 1; |
15029 | zSql[nSql] = ';'; |
15030 | zSql[nSql + 1] = 0; |
15031 | rc = sqlite3_complete(zSql); |
15032 | zSql[nSql] = 0; |
15033 | return rc; |
15034 | } |
15035 | |
15036 | /* |
15037 | ** Run a single line of SQL |
15038 | */ |
15039 | static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline) { |
15040 | int rc; |
15041 | char *zErrMsg = 0; |
15042 | |
15043 | open_db(p, 0); |
15044 | if (ShellHasFlag(p, SHFLG_Backslash)) |
15045 | resolve_backslashes(zSql); |
15046 | BEGIN_TIMER; |
15047 | rc = shell_exec(p, zSql, &zErrMsg); |
15048 | END_TIMER; |
15049 | if (rc || zErrMsg) { |
15050 | char zPrefix[100]; |
15051 | if (in != 0 || !stdin_is_interactive) { |
15052 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error: near line %d:" , startline); |
15053 | } else { |
15054 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:" ); |
15055 | } |
15056 | if (zErrMsg != 0) { |
15057 | utf8_printf(stderr, "%s %s\n" , zPrefix, zErrMsg); |
15058 | sqlite3_free(zErrMsg); |
15059 | zErrMsg = 0; |
15060 | } else { |
15061 | utf8_printf(stderr, "%s %s\n" , zPrefix, sqlite3_errmsg(p->db)); |
15062 | } |
15063 | return 1; |
15064 | } else if (ShellHasFlag(p, SHFLG_CountChanges)) { |
15065 | raw_printf(p->out, "changes: %3d total_changes: %d\n" , sqlite3_changes(p->db), sqlite3_total_changes(p->db)); |
15066 | } |
15067 | return 0; |
15068 | } |
15069 | |
15070 | /* |
15071 | ** Read input from *in and process it. If *in==0 then input |
15072 | ** is interactive - the user is typing it it. Otherwise, input |
15073 | ** is coming from a file or device. A prompt is issued and history |
15074 | ** is saved only if input is interactive. An interrupt signal will |
15075 | ** cause this routine to exit immediately, unless input is interactive. |
15076 | ** |
15077 | ** Return the number of errors. |
15078 | */ |
15079 | static int process_input(ShellState *p, FILE *in) { |
15080 | char *zLine = 0; /* A single input line */ |
15081 | char *zSql = 0; /* Accumulated SQL text */ |
15082 | int nLine; /* Length of current line */ |
15083 | int nSql = 0; /* Bytes of zSql[] used */ |
15084 | int nAlloc = 0; /* Allocated zSql[] space */ |
15085 | int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */ |
15086 | int rc; /* Error code */ |
15087 | int errCnt = 0; /* Number of errors seen */ |
15088 | int lineno = 0; /* Current line number */ |
15089 | int startline = 0; /* Line number for start of current input */ |
15090 | |
15091 | while (errCnt == 0 || !bail_on_error || (in == 0 && stdin_is_interactive)) { |
15092 | fflush(p->out); |
15093 | zLine = one_input_line(in, zLine, nSql > 0); |
15094 | if (zLine == 0) { |
15095 | /* End of input */ |
15096 | if (in == 0 && stdin_is_interactive) |
15097 | printf("\n" ); |
15098 | break; |
15099 | } |
15100 | if (seenInterrupt) { |
15101 | if (in != 0) |
15102 | break; |
15103 | seenInterrupt = 0; |
15104 | } |
15105 | lineno++; |
15106 | if (nSql == 0 && _all_whitespace(zLine)) { |
15107 | if (ShellHasFlag(p, SHFLG_Echo)) |
15108 | printf("%s\n" , zLine); |
15109 | continue; |
15110 | } |
15111 | if (zLine && zLine[0] == '.' && nSql == 0) { |
15112 | if (ShellHasFlag(p, SHFLG_Echo)) |
15113 | printf("%s\n" , zLine); |
15114 | rc = do_meta_command(zLine, p); |
15115 | if (rc == 2) { /* exit requested */ |
15116 | break; |
15117 | } else if (rc) { |
15118 | errCnt++; |
15119 | } |
15120 | continue; |
15121 | } |
15122 | if (line_is_command_terminator(zLine) && line_is_complete(zSql, nSql)) { |
15123 | memcpy(zLine, ";" , 2); |
15124 | } |
15125 | nLine = strlen30(zLine); |
15126 | if (nSql + nLine + 2 >= nAlloc) { |
15127 | nAlloc = nSql + nLine + 100; |
15128 | zSql = realloc(zSql, nAlloc); |
15129 | if (zSql == 0) { |
15130 | raw_printf(stderr, "Error: out of memory\n" ); |
15131 | exit(1); |
15132 | } |
15133 | } |
15134 | nSqlPrior = nSql; |
15135 | if (nSql == 0) { |
15136 | int i; |
15137 | for (i = 0; zLine[i] && IsSpace(zLine[i]); i++) { |
15138 | } |
15139 | assert(nAlloc > 0 && zSql != 0); |
15140 | memcpy(zSql, zLine + i, nLine + 1 - i); |
15141 | startline = lineno; |
15142 | nSql = nLine - i; |
15143 | } else { |
15144 | zSql[nSql++] = '\n'; |
15145 | memcpy(zSql + nSql, zLine, nLine + 1); |
15146 | nSql += nLine; |
15147 | } |
15148 | if (nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql - nSqlPrior) && sqlite3_complete(zSql)) { |
15149 | errCnt += runOneSqlLine(p, zSql, in, startline); |
15150 | nSql = 0; |
15151 | if (p->outCount) { |
15152 | output_reset(p); |
15153 | p->outCount = 0; |
15154 | } else { |
15155 | clearTempFile(p); |
15156 | } |
15157 | } else if (nSql && _all_whitespace(zSql)) { |
15158 | if (ShellHasFlag(p, SHFLG_Echo)) |
15159 | printf("%s\n" , zSql); |
15160 | nSql = 0; |
15161 | } |
15162 | } |
15163 | if (nSql && !_all_whitespace(zSql)) { |
15164 | runOneSqlLine(p, zSql, in, startline); |
15165 | } |
15166 | free(zSql); |
15167 | free(zLine); |
15168 | return errCnt > 0; |
15169 | } |
15170 | |
15171 | /* |
15172 | ** Return a pathname which is the user's home directory. A |
15173 | ** 0 return indicates an error of some kind. |
15174 | */ |
15175 | static char *find_home_dir(int clearFlag) { |
15176 | static char *home_dir = NULL; |
15177 | if (clearFlag) { |
15178 | free(home_dir); |
15179 | home_dir = 0; |
15180 | return 0; |
15181 | } |
15182 | if (home_dir) |
15183 | return home_dir; |
15184 | |
15185 | #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL) |
15186 | { |
15187 | struct passwd *pwent; |
15188 | uid_t uid = getuid(); |
15189 | if ((pwent = getpwuid(uid)) != NULL) { |
15190 | home_dir = pwent->pw_dir; |
15191 | } |
15192 | } |
15193 | #endif |
15194 | |
15195 | #if defined(_WIN32_WCE) |
15196 | /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() |
15197 | */ |
15198 | home_dir = "/" ; |
15199 | #else |
15200 | |
15201 | #if defined(_WIN32) || defined(WIN32) |
15202 | if (!home_dir) { |
15203 | home_dir = getenv("USERPROFILE" ); |
15204 | } |
15205 | #endif |
15206 | |
15207 | if (!home_dir) { |
15208 | home_dir = getenv("HOME" ); |
15209 | } |
15210 | |
15211 | #if defined(_WIN32) || defined(WIN32) |
15212 | if (!home_dir) { |
15213 | char *zDrive, *zPath; |
15214 | int n; |
15215 | zDrive = getenv("HOMEDRIVE" ); |
15216 | zPath = getenv("HOMEPATH" ); |
15217 | if (zDrive && zPath) { |
15218 | n = strlen30(zDrive) + strlen30(zPath) + 1; |
15219 | home_dir = malloc(n); |
15220 | if (home_dir == 0) |
15221 | return 0; |
15222 | sqlite3_snprintf(n, home_dir, "%s%s" , zDrive, zPath); |
15223 | return home_dir; |
15224 | } |
15225 | home_dir = "c:\\" ; |
15226 | } |
15227 | #endif |
15228 | |
15229 | #endif /* !_WIN32_WCE */ |
15230 | |
15231 | if (home_dir) { |
15232 | int n = strlen30(home_dir) + 1; |
15233 | char *z = malloc(n); |
15234 | if (z) |
15235 | memcpy(z, home_dir, n); |
15236 | home_dir = z; |
15237 | } |
15238 | |
15239 | return home_dir; |
15240 | } |
15241 | |
15242 | /* |
15243 | ** Read input from the file given by sqliterc_override. Or if that |
15244 | ** parameter is NULL, take input from ~/.sqliterc |
15245 | ** |
15246 | ** Returns the number of errors. |
15247 | */ |
15248 | static void process_sqliterc(ShellState *p, /* Configuration data */ |
15249 | const char *sqliterc_override /* Name of config file. NULL to use default */ |
15250 | ) { |
15251 | char *home_dir = NULL; |
15252 | const char *sqliterc = sqliterc_override; |
15253 | char *zBuf = 0; |
15254 | FILE *in = NULL; |
15255 | |
15256 | if (sqliterc == NULL) { |
15257 | home_dir = find_home_dir(0); |
15258 | if (home_dir == 0) { |
15259 | raw_printf(stderr, "-- warning: cannot find home directory;" |
15260 | " cannot read ~/.sqliterc\n" ); |
15261 | return; |
15262 | } |
15263 | sqlite3_initialize(); |
15264 | zBuf = sqlite3_mprintf("%s/.sqliterc" , home_dir); |
15265 | sqliterc = zBuf; |
15266 | } |
15267 | in = fopen(sqliterc, "rb" ); |
15268 | if (in) { |
15269 | if (stdin_is_interactive) { |
15270 | utf8_printf(stderr, "-- Loading resources from %s\n" , sqliterc); |
15271 | } |
15272 | process_input(p, in); |
15273 | fclose(in); |
15274 | } |
15275 | sqlite3_free(zBuf); |
15276 | } |
15277 | |
15278 | /* |
15279 | ** Show available command line options |
15280 | */ |
15281 | static const char zOptions[] = |
15282 | #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) |
15283 | " -A ARGS... run \".archive ARGS\" and exit\n" |
15284 | #endif |
15285 | " -append append the database to the end of the file\n" |
15286 | " -ascii set output mode to 'ascii'\n" |
15287 | " -bail stop after hitting an error\n" |
15288 | " -batch force batch I/O\n" |
15289 | " -column set output mode to 'column'\n" |
15290 | " -cmd COMMAND run \"COMMAND\" before reading stdin\n" |
15291 | " -csv set output mode to 'csv'\n" |
15292 | " -echo print commands before execution\n" |
15293 | " -init FILENAME read/process named file\n" |
15294 | " -[no]header turn headers on or off\n" |
15295 | #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) |
15296 | " -heap SIZE Size of heap for memsys3 or memsys5\n" |
15297 | #endif |
15298 | " -help show this message\n" |
15299 | " -html set output mode to HTML\n" |
15300 | " -interactive force interactive I/O\n" |
15301 | " -line set output mode to 'line'\n" |
15302 | " -list set output mode to 'list'\n" |
15303 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
15304 | " -mmap N default mmap size set to N\n" |
15305 | #ifdef SQLITE_ENABLE_MULTIPLEX |
15306 | " -multiplex enable the multiplexor VFS\n" |
15307 | #endif |
15308 | " -newline SEP set output row separator. Default: '\\n'\n" |
15309 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
15310 | " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" |
15311 | " -quote set output mode to 'quote'\n" |
15312 | " -readonly open the database read-only\n" |
15313 | " -separator SEP set output column separator. Default: '|'\n" |
15314 | " -stats print memory stats before each finalize\n" |
15315 | " -version show SQLite version\n" |
15316 | " -vfs NAME use NAME as the default VFS\n" |
15317 | #ifdef SQLITE_ENABLE_VFSTRACE |
15318 | " -vfstrace enable tracing of all VFS calls\n" |
15319 | #endif |
15320 | #ifdef SQLITE_HAVE_ZLIB |
15321 | " -zip open the file as a ZIP Archive\n" |
15322 | #endif |
15323 | ; |
15324 | static void usage(int showDetail) { |
15325 | utf8_printf(stderr, |
15326 | "Usage: %s [OPTIONS] FILENAME [SQL]\n" |
15327 | "FILENAME is the name of an SQLite database. A new database is created\n" |
15328 | "if the file does not previously exist.\n" , |
15329 | Argv0); |
15330 | if (showDetail) { |
15331 | utf8_printf(stderr, "OPTIONS include:\n%s" , zOptions); |
15332 | } else { |
15333 | raw_printf(stderr, "Use the -help option for additional information\n" ); |
15334 | } |
15335 | exit(1); |
15336 | } |
15337 | |
15338 | /* |
15339 | ** Initialize the state information in data |
15340 | */ |
15341 | static void main_init(ShellState *data) { |
15342 | memset(data, 0, sizeof(*data)); |
15343 | data->normalMode = data->cMode = data->mode = MODE_List; |
15344 | data->autoExplain = 1; |
15345 | memcpy(data->colSeparator, SEP_Column, 2); |
15346 | memcpy(data->rowSeparator, SEP_Row, 2); |
15347 | data->showHeader = 0; |
15348 | data->shellFlgs = SHFLG_Lookaside; |
15349 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
15350 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
15351 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
15352 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt, "sqlite> " ); |
15353 | sqlite3_snprintf(sizeof(continuePrompt), continuePrompt, " ...> " ); |
15354 | } |
15355 | |
15356 | /* |
15357 | ** Output text to the console in a font that attracts extra attention. |
15358 | */ |
15359 | #ifdef _WIN32 |
15360 | static void printBold(const char *zText) { |
15361 | HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); |
15362 | CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo; |
15363 | GetConsoleScreenBufferInfo(out, &defaultScreenInfo); |
15364 | SetConsoleTextAttribute(out, FOREGROUND_RED | FOREGROUND_INTENSITY); |
15365 | printf("%s" , zText); |
15366 | SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); |
15367 | } |
15368 | #else |
15369 | static void printBold(const char *zText) { |
15370 | printf("\033[1m%s\033[0m" , zText); |
15371 | } |
15372 | #endif |
15373 | |
15374 | /* |
15375 | ** Get the argument to an --option. Throw an error and die if no argument |
15376 | ** is available. |
15377 | */ |
15378 | static char *cmdline_option_value(int argc, char **argv, int i) { |
15379 | if (i == argc) { |
15380 | utf8_printf(stderr, "%s: Error: missing argument to %s\n" , argv[0], argv[argc - 1]); |
15381 | exit(1); |
15382 | } |
15383 | return argv[i]; |
15384 | } |
15385 | |
15386 | #ifndef SQLITE_SHELL_IS_UTF8 |
15387 | #if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) |
15388 | #define SQLITE_SHELL_IS_UTF8 (0) |
15389 | #else |
15390 | #define SQLITE_SHELL_IS_UTF8 (1) |
15391 | #endif |
15392 | #endif |
15393 | |
15394 | #if SQLITE_SHELL_IS_UTF8 |
15395 | int SQLITE_CDECL main(int argc, char **argv) { |
15396 | #else |
15397 | int SQLITE_CDECL wmain(int argc, wchar_t **wargv) { |
15398 | char **argv; |
15399 | #endif |
15400 | char *zErrMsg = 0; |
15401 | ShellState data; |
15402 | const char *zInitFile = 0; |
15403 | int i; |
15404 | int rc = 0; |
15405 | int warnInmemoryDb = 0; |
15406 | int readStdin = 1; |
15407 | int nCmd = 0; |
15408 | char **azCmd = 0; |
15409 | |
15410 | setBinaryMode(stdin, 0); |
15411 | setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ |
15412 | stdin_is_interactive = isatty(0); |
15413 | stdout_is_console = isatty(1); |
15414 | |
15415 | #if USE_SYSTEM_SQLITE + 0 != 1 |
15416 | if (strncmp(sqlite3_sourceid(), SQLITE_SOURCE_ID, 60) != 0) { |
15417 | utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n" , sqlite3_sourceid(), |
15418 | SQLITE_SOURCE_ID); |
15419 | exit(1); |
15420 | } |
15421 | #endif |
15422 | main_init(&data); |
15423 | |
15424 | /* On Windows, we must translate command-line arguments into UTF-8. |
15425 | ** The SQLite memory allocator subsystem has to be enabled in order to |
15426 | ** do this. But we want to run an sqlite3_shutdown() afterwards so that |
15427 | ** subsequent sqlite3_config() calls will work. So copy all results into |
15428 | ** memory that does not come from the SQLite memory allocator. |
15429 | */ |
15430 | #if !SQLITE_SHELL_IS_UTF8 |
15431 | sqlite3_initialize(); |
15432 | argv = malloc(sizeof(argv[0]) * argc); |
15433 | if (argv == 0) { |
15434 | raw_printf(stderr, "out of memory\n" ); |
15435 | exit(1); |
15436 | } |
15437 | for (i = 0; i < argc; i++) { |
15438 | char *z = sqlite3_win32_unicode_to_utf8(wargv[i]); |
15439 | int n; |
15440 | if (z == 0) { |
15441 | raw_printf(stderr, "out of memory\n" ); |
15442 | exit(1); |
15443 | } |
15444 | n = (int)strlen(z); |
15445 | argv[i] = malloc(n + 1); |
15446 | if (argv[i] == 0) { |
15447 | raw_printf(stderr, "out of memory\n" ); |
15448 | exit(1); |
15449 | } |
15450 | memcpy(argv[i], z, n + 1); |
15451 | sqlite3_free(z); |
15452 | } |
15453 | sqlite3_shutdown(); |
15454 | #endif |
15455 | |
15456 | assert(argc >= 1 && argv && argv[0]); |
15457 | Argv0 = argv[0]; |
15458 | |
15459 | /* Make sure we have a valid signal handler early, before anything |
15460 | ** else is done. |
15461 | */ |
15462 | #ifdef SIGINT |
15463 | signal(SIGINT, interrupt_handler); |
15464 | #elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) |
15465 | SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE); |
15466 | #endif |
15467 | |
15468 | #ifdef SQLITE_SHELL_DBNAME_PROC |
15469 | { |
15470 | /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name |
15471 | ** of a C-function that will provide the name of the database file. Use |
15472 | ** this compile-time option to embed this shell program in larger |
15473 | ** applications. */ |
15474 | extern void SQLITE_SHELL_DBNAME_PROC(const char **); |
15475 | SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename); |
15476 | warnInmemoryDb = 0; |
15477 | } |
15478 | #endif |
15479 | |
15480 | /* Do an initial pass through the command-line argument to locate |
15481 | ** the name of the database file, the name of the initialization file, |
15482 | ** the size of the alternative malloc heap, |
15483 | ** and the first command to execute. |
15484 | */ |
15485 | for (i = 1; i < argc; i++) { |
15486 | char *z; |
15487 | z = argv[i]; |
15488 | if (z[0] != '-') { |
15489 | if (data.zDbFilename == 0) { |
15490 | data.zDbFilename = z; |
15491 | } else { |
15492 | /* Excesss arguments are interpreted as SQL (or dot-commands) and |
15493 | ** mean that nothing is read from stdin */ |
15494 | readStdin = 0; |
15495 | nCmd++; |
15496 | azCmd = realloc(azCmd, sizeof(azCmd[0]) * nCmd); |
15497 | if (azCmd == 0) { |
15498 | raw_printf(stderr, "out of memory\n" ); |
15499 | exit(1); |
15500 | } |
15501 | azCmd[nCmd - 1] = z; |
15502 | } |
15503 | } |
15504 | if (z[1] == '-') |
15505 | z++; |
15506 | if (strcmp(z, "-separator" ) == 0 || strcmp(z, "-nullvalue" ) == 0 || strcmp(z, "-newline" ) == 0 || |
15507 | strcmp(z, "-cmd" ) == 0) { |
15508 | (void)cmdline_option_value(argc, argv, ++i); |
15509 | } else if (strcmp(z, "-init" ) == 0) { |
15510 | zInitFile = cmdline_option_value(argc, argv, ++i); |
15511 | } else if (strcmp(z, "-batch" ) == 0) { |
15512 | /* Need to check for batch mode here to so we can avoid printing |
15513 | ** informational messages (like from process_sqliterc) before |
15514 | ** we do the actual processing of arguments later in a second pass. |
15515 | */ |
15516 | stdin_is_interactive = 0; |
15517 | } else if (strcmp(z, "-heap" ) == 0) { |
15518 | #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) |
15519 | const char *zSize; |
15520 | sqlite3_int64 szHeap; |
15521 | |
15522 | zSize = cmdline_option_value(argc, argv, ++i); |
15523 | szHeap = integerValue(zSize); |
15524 | if (szHeap > 0x7fff0000) |
15525 | szHeap = 0x7fff0000; |
15526 | sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); |
15527 | #else |
15528 | (void)cmdline_option_value(argc, argv, ++i); |
15529 | #endif |
15530 | } else if (strcmp(z, "-pagecache" ) == 0) { |
15531 | int n, sz; |
15532 | sz = (int)integerValue(cmdline_option_value(argc, argv, ++i)); |
15533 | if (sz > 70000) |
15534 | sz = 70000; |
15535 | if (sz < 0) |
15536 | sz = 0; |
15537 | n = (int)integerValue(cmdline_option_value(argc, argv, ++i)); |
15538 | sqlite3_config(SQLITE_CONFIG_PAGECACHE, (n > 0 && sz > 0) ? malloc(n * sz) : 0, sz, n); |
15539 | data.shellFlgs |= SHFLG_Pagecache; |
15540 | } else if (strcmp(z, "-lookaside" ) == 0) { |
15541 | int n, sz; |
15542 | sz = (int)integerValue(cmdline_option_value(argc, argv, ++i)); |
15543 | if (sz < 0) |
15544 | sz = 0; |
15545 | n = (int)integerValue(cmdline_option_value(argc, argv, ++i)); |
15546 | if (n < 0) |
15547 | n = 0; |
15548 | sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); |
15549 | if (sz * n == 0) |
15550 | data.shellFlgs &= ~SHFLG_Lookaside; |
15551 | #ifdef SQLITE_ENABLE_VFSTRACE |
15552 | } else if (strcmp(z, "-vfstrace" ) == 0) { |
15553 | extern int vfstrace_register(const char *zTraceName, const char *zOldVfsName, |
15554 | int (*xOut)(const char *, void *), void *pOutArg, int makeDefault); |
15555 | vfstrace_register("trace" , 0, (int (*)(const char *, void *))fputs, stderr, 1); |
15556 | #endif |
15557 | #ifdef SQLITE_ENABLE_MULTIPLEX |
15558 | } else if (strcmp(z, "-multiplex" ) == 0) { |
15559 | extern int sqlite3_multiple_initialize(const char *, int); |
15560 | sqlite3_multiplex_initialize(0, 1); |
15561 | #endif |
15562 | } else if (strcmp(z, "-mmap" ) == 0) { |
15563 | sqlite3_int64 sz = integerValue(cmdline_option_value(argc, argv, ++i)); |
15564 | sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); |
15565 | } else if (strcmp(z, "-vfs" ) == 0) { |
15566 | sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc, argv, ++i)); |
15567 | if (pVfs) { |
15568 | sqlite3_vfs_register(pVfs, 1); |
15569 | } else { |
15570 | utf8_printf(stderr, "no such VFS: \"%s\"\n" , argv[i]); |
15571 | exit(1); |
15572 | } |
15573 | #ifdef SQLITE_HAVE_ZLIB |
15574 | } else if (strcmp(z, "-zip" ) == 0) { |
15575 | data.openMode = SHELL_OPEN_ZIPFILE; |
15576 | #endif |
15577 | } else if (strcmp(z, "-append" ) == 0) { |
15578 | data.openMode = SHELL_OPEN_APPENDVFS; |
15579 | } else if (strcmp(z, "-readonly" ) == 0) { |
15580 | data.openMode = SHELL_OPEN_READONLY; |
15581 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
15582 | } else if (strncmp(z, "-A" , 2) == 0) { |
15583 | /* All remaining command-line arguments are passed to the ".archive" |
15584 | ** command, so ignore them */ |
15585 | break; |
15586 | #endif |
15587 | } |
15588 | } |
15589 | if (data.zDbFilename == 0) { |
15590 | #ifndef SQLITE_OMIT_MEMORYDB |
15591 | data.zDbFilename = ":memory:" ; |
15592 | warnInmemoryDb = argc == 1; |
15593 | #else |
15594 | utf8_printf(stderr, "%s: Error: no database filename specified\n" , Argv0); |
15595 | return 1; |
15596 | #endif |
15597 | } |
15598 | data.out = stdout; |
15599 | sqlite3_appendvfs_init(0, 0, 0); |
15600 | |
15601 | /* Go ahead and open the database file if it already exists. If the |
15602 | ** file does not exist, delay opening it. This prevents empty database |
15603 | ** files from being created if a user mistypes the database name argument |
15604 | ** to the sqlite command-line tool. |
15605 | */ |
15606 | if (access(data.zDbFilename, 0) == 0) { |
15607 | open_db(&data, 0); |
15608 | } |
15609 | |
15610 | /* Process the initialization file if there is one. If no -init option |
15611 | ** is given on the command line, look for a file named ~/.sqliterc and |
15612 | ** try to process it. |
15613 | */ |
15614 | process_sqliterc(&data, zInitFile); |
15615 | |
15616 | /* Make a second pass through the command-line argument and set |
15617 | ** options. This second pass is delayed until after the initialization |
15618 | ** file is processed so that the command-line arguments will override |
15619 | ** settings in the initialization file. |
15620 | */ |
15621 | for (i = 1; i < argc; i++) { |
15622 | char *z = argv[i]; |
15623 | if (z[0] != '-') |
15624 | continue; |
15625 | if (z[1] == '-') { |
15626 | z++; |
15627 | } |
15628 | if (strcmp(z, "-init" ) == 0) { |
15629 | i++; |
15630 | } else if (strcmp(z, "-html" ) == 0) { |
15631 | data.mode = MODE_Html; |
15632 | } else if (strcmp(z, "-list" ) == 0) { |
15633 | data.mode = MODE_List; |
15634 | } else if (strcmp(z, "-quote" ) == 0) { |
15635 | data.mode = MODE_Quote; |
15636 | } else if (strcmp(z, "-line" ) == 0) { |
15637 | data.mode = MODE_Line; |
15638 | } else if (strcmp(z, "-column" ) == 0) { |
15639 | data.mode = MODE_Column; |
15640 | } else if (strcmp(z, "-csv" ) == 0) { |
15641 | data.mode = MODE_Csv; |
15642 | memcpy(data.colSeparator, "," , 2); |
15643 | #ifdef SQLITE_HAVE_ZLIB |
15644 | } else if (strcmp(z, "-zip" ) == 0) { |
15645 | data.openMode = SHELL_OPEN_ZIPFILE; |
15646 | #endif |
15647 | } else if (strcmp(z, "-append" ) == 0) { |
15648 | data.openMode = SHELL_OPEN_APPENDVFS; |
15649 | } else if (strcmp(z, "-readonly" ) == 0) { |
15650 | data.openMode = SHELL_OPEN_READONLY; |
15651 | } else if (strcmp(z, "-ascii" ) == 0) { |
15652 | data.mode = MODE_Ascii; |
15653 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit); |
15654 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record); |
15655 | } else if (strcmp(z, "-separator" ) == 0) { |
15656 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, "%s" , cmdline_option_value(argc, argv, ++i)); |
15657 | } else if (strcmp(z, "-newline" ) == 0) { |
15658 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, "%s" , cmdline_option_value(argc, argv, ++i)); |
15659 | } else if (strcmp(z, "-nullvalue" ) == 0) { |
15660 | sqlite3_snprintf(sizeof(data.nullValue), data.nullValue, "%s" , cmdline_option_value(argc, argv, ++i)); |
15661 | } else if (strcmp(z, "-header" ) == 0) { |
15662 | data.showHeader = 1; |
15663 | } else if (strcmp(z, "-noheader" ) == 0) { |
15664 | data.showHeader = 0; |
15665 | } else if (strcmp(z, "-echo" ) == 0) { |
15666 | ShellSetFlag(&data, SHFLG_Echo); |
15667 | } else if (strcmp(z, "-eqp" ) == 0) { |
15668 | data.autoEQP = AUTOEQP_on; |
15669 | } else if (strcmp(z, "-eqpfull" ) == 0) { |
15670 | data.autoEQP = AUTOEQP_full; |
15671 | } else if (strcmp(z, "-stats" ) == 0) { |
15672 | data.statsOn = 1; |
15673 | } else if (strcmp(z, "-scanstats" ) == 0) { |
15674 | data.scanstatsOn = 1; |
15675 | } else if (strcmp(z, "-backslash" ) == 0) { |
15676 | /* Undocumented command-line option: -backslash |
15677 | ** Causes C-style backslash escapes to be evaluated in SQL statements |
15678 | ** prior to sending the SQL into SQLite. Useful for injecting |
15679 | ** crazy bytes in the middle of SQL statements for testing and debugging. |
15680 | */ |
15681 | ShellSetFlag(&data, SHFLG_Backslash); |
15682 | } else if (strcmp(z, "-bail" ) == 0) { |
15683 | bail_on_error = 1; |
15684 | } else if (strcmp(z, "-version" ) == 0) { |
15685 | printf("%s %s\n" , sqlite3_libversion(), sqlite3_sourceid()); |
15686 | return 0; |
15687 | } else if (strcmp(z, "-interactive" ) == 0) { |
15688 | stdin_is_interactive = 1; |
15689 | } else if (strcmp(z, "-batch" ) == 0) { |
15690 | stdin_is_interactive = 0; |
15691 | } else if (strcmp(z, "-heap" ) == 0) { |
15692 | i++; |
15693 | } else if (strcmp(z, "-pagecache" ) == 0) { |
15694 | i += 2; |
15695 | } else if (strcmp(z, "-lookaside" ) == 0) { |
15696 | i += 2; |
15697 | } else if (strcmp(z, "-mmap" ) == 0) { |
15698 | i++; |
15699 | } else if (strcmp(z, "-vfs" ) == 0) { |
15700 | i++; |
15701 | #ifdef SQLITE_ENABLE_VFSTRACE |
15702 | } else if (strcmp(z, "-vfstrace" ) == 0) { |
15703 | i++; |
15704 | #endif |
15705 | #ifdef SQLITE_ENABLE_MULTIPLEX |
15706 | } else if (strcmp(z, "-multiplex" ) == 0) { |
15707 | i++; |
15708 | #endif |
15709 | } else if (strcmp(z, "-help" ) == 0) { |
15710 | usage(1); |
15711 | } else if (strcmp(z, "-cmd" ) == 0) { |
15712 | /* Run commands that follow -cmd first and separately from commands |
15713 | ** that simply appear on the command-line. This seems goofy. It would |
15714 | ** be better if all commands ran in the order that they appear. But |
15715 | ** we retain the goofy behavior for historical compatibility. */ |
15716 | if (i == argc - 1) |
15717 | break; |
15718 | z = cmdline_option_value(argc, argv, ++i); |
15719 | if (z[0] == '.') { |
15720 | rc = do_meta_command(z, &data); |
15721 | if (rc && bail_on_error) |
15722 | return rc == 2 ? 0 : rc; |
15723 | } else { |
15724 | open_db(&data, 0); |
15725 | rc = shell_exec(&data, z, &zErrMsg); |
15726 | if (zErrMsg != 0) { |
15727 | utf8_printf(stderr, "Error: %s\n" , zErrMsg); |
15728 | if (bail_on_error) |
15729 | return rc != 0 ? rc : 1; |
15730 | } else if (rc != 0) { |
15731 | utf8_printf(stderr, "Error: unable to process SQL \"%s\"\n" , z); |
15732 | if (bail_on_error) |
15733 | return rc; |
15734 | } |
15735 | } |
15736 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
15737 | } else if (strncmp(z, "-A" , 2) == 0) { |
15738 | if (nCmd > 0) { |
15739 | utf8_printf(stderr, |
15740 | "Error: cannot mix regular SQL or dot-commands" |
15741 | " with \"%s\"\n" , |
15742 | z); |
15743 | return 1; |
15744 | } |
15745 | open_db(&data, 0); |
15746 | if (z[2]) { |
15747 | argv[i] = &z[2]; |
15748 | arDotCommand(&data, argv + (i - 1), argc - (i - 1)); |
15749 | } else { |
15750 | arDotCommand(&data, argv + i, argc - i); |
15751 | } |
15752 | readStdin = 0; |
15753 | break; |
15754 | #endif |
15755 | } else { |
15756 | utf8_printf(stderr, "%s: Error: unknown option: %s\n" , Argv0, z); |
15757 | raw_printf(stderr, "Use -help for a list of options.\n" ); |
15758 | return 1; |
15759 | } |
15760 | data.cMode = data.mode; |
15761 | } |
15762 | |
15763 | if (!readStdin) { |
15764 | /* Run all arguments that do not begin with '-' as if they were separate |
15765 | ** command-line inputs, except for the argToSkip argument which contains |
15766 | ** the database filename. |
15767 | */ |
15768 | for (i = 0; i < nCmd; i++) { |
15769 | if (azCmd[i][0] == '.') { |
15770 | rc = do_meta_command(azCmd[i], &data); |
15771 | if (rc) |
15772 | return rc == 2 ? 0 : rc; |
15773 | } else { |
15774 | open_db(&data, 0); |
15775 | rc = shell_exec(&data, azCmd[i], &zErrMsg); |
15776 | if (zErrMsg != 0) { |
15777 | utf8_printf(stderr, "Error: %s\n" , zErrMsg); |
15778 | return rc != 0 ? rc : 1; |
15779 | } else if (rc != 0) { |
15780 | utf8_printf(stderr, "Error: unable to process SQL: %s\n" , azCmd[i]); |
15781 | return rc; |
15782 | } |
15783 | } |
15784 | } |
15785 | free(azCmd); |
15786 | } else { |
15787 | /* Run commands received from standard input |
15788 | */ |
15789 | if (stdin_is_interactive) { |
15790 | char *zHome; |
15791 | char *zHistory = 0; |
15792 | int nHistory; |
15793 | printf("SQLite version %s %.19s\n" /*extra-version-info*/ |
15794 | "Enter \".help\" for usage hints.\n" , |
15795 | sqlite3_libversion(), sqlite3_sourceid()); |
15796 | if (warnInmemoryDb) { |
15797 | printf("Connected to a " ); |
15798 | printBold("transient in-memory database" ); |
15799 | printf(".\nUse \".open FILENAME\" to reopen on a " |
15800 | "persistent database.\n" ); |
15801 | } |
15802 | zHome = find_home_dir(0); |
15803 | if (zHome) { |
15804 | nHistory = strlen30(zHome) + 20; |
15805 | if ((zHistory = malloc(nHistory)) != 0) { |
15806 | sqlite3_snprintf(nHistory, zHistory, "%s/.sqlite_history" , zHome); |
15807 | } |
15808 | } |
15809 | if (zHistory) { |
15810 | shell_read_history(zHistory); |
15811 | } |
15812 | #if HAVE_READLINE || HAVE_EDITLINE |
15813 | rl_attempted_completion_function = readline_completion; |
15814 | #elif HAVE_LINENOISE |
15815 | linenoiseSetCompletionCallback(linenoise_completion); |
15816 | #endif |
15817 | rc = process_input(&data, 0); |
15818 | if (zHistory) { |
15819 | shell_stifle_history(2000); |
15820 | shell_write_history(zHistory); |
15821 | free(zHistory); |
15822 | } |
15823 | } else { |
15824 | rc = process_input(&data, stdin); |
15825 | } |
15826 | } |
15827 | set_table_name(&data, 0); |
15828 | if (data.db) { |
15829 | session_close_all(&data); |
15830 | sqlite3_close(data.db); |
15831 | } |
15832 | sqlite3_free(data.zFreeOnClose); |
15833 | find_home_dir(1); |
15834 | output_reset(&data); |
15835 | data.doXdgOpen = 0; |
15836 | clearTempFile(&data); |
15837 | #if !SQLITE_SHELL_IS_UTF8 |
15838 | for (i = 0; i < argc; i++) |
15839 | free(argv[i]); |
15840 | free(argv); |
15841 | #endif |
15842 | return rc; |
15843 | } |
15844 | |