From: drh Date: Thu, 29 May 2014 12:36:14 +0000 (+0000) Subject: Improvements to error messages for errors in the dot-commands of the X-Git-Tag: version-3.8.5~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c2ce0bea88a56c20c9bcac526e7dca3335f65ae8;p=thirdparty%2Fsqlite.git Improvements to error messages for errors in the dot-commands of the command-line shell. Add the ".once" command. The output of ".help" now goes to the designated output channel. FossilOrigin-Name: 48dce821a07ac29da6ce05e92cf3f6e52b6eb388 --- diff --git a/manifest b/manifest index 0d3e2478c4..fb3c92c2cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\squote\sthe\sarguments\sto\sthe\s".shell"\sand\s".system"\scommands\sif\sthey\ncontain\sspaces. -D 2014-05-29T03:17:29.412 +C Improvements\sto\serror\smessages\sfor\serrors\sin\sthe\sdot-commands\sof\sthe\ncommand-line\sshell.\s\sAdd\sthe\s".once"\scommand.\s\sThe\soutput\sof\s".help"\nnow\sgoes\sto\sthe\sdesignated\soutput\schannel. +D 2014-05-29T12:36:14.908 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c 7df17ec5506c2427576d412bee0e6ea740e12563 -F src/shell.c f389c2bcae6192daad01b46169e63538456427fa +F src/shell.c a94689054bc0a66608f3d75b3ced2b886c3d7f50 F src/sqlite.h.in 564fc23db33870b5096b20d72df7491ce0b8b74f F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -813,11 +813,11 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test f2a1d471e5cd2b42f7a65b166dc1ace2b8d11583 +F test/shell1.test fb080d67c81e8a80a79ea04b36f127209b5bd112 F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3 F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 -F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 -F test/shell5.test fa5583230c0aea5c9ff33f0ac1e26b1e3f03d153 +F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5 +F test/shell5.test 6b1a53c49a4ff5c3bd0bad17a85ecba505608278 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 @@ -1173,7 +1173,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d018a34a05cec6adda61ed225d084c587343f2a6 -R c32df26ea35dc6668db5bcd28814662e +P e58f4bd39d51c4c1a28684dab6427de81173d564 +R 7215154feb44506111be05bd24ee86a7 U drh -Z a04310abc4a1ec4cc8144d03b2ee32a5 +Z cfc4096d1968e16f0aae201a0082ea68 diff --git a/manifest.uuid b/manifest.uuid index 944a28888f..9fb4a9df39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e58f4bd39d51c4c1a28684dab6427de81173d564 \ No newline at end of file +48dce821a07ac29da6ce05e92cf3f6e52b6eb388 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index f51ce9a164..e2748911e6 100644 --- a/src/shell.c +++ b/src/shell.c @@ -446,8 +446,9 @@ struct previous_mode_data { struct callback_data { sqlite3 *db; /* The database */ 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 outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ @@ -878,7 +879,8 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int }else if( aiType && aiType[i]==SQLITE_TEXT ){ if( zSep[0] ) fprintf(p->out,"%s",zSep); 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]); }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); @@ -1570,17 +1572,17 @@ static int run_schema_dump_query( */ static char zHelp[] = ".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" ".databases List names and files of attached databases\n" ".dump ?TABLE? ... Dump the database in an SQL text format\n" " If TABLE specified, only dump tables matching\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" ".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" - ".headers ON|OFF Turn display of headers on or off\n" + ".headers on|off Turn display of headers on or off\n" ".help Show this message\n" ".import FILE TABLE Import data from FILE into TABLE\n" ".indices ?TABLE? Show names of all indices\n" @@ -1603,9 +1605,9 @@ static char zHelp[] = " tabs Tab-separated values\n" " tcl TCL list elements\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" - ".output FILENAME Send output to FILENAME\n" - ".output stdout Send output to the screen\n" + ".output ?FILENAME? Send output to FILENAME or stdout\n" ".print STRING... Print literal STRING\n" ".prompt MAIN CONTINUE Replace the standard prompts\n" ".quit Exit this program\n" @@ -1618,22 +1620,19 @@ static char zHelp[] = ".separator STRING Change separator used by output mode and .import\n" ".shell CMD ARGS... Run CMD ARGS... in a system shell\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" " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\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" ".vfsname ?AUX? Print the name of the VFS stack\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 */ static int process_input(struct callback_data *p, FILE *in); @@ -1675,6 +1674,7 @@ static void open_db(struct callback_data *p, int keepAlive){ static void resolve_backslashes(char *z){ int i, j; char c; + while( *z && *z!='\\' ) z++; for(i=j=0; (c = z[i])!=0; i++, j++){ if( c=='\\' ){ c = z[++i]; @@ -1700,7 +1700,7 @@ static void resolve_backslashes(char *z){ } z[j] = c; } - z[j] = 0; + if( joutfile[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 ** process that line. @@ -2242,8 +2255,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){ sqlite3_close(pDest); }else - if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){ - bail_on_error = booleanValue(azArg[1]); + if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){ + if( nArg==2 ){ + bail_on_error = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .bail on|off\n"); + rc = 1; + } }else /* The undocumented ".breakpoint" command causes a call to the no-op @@ -2253,11 +2271,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){ test_breakpoint(); }else - if( c=='c' && strncmp(azArg[0], "clone", n)==0 && nArg>1 && nArg<3 ){ - tryToClone(p, azArg[1]); + if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){ + if( nArg==2 ){ + tryToClone(p, azArg[1]); + }else{ + fprintf(stderr, "Usage: .clone FILENAME\n"); + rc = 1; + } }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; char *zErrMsg = 0; open_db(p, 0); @@ -2276,11 +2299,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }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); /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** 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, "BEGIN TRANSACTION;\n"); p->writableSchema = 0; @@ -2325,12 +2353,22 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); }else - if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){ - p->echoOn = booleanValue(azArg[1]); + if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ + if( nArg==2 ){ + p->echoOn = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .echo on|off\n"); + rc = 1; + } }else - if( c=='e' && strncmp(azArg[0], "eqp", n)==0 && nArg>1 && nArg<3 ){ - p->autoEQP = booleanValue(azArg[1]); + if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ + if( nArg==2 ){ + p->autoEQP = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .eqp on|off\n"); + rc = 1; + } }else if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ @@ -2338,7 +2376,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ rc = 2; }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; if(val == 1) { if(!p->explainPrev.valid) { @@ -2373,19 +2411,20 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='h' && (strncmp(azArg[0], "header", n)==0 || - strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){ - p->showHeader = booleanValue(azArg[1]); + if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ + if( nArg==2 ){ + p->showHeader = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .headers on|off\n"); + rc = 1; + } }else if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ - fprintf(stderr,"%s",zHelp); - if( HAS_TIMER ){ - fprintf(stderr,"%s",zTimerHelp); - } + fprintf(p->out, "%s", zHelp); }else - if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){ + if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ char *zTable = azArg[2]; /* Insert data into this table */ char *zFile = azArg[1]; /* Name of file to extra content from */ sqlite3_stmt *pStmt = NULL; /* A statement */ @@ -2398,6 +2437,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ CSVReader sCsv; /* Reader context */ int (*xCloser)(FILE*); /* Procedure to close th3 connection */ + if( nArg!=3 ){ + fprintf(stderr, "Usage: .import FILE TABLE\n"); + goto meta_command_exit; + } seenInterrupt = 0; memset(&sCsv, 0, sizeof(sCsv)); open_db(p, 0); @@ -2536,7 +2579,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); }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; char *zErrMsg = 0; open_db(p, 0); @@ -2553,7 +2596,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ "ORDER BY 1", callback, &data, &zErrMsg ); - }else{ + }else if( nArg==2 ){ zShellStatic = azArg[1]; rc = sqlite3_exec(p->db, "SELECT name FROM sqlite_master " @@ -2565,6 +2608,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ callback, &data, &zErrMsg ); zShellStatic = 0; + }else{ + fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; } if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); @@ -2600,9 +2647,14 @@ static int do_meta_command(char *zLine, struct callback_data *p){ #endif #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; char *zErrMsg = 0; + if( nArg<2 ){ + fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n"); + rc = 1; + goto meta_command_exit; + } zFile = azArg[1]; zProc = nArg>=3 ? azArg[2] : 0; open_db(p, 0); @@ -2615,38 +2667,41 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else #endif - if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){ - const char *zFile = azArg[1]; - output_file_close(p->pLog); - p->pLog = output_file_open(zFile); + if( c=='l' && strncmp(azArg[0], "log", n)==0 ){ + if( nArg!=2 ){ + fprintf(stderr, "Usage: .log FILENAME\n"); + rc = 1; + }else{ + const char *zFile = azArg[1]; + output_file_close(p->pLog); + p->pLog = output_file_open(zFile); + } }else - if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){ - int n2 = strlen30(azArg[1]); - if( (n2==4 && strncmp(azArg[1],"line",n2)==0) - || - (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){ + if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){ + const char *zMode = nArg>=2 ? azArg[1] : ""; + int n2 = (int)strlen(zMode); + int c2 = zMode[0]; + if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){ p->mode = MODE_Line; - }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0) - || - (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){ + }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){ 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; - }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){ + }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ 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; 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; sqlite3_snprintf(sizeof(p->separator), p->separator, ","); - }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){ + }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ p->mode = MODE_List; 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; - set_table_name(p, "table"); + set_table_name(p, nArg>=3 ? azArg[2] : "table"); }else { fprintf(stderr,"Error: mode should be one of: " "column csv html insert line list tabs tcl\n"); @@ -2654,23 +2709,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){ - int n2 = strlen30(azArg[1]); - if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){ - p->mode = MODE_Insert; - set_table_name(p, azArg[2]); - }else { - fprintf(stderr, "Error: invalid arguments: " - " \"%s\". Enter \".help\" for help\n", azArg[2]); + if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ + if( nArg==2 ){ + sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, + "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); + }else{ + fprintf(stderr, "Usage: .nullvalue STRING\n"); rc = 1; } }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 ){ sqlite3 *savedDb = p->db; const char *zSavedFilename = p->zDbFilename; @@ -2691,32 +2739,45 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){ - if( p->outfile[0]=='|' ){ - pclose(p->out); + if( c=='o' + && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0) + ){ + 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{ - output_file_close(p->out); + p->outCount = 0; } - p->outfile[0] = 0; - if( azArg[1][0]=='|' ){ - p->out = popen(&azArg[1][1], "w"); + output_reset(p); + if( zFile[0]=='|' ){ + p->out = popen(zFile + 1, "w"); 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; rc = 1; }else{ - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); + sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } }else{ - p->out = output_file_open(azArg[1]); + p->out = output_file_open(zFile); if( p->out==0 ){ - if( strcmp(azArg[1],"off")!=0 ){ - fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]); + if( strcmp(zFile,"off")!=0 ){ + fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile); } p->out = stdout; rc = 1; } else { - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); + sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } }else @@ -2730,7 +2791,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(p->out, "\n"); }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) { strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); } @@ -2739,12 +2800,18 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){ + if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ rc = 2; }else - if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){ - FILE *alt = fopen(azArg[1], "rb"); + if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ + 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 ){ fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; @@ -2754,7 +2821,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }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 *zDb; sqlite3 *pSrc; @@ -2764,9 +2831,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( nArg==2 ){ zSrcFile = azArg[1]; zDb = "main"; - }else{ + }else if( nArg==3 ){ zSrcFile = azArg[2]; zDb = azArg[1]; + }else{ + fprintf(stderr, "Usage: .restore ?DB? FILE\n"); + rc = 1; + goto meta_command_exit; } rc = sqlite3_open(zSrcFile, &pSrc); if( rc!=SQLITE_OK ){ @@ -2801,14 +2872,14 @@ static int do_meta_command(char *zLine, struct callback_data *p){ sqlite3_close(pSrc); }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; char *zErrMsg = 0; open_db(p, 0); memcpy(&data, p, sizeof(data)); data.showHeader = 0; data.mode = MODE_Semi; - if( nArg>1 ){ + if( nArg==2 ){ int i; for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); if( strcmp(azArg[1],"sqlite_master")==0 ){ @@ -2852,7 +2923,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ callback, &data, &zErrMsg); zShellStatic = 0; } - }else{ + }else if( nArg==1 ){ rc = sqlite3_exec(p->db, "SELECT sql FROM " " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" @@ -2862,6 +2933,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ "ORDER BY rowid", callback, &data, &zErrMsg ); + }else{ + fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n"); + rc = 1; + goto meta_command_exit; } if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); @@ -2891,24 +2966,33 @@ static int do_meta_command(char *zLine, struct callback_data *p){ for(i=1; iout, "%s", zBuf); } } }else #endif - if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){ - sqlite3_snprintf(sizeof(p->separator), p->separator, - "%.*s", (int)sizeof(p->separator)-1, azArg[1]); + if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ + if( nArg==2 ){ + sqlite3_snprintf(sizeof(p->separator), p->separator, + "%.*s", (int)sizeof(p->separator)-1, azArg[1]); + }else{ + fprintf(stderr, "Usage: .separator STRING\n"); + rc = 1; + } }else if( c=='s' && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) - && nArg>=2 ){ char *zCmd; int i; + 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; iout,"%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","explain", p->explainPrev.valid ? "on" :"off"); @@ -2941,11 +3030,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(p->out,"\n"); }else - if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){ - p->statsOn = booleanValue(azArg[1]); + if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ + if( nArg==2 ){ + p->statsOn = booleanValue(azArg[1]); + }else{ + fprintf(stderr, "Usage: .stats on|off\n"); + rc = 1; + } }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; char **azResult; int nRow, nAlloc; @@ -3151,20 +3245,32 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }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); - sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1])); + sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); }else - if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 - && nArg==2 - ){ - enableTimer = booleanValue(azArg[1]); + if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){ + if( nArg==2 ){ + 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 - if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){ + if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ open_db(p, 0); 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]); #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) if( p->traceOut==0 ){ @@ -3195,11 +3301,11 @@ static int do_meta_command(char *zLine, struct callback_data *p){ #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ extern int sqlite3WhereTrace; - sqlite3WhereTrace = booleanValue(azArg[1]); + sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; }else #endif - if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ + if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ int j; assert( nArg<=ArraySize(azArg) ); for(j=1; jcolWidth); j++){ @@ -3213,6 +3319,11 @@ static int do_meta_command(char *zLine, struct callback_data *p){ rc = 1; } +meta_command_exit: + if( p->outCount ){ + p->outCount--; + if( p->outCount==0 ) output_reset(p); + } return rc; } @@ -3380,6 +3491,10 @@ static int process_input(struct callback_data *p, FILE *in){ errCnt++; } nSql = 0; + if( p->outCount ){ + output_reset(p); + p->outCount = 0; + } }else if( nSql && _all_whitespace(zSql) ){ if( p->echoOn ) printf("%s\n", zSql); nSql = 0; diff --git a/test/shell1.test b/test/shell1.test index 6ea4f4a82c..e6fb0c28d2 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -268,7 +268,7 @@ do_test shell1-3.1.4 { # .bail ON|OFF Stop after hitting an error. Default OFF do_test shell1-3.2.1 { catchcmd "test.db" ".bail" -} {1 {Error: unknown command or invalid arguments: "bail". Enter ".help" for help}} +} {1 {Usage: .bail on|off}} do_test shell1-3.2.2 { catchcmd "test.db" ".bail ON" } {0 {}} @@ -278,16 +278,16 @@ do_test shell1-3.2.3 { do_test shell1-3.2.4 { # too many arguments catchcmd "test.db" ".bail OFF BAD" -} {1 {Error: unknown command or invalid arguments: "bail". Enter ".help" for help}} +} {1 {Usage: .bail on|off}} # .databases List names and files of attached databases do_test shell1-3.3.1 { catchcmd "-csv test.db" ".databases" } "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/" do_test shell1-3.3.2 { - # too many arguments + # extra arguments ignored catchcmd "test.db" ".databases BAD" -} {1 {Error: unknown command or invalid arguments: "databases". Enter ".help" for help}} +} "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/" # .dump ?TABLE? ... Dump the database in an SQL text format # If TABLE specified, only dump tables matching @@ -305,12 +305,12 @@ do_test shell1-3.4.2 { do_test shell1-3.4.3 { # too many arguments catchcmd "test.db" ".dump FOO BAD" -} {1 {Error: unknown command or invalid arguments: "dump". Enter ".help" for help}} +} {1 {Usage: .dump ?LIKE-PATTERN?}} # .echo ON|OFF Turn command echo on or off do_test shell1-3.5.1 { catchcmd "test.db" ".echo" -} {1 {Error: unknown command or invalid arguments: "echo". Enter ".help" for help}} +} {1 {Usage: .echo on|off}} do_test shell1-3.5.2 { catchcmd "test.db" ".echo ON" } {0 {}} @@ -320,7 +320,7 @@ do_test shell1-3.5.3 { do_test shell1-3.5.4 { # too many arguments catchcmd "test.db" ".echo OFF BAD" -} {1 {Error: unknown command or invalid arguments: "echo". Enter ".help" for help}} +} {1 {Usage: .echo on|off}} # .exit Exit this program do_test shell1-3.6.1 { @@ -339,15 +339,15 @@ do_test shell1-3.7.3 { catchcmd "test.db" ".explain OFF" } {0 {}} do_test shell1-3.7.4 { - # too many arguments + # extra arguments ignored catchcmd "test.db" ".explain OFF BAD" -} {1 {Error: unknown command or invalid arguments: "explain". Enter ".help" for help}} +} {0 {}} # .header(s) ON|OFF Turn display of headers on or off do_test shell1-3.9.1 { catchcmd "test.db" ".header" -} {1 {Error: unknown command or invalid arguments: "header". Enter ".help" for help}} +} {1 {Usage: .headers on|off}} do_test shell1-3.9.2 { catchcmd "test.db" ".header ON" } {0 {}} @@ -357,11 +357,11 @@ do_test shell1-3.9.3 { do_test shell1-3.9.4 { # too many arguments catchcmd "test.db" ".header OFF BAD" -} {1 {Error: unknown command or invalid arguments: "header". Enter ".help" for help}} +} {1 {Usage: .headers on|off}} do_test shell1-3.9.5 { catchcmd "test.db" ".headers" -} {1 {Error: unknown command or invalid arguments: "headers". Enter ".help" for help}} +} {1 {Usage: .headers on|off}} do_test shell1-3.9.6 { catchcmd "test.db" ".headers ON" } {0 {}} @@ -371,7 +371,7 @@ do_test shell1-3.9.7 { do_test shell1-3.9.8 { # too many arguments catchcmd "test.db" ".headers OFF BAD" -} {1 {Error: unknown command or invalid arguments: "headers". Enter ".help" for help}} +} {1 {Usage: .headers on|off}} # .help Show this message do_test shell1-3.10.1 { @@ -393,17 +393,17 @@ do_test shell1-3.10.2 { # .import FILE TABLE Import data from FILE into TABLE do_test shell1-3.11.1 { catchcmd "test.db" ".import" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} do_test shell1-3.11.2 { catchcmd "test.db" ".import FOO" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} #do_test shell1-3.11.2 { # catchcmd "test.db" ".import FOO BAR" #} {1 {Error: no such table: BAR}} do_test shell1-3.11.3 { # too many arguments catchcmd "test.db" ".import FOO BAR BAD" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} # .indices ?TABLE? Show names of all indices # If TABLE specified, only show indices for tables @@ -417,7 +417,7 @@ do_test shell1-3.12.2 { do_test shell1-3.12.3 { # too many arguments catchcmd "test.db" ".indices FOO BAD" -} {1 {Error: unknown command or invalid arguments: "indices". Enter ".help" for help}} +} {1 {Usage: .indices ?LIKE-PATTERN?}} # .mode MODE ?TABLE? Set output mode where MODE is one of: # csv Comma-separated values @@ -430,7 +430,7 @@ do_test shell1-3.12.3 { # tcl TCL list elements do_test shell1-3.13.1 { catchcmd "test.db" ".mode" -} {1 {Error: unknown command or invalid arguments: "mode". Enter ".help" for help}} +} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} do_test shell1-3.13.2 { catchcmd "test.db" ".mode FOO" } {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} @@ -459,9 +459,9 @@ do_test shell1-3.13.10 { catchcmd "test.db" ".mode tcl" } {0 {}} do_test shell1-3.13.11 { - # too many arguments + # extra arguments ignored catchcmd "test.db" ".mode tcl BAD" -} {1 {Error: invalid arguments: "BAD". Enter ".help" for help}} +} {0 {}} # don't allow partial mode type matches do_test shell1-3.13.12 { @@ -472,31 +472,31 @@ do_test shell1-3.13.13 { } {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} do_test shell1-3.13.14 { catchcmd "test.db" ".mode lin" -} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} +} {0 {}} # .nullvalue STRING Print STRING in place of NULL values do_test shell1-3.14.1 { catchcmd "test.db" ".nullvalue" -} {1 {Error: unknown command or invalid arguments: "nullvalue". Enter ".help" for help}} +} {1 {Usage: .nullvalue STRING}} do_test shell1-3.14.2 { catchcmd "test.db" ".nullvalue FOO" } {0 {}} do_test shell1-3.14.3 { # too many arguments catchcmd "test.db" ".nullvalue FOO BAD" -} {1 {Error: unknown command or invalid arguments: "nullvalue". Enter ".help" for help}} +} {1 {Usage: .nullvalue STRING}} # .output FILENAME Send output to FILENAME do_test shell1-3.15.1 { catchcmd "test.db" ".output" -} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}} +} {0 {}} do_test shell1-3.15.2 { catchcmd "test.db" ".output FOO" } {0 {}} do_test shell1-3.15.3 { # too many arguments catchcmd "test.db" ".output FOO BAD" -} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}} +} {1 {Usage: .output FILE}} # .output stdout Send output to the screen do_test shell1-3.16.1 { @@ -505,12 +505,12 @@ do_test shell1-3.16.1 { do_test shell1-3.16.2 { # too many arguments catchcmd "test.db" ".output stdout BAD" -} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}} +} {1 {Usage: .output FILE}} # .prompt MAIN CONTINUE Replace the standard prompts do_test shell1-3.17.1 { catchcmd "test.db" ".prompt" -} {1 {Error: unknown command or invalid arguments: "prompt". Enter ".help" for help}} +} {0 {}} do_test shell1-3.17.2 { catchcmd "test.db" ".prompt FOO" } {0 {}} @@ -520,7 +520,7 @@ do_test shell1-3.17.3 { do_test shell1-3.17.4 { # too many arguments catchcmd "test.db" ".prompt FOO BAR BAD" -} {1 {Error: unknown command or invalid arguments: "prompt". Enter ".help" for help}} +} {0 {}} # .quit Exit this program do_test shell1-3.18.1 { @@ -529,12 +529,12 @@ do_test shell1-3.18.1 { do_test shell1-3.18.2 { # too many arguments catchcmd "test.db" ".quit BAD" -} {1 {Error: unknown command or invalid arguments: "quit". Enter ".help" for help}} +} {0 {}} # .read FILENAME Execute SQL in FILENAME do_test shell1-3.19.1 { catchcmd "test.db" ".read" -} {1 {Error: unknown command or invalid arguments: "read". Enter ".help" for help}} +} {1 {Usage: .read FILE}} do_test shell1-3.19.2 { forcedelete FOO catchcmd "test.db" ".read FOO" @@ -542,12 +542,12 @@ do_test shell1-3.19.2 { do_test shell1-3.19.3 { # too many arguments catchcmd "test.db" ".read FOO BAD" -} {1 {Error: unknown command or invalid arguments: "read". Enter ".help" for help}} +} {1 {Usage: .read FILE}} # .restore ?DB? FILE Restore content of DB (default "main") from FILE do_test shell1-3.20.1 { catchcmd "test.db" ".restore" -} {1 {Error: unknown command or invalid arguments: "restore". Enter ".help" for help}} +} {1 {Usage: .restore ?DB? FILE}} do_test shell1-3.20.2 { catchcmd "test.db" ".restore FOO" } {0 {}} @@ -557,7 +557,7 @@ do_test shell1-3.20.3 { do_test shell1-3.20.4 { # too many arguments catchcmd "test.db" ".restore FOO BAR BAD" -} {1 {Error: unknown command or invalid arguments: "restore". Enter ".help" for help}} +} {1 {Usage: .restore ?DB? FILE}} # .schema ?TABLE? Show the CREATE statements # If TABLE specified, only show tables matching @@ -571,7 +571,7 @@ do_test shell1-3.21.2 { do_test shell1-3.21.3 { # too many arguments catchcmd "test.db" ".schema FOO BAD" -} {1 {Error: unknown command or invalid arguments: "schema". Enter ".help" for help}} +} {1 {Usage: .schema ?LIKE-PATTERN?}} do_test shell1-3.21.4 { catchcmd "test.db" { @@ -588,14 +588,14 @@ db eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;} # .separator STRING Change separator used by output mode and .import do_test shell1-3.22.1 { catchcmd "test.db" ".separator" -} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} +} {1 {Usage: .separator STRING}} do_test shell1-3.22.2 { catchcmd "test.db" ".separator FOO" } {0 {}} do_test shell1-3.22.3 { # too many arguments catchcmd "test.db" ".separator FOO BAD" -} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} +} {1 {Usage: .separator STRING}} # .show Show the current values for various settings do_test shell1-3.23.1 { @@ -613,12 +613,12 @@ do_test shell1-3.23.1 { do_test shell1-3.23.2 { # too many arguments catchcmd "test.db" ".show BAD" -} {1 {Error: unknown command or invalid arguments: "show". Enter ".help" for help}} +} {1 {Usage: .show}} # .stats ON|OFF Turn stats on or off do_test shell1-3.23b.1 { catchcmd "test.db" ".stats" -} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}} +} {1 {Usage: .stats on|off}} do_test shell1-3.23b.2 { catchcmd "test.db" ".stats ON" } {0 {}} @@ -628,7 +628,7 @@ do_test shell1-3.23b.3 { do_test shell1-3.23b.4 { # too many arguments catchcmd "test.db" ".stats OFF BAD" -} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}} +} {1 {Usage: .stats on|off}} # .tables ?TABLE? List names of tables # If TABLE specified, only list tables matching @@ -642,12 +642,12 @@ do_test shell1-3.24.2 { do_test shell1-3.24.3 { # too many arguments catchcmd "test.db" ".tables FOO BAD" -} {1 {Error: unknown command or invalid arguments: "tables". Enter ".help" for help}} +} {0 {}} # .timeout MS Try opening locked tables for MS milliseconds do_test shell1-3.25.1 { catchcmd "test.db" ".timeout" -} {1 {Error: unknown command or invalid arguments: "timeout". Enter ".help" for help}} +} {0 {}} do_test shell1-3.25.2 { catchcmd "test.db" ".timeout zzz" # this should be treated the same as a '0' timeout @@ -658,12 +658,12 @@ do_test shell1-3.25.3 { do_test shell1-3.25.4 { # too many arguments catchcmd "test.db" ".timeout 1 BAD" -} {1 {Error: unknown command or invalid arguments: "timeout". Enter ".help" for help}} +} {0 {}} # .width NUM NUM ... Set column widths for "column" mode do_test shell1-3.26.1 { catchcmd "test.db" ".width" -} {1 {Error: unknown command or invalid arguments: "width". Enter ".help" for help}} +} {0 {}} do_test shell1-3.26.2 { catchcmd "test.db" ".width xxx" # this should be treated the same as a '0' width for col 1 @@ -689,7 +689,7 @@ do_test shell1-3.26.6 { # .timer ON|OFF Turn the CPU timer measurement on or off do_test shell1-3.27.1 { catchcmd "test.db" ".timer" -} {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}} +} {1 {Usage: .timer on|off}} do_test shell1-3.27.2 { catchcmd "test.db" ".timer ON" } {0 {}} @@ -699,7 +699,7 @@ do_test shell1-3.27.3 { do_test shell1-3.27.4 { # too many arguments catchcmd "test.db" ".timer OFF BAD" -} {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}} +} {1 {Usage: .timer on|off}} do_test shell1-3-28.1 { catchcmd test.db \ diff --git a/test/shell4.test b/test/shell4.test index 5af44c8fd7..c29faf00cf 100644 --- a/test/shell4.test +++ b/test/shell4.test @@ -63,7 +63,7 @@ do_test shell4-1.2.2 { # .stats ON|OFF Turn stats on or off do_test shell4-1.3.1 { catchcmd "test.db" ".stats" -} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}} +} {1 {Usage: .stats on|off}} do_test shell4-1.3.2 { catchcmd "test.db" ".stats ON" } {0 {}} @@ -73,7 +73,7 @@ do_test shell4-1.3.3 { do_test shell4-1.3.4 { # too many arguments catchcmd "test.db" ".stats OFF BAD" -} {1 {Error: unknown command or invalid arguments: "stats". Enter ".help" for help}} +} {1 {Usage: .stats on|off}} # NB. whitespace is important do_test shell4-1.4.1 { diff --git a/test/shell5.test b/test/shell5.test index a14c84a48c..734833f6fc 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -40,29 +40,29 @@ forcedelete test.db test.db-journal test.db-wal # .import FILE TABLE Import data from FILE into TABLE do_test shell5-1.1.1 { catchcmd "test.db" ".import" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} do_test shell5-1.1.2 { catchcmd "test.db" ".import FOO" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} #do_test shell5-1.1.2 { # catchcmd "test.db" ".import FOO BAR" #} {1 {Error: no such table: BAR}} do_test shell5-1.1.3 { # too many arguments catchcmd "test.db" ".import FOO BAR BAD" -} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} +} {1 {Usage: .import FILE TABLE}} # .separator STRING Change separator used by output mode and .import -do_test shell1-1.2.1 { +do_test shell5-1.2.1 { catchcmd "test.db" ".separator" -} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} -do_test shell1-1.2.2 { +} {1 {Usage: .separator STRING}} +do_test shell5-1.2.2 { catchcmd "test.db" ".separator FOO" } {0 {}} -do_test shell1-1.2.3 { +do_test shell5-1.2.3 { # too many arguments catchcmd "test.db" ".separator FOO BAD" -} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} +} {1 {Usage: .separator STRING}} # separator should default to "|" do_test shell5-1.3.1 {