Back to index

lightning-sunbird  0.9+nobinonly
shell.c
Go to the documentation of this file.
00001 /*
00002 ** 2001 September 15
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** This file contains code to implement the "sqlite" command line
00013 ** utility for accessing SQLite databases.
00014 **
00015 ** $Id: shell.c,v 1.136 2006/05/10 14:39:14 drh Exp $
00016 */
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <stdio.h>
00020 #include <assert.h>
00021 #include "sqlite3.h"
00022 #include <ctype.h>
00023 
00024 #if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
00025 # include <signal.h>
00026 # include <pwd.h>
00027 # include <unistd.h>
00028 # include <sys/types.h>
00029 #endif
00030 
00031 #ifdef __MACOS__
00032 # include <console.h>
00033 # include <signal.h>
00034 # include <unistd.h>
00035 # include <extras.h>
00036 # include <Files.h>
00037 # include <Folders.h>
00038 #endif
00039 
00040 #if defined(HAVE_READLINE) && HAVE_READLINE==1
00041 # include <readline/readline.h>
00042 # include <readline/history.h>
00043 #else
00044 # define readline(p) local_getline(p,stdin)
00045 # define add_history(X)
00046 # define read_history(X)
00047 # define write_history(X)
00048 # define stifle_history(X)
00049 #endif
00050 
00051 /* Make sure isatty() has a prototype.
00052 */
00053 extern int isatty();
00054 
00055 /*
00056 ** The following is the open SQLite database.  We make a pointer
00057 ** to this database a static variable so that it can be accessed
00058 ** by the SIGINT handler to interrupt database processing.
00059 */
00060 static sqlite3 *db = 0;
00061 
00062 /*
00063 ** True if an interrupt (Control-C) has been received.
00064 */
00065 static volatile int seenInterrupt = 0;
00066 
00067 /*
00068 ** This is the name of our program. It is set in main(), used
00069 ** in a number of other places, mostly for error messages.
00070 */
00071 static char *Argv0;
00072 
00073 /*
00074 ** Prompt strings. Initialized in main. Settable with
00075 **   .prompt main continue
00076 */
00077 static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
00078 static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
00079 
00080 
00081 /*
00082 ** Determines if a string is a number of not.
00083 */
00084 static int isNumber(const char *z, int *realnum){
00085   if( *z=='-' || *z=='+' ) z++;
00086   if( !isdigit(*z) ){
00087     return 0;
00088   }
00089   z++;
00090   if( realnum ) *realnum = 0;
00091   while( isdigit(*z) ){ z++; }
00092   if( *z=='.' ){
00093     z++;
00094     if( !isdigit(*z) ) return 0;
00095     while( isdigit(*z) ){ z++; }
00096     if( realnum ) *realnum = 1;
00097   }
00098   if( *z=='e' || *z=='E' ){
00099     z++;
00100     if( *z=='+' || *z=='-' ) z++;
00101     if( !isdigit(*z) ) return 0;
00102     while( isdigit(*z) ){ z++; }
00103     if( realnum ) *realnum = 1;
00104   }
00105   return *z==0;
00106 }
00107 
00108 /*
00109 ** A global char* and an SQL function to access its current value 
00110 ** from within an SQL statement. This program used to use the 
00111 ** sqlite_exec_printf() API to substitue a string into an SQL statement.
00112 ** The correct way to do this with sqlite3 is to use the bind API, but
00113 ** since the shell is built around the callback paradigm it would be a lot
00114 ** of work. Instead just use this hack, which is quite harmless.
00115 */
00116 static const char *zShellStatic = 0;
00117 static void shellstaticFunc(
00118   sqlite3_context *context,
00119   int argc,
00120   sqlite3_value **argv
00121 ){
00122   assert( 0==argc );
00123   assert( zShellStatic );
00124   sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
00125 }
00126 
00127 
00128 /*
00129 ** This routine reads a line of text from FILE in, stores
00130 ** the text in memory obtained from malloc() and returns a pointer
00131 ** to the text.  NULL is returned at end of file, or if malloc()
00132 ** fails.
00133 **
00134 ** The interface is like "readline" but no command-line editing
00135 ** is done.
00136 */
00137 static char *local_getline(char *zPrompt, FILE *in){
00138   char *zLine;
00139   int nLine;
00140   int n;
00141   int eol;
00142 
00143   if( zPrompt && *zPrompt ){
00144     printf("%s",zPrompt);
00145     fflush(stdout);
00146   }
00147   nLine = 100;
00148   zLine = malloc( nLine );
00149   if( zLine==0 ) return 0;
00150   n = 0;
00151   eol = 0;
00152   while( !eol ){
00153     if( n+100>nLine ){
00154       nLine = nLine*2 + 100;
00155       zLine = realloc(zLine, nLine);
00156       if( zLine==0 ) return 0;
00157     }
00158     if( fgets(&zLine[n], nLine - n, in)==0 ){
00159       if( n==0 ){
00160         free(zLine);
00161         return 0;
00162       }
00163       zLine[n] = 0;
00164       eol = 1;
00165       break;
00166     }
00167     while( zLine[n] ){ n++; }
00168     if( n>0 && zLine[n-1]=='\n' ){
00169       n--;
00170       zLine[n] = 0;
00171       eol = 1;
00172     }
00173   }
00174   zLine = realloc( zLine, n+1 );
00175   return zLine;
00176 }
00177 
00178 /*
00179 ** Retrieve a single line of input text.  "isatty" is true if text
00180 ** is coming from a terminal.  In that case, we issue a prompt and
00181 ** attempt to use "readline" for command-line editing.  If "isatty"
00182 ** is false, use "local_getline" instead of "readline" and issue no prompt.
00183 **
00184 ** zPrior is a string of prior text retrieved.  If not the empty
00185 ** string, then issue a continuation prompt.
00186 */
00187 static char *one_input_line(const char *zPrior, FILE *in){
00188   char *zPrompt;
00189   char *zResult;
00190   if( in!=0 ){
00191     return local_getline(0, in);
00192   }
00193   if( zPrior && zPrior[0] ){
00194     zPrompt = continuePrompt;
00195   }else{
00196     zPrompt = mainPrompt;
00197   }
00198   zResult = readline(zPrompt);
00199 #if defined(HAVE_READLINE) && HAVE_READLINE==1
00200   if( zResult ) add_history(zResult);
00201 #endif
00202   return zResult;
00203 }
00204 
00205 struct previous_mode_data {
00206   int valid;        /* Is there legit data in here? */
00207   int mode;
00208   int showHeader;
00209   int colWidth[100];
00210 };
00211 /*
00212 ** An pointer to an instance of this structure is passed from
00213 ** the main program to the callback.  This is used to communicate
00214 ** state and mode information.
00215 */
00216 struct callback_data {
00217   sqlite3 *db;            /* The database */
00218   int echoOn;            /* True to echo input commands */
00219   int cnt;               /* Number of records displayed so far */
00220   FILE *out;             /* Write results here */
00221   int mode;              /* An output mode setting */
00222   int showHeader;        /* True to show column names in List or Column mode */
00223   char *zDestTable;      /* Name of destination table when MODE_Insert */
00224   char separator[20];    /* Separator character for MODE_List */
00225   int colWidth[100];     /* Requested width of each column when in column mode*/
00226   int actualWidth[100];  /* Actual width of each column */
00227   char nullvalue[20];    /* The text to print when a NULL comes back from
00228                          ** the database */
00229   struct previous_mode_data explainPrev;
00230                          /* Holds the mode information just before
00231                          ** .explain ON */
00232   char outfile[FILENAME_MAX]; /* Filename for *out */
00233   const char *zDbFilename;    /* name of the database file */
00234   char *zKey;                 /* Encryption key */
00235 };
00236 
00237 /*
00238 ** These are the allowed modes.
00239 */
00240 #define MODE_Line     0  /* One column per line.  Blank line between records */
00241 #define MODE_Column   1  /* One record per line in neat columns */
00242 #define MODE_List     2  /* One record per line with a separator */
00243 #define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */
00244 #define MODE_Html     4  /* Generate an XHTML table */
00245 #define MODE_Insert   5  /* Generate SQL "insert" statements */
00246 #define MODE_Tcl      6  /* Generate ANSI-C or TCL quoted elements */
00247 #define MODE_Csv      7  /* Quote strings, numbers are plain */
00248 #define MODE_NUM_OF   8  /* The number of modes (not a mode itself) */
00249 
00250 static const char *modeDescr[MODE_NUM_OF] = {
00251   "line",
00252   "column",
00253   "list",
00254   "semi",
00255   "html",
00256   "insert",
00257   "tcl",
00258   "csv",
00259 };
00260 
00261 /*
00262 ** Number of elements in an array
00263 */
00264 #define ArraySize(X)  (sizeof(X)/sizeof(X[0]))
00265 
00266 /*
00267 ** Output the given string as a quoted string using SQL quoting conventions.
00268 */
00269 static void output_quoted_string(FILE *out, const char *z){
00270   int i;
00271   int nSingle = 0;
00272   for(i=0; z[i]; i++){
00273     if( z[i]=='\'' ) nSingle++;
00274   }
00275   if( nSingle==0 ){
00276     fprintf(out,"'%s'",z);
00277   }else{
00278     fprintf(out,"'");
00279     while( *z ){
00280       for(i=0; z[i] && z[i]!='\''; i++){}
00281       if( i==0 ){
00282         fprintf(out,"''");
00283         z++;
00284       }else if( z[i]=='\'' ){
00285         fprintf(out,"%.*s''",i,z);
00286         z += i+1;
00287       }else{
00288         fprintf(out,"%s",z);
00289         break;
00290       }
00291     }
00292     fprintf(out,"'");
00293   }
00294 }
00295 
00296 /*
00297 ** Output the given string as a quoted according to C or TCL quoting rules.
00298 */
00299 static void output_c_string(FILE *out, const char *z){
00300   unsigned int c;
00301   fputc('"', out);
00302   while( (c = *(z++))!=0 ){
00303     if( c=='\\' ){
00304       fputc(c, out);
00305       fputc(c, out);
00306     }else if( c=='\t' ){
00307       fputc('\\', out);
00308       fputc('t', out);
00309     }else if( c=='\n' ){
00310       fputc('\\', out);
00311       fputc('n', out);
00312     }else if( c=='\r' ){
00313       fputc('\\', out);
00314       fputc('r', out);
00315     }else if( !isprint(c) ){
00316       fprintf(out, "\\%03o", c&0xff);
00317     }else{
00318       fputc(c, out);
00319     }
00320   }
00321   fputc('"', out);
00322 }
00323 
00324 /*
00325 ** Output the given string with characters that are special to
00326 ** HTML escaped.
00327 */
00328 static void output_html_string(FILE *out, const char *z){
00329   int i;
00330   while( *z ){
00331     for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
00332     if( i>0 ){
00333       fprintf(out,"%.*s",i,z);
00334     }
00335     if( z[i]=='<' ){
00336       fprintf(out,"&lt;");
00337     }else if( z[i]=='&' ){
00338       fprintf(out,"&amp;");
00339     }else{
00340       break;
00341     }
00342     z += i + 1;
00343   }
00344 }
00345 
00346 /*
00347 ** Output a single term of CSV.  Actually, p->separator is used for
00348 ** the separator, which may or may not be a comma.  p->nullvalue is
00349 ** the null value.  Strings are quoted using ANSI-C rules.  Numbers
00350 ** appear outside of quotes.
00351 */
00352 static void output_csv(struct callback_data *p, const char *z, int bSep){
00353   if( z==0 ){
00354     fprintf(p->out,"%s",p->nullvalue);
00355   }else if( isNumber(z, 0) ){
00356     fprintf(p->out,"%s",z);
00357   }else{
00358     output_c_string(p->out, z);
00359   }
00360   if( bSep ){
00361     fprintf(p->out, p->separator);
00362   }
00363 }
00364 
00365 #ifdef SIGINT
00366 /*
00367 ** This routine runs when the user presses Ctrl-C
00368 */
00369 static void interrupt_handler(int NotUsed){
00370   seenInterrupt = 1;
00371   if( db ) sqlite3_interrupt(db);
00372 }
00373 #endif
00374 
00375 /*
00376 ** This is the callback routine that the SQLite library
00377 ** invokes for each row of a query result.
00378 */
00379 static int callback(void *pArg, int nArg, char **azArg, char **azCol){
00380   int i;
00381   struct callback_data *p = (struct callback_data*)pArg;
00382   switch( p->mode ){
00383     case MODE_Line: {
00384       int w = 5;
00385       if( azArg==0 ) break;
00386       for(i=0; i<nArg; i++){
00387         int len = strlen(azCol[i]);
00388         if( len>w ) w = len;
00389       }
00390       if( p->cnt++>0 ) fprintf(p->out,"\n");
00391       for(i=0; i<nArg; i++){
00392         fprintf(p->out,"%*s = %s\n", w, azCol[i], 
00393                 azArg[i] ? azArg[i] : p->nullvalue);
00394       }
00395       break;
00396     }
00397     case MODE_Column: {
00398       if( p->cnt++==0 ){
00399         for(i=0; i<nArg; i++){
00400           int w, n;
00401           if( i<ArraySize(p->colWidth) ){
00402              w = p->colWidth[i];
00403           }else{
00404              w = 0;
00405           }
00406           if( w<=0 ){
00407             w = strlen(azCol[i] ? azCol[i] : "");
00408             if( w<10 ) w = 10;
00409             n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
00410             if( w<n ) w = n;
00411           }
00412           if( i<ArraySize(p->actualWidth) ){
00413             p->actualWidth[i] = w;
00414           }
00415           if( p->showHeader ){
00416             fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");
00417           }
00418         }
00419         if( p->showHeader ){
00420           for(i=0; i<nArg; i++){
00421             int w;
00422             if( i<ArraySize(p->actualWidth) ){
00423                w = p->actualWidth[i];
00424             }else{
00425                w = 10;
00426             }
00427             fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
00428                    "----------------------------------------------------------",
00429                     i==nArg-1 ? "\n": "  ");
00430           }
00431         }
00432       }
00433       if( azArg==0 ) break;
00434       for(i=0; i<nArg; i++){
00435         int w;
00436         if( i<ArraySize(p->actualWidth) ){
00437            w = p->actualWidth[i];
00438         }else{
00439            w = 10;
00440         }
00441         fprintf(p->out,"%-*.*s%s",w,w,
00442             azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
00443       }
00444       break;
00445     }
00446     case MODE_Semi:
00447     case MODE_List: {
00448       if( p->cnt++==0 && p->showHeader ){
00449         for(i=0; i<nArg; i++){
00450           fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
00451         }
00452       }
00453       if( azArg==0 ) break;
00454       for(i=0; i<nArg; i++){
00455         char *z = azArg[i];
00456         if( z==0 ) z = p->nullvalue;
00457         fprintf(p->out, "%s", z);
00458         if( i<nArg-1 ){
00459           fprintf(p->out, "%s", p->separator);
00460         }else if( p->mode==MODE_Semi ){
00461           fprintf(p->out, ";\n");
00462         }else{
00463           fprintf(p->out, "\n");
00464         }
00465       }
00466       break;
00467     }
00468     case MODE_Html: {
00469       if( p->cnt++==0 && p->showHeader ){
00470         fprintf(p->out,"<TR>");
00471         for(i=0; i<nArg; i++){
00472           fprintf(p->out,"<TH>%s</TH>",azCol[i]);
00473         }
00474         fprintf(p->out,"</TR>\n");
00475       }
00476       if( azArg==0 ) break;
00477       fprintf(p->out,"<TR>");
00478       for(i=0; i<nArg; i++){
00479         fprintf(p->out,"<TD>");
00480         output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
00481         fprintf(p->out,"</TD>\n");
00482       }
00483       fprintf(p->out,"</TR>\n");
00484       break;
00485     }
00486     case MODE_Tcl: {
00487       if( p->cnt++==0 && p->showHeader ){
00488         for(i=0; i<nArg; i++){
00489           output_c_string(p->out,azCol[i]);
00490           fprintf(p->out, "%s", p->separator);
00491         }
00492         fprintf(p->out,"\n");
00493       }
00494       if( azArg==0 ) break;
00495       for(i=0; i<nArg; i++){
00496         output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
00497         fprintf(p->out, "%s", p->separator);
00498       }
00499       fprintf(p->out,"\n");
00500       break;
00501     }
00502     case MODE_Csv: {
00503       if( p->cnt++==0 && p->showHeader ){
00504         for(i=0; i<nArg; i++){
00505           output_csv(p, azCol[i], i<nArg-1);
00506         }
00507         fprintf(p->out,"\n");
00508       }
00509       if( azArg==0 ) break;
00510       for(i=0; i<nArg; i++){
00511         output_csv(p, azArg[i], i<nArg-1);
00512       }
00513       fprintf(p->out,"\n");
00514       break;
00515     }
00516     case MODE_Insert: {
00517       if( azArg==0 ) break;
00518       fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
00519       for(i=0; i<nArg; i++){
00520         char *zSep = i>0 ? ",": "";
00521         if( azArg[i]==0 ){
00522           fprintf(p->out,"%sNULL",zSep);
00523         }else if( isNumber(azArg[i], 0) ){
00524           fprintf(p->out,"%s%s",zSep, azArg[i]);
00525         }else{
00526           if( zSep[0] ) fprintf(p->out,"%s",zSep);
00527           output_quoted_string(p->out, azArg[i]);
00528         }
00529       }
00530       fprintf(p->out,");\n");
00531       break;
00532     }
00533   }
00534   return 0;
00535 }
00536 
00537 /*
00538 ** Set the destination table field of the callback_data structure to
00539 ** the name of the table given.  Escape any quote characters in the
00540 ** table name.
00541 */
00542 static void set_table_name(struct callback_data *p, const char *zName){
00543   int i, n;
00544   int needQuote;
00545   char *z;
00546 
00547   if( p->zDestTable ){
00548     free(p->zDestTable);
00549     p->zDestTable = 0;
00550   }
00551   if( zName==0 ) return;
00552   needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
00553   for(i=n=0; zName[i]; i++, n++){
00554     if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
00555       needQuote = 1;
00556       if( zName[i]=='\'' ) n++;
00557     }
00558   }
00559   if( needQuote ) n += 2;
00560   z = p->zDestTable = malloc( n+1 );
00561   if( z==0 ){
00562     fprintf(stderr,"Out of memory!\n");
00563     exit(1);
00564   }
00565   n = 0;
00566   if( needQuote ) z[n++] = '\'';
00567   for(i=0; zName[i]; i++){
00568     z[n++] = zName[i];
00569     if( zName[i]=='\'' ) z[n++] = '\'';
00570   }
00571   if( needQuote ) z[n++] = '\'';
00572   z[n] = 0;
00573 }
00574 
00575 /* zIn is either a pointer to a NULL-terminated string in memory obtained
00576 ** from malloc(), or a NULL pointer. The string pointed to by zAppend is
00577 ** added to zIn, and the result returned in memory obtained from malloc().
00578 ** zIn, if it was not NULL, is freed.
00579 **
00580 ** If the third argument, quote, is not '\0', then it is used as a 
00581 ** quote character for zAppend.
00582 */
00583 static char * appendText(char *zIn, char const *zAppend, char quote){
00584   int len;
00585   int i;
00586   int nAppend = strlen(zAppend);
00587   int nIn = (zIn?strlen(zIn):0);
00588 
00589   len = nAppend+nIn+1;
00590   if( quote ){
00591     len += 2;
00592     for(i=0; i<nAppend; i++){
00593       if( zAppend[i]==quote ) len++;
00594     }
00595   }
00596 
00597   zIn = (char *)realloc(zIn, len);
00598   if( !zIn ){
00599     return 0;
00600   }
00601 
00602   if( quote ){
00603     char *zCsr = &zIn[nIn];
00604     *zCsr++ = quote;
00605     for(i=0; i<nAppend; i++){
00606       *zCsr++ = zAppend[i];
00607       if( zAppend[i]==quote ) *zCsr++ = quote;
00608     }
00609     *zCsr++ = quote;
00610     *zCsr++ = '\0';
00611     assert( (zCsr-zIn)==len );
00612   }else{
00613     memcpy(&zIn[nIn], zAppend, nAppend);
00614     zIn[len-1] = '\0';
00615   }
00616 
00617   return zIn;
00618 }
00619 
00620 
00621 /*
00622 ** Execute a query statement that has a single result column.  Print
00623 ** that result column on a line by itself with a semicolon terminator.
00624 */
00625 static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){
00626   sqlite3_stmt *pSelect;
00627   int rc;
00628   rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
00629   if( rc!=SQLITE_OK || !pSelect ){
00630     return rc;
00631   }
00632   rc = sqlite3_step(pSelect);
00633   while( rc==SQLITE_ROW ){
00634     fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
00635     rc = sqlite3_step(pSelect);
00636   }
00637   return sqlite3_finalize(pSelect);
00638 }
00639 
00640 
00641 /*
00642 ** This is a different callback routine used for dumping the database.
00643 ** Each row received by this callback consists of a table name,
00644 ** the table type ("index" or "table") and SQL to create the table.
00645 ** This routine should print text sufficient to recreate the table.
00646 */
00647 static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
00648   int rc;
00649   const char *zTable;
00650   const char *zType;
00651   const char *zSql;
00652   struct callback_data *p = (struct callback_data *)pArg;
00653 
00654   if( nArg!=3 ) return 1;
00655   zTable = azArg[0];
00656   zType = azArg[1];
00657   zSql = azArg[2];
00658   
00659   if( strcmp(zTable, "sqlite_sequence")==0 ){
00660     fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
00661   }else if( strcmp(zTable, "sqlite_stat1")==0 ){
00662     fprintf(p->out, "ANALYZE sqlite_master;\n");
00663   }else if( strncmp(zTable, "sqlite_", 7)==0 ){
00664     return 0;
00665   }else{
00666     fprintf(p->out, "%s;\n", zSql);
00667   }
00668 
00669   if( strcmp(zType, "table")==0 ){
00670     sqlite3_stmt *pTableInfo = 0;
00671     char *zSelect = 0;
00672     char *zTableInfo = 0;
00673     char *zTmp = 0;
00674    
00675     zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
00676     zTableInfo = appendText(zTableInfo, zTable, '"');
00677     zTableInfo = appendText(zTableInfo, ");", 0);
00678 
00679     rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
00680     if( zTableInfo ) free(zTableInfo);
00681     if( rc!=SQLITE_OK || !pTableInfo ){
00682       return 1;
00683     }
00684 
00685     zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
00686     zTmp = appendText(zTmp, zTable, '"');
00687     if( zTmp ){
00688       zSelect = appendText(zSelect, zTmp, '\'');
00689     }
00690     zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
00691     rc = sqlite3_step(pTableInfo);
00692     while( rc==SQLITE_ROW ){
00693       const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
00694       zSelect = appendText(zSelect, "quote(", 0);
00695       zSelect = appendText(zSelect, zText, '"');
00696       rc = sqlite3_step(pTableInfo);
00697       if( rc==SQLITE_ROW ){
00698         zSelect = appendText(zSelect, ") || ', ' || ", 0);
00699       }else{
00700         zSelect = appendText(zSelect, ") ", 0);
00701       }
00702     }
00703     rc = sqlite3_finalize(pTableInfo);
00704     if( rc!=SQLITE_OK ){
00705       if( zSelect ) free(zSelect);
00706       return 1;
00707     }
00708     zSelect = appendText(zSelect, "|| ')' FROM  ", 0);
00709     zSelect = appendText(zSelect, zTable, '"');
00710 
00711     rc = run_table_dump_query(p->out, p->db, zSelect);
00712     if( rc==SQLITE_CORRUPT ){
00713       zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
00714       rc = run_table_dump_query(p->out, p->db, zSelect);
00715     }
00716     if( zSelect ) free(zSelect);
00717     if( rc!=SQLITE_OK ){
00718       return 1;
00719     }
00720   }
00721   return 0;
00722 }
00723 
00724 /*
00725 ** Run zQuery.  Update dump_callback() as the callback routine.
00726 ** If we get a SQLITE_CORRUPT error, rerun the query after appending
00727 ** "ORDER BY rowid DESC" to the end.
00728 */
00729 static int run_schema_dump_query(
00730   struct callback_data *p, 
00731   const char *zQuery,
00732   char **pzErrMsg
00733 ){
00734   int rc;
00735   rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
00736   if( rc==SQLITE_CORRUPT ){
00737     char *zQ2;
00738     int len = strlen(zQuery);
00739     if( pzErrMsg ) sqlite3_free(*pzErrMsg);
00740     zQ2 = malloc( len+100 );
00741     if( zQ2==0 ) return rc;
00742     sprintf(zQ2, "%s ORDER BY rowid DESC", zQuery);
00743     rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
00744     free(zQ2);
00745   }
00746   return rc;
00747 }
00748 
00749 /*
00750 ** Text of a help message
00751 */
00752 static char zHelp[] =
00753   ".databases             List names and files of attached databases\n"
00754   ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
00755   ".echo ON|OFF           Turn command echo on or off\n"
00756   ".exit                  Exit this program\n"
00757   ".explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.\n"
00758   ".header(s) ON|OFF      Turn display of headers on or off\n"
00759   ".help                  Show this message\n"
00760   ".import FILE TABLE     Import data from FILE into TABLE\n"
00761   ".indices TABLE         Show names of all indices on TABLE\n"
00762   ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
00763   "                         csv      Comma-separated values\n"
00764   "                         column   Left-aligned columns.  (See .width)\n"
00765   "                         html     HTML <table> code\n"
00766   "                         insert   SQL insert statements for TABLE\n"
00767   "                         line     One value per line\n"
00768   "                         list     Values delimited by .separator string\n"
00769   "                         tabs     Tab-separated values\n"
00770   "                         tcl      TCL list elements\n"
00771   ".nullvalue STRING      Print STRING in place of NULL values\n"
00772   ".output FILENAME       Send output to FILENAME\n"
00773   ".output stdout         Send output to the screen\n"
00774   ".prompt MAIN CONTINUE  Replace the standard prompts\n"
00775   ".quit                  Exit this program\n"
00776   ".read FILENAME         Execute SQL in FILENAME\n"
00777   ".schema ?TABLE?        Show the CREATE statements\n"
00778   ".separator STRING      Change separator used by output mode and .import\n"
00779   ".show                  Show the current values for various settings\n"
00780   ".tables ?PATTERN?      List names of tables matching a LIKE pattern\n"
00781   ".timeout MS            Try opening locked tables for MS milliseconds\n"
00782   ".width NUM NUM ...     Set column widths for \"column\" mode\n"
00783 ;
00784 
00785 /* Forward reference */
00786 static void process_input(struct callback_data *p, FILE *in);
00787 
00788 /*
00789 ** Make sure the database is open.  If it is not, then open it.  If
00790 ** the database fails to open, print an error message and exit.
00791 */
00792 static void open_db(struct callback_data *p){
00793   if( p->db==0 ){
00794     sqlite3_open(p->zDbFilename, &p->db);
00795     db = p->db;
00796     sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
00797         shellstaticFunc, 0, 0);
00798     if( SQLITE_OK!=sqlite3_errcode(db) ){
00799       fprintf(stderr,"Unable to open database \"%s\": %s\n", 
00800           p->zDbFilename, sqlite3_errmsg(db));
00801       exit(1);
00802     }
00803   }
00804 }
00805 
00806 /*
00807 ** Do C-language style dequoting.
00808 **
00809 **    \t    -> tab
00810 **    \n    -> newline
00811 **    \r    -> carriage return
00812 **    \NNN  -> ascii character NNN in octal
00813 **    \\    -> backslash
00814 */
00815 static void resolve_backslashes(char *z){
00816   int i, j, c;
00817   for(i=j=0; (c = z[i])!=0; i++, j++){
00818     if( c=='\\' ){
00819       c = z[++i];
00820       if( c=='n' ){
00821         c = '\n';
00822       }else if( c=='t' ){
00823         c = '\t';
00824       }else if( c=='r' ){
00825         c = '\r';
00826       }else if( c>='0' && c<='7' ){
00827         c -= '0';
00828         if( z[i+1]>='0' && z[i+1]<='7' ){
00829           i++;
00830           c = (c<<3) + z[i] - '0';
00831           if( z[i+1]>='0' && z[i+1]<='7' ){
00832             i++;
00833             c = (c<<3) + z[i] - '0';
00834           }
00835         }
00836       }
00837     }
00838     z[j] = c;
00839   }
00840   z[j] = 0;
00841 }
00842 
00843 /*
00844 ** If an input line begins with "." then invoke this routine to
00845 ** process that line.
00846 **
00847 ** Return 1 to exit and 0 to continue.
00848 */
00849 static int do_meta_command(char *zLine, struct callback_data *p){
00850   int i = 1;
00851   int nArg = 0;
00852   int n, c;
00853   int rc = 0;
00854   char *azArg[50];
00855 
00856   /* Parse the input line into tokens.
00857   */
00858   while( zLine[i] && nArg<ArraySize(azArg) ){
00859     while( isspace((unsigned char)zLine[i]) ){ i++; }
00860     if( zLine[i]==0 ) break;
00861     if( zLine[i]=='\'' || zLine[i]=='"' ){
00862       int delim = zLine[i++];
00863       azArg[nArg++] = &zLine[i];
00864       while( zLine[i] && zLine[i]!=delim ){ i++; }
00865       if( zLine[i]==delim ){
00866         zLine[i++] = 0;
00867       }
00868       if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
00869     }else{
00870       azArg[nArg++] = &zLine[i];
00871       while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
00872       if( zLine[i] ) zLine[i++] = 0;
00873       resolve_backslashes(azArg[nArg-1]);
00874     }
00875   }
00876 
00877   /* Process the input line.
00878   */
00879   if( nArg==0 ) return rc;
00880   n = strlen(azArg[0]);
00881   c = azArg[0][0];
00882   if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
00883     struct callback_data data;
00884     char *zErrMsg = 0;
00885     open_db(p);
00886     memcpy(&data, p, sizeof(data));
00887     data.showHeader = 1;
00888     data.mode = MODE_Column;
00889     data.colWidth[0] = 3;
00890     data.colWidth[1] = 15;
00891     data.colWidth[2] = 58;
00892     data.cnt = 0;
00893     sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
00894     if( zErrMsg ){
00895       fprintf(stderr,"Error: %s\n", zErrMsg);
00896       sqlite3_free(zErrMsg);
00897     }
00898   }else
00899 
00900   if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
00901     char *zErrMsg = 0;
00902     open_db(p);
00903     fprintf(p->out, "BEGIN TRANSACTION;\n");
00904     if( nArg==1 ){
00905       run_schema_dump_query(p, 
00906         "SELECT name, type, sql FROM sqlite_master "
00907         "WHERE sql NOT NULL AND type=='table'", 0
00908       );
00909       run_schema_dump_query(p, 
00910         "SELECT name, type, sql FROM sqlite_master "
00911         "WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0
00912       );
00913     }else{
00914       int i;
00915       for(i=1; i<nArg; i++){
00916         zShellStatic = azArg[i];
00917         run_schema_dump_query(p,
00918           "SELECT name, type, sql FROM sqlite_master "
00919           "WHERE tbl_name LIKE shellstatic() AND type=='table'"
00920           "  AND sql NOT NULL", 0);
00921         run_schema_dump_query(p,
00922           "SELECT name, type, sql FROM sqlite_master "
00923           "WHERE tbl_name LIKE shellstatic() AND type!='table'"
00924           "  AND type!='meta' AND sql NOT NULL", 0);
00925         zShellStatic = 0;
00926       }
00927     }
00928     if( zErrMsg ){
00929       fprintf(stderr,"Error: %s\n", zErrMsg);
00930       sqlite3_free(zErrMsg);
00931     }else{
00932       fprintf(p->out, "COMMIT;\n");
00933     }
00934   }else
00935 
00936   if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
00937     int j;
00938     char *z = azArg[1];
00939     int val = atoi(azArg[1]);
00940     for(j=0; z[j]; j++){
00941       z[j] = tolower((unsigned char)z[j]);
00942     }
00943     if( strcmp(z,"on")==0 ){
00944       val = 1;
00945     }else if( strcmp(z,"yes")==0 ){
00946       val = 1;
00947     }
00948     p->echoOn = val;
00949   }else
00950 
00951   if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
00952     rc = 1;
00953   }else
00954 
00955   if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
00956     int j;
00957     static char zOne[] = "1";
00958     char *z = nArg>=2 ? azArg[1] : zOne;
00959     int val = atoi(z);
00960     for(j=0; z[j]; j++){
00961       z[j] = tolower((unsigned char)z[j]);
00962     }
00963     if( strcmp(z,"on")==0 ){
00964       val = 1;
00965     }else if( strcmp(z,"yes")==0 ){
00966       val = 1;
00967     }
00968     if(val == 1) {
00969       if(!p->explainPrev.valid) {
00970         p->explainPrev.valid = 1;
00971         p->explainPrev.mode = p->mode;
00972         p->explainPrev.showHeader = p->showHeader;
00973         memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
00974       }
00975       /* We could put this code under the !p->explainValid
00976       ** condition so that it does not execute if we are already in
00977       ** explain mode. However, always executing it allows us an easy
00978       ** was to reset to explain mode in case the user previously
00979       ** did an .explain followed by a .width, .mode or .header
00980       ** command.
00981       */
00982       p->mode = MODE_Column;
00983       p->showHeader = 1;
00984       memset(p->colWidth,0,ArraySize(p->colWidth));
00985       p->colWidth[0] = 4;
00986       p->colWidth[1] = 14;
00987       p->colWidth[2] = 10;
00988       p->colWidth[3] = 10;
00989       p->colWidth[4] = 33;
00990     }else if (p->explainPrev.valid) {
00991       p->explainPrev.valid = 0;
00992       p->mode = p->explainPrev.mode;
00993       p->showHeader = p->explainPrev.showHeader;
00994       memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
00995     }
00996   }else
00997 
00998   if( c=='h' && (strncmp(azArg[0], "header", n)==0
00999                  ||
01000                  strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
01001     int j;
01002     char *z = azArg[1];
01003     int val = atoi(azArg[1]);
01004     for(j=0; z[j]; j++){
01005       z[j] = tolower((unsigned char)z[j]);
01006     }
01007     if( strcmp(z,"on")==0 ){
01008       val = 1;
01009     }else if( strcmp(z,"yes")==0 ){
01010       val = 1;
01011     }
01012     p->showHeader = val;
01013   }else
01014 
01015   if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
01016     fprintf(stderr,zHelp);
01017   }else
01018 
01019   if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){
01020     char *zTable = azArg[2];    /* Insert data into this table */
01021     char *zFile = azArg[1];     /* The file from which to extract data */
01022     sqlite3_stmt *pStmt;        /* A statement */
01023     int rc;                     /* Result code */
01024     int nCol;                   /* Number of columns in the table */
01025     int nByte;                  /* Number of bytes in an SQL string */
01026     int i, j;                   /* Loop counters */
01027     int nSep;                   /* Number of bytes in p->separator[] */
01028     char *zSql;                 /* An SQL statement */
01029     char *zLine;                /* A single line of input from the file */
01030     char **azCol;               /* zLine[] broken up into columns */
01031     char *zCommit;              /* How to commit changes */   
01032     FILE *in;                   /* The input file */
01033     int lineno = 0;             /* Line number of input file */
01034 
01035     nSep = strlen(p->separator);
01036     if( nSep==0 ){
01037       fprintf(stderr, "non-null separator required for import\n");
01038       return 0;
01039     }
01040     zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
01041     if( zSql==0 ) return 0;
01042     nByte = strlen(zSql);
01043     rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
01044     sqlite3_free(zSql);
01045     if( rc ){
01046       fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
01047       nCol = 0;
01048     }else{
01049       nCol = sqlite3_column_count(pStmt);
01050     }
01051     sqlite3_finalize(pStmt);
01052     if( nCol==0 ) return 0;
01053     zSql = malloc( nByte + 20 + nCol*2 );
01054     if( zSql==0 ) return 0;
01055     sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
01056     j = strlen(zSql);
01057     for(i=1; i<nCol; i++){
01058       zSql[j++] = ',';
01059       zSql[j++] = '?';
01060     }
01061     zSql[j++] = ')';
01062     zSql[j] = 0;
01063     rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
01064     free(zSql);
01065     if( rc ){
01066       fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
01067       sqlite3_finalize(pStmt);
01068       return 0;
01069     }
01070     in = fopen(zFile, "rb");
01071     if( in==0 ){
01072       fprintf(stderr, "cannot open file: %s\n", zFile);
01073       sqlite3_finalize(pStmt);
01074       return 0;
01075     }
01076     azCol = malloc( sizeof(azCol[0])*(nCol+1) );
01077     if( azCol==0 ){
01078       fclose(in);
01079       return 0;
01080     }
01081     sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
01082     zCommit = "COMMIT";
01083     while( (zLine = local_getline(0, in))!=0 ){
01084       char *z;
01085       i = 0;
01086       lineno++;
01087       azCol[0] = zLine;
01088       for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
01089         if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
01090           *z = 0;
01091           i++;
01092           if( i<nCol ){
01093             azCol[i] = &z[nSep];
01094             z += nSep-1;
01095           }
01096         }
01097       }
01098       *z = 0;
01099       if( i+1!=nCol ){
01100         fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
01101            zFile, lineno, nCol, i+1);
01102         zCommit = "ROLLBACK";
01103         break;
01104       }
01105       for(i=0; i<nCol; i++){
01106         sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
01107       }
01108       sqlite3_step(pStmt);
01109       rc = sqlite3_reset(pStmt);
01110       free(zLine);
01111       if( rc!=SQLITE_OK ){
01112         fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
01113         zCommit = "ROLLBACK";
01114         break;
01115       }
01116     }
01117     free(azCol);
01118     fclose(in);
01119     sqlite3_finalize(pStmt);
01120     sqlite3_exec(p->db, zCommit, 0, 0, 0);
01121   }else
01122 
01123   if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
01124     struct callback_data data;
01125     char *zErrMsg = 0;
01126     open_db(p);
01127     memcpy(&data, p, sizeof(data));
01128     data.showHeader = 0;
01129     data.mode = MODE_List;
01130     zShellStatic = azArg[1];
01131     sqlite3_exec(p->db,
01132       "SELECT name FROM sqlite_master "
01133       "WHERE type='index' AND tbl_name LIKE shellstatic() "
01134       "UNION ALL "
01135       "SELECT name FROM sqlite_temp_master "
01136       "WHERE type='index' AND tbl_name LIKE shellstatic() "
01137       "ORDER BY 1",
01138       callback, &data, &zErrMsg
01139     );
01140     zShellStatic = 0;
01141     if( zErrMsg ){
01142       fprintf(stderr,"Error: %s\n", zErrMsg);
01143       sqlite3_free(zErrMsg);
01144     }
01145   }else
01146 
01147   if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
01148     int n2 = strlen(azArg[1]);
01149     if( strncmp(azArg[1],"line",n2)==0
01150         ||
01151         strncmp(azArg[1],"lines",n2)==0 ){
01152       p->mode = MODE_Line;
01153     }else if( strncmp(azArg[1],"column",n2)==0
01154               ||
01155               strncmp(azArg[1],"columns",n2)==0 ){
01156       p->mode = MODE_Column;
01157     }else if( strncmp(azArg[1],"list",n2)==0 ){
01158       p->mode = MODE_List;
01159     }else if( strncmp(azArg[1],"html",n2)==0 ){
01160       p->mode = MODE_Html;
01161     }else if( strncmp(azArg[1],"tcl",n2)==0 ){
01162       p->mode = MODE_Tcl;
01163     }else if( strncmp(azArg[1],"csv",n2)==0 ){
01164       p->mode = MODE_Csv;
01165       strcpy(p->separator, ",");
01166     }else if( strncmp(azArg[1],"tabs",n2)==0 ){
01167       p->mode = MODE_List;
01168       strcpy(p->separator, "\t");
01169     }else if( strncmp(azArg[1],"insert",n2)==0 ){
01170       p->mode = MODE_Insert;
01171       if( nArg>=3 ){
01172         set_table_name(p, azArg[2]);
01173       }else{
01174         set_table_name(p, "table");
01175       }
01176     }else {
01177       fprintf(stderr,"mode should be on of: "
01178          "column csv html insert line list tabs tcl\n");
01179     }
01180   }else
01181 
01182   if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
01183     sprintf(p->nullvalue, "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
01184   }else
01185 
01186   if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
01187     if( p->out!=stdout ){
01188       fclose(p->out);
01189     }
01190     if( strcmp(azArg[1],"stdout")==0 ){
01191       p->out = stdout;
01192       strcpy(p->outfile,"stdout");
01193     }else{
01194       p->out = fopen(azArg[1], "wb");
01195       if( p->out==0 ){
01196         fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
01197         p->out = stdout;
01198       } else {
01199          strcpy(p->outfile,azArg[1]);
01200       }
01201     }
01202   }else
01203 
01204   if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
01205     if( nArg >= 2) {
01206       strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
01207     }
01208     if( nArg >= 3) {
01209       strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
01210     }
01211   }else
01212 
01213   if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
01214     rc = 1;
01215   }else
01216 
01217   if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
01218     FILE *alt = fopen(azArg[1], "rb");
01219     if( alt==0 ){
01220       fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
01221     }else{
01222       process_input(p, alt);
01223       fclose(alt);
01224     }
01225   }else
01226 
01227   if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
01228     struct callback_data data;
01229     char *zErrMsg = 0;
01230     open_db(p);
01231     memcpy(&data, p, sizeof(data));
01232     data.showHeader = 0;
01233     data.mode = MODE_Semi;
01234     if( nArg>1 ){
01235       int i;
01236       for(i=0; azArg[1][i]; i++) azArg[1][i] = tolower(azArg[1][i]);
01237       if( strcmp(azArg[1],"sqlite_master")==0 ){
01238         char *new_argv[2], *new_colv[2];
01239         new_argv[0] = "CREATE TABLE sqlite_master (\n"
01240                       "  type text,\n"
01241                       "  name text,\n"
01242                       "  tbl_name text,\n"
01243                       "  rootpage integer,\n"
01244                       "  sql text\n"
01245                       ")";
01246         new_argv[1] = 0;
01247         new_colv[0] = "sql";
01248         new_colv[1] = 0;
01249         callback(&data, 1, new_argv, new_colv);
01250       }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
01251         char *new_argv[2], *new_colv[2];
01252         new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
01253                       "  type text,\n"
01254                       "  name text,\n"
01255                       "  tbl_name text,\n"
01256                       "  rootpage integer,\n"
01257                       "  sql text\n"
01258                       ")";
01259         new_argv[1] = 0;
01260         new_colv[0] = "sql";
01261         new_colv[1] = 0;
01262         callback(&data, 1, new_argv, new_colv);
01263       }else{
01264         zShellStatic = azArg[1];
01265         sqlite3_exec(p->db,
01266           "SELECT sql FROM "
01267           "  (SELECT * FROM sqlite_master UNION ALL"
01268           "   SELECT * FROM sqlite_temp_master) "
01269           "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
01270           "ORDER BY substr(type,2,1), name",
01271           callback, &data, &zErrMsg);
01272         zShellStatic = 0;
01273       }
01274     }else{
01275       sqlite3_exec(p->db,
01276          "SELECT sql FROM "
01277          "  (SELECT * FROM sqlite_master UNION ALL"
01278          "   SELECT * FROM sqlite_temp_master) "
01279          "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
01280          "ORDER BY substr(type,2,1), name",
01281          callback, &data, &zErrMsg
01282       );
01283     }
01284     if( zErrMsg ){
01285       fprintf(stderr,"Error: %s\n", zErrMsg);
01286       sqlite3_free(zErrMsg);
01287     }
01288   }else
01289 
01290   if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
01291     sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]);
01292   }else
01293 
01294   if( c=='s' && strncmp(azArg[0], "show", n)==0){
01295     int i;
01296     fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
01297     fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
01298     fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
01299     fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
01300     fprintf(p->out,"%9.9s: ", "nullvalue");
01301       output_c_string(p->out, p->nullvalue);
01302       fprintf(p->out, "\n");
01303     fprintf(p->out,"%9.9s: %s\n","output",
01304                                  strlen(p->outfile) ? p->outfile : "stdout");
01305     fprintf(p->out,"%9.9s: ", "separator");
01306       output_c_string(p->out, p->separator);
01307       fprintf(p->out, "\n");
01308     fprintf(p->out,"%9.9s: ","width");
01309     for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
01310       fprintf(p->out,"%d ",p->colWidth[i]);
01311     }
01312     fprintf(p->out,"\n");
01313   }else
01314 
01315   if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
01316     char **azResult;
01317     int nRow, rc;
01318     char *zErrMsg;
01319     open_db(p);
01320     if( nArg==1 ){
01321       rc = sqlite3_get_table(p->db,
01322         "SELECT name FROM sqlite_master "
01323         "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
01324         "UNION ALL "
01325         "SELECT name FROM sqlite_temp_master "
01326         "WHERE type IN ('table','view') "
01327         "ORDER BY 1",
01328         &azResult, &nRow, 0, &zErrMsg
01329       );
01330     }else{
01331       zShellStatic = azArg[1];
01332       rc = sqlite3_get_table(p->db,
01333         "SELECT name FROM sqlite_master "
01334         "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
01335         "UNION ALL "
01336         "SELECT name FROM sqlite_temp_master "
01337         "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
01338         "ORDER BY 1",
01339         &azResult, &nRow, 0, &zErrMsg
01340       );
01341       zShellStatic = 0;
01342     }
01343     if( zErrMsg ){
01344       fprintf(stderr,"Error: %s\n", zErrMsg);
01345       sqlite3_free(zErrMsg);
01346     }
01347     if( rc==SQLITE_OK ){
01348       int len, maxlen = 0;
01349       int i, j;
01350       int nPrintCol, nPrintRow;
01351       for(i=1; i<=nRow; i++){
01352         if( azResult[i]==0 ) continue;
01353         len = strlen(azResult[i]);
01354         if( len>maxlen ) maxlen = len;
01355       }
01356       nPrintCol = 80/(maxlen+2);
01357       if( nPrintCol<1 ) nPrintCol = 1;
01358       nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
01359       for(i=0; i<nPrintRow; i++){
01360         for(j=i+1; j<=nRow; j+=nPrintRow){
01361           char *zSp = j<=nPrintRow ? "" : "  ";
01362           printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
01363         }
01364         printf("\n");
01365       }
01366     }
01367     sqlite3_free_table(azResult);
01368   }else
01369 
01370   if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
01371     open_db(p);
01372     sqlite3_busy_timeout(p->db, atoi(azArg[1]));
01373   }else
01374 
01375   if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
01376     int j;
01377     assert( nArg<=ArraySize(azArg) );
01378     for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
01379       p->colWidth[j-1] = atoi(azArg[j]);
01380     }
01381   }else
01382 
01383   {
01384     fprintf(stderr, "unknown command or invalid arguments: "
01385       " \"%s\". Enter \".help\" for help\n", azArg[0]);
01386   }
01387 
01388   return rc;
01389 }
01390 
01391 /*
01392 ** Return TRUE if the last non-whitespace character in z[] is a semicolon.
01393 ** z[] is N characters long.
01394 */
01395 static int _ends_with_semicolon(const char *z, int N){
01396   while( N>0 && isspace((unsigned char)z[N-1]) ){ N--; }
01397   return N>0 && z[N-1]==';';
01398 }
01399 
01400 /*
01401 ** Test to see if a line consists entirely of whitespace.
01402 */
01403 static int _all_whitespace(const char *z){
01404   for(; *z; z++){
01405     if( isspace(*(unsigned char*)z) ) continue;
01406     if( *z=='/' && z[1]=='*' ){
01407       z += 2;
01408       while( *z && (*z!='*' || z[1]!='/') ){ z++; }
01409       if( *z==0 ) return 0;
01410       z++;
01411       continue;
01412     }
01413     if( *z=='-' && z[1]=='-' ){
01414       z += 2;
01415       while( *z && *z!='\n' ){ z++; }
01416       if( *z==0 ) return 1;
01417       continue;
01418     }
01419     return 0;
01420   }
01421   return 1;
01422 }
01423 
01424 /*
01425 ** Return TRUE if the line typed in is an SQL command terminator other
01426 ** than a semi-colon.  The SQL Server style "go" command is understood
01427 ** as is the Oracle "/".
01428 */
01429 static int _is_command_terminator(const char *zLine){
01430   while( isspace(*(unsigned char*)zLine) ){ zLine++; };
01431   if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1;  /* Oracle */
01432   if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
01433          && _all_whitespace(&zLine[2]) ){
01434     return 1;  /* SQL Server */
01435   }
01436   return 0;
01437 }
01438 
01439 /*
01440 ** Read input from *in and process it.  If *in==0 then input
01441 ** is interactive - the user is typing it it.  Otherwise, input
01442 ** is coming from a file or device.  A prompt is issued and history
01443 ** is saved only if input is interactive.  An interrupt signal will
01444 ** cause this routine to exit immediately, unless input is interactive.
01445 */
01446 static void process_input(struct callback_data *p, FILE *in){
01447   char *zLine;
01448   char *zSql = 0;
01449   int nSql = 0;
01450   char *zErrMsg;
01451   int rc;
01452   while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){
01453     if( seenInterrupt ){
01454       if( in!=0 ) break;
01455       seenInterrupt = 0;
01456     }
01457     if( p->echoOn ) printf("%s\n", zLine);
01458     if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
01459     if( zLine && zLine[0]=='.' && nSql==0 ){
01460       int rc = do_meta_command(zLine, p);
01461       free(zLine);
01462       if( rc ) break;
01463       continue;
01464     }
01465     if( _is_command_terminator(zLine) ){
01466       strcpy(zLine,";");
01467     }
01468     if( zSql==0 ){
01469       int i;
01470       for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
01471       if( zLine[i]!=0 ){
01472         nSql = strlen(zLine);
01473         zSql = malloc( nSql+1 );
01474         if( zSql==0 ){
01475           fprintf(stderr, "out of memory\n");
01476           exit(1);
01477         }
01478         strcpy(zSql, zLine);
01479       }
01480     }else{
01481       int len = strlen(zLine);
01482       zSql = realloc( zSql, nSql + len + 2 );
01483       if( zSql==0 ){
01484         fprintf(stderr,"%s: out of memory!\n", Argv0);
01485         exit(1);
01486       }
01487       strcpy(&zSql[nSql++], "\n");
01488       strcpy(&zSql[nSql], zLine);
01489       nSql += len;
01490     }
01491     free(zLine);
01492     if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite3_complete(zSql) ){
01493       p->cnt = 0;
01494       open_db(p);
01495       rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg);
01496       if( rc || zErrMsg ){
01497         /* if( in!=0 && !p->echoOn ) printf("%s\n",zSql); */
01498         if( zErrMsg!=0 ){
01499           printf("SQL error: %s\n", zErrMsg);
01500           sqlite3_free(zErrMsg);
01501           zErrMsg = 0;
01502         }else{
01503           printf("SQL error: %s\n", sqlite3_errmsg(p->db));
01504         }
01505       }
01506       free(zSql);
01507       zSql = 0;
01508       nSql = 0;
01509     }
01510   }
01511   if( zSql ){
01512     if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
01513     free(zSql);
01514   }
01515 }
01516 
01517 /*
01518 ** Return a pathname which is the user's home directory.  A
01519 ** 0 return indicates an error of some kind.  Space to hold the
01520 ** resulting string is obtained from malloc().  The calling
01521 ** function should free the result.
01522 */
01523 static char *find_home_dir(void){
01524   char *home_dir = NULL;
01525 
01526 #if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
01527   struct passwd *pwent;
01528   uid_t uid = getuid();
01529   if( (pwent=getpwuid(uid)) != NULL) {
01530     home_dir = pwent->pw_dir;
01531   }
01532 #endif
01533 
01534 #ifdef __MACOS__
01535   char home_path[_MAX_PATH+1];
01536   home_dir = getcwd(home_path, _MAX_PATH);
01537 #endif
01538 
01539   if (!home_dir) {
01540     home_dir = getenv("HOME");
01541     if (!home_dir) {
01542       home_dir = getenv("HOMEPATH"); /* Windows? */
01543     }
01544   }
01545 
01546 #if defined(_WIN32) || defined(WIN32)
01547   if (!home_dir) {
01548     home_dir = "c:";
01549   }
01550 #endif
01551 
01552   if( home_dir ){
01553     char *z = malloc( strlen(home_dir)+1 );
01554     if( z ) strcpy(z, home_dir);
01555     home_dir = z;
01556   }
01557 
01558   return home_dir;
01559 }
01560 
01561 /*
01562 ** Read input from the file given by sqliterc_override.  Or if that
01563 ** parameter is NULL, take input from ~/.sqliterc
01564 */
01565 static void process_sqliterc(
01566   struct callback_data *p,        /* Configuration data */
01567   const char *sqliterc_override   /* Name of config file. NULL to use default */
01568 ){
01569   char *home_dir = NULL;
01570   const char *sqliterc = sqliterc_override;
01571   char *zBuf = 0;
01572   FILE *in = NULL;
01573 
01574   if (sqliterc == NULL) {
01575     home_dir = find_home_dir();
01576     if( home_dir==0 ){
01577       fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
01578       return;
01579     }
01580     zBuf = malloc(strlen(home_dir) + 15);
01581     if( zBuf==0 ){
01582       fprintf(stderr,"%s: out of memory!\n", Argv0);
01583       exit(1);
01584     }
01585     sprintf(zBuf,"%s/.sqliterc",home_dir);
01586     free(home_dir);
01587     sqliterc = (const char*)zBuf;
01588   }
01589   in = fopen(sqliterc,"rb");
01590   if( in ){
01591     if( isatty(fileno(stdout)) ){
01592       printf("Loading resources from %s\n",sqliterc);
01593     }
01594     process_input(p,in);
01595     fclose(in);
01596   }
01597   free(zBuf);
01598   return;
01599 }
01600 
01601 /*
01602 ** Show available command line options
01603 */
01604 static const char zOptions[] = 
01605   "   -init filename       read/process named file\n"
01606   "   -echo                print commands before execution\n"
01607   "   -[no]header          turn headers on or off\n"
01608   "   -column              set output mode to 'column'\n"
01609   "   -html                set output mode to HTML\n"
01610   "   -line                set output mode to 'line'\n"
01611   "   -list                set output mode to 'list'\n"
01612   "   -separator 'x'       set output field separator (|)\n"
01613   "   -nullvalue 'text'    set text string for NULL values\n"
01614   "   -version             show SQLite version\n"
01615   "   -help                show this text, also show dot-commands\n"
01616 ;
01617 static void usage(int showDetail){
01618   fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0);
01619   if( showDetail ){
01620     fprintf(stderr, "Options are:\n%s", zOptions);
01621   }else{
01622     fprintf(stderr, "Use the -help option for additional information\n");
01623   }
01624   exit(1);
01625 }
01626 
01627 /*
01628 ** Initialize the state information in data
01629 */
01630 static void main_init(struct callback_data *data) {
01631   memset(data, 0, sizeof(*data));
01632   data->mode = MODE_List;
01633   strcpy(data->separator,"|");
01634   data->showHeader = 0;
01635   strcpy(mainPrompt,"sqlite> ");
01636   strcpy(continuePrompt,"   ...> ");
01637 }
01638 
01639 int main(int argc, char **argv){
01640   char *zErrMsg = 0;
01641   struct callback_data data;
01642   const char *zInitFile = 0;
01643   char *zFirstCmd = 0;
01644   int i;
01645 
01646 #ifdef __MACOS__
01647   argc = ccommand(&argv);
01648 #endif
01649 
01650   Argv0 = argv[0];
01651   main_init(&data);
01652 
01653   /* Make sure we have a valid signal handler early, before anything
01654   ** else is done.
01655   */
01656 #ifdef SIGINT
01657   signal(SIGINT, interrupt_handler);
01658 #endif
01659 
01660   /* Do an initial pass through the command-line argument to locate
01661   ** the name of the database file, the name of the initialization file,
01662   ** and the first command to execute.
01663   */
01664   for(i=1; i<argc-1; i++){
01665     if( argv[i][0]!='-' ) break;
01666     if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
01667       i++;
01668     }else if( strcmp(argv[i],"-init")==0 ){
01669       i++;
01670       zInitFile = argv[i];
01671     }else if( strcmp(argv[i],"-key")==0 ){
01672       i++;
01673       data.zKey = sqlite3_mprintf("%s",argv[i]);
01674     }
01675   }
01676   if( i<argc ){
01677     data.zDbFilename = argv[i++];
01678   }else{
01679 #ifndef SQLITE_OMIT_MEMORYDB
01680     data.zDbFilename = ":memory:";
01681 #else
01682     data.zDbFilename = 0;
01683 #endif
01684   }
01685   if( i<argc ){
01686     zFirstCmd = argv[i++];
01687   }
01688   data.out = stdout;
01689 
01690 #ifdef SQLITE_OMIT_MEMORYDB
01691   if( data.zDbFilename==0 ){
01692     fprintf(stderr,"%s: no database filename specified\n", argv[0]);
01693     exit(1);
01694   }
01695 #endif
01696 
01697   /* Go ahead and open the database file if it already exists.  If the
01698   ** file does not exist, delay opening it.  This prevents empty database
01699   ** files from being created if a user mistypes the database name argument
01700   ** to the sqlite command-line tool.
01701   */
01702   if( access(data.zDbFilename, 0)==0 ){
01703     open_db(&data);
01704   }
01705 
01706   /* Process the initialization file if there is one.  If no -init option
01707   ** is given on the command line, look for a file named ~/.sqliterc and
01708   ** try to process it.
01709   */
01710   process_sqliterc(&data,zInitFile);
01711 
01712   /* Make a second pass through the command-line argument and set
01713   ** options.  This second pass is delayed until after the initialization
01714   ** file is processed so that the command-line arguments will override
01715   ** settings in the initialization file.
01716   */
01717   for(i=1; i<argc && argv[i][0]=='-'; i++){
01718     char *z = argv[i];
01719     if( strcmp(z,"-init")==0 || strcmp(z,"-key")==0 ){
01720       i++;
01721     }else if( strcmp(z,"-html")==0 ){
01722       data.mode = MODE_Html;
01723     }else if( strcmp(z,"-list")==0 ){
01724       data.mode = MODE_List;
01725     }else if( strcmp(z,"-line")==0 ){
01726       data.mode = MODE_Line;
01727     }else if( strcmp(z,"-column")==0 ){
01728       data.mode = MODE_Column;
01729     }else if( strcmp(z,"-separator")==0 ){
01730       i++;
01731       sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]);
01732     }else if( strcmp(z,"-nullvalue")==0 ){
01733       i++;
01734       sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
01735     }else if( strcmp(z,"-header")==0 ){
01736       data.showHeader = 1;
01737     }else if( strcmp(z,"-noheader")==0 ){
01738       data.showHeader = 0;
01739     }else if( strcmp(z,"-echo")==0 ){
01740       data.echoOn = 1;
01741     }else if( strcmp(z,"-version")==0 ){
01742       printf("%s\n", sqlite3_libversion());
01743       return 1;
01744     }else if( strcmp(z,"-help")==0 ){
01745       usage(1);
01746     }else{
01747       fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
01748       fprintf(stderr,"Use -help for a list of options.\n");
01749       return 1;
01750     }
01751   }
01752 
01753   if( zFirstCmd ){
01754     /* Run just the command that follows the database name
01755     */
01756     if( zFirstCmd[0]=='.' ){
01757       do_meta_command(zFirstCmd, &data);
01758       exit(0);
01759     }else{
01760       int rc;
01761       open_db(&data);
01762       rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
01763       if( rc!=0 && zErrMsg!=0 ){
01764         fprintf(stderr,"SQL error: %s\n", zErrMsg);
01765         exit(1);
01766       }
01767     }
01768   }else{
01769     /* Run commands received from standard input
01770     */
01771     if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){
01772       char *zHome;
01773       char *zHistory = 0;
01774       printf(
01775         "SQLite version %s\n"
01776         "Enter \".help\" for instructions\n",
01777         sqlite3_libversion()
01778       );
01779       zHome = find_home_dir();
01780       if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){
01781         sprintf(zHistory,"%s/.sqlite_history", zHome);
01782       }
01783 #if defined(HAVE_READLINE) && HAVE_READLINE==1
01784       if( zHistory ) read_history(zHistory);
01785 #endif
01786       process_input(&data, 0);
01787       if( zHistory ){
01788         stifle_history(100);
01789         write_history(zHistory);
01790       }
01791     }else{
01792       process_input(&data, stdin);
01793     }
01794   }
01795   set_table_name(&data, 0);
01796   if( db ) sqlite3_close(db);
01797   return 0;
01798 }