Return to shell.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / elwix / files / sqlite / dist |
1.2 ! misho 1: /* ! 2: ** 2001 September 15 ! 3: ** ! 4: ** The author disclaims copyright to this source code. In place of ! 5: ** a legal notice, here is a blessing: ! 6: ** ! 7: ** May you do good and not evil. ! 8: ** May you find forgiveness for yourself and forgive others. ! 9: ** May you share freely, never taking more than you give. ! 10: ** ! 11: ************************************************************************* ! 12: ** This file contains code to implement the "sqlite" command line ! 13: ** utility for accessing SQLite databases. ! 14: */ ! 15: #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) ! 16: /* This needs to come before any includes for MSVC compiler */ ! 17: #define _CRT_SECURE_NO_WARNINGS ! 18: #endif ! 19: ! 20: /* ! 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: #include <ctype.h> ! 37: #include <stdarg.h> ! 38: ! 39: #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) ! 40: # include <signal.h> ! 41: # if !defined(__RTP__) && !defined(_WRS_KERNEL) ! 42: # include <pwd.h> ! 43: # endif ! 44: # include <unistd.h> ! 45: # include <sys/types.h> ! 46: #endif ! 47: ! 48: #ifdef __OS2__ ! 49: # include <unistd.h> ! 50: #endif ! 51: ! 52: #ifdef HAVE_EDITLINE ! 53: # include <editline/editline.h> ! 54: #endif ! 55: #if defined(HAVE_READLINE) && HAVE_READLINE==1 ! 56: # include <readline/readline.h> ! 57: # include <readline/history.h> ! 58: #endif ! 59: #if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1) ! 60: # define readline(p) local_getline(p,stdin) ! 61: # define add_history(X) ! 62: # define read_history(X) ! 63: # define write_history(X) ! 64: # define stifle_history(X) ! 65: #endif ! 66: ! 67: #if defined(_WIN32) || defined(WIN32) ! 68: # include <io.h> ! 69: #define isatty(h) _isatty(h) ! 70: #define access(f,m) _access((f),(m)) ! 71: #else ! 72: /* Make sure isatty() has a prototype. ! 73: */ ! 74: extern int isatty(int); ! 75: #endif ! 76: ! 77: #if defined(_WIN32_WCE) ! 78: /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() ! 79: * thus we always assume that we have a console. That can be ! 80: * overridden with the -batch command line option. ! 81: */ ! 82: #define isatty(x) 1 ! 83: #endif ! 84: ! 85: /* True if the timer is enabled */ ! 86: static int enableTimer = 0; ! 87: ! 88: /* ctype macros that work with signed characters */ ! 89: #define IsSpace(X) isspace((unsigned char)X) ! 90: #define IsDigit(X) isdigit((unsigned char)X) ! 91: #define ToLower(X) (char)tolower((unsigned char)X) ! 92: ! 93: #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) ! 94: #include <sys/time.h> ! 95: #include <sys/resource.h> ! 96: ! 97: /* Saved resource information for the beginning of an operation */ ! 98: static struct rusage sBegin; ! 99: ! 100: /* ! 101: ** Begin timing an operation ! 102: */ ! 103: static void beginTimer(void){ ! 104: if( enableTimer ){ ! 105: getrusage(RUSAGE_SELF, &sBegin); ! 106: } ! 107: } ! 108: ! 109: /* Return the difference of two time_structs in seconds */ ! 110: static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ ! 111: return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + ! 112: (double)(pEnd->tv_sec - pStart->tv_sec); ! 113: } ! 114: ! 115: /* ! 116: ** Print the timing results. ! 117: */ ! 118: static void endTimer(void){ ! 119: if( enableTimer ){ ! 120: struct rusage sEnd; ! 121: getrusage(RUSAGE_SELF, &sEnd); ! 122: printf("CPU Time: user %f sys %f\n", ! 123: timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), ! 124: timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); ! 125: } ! 126: } ! 127: ! 128: #define BEGIN_TIMER beginTimer() ! 129: #define END_TIMER endTimer() ! 130: #define HAS_TIMER 1 ! 131: ! 132: #elif (defined(_WIN32) || defined(WIN32)) ! 133: ! 134: #include <windows.h> ! 135: ! 136: /* Saved resource information for the beginning of an operation */ ! 137: static HANDLE hProcess; ! 138: static FILETIME ftKernelBegin; ! 139: static FILETIME ftUserBegin; ! 140: typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); ! 141: static GETPROCTIMES getProcessTimesAddr = NULL; ! 142: ! 143: /* ! 144: ** Check to see if we have timer support. Return 1 if necessary ! 145: ** support found (or found previously). ! 146: */ ! 147: static int hasTimer(void){ ! 148: if( getProcessTimesAddr ){ ! 149: return 1; ! 150: } else { ! 151: /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions. ! 152: ** See if the version we are running on has it, and if it does, save off ! 153: ** a pointer to it and the current process handle. ! 154: */ ! 155: hProcess = GetCurrentProcess(); ! 156: if( hProcess ){ ! 157: HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); ! 158: if( NULL != hinstLib ){ ! 159: getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); ! 160: if( NULL != getProcessTimesAddr ){ ! 161: return 1; ! 162: } ! 163: FreeLibrary(hinstLib); ! 164: } ! 165: } ! 166: } ! 167: return 0; ! 168: } ! 169: ! 170: /* ! 171: ** Begin timing an operation ! 172: */ ! 173: static void beginTimer(void){ ! 174: if( enableTimer && getProcessTimesAddr ){ ! 175: FILETIME ftCreation, ftExit; ! 176: getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin); ! 177: } ! 178: } ! 179: ! 180: /* Return the difference of two FILETIME structs in seconds */ ! 181: static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ ! 182: sqlite_int64 i64Start = *((sqlite_int64 *) pStart); ! 183: sqlite_int64 i64End = *((sqlite_int64 *) pEnd); ! 184: return (double) ((i64End - i64Start) / 10000000.0); ! 185: } ! 186: ! 187: /* ! 188: ** Print the timing results. ! 189: */ ! 190: static void endTimer(void){ ! 191: if( enableTimer && getProcessTimesAddr){ ! 192: FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; ! 193: getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd); ! 194: printf("CPU Time: user %f sys %f\n", ! 195: timeDiff(&ftUserBegin, &ftUserEnd), ! 196: timeDiff(&ftKernelBegin, &ftKernelEnd)); ! 197: } ! 198: } ! 199: ! 200: #define BEGIN_TIMER beginTimer() ! 201: #define END_TIMER endTimer() ! 202: #define HAS_TIMER hasTimer() ! 203: ! 204: #else ! 205: #define BEGIN_TIMER ! 206: #define END_TIMER ! 207: #define HAS_TIMER 0 ! 208: #endif ! 209: ! 210: /* ! 211: ** Used to prevent warnings about unused parameters ! 212: */ ! 213: #define UNUSED_PARAMETER(x) (void)(x) ! 214: ! 215: /* ! 216: ** If the following flag is set, then command execution stops ! 217: ** at an error if we are not interactive. ! 218: */ ! 219: static int bail_on_error = 0; ! 220: ! 221: /* ! 222: ** Threat stdin as an interactive input if the following variable ! 223: ** is true. Otherwise, assume stdin is connected to a file or pipe. ! 224: */ ! 225: static int stdin_is_interactive = 1; ! 226: ! 227: /* ! 228: ** The following is the open SQLite database. We make a pointer ! 229: ** to this database a static variable so that it can be accessed ! 230: ** by the SIGINT handler to interrupt database processing. ! 231: */ ! 232: static sqlite3 *db = 0; ! 233: ! 234: /* ! 235: ** True if an interrupt (Control-C) has been received. ! 236: */ ! 237: static volatile int seenInterrupt = 0; ! 238: ! 239: /* ! 240: ** This is the name of our program. It is set in main(), used ! 241: ** in a number of other places, mostly for error messages. ! 242: */ ! 243: static char *Argv0; ! 244: ! 245: /* ! 246: ** Prompt strings. Initialized in main. Settable with ! 247: ** .prompt main continue ! 248: */ ! 249: static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ ! 250: static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ ! 251: ! 252: /* ! 253: ** Write I/O traces to the following stream. ! 254: */ ! 255: #ifdef SQLITE_ENABLE_IOTRACE ! 256: static FILE *iotrace = 0; ! 257: #endif ! 258: ! 259: /* ! 260: ** This routine works like printf in that its first argument is a ! 261: ** format string and subsequent arguments are values to be substituted ! 262: ** in place of % fields. The result of formatting this string ! 263: ** is written to iotrace. ! 264: */ ! 265: #ifdef SQLITE_ENABLE_IOTRACE ! 266: static void iotracePrintf(const char *zFormat, ...){ ! 267: va_list ap; ! 268: char *z; ! 269: if( iotrace==0 ) return; ! 270: va_start(ap, zFormat); ! 271: z = sqlite3_vmprintf(zFormat, ap); ! 272: va_end(ap); ! 273: fprintf(iotrace, "%s", z); ! 274: sqlite3_free(z); ! 275: } ! 276: #endif ! 277: ! 278: ! 279: /* ! 280: ** Determines if a string is a number of not. ! 281: */ ! 282: static int isNumber(const char *z, int *realnum){ ! 283: if( *z=='-' || *z=='+' ) z++; ! 284: if( !IsDigit(*z) ){ ! 285: return 0; ! 286: } ! 287: z++; ! 288: if( realnum ) *realnum = 0; ! 289: while( IsDigit(*z) ){ z++; } ! 290: if( *z=='.' ){ ! 291: z++; ! 292: if( !IsDigit(*z) ) return 0; ! 293: while( IsDigit(*z) ){ z++; } ! 294: if( realnum ) *realnum = 1; ! 295: } ! 296: if( *z=='e' || *z=='E' ){ ! 297: z++; ! 298: if( *z=='+' || *z=='-' ) z++; ! 299: if( !IsDigit(*z) ) return 0; ! 300: while( IsDigit(*z) ){ z++; } ! 301: if( realnum ) *realnum = 1; ! 302: } ! 303: return *z==0; ! 304: } ! 305: ! 306: /* ! 307: ** A global char* and an SQL function to access its current value ! 308: ** from within an SQL statement. This program used to use the ! 309: ** sqlite_exec_printf() API to substitue a string into an SQL statement. ! 310: ** The correct way to do this with sqlite3 is to use the bind API, but ! 311: ** since the shell is built around the callback paradigm it would be a lot ! 312: ** of work. Instead just use this hack, which is quite harmless. ! 313: */ ! 314: static const char *zShellStatic = 0; ! 315: static void shellstaticFunc( ! 316: sqlite3_context *context, ! 317: int argc, ! 318: sqlite3_value **argv ! 319: ){ ! 320: assert( 0==argc ); ! 321: assert( zShellStatic ); ! 322: UNUSED_PARAMETER(argc); ! 323: UNUSED_PARAMETER(argv); ! 324: sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC); ! 325: } ! 326: ! 327: ! 328: /* ! 329: ** This routine reads a line of text from FILE in, stores ! 330: ** the text in memory obtained from malloc() and returns a pointer ! 331: ** to the text. NULL is returned at end of file, or if malloc() ! 332: ** fails. ! 333: ** ! 334: ** The interface is like "readline" but no command-line editing ! 335: ** is done. ! 336: */ ! 337: static char *local_getline(char *zPrompt, FILE *in){ ! 338: char *zLine; ! 339: int nLine; ! 340: int n; ! 341: ! 342: if( zPrompt && *zPrompt ){ ! 343: printf("%s",zPrompt); ! 344: fflush(stdout); ! 345: } ! 346: nLine = 100; ! 347: zLine = malloc( nLine ); ! 348: if( zLine==0 ) return 0; ! 349: n = 0; ! 350: while( 1 ){ ! 351: if( n+100>nLine ){ ! 352: nLine = nLine*2 + 100; ! 353: zLine = realloc(zLine, nLine); ! 354: if( zLine==0 ) return 0; ! 355: } ! 356: if( fgets(&zLine[n], nLine - n, in)==0 ){ ! 357: if( n==0 ){ ! 358: free(zLine); ! 359: return 0; ! 360: } ! 361: zLine[n] = 0; ! 362: break; ! 363: } ! 364: while( zLine[n] ){ n++; } ! 365: if( n>0 && zLine[n-1]=='\n' ){ ! 366: n--; ! 367: if( n>0 && zLine[n-1]=='\r' ) n--; ! 368: zLine[n] = 0; ! 369: break; ! 370: } ! 371: } ! 372: zLine = realloc( zLine, n+1 ); ! 373: return zLine; ! 374: } ! 375: ! 376: /* ! 377: ** Retrieve a single line of input text. ! 378: ** ! 379: ** zPrior is a string of prior text retrieved. If not the empty ! 380: ** string, then issue a continuation prompt. ! 381: */ ! 382: static char *one_input_line(const char *zPrior, FILE *in){ ! 383: char *zPrompt; ! 384: char *zResult; ! 385: if( in!=0 ){ ! 386: return local_getline(0, in); ! 387: } ! 388: if( zPrior && zPrior[0] ){ ! 389: zPrompt = continuePrompt; ! 390: }else{ ! 391: zPrompt = mainPrompt; ! 392: } ! 393: zResult = readline(zPrompt); ! 394: #if defined(HAVE_READLINE) && HAVE_READLINE==1 ! 395: if( zResult && *zResult ) add_history(zResult); ! 396: #endif ! 397: return zResult; ! 398: } ! 399: ! 400: struct previous_mode_data { ! 401: int valid; /* Is there legit data in here? */ ! 402: int mode; ! 403: int showHeader; ! 404: int colWidth[100]; ! 405: }; ! 406: ! 407: /* ! 408: ** An pointer to an instance of this structure is passed from ! 409: ** the main program to the callback. This is used to communicate ! 410: ** state and mode information. ! 411: */ ! 412: struct callback_data { ! 413: sqlite3 *db; /* The database */ ! 414: int echoOn; /* True to echo input commands */ ! 415: int statsOn; /* True to display memory stats before each finalize */ ! 416: int cnt; /* Number of records displayed so far */ ! 417: FILE *out; /* Write results here */ ! 418: int nErr; /* Number of errors seen */ ! 419: int mode; /* An output mode setting */ ! 420: int writableSchema; /* True if PRAGMA writable_schema=ON */ ! 421: int showHeader; /* True to show column names in List or Column mode */ ! 422: char *zDestTable; /* Name of destination table when MODE_Insert */ ! 423: char separator[20]; /* Separator character for MODE_List */ ! 424: int colWidth[100]; /* Requested width of each column when in column mode*/ ! 425: int actualWidth[100]; /* Actual width of each column */ ! 426: char nullvalue[20]; /* The text to print when a NULL comes back from ! 427: ** the database */ ! 428: struct previous_mode_data explainPrev; ! 429: /* Holds the mode information just before ! 430: ** .explain ON */ ! 431: char outfile[FILENAME_MAX]; /* Filename for *out */ ! 432: const char *zDbFilename; /* name of the database file */ ! 433: const char *zVfs; /* Name of VFS to use */ ! 434: sqlite3_stmt *pStmt; /* Current statement if any. */ ! 435: FILE *pLog; /* Write log output here */ ! 436: }; ! 437: ! 438: /* ! 439: ** These are the allowed modes. ! 440: */ ! 441: #define MODE_Line 0 /* One column per line. Blank line between records */ ! 442: #define MODE_Column 1 /* One record per line in neat columns */ ! 443: #define MODE_List 2 /* One record per line with a separator */ ! 444: #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ ! 445: #define MODE_Html 4 /* Generate an XHTML table */ ! 446: #define MODE_Insert 5 /* Generate SQL "insert" statements */ ! 447: #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ ! 448: #define MODE_Csv 7 /* Quote strings, numbers are plain */ ! 449: #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ ! 450: ! 451: static const char *modeDescr[] = { ! 452: "line", ! 453: "column", ! 454: "list", ! 455: "semi", ! 456: "html", ! 457: "insert", ! 458: "tcl", ! 459: "csv", ! 460: "explain", ! 461: }; ! 462: ! 463: /* ! 464: ** Number of elements in an array ! 465: */ ! 466: #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) ! 467: ! 468: /* ! 469: ** Compute a string length that is limited to what can be stored in ! 470: ** lower 30 bits of a 32-bit signed integer. ! 471: */ ! 472: static int strlen30(const char *z){ ! 473: const char *z2 = z; ! 474: while( *z2 ){ z2++; } ! 475: return 0x3fffffff & (int)(z2 - z); ! 476: } ! 477: ! 478: /* ! 479: ** A callback for the sqlite3_log() interface. ! 480: */ ! 481: static void shellLog(void *pArg, int iErrCode, const char *zMsg){ ! 482: struct callback_data *p = (struct callback_data*)pArg; ! 483: if( p->pLog==0 ) return; ! 484: fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); ! 485: fflush(p->pLog); ! 486: } ! 487: ! 488: /* ! 489: ** Output the given string as a hex-encoded blob (eg. X'1234' ) ! 490: */ ! 491: static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ ! 492: int i; ! 493: char *zBlob = (char *)pBlob; ! 494: fprintf(out,"X'"); ! 495: for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]); } ! 496: fprintf(out,"'"); ! 497: } ! 498: ! 499: /* ! 500: ** Output the given string as a quoted string using SQL quoting conventions. ! 501: */ ! 502: static void output_quoted_string(FILE *out, const char *z){ ! 503: int i; ! 504: int nSingle = 0; ! 505: for(i=0; z[i]; i++){ ! 506: if( z[i]=='\'' ) nSingle++; ! 507: } ! 508: if( nSingle==0 ){ ! 509: fprintf(out,"'%s'",z); ! 510: }else{ ! 511: fprintf(out,"'"); ! 512: while( *z ){ ! 513: for(i=0; z[i] && z[i]!='\''; i++){} ! 514: if( i==0 ){ ! 515: fprintf(out,"''"); ! 516: z++; ! 517: }else if( z[i]=='\'' ){ ! 518: fprintf(out,"%.*s''",i,z); ! 519: z += i+1; ! 520: }else{ ! 521: fprintf(out,"%s",z); ! 522: break; ! 523: } ! 524: } ! 525: fprintf(out,"'"); ! 526: } ! 527: } ! 528: ! 529: /* ! 530: ** Output the given string as a quoted according to C or TCL quoting rules. ! 531: */ ! 532: static void output_c_string(FILE *out, const char *z){ ! 533: unsigned int c; ! 534: fputc('"', out); ! 535: while( (c = *(z++))!=0 ){ ! 536: if( c=='\\' ){ ! 537: fputc(c, out); ! 538: fputc(c, out); ! 539: }else if( c=='\t' ){ ! 540: fputc('\\', out); ! 541: fputc('t', out); ! 542: }else if( c=='\n' ){ ! 543: fputc('\\', out); ! 544: fputc('n', out); ! 545: }else if( c=='\r' ){ ! 546: fputc('\\', out); ! 547: fputc('r', out); ! 548: }else if( !isprint(c) ){ ! 549: fprintf(out, "\\%03o", c&0xff); ! 550: }else{ ! 551: fputc(c, out); ! 552: } ! 553: } ! 554: fputc('"', out); ! 555: } ! 556: ! 557: /* ! 558: ** Output the given string with characters that are special to ! 559: ** HTML escaped. ! 560: */ ! 561: static void output_html_string(FILE *out, const char *z){ ! 562: int i; ! 563: while( *z ){ ! 564: for(i=0; z[i] ! 565: && z[i]!='<' ! 566: && z[i]!='&' ! 567: && z[i]!='>' ! 568: && z[i]!='\"' ! 569: && z[i]!='\''; ! 570: i++){} ! 571: if( i>0 ){ ! 572: fprintf(out,"%.*s",i,z); ! 573: } ! 574: if( z[i]=='<' ){ ! 575: fprintf(out,"<"); ! 576: }else if( z[i]=='&' ){ ! 577: fprintf(out,"&"); ! 578: }else if( z[i]=='>' ){ ! 579: fprintf(out,">"); ! 580: }else if( z[i]=='\"' ){ ! 581: fprintf(out,"""); ! 582: }else if( z[i]=='\'' ){ ! 583: fprintf(out,"'"); ! 584: }else{ ! 585: break; ! 586: } ! 587: z += i + 1; ! 588: } ! 589: } ! 590: ! 591: /* ! 592: ** If a field contains any character identified by a 1 in the following ! 593: ** array, then the string must be quoted for CSV. ! 594: */ ! 595: static const char needCsvQuote[] = { ! 596: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 597: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 598: 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ! 599: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 600: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 601: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 602: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 603: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ! 604: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 605: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 606: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 607: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 608: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 609: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 610: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 611: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 612: }; ! 613: ! 614: /* ! 615: ** Output a single term of CSV. Actually, p->separator is used for ! 616: ** the separator, which may or may not be a comma. p->nullvalue is ! 617: ** the null value. Strings are quoted using ANSI-C rules. Numbers ! 618: ** appear outside of quotes. ! 619: */ ! 620: static void output_csv(struct callback_data *p, const char *z, int bSep){ ! 621: FILE *out = p->out; ! 622: if( z==0 ){ ! 623: fprintf(out,"%s",p->nullvalue); ! 624: }else{ ! 625: int i; ! 626: int nSep = strlen30(p->separator); ! 627: for(i=0; z[i]; i++){ ! 628: if( needCsvQuote[((unsigned char*)z)[i]] ! 629: || (z[i]==p->separator[0] && ! 630: (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){ ! 631: i = 0; ! 632: break; ! 633: } ! 634: } ! 635: if( i==0 ){ ! 636: putc('"', out); ! 637: for(i=0; z[i]; i++){ ! 638: if( z[i]=='"' ) putc('"', out); ! 639: putc(z[i], out); ! 640: } ! 641: putc('"', out); ! 642: }else{ ! 643: fprintf(out, "%s", z); ! 644: } ! 645: } ! 646: if( bSep ){ ! 647: fprintf(p->out, "%s", p->separator); ! 648: } ! 649: } ! 650: ! 651: #ifdef SIGINT ! 652: /* ! 653: ** This routine runs when the user presses Ctrl-C ! 654: */ ! 655: static void interrupt_handler(int NotUsed){ ! 656: UNUSED_PARAMETER(NotUsed); ! 657: seenInterrupt = 1; ! 658: if( db ) sqlite3_interrupt(db); ! 659: } ! 660: #endif ! 661: ! 662: /* ! 663: ** This is the callback routine that the shell ! 664: ** invokes for each row of a query result. ! 665: */ ! 666: static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){ ! 667: int i; ! 668: struct callback_data *p = (struct callback_data*)pArg; ! 669: ! 670: switch( p->mode ){ ! 671: case MODE_Line: { ! 672: int w = 5; ! 673: if( azArg==0 ) break; ! 674: for(i=0; i<nArg; i++){ ! 675: int len = strlen30(azCol[i] ? azCol[i] : ""); ! 676: if( len>w ) w = len; ! 677: } ! 678: if( p->cnt++>0 ) fprintf(p->out,"\n"); ! 679: for(i=0; i<nArg; i++){ ! 680: fprintf(p->out,"%*s = %s\n", w, azCol[i], ! 681: azArg[i] ? azArg[i] : p->nullvalue); ! 682: } ! 683: break; ! 684: } ! 685: case MODE_Explain: ! 686: case MODE_Column: { ! 687: if( p->cnt++==0 ){ ! 688: for(i=0; i<nArg; i++){ ! 689: int w, n; ! 690: if( i<ArraySize(p->colWidth) ){ ! 691: w = p->colWidth[i]; ! 692: }else{ ! 693: w = 0; ! 694: } ! 695: if( w<=0 ){ ! 696: w = strlen30(azCol[i] ? azCol[i] : ""); ! 697: if( w<10 ) w = 10; ! 698: n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue); ! 699: if( w<n ) w = n; ! 700: } ! 701: if( i<ArraySize(p->actualWidth) ){ ! 702: p->actualWidth[i] = w; ! 703: } ! 704: if( p->showHeader ){ ! 705: fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " "); ! 706: } ! 707: } ! 708: if( p->showHeader ){ ! 709: for(i=0; i<nArg; i++){ ! 710: int w; ! 711: if( i<ArraySize(p->actualWidth) ){ ! 712: w = p->actualWidth[i]; ! 713: }else{ ! 714: w = 10; ! 715: } ! 716: fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------" ! 717: "----------------------------------------------------------", ! 718: i==nArg-1 ? "\n": " "); ! 719: } ! 720: } ! 721: } ! 722: if( azArg==0 ) break; ! 723: for(i=0; i<nArg; i++){ ! 724: int w; ! 725: if( i<ArraySize(p->actualWidth) ){ ! 726: w = p->actualWidth[i]; ! 727: }else{ ! 728: w = 10; ! 729: } ! 730: if( p->mode==MODE_Explain && azArg[i] && ! 731: strlen30(azArg[i])>w ){ ! 732: w = strlen30(azArg[i]); ! 733: } ! 734: fprintf(p->out,"%-*.*s%s",w,w, ! 735: azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); ! 736: } ! 737: break; ! 738: } ! 739: case MODE_Semi: ! 740: case MODE_List: { ! 741: if( p->cnt++==0 && p->showHeader ){ ! 742: for(i=0; i<nArg; i++){ ! 743: fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator); ! 744: } ! 745: } ! 746: if( azArg==0 ) break; ! 747: for(i=0; i<nArg; i++){ ! 748: char *z = azArg[i]; ! 749: if( z==0 ) z = p->nullvalue; ! 750: fprintf(p->out, "%s", z); ! 751: if( i<nArg-1 ){ ! 752: fprintf(p->out, "%s", p->separator); ! 753: }else if( p->mode==MODE_Semi ){ ! 754: fprintf(p->out, ";\n"); ! 755: }else{ ! 756: fprintf(p->out, "\n"); ! 757: } ! 758: } ! 759: break; ! 760: } ! 761: case MODE_Html: { ! 762: if( p->cnt++==0 && p->showHeader ){ ! 763: fprintf(p->out,"<TR>"); ! 764: for(i=0; i<nArg; i++){ ! 765: fprintf(p->out,"<TH>"); ! 766: output_html_string(p->out, azCol[i]); ! 767: fprintf(p->out,"</TH>\n"); ! 768: } ! 769: fprintf(p->out,"</TR>\n"); ! 770: } ! 771: if( azArg==0 ) break; ! 772: fprintf(p->out,"<TR>"); ! 773: for(i=0; i<nArg; i++){ ! 774: fprintf(p->out,"<TD>"); ! 775: output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); ! 776: fprintf(p->out,"</TD>\n"); ! 777: } ! 778: fprintf(p->out,"</TR>\n"); ! 779: break; ! 780: } ! 781: case MODE_Tcl: { ! 782: if( p->cnt++==0 && p->showHeader ){ ! 783: for(i=0; i<nArg; i++){ ! 784: output_c_string(p->out,azCol[i] ? azCol[i] : ""); ! 785: fprintf(p->out, "%s", p->separator); ! 786: } ! 787: fprintf(p->out,"\n"); ! 788: } ! 789: if( azArg==0 ) break; ! 790: for(i=0; i<nArg; i++){ ! 791: output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); ! 792: fprintf(p->out, "%s", p->separator); ! 793: } ! 794: fprintf(p->out,"\n"); ! 795: break; ! 796: } ! 797: case MODE_Csv: { ! 798: if( p->cnt++==0 && p->showHeader ){ ! 799: for(i=0; i<nArg; i++){ ! 800: output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); ! 801: } ! 802: fprintf(p->out,"\n"); ! 803: } ! 804: if( azArg==0 ) break; ! 805: for(i=0; i<nArg; i++){ ! 806: output_csv(p, azArg[i], i<nArg-1); ! 807: } ! 808: fprintf(p->out,"\n"); ! 809: break; ! 810: } ! 811: case MODE_Insert: { ! 812: p->cnt++; ! 813: if( azArg==0 ) break; ! 814: fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable); ! 815: for(i=0; i<nArg; i++){ ! 816: char *zSep = i>0 ? ",": ""; ! 817: if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ ! 818: fprintf(p->out,"%sNULL",zSep); ! 819: }else if( aiType && aiType[i]==SQLITE_TEXT ){ ! 820: if( zSep[0] ) fprintf(p->out,"%s",zSep); ! 821: output_quoted_string(p->out, azArg[i]); ! 822: }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){ ! 823: fprintf(p->out,"%s%s",zSep, azArg[i]); ! 824: }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ ! 825: const void *pBlob = sqlite3_column_blob(p->pStmt, i); ! 826: int nBlob = sqlite3_column_bytes(p->pStmt, i); ! 827: if( zSep[0] ) fprintf(p->out,"%s",zSep); ! 828: output_hex_blob(p->out, pBlob, nBlob); ! 829: }else if( isNumber(azArg[i], 0) ){ ! 830: fprintf(p->out,"%s%s",zSep, azArg[i]); ! 831: }else{ ! 832: if( zSep[0] ) fprintf(p->out,"%s",zSep); ! 833: output_quoted_string(p->out, azArg[i]); ! 834: } ! 835: } ! 836: fprintf(p->out,");\n"); ! 837: break; ! 838: } ! 839: } ! 840: return 0; ! 841: } ! 842: ! 843: /* ! 844: ** This is the callback routine that the SQLite library ! 845: ** invokes for each row of a query result. ! 846: */ ! 847: static int callback(void *pArg, int nArg, char **azArg, char **azCol){ ! 848: /* since we don't have type info, call the shell_callback with a NULL value */ ! 849: return shell_callback(pArg, nArg, azArg, azCol, NULL); ! 850: } ! 851: ! 852: /* ! 853: ** Set the destination table field of the callback_data structure to ! 854: ** the name of the table given. Escape any quote characters in the ! 855: ** table name. ! 856: */ ! 857: static void set_table_name(struct callback_data *p, const char *zName){ ! 858: int i, n; ! 859: int needQuote; ! 860: char *z; ! 861: ! 862: if( p->zDestTable ){ ! 863: free(p->zDestTable); ! 864: p->zDestTable = 0; ! 865: } ! 866: if( zName==0 ) return; ! 867: needQuote = !isalpha((unsigned char)*zName) && *zName!='_'; ! 868: for(i=n=0; zName[i]; i++, n++){ ! 869: if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){ ! 870: needQuote = 1; ! 871: if( zName[i]=='\'' ) n++; ! 872: } ! 873: } ! 874: if( needQuote ) n += 2; ! 875: z = p->zDestTable = malloc( n+1 ); ! 876: if( z==0 ){ ! 877: fprintf(stderr,"Error: out of memory\n"); ! 878: exit(1); ! 879: } ! 880: n = 0; ! 881: if( needQuote ) z[n++] = '\''; ! 882: for(i=0; zName[i]; i++){ ! 883: z[n++] = zName[i]; ! 884: if( zName[i]=='\'' ) z[n++] = '\''; ! 885: } ! 886: if( needQuote ) z[n++] = '\''; ! 887: z[n] = 0; ! 888: } ! 889: ! 890: /* zIn is either a pointer to a NULL-terminated string in memory obtained ! 891: ** from malloc(), or a NULL pointer. The string pointed to by zAppend is ! 892: ** added to zIn, and the result returned in memory obtained from malloc(). ! 893: ** zIn, if it was not NULL, is freed. ! 894: ** ! 895: ** If the third argument, quote, is not '\0', then it is used as a ! 896: ** quote character for zAppend. ! 897: */ ! 898: static char *appendText(char *zIn, char const *zAppend, char quote){ ! 899: int len; ! 900: int i; ! 901: int nAppend = strlen30(zAppend); ! 902: int nIn = (zIn?strlen30(zIn):0); ! 903: ! 904: len = nAppend+nIn+1; ! 905: if( quote ){ ! 906: len += 2; ! 907: for(i=0; i<nAppend; i++){ ! 908: if( zAppend[i]==quote ) len++; ! 909: } ! 910: } ! 911: ! 912: zIn = (char *)realloc(zIn, len); ! 913: if( !zIn ){ ! 914: return 0; ! 915: } ! 916: ! 917: if( quote ){ ! 918: char *zCsr = &zIn[nIn]; ! 919: *zCsr++ = quote; ! 920: for(i=0; i<nAppend; i++){ ! 921: *zCsr++ = zAppend[i]; ! 922: if( zAppend[i]==quote ) *zCsr++ = quote; ! 923: } ! 924: *zCsr++ = quote; ! 925: *zCsr++ = '\0'; ! 926: assert( (zCsr-zIn)==len ); ! 927: }else{ ! 928: memcpy(&zIn[nIn], zAppend, nAppend); ! 929: zIn[len-1] = '\0'; ! 930: } ! 931: ! 932: return zIn; ! 933: } ! 934: ! 935: ! 936: /* ! 937: ** Execute a query statement that has a single result column. Print ! 938: ** that result column on a line by itself with a semicolon terminator. ! 939: ** ! 940: ** This is used, for example, to show the schema of the database by ! 941: ** querying the SQLITE_MASTER table. ! 942: */ ! 943: static int run_table_dump_query( ! 944: struct callback_data *p, /* Query context */ ! 945: const char *zSelect, /* SELECT statement to extract content */ ! 946: const char *zFirstRow /* Print before first row, if not NULL */ ! 947: ){ ! 948: sqlite3_stmt *pSelect; ! 949: int rc; ! 950: rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0); ! 951: if( rc!=SQLITE_OK || !pSelect ){ ! 952: fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); ! 953: p->nErr++; ! 954: return rc; ! 955: } ! 956: rc = sqlite3_step(pSelect); ! 957: while( rc==SQLITE_ROW ){ ! 958: if( zFirstRow ){ ! 959: fprintf(p->out, "%s", zFirstRow); ! 960: zFirstRow = 0; ! 961: } ! 962: fprintf(p->out, "%s;\n", sqlite3_column_text(pSelect, 0)); ! 963: rc = sqlite3_step(pSelect); ! 964: } ! 965: rc = sqlite3_finalize(pSelect); ! 966: if( rc!=SQLITE_OK ){ ! 967: fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); ! 968: p->nErr++; ! 969: } ! 970: return rc; ! 971: } ! 972: ! 973: /* ! 974: ** Allocate space and save off current error string. ! 975: */ ! 976: static char *save_err_msg( ! 977: sqlite3 *db /* Database to query */ ! 978: ){ ! 979: int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); ! 980: char *zErrMsg = sqlite3_malloc(nErrMsg); ! 981: if( zErrMsg ){ ! 982: memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); ! 983: } ! 984: return zErrMsg; ! 985: } ! 986: ! 987: /* ! 988: ** Display memory stats. ! 989: */ ! 990: static int display_stats( ! 991: sqlite3 *db, /* Database to query */ ! 992: struct callback_data *pArg, /* Pointer to struct callback_data */ ! 993: int bReset /* True to reset the stats */ ! 994: ){ ! 995: int iCur; ! 996: int iHiwtr; ! 997: ! 998: if( pArg && pArg->out ){ ! 999: ! 1000: iHiwtr = iCur = -1; ! 1001: sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset); ! 1002: fprintf(pArg->out, "Memory Used: %d (max %d) bytes\n", iCur, iHiwtr); ! 1003: iHiwtr = iCur = -1; ! 1004: sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset); ! 1005: fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", iCur, iHiwtr); ! 1006: /* ! 1007: ** Not currently used by the CLI. ! 1008: ** iHiwtr = iCur = -1; ! 1009: ** sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset); ! 1010: ** fprintf(pArg->out, "Number of Pcache Pages Used: %d (max %d) pages\n", iCur, iHiwtr); ! 1011: */ ! 1012: iHiwtr = iCur = -1; ! 1013: sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset); ! 1014: fprintf(pArg->out, "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr); ! 1015: /* ! 1016: ** Not currently used by the CLI. ! 1017: ** iHiwtr = iCur = -1; ! 1018: ** sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset); ! 1019: ** fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n", iCur, iHiwtr); ! 1020: */ ! 1021: iHiwtr = iCur = -1; ! 1022: sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset); ! 1023: fprintf(pArg->out, "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr); ! 1024: iHiwtr = iCur = -1; ! 1025: sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset); ! 1026: fprintf(pArg->out, "Largest Allocation: %d bytes\n", iHiwtr); ! 1027: iHiwtr = iCur = -1; ! 1028: sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset); ! 1029: fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n", iHiwtr); ! 1030: iHiwtr = iCur = -1; ! 1031: sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset); ! 1032: fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n", iHiwtr); ! 1033: #ifdef YYTRACKMAXSTACKDEPTH ! 1034: iHiwtr = iCur = -1; ! 1035: sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset); ! 1036: fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", iCur, iHiwtr); ! 1037: #endif ! 1038: } ! 1039: ! 1040: if( pArg && pArg->out && db ){ ! 1041: iHiwtr = iCur = -1; ! 1042: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset); ! 1043: fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); ! 1044: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset); ! 1045: fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr); ! 1046: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset); ! 1047: fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr); ! 1048: sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset); ! 1049: fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr); ! 1050: iHiwtr = iCur = -1; ! 1051: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); ! 1052: fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1; ! 1053: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); ! 1054: fprintf(pArg->out, "Page cache hits: %d\n", iCur); ! 1055: iHiwtr = iCur = -1; ! 1056: sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); ! 1057: fprintf(pArg->out, "Page cache misses: %d\n", iCur); ! 1058: iHiwtr = iCur = -1; ! 1059: sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); ! 1060: fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur); ! 1061: iHiwtr = iCur = -1; ! 1062: sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); ! 1063: fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", iCur); ! 1064: } ! 1065: ! 1066: if( pArg && pArg->out && db && pArg->pStmt ){ ! 1067: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset); ! 1068: fprintf(pArg->out, "Fullscan Steps: %d\n", iCur); ! 1069: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); ! 1070: fprintf(pArg->out, "Sort Operations: %d\n", iCur); ! 1071: iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset); ! 1072: fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur); ! 1073: } ! 1074: ! 1075: return 0; ! 1076: } ! 1077: ! 1078: /* ! 1079: ** Execute a statement or set of statements. Print ! 1080: ** any result rows/columns depending on the current mode ! 1081: ** set via the supplied callback. ! 1082: ** ! 1083: ** This is very similar to SQLite's built-in sqlite3_exec() ! 1084: ** function except it takes a slightly different callback ! 1085: ** and callback data argument. ! 1086: */ ! 1087: static int shell_exec( ! 1088: sqlite3 *db, /* An open database */ ! 1089: const char *zSql, /* SQL to be evaluated */ ! 1090: int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */ ! 1091: /* (not the same as sqlite3_exec) */ ! 1092: struct callback_data *pArg, /* Pointer to struct callback_data */ ! 1093: char **pzErrMsg /* Error msg written here */ ! 1094: ){ ! 1095: sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ ! 1096: int rc = SQLITE_OK; /* Return Code */ ! 1097: int rc2; ! 1098: const char *zLeftover; /* Tail of unprocessed SQL */ ! 1099: ! 1100: if( pzErrMsg ){ ! 1101: *pzErrMsg = NULL; ! 1102: } ! 1103: ! 1104: while( zSql[0] && (SQLITE_OK == rc) ){ ! 1105: rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); ! 1106: if( SQLITE_OK != rc ){ ! 1107: if( pzErrMsg ){ ! 1108: *pzErrMsg = save_err_msg(db); ! 1109: } ! 1110: }else{ ! 1111: if( !pStmt ){ ! 1112: /* this happens for a comment or white-space */ ! 1113: zSql = zLeftover; ! 1114: while( IsSpace(zSql[0]) ) zSql++; ! 1115: continue; ! 1116: } ! 1117: ! 1118: /* save off the prepared statment handle and reset row count */ ! 1119: if( pArg ){ ! 1120: pArg->pStmt = pStmt; ! 1121: pArg->cnt = 0; ! 1122: } ! 1123: ! 1124: /* echo the sql statement if echo on */ ! 1125: if( pArg && pArg->echoOn ){ ! 1126: const char *zStmtSql = sqlite3_sql(pStmt); ! 1127: fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); ! 1128: } ! 1129: ! 1130: /* Output TESTCTRL_EXPLAIN text of requested */ ! 1131: if( pArg && pArg->mode==MODE_Explain ){ ! 1132: const char *zExplain = 0; ! 1133: sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain); ! 1134: if( zExplain && zExplain[0] ){ ! 1135: fprintf(pArg->out, "%s", zExplain); ! 1136: } ! 1137: } ! 1138: ! 1139: /* perform the first step. this will tell us if we ! 1140: ** have a result set or not and how wide it is. ! 1141: */ ! 1142: rc = sqlite3_step(pStmt); ! 1143: /* if we have a result set... */ ! 1144: if( SQLITE_ROW == rc ){ ! 1145: /* if we have a callback... */ ! 1146: if( xCallback ){ ! 1147: /* allocate space for col name ptr, value ptr, and type */ ! 1148: int nCol = sqlite3_column_count(pStmt); ! 1149: void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1); ! 1150: if( !pData ){ ! 1151: rc = SQLITE_NOMEM; ! 1152: }else{ ! 1153: char **azCols = (char **)pData; /* Names of result columns */ ! 1154: char **azVals = &azCols[nCol]; /* Results */ ! 1155: int *aiTypes = (int *)&azVals[nCol]; /* Result types */ ! 1156: int i; ! 1157: assert(sizeof(int) <= sizeof(char *)); ! 1158: /* save off ptrs to column names */ ! 1159: for(i=0; i<nCol; i++){ ! 1160: azCols[i] = (char *)sqlite3_column_name(pStmt, i); ! 1161: } ! 1162: do{ ! 1163: /* extract the data and data types */ ! 1164: for(i=0; i<nCol; i++){ ! 1165: azVals[i] = (char *)sqlite3_column_text(pStmt, i); ! 1166: aiTypes[i] = sqlite3_column_type(pStmt, i); ! 1167: if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ ! 1168: rc = SQLITE_NOMEM; ! 1169: break; /* from for */ ! 1170: } ! 1171: } /* end for */ ! 1172: ! 1173: /* if data and types extracted successfully... */ ! 1174: if( SQLITE_ROW == rc ){ ! 1175: /* call the supplied callback with the result row data */ ! 1176: if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ ! 1177: rc = SQLITE_ABORT; ! 1178: }else{ ! 1179: rc = sqlite3_step(pStmt); ! 1180: } ! 1181: } ! 1182: } while( SQLITE_ROW == rc ); ! 1183: sqlite3_free(pData); ! 1184: } ! 1185: }else{ ! 1186: do{ ! 1187: rc = sqlite3_step(pStmt); ! 1188: } while( rc == SQLITE_ROW ); ! 1189: } ! 1190: } ! 1191: ! 1192: /* print usage stats if stats on */ ! 1193: if( pArg && pArg->statsOn ){ ! 1194: display_stats(db, pArg, 0); ! 1195: } ! 1196: ! 1197: /* Finalize the statement just executed. If this fails, save a ! 1198: ** copy of the error message. Otherwise, set zSql to point to the ! 1199: ** next statement to execute. */ ! 1200: rc2 = sqlite3_finalize(pStmt); ! 1201: if( rc!=SQLITE_NOMEM ) rc = rc2; ! 1202: if( rc==SQLITE_OK ){ ! 1203: zSql = zLeftover; ! 1204: while( IsSpace(zSql[0]) ) zSql++; ! 1205: }else if( pzErrMsg ){ ! 1206: *pzErrMsg = save_err_msg(db); ! 1207: } ! 1208: ! 1209: /* clear saved stmt handle */ ! 1210: if( pArg ){ ! 1211: pArg->pStmt = NULL; ! 1212: } ! 1213: } ! 1214: } /* end while */ ! 1215: ! 1216: return rc; ! 1217: } ! 1218: ! 1219: ! 1220: /* ! 1221: ** This is a different callback routine used for dumping the database. ! 1222: ** Each row received by this callback consists of a table name, ! 1223: ** the table type ("index" or "table") and SQL to create the table. ! 1224: ** This routine should print text sufficient to recreate the table. ! 1225: */ ! 1226: static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ ! 1227: int rc; ! 1228: const char *zTable; ! 1229: const char *zType; ! 1230: const char *zSql; ! 1231: const char *zPrepStmt = 0; ! 1232: struct callback_data *p = (struct callback_data *)pArg; ! 1233: ! 1234: UNUSED_PARAMETER(azCol); ! 1235: if( nArg!=3 ) return 1; ! 1236: zTable = azArg[0]; ! 1237: zType = azArg[1]; ! 1238: zSql = azArg[2]; ! 1239: ! 1240: if( strcmp(zTable, "sqlite_sequence")==0 ){ ! 1241: zPrepStmt = "DELETE FROM sqlite_sequence;\n"; ! 1242: }else if( strcmp(zTable, "sqlite_stat1")==0 ){ ! 1243: fprintf(p->out, "ANALYZE sqlite_master;\n"); ! 1244: }else if( strncmp(zTable, "sqlite_", 7)==0 ){ ! 1245: return 0; ! 1246: }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ ! 1247: char *zIns; ! 1248: if( !p->writableSchema ){ ! 1249: fprintf(p->out, "PRAGMA writable_schema=ON;\n"); ! 1250: p->writableSchema = 1; ! 1251: } ! 1252: zIns = sqlite3_mprintf( ! 1253: "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" ! 1254: "VALUES('table','%q','%q',0,'%q');", ! 1255: zTable, zTable, zSql); ! 1256: fprintf(p->out, "%s\n", zIns); ! 1257: sqlite3_free(zIns); ! 1258: return 0; ! 1259: }else{ ! 1260: fprintf(p->out, "%s;\n", zSql); ! 1261: } ! 1262: ! 1263: if( strcmp(zType, "table")==0 ){ ! 1264: sqlite3_stmt *pTableInfo = 0; ! 1265: char *zSelect = 0; ! 1266: char *zTableInfo = 0; ! 1267: char *zTmp = 0; ! 1268: int nRow = 0; ! 1269: ! 1270: zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0); ! 1271: zTableInfo = appendText(zTableInfo, zTable, '"'); ! 1272: zTableInfo = appendText(zTableInfo, ");", 0); ! 1273: ! 1274: rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0); ! 1275: free(zTableInfo); ! 1276: if( rc!=SQLITE_OK || !pTableInfo ){ ! 1277: return 1; ! 1278: } ! 1279: ! 1280: zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0); ! 1281: zTmp = appendText(zTmp, zTable, '"'); ! 1282: if( zTmp ){ ! 1283: zSelect = appendText(zSelect, zTmp, '\''); ! 1284: } ! 1285: zSelect = appendText(zSelect, " || ' VALUES(' || ", 0); ! 1286: rc = sqlite3_step(pTableInfo); ! 1287: while( rc==SQLITE_ROW ){ ! 1288: const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1); ! 1289: zSelect = appendText(zSelect, "quote(", 0); ! 1290: zSelect = appendText(zSelect, zText, '"'); ! 1291: rc = sqlite3_step(pTableInfo); ! 1292: if( rc==SQLITE_ROW ){ ! 1293: zSelect = appendText(zSelect, ") || ',' || ", 0); ! 1294: }else{ ! 1295: zSelect = appendText(zSelect, ") ", 0); ! 1296: } ! 1297: nRow++; ! 1298: } ! 1299: rc = sqlite3_finalize(pTableInfo); ! 1300: if( rc!=SQLITE_OK || nRow==0 ){ ! 1301: free(zSelect); ! 1302: return 1; ! 1303: } ! 1304: zSelect = appendText(zSelect, "|| ')' FROM ", 0); ! 1305: zSelect = appendText(zSelect, zTable, '"'); ! 1306: ! 1307: rc = run_table_dump_query(p, zSelect, zPrepStmt); ! 1308: if( rc==SQLITE_CORRUPT ){ ! 1309: zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); ! 1310: run_table_dump_query(p, zSelect, 0); ! 1311: } ! 1312: if( zSelect ) free(zSelect); ! 1313: } ! 1314: return 0; ! 1315: } ! 1316: ! 1317: /* ! 1318: ** Run zQuery. Use dump_callback() as the callback routine so that ! 1319: ** the contents of the query are output as SQL statements. ! 1320: ** ! 1321: ** If we get a SQLITE_CORRUPT error, rerun the query after appending ! 1322: ** "ORDER BY rowid DESC" to the end. ! 1323: */ ! 1324: static int run_schema_dump_query( ! 1325: struct callback_data *p, ! 1326: const char *zQuery ! 1327: ){ ! 1328: int rc; ! 1329: char *zErr = 0; ! 1330: rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); ! 1331: if( rc==SQLITE_CORRUPT ){ ! 1332: char *zQ2; ! 1333: int len = strlen30(zQuery); ! 1334: fprintf(p->out, "/****** CORRUPTION ERROR *******/\n"); ! 1335: if( zErr ){ ! 1336: fprintf(p->out, "/****** %s ******/\n", zErr); ! 1337: sqlite3_free(zErr); ! 1338: zErr = 0; ! 1339: } ! 1340: zQ2 = malloc( len+100 ); ! 1341: if( zQ2==0 ) return rc; ! 1342: sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery); ! 1343: rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); ! 1344: if( rc ){ ! 1345: fprintf(p->out, "/****** ERROR: %s ******/\n", zErr); ! 1346: }else{ ! 1347: rc = SQLITE_CORRUPT; ! 1348: } ! 1349: sqlite3_free(zErr); ! 1350: free(zQ2); ! 1351: } ! 1352: return rc; ! 1353: } ! 1354: ! 1355: /* ! 1356: ** Text of a help message ! 1357: */ ! 1358: static char zHelp[] = ! 1359: ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ! 1360: ".bail ON|OFF Stop after hitting an error. Default OFF\n" ! 1361: ".databases List names and files of attached databases\n" ! 1362: ".dump ?TABLE? ... Dump the database in an SQL text format\n" ! 1363: " If TABLE specified, only dump tables matching\n" ! 1364: " LIKE pattern TABLE.\n" ! 1365: ".echo ON|OFF Turn command echo on or off\n" ! 1366: ".exit Exit this program\n" ! 1367: ".explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.\n" ! 1368: " With no args, it turns EXPLAIN on.\n" ! 1369: ".header(s) ON|OFF Turn display of headers on or off\n" ! 1370: ".help Show this message\n" ! 1371: ".import FILE TABLE Import data from FILE into TABLE\n" ! 1372: ".indices ?TABLE? Show names of all indices\n" ! 1373: " If TABLE specified, only show indices for tables\n" ! 1374: " matching LIKE pattern TABLE.\n" ! 1375: #ifdef SQLITE_ENABLE_IOTRACE ! 1376: ".iotrace FILE Enable I/O diagnostic logging to FILE\n" ! 1377: #endif ! 1378: #ifndef SQLITE_OMIT_LOAD_EXTENSION ! 1379: ".load FILE ?ENTRY? Load an extension library\n" ! 1380: #endif ! 1381: ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" ! 1382: ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" ! 1383: " csv Comma-separated values\n" ! 1384: " column Left-aligned columns. (See .width)\n" ! 1385: " html HTML <table> code\n" ! 1386: " insert SQL insert statements for TABLE\n" ! 1387: " line One value per line\n" ! 1388: " list Values delimited by .separator string\n" ! 1389: " tabs Tab-separated values\n" ! 1390: " tcl TCL list elements\n" ! 1391: ".nullvalue STRING Print STRING in place of NULL values\n" ! 1392: ".output FILENAME Send output to FILENAME\n" ! 1393: ".output stdout Send output to the screen\n" ! 1394: ".prompt MAIN CONTINUE Replace the standard prompts\n" ! 1395: ".quit Exit this program\n" ! 1396: ".read FILENAME Execute SQL in FILENAME\n" ! 1397: ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ! 1398: ".schema ?TABLE? Show the CREATE statements\n" ! 1399: " If TABLE specified, only show tables matching\n" ! 1400: " LIKE pattern TABLE.\n" ! 1401: ".separator STRING Change separator used by output mode and .import\n" ! 1402: ".show Show the current values for various settings\n" ! 1403: ".stats ON|OFF Turn stats on or off\n" ! 1404: ".tables ?TABLE? List names of tables\n" ! 1405: " If TABLE specified, only list tables matching\n" ! 1406: " LIKE pattern TABLE.\n" ! 1407: ".timeout MS Try opening locked tables for MS milliseconds\n" ! 1408: ".vfsname ?AUX? Print the name of the VFS stack\n" ! 1409: ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" ! 1410: ; ! 1411: ! 1412: static char zTimerHelp[] = ! 1413: ".timer ON|OFF Turn the CPU timer measurement on or off\n" ! 1414: ; ! 1415: ! 1416: /* Forward reference */ ! 1417: static int process_input(struct callback_data *p, FILE *in); ! 1418: ! 1419: /* ! 1420: ** Make sure the database is open. If it is not, then open it. If ! 1421: ** the database fails to open, print an error message and exit. ! 1422: */ ! 1423: static void open_db(struct callback_data *p){ ! 1424: if( p->db==0 ){ ! 1425: sqlite3_open(p->zDbFilename, &p->db); ! 1426: db = p->db; ! 1427: if( db && sqlite3_errcode(db)==SQLITE_OK ){ ! 1428: sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0, ! 1429: shellstaticFunc, 0, 0); ! 1430: } ! 1431: if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){ ! 1432: fprintf(stderr,"Error: unable to open database \"%s\": %s\n", ! 1433: p->zDbFilename, sqlite3_errmsg(db)); ! 1434: exit(1); ! 1435: } ! 1436: #ifndef SQLITE_OMIT_LOAD_EXTENSION ! 1437: sqlite3_enable_load_extension(p->db, 1); ! 1438: #endif ! 1439: } ! 1440: } ! 1441: ! 1442: /* ! 1443: ** Do C-language style dequoting. ! 1444: ** ! 1445: ** \t -> tab ! 1446: ** \n -> newline ! 1447: ** \r -> carriage return ! 1448: ** \NNN -> ascii character NNN in octal ! 1449: ** \\ -> backslash ! 1450: */ ! 1451: static void resolve_backslashes(char *z){ ! 1452: int i, j; ! 1453: char c; ! 1454: for(i=j=0; (c = z[i])!=0; i++, j++){ ! 1455: if( c=='\\' ){ ! 1456: c = z[++i]; ! 1457: if( c=='n' ){ ! 1458: c = '\n'; ! 1459: }else if( c=='t' ){ ! 1460: c = '\t'; ! 1461: }else if( c=='r' ){ ! 1462: c = '\r'; ! 1463: }else if( c>='0' && c<='7' ){ ! 1464: c -= '0'; ! 1465: if( z[i+1]>='0' && z[i+1]<='7' ){ ! 1466: i++; ! 1467: c = (c<<3) + z[i] - '0'; ! 1468: if( z[i+1]>='0' && z[i+1]<='7' ){ ! 1469: i++; ! 1470: c = (c<<3) + z[i] - '0'; ! 1471: } ! 1472: } ! 1473: } ! 1474: } ! 1475: z[j] = c; ! 1476: } ! 1477: z[j] = 0; ! 1478: } ! 1479: ! 1480: /* ! 1481: ** Interpret zArg as a boolean value. Return either 0 or 1. ! 1482: */ ! 1483: static int booleanValue(char *zArg){ ! 1484: int val = atoi(zArg); ! 1485: int j; ! 1486: for(j=0; zArg[j]; j++){ ! 1487: zArg[j] = ToLower(zArg[j]); ! 1488: } ! 1489: if( strcmp(zArg,"on")==0 ){ ! 1490: val = 1; ! 1491: }else if( strcmp(zArg,"yes")==0 ){ ! 1492: val = 1; ! 1493: } ! 1494: return val; ! 1495: } ! 1496: ! 1497: /* ! 1498: ** If an input line begins with "." then invoke this routine to ! 1499: ** process that line. ! 1500: ** ! 1501: ** Return 1 on error, 2 to exit, and 0 otherwise. ! 1502: */ ! 1503: static int do_meta_command(char *zLine, struct callback_data *p){ ! 1504: int i = 1; ! 1505: int nArg = 0; ! 1506: int n, c; ! 1507: int rc = 0; ! 1508: char *azArg[50]; ! 1509: ! 1510: /* Parse the input line into tokens. ! 1511: */ ! 1512: while( zLine[i] && nArg<ArraySize(azArg) ){ ! 1513: while( IsSpace(zLine[i]) ){ i++; } ! 1514: if( zLine[i]==0 ) break; ! 1515: if( zLine[i]=='\'' || zLine[i]=='"' ){ ! 1516: int delim = zLine[i++]; ! 1517: azArg[nArg++] = &zLine[i]; ! 1518: while( zLine[i] && zLine[i]!=delim ){ i++; } ! 1519: if( zLine[i]==delim ){ ! 1520: zLine[i++] = 0; ! 1521: } ! 1522: if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); ! 1523: }else{ ! 1524: azArg[nArg++] = &zLine[i]; ! 1525: while( zLine[i] && !IsSpace(zLine[i]) ){ i++; } ! 1526: if( zLine[i] ) zLine[i++] = 0; ! 1527: resolve_backslashes(azArg[nArg-1]); ! 1528: } ! 1529: } ! 1530: ! 1531: /* Process the input line. ! 1532: */ ! 1533: if( nArg==0 ) return 0; /* no tokens, no error */ ! 1534: n = strlen30(azArg[0]); ! 1535: c = azArg[0][0]; ! 1536: if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){ ! 1537: const char *zDestFile; ! 1538: const char *zDb; ! 1539: sqlite3 *pDest; ! 1540: sqlite3_backup *pBackup; ! 1541: if( nArg==2 ){ ! 1542: zDestFile = azArg[1]; ! 1543: zDb = "main"; ! 1544: }else{ ! 1545: zDestFile = azArg[2]; ! 1546: zDb = azArg[1]; ! 1547: } ! 1548: rc = sqlite3_open(zDestFile, &pDest); ! 1549: if( rc!=SQLITE_OK ){ ! 1550: fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile); ! 1551: sqlite3_close(pDest); ! 1552: return 1; ! 1553: } ! 1554: open_db(p); ! 1555: pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); ! 1556: if( pBackup==0 ){ ! 1557: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); ! 1558: sqlite3_close(pDest); ! 1559: return 1; ! 1560: } ! 1561: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} ! 1562: sqlite3_backup_finish(pBackup); ! 1563: if( rc==SQLITE_DONE ){ ! 1564: rc = 0; ! 1565: }else{ ! 1566: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); ! 1567: rc = 1; ! 1568: } ! 1569: sqlite3_close(pDest); ! 1570: }else ! 1571: ! 1572: if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){ ! 1573: bail_on_error = booleanValue(azArg[1]); ! 1574: }else ! 1575: ! 1576: if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){ ! 1577: struct callback_data data; ! 1578: char *zErrMsg = 0; ! 1579: open_db(p); ! 1580: memcpy(&data, p, sizeof(data)); ! 1581: data.showHeader = 1; ! 1582: data.mode = MODE_Column; ! 1583: data.colWidth[0] = 3; ! 1584: data.colWidth[1] = 15; ! 1585: data.colWidth[2] = 58; ! 1586: data.cnt = 0; ! 1587: sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); ! 1588: if( zErrMsg ){ ! 1589: fprintf(stderr,"Error: %s\n", zErrMsg); ! 1590: sqlite3_free(zErrMsg); ! 1591: rc = 1; ! 1592: } ! 1593: }else ! 1594: ! 1595: if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){ ! 1596: open_db(p); ! 1597: /* When playing back a "dump", the content might appear in an order ! 1598: ** which causes immediate foreign key constraints to be violated. ! 1599: ** So disable foreign-key constraint enforcement to prevent problems. */ ! 1600: fprintf(p->out, "PRAGMA foreign_keys=OFF;\n"); ! 1601: fprintf(p->out, "BEGIN TRANSACTION;\n"); ! 1602: p->writableSchema = 0; ! 1603: sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); ! 1604: p->nErr = 0; ! 1605: if( nArg==1 ){ ! 1606: run_schema_dump_query(p, ! 1607: "SELECT name, type, sql FROM sqlite_master " ! 1608: "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" ! 1609: ); ! 1610: run_schema_dump_query(p, ! 1611: "SELECT name, type, sql FROM sqlite_master " ! 1612: "WHERE name=='sqlite_sequence'" ! 1613: ); ! 1614: run_table_dump_query(p, ! 1615: "SELECT sql FROM sqlite_master " ! 1616: "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 ! 1617: ); ! 1618: }else{ ! 1619: int i; ! 1620: for(i=1; i<nArg; i++){ ! 1621: zShellStatic = azArg[i]; ! 1622: run_schema_dump_query(p, ! 1623: "SELECT name, type, sql FROM sqlite_master " ! 1624: "WHERE tbl_name LIKE shellstatic() AND type=='table'" ! 1625: " AND sql NOT NULL"); ! 1626: run_table_dump_query(p, ! 1627: "SELECT sql FROM sqlite_master " ! 1628: "WHERE sql NOT NULL" ! 1629: " AND type IN ('index','trigger','view')" ! 1630: " AND tbl_name LIKE shellstatic()", 0 ! 1631: ); ! 1632: zShellStatic = 0; ! 1633: } ! 1634: } ! 1635: if( p->writableSchema ){ ! 1636: fprintf(p->out, "PRAGMA writable_schema=OFF;\n"); ! 1637: p->writableSchema = 0; ! 1638: } ! 1639: sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); ! 1640: sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); ! 1641: fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); ! 1642: }else ! 1643: ! 1644: if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){ ! 1645: p->echoOn = booleanValue(azArg[1]); ! 1646: }else ! 1647: ! 1648: if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){ ! 1649: rc = 2; ! 1650: }else ! 1651: ! 1652: if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){ ! 1653: int val = nArg>=2 ? booleanValue(azArg[1]) : 1; ! 1654: if(val == 1) { ! 1655: if(!p->explainPrev.valid) { ! 1656: p->explainPrev.valid = 1; ! 1657: p->explainPrev.mode = p->mode; ! 1658: p->explainPrev.showHeader = p->showHeader; ! 1659: memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth)); ! 1660: } ! 1661: /* We could put this code under the !p->explainValid ! 1662: ** condition so that it does not execute if we are already in ! 1663: ** explain mode. However, always executing it allows us an easy ! 1664: ** was to reset to explain mode in case the user previously ! 1665: ** did an .explain followed by a .width, .mode or .header ! 1666: ** command. ! 1667: */ ! 1668: p->mode = MODE_Explain; ! 1669: p->showHeader = 1; ! 1670: memset(p->colWidth,0,ArraySize(p->colWidth)); ! 1671: p->colWidth[0] = 4; /* addr */ ! 1672: p->colWidth[1] = 13; /* opcode */ ! 1673: p->colWidth[2] = 4; /* P1 */ ! 1674: p->colWidth[3] = 4; /* P2 */ ! 1675: p->colWidth[4] = 4; /* P3 */ ! 1676: p->colWidth[5] = 13; /* P4 */ ! 1677: p->colWidth[6] = 2; /* P5 */ ! 1678: p->colWidth[7] = 13; /* Comment */ ! 1679: }else if (p->explainPrev.valid) { ! 1680: p->explainPrev.valid = 0; ! 1681: p->mode = p->explainPrev.mode; ! 1682: p->showHeader = p->explainPrev.showHeader; ! 1683: memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth)); ! 1684: } ! 1685: }else ! 1686: ! 1687: if( c=='h' && (strncmp(azArg[0], "header", n)==0 || ! 1688: strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){ ! 1689: p->showHeader = booleanValue(azArg[1]); ! 1690: }else ! 1691: ! 1692: if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ ! 1693: fprintf(stderr,"%s",zHelp); ! 1694: if( HAS_TIMER ){ ! 1695: fprintf(stderr,"%s",zTimerHelp); ! 1696: } ! 1697: }else ! 1698: ! 1699: if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){ ! 1700: char *zTable = azArg[2]; /* Insert data into this table */ ! 1701: char *zFile = azArg[1]; /* The file from which to extract data */ ! 1702: sqlite3_stmt *pStmt = NULL; /* A statement */ ! 1703: int nCol; /* Number of columns in the table */ ! 1704: int nByte; /* Number of bytes in an SQL string */ ! 1705: int i, j; /* Loop counters */ ! 1706: int nSep; /* Number of bytes in p->separator[] */ ! 1707: char *zSql; /* An SQL statement */ ! 1708: char *zLine; /* A single line of input from the file */ ! 1709: char **azCol; /* zLine[] broken up into columns */ ! 1710: char *zCommit; /* How to commit changes */ ! 1711: FILE *in; /* The input file */ ! 1712: int lineno = 0; /* Line number of input file */ ! 1713: ! 1714: open_db(p); ! 1715: nSep = strlen30(p->separator); ! 1716: if( nSep==0 ){ ! 1717: fprintf(stderr, "Error: non-null separator required for import\n"); ! 1718: return 1; ! 1719: } ! 1720: zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); ! 1721: if( zSql==0 ){ ! 1722: fprintf(stderr, "Error: out of memory\n"); ! 1723: return 1; ! 1724: } ! 1725: nByte = strlen30(zSql); ! 1726: rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); ! 1727: sqlite3_free(zSql); ! 1728: if( rc ){ ! 1729: if (pStmt) sqlite3_finalize(pStmt); ! 1730: fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); ! 1731: return 1; ! 1732: } ! 1733: nCol = sqlite3_column_count(pStmt); ! 1734: sqlite3_finalize(pStmt); ! 1735: pStmt = 0; ! 1736: if( nCol==0 ) return 0; /* no columns, no error */ ! 1737: zSql = malloc( nByte + 20 + nCol*2 ); ! 1738: if( zSql==0 ){ ! 1739: fprintf(stderr, "Error: out of memory\n"); ! 1740: return 1; ! 1741: } ! 1742: sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable); ! 1743: j = strlen30(zSql); ! 1744: for(i=1; i<nCol; i++){ ! 1745: zSql[j++] = ','; ! 1746: zSql[j++] = '?'; ! 1747: } ! 1748: zSql[j++] = ')'; ! 1749: zSql[j] = 0; ! 1750: rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); ! 1751: free(zSql); ! 1752: if( rc ){ ! 1753: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); ! 1754: if (pStmt) sqlite3_finalize(pStmt); ! 1755: return 1; ! 1756: } ! 1757: in = fopen(zFile, "rb"); ! 1758: if( in==0 ){ ! 1759: fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); ! 1760: sqlite3_finalize(pStmt); ! 1761: return 1; ! 1762: } ! 1763: azCol = malloc( sizeof(azCol[0])*(nCol+1) ); ! 1764: if( azCol==0 ){ ! 1765: fprintf(stderr, "Error: out of memory\n"); ! 1766: fclose(in); ! 1767: sqlite3_finalize(pStmt); ! 1768: return 1; ! 1769: } ! 1770: sqlite3_exec(p->db, "BEGIN", 0, 0, 0); ! 1771: zCommit = "COMMIT"; ! 1772: while( (zLine = local_getline(0, in))!=0 ){ ! 1773: char *z; ! 1774: lineno++; ! 1775: azCol[0] = zLine; ! 1776: for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){ ! 1777: if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){ ! 1778: *z = 0; ! 1779: i++; ! 1780: if( i<nCol ){ ! 1781: azCol[i] = &z[nSep]; ! 1782: z += nSep-1; ! 1783: } ! 1784: } ! 1785: } /* end for */ ! 1786: *z = 0; ! 1787: if( i+1!=nCol ){ ! 1788: fprintf(stderr, ! 1789: "Error: %s line %d: expected %d columns of data but found %d\n", ! 1790: zFile, lineno, nCol, i+1); ! 1791: zCommit = "ROLLBACK"; ! 1792: free(zLine); ! 1793: rc = 1; ! 1794: break; /* from while */ ! 1795: } ! 1796: for(i=0; i<nCol; i++){ ! 1797: sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); ! 1798: } ! 1799: sqlite3_step(pStmt); ! 1800: rc = sqlite3_reset(pStmt); ! 1801: free(zLine); ! 1802: if( rc!=SQLITE_OK ){ ! 1803: fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); ! 1804: zCommit = "ROLLBACK"; ! 1805: rc = 1; ! 1806: break; /* from while */ ! 1807: } ! 1808: } /* end while */ ! 1809: free(azCol); ! 1810: fclose(in); ! 1811: sqlite3_finalize(pStmt); ! 1812: sqlite3_exec(p->db, zCommit, 0, 0, 0); ! 1813: }else ! 1814: ! 1815: if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){ ! 1816: struct callback_data data; ! 1817: char *zErrMsg = 0; ! 1818: open_db(p); ! 1819: memcpy(&data, p, sizeof(data)); ! 1820: data.showHeader = 0; ! 1821: data.mode = MODE_List; ! 1822: if( nArg==1 ){ ! 1823: rc = sqlite3_exec(p->db, ! 1824: "SELECT name FROM sqlite_master " ! 1825: "WHERE type='index' AND name NOT LIKE 'sqlite_%' " ! 1826: "UNION ALL " ! 1827: "SELECT name FROM sqlite_temp_master " ! 1828: "WHERE type='index' " ! 1829: "ORDER BY 1", ! 1830: callback, &data, &zErrMsg ! 1831: ); ! 1832: }else{ ! 1833: zShellStatic = azArg[1]; ! 1834: rc = sqlite3_exec(p->db, ! 1835: "SELECT name FROM sqlite_master " ! 1836: "WHERE type='index' AND tbl_name LIKE shellstatic() " ! 1837: "UNION ALL " ! 1838: "SELECT name FROM sqlite_temp_master " ! 1839: "WHERE type='index' AND tbl_name LIKE shellstatic() " ! 1840: "ORDER BY 1", ! 1841: callback, &data, &zErrMsg ! 1842: ); ! 1843: zShellStatic = 0; ! 1844: } ! 1845: if( zErrMsg ){ ! 1846: fprintf(stderr,"Error: %s\n", zErrMsg); ! 1847: sqlite3_free(zErrMsg); ! 1848: rc = 1; ! 1849: }else if( rc != SQLITE_OK ){ ! 1850: fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n"); ! 1851: rc = 1; ! 1852: } ! 1853: }else ! 1854: ! 1855: #ifdef SQLITE_ENABLE_IOTRACE ! 1856: if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ ! 1857: extern void (*sqlite3IoTrace)(const char*, ...); ! 1858: if( iotrace && iotrace!=stdout ) fclose(iotrace); ! 1859: iotrace = 0; ! 1860: if( nArg<2 ){ ! 1861: sqlite3IoTrace = 0; ! 1862: }else if( strcmp(azArg[1], "-")==0 ){ ! 1863: sqlite3IoTrace = iotracePrintf; ! 1864: iotrace = stdout; ! 1865: }else{ ! 1866: iotrace = fopen(azArg[1], "w"); ! 1867: if( iotrace==0 ){ ! 1868: fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); ! 1869: sqlite3IoTrace = 0; ! 1870: rc = 1; ! 1871: }else{ ! 1872: sqlite3IoTrace = iotracePrintf; ! 1873: } ! 1874: } ! 1875: }else ! 1876: #endif ! 1877: ! 1878: #ifndef SQLITE_OMIT_LOAD_EXTENSION ! 1879: if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){ ! 1880: const char *zFile, *zProc; ! 1881: char *zErrMsg = 0; ! 1882: zFile = azArg[1]; ! 1883: zProc = nArg>=3 ? azArg[2] : 0; ! 1884: open_db(p); ! 1885: rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); ! 1886: if( rc!=SQLITE_OK ){ ! 1887: fprintf(stderr, "Error: %s\n", zErrMsg); ! 1888: sqlite3_free(zErrMsg); ! 1889: rc = 1; ! 1890: } ! 1891: }else ! 1892: #endif ! 1893: ! 1894: if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){ ! 1895: const char *zFile = azArg[1]; ! 1896: if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){ ! 1897: fclose(p->pLog); ! 1898: p->pLog = 0; ! 1899: } ! 1900: if( strcmp(zFile,"stdout")==0 ){ ! 1901: p->pLog = stdout; ! 1902: }else if( strcmp(zFile, "stderr")==0 ){ ! 1903: p->pLog = stderr; ! 1904: }else if( strcmp(zFile, "off")==0 ){ ! 1905: p->pLog = 0; ! 1906: }else{ ! 1907: p->pLog = fopen(zFile, "w"); ! 1908: if( p->pLog==0 ){ ! 1909: fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); ! 1910: } ! 1911: } ! 1912: }else ! 1913: ! 1914: if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){ ! 1915: int n2 = strlen30(azArg[1]); ! 1916: if( (n2==4 && strncmp(azArg[1],"line",n2)==0) ! 1917: || ! 1918: (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){ ! 1919: p->mode = MODE_Line; ! 1920: }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0) ! 1921: || ! 1922: (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){ ! 1923: p->mode = MODE_Column; ! 1924: }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){ ! 1925: p->mode = MODE_List; ! 1926: }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){ ! 1927: p->mode = MODE_Html; ! 1928: }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){ ! 1929: p->mode = MODE_Tcl; ! 1930: }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){ ! 1931: p->mode = MODE_Csv; ! 1932: sqlite3_snprintf(sizeof(p->separator), p->separator, ","); ! 1933: }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){ ! 1934: p->mode = MODE_List; ! 1935: sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); ! 1936: }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){ ! 1937: p->mode = MODE_Insert; ! 1938: set_table_name(p, "table"); ! 1939: }else { ! 1940: fprintf(stderr,"Error: mode should be one of: " ! 1941: "column csv html insert line list tabs tcl\n"); ! 1942: rc = 1; ! 1943: } ! 1944: }else ! 1945: ! 1946: if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){ ! 1947: int n2 = strlen30(azArg[1]); ! 1948: if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){ ! 1949: p->mode = MODE_Insert; ! 1950: set_table_name(p, azArg[2]); ! 1951: }else { ! 1952: fprintf(stderr, "Error: invalid arguments: " ! 1953: " \"%s\". Enter \".help\" for help\n", azArg[2]); ! 1954: rc = 1; ! 1955: } ! 1956: }else ! 1957: ! 1958: if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) { ! 1959: sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, ! 1960: "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); ! 1961: }else ! 1962: ! 1963: if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){ ! 1964: if( p->out!=stdout ){ ! 1965: fclose(p->out); ! 1966: } ! 1967: if( strcmp(azArg[1],"stdout")==0 ){ ! 1968: p->out = stdout; ! 1969: sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout"); ! 1970: }else{ ! 1971: p->out = fopen(azArg[1], "wb"); ! 1972: if( p->out==0 ){ ! 1973: fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]); ! 1974: p->out = stdout; ! 1975: rc = 1; ! 1976: } else { ! 1977: sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); ! 1978: } ! 1979: } ! 1980: }else ! 1981: ! 1982: if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){ ! 1983: if( nArg >= 2) { ! 1984: strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); ! 1985: } ! 1986: if( nArg >= 3) { ! 1987: strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); ! 1988: } ! 1989: }else ! 1990: ! 1991: if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){ ! 1992: rc = 2; ! 1993: }else ! 1994: ! 1995: if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){ ! 1996: FILE *alt = fopen(azArg[1], "rb"); ! 1997: if( alt==0 ){ ! 1998: fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); ! 1999: rc = 1; ! 2000: }else{ ! 2001: rc = process_input(p, alt); ! 2002: fclose(alt); ! 2003: } ! 2004: }else ! 2005: ! 2006: if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){ ! 2007: const char *zSrcFile; ! 2008: const char *zDb; ! 2009: sqlite3 *pSrc; ! 2010: sqlite3_backup *pBackup; ! 2011: int nTimeout = 0; ! 2012: ! 2013: if( nArg==2 ){ ! 2014: zSrcFile = azArg[1]; ! 2015: zDb = "main"; ! 2016: }else{ ! 2017: zSrcFile = azArg[2]; ! 2018: zDb = azArg[1]; ! 2019: } ! 2020: rc = sqlite3_open(zSrcFile, &pSrc); ! 2021: if( rc!=SQLITE_OK ){ ! 2022: fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); ! 2023: sqlite3_close(pSrc); ! 2024: return 1; ! 2025: } ! 2026: open_db(p); ! 2027: pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); ! 2028: if( pBackup==0 ){ ! 2029: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); ! 2030: sqlite3_close(pSrc); ! 2031: return 1; ! 2032: } ! 2033: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ! 2034: || rc==SQLITE_BUSY ){ ! 2035: if( rc==SQLITE_BUSY ){ ! 2036: if( nTimeout++ >= 3 ) break; ! 2037: sqlite3_sleep(100); ! 2038: } ! 2039: } ! 2040: sqlite3_backup_finish(pBackup); ! 2041: if( rc==SQLITE_DONE ){ ! 2042: rc = 0; ! 2043: }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ ! 2044: fprintf(stderr, "Error: source database is busy\n"); ! 2045: rc = 1; ! 2046: }else{ ! 2047: fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); ! 2048: rc = 1; ! 2049: } ! 2050: sqlite3_close(pSrc); ! 2051: }else ! 2052: ! 2053: if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){ ! 2054: struct callback_data data; ! 2055: char *zErrMsg = 0; ! 2056: open_db(p); ! 2057: memcpy(&data, p, sizeof(data)); ! 2058: data.showHeader = 0; ! 2059: data.mode = MODE_Semi; ! 2060: if( nArg>1 ){ ! 2061: int i; ! 2062: for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); ! 2063: if( strcmp(azArg[1],"sqlite_master")==0 ){ ! 2064: char *new_argv[2], *new_colv[2]; ! 2065: new_argv[0] = "CREATE TABLE sqlite_master (\n" ! 2066: " type text,\n" ! 2067: " name text,\n" ! 2068: " tbl_name text,\n" ! 2069: " rootpage integer,\n" ! 2070: " sql text\n" ! 2071: ")"; ! 2072: new_argv[1] = 0; ! 2073: new_colv[0] = "sql"; ! 2074: new_colv[1] = 0; ! 2075: callback(&data, 1, new_argv, new_colv); ! 2076: rc = SQLITE_OK; ! 2077: }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ ! 2078: char *new_argv[2], *new_colv[2]; ! 2079: new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" ! 2080: " type text,\n" ! 2081: " name text,\n" ! 2082: " tbl_name text,\n" ! 2083: " rootpage integer,\n" ! 2084: " sql text\n" ! 2085: ")"; ! 2086: new_argv[1] = 0; ! 2087: new_colv[0] = "sql"; ! 2088: new_colv[1] = 0; ! 2089: callback(&data, 1, new_argv, new_colv); ! 2090: rc = SQLITE_OK; ! 2091: }else{ ! 2092: zShellStatic = azArg[1]; ! 2093: rc = sqlite3_exec(p->db, ! 2094: "SELECT sql FROM " ! 2095: " (SELECT sql sql, type type, tbl_name tbl_name, name name" ! 2096: " FROM sqlite_master UNION ALL" ! 2097: " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) " ! 2098: "WHERE lower(tbl_name) LIKE shellstatic()" ! 2099: " AND type!='meta' AND sql NOTNULL " ! 2100: "ORDER BY substr(type,2,1), name", ! 2101: callback, &data, &zErrMsg); ! 2102: zShellStatic = 0; ! 2103: } ! 2104: }else{ ! 2105: rc = sqlite3_exec(p->db, ! 2106: "SELECT sql FROM " ! 2107: " (SELECT sql sql, type type, tbl_name tbl_name, name name" ! 2108: " FROM sqlite_master UNION ALL" ! 2109: " SELECT sql, type, tbl_name, name FROM sqlite_temp_master) " ! 2110: "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" ! 2111: "ORDER BY substr(type,2,1), name", ! 2112: callback, &data, &zErrMsg ! 2113: ); ! 2114: } ! 2115: if( zErrMsg ){ ! 2116: fprintf(stderr,"Error: %s\n", zErrMsg); ! 2117: sqlite3_free(zErrMsg); ! 2118: rc = 1; ! 2119: }else if( rc != SQLITE_OK ){ ! 2120: fprintf(stderr,"Error: querying schema information\n"); ! 2121: rc = 1; ! 2122: }else{ ! 2123: rc = 0; ! 2124: } ! 2125: }else ! 2126: ! 2127: if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){ ! 2128: sqlite3_snprintf(sizeof(p->separator), p->separator, ! 2129: "%.*s", (int)sizeof(p->separator)-1, azArg[1]); ! 2130: }else ! 2131: ! 2132: if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){ ! 2133: int i; ! 2134: fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); ! 2135: fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off"); ! 2136: fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off"); ! 2137: fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]); ! 2138: fprintf(p->out,"%9.9s: ", "nullvalue"); ! 2139: output_c_string(p->out, p->nullvalue); ! 2140: fprintf(p->out, "\n"); ! 2141: fprintf(p->out,"%9.9s: %s\n","output", ! 2142: strlen30(p->outfile) ? p->outfile : "stdout"); ! 2143: fprintf(p->out,"%9.9s: ", "separator"); ! 2144: output_c_string(p->out, p->separator); ! 2145: fprintf(p->out, "\n"); ! 2146: fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); ! 2147: fprintf(p->out,"%9.9s: ","width"); ! 2148: for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { ! 2149: fprintf(p->out,"%d ",p->colWidth[i]); ! 2150: } ! 2151: fprintf(p->out,"\n"); ! 2152: }else ! 2153: ! 2154: if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){ ! 2155: p->statsOn = booleanValue(azArg[1]); ! 2156: }else ! 2157: ! 2158: if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){ ! 2159: char **azResult; ! 2160: int nRow; ! 2161: char *zErrMsg; ! 2162: open_db(p); ! 2163: if( nArg==1 ){ ! 2164: rc = sqlite3_get_table(p->db, ! 2165: "SELECT name FROM sqlite_master " ! 2166: "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%' " ! 2167: "UNION ALL " ! 2168: "SELECT name FROM sqlite_temp_master " ! 2169: "WHERE type IN ('table','view') " ! 2170: "ORDER BY 1", ! 2171: &azResult, &nRow, 0, &zErrMsg ! 2172: ); ! 2173: }else{ ! 2174: zShellStatic = azArg[1]; ! 2175: rc = sqlite3_get_table(p->db, ! 2176: "SELECT name FROM sqlite_master " ! 2177: "WHERE type IN ('table','view') AND name LIKE shellstatic() " ! 2178: "UNION ALL " ! 2179: "SELECT name FROM sqlite_temp_master " ! 2180: "WHERE type IN ('table','view') AND name LIKE shellstatic() " ! 2181: "ORDER BY 1", ! 2182: &azResult, &nRow, 0, &zErrMsg ! 2183: ); ! 2184: zShellStatic = 0; ! 2185: } ! 2186: if( zErrMsg ){ ! 2187: fprintf(stderr,"Error: %s\n", zErrMsg); ! 2188: sqlite3_free(zErrMsg); ! 2189: rc = 1; ! 2190: }else if( rc != SQLITE_OK ){ ! 2191: fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n"); ! 2192: rc = 1; ! 2193: }else{ ! 2194: int len, maxlen = 0; ! 2195: int i, j; ! 2196: int nPrintCol, nPrintRow; ! 2197: for(i=1; i<=nRow; i++){ ! 2198: if( azResult[i]==0 ) continue; ! 2199: len = strlen30(azResult[i]); ! 2200: if( len>maxlen ) maxlen = len; ! 2201: } ! 2202: nPrintCol = 80/(maxlen+2); ! 2203: if( nPrintCol<1 ) nPrintCol = 1; ! 2204: nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; ! 2205: for(i=0; i<nPrintRow; i++){ ! 2206: for(j=i+1; j<=nRow; j+=nPrintRow){ ! 2207: char *zSp = j<=nPrintRow ? "" : " "; ! 2208: printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : ""); ! 2209: } ! 2210: printf("\n"); ! 2211: } ! 2212: } ! 2213: sqlite3_free_table(azResult); ! 2214: }else ! 2215: ! 2216: if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ ! 2217: static const struct { ! 2218: const char *zCtrlName; /* Name of a test-control option */ ! 2219: int ctrlCode; /* Integer code for that option */ ! 2220: } aCtrl[] = { ! 2221: { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, ! 2222: { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, ! 2223: { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, ! 2224: { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, ! 2225: { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, ! 2226: { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, ! 2227: { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, ! 2228: { "assert", SQLITE_TESTCTRL_ASSERT }, ! 2229: { "always", SQLITE_TESTCTRL_ALWAYS }, ! 2230: { "reserve", SQLITE_TESTCTRL_RESERVE }, ! 2231: { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, ! 2232: { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, ! 2233: { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, ! 2234: }; ! 2235: int testctrl = -1; ! 2236: int rc = 0; ! 2237: int i, n; ! 2238: open_db(p); ! 2239: ! 2240: /* convert testctrl text option to value. allow any unique prefix ! 2241: ** of the option name, or a numerical value. */ ! 2242: n = strlen30(azArg[1]); ! 2243: for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){ ! 2244: if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ ! 2245: if( testctrl<0 ){ ! 2246: testctrl = aCtrl[i].ctrlCode; ! 2247: }else{ ! 2248: fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]); ! 2249: testctrl = -1; ! 2250: break; ! 2251: } ! 2252: } ! 2253: } ! 2254: if( testctrl<0 ) testctrl = atoi(azArg[1]); ! 2255: if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){ ! 2256: fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); ! 2257: }else{ ! 2258: switch(testctrl){ ! 2259: ! 2260: /* sqlite3_test_control(int, db, int) */ ! 2261: case SQLITE_TESTCTRL_OPTIMIZATIONS: ! 2262: case SQLITE_TESTCTRL_RESERVE: ! 2263: if( nArg==3 ){ ! 2264: int opt = (int)strtol(azArg[2], 0, 0); ! 2265: rc = sqlite3_test_control(testctrl, p->db, opt); ! 2266: printf("%d (0x%08x)\n", rc, rc); ! 2267: } else { ! 2268: fprintf(stderr,"Error: testctrl %s takes a single int option\n", ! 2269: azArg[1]); ! 2270: } ! 2271: break; ! 2272: ! 2273: /* sqlite3_test_control(int) */ ! 2274: case SQLITE_TESTCTRL_PRNG_SAVE: ! 2275: case SQLITE_TESTCTRL_PRNG_RESTORE: ! 2276: case SQLITE_TESTCTRL_PRNG_RESET: ! 2277: if( nArg==2 ){ ! 2278: rc = sqlite3_test_control(testctrl); ! 2279: printf("%d (0x%08x)\n", rc, rc); ! 2280: } else { ! 2281: fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]); ! 2282: } ! 2283: break; ! 2284: ! 2285: /* sqlite3_test_control(int, uint) */ ! 2286: case SQLITE_TESTCTRL_PENDING_BYTE: ! 2287: if( nArg==3 ){ ! 2288: unsigned int opt = (unsigned int)atoi(azArg[2]); ! 2289: rc = sqlite3_test_control(testctrl, opt); ! 2290: printf("%d (0x%08x)\n", rc, rc); ! 2291: } else { ! 2292: fprintf(stderr,"Error: testctrl %s takes a single unsigned" ! 2293: " int option\n", azArg[1]); ! 2294: } ! 2295: break; ! 2296: ! 2297: /* sqlite3_test_control(int, int) */ ! 2298: case SQLITE_TESTCTRL_ASSERT: ! 2299: case SQLITE_TESTCTRL_ALWAYS: ! 2300: if( nArg==3 ){ ! 2301: int opt = atoi(azArg[2]); ! 2302: rc = sqlite3_test_control(testctrl, opt); ! 2303: printf("%d (0x%08x)\n", rc, rc); ! 2304: } else { ! 2305: fprintf(stderr,"Error: testctrl %s takes a single int option\n", ! 2306: azArg[1]); ! 2307: } ! 2308: break; ! 2309: ! 2310: /* sqlite3_test_control(int, char *) */ ! 2311: #ifdef SQLITE_N_KEYWORD ! 2312: case SQLITE_TESTCTRL_ISKEYWORD: ! 2313: if( nArg==3 ){ ! 2314: const char *opt = azArg[2]; ! 2315: rc = sqlite3_test_control(testctrl, opt); ! 2316: printf("%d (0x%08x)\n", rc, rc); ! 2317: } else { ! 2318: fprintf(stderr,"Error: testctrl %s takes a single char * option\n", ! 2319: azArg[1]); ! 2320: } ! 2321: break; ! 2322: #endif ! 2323: ! 2324: case SQLITE_TESTCTRL_BITVEC_TEST: ! 2325: case SQLITE_TESTCTRL_FAULT_INSTALL: ! 2326: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: ! 2327: case SQLITE_TESTCTRL_SCRATCHMALLOC: ! 2328: default: ! 2329: fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", ! 2330: azArg[1]); ! 2331: break; ! 2332: } ! 2333: } ! 2334: }else ! 2335: ! 2336: if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){ ! 2337: open_db(p); ! 2338: sqlite3_busy_timeout(p->db, atoi(azArg[1])); ! 2339: }else ! 2340: ! 2341: if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ! 2342: && nArg==2 ! 2343: ){ ! 2344: enableTimer = booleanValue(azArg[1]); ! 2345: }else ! 2346: ! 2347: if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ ! 2348: printf("SQLite %s %s\n" /*extra-version-info*/, ! 2349: sqlite3_libversion(), sqlite3_sourceid()); ! 2350: }else ! 2351: ! 2352: if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ ! 2353: const char *zDbName = nArg==2 ? azArg[1] : "main"; ! 2354: char *zVfsName = 0; ! 2355: if( p->db ){ ! 2356: sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); ! 2357: if( zVfsName ){ ! 2358: printf("%s\n", zVfsName); ! 2359: sqlite3_free(zVfsName); ! 2360: } ! 2361: } ! 2362: }else ! 2363: ! 2364: if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ ! 2365: int j; ! 2366: assert( nArg<=ArraySize(azArg) ); ! 2367: for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ ! 2368: p->colWidth[j-1] = atoi(azArg[j]); ! 2369: } ! 2370: }else ! 2371: ! 2372: { ! 2373: fprintf(stderr, "Error: unknown command or invalid arguments: " ! 2374: " \"%s\". Enter \".help\" for help\n", azArg[0]); ! 2375: rc = 1; ! 2376: } ! 2377: ! 2378: return rc; ! 2379: } ! 2380: ! 2381: /* ! 2382: ** Return TRUE if a semicolon occurs anywhere in the first N characters ! 2383: ** of string z[]. ! 2384: */ ! 2385: static int _contains_semicolon(const char *z, int N){ ! 2386: int i; ! 2387: for(i=0; i<N; i++){ if( z[i]==';' ) return 1; } ! 2388: return 0; ! 2389: } ! 2390: ! 2391: /* ! 2392: ** Test to see if a line consists entirely of whitespace. ! 2393: */ ! 2394: static int _all_whitespace(const char *z){ ! 2395: for(; *z; z++){ ! 2396: if( IsSpace(z[0]) ) continue; ! 2397: if( *z=='/' && z[1]=='*' ){ ! 2398: z += 2; ! 2399: while( *z && (*z!='*' || z[1]!='/') ){ z++; } ! 2400: if( *z==0 ) return 0; ! 2401: z++; ! 2402: continue; ! 2403: } ! 2404: if( *z=='-' && z[1]=='-' ){ ! 2405: z += 2; ! 2406: while( *z && *z!='\n' ){ z++; } ! 2407: if( *z==0 ) return 1; ! 2408: continue; ! 2409: } ! 2410: return 0; ! 2411: } ! 2412: return 1; ! 2413: } ! 2414: ! 2415: /* ! 2416: ** Return TRUE if the line typed in is an SQL command terminator other ! 2417: ** than a semi-colon. The SQL Server style "go" command is understood ! 2418: ** as is the Oracle "/". ! 2419: */ ! 2420: static int _is_command_terminator(const char *zLine){ ! 2421: while( IsSpace(zLine[0]) ){ zLine++; }; ! 2422: if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){ ! 2423: return 1; /* Oracle */ ! 2424: } ! 2425: if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' ! 2426: && _all_whitespace(&zLine[2]) ){ ! 2427: return 1; /* SQL Server */ ! 2428: } ! 2429: return 0; ! 2430: } ! 2431: ! 2432: /* ! 2433: ** Return true if zSql is a complete SQL statement. Return false if it ! 2434: ** ends in the middle of a string literal or C-style comment. ! 2435: */ ! 2436: static int _is_complete(char *zSql, int nSql){ ! 2437: int rc; ! 2438: if( zSql==0 ) return 1; ! 2439: zSql[nSql] = ';'; ! 2440: zSql[nSql+1] = 0; ! 2441: rc = sqlite3_complete(zSql); ! 2442: zSql[nSql] = 0; ! 2443: return rc; ! 2444: } ! 2445: ! 2446: /* ! 2447: ** Read input from *in and process it. If *in==0 then input ! 2448: ** is interactive - the user is typing it it. Otherwise, input ! 2449: ** is coming from a file or device. A prompt is issued and history ! 2450: ** is saved only if input is interactive. An interrupt signal will ! 2451: ** cause this routine to exit immediately, unless input is interactive. ! 2452: ** ! 2453: ** Return the number of errors. ! 2454: */ ! 2455: static int process_input(struct callback_data *p, FILE *in){ ! 2456: char *zLine = 0; ! 2457: char *zSql = 0; ! 2458: int nSql = 0; ! 2459: int nSqlPrior = 0; ! 2460: char *zErrMsg; ! 2461: int rc; ! 2462: int errCnt = 0; ! 2463: int lineno = 0; ! 2464: int startline = 0; ! 2465: ! 2466: while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){ ! 2467: fflush(p->out); ! 2468: free(zLine); ! 2469: zLine = one_input_line(zSql, in); ! 2470: if( zLine==0 ){ ! 2471: break; /* We have reached EOF */ ! 2472: } ! 2473: if( seenInterrupt ){ ! 2474: if( in!=0 ) break; ! 2475: seenInterrupt = 0; ! 2476: } ! 2477: lineno++; ! 2478: if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue; ! 2479: if( zLine && zLine[0]=='.' && nSql==0 ){ ! 2480: if( p->echoOn ) printf("%s\n", zLine); ! 2481: rc = do_meta_command(zLine, p); ! 2482: if( rc==2 ){ /* exit requested */ ! 2483: break; ! 2484: }else if( rc ){ ! 2485: errCnt++; ! 2486: } ! 2487: continue; ! 2488: } ! 2489: if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){ ! 2490: memcpy(zLine,";",2); ! 2491: } ! 2492: nSqlPrior = nSql; ! 2493: if( zSql==0 ){ ! 2494: int i; ! 2495: for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} ! 2496: if( zLine[i]!=0 ){ ! 2497: nSql = strlen30(zLine); ! 2498: zSql = malloc( nSql+3 ); ! 2499: if( zSql==0 ){ ! 2500: fprintf(stderr, "Error: out of memory\n"); ! 2501: exit(1); ! 2502: } ! 2503: memcpy(zSql, zLine, nSql+1); ! 2504: startline = lineno; ! 2505: } ! 2506: }else{ ! 2507: int len = strlen30(zLine); ! 2508: zSql = realloc( zSql, nSql + len + 4 ); ! 2509: if( zSql==0 ){ ! 2510: fprintf(stderr,"Error: out of memory\n"); ! 2511: exit(1); ! 2512: } ! 2513: zSql[nSql++] = '\n'; ! 2514: memcpy(&zSql[nSql], zLine, len+1); ! 2515: nSql += len; ! 2516: } ! 2517: if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) ! 2518: && sqlite3_complete(zSql) ){ ! 2519: p->cnt = 0; ! 2520: open_db(p); ! 2521: BEGIN_TIMER; ! 2522: rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); ! 2523: END_TIMER; ! 2524: if( rc || zErrMsg ){ ! 2525: char zPrefix[100]; ! 2526: if( in!=0 || !stdin_is_interactive ){ ! 2527: sqlite3_snprintf(sizeof(zPrefix), zPrefix, ! 2528: "Error: near line %d:", startline); ! 2529: }else{ ! 2530: sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); ! 2531: } ! 2532: if( zErrMsg!=0 ){ ! 2533: fprintf(stderr, "%s %s\n", zPrefix, zErrMsg); ! 2534: sqlite3_free(zErrMsg); ! 2535: zErrMsg = 0; ! 2536: }else{ ! 2537: fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); ! 2538: } ! 2539: errCnt++; ! 2540: } ! 2541: free(zSql); ! 2542: zSql = 0; ! 2543: nSql = 0; ! 2544: } ! 2545: } ! 2546: if( zSql ){ ! 2547: if( !_all_whitespace(zSql) ){ ! 2548: fprintf(stderr, "Error: incomplete SQL: %s\n", zSql); ! 2549: } ! 2550: free(zSql); ! 2551: } ! 2552: free(zLine); ! 2553: return errCnt; ! 2554: } ! 2555: ! 2556: /* ! 2557: ** Return a pathname which is the user's home directory. A ! 2558: ** 0 return indicates an error of some kind. Space to hold the ! 2559: ** resulting string is obtained from malloc(). The calling ! 2560: ** function should free the result. ! 2561: */ ! 2562: static char *find_home_dir(void){ ! 2563: char *home_dir = NULL; ! 2564: ! 2565: #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL) ! 2566: struct passwd *pwent; ! 2567: uid_t uid = getuid(); ! 2568: if( (pwent=getpwuid(uid)) != NULL) { ! 2569: home_dir = pwent->pw_dir; ! 2570: } ! 2571: #endif ! 2572: ! 2573: #if defined(_WIN32_WCE) ! 2574: /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() ! 2575: */ ! 2576: home_dir = strdup("/"); ! 2577: #else ! 2578: ! 2579: #if defined(_WIN32) || defined(WIN32) || defined(__OS2__) ! 2580: if (!home_dir) { ! 2581: home_dir = getenv("USERPROFILE"); ! 2582: } ! 2583: #endif ! 2584: ! 2585: if (!home_dir) { ! 2586: home_dir = getenv("HOME"); ! 2587: } ! 2588: ! 2589: #if defined(_WIN32) || defined(WIN32) || defined(__OS2__) ! 2590: if (!home_dir) { ! 2591: char *zDrive, *zPath; ! 2592: int n; ! 2593: zDrive = getenv("HOMEDRIVE"); ! 2594: zPath = getenv("HOMEPATH"); ! 2595: if( zDrive && zPath ){ ! 2596: n = strlen30(zDrive) + strlen30(zPath) + 1; ! 2597: home_dir = malloc( n ); ! 2598: if( home_dir==0 ) return 0; ! 2599: sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); ! 2600: return home_dir; ! 2601: } ! 2602: home_dir = "c:\\"; ! 2603: } ! 2604: #endif ! 2605: ! 2606: #endif /* !_WIN32_WCE */ ! 2607: ! 2608: if( home_dir ){ ! 2609: int n = strlen30(home_dir) + 1; ! 2610: char *z = malloc( n ); ! 2611: if( z ) memcpy(z, home_dir, n); ! 2612: home_dir = z; ! 2613: } ! 2614: ! 2615: return home_dir; ! 2616: } ! 2617: ! 2618: /* ! 2619: ** Read input from the file given by sqliterc_override. Or if that ! 2620: ** parameter is NULL, take input from ~/.sqliterc ! 2621: ** ! 2622: ** Returns the number of errors. ! 2623: */ ! 2624: static int process_sqliterc( ! 2625: struct callback_data *p, /* Configuration data */ ! 2626: const char *sqliterc_override /* Name of config file. NULL to use default */ ! 2627: ){ ! 2628: char *home_dir = NULL; ! 2629: const char *sqliterc = sqliterc_override; ! 2630: char *zBuf = 0; ! 2631: FILE *in = NULL; ! 2632: int nBuf; ! 2633: int rc = 0; ! 2634: ! 2635: if (sqliterc == NULL) { ! 2636: home_dir = find_home_dir(); ! 2637: if( home_dir==0 ){ ! 2638: #if !defined(__RTP__) && !defined(_WRS_KERNEL) ! 2639: fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0); ! 2640: #endif ! 2641: return 1; ! 2642: } ! 2643: nBuf = strlen30(home_dir) + 16; ! 2644: zBuf = malloc( nBuf ); ! 2645: if( zBuf==0 ){ ! 2646: fprintf(stderr,"%s: Error: out of memory\n",Argv0); ! 2647: return 1; ! 2648: } ! 2649: sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir); ! 2650: free(home_dir); ! 2651: sqliterc = (const char*)zBuf; ! 2652: } ! 2653: in = fopen(sqliterc,"rb"); ! 2654: if( in ){ ! 2655: if( stdin_is_interactive ){ ! 2656: fprintf(stderr,"-- Loading resources from %s\n",sqliterc); ! 2657: } ! 2658: rc = process_input(p,in); ! 2659: fclose(in); ! 2660: } ! 2661: free(zBuf); ! 2662: return rc; ! 2663: } ! 2664: ! 2665: /* ! 2666: ** Show available command line options ! 2667: */ ! 2668: static const char zOptions[] = ! 2669: " -help show this message\n" ! 2670: " -init filename read/process named file\n" ! 2671: " -echo print commands before execution\n" ! 2672: " -[no]header turn headers on or off\n" ! 2673: " -bail stop after hitting an error\n" ! 2674: " -interactive force interactive I/O\n" ! 2675: " -batch force batch I/O\n" ! 2676: " -column set output mode to 'column'\n" ! 2677: " -csv set output mode to 'csv'\n" ! 2678: " -html set output mode to HTML\n" ! 2679: " -line set output mode to 'line'\n" ! 2680: " -list set output mode to 'list'\n" ! 2681: " -separator 'x' set output field separator (|)\n" ! 2682: " -stats print memory stats before each finalize\n" ! 2683: " -nullvalue 'text' set text string for NULL values\n" ! 2684: " -version show SQLite version\n" ! 2685: " -vfs NAME use NAME as the default VFS\n" ! 2686: #ifdef SQLITE_ENABLE_VFSTRACE ! 2687: " -vfstrace enable tracing of all VFS calls\n" ! 2688: #endif ! 2689: #ifdef SQLITE_ENABLE_MULTIPLEX ! 2690: " -multiplex enable the multiplexor VFS\n" ! 2691: #endif ! 2692: ; ! 2693: static void usage(int showDetail){ ! 2694: fprintf(stderr, ! 2695: "Usage: %s [OPTIONS] FILENAME [SQL]\n" ! 2696: "FILENAME is the name of an SQLite database. A new database is created\n" ! 2697: "if the file does not previously exist.\n", Argv0); ! 2698: if( showDetail ){ ! 2699: fprintf(stderr, "OPTIONS include:\n%s", zOptions); ! 2700: }else{ ! 2701: fprintf(stderr, "Use the -help option for additional information\n"); ! 2702: } ! 2703: exit(1); ! 2704: } ! 2705: ! 2706: /* ! 2707: ** Initialize the state information in data ! 2708: */ ! 2709: static void main_init(struct callback_data *data) { ! 2710: memset(data, 0, sizeof(*data)); ! 2711: data->mode = MODE_List; ! 2712: memcpy(data->separator,"|", 2); ! 2713: data->showHeader = 0; ! 2714: sqlite3_config(SQLITE_CONFIG_URI, 1); ! 2715: sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); ! 2716: sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); ! 2717: sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); ! 2718: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); ! 2719: } ! 2720: ! 2721: int main(int argc, char **argv){ ! 2722: char *zErrMsg = 0; ! 2723: struct callback_data data; ! 2724: const char *zInitFile = 0; ! 2725: char *zFirstCmd = 0; ! 2726: int i; ! 2727: int rc = 0; ! 2728: ! 2729: if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ ! 2730: fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", ! 2731: sqlite3_sourceid(), SQLITE_SOURCE_ID); ! 2732: exit(1); ! 2733: } ! 2734: Argv0 = argv[0]; ! 2735: main_init(&data); ! 2736: stdin_is_interactive = isatty(0); ! 2737: ! 2738: /* Make sure we have a valid signal handler early, before anything ! 2739: ** else is done. ! 2740: */ ! 2741: #ifdef SIGINT ! 2742: signal(SIGINT, interrupt_handler); ! 2743: #endif ! 2744: ! 2745: /* Do an initial pass through the command-line argument to locate ! 2746: ** the name of the database file, the name of the initialization file, ! 2747: ** the size of the alternative malloc heap, ! 2748: ** and the first command to execute. ! 2749: */ ! 2750: for(i=1; i<argc-1; i++){ ! 2751: char *z; ! 2752: if( argv[i][0]!='-' ) break; ! 2753: z = argv[i]; ! 2754: if( z[0]=='-' && z[1]=='-' ) z++; ! 2755: if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){ ! 2756: i++; ! 2757: }else if( strcmp(argv[i],"-init")==0 ){ ! 2758: i++; ! 2759: zInitFile = argv[i]; ! 2760: /* Need to check for batch mode here to so we can avoid printing ! 2761: ** informational messages (like from process_sqliterc) before ! 2762: ** we do the actual processing of arguments later in a second pass. ! 2763: */ ! 2764: }else if( strcmp(argv[i],"-batch")==0 ){ ! 2765: stdin_is_interactive = 0; ! 2766: }else if( strcmp(argv[i],"-heap")==0 ){ ! 2767: #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) ! 2768: int j, c; ! 2769: const char *zSize; ! 2770: sqlite3_int64 szHeap; ! 2771: ! 2772: zSize = argv[++i]; ! 2773: szHeap = atoi(zSize); ! 2774: for(j=0; (c = zSize[j])!=0; j++){ ! 2775: if( c=='M' ){ szHeap *= 1000000; break; } ! 2776: if( c=='K' ){ szHeap *= 1000; break; } ! 2777: if( c=='G' ){ szHeap *= 1000000000; break; } ! 2778: } ! 2779: if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; ! 2780: sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); ! 2781: #endif ! 2782: #ifdef SQLITE_ENABLE_VFSTRACE ! 2783: }else if( strcmp(argv[i],"-vfstrace")==0 ){ ! 2784: extern int vfstrace_register( ! 2785: const char *zTraceName, ! 2786: const char *zOldVfsName, ! 2787: int (*xOut)(const char*,void*), ! 2788: void *pOutArg, ! 2789: int makeDefault ! 2790: ); ! 2791: vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); ! 2792: #endif ! 2793: #ifdef SQLITE_ENABLE_MULTIPLEX ! 2794: }else if( strcmp(argv[i],"-multiplex")==0 ){ ! 2795: extern int sqlite3_multiple_initialize(const char*,int); ! 2796: sqlite3_multiplex_initialize(0, 1); ! 2797: #endif ! 2798: }else if( strcmp(argv[i],"-vfs")==0 ){ ! 2799: sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]); ! 2800: if( pVfs ){ ! 2801: sqlite3_vfs_register(pVfs, 1); ! 2802: }else{ ! 2803: fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]); ! 2804: exit(1); ! 2805: } ! 2806: } ! 2807: } ! 2808: if( i<argc ){ ! 2809: #if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2 ! 2810: data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] ); ! 2811: #else ! 2812: data.zDbFilename = argv[i++]; ! 2813: #endif ! 2814: }else{ ! 2815: #ifndef SQLITE_OMIT_MEMORYDB ! 2816: data.zDbFilename = ":memory:"; ! 2817: #else ! 2818: data.zDbFilename = 0; ! 2819: #endif ! 2820: } ! 2821: if( i<argc ){ ! 2822: zFirstCmd = argv[i++]; ! 2823: } ! 2824: if( i<argc ){ ! 2825: fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]); ! 2826: fprintf(stderr,"Use -help for a list of options.\n"); ! 2827: return 1; ! 2828: } ! 2829: data.out = stdout; ! 2830: ! 2831: #ifdef SQLITE_OMIT_MEMORYDB ! 2832: if( data.zDbFilename==0 ){ ! 2833: fprintf(stderr,"%s: Error: no database filename specified\n", Argv0); ! 2834: return 1; ! 2835: } ! 2836: #endif ! 2837: ! 2838: /* Go ahead and open the database file if it already exists. If the ! 2839: ** file does not exist, delay opening it. This prevents empty database ! 2840: ** files from being created if a user mistypes the database name argument ! 2841: ** to the sqlite command-line tool. ! 2842: */ ! 2843: if( access(data.zDbFilename, 0)==0 ){ ! 2844: open_db(&data); ! 2845: } ! 2846: ! 2847: /* Process the initialization file if there is one. If no -init option ! 2848: ** is given on the command line, look for a file named ~/.sqliterc and ! 2849: ** try to process it. ! 2850: */ ! 2851: rc = process_sqliterc(&data,zInitFile); ! 2852: if( rc>0 ){ ! 2853: return rc; ! 2854: } ! 2855: ! 2856: /* Make a second pass through the command-line argument and set ! 2857: ** options. This second pass is delayed until after the initialization ! 2858: ** file is processed so that the command-line arguments will override ! 2859: ** settings in the initialization file. ! 2860: */ ! 2861: for(i=1; i<argc && argv[i][0]=='-'; i++){ ! 2862: char *z = argv[i]; ! 2863: if( z[1]=='-' ){ z++; } ! 2864: if( strcmp(z,"-init")==0 ){ ! 2865: i++; ! 2866: }else if( strcmp(z,"-html")==0 ){ ! 2867: data.mode = MODE_Html; ! 2868: }else if( strcmp(z,"-list")==0 ){ ! 2869: data.mode = MODE_List; ! 2870: }else if( strcmp(z,"-line")==0 ){ ! 2871: data.mode = MODE_Line; ! 2872: }else if( strcmp(z,"-column")==0 ){ ! 2873: data.mode = MODE_Column; ! 2874: }else if( strcmp(z,"-csv")==0 ){ ! 2875: data.mode = MODE_Csv; ! 2876: memcpy(data.separator,",",2); ! 2877: }else if( strcmp(z,"-separator")==0 ){ ! 2878: i++; ! 2879: if(i>=argc){ ! 2880: fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z); ! 2881: fprintf(stderr,"Use -help for a list of options.\n"); ! 2882: return 1; ! 2883: } ! 2884: sqlite3_snprintf(sizeof(data.separator), data.separator, ! 2885: "%.*s",(int)sizeof(data.separator)-1,argv[i]); ! 2886: }else if( strcmp(z,"-nullvalue")==0 ){ ! 2887: i++; ! 2888: if(i>=argc){ ! 2889: fprintf(stderr,"%s: Error: missing argument for option: %s\n", Argv0, z); ! 2890: fprintf(stderr,"Use -help for a list of options.\n"); ! 2891: return 1; ! 2892: } ! 2893: sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, ! 2894: "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]); ! 2895: }else if( strcmp(z,"-header")==0 ){ ! 2896: data.showHeader = 1; ! 2897: }else if( strcmp(z,"-noheader")==0 ){ ! 2898: data.showHeader = 0; ! 2899: }else if( strcmp(z,"-echo")==0 ){ ! 2900: data.echoOn = 1; ! 2901: }else if( strcmp(z,"-stats")==0 ){ ! 2902: data.statsOn = 1; ! 2903: }else if( strcmp(z,"-bail")==0 ){ ! 2904: bail_on_error = 1; ! 2905: }else if( strcmp(z,"-version")==0 ){ ! 2906: printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); ! 2907: return 0; ! 2908: }else if( strcmp(z,"-interactive")==0 ){ ! 2909: stdin_is_interactive = 1; ! 2910: }else if( strcmp(z,"-batch")==0 ){ ! 2911: stdin_is_interactive = 0; ! 2912: }else if( strcmp(z,"-heap")==0 ){ ! 2913: i++; ! 2914: }else if( strcmp(z,"-vfs")==0 ){ ! 2915: i++; ! 2916: #ifdef SQLITE_ENABLE_VFSTRACE ! 2917: }else if( strcmp(z,"-vfstrace")==0 ){ ! 2918: i++; ! 2919: #endif ! 2920: #ifdef SQLITE_ENABLE_MULTIPLEX ! 2921: }else if( strcmp(z,"-multiplex")==0 ){ ! 2922: i++; ! 2923: #endif ! 2924: }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){ ! 2925: usage(1); ! 2926: }else{ ! 2927: fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); ! 2928: fprintf(stderr,"Use -help for a list of options.\n"); ! 2929: return 1; ! 2930: } ! 2931: } ! 2932: ! 2933: if( zFirstCmd ){ ! 2934: /* Run just the command that follows the database name ! 2935: */ ! 2936: if( zFirstCmd[0]=='.' ){ ! 2937: rc = do_meta_command(zFirstCmd, &data); ! 2938: }else{ ! 2939: open_db(&data); ! 2940: rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg); ! 2941: if( zErrMsg!=0 ){ ! 2942: fprintf(stderr,"Error: %s\n", zErrMsg); ! 2943: return rc!=0 ? rc : 1; ! 2944: }else if( rc!=0 ){ ! 2945: fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd); ! 2946: return rc; ! 2947: } ! 2948: } ! 2949: }else{ ! 2950: /* Run commands received from standard input ! 2951: */ ! 2952: if( stdin_is_interactive ){ ! 2953: char *zHome; ! 2954: char *zHistory = 0; ! 2955: int nHistory; ! 2956: printf( ! 2957: "SQLite version %s %.19s\n" /*extra-version-info*/ ! 2958: "Enter \".help\" for instructions\n" ! 2959: "Enter SQL statements terminated with a \";\"\n", ! 2960: sqlite3_libversion(), sqlite3_sourceid() ! 2961: ); ! 2962: zHome = find_home_dir(); ! 2963: if( zHome ){ ! 2964: nHistory = strlen30(zHome) + 20; ! 2965: if( (zHistory = malloc(nHistory))!=0 ){ ! 2966: sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); ! 2967: } ! 2968: } ! 2969: #if defined(HAVE_READLINE) && HAVE_READLINE==1 ! 2970: if( zHistory ) read_history(zHistory); ! 2971: #endif ! 2972: rc = process_input(&data, 0); ! 2973: if( zHistory ){ ! 2974: stifle_history(100); ! 2975: write_history(zHistory); ! 2976: free(zHistory); ! 2977: } ! 2978: free(zHome); ! 2979: }else{ ! 2980: rc = process_input(&data, stdin); ! 2981: } ! 2982: } ! 2983: set_table_name(&data, 0); ! 2984: if( data.db ){ ! 2985: sqlite3_close(data.db); ! 2986: } ! 2987: return rc; ! 2988: }