/*** 2001 September 15**** The author disclaims copyright to this source code. In place of** a legal notice, here is a blessing:**** May you do good and not evil.** May you find forgiveness for yourself and forgive others.** May you share freely, never taking more than you give. RUSAGE_SELF***************************************************************************** This file contains code to implement the "sqlite" command line** utility for accessing SQLite databases.*/#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)/* This needs to come before any includes for MSVC compiler */#define _CRT_SECURE_NO_WARNINGS#endif /*** Enable large-file support for fopen() and friends on unix.*/#ifndef SQLITE_DISABLE_LFS# define _LARGE_FILE 1# ifndef _FILE_OFFSET_BITS# define _FILE_OFFSET_BITS 64# endif# define _LARGEFILE_SOURCE 1#endif #include <stdlib.h>#include <string.h>#include <stdio.h>#include <assert.h>#include "sqlite3.h"#include <ctype.h>#include <stdarg.h> #if !defined(_WIN32) && !defined(WIN32)# include <signal.h># if !defined(__RTP__) && !defined(_WRS_KERNEL)# include <pwd.h># endif# include <unistd.h># include <sys/types.h>#endif #ifdef HAVE_EDITLINE/* changed to reflect modern header structure */# include <editline/readline.h># include <histedit.h>#endif/*#if defined(HAVE_READLINE) && HAVE_READLINE==1# include <readline/readline.h># include <readline/history.h>#endif */#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)# define readline(p) local_getline(p,stdin,0)# define add_history(X)# define read_history(X)# define write_history(X)# define stifle_history(X)#endif #if defined(_WIN32) || defined(WIN32)# include <io.h>#define isatty(h) _isatty(h)#define access(f,m) _access((f),(m))#undef popen#define popen(a,b) _popen((a),(b))#undef pclose#define pclose(x) _pclose(x)#else/* Make sure isatty() has a prototype.*/extern int isatty(int);#endif #if defined(_WIN32_WCE)/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() * thus we always assume that we have a console. That can be * overridden with the -batch command line option. */#define isatty(x) 1#endif /* True if the timer is enabled */static int enableTimer = 0; /* ctype macros that work with signed characters */#define IsSpace(X) isspace((unsigned char)X)#define IsDigit(X) isdigit((unsigned char)X)#define ToLower(X) (char)tolower((unsigned char)X) #if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) && !defined(PLAN9)#include <sys/time.h>#include <sys/resource.h> /* Saved resource information for the beginning of an operation */static struct rusage sBegin; /*** Begin timing an operation*/static void beginTimer(void){ if( enableTimer ){ getrusage(RUSAGE_SELF, &sBegin); }} /* Return the difference of two time_structs in seconds */static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + (double)(pEnd->tv_sec - pStart->tv_sec);} /*** Print the timing results.*/static void endTimer(void){ if( enableTimer ){ struct rusage sEnd; getrusage(RUSAGE_SELF, &sEnd); printf("CPU Time: user %f sys %f\n", timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); }} #define BEGIN_TIMER beginTimer()#define END_TIMER endTimer()#define HAS_TIMER 1 #elif (defined(_WIN32) || defined(WIN32)) #include <windows.h> /* Saved resource information for the beginning of an operation */static HANDLE hProcess;static FILETIME ftKernelBegin;static FILETIME ftUserBegin;typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);static GETPROCTIMES getProcessTimesAddr = NULL; /*** Check to see if we have timer support. Return 1 if necessary** support found (or found previously).*/static int hasTimer(void){ if( getProcessTimesAddr ){ return 1; } else { /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions. ** See if the version we are running on has it, and if it does, save off ** a pointer to it and the current process handle. */ hProcess = GetCurrentProcess(); if( hProcess ){ HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); if( NULL != hinstLib ){ getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); if( NULL != getProcessTimesAddr ){ return 1; } FreeLibrary(hinstLib); } } } return 0;} /*** Begin timing an operation*/static void beginTimer(void){ if( enableTimer && getProcessTimesAddr ){ FILETIME ftCreation, ftExit; getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin); }} /* Return the difference of two FILETIME structs in seconds */static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ sqlite_int64 i64Start = *((sqlite_int64 *) pStart); sqlite_int64 i64End = *((sqlite_int64 *) pEnd); return (double) ((i64End - i64Start) / 10000000.0);} /*** Print the timing results.*/static void endTimer(void){ if( enableTimer && getProcessTimesAddr){ FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd); printf("CPU Time: user %f sys %f\n", timeDiff(&ftUserBegin, &ftUserEnd), timeDiff(&ftKernelBegin, &ftKernelEnd)); }} #define BEGIN_TIMER beginTimer()#define END_TIMER endTimer()#define HAS_TIMER hasTimer() #else#define BEGIN_TIMER #define END_TIMER#define HAS_TIMER 0#endif /*** Used to prevent warnings about unused parameters*/#define UNUSED_PARAMETER(x) (void)(x) /*** If the following flag is set, then command execution stops** at an error if we are not interactive.*/static int bail_on_error = 0; /*** Threat stdin as an interactive input if the following variable** is true. Otherwise, assume stdin is connected to a file or pipe.*/static int stdin_is_interactive = 1; /*** The following is the open SQLite database. We make a pointer** to this database a static variable so that it can be accessed** by the SIGINT handler to interrupt database processing.*/static sqlite3 *db = 0; /*** True if an interrupt (Control-C) has been received.*/static volatile int seenInterrupt = 0; /*** This is the name of our program. It is set in main(), used** in a number of other places, mostly for error messages.*/static char *Argv0; /*** Prompt strings. Initialized in main. Settable with** .prompt main continue*/static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ /*** Write I/O traces to the following stream.*/#ifdef SQLITE_ENABLE_IOTRACEstatic FILE *iotrace = 0;#endif /*** This routine works like printf in that its first argument is a** format string and subsequent arguments are values to be substituted** in place of % fields. The result of formatting this string** is written to iotrace.*/#ifdef SQLITE_ENABLE_IOTRACEstatic void iotracePrintf(const char *zFormat, ...){ va_list ap; char *z; if( iotrace==0 ) return; va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); va_end(ap); fprintf(iotrace, "%s", z); sqlite3_free(z);}#endif /*** Determines if a string is a number of not.*/static int isNumber(const char *z, int *realnum){ if( *z=='-' || *z=='+' ) z++; if( !IsDigit(*z) ){ return 0; } z++; if( realnum ) *realnum = 0; while( IsDigit(*z) ){ z++; } if( *z=='.' ){ z++; if( !IsDigit(*z) ) return 0; while( IsDigit(*z) ){ z++; } if( realnum ) *realnum = 1; } if( *z=='e' || *z=='E' ){ z++; if( *z=='+' || *z=='-' ) z++; if( !IsDigit(*z) ) return 0; while( IsDigit(*z) ){ z++; } if( realnum ) *realnum = 1; } return *z==0;} /*** A global char* and an SQL function to access its current value ** from within an SQL statement. This program used to use the ** sqlite_exec_printf() API to substitue a string into an SQL statement.** The correct way to do this with sqlite3 is to use the bind API, but** since the shell is built around the callback paradigm it would be a lot** of work. Instead just use this hack, which is quite harmless.*/static const char *zShellStatic = 0;static void shellstaticFunc( sqlite3_context *context, int argc, sqlite3_value **argv){ assert( 0==argc ); assert( zShellStatic ); UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);} /*** This routine reads a line of text from FILE in, stores** the text in memory obtained from malloc() and returns a pointer** to the text. NULL is returned at end of file, or if malloc()** fails.**** The interface is like "readline" but no command-line editing** is done.*/static char *local_getline(char *zPrompt, FILE *in, int csvFlag){ char *zLine; int nLine; int n; int inQuote = 0; if( zPrompt && *zPrompt ){ printf("%s",zPrompt); fflush(stdout); } nLine = 100; zLine = malloc( nLine ); if( zLine==0 ) return 0; n = 0; while( 1 ){ if( n+100>nLine ){ nLine = nLine*2 + 100; zLine = realloc(zLine, nLine); if( zLine==0 ) return 0; } if( fgets(&zLine[n], nLine - n, in)==0 ){ if( n==0 ){ free(zLine); return 0; } zLine[n] = 0; break; } while( zLine[n] ){ if( zLine[n]=='"' ) inQuote = !inQuote; n++; } if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){ n--; if( n>0 && zLine[n-1]=='\r' ) n--; zLine[n] = 0; break; } } zLine = realloc( zLine, n+1 ); return zLine;} /*** Retrieve a single line of input text.**** zPrior is a string of prior text retrieved. If not the empty** string, then issue a continuation prompt.*/static char *one_input_line(const char *zPrior, FILE *in){ char *zPrompt; char *zResult; if( in!=0 ){ return local_getline(0, in, 0); } if( zPrior && zPrior[0] ){ zPrompt = continuePrompt; }else{ zPrompt = mainPrompt; } zResult = readline(zPrompt);#if defined(HAVE_READLINE) && HAVE_READLINE==1 if( zResult && *zResult ) add_history(zResult);#endif return zResult;} struct previous_mode_data { int valid; /* Is there legit data in here? */ int mode; int showHeader; int colWidth[100];}; /*** An pointer to an instance of this structure is passed from** the main program to the callback. This is used to communicate** state and mode information.*/struct callback_data { sqlite3 *db; /* The database */ int echoOn; /* True to echo input commands */ int statsOn; /* True to display memory stats before each finalize */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ int nErr; /* Number of errors seen */ int mode; /* An output mode setting */ int writableSchema; /* True if PRAGMA writable_schema=ON */ int showHeader; /* True to show column names in List or Column mode */ char *zDestTable; /* Name of destination table when MODE_Insert */ char separator[20]; /* Separator character for MODE_List */ int colWidth[100]; /* Requested width of each column when in column mode*/ int actualWidth[100]; /* Actual width of each column */ char nullvalue[20]; /* The text to print when a NULL comes back from ** the database */ struct previous_mode_data explainPrev; /* Holds the mode information just before ** .explain ON */ char outfile[FILENAME_MAX]; /* Filename for *out */ const char *zDbFilename; /* name of the database file */ const char *zVfs; /* Name of VFS to use */ sqlite3_stmt *pStmt; /* Current statement if any. */ FILE *pLog; /* Write log output here */}; /*** These are the allowed modes.*/#define MODE_Line 0 /* One column per line. Blank line between records */#define MODE_Column 1 /* One record per line in neat columns */#define MODE_List 2 /* One record per line with a separator */#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */#define MODE_Html 4 /* Generate an XHTML table */#define MODE_Insert 5 /* Generate SQL "insert" statements */#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */#define MODE_Csv 7 /* Quote strings, numbers are plain */#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ static const char *modeDescr[] = { "line", "column", "list", "semi", "html", "insert", "tcl", "csv", "explain",}; /*** Number of elements in an array*/#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) /*** Compute a string length that is limited to what can be stored in** lower 30 bits of a 32-bit signed integer.*/static int strlen30(const char *z){ const char *z2 = z; while( *z2 ){ z2++; } return 0x3fffffff & (int)(z2 - z);} /*** A callback for the sqlite3_log() interface.*/static void shellLog(void *pArg, int iErrCode, const char *zMsg){ struct callback_data *p = (struct callback_data*)pArg; if( p->pLog==0 ) return; fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); fflush(p->pLog);} /*** Output the given string as a hex-encoded blob (eg. X'1234' )*/static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ int i;Lines 1–500 of 3166. Load more
/* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. RUSAGE_SELF ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. */ #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) /* This needs to come before any includes for MSVC compiler */ #define _CRT_SECURE_NO_WARNINGS #endif /* ** Enable large-file support for fopen() and friends on unix. */ #ifndef SQLITE_DISABLE_LFS # define _LARGE_FILE 1 # ifndef _FILE_OFFSET_BITS # define _FILE_OFFSET_BITS 64 # endif # define _LARGEFILE_SOURCE 1 #endif #include <stdlib.h> #include <string.h> #include <stdio.h> #include <assert.h> #include "sqlite3.h" #include <ctype.h> #include <stdarg.h> #if !defined(_WIN32) && !defined(WIN32) # include <signal.h> # if !defined(__RTP__) && !defined(_WRS_KERNEL) # include <pwd.h> # endif # include <unistd.h> # include <sys/types.h> #endif #ifdef HAVE_EDITLINE /* changed to reflect modern header structure */ # include <editline/readline.h> # include <histedit.h> #endif /* #if defined(HAVE_READLINE) && HAVE_READLINE==1 # include <readline/readline.h> # include <readline/history.h> #endif */ #if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1) # define readline(p) local_getline(p,stdin,0) # define add_history(X) # define read_history(X) # define write_history(X) # define stifle_history(X) #endif #if defined(_WIN32) || defined(WIN32) # include <io.h> #define isatty(h) _isatty(h) #define access(f,m) _access((f),(m)) #undef popen #define popen(a,b) _popen((a),(b)) #undef pclose #define pclose(x) _pclose(x) #else /* Make sure isatty() has a prototype. */ extern int isatty(int); #endif #if defined(_WIN32_WCE) /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() * thus we always assume that we have a console. That can be * overridden with the -batch command line option. */ #define isatty(x) 1 #endif /* True if the timer is enabled */ static int enableTimer = 0; /* ctype macros that work with signed characters */ #define IsSpace(X) isspace((unsigned char)X) #define IsDigit(X) isdigit((unsigned char)X) #define ToLower(X) (char)tolower((unsigned char)X) #if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) && !defined(PLAN9) #include <sys/time.h> #include <sys/resource.h> /* Saved resource information for the beginning of an operation */ static struct rusage sBegin; /* ** Begin timing an operation */ static void beginTimer(void){ if( enableTimer ){ getrusage(RUSAGE_SELF, &sBegin); } } /* Return the difference of two time_structs in seconds */ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + (double)(pEnd->tv_sec - pStart->tv_sec); } /* ** Print the timing results. */ static void endTimer(void){ if( enableTimer ){ struct rusage sEnd; getrusage(RUSAGE_SELF, &sEnd); printf("CPU Time: user %f sys %f\n", timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); } } #define BEGIN_TIMER beginTimer() #define END_TIMER endTimer() #define HAS_TIMER 1 #elif (defined(_WIN32) || defined(WIN32)) #include <windows.h> /* Saved resource information for the beginning of an operation */ static HANDLE hProcess; static FILETIME ftKernelBegin; static FILETIME ftUserBegin; typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); static GETPROCTIMES getProcessTimesAddr = NULL; /* ** Check to see if we have timer support. Return 1 if necessary ** support found (or found previously). */ static int hasTimer(void){ if( getProcessTimesAddr ){ return 1; } else { /* GetProcessTimes() isn't supported in WIN95 and some other Windows versions. ** See if the version we are running on has it, and if it does, save off ** a pointer to it and the current process handle. */ hProcess = GetCurrentProcess(); if( hProcess ){ HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); if( NULL != hinstLib ){ getProcessTimesAddr = (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); if( NULL != getProcessTimesAddr ){ return 1; } FreeLibrary(hinstLib); } } } return 0; } /* ** Begin timing an operation */ static void beginTimer(void){ if( enableTimer && getProcessTimesAddr ){ FILETIME ftCreation, ftExit; getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin); } } /* Return the difference of two FILETIME structs in seconds */ static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ sqlite_int64 i64Start = *((sqlite_int64 *) pStart); sqlite_int64 i64End = *((sqlite_int64 *) pEnd); return (double) ((i64End - i64Start) / 10000000.0); } /* ** Print the timing results. */ static void endTimer(void){ if( enableTimer && getProcessTimesAddr){ FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd); printf("CPU Time: user %f sys %f\n", timeDiff(&ftUserBegin, &ftUserEnd), timeDiff(&ftKernelBegin, &ftKernelEnd)); } } #define BEGIN_TIMER beginTimer() #define END_TIMER endTimer() #define HAS_TIMER hasTimer() #else #define BEGIN_TIMER #define END_TIMER #define HAS_TIMER 0 #endif /* ** Used to prevent warnings about unused parameters */ #define UNUSED_PARAMETER(x) (void)(x) /* ** If the following flag is set, then command execution stops ** at an error if we are not interactive. */ static int bail_on_error = 0; /* ** Threat stdin as an interactive input if the following variable ** is true. Otherwise, assume stdin is connected to a file or pipe. */ static int stdin_is_interactive = 1; /* ** The following is the open SQLite database. We make a pointer ** to this database a static variable so that it can be accessed ** by the SIGINT handler to interrupt database processing. */ static sqlite3 *db = 0; /* ** True if an interrupt (Control-C) has been received. */ static volatile int seenInterrupt = 0; /* ** This is the name of our program. It is set in main(), used ** in a number of other places, mostly for error messages. */ static char *Argv0; /* ** Prompt strings. Initialized in main. Settable with ** .prompt main continue */ static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ /* ** Write I/O traces to the following stream. */ #ifdef SQLITE_ENABLE_IOTRACE static FILE *iotrace = 0; #endif /* ** This routine works like printf in that its first argument is a ** format string and subsequent arguments are values to be substituted ** in place of % fields. The result of formatting this string ** is written to iotrace. */ #ifdef SQLITE_ENABLE_IOTRACE static void iotracePrintf(const char *zFormat, ...){ va_list ap; char *z; if( iotrace==0 ) return; va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); va_end(ap); fprintf(iotrace, "%s", z); sqlite3_free(z); } #endif /* ** Determines if a string is a number of not. */ static int isNumber(const char *z, int *realnum){ if( *z=='-' || *z=='+' ) z++; if( !IsDigit(*z) ){ return 0; } z++; if( realnum ) *realnum = 0; while( IsDigit(*z) ){ z++; } if( *z=='.' ){ z++; if( !IsDigit(*z) ) return 0; while( IsDigit(*z) ){ z++; } if( realnum ) *realnum = 1; } if( *z=='e' || *z=='E' ){ z++; if( *z=='+' || *z=='-' ) z++; if( !IsDigit(*z) ) return 0; while( IsDigit(*z) ){ z++; } if( realnum ) *realnum = 1; } return *z==0; } /* ** A global char* and an SQL function to access its current value ** from within an SQL statement. This program used to use the ** sqlite_exec_printf() API to substitue a string into an SQL statement. ** The correct way to do this with sqlite3 is to use the bind API, but ** since the shell is built around the callback paradigm it would be a lot ** of work. Instead just use this hack, which is quite harmless. */ static const char *zShellStatic = 0; static void shellstaticFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ assert( 0==argc ); assert( zShellStatic ); UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC); } /* ** This routine reads a line of text from FILE in, stores ** the text in memory obtained from malloc() and returns a pointer ** to the text. NULL is returned at end of file, or if malloc() ** fails. ** ** The interface is like "readline" but no command-line editing ** is done. */ static char *local_getline(char *zPrompt, FILE *in, int csvFlag){ char *zLine; int nLine; int n; int inQuote = 0; if( zPrompt && *zPrompt ){ printf("%s",zPrompt); fflush(stdout); } nLine = 100; zLine = malloc( nLine ); if( zLine==0 ) return 0; n = 0; while( 1 ){ if( n+100>nLine ){ nLine = nLine*2 + 100; zLine = realloc(zLine, nLine); if( zLine==0 ) return 0; } if( fgets(&zLine[n], nLine - n, in)==0 ){ if( n==0 ){ free(zLine); return 0; } zLine[n] = 0; break; } while( zLine[n] ){ if( zLine[n]=='"' ) inQuote = !inQuote; n++; } if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){ n--; if( n>0 && zLine[n-1]=='\r' ) n--; zLine[n] = 0; break; } } zLine = realloc( zLine, n+1 ); return zLine; } /* ** Retrieve a single line of input text. ** ** zPrior is a string of prior text retrieved. If not the empty ** string, then issue a continuation prompt. */ static char *one_input_line(const char *zPrior, FILE *in){ char *zPrompt; char *zResult; if( in!=0 ){ return local_getline(0, in, 0); } if( zPrior && zPrior[0] ){ zPrompt = continuePrompt; }else{ zPrompt = mainPrompt; } zResult = readline(zPrompt); #if defined(HAVE_READLINE) && HAVE_READLINE==1 if( zResult && *zResult ) add_history(zResult); #endif return zResult; } struct previous_mode_data { int valid; /* Is there legit data in here? */ int mode; int showHeader; int colWidth[100]; }; /* ** An pointer to an instance of this structure is passed from ** the main program to the callback. This is used to communicate ** state and mode information. */ struct callback_data { sqlite3 *db; /* The database */ int echoOn; /* True to echo input commands */ int statsOn; /* True to display memory stats before each finalize */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ int nErr; /* Number of errors seen */ int mode; /* An output mode setting */ int writableSchema; /* True if PRAGMA writable_schema=ON */ int showHeader; /* True to show column names in List or Column mode */ char *zDestTable; /* Name of destination table when MODE_Insert */ char separator[20]; /* Separator character for MODE_List */ int colWidth[100]; /* Requested width of each column when in column mode*/ int actualWidth[100]; /* Actual width of each column */ char nullvalue[20]; /* The text to print when a NULL comes back from ** the database */ struct previous_mode_data explainPrev; /* Holds the mode information just before ** .explain ON */ char outfile[FILENAME_MAX]; /* Filename for *out */ const char *zDbFilename; /* name of the database file */ const char *zVfs; /* Name of VFS to use */ sqlite3_stmt *pStmt; /* Current statement if any. */ FILE *pLog; /* Write log output here */ }; /* ** These are the allowed modes. */ #define MODE_Line 0 /* One column per line. Blank line between records */ #define MODE_Column 1 /* One record per line in neat columns */ #define MODE_List 2 /* One record per line with a separator */ #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ #define MODE_Html 4 /* Generate an XHTML table */ #define MODE_Insert 5 /* Generate SQL "insert" statements */ #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ #define MODE_Csv 7 /* Quote strings, numbers are plain */ #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ static const char *modeDescr[] = { "line", "column", "list", "semi", "html", "insert", "tcl", "csv", "explain", }; /* ** Number of elements in an array */ #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) /* ** Compute a string length that is limited to what can be stored in ** lower 30 bits of a 32-bit signed integer. */ static int strlen30(const char *z){ const char *z2 = z; while( *z2 ){ z2++; } return 0x3fffffff & (int)(z2 - z); } /* ** A callback for the sqlite3_log() interface. */ static void shellLog(void *pArg, int iErrCode, const char *zMsg){ struct callback_data *p = (struct callback_data*)pArg; if( p->pLog==0 ) return; fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); fflush(p->pLog); } /* ** Output the given string as a hex-encoded blob (eg. X'1234' ) */ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ int i;