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