[BACK]Return to shell.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / sqlite3

Diff for /src/usr.bin/sqlite3/Attic/shell.c between version 1.1.1.8 and 1.1.1.9

version 1.1.1.8, 2014/03/24 01:45:06 version 1.1.1.9, 2014/09/29 22:58:46
Line 64 
Line 64 
   
 #if defined(_WIN32) || defined(WIN32)  #if defined(_WIN32) || defined(WIN32)
 # include <io.h>  # include <io.h>
   # include <fcntl.h>
 #define isatty(h) _isatty(h)  #define isatty(h) _isatty(h)
 #ifndef access  #ifndef access
 # define access(f,m) _access((f),(m))  # define access(f,m) _access((f),(m))
Line 446 
Line 447 
 struct callback_data {  struct callback_data {
   sqlite3 *db;           /* The database */    sqlite3 *db;           /* The database */
   int echoOn;            /* True to echo input commands */    int echoOn;            /* True to echo input commands */
   int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL statement */    int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
   int statsOn;           /* True to display memory stats before each finalize */    int statsOn;           /* True to display memory stats before each finalize */
     int outCount;          /* Revert to stdout when reaching zero */
   int cnt;               /* Number of records displayed so far */    int cnt;               /* Number of records displayed so far */
   FILE *out;             /* Write results here */    FILE *out;             /* Write results here */
   FILE *traceOut;        /* Output for sqlite3_trace() */    FILE *traceOut;        /* Output for sqlite3_trace() */
Line 457 
Line 459 
   int showHeader;        /* True to show column names in List or Column mode */    int showHeader;        /* True to show column names in List or Column mode */
   char *zDestTable;      /* Name of destination table when MODE_Insert */    char *zDestTable;      /* Name of destination table when MODE_Insert */
   char separator[20];    /* Separator character for MODE_List */    char separator[20];    /* Separator character for MODE_List */
     char newline[20];      /* Record separator in MODE_Csv */
   int colWidth[100];     /* Requested width of each column when in column mode*/    int colWidth[100];     /* Requested width of each column when in column mode*/
   int actualWidth[100];  /* Actual width of each column */    int actualWidth[100];  /* Actual width of each column */
   char nullvalue[20];    /* The text to print when a NULL comes back from    char nullvalue[20];    /* The text to print when a NULL comes back from
Line 658 
Line 661 
 /*  /*
 ** Output a single term of CSV.  Actually, p->separator is used for  ** Output a single term of CSV.  Actually, p->separator is used for
 ** the separator, which may or may not be a comma.  p->nullvalue is  ** the separator, which may or may not be a comma.  p->nullvalue is
 ** the null value.  Strings are quoted if necessary.  ** the null value.  Strings are quoted if necessary.  The separator
   ** is only issued if bSep is true.
 */  */
 static void output_csv(struct callback_data *p, const char *z, int bSep){  static void output_csv(struct callback_data *p, const char *z, int bSep){
   FILE *out = p->out;    FILE *out = p->out;
Line 697 
Line 701 
 */  */
 static void interrupt_handler(int NotUsed){  static void interrupt_handler(int NotUsed){
   UNUSED_PARAMETER(NotUsed);    UNUSED_PARAMETER(NotUsed);
   seenInterrupt = 1;    seenInterrupt++;
     if( seenInterrupt>2 ) exit(1);
   if( db ) sqlite3_interrupt(db);    if( db ) sqlite3_interrupt(db);
 }  }
 #endif  #endif
Line 853 
Line 858 
       break;        break;
     }      }
     case MODE_Csv: {      case MODE_Csv: {
   #if defined(WIN32) || defined(_WIN32)
         fflush(p->out);
         _setmode(_fileno(p->out), _O_BINARY);
   #endif
       if( p->cnt++==0 && p->showHeader ){        if( p->cnt++==0 && p->showHeader ){
         for(i=0; i<nArg; i++){          for(i=0; i<nArg; i++){
           output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);            output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
         }          }
         fprintf(p->out,"\n");          fprintf(p->out,"%s",p->newline);
       }        }
       if( azArg==0 ) break;        if( azArg>0 ){
       for(i=0; i<nArg; i++){          for(i=0; i<nArg; i++){
         output_csv(p, azArg[i], i<nArg-1);            output_csv(p, azArg[i], i<nArg-1);
           }
           fprintf(p->out,"%s",p->newline);
       }        }
       fprintf(p->out,"\n");  #if defined(WIN32) || defined(_WIN32)
         fflush(p->out);
         _setmode(_fileno(p->out), _O_TEXT);
   #endif
       break;        break;
     }      }
     case MODE_Insert: {      case MODE_Insert: {
Line 877 
Line 891 
         }else if( aiType && aiType[i]==SQLITE_TEXT ){          }else if( aiType && aiType[i]==SQLITE_TEXT ){
           if( zSep[0] ) fprintf(p->out,"%s",zSep);            if( zSep[0] ) fprintf(p->out,"%s",zSep);
           output_quoted_string(p->out, azArg[i]);            output_quoted_string(p->out, azArg[i]);
         }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){          }else if( aiType && (aiType[i]==SQLITE_INTEGER
                                || aiType[i]==SQLITE_FLOAT) ){
           fprintf(p->out,"%s%s",zSep, azArg[i]);            fprintf(p->out,"%s%s",zSep, azArg[i]);
         }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){          }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
           const void *pBlob = sqlite3_column_blob(p->pStmt, i);            const void *pBlob = sqlite3_column_blob(p->pStmt, i);
Line 1195 
Line 1210 
   int nAlloc = 0;                 /* Allocated size of p->aiIndent[], abYield */    int nAlloc = 0;                 /* Allocated size of p->aiIndent[], abYield */
   int iOp;                        /* Index of operation in p->aiIndent[] */    int iOp;                        /* Index of operation in p->aiIndent[] */
   
   const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };    const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
   const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 };                             "NextIfOpen", "PrevIfOpen", 0 };
     const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 };
   const char *azGoto[] = { "Goto", 0 };    const char *azGoto[] = { "Goto", 0 };
   
   /* Try to figure out if this is really an EXPLAIN statement. If this    /* Try to figure out if this is really an EXPLAIN statement. If this
Line 1568 
Line 1584 
 */  */
 static char zHelp[] =  static char zHelp[] =
   ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"    ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
   ".bail ON|OFF           Stop after hitting an error.  Default OFF\n"    ".bail on|off           Stop after hitting an error.  Default OFF\n"
   ".clone NEWDB           Clone data into NEWDB from the existing database\n"    ".clone NEWDB           Clone data into NEWDB from the existing database\n"
   ".databases             List names and files of attached databases\n"    ".databases             List names and files of attached databases\n"
   ".dump ?TABLE? ...      Dump the database in an SQL text format\n"    ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
   "                         If TABLE specified, only dump tables matching\n"    "                         If TABLE specified, only dump tables matching\n"
   "                         LIKE pattern TABLE.\n"    "                         LIKE pattern TABLE.\n"
   ".echo ON|OFF           Turn command echo on or off\n"    ".echo on|off           Turn command echo on or off\n"
     ".eqp on|off            Enable or disable automatic EXPLAIN QUERY PLAN\n"
   ".exit                  Exit this program\n"    ".exit                  Exit this program\n"
   ".explain ?ON|OFF?      Turn output mode suitable for EXPLAIN on or off.\n"    ".explain ?on|off?      Turn output mode suitable for EXPLAIN on or off.\n"
   "                         With no args, it turns EXPLAIN on.\n"    "                         With no args, it turns EXPLAIN on.\n"
   ".header(s) ON|OFF      Turn display of headers on or off\n"    ".fullschema            Show schema and the content of sqlite_stat tables\n"
     ".headers on|off        Turn display of headers on or off\n"
   ".help                  Show this message\n"    ".help                  Show this message\n"
   ".import FILE TABLE     Import data from FILE into TABLE\n"    ".import FILE TABLE     Import data from FILE into TABLE\n"
   ".indices ?TABLE?       Show names of all indices\n"    ".indices ?TABLE?       Show names of all indices\n"
Line 1601 
Line 1619 
   "                         tabs     Tab-separated values\n"    "                         tabs     Tab-separated values\n"
   "                         tcl      TCL list elements\n"    "                         tcl      TCL list elements\n"
   ".nullvalue STRING      Use STRING in place of NULL values\n"    ".nullvalue STRING      Use STRING in place of NULL values\n"
     ".once FILENAME         Output for the next SQL command only to FILENAME\n"
   ".open ?FILENAME?       Close existing database and reopen FILENAME\n"    ".open ?FILENAME?       Close existing database and reopen FILENAME\n"
   ".output FILENAME       Send output to FILENAME\n"    ".output ?FILENAME?     Send output to FILENAME or stdout\n"
   ".output stdout         Send output to the screen\n"  
   ".print STRING...       Print literal STRING\n"    ".print STRING...       Print literal STRING\n"
   ".prompt MAIN CONTINUE  Replace the standard prompts\n"    ".prompt MAIN CONTINUE  Replace the standard prompts\n"
   ".quit                  Exit this program\n"    ".quit                  Exit this program\n"
Line 1613 
Line 1631 
   ".schema ?TABLE?        Show the CREATE statements\n"    ".schema ?TABLE?        Show the CREATE statements\n"
   "                         If TABLE specified, only show tables matching\n"    "                         If TABLE specified, only show tables matching\n"
   "                         LIKE pattern TABLE.\n"    "                         LIKE pattern TABLE.\n"
   ".separator STRING      Change separator used by output mode and .import\n"    ".separator STRING ?NL? Change separator used by output mode and .import\n"
     "                         NL is the end-of-line mark for CSV\n"
     ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
   ".show                  Show the current values for various settings\n"    ".show                  Show the current values for various settings\n"
   ".stats ON|OFF          Turn stats on or off\n"    ".stats on|off          Turn stats on or off\n"
     ".system CMD ARGS...    Run CMD ARGS... in a system shell\n"
   ".tables ?TABLE?        List names of tables\n"    ".tables ?TABLE?        List names of tables\n"
   "                         If TABLE specified, only list tables matching\n"    "                         If TABLE specified, only list tables matching\n"
   "                         LIKE pattern TABLE.\n"    "                         LIKE pattern TABLE.\n"
   ".timeout MS            Try opening locked tables for MS milliseconds\n"    ".timeout MS            Try opening locked tables for MS milliseconds\n"
     ".timer on|off          Turn SQL timer on or off\n"
   ".trace FILE|off        Output each SQL statement as it is run\n"    ".trace FILE|off        Output each SQL statement as it is run\n"
   ".vfsname ?AUX?         Print the name of the VFS stack\n"    ".vfsname ?AUX?         Print the name of the VFS stack\n"
   ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"    ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
     "                         Negative values right-justify\n"
 ;  ;
   
 static char zTimerHelp[] =  
   ".timer ON|OFF          Turn the CPU timer measurement on or off\n"  
 ;  
   
 /* Forward reference */  /* Forward reference */
 static int process_input(struct callback_data *p, FILE *in);  static int process_input(struct callback_data *p, FILE *in);
   /*
   ** Implementation of the "readfile(X)" SQL function.  The entire content
   ** of the file named X is read and returned as a BLOB.  NULL is returned
   ** if the file does not exist or is unreadable.
   */
   static void readfileFunc(
     sqlite3_context *context,
     int argc,
     sqlite3_value **argv
   ){
     const char *zName;
     FILE *in;
     long nIn;
     void *pBuf;
   
     zName = (const char*)sqlite3_value_text(argv[0]);
     if( zName==0 ) return;
     in = fopen(zName, "rb");
     if( in==0 ) return;
     fseek(in, 0, SEEK_END);
     nIn = ftell(in);
     rewind(in);
     pBuf = sqlite3_malloc( nIn );
     if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
       sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
     }else{
       sqlite3_free(pBuf);
     }
     fclose(in);
   }
   
 /*  /*
   ** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
   ** is written into file X.  The number of bytes written is returned.  Or
   ** NULL is returned if something goes wrong, such as being unable to open
   ** file X for writing.
   */
   static void writefileFunc(
     sqlite3_context *context,
     int argc,
     sqlite3_value **argv
   ){
     FILE *out;
     const char *z;
     sqlite3_int64 rc;
     const char *zFile;
   
     zFile = (const char*)sqlite3_value_text(argv[0]);
     if( zFile==0 ) return;
     out = fopen(zFile, "wb");
     if( out==0 ) return;
     z = (const char*)sqlite3_value_blob(argv[1]);
     if( z==0 ){
       rc = 0;
     }else{
       rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
     }
     fclose(out);
     sqlite3_result_int64(context, rc);
   }
   
   /*
 ** Make sure the database is open.  If it is not, then open it.  If  ** Make sure the database is open.  If it is not, then open it.  If
 ** the database fails to open, print an error message and exit.  ** the database fails to open, print an error message and exit.
 */  */
Line 1654 
Line 1733 
 #ifndef SQLITE_OMIT_LOAD_EXTENSION  #ifndef SQLITE_OMIT_LOAD_EXTENSION
     sqlite3_enable_load_extension(p->db, 1);      sqlite3_enable_load_extension(p->db, 1);
 #endif  #endif
       sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
                               readfileFunc, 0, 0);
       sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
                               writefileFunc, 0, 0);
   }    }
 }  }
   
Line 1670 
Line 1753 
 static void resolve_backslashes(char *z){  static void resolve_backslashes(char *z){
   int i, j;    int i, j;
   char c;    char c;
     while( *z && *z!='\\' ) z++;
   for(i=j=0; (c = z[i])!=0; i++, j++){    for(i=j=0; (c = z[i])!=0; i++, j++){
     if( c=='\\' ){      if( c=='\\' ){
       c = z[++i];        c = z[++i];
Line 1695 
Line 1779 
     }      }
     z[j] = c;      z[j] = c;
   }    }
   z[j] = 0;    if( j<i ) z[j] = 0;
 }  }
   
 /*  /*
Line 2129 
Line 2213 
     fprintf(stderr, "Cannot create output database: %s\n",      fprintf(stderr, "Cannot create output database: %s\n",
             sqlite3_errmsg(newDb));              sqlite3_errmsg(newDb));
   }else{    }else{
       sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
     sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);      sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
     tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);      tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
     tryToCloneSchema(p, newDb, "type!='table'", 0);      tryToCloneSchema(p, newDb, "type!='table'", 0);
     sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);      sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
       sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
   }    }
   sqlite3_close(newDb);    sqlite3_close(newDb);
 }  }
   
 /*  /*
   ** Change the output file back to stdout
   */
   static void output_reset(struct callback_data *p){
     if( p->outfile[0]=='|' ){
       pclose(p->out);
     }else{
       output_file_close(p->out);
     }
     p->outfile[0] = 0;
     p->out = stdout;
   }
   
   /*
 ** If an input line begins with "." then invoke this routine to  ** If an input line begins with "." then invoke this routine to
 ** process that line.  ** process that line.
 **  **
Line 2235 
Line 2334 
     sqlite3_close(pDest);      sqlite3_close(pDest);
   }else    }else
   
   if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){    if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
     bail_on_error = booleanValue(azArg[1]);      if( nArg==2 ){
         bail_on_error = booleanValue(azArg[1]);
       }else{
         fprintf(stderr, "Usage: .bail on|off\n");
         rc = 1;
       }
   }else    }else
   
   /* The undocumented ".breakpoint" command causes a call to the no-op    /* The undocumented ".breakpoint" command causes a call to the no-op
Line 2246 
Line 2350 
     test_breakpoint();      test_breakpoint();
   }else    }else
   
   if( c=='c' && strncmp(azArg[0], "clone", n)==0 && nArg>1 && nArg<3 ){    if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
     tryToClone(p, azArg[1]);      if( nArg==2 ){
         tryToClone(p, azArg[1]);
       }else{
         fprintf(stderr, "Usage: .clone FILENAME\n");
         rc = 1;
       }
   }else    }else
   
   if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){    if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
     struct callback_data data;      struct callback_data data;
     char *zErrMsg = 0;      char *zErrMsg = 0;
     open_db(p, 0);      open_db(p, 0);
Line 2269 
Line 2378 
     }      }
   }else    }else
   
   if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){    if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
     open_db(p, 0);      open_db(p, 0);
     /* When playing back a "dump", the content might appear in an order      /* When playing back a "dump", the content might appear in an order
     ** which causes immediate foreign key constraints to be violated.      ** which causes immediate foreign key constraints to be violated.
     ** So disable foreign-key constraint enforcement to prevent problems. */      ** So disable foreign-key constraint enforcement to prevent problems. */
       if( nArg!=1 && nArg!=2 ){
         fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
         rc = 1;
         goto meta_command_exit;
       }
     fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");      fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
     fprintf(p->out, "BEGIN TRANSACTION;\n");      fprintf(p->out, "BEGIN TRANSACTION;\n");
     p->writableSchema = 0;      p->writableSchema = 0;
Line 2318 
Line 2432 
     fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");      fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
   }else    }else
   
   if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){    if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
     p->echoOn = booleanValue(azArg[1]);      if( nArg==2 ){
         p->echoOn = booleanValue(azArg[1]);
       }else{
         fprintf(stderr, "Usage: .echo on|off\n");
         rc = 1;
       }
   }else    }else
   
   if( c=='e' && strncmp(azArg[0], "eqp", n)==0 && nArg>1 && nArg<3 ){    if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
     p->autoEQP = booleanValue(azArg[1]);      if( nArg==2 ){
         p->autoEQP = booleanValue(azArg[1]);
       }else{
         fprintf(stderr, "Usage: .eqp on|off\n");
         rc = 1;
       }
   }else    }else
   
   if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){    if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
Line 2331 
Line 2455 
     rc = 2;      rc = 2;
   }else    }else
   
   if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){    if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
     int val = nArg>=2 ? booleanValue(azArg[1]) : 1;      int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
     if(val == 1) {      if(val == 1) {
       if(!p->explainPrev.valid) {        if(!p->explainPrev.valid) {
Line 2366 
Line 2490 
     }      }
   }else    }else
   
   if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||    if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
                  strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){      struct callback_data data;
     p->showHeader = booleanValue(azArg[1]);      char *zErrMsg = 0;
       int doStats = 0;
       if( nArg!=1 ){
         fprintf(stderr, "Usage: .fullschema\n");
         rc = 1;
         goto meta_command_exit;
       }
       open_db(p, 0);
       memcpy(&data, p, sizeof(data));
       data.showHeader = 0;
       data.mode = MODE_Semi;
       rc = sqlite3_exec(p->db,
          "SELECT sql FROM"
          "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
          "     FROM sqlite_master UNION ALL"
          "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
          "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
          "ORDER BY rowid",
          callback, &data, &zErrMsg
       );
       if( rc==SQLITE_OK ){
         sqlite3_stmt *pStmt;
         rc = sqlite3_prepare_v2(p->db,
                  "SELECT rowid FROM sqlite_master"
                  " WHERE name GLOB 'sqlite_stat[134]'",
                  -1, &pStmt, 0);
         doStats = sqlite3_step(pStmt)==SQLITE_ROW;
         sqlite3_finalize(pStmt);
       }
       if( doStats==0 ){
         fprintf(p->out, "/* No STAT tables available */\n");
       }else{
         fprintf(p->out, "ANALYZE sqlite_master;\n");
         sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
                      callback, &data, &zErrMsg);
         data.mode = MODE_Insert;
         data.zDestTable = "sqlite_stat1";
         shell_exec(p->db, "SELECT * FROM sqlite_stat1",
                    shell_callback, &data,&zErrMsg);
         data.zDestTable = "sqlite_stat3";
         shell_exec(p->db, "SELECT * FROM sqlite_stat3",
                    shell_callback, &data,&zErrMsg);
         data.zDestTable = "sqlite_stat4";
         shell_exec(p->db, "SELECT * FROM sqlite_stat4",
                    shell_callback, &data, &zErrMsg);
         fprintf(p->out, "ANALYZE sqlite_master;\n");
       }
   }else    }else
   
   if( c=='h' && strncmp(azArg[0], "help", n)==0 ){    if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
     fprintf(stderr,"%s",zHelp);      if( nArg==2 ){
     if( HAS_TIMER ){        p->showHeader = booleanValue(azArg[1]);
       fprintf(stderr,"%s",zTimerHelp);      }else{
         fprintf(stderr, "Usage: .headers on|off\n");
         rc = 1;
     }      }
   }else    }else
   
   if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){    if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
     char *zTable = azArg[2];    /* Insert data into this table */      fprintf(p->out, "%s", zHelp);
     char *zFile = azArg[1];     /* Name of file to extra content from */    }else
   
     if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
       char *zTable;               /* Insert data into this table */
       char *zFile;                /* Name of file to extra content from */
     sqlite3_stmt *pStmt = NULL; /* A statement */      sqlite3_stmt *pStmt = NULL; /* A statement */
     int nCol;                   /* Number of columns in the table */      int nCol;                   /* Number of columns in the table */
     int nByte;                  /* Number of bytes in an SQL string */      int nByte;                  /* Number of bytes in an SQL string */
Line 2391 
Line 2567 
     CSVReader sCsv;             /* Reader context */      CSVReader sCsv;             /* Reader context */
     int (*xCloser)(FILE*);      /* Procedure to close th3 connection */      int (*xCloser)(FILE*);      /* Procedure to close th3 connection */
   
       if( nArg!=3 ){
         fprintf(stderr, "Usage: .import FILE TABLE\n");
         goto meta_command_exit;
       }
       zFile = azArg[1];
       zTable = azArg[2];
     seenInterrupt = 0;      seenInterrupt = 0;
     memset(&sCsv, 0, sizeof(sCsv));      memset(&sCsv, 0, sizeof(sCsv));
     open_db(p, 0);      open_db(p, 0);
Line 2427 
Line 2609 
     }      }
     nByte = strlen30(zSql);      nByte = strlen30(zSql);
     rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
       csv_append_char(&sCsv, 0);    /* To ensure sCsv.z is allocated */
     if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){      if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
       char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);        char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
       char cSep = '(';        char cSep = '(';
Line 2500 
Line 2683 
                           "filling the rest with NULL\n",                            "filling the rest with NULL\n",
                           sCsv.zFile, startLine, nCol, i+1);                            sCsv.zFile, startLine, nCol, i+1);
           i++;            i++;
           while( i<nCol ){ sqlite3_bind_null(pStmt, i); i++; }            while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
         }          }
       }        }
       if( sCsv.cTerm==sCsv.cSeparator ){        if( sCsv.cTerm==sCsv.cSeparator ){
Line 2528 
Line 2711 
     if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);      if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
   }else    }else
   
   if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){    if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
     struct callback_data data;      struct callback_data data;
     char *zErrMsg = 0;      char *zErrMsg = 0;
     open_db(p, 0);      open_db(p, 0);
Line 2545 
Line 2728 
         "ORDER BY 1",          "ORDER BY 1",
         callback, &data, &zErrMsg          callback, &data, &zErrMsg
       );        );
     }else{      }else if( nArg==2 ){
       zShellStatic = azArg[1];        zShellStatic = azArg[1];
       rc = sqlite3_exec(p->db,        rc = sqlite3_exec(p->db,
         "SELECT name FROM sqlite_master "          "SELECT name FROM sqlite_master "
Line 2557 
Line 2740 
         callback, &data, &zErrMsg          callback, &data, &zErrMsg
       );        );
       zShellStatic = 0;        zShellStatic = 0;
       }else{
         fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
         rc = 1;
         goto meta_command_exit;
     }      }
     if( zErrMsg ){      if( zErrMsg ){
       fprintf(stderr,"Error: %s\n", zErrMsg);        fprintf(stderr,"Error: %s\n", zErrMsg);
Line 2592 
Line 2779 
 #endif  #endif
   
 #ifndef SQLITE_OMIT_LOAD_EXTENSION  #ifndef SQLITE_OMIT_LOAD_EXTENSION
   if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){    if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
     const char *zFile, *zProc;      const char *zFile, *zProc;
     char *zErrMsg = 0;      char *zErrMsg = 0;
       if( nArg<2 ){
         fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
         rc = 1;
         goto meta_command_exit;
       }
     zFile = azArg[1];      zFile = azArg[1];
     zProc = nArg>=3 ? azArg[2] : 0;      zProc = nArg>=3 ? azArg[2] : 0;
     open_db(p, 0);      open_db(p, 0);
Line 2607 
Line 2799 
   }else    }else
 #endif  #endif
   
   if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){    if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
     const char *zFile = azArg[1];      if( nArg!=2 ){
     output_file_close(p->pLog);        fprintf(stderr, "Usage: .log FILENAME\n");
     p->pLog = output_file_open(zFile);        rc = 1;
       }else{
         const char *zFile = azArg[1];
         output_file_close(p->pLog);
         p->pLog = output_file_open(zFile);
       }
   }else    }else
   
   if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){    if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
     int n2 = strlen30(azArg[1]);      const char *zMode = nArg>=2 ? azArg[1] : "";
     if( (n2==4 && strncmp(azArg[1],"line",n2)==0)      int n2 = (int)strlen(zMode);
         ||      int c2 = zMode[0];
         (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){      if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
       p->mode = MODE_Line;        p->mode = MODE_Line;
     }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)      }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
               ||  
               (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){  
       p->mode = MODE_Column;        p->mode = MODE_Column;
     }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){      }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
       p->mode = MODE_List;        p->mode = MODE_List;
     }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){      }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
       p->mode = MODE_Html;        p->mode = MODE_Html;
     }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){      }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
       p->mode = MODE_Tcl;        p->mode = MODE_Tcl;
       sqlite3_snprintf(sizeof(p->separator), p->separator, " ");        sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
     }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){      }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
       p->mode = MODE_Csv;        p->mode = MODE_Csv;
       sqlite3_snprintf(sizeof(p->separator), p->separator, ",");        sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
     }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){        sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n");
       }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
       p->mode = MODE_List;        p->mode = MODE_List;
       sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");        sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
     }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){      }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
       p->mode = MODE_Insert;        p->mode = MODE_Insert;
       set_table_name(p, "table");        set_table_name(p, nArg>=3 ? azArg[2] : "table");
     }else {      }else {
       fprintf(stderr,"Error: mode should be one of: "        fprintf(stderr,"Error: mode should be one of: "
          "column csv html insert line list tabs tcl\n");           "column csv html insert line list tabs tcl\n");
Line 2646 
Line 2842 
     }      }
   }else    }else
   
   if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){    if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
     int n2 = strlen30(azArg[1]);      if( nArg==2 ){
     if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){        sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
       p->mode = MODE_Insert;                         "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
       set_table_name(p, azArg[2]);      }else{
     }else {        fprintf(stderr, "Usage: .nullvalue STRING\n");
       fprintf(stderr, "Error: invalid arguments: "  
         " \"%s\". Enter \".help\" for help\n", azArg[2]);  
       rc = 1;        rc = 1;
     }      }
   }else    }else
   
   if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {  
     sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,  
                      "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);  
   }else  
   
   if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){    if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
     sqlite3 *savedDb = p->db;      sqlite3 *savedDb = p->db;
     const char *zSavedFilename = p->zDbFilename;      const char *zSavedFilename = p->zDbFilename;
Line 2683 
Line 2872 
     }      }
   }else    }else
   
   if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){    if( c=='o'
     if( p->outfile[0]=='|' ){     && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
       pclose(p->out);    ){
       const char *zFile = nArg>=2 ? azArg[1] : "stdout";
       if( nArg>2 ){
         fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
         rc = 1;
         goto meta_command_exit;
       }
       if( n>1 && strncmp(azArg[0], "once", n)==0 ){
         if( nArg<2 ){
           fprintf(stderr, "Usage: .once FILE\n");
           rc = 1;
           goto meta_command_exit;
         }
         p->outCount = 2;
     }else{      }else{
       output_file_close(p->out);        p->outCount = 0;
     }      }
     p->outfile[0] = 0;      output_reset(p);
     if( azArg[1][0]=='|' ){      if( zFile[0]=='|' ){
       p->out = popen(&azArg[1][1], "w");        p->out = popen(zFile + 1, "w");
       if( p->out==0 ){        if( p->out==0 ){
         fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);          fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
         p->out = stdout;          p->out = stdout;
         rc = 1;          rc = 1;
       }else{        }else{
         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);          sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
       }        }
     }else{      }else{
       p->out = output_file_open(azArg[1]);        p->out = output_file_open(zFile);
       if( p->out==0 ){        if( p->out==0 ){
         if( strcmp(azArg[1],"off")!=0 ){          if( strcmp(zFile,"off")!=0 ){
           fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);            fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
         }          }
         p->out = stdout;          p->out = stdout;
         rc = 1;          rc = 1;
       } else {        } else {
         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);          sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
       }        }
     }      }
   }else    }else
Line 2722 
Line 2924 
     fprintf(p->out, "\n");      fprintf(p->out, "\n");
   }else    }else
   
   if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){    if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
     if( nArg >= 2) {      if( nArg >= 2) {
       strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);        strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
     }      }
Line 2731 
Line 2933 
     }      }
   }else    }else
   
   if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){    if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
     rc = 2;      rc = 2;
   }else    }else
   
   if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){    if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
     FILE *alt = fopen(azArg[1], "rb");      FILE *alt;
       if( nArg!=2 ){
         fprintf(stderr, "Usage: .read FILE\n");
         rc = 1;
         goto meta_command_exit;
       }
       alt = fopen(azArg[1], "rb");
     if( alt==0 ){      if( alt==0 ){
       fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);        fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
       rc = 1;        rc = 1;
Line 2746 
Line 2954 
     }      }
   }else    }else
   
   if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){    if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
     const char *zSrcFile;      const char *zSrcFile;
     const char *zDb;      const char *zDb;
     sqlite3 *pSrc;      sqlite3 *pSrc;
Line 2756 
Line 2964 
     if( nArg==2 ){      if( nArg==2 ){
       zSrcFile = azArg[1];        zSrcFile = azArg[1];
       zDb = "main";        zDb = "main";
     }else{      }else if( nArg==3 ){
       zSrcFile = azArg[2];        zSrcFile = azArg[2];
       zDb = azArg[1];        zDb = azArg[1];
       }else{
         fprintf(stderr, "Usage: .restore ?DB? FILE\n");
         rc = 1;
         goto meta_command_exit;
     }      }
     rc = sqlite3_open(zSrcFile, &pSrc);      rc = sqlite3_open(zSrcFile, &pSrc);
     if( rc!=SQLITE_OK ){      if( rc!=SQLITE_OK ){
Line 2793 
Line 3005 
     sqlite3_close(pSrc);      sqlite3_close(pSrc);
   }else    }else
   
   if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){    if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
     struct callback_data data;      struct callback_data data;
     char *zErrMsg = 0;      char *zErrMsg = 0;
     open_db(p, 0);      open_db(p, 0);
     memcpy(&data, p, sizeof(data));      memcpy(&data, p, sizeof(data));
     data.showHeader = 0;      data.showHeader = 0;
     data.mode = MODE_Semi;      data.mode = MODE_Semi;
     if( nArg>1 ){      if( nArg==2 ){
       int i;        int i;
       for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);        for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
       if( strcmp(azArg[1],"sqlite_master")==0 ){        if( strcmp(azArg[1],"sqlite_master")==0 ){
Line 2844 
Line 3056 
           callback, &data, &zErrMsg);            callback, &data, &zErrMsg);
         zShellStatic = 0;          zShellStatic = 0;
       }        }
     }else{      }else if( nArg==1 ){
       rc = sqlite3_exec(p->db,        rc = sqlite3_exec(p->db,
          "SELECT sql FROM "           "SELECT sql FROM "
          "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"           "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
Line 2854 
Line 3066 
          "ORDER BY rowid",           "ORDER BY rowid",
          callback, &data, &zErrMsg           callback, &data, &zErrMsg
       );        );
       }else{
         fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
         rc = 1;
         goto meta_command_exit;
     }      }
     if( zErrMsg ){      if( zErrMsg ){
       fprintf(stderr,"Error: %s\n", zErrMsg);        fprintf(stderr,"Error: %s\n", zErrMsg);
Line 2883 
Line 3099 
       for(i=1; i<nArg; i++){        for(i=1; i<nArg; i++){
         char zBuf[200];          char zBuf[200];
         v = integerValue(azArg[i]);          v = integerValue(azArg[i]);
         sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);          sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
         fprintf(p->out, "%s", zBuf);          fprintf(p->out, "%s", zBuf);
       }        }
     }      }
   }else    }else
 #endif  #endif
   
   if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){    if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
     sqlite3_snprintf(sizeof(p->separator), p->separator,      if( nArg<2 || nArg>3 ){
                      "%.*s", (int)sizeof(p->separator)-1, azArg[1]);        fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n");
         rc = 1;
       }
       if( nArg>=2 ){
         sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]);
       }
       if( nArg>=3 ){
         sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]);
       }
   }else    }else
   
   if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){    if( c=='s'
      && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
     ){
       char *zCmd;
       int i, x;
       if( nArg<2 ){
         fprintf(stderr, "Usage: .system COMMAND\n");
         rc = 1;
         goto meta_command_exit;
       }
       zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
       for(i=2; i<nArg; i++){
         zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
                                zCmd, azArg[i]);
       }
       x = system(zCmd);
       sqlite3_free(zCmd);
       if( x ) fprintf(stderr, "System command returns %d\n", x);
     }else
   
     if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
     int i;      int i;
       if( nArg!=1 ){
         fprintf(stderr, "Usage: .show\n");
         rc = 1;
         goto meta_command_exit;
       }
     fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");      fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
     fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");      fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
     fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");      fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
Line 2909 
Line 3158 
             strlen30(p->outfile) ? p->outfile : "stdout");              strlen30(p->outfile) ? p->outfile : "stdout");
     fprintf(p->out,"%9.9s: ", "separator");      fprintf(p->out,"%9.9s: ", "separator");
       output_c_string(p->out, p->separator);        output_c_string(p->out, p->separator);
         fprintf(p->out," ");
         output_c_string(p->out, p->newline);
       fprintf(p->out, "\n");        fprintf(p->out, "\n");
     fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");      fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off");
     fprintf(p->out,"%9.9s: ","width");      fprintf(p->out,"%9.9s: ","width");
Line 2918 
Line 3169 
     fprintf(p->out,"\n");      fprintf(p->out,"\n");
   }else    }else
   
   if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){    if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
     p->statsOn = booleanValue(azArg[1]);      if( nArg==2 ){
         p->statsOn = booleanValue(azArg[1]);
       }else{
         fprintf(stderr, "Usage: .stats on|off\n");
         rc = 1;
       }
   }else    }else
   
   if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){    if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
     sqlite3_stmt *pStmt;      sqlite3_stmt *pStmt;
     char **azResult;      char **azResult;
     int nRow, nAlloc;      int nRow, nAlloc;
Line 3024 
Line 3280 
       { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },        { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },
       { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },        { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
       { "scratchmalloc",         SQLITE_TESTCTRL_SCRATCHMALLOC          },        { "scratchmalloc",         SQLITE_TESTCTRL_SCRATCHMALLOC          },
         { "byteorder",             SQLITE_TESTCTRL_BYTEORDER              },
     };      };
     int testctrl = -1;      int testctrl = -1;
     int rc = 0;      int rc = 0;
Line 3064 
Line 3321 
           break;            break;
   
         /* sqlite3_test_control(int) */          /* sqlite3_test_control(int) */
         case SQLITE_TESTCTRL_PRNG_SAVE:          case SQLITE_TESTCTRL_PRNG_SAVE:
         case SQLITE_TESTCTRL_PRNG_RESTORE:          case SQLITE_TESTCTRL_PRNG_RESTORE:
         case SQLITE_TESTCTRL_PRNG_RESET:          case SQLITE_TESTCTRL_PRNG_RESET:
           case SQLITE_TESTCTRL_BYTEORDER:
           if( nArg==2 ){            if( nArg==2 ){
             rc = sqlite3_test_control(testctrl);              rc = sqlite3_test_control(testctrl);
             fprintf(p->out, "%d (0x%08x)\n", rc, rc);              fprintf(p->out, "%d (0x%08x)\n", rc, rc);
Line 3126 
Line 3384 
     }      }
   }else    }else
   
   if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){    if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
     open_db(p, 0);      open_db(p, 0);
     sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));      sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
   }else    }else
   
   if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0    if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
    && nArg==2      if( nArg==2 ){
   ){        enableTimer = booleanValue(azArg[1]);
     enableTimer = booleanValue(azArg[1]);        if( enableTimer && !HAS_TIMER ){
           fprintf(stderr, "Error: timer not available on this system.\n");
           enableTimer = 0;
         }
       }else{
         fprintf(stderr, "Usage: .timer on|off\n");
         rc = 1;
       }
   }else    }else
   
   if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){    if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
     open_db(p, 0);      open_db(p, 0);
     output_file_close(p->traceOut);      output_file_close(p->traceOut);
       if( nArg!=2 ){
         fprintf(stderr, "Usage: .trace FILE|off\n");
         rc = 1;
         goto meta_command_exit;
       }
     p->traceOut = output_file_open(azArg[1]);      p->traceOut = output_file_open(azArg[1]);
 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)  #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
     if( p->traceOut==0 ){      if( p->traceOut==0 ){
Line 3170 
Line 3440 
 #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)  #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
   if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){    if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
     extern int sqlite3WhereTrace;      extern int sqlite3WhereTrace;
     sqlite3WhereTrace = booleanValue(azArg[1]);      sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
   }else    }else
 #endif  #endif
   
   if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){    if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
     int j;      int j;
     assert( nArg<=ArraySize(azArg) );      assert( nArg<=ArraySize(azArg) );
     for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){      for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
Line 3188 
Line 3458 
     rc = 1;      rc = 1;
   }    }
   
   meta_command_exit:
     if( p->outCount ){
       p->outCount--;
       if( p->outCount==0 ) output_reset(p);
     }
   return rc;    return rc;
 }  }
   
Line 3355 
Line 3630 
         errCnt++;          errCnt++;
       }        }
       nSql = 0;        nSql = 0;
         if( p->outCount ){
           output_reset(p);
           p->outCount = 0;
         }
     }else if( nSql && _all_whitespace(zSql) ){      }else if( nSql && _all_whitespace(zSql) ){
       if( p->echoOn ) printf("%s\n", zSql);        if( p->echoOn ) printf("%s\n", zSql);
       nSql = 0;        nSql = 0;
Line 3497 
Line 3776 
 #ifdef SQLITE_ENABLE_MULTIPLEX  #ifdef SQLITE_ENABLE_MULTIPLEX
   "   -multiplex           enable the multiplexor VFS\n"    "   -multiplex           enable the multiplexor VFS\n"
 #endif  #endif
     "   -newline SEP         set newline character(s) for CSV\n"
   "   -nullvalue TEXT      set text string for NULL values. Default ''\n"    "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
   "   -separator SEP       set output field separator. Default: '|'\n"    "   -separator SEP       set output field separator. Default: '|'\n"
   "   -stats               print memory stats before each finalize\n"    "   -stats               print memory stats before each finalize\n"
Line 3526 
Line 3806 
   memset(data, 0, sizeof(*data));    memset(data, 0, sizeof(*data));
   data->mode = MODE_List;    data->mode = MODE_List;
   memcpy(data->separator,"|", 2);    memcpy(data->separator,"|", 2);
     memcpy(data->newline,"\r\n", 3);
   data->showHeader = 0;    data->showHeader = 0;
   sqlite3_config(SQLITE_CONFIG_URI, 1);    sqlite3_config(SQLITE_CONFIG_URI, 1);
   sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);    sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
Line 3618 
Line 3899 
     if( z[1]=='-' ) z++;      if( z[1]=='-' ) z++;
     if( strcmp(z,"-separator")==0      if( strcmp(z,"-separator")==0
      || strcmp(z,"-nullvalue")==0       || strcmp(z,"-nullvalue")==0
        || strcmp(z,"-newline")==0
      || strcmp(z,"-cmd")==0       || strcmp(z,"-cmd")==0
     ){      ){
       (void)cmdline_option_value(argc, argv, ++i);        (void)cmdline_option_value(argc, argv, ++i);
Line 3726 
Line 4008 
       memcpy(data.separator,",",2);        memcpy(data.separator,",",2);
     }else if( strcmp(z,"-separator")==0 ){      }else if( strcmp(z,"-separator")==0 ){
       sqlite3_snprintf(sizeof(data.separator), data.separator,        sqlite3_snprintf(sizeof(data.separator), data.separator,
                          "%s",cmdline_option_value(argc,argv,++i));
       }else if( strcmp(z,"-newline")==0 ){
         sqlite3_snprintf(sizeof(data.newline), data.newline,
                        "%s",cmdline_option_value(argc,argv,++i));                         "%s",cmdline_option_value(argc,argv,++i));
     }else if( strcmp(z,"-nullvalue")==0 ){      }else if( strcmp(z,"-nullvalue")==0 ){
       sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,        sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,

Legend:
Removed from v.1.1.1.8  
changed lines
  Added in v.1.1.1.9