1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-06 15:49:35 +03:00

Improved shell "dot" command argument handling. Ticket [f12a9eeedc].

FossilOrigin-Name: 9fb699193378bf812ef97889adc0b1a98ad56d5b
This commit is contained in:
shaneh
2009-11-06 17:20:17 +00:00
parent 3313b14f46
commit e2aa9d7192
4 changed files with 345 additions and 133 deletions

View File

@@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE----- C Improved\sshell\s"dot"\scommand\sargument\shandling.\s\sTicket\s[f12a9eeedc].
Hash: SHA1 D 2009-11-06T17:20:17
C Fix\sthe\sbackup\sAPI\sso\sthat\sa\sbackup\sfrom\san\sempty\sdatabase\sto\sa\snon-empty\ndatabase\sworks.\s\sTicket\s[0bf974bdf9].\s\sThe\sonly\schanges\sare\sin\sassert()\nstatements.
D 2009-11-06T04:13:18
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in a77dfde96ad86aafd3f71651a4333a104debe86a F Makefile.in a77dfde96ad86aafd3f71651a4333a104debe86a
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -164,7 +161,7 @@ F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
F src/resolve.c f263d685bf21d0707b595455e0a0c95a3f5398f6 F src/resolve.c f263d685bf21d0707b595455e0a0c95a3f5398f6
F src/rowset.c c64dafba1f9fd876836c8db8682966b9d197eb1f F src/rowset.c c64dafba1f9fd876836c8db8682966b9d197eb1f
F src/select.c cbe366a0ce114856e66f5daf0f848d7c48a88298 F src/select.c cbe366a0ce114856e66f5daf0f848d7c48a88298
F src/shell.c f66531a57fff927f95c98d99c28237d88e400c86 F src/shell.c 07e6265ead0dc517c242276949d5a262ca8a87a7
F src/sqlite.h.in 4464e9772122f0447305d425e04d122b6f1bffec F src/sqlite.h.in 4464e9772122f0447305d425e04d122b6f1bffec
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h 55d26b83d16107804693982028c8b3a075f5a836 F src/sqliteInt.h 55d26b83d16107804693982028c8b3a075f5a836
@@ -753,7 +750,7 @@ F tool/mksqlite3h.tcl eb100dce83f24b501b325b340f8b5eb8e5106b3b
F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87 F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/shell1.test 404512b1c3f839e97e42666120346d267b5c5b47 F tool/shell1.test 71fa122a37cfd8a4de39e7b53012aae3b1511096
F tool/showdb.c 8ab8b3b53884312aafb7ef60982e255a6c31d238 F tool/showdb.c 8ab8b3b53884312aafb7ef60982e255a6c31d238
F tool/showjournal.c ec3b171be148656827c4949fbfb8ab4370822f87 F tool/showjournal.c ec3b171be148656827c4949fbfb8ab4370822f87
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
@@ -765,14 +762,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P d410cd4e42ecf50a849f49cf3395ec169350e7cf P ddb71cd9ed395804a13dc136bb7688a7627c798f
R b6fd4922d8c93defdc16b7c4fc43d34c R c0a38f994aec3b7175756a6deebcbc05
U drh U shaneh
Z c58c667f47a419949ef32e3c3c6a33b9 Z 41814e7c3b68e673756d4c35a2fa402a
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFK86JioxKgR168RlERArjsAJ4iUjlJBvgOkG5Q0ykoZ9HOp9lYXwCfXOv9
56uC4JRhdJF56nAXOwquqLE=
=qYH+
-----END PGP SIGNATURE-----

View File

@@ -1 +1 @@
ddb71cd9ed395804a13dc136bb7688a7627c798f 9fb699193378bf812ef97889adc0b1a98ad56d5b

View File

@@ -2140,7 +2140,8 @@ static char zHelp[] =
" 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"
".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"
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY) #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY)
".genfkey ?OPTIONS? Options are:\n" ".genfkey ?OPTIONS? Options are:\n"
" --no-drop: Do not drop old fkey triggers.\n" " --no-drop: Do not drop old fkey triggers.\n"
@@ -2186,7 +2187,7 @@ static char zHelp[] =
" 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"
".width NUM NUM ... Set column widths for \"column\" mode\n" ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
; ;
static char zTimerHelp[] = static char zTimerHelp[] =
@@ -2313,7 +2314,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( nArg==0 ) return 0; /* no tokens, no error */ if( nArg==0 ) return 0; /* no tokens, no error */
n = strlen30(azArg[0]); n = strlen30(azArg[0]);
c = azArg[0][0]; c = azArg[0][0];
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){ if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
const char *zDestFile; const char *zDestFile;
const char *zDb; const char *zDb;
sqlite3 *pDest; sqlite3 *pDest;
@@ -2349,11 +2350,11 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite3_close(pDest); sqlite3_close(pDest);
}else }else
if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){ if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
bail_on_error = booleanValue(azArg[1]); bail_on_error = booleanValue(azArg[1]);
}else }else
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
struct callback_data data; struct callback_data data;
char *zErrMsg = 0; char *zErrMsg = 0;
open_db(p); open_db(p);
@@ -2372,7 +2373,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
} }
}else }else
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
char *zErrMsg = 0; char *zErrMsg = 0;
open_db(p); open_db(p);
/* When playing back a "dump", the content might appear in an order /* When playing back a "dump", the content might appear in an order
@@ -2425,15 +2426,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){
} }
}else }else
if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){ if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
p->echoOn = booleanValue(azArg[1]); p->echoOn = booleanValue(azArg[1]);
}else }else
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
rc = 2; rc = 2;
}else }else
if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
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) {
@@ -2480,7 +2481,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
#endif #endif
if( c=='h' && (strncmp(azArg[0], "header", n)==0 || if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){ strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
p->showHeader = booleanValue(azArg[1]); p->showHeader = booleanValue(azArg[1]);
}else }else
@@ -2491,7 +2492,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
} }
}else }else
if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){ if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
char *zTable = azArg[2]; /* Insert data into this table */ char *zTable = azArg[2]; /* Insert data into this table */
char *zFile = azArg[1]; /* The file from which to extract data */ char *zFile = azArg[1]; /* The file from which to extract data */
sqlite3_stmt *pStmt = NULL; /* A statement */ sqlite3_stmt *pStmt = NULL; /* A statement */
@@ -2608,7 +2609,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite3_exec(p->db, zCommit, 0, 0, 0); sqlite3_exec(p->db, zCommit, 0, 0, 0);
}else }else
if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
struct callback_data data; struct callback_data data;
char *zErrMsg = 0; char *zErrMsg = 0;
open_db(p); open_db(p);
@@ -2687,35 +2688,31 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else }else
#endif #endif
if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){ if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
int n2 = strlen30(azArg[1]); int n2 = strlen30(azArg[1]);
if( strncmp(azArg[1],"line",n2)==0 if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
|| ||
strncmp(azArg[1],"lines",n2)==0 ){ (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
p->mode = MODE_Line; p->mode = MODE_Line;
}else if( strncmp(azArg[1],"column",n2)==0 }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
|| ||
strncmp(azArg[1],"columns",n2)==0 ){ (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
p->mode = MODE_Column; p->mode = MODE_Column;
}else if( strncmp(azArg[1],"list",n2)==0 ){ }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
p->mode = MODE_List; p->mode = MODE_List;
}else if( strncmp(azArg[1],"html",n2)==0 ){ }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
p->mode = MODE_Html; p->mode = MODE_Html;
}else if( strncmp(azArg[1],"tcl",n2)==0 ){ }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
p->mode = MODE_Tcl; p->mode = MODE_Tcl;
}else if( strncmp(azArg[1],"csv",n2)==0 ){ }else if( n2==3 && 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( strncmp(azArg[1],"tabs",n2)==0 ){ }else if( n2==4 && 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( strncmp(azArg[1],"insert",n2)==0 ){ }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
p->mode = MODE_Insert; p->mode = MODE_Insert;
if( nArg>=3 ){ set_table_name(p, "table");
set_table_name(p, azArg[2]);
}else{
set_table_name(p, "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");
@@ -2723,6 +2720,18 @@ static int do_meta_command(char *zLine, struct callback_data *p){
} }
}else }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]);
rc = 1;
}
}else
if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) { if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
"%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
@@ -2756,7 +2765,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
} }
}else }else
if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
rc = 2; rc = 2;
}else }else
@@ -2771,7 +2780,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
} }
}else }else
if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){ if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
const char *zSrcFile; const char *zSrcFile;
const char *zDb; const char *zDb;
sqlite3 *pSrc; sqlite3 *pSrc;
@@ -2818,7 +2827,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite3_close(pSrc); sqlite3_close(pSrc);
}else }else
if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
struct callback_data data; struct callback_data data;
char *zErrMsg = 0; char *zErrMsg = 0;
open_db(p); open_db(p);
@@ -2896,7 +2905,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
"%.*s", (int)sizeof(p->separator)-1, azArg[1]); "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
}else }else
if( c=='s' && strncmp(azArg[0], "show", n)==0){ if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
int i; int i;
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","explain", p->explainPrev.valid ? "on" :"off"); fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
@@ -2917,7 +2926,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
fprintf(p->out,"\n"); fprintf(p->out,"\n");
}else }else
if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){ if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
char **azResult; char **azResult;
int nRow; int nRow;
char *zErrMsg; char *zErrMsg;
@@ -2975,12 +2984,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite3_free_table(azResult); sqlite3_free_table(azResult);
}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 && nArg==2 ){
open_db(p); open_db(p);
sqlite3_busy_timeout(p->db, atoi(azArg[1])); sqlite3_busy_timeout(p->db, atoi(azArg[1]));
}else if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){ }else
if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){
enableTimer = booleanValue(azArg[1]); enableTimer = booleanValue(azArg[1]);
}else if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ }else
if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
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++){

View File

@@ -16,7 +16,8 @@
# Test plan: # Test plan:
# #
# shell-1.*: Basic test that command can be called. # shell-1.*: Basic "dot" command token parsing.
# shell-2.*: Basic test that "dot" command can be called.
# #
package require sqlite3 package require sqlite3
@@ -30,6 +31,7 @@ proc do_test {name cmd expected} {
puts Error puts Error
puts " Got: $res" puts " Got: $res"
puts " Expected: $expected" puts " Expected: $expected"
exit
} }
} }
@@ -46,78 +48,186 @@ proc catchcmd {cmd} {
set out [open cmds.txt w] set out [open cmds.txt w]
puts $out $cmd puts $out $cmd
close $out close $out
set rc [catch { exec ./sqlite3 test.db < cmds.txt } msg] set rc [catch { exec ./sqlite test.db < cmds.txt } msg]
list $rc $msg list $rc $msg
} }
file delete -force test.db test.db.journal file delete -force test.db test.db.journal
sqlite3 db test.db sqlite3 db test.db
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Test cases shell-1.* Basic test that command can be called. # Test cases shell-1.* Basic "dot" command token parsing.
#
# check first token handling
do_test shell-1.1.1 {
catchcmd ".foo"
} {1 {Error: unknown command or invalid arguments: "foo". Enter ".help" for help}}
do_test shell-1.1.2 {
catchcmd ".\"foo OFF\""
} {1 {Error: unknown command or invalid arguments: "foo OFF". Enter ".help" for help}}
do_test shell-1.1.3 {
catchcmd ".\'foo OFF\'"
} {1 {Error: unknown command or invalid arguments: "foo OFF". Enter ".help" for help}}
# unbalanced quotes
do_test shell-1.2.1 {
catchcmd ".\"foo OFF"
} {1 {Error: unknown command or invalid arguments: "foo OFF". Enter ".help" for help}}
do_test shell-1.2.2 {
catchcmd ".\'foo OFF"
} {1 {Error: unknown command or invalid arguments: "foo OFF". Enter ".help" for help}}
do_test shell-1.2.3 {
catchcmd ".explain \"OFF"
} {0 {}}
do_test shell-1.2.4 {
catchcmd ".explain \'OFF"
} {0 {}}
do_test shell-1.2.5 {
catchcmd ".mode \"insert FOO"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell-1.2.6 {
catchcmd ".mode \'insert FOO"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
# check multiple tokens, and quoted tokens
do_test shell-1.3.1 {
catchcmd ".explain 1"
} {0 {}}
do_test shell-1.3.2 {
catchcmd ".explain on"
} {0 {}}
do_test shell-1.3.3 {
catchcmd ".explain \"1 2 3\""
} {0 {}}
do_test shell-1.3.4 {
catchcmd ".explain \"OFF\""
} {0 {}}
do_test shell-1.3.5 {
catchcmd ".\'explain\' \'OFF\'"
} {0 {}}
do_test shell-1.3.6 {
catchcmd ".explain \'OFF\'"
} {0 {}}
do_test shell-1.3.7 {
catchcmd ".\'explain\' \'OFF\'"
} {0 {}}
# check quoted args are unquoted
do_test shell-1.4.1 {
catchcmd ".mode FOO"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell-1.4.2 {
catchcmd ".mode csv"
} {0 {}}
do_test shell-1.4.2 {
catchcmd ".mode \"csv\""
} {0 {}}
#----------------------------------------------------------------------------
# Test cases shell-2.* Basic test that "dot" command can be called.
# #
# .backup ?DB? FILE Backup DB (default "main") to FILE # .backup ?DB? FILE Backup DB (default "main") to FILE
do_test shell-1.1.1 { do_test shell-2.1.1 {
catchcmd ".backup"
} {1 {Error: unknown command or invalid arguments: "backup". Enter ".help" for help}}
do_test shell-2.1.2 {
# catchcmd ".backup FOO"
#TBD!!! this asserts currently
} {} } {}
do_test shell-2.1.3 {
catchcmd ".backup FOO BAR"
} {1 {Error: unknown database FOO}}
do_test shell-2.1.4 {
# too many arguments
catchcmd ".backup FOO BAR BAD"
} {1 {Error: unknown command or invalid arguments: "backup". Enter ".help" for help}}
# .bail ON|OFF Stop after hitting an error. Default OFF # .bail ON|OFF Stop after hitting an error. Default OFF
do_test shell-1.2.1 { do_test shell-2.2.1 {
catchcmd ".bail" catchcmd ".bail"
} {1 {Error: unknown command or invalid arguments: "bail". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "bail". Enter ".help" for help}}
do_test shell-1.2.2 { do_test shell-2.2.2 {
catchcmd ".bail ON" catchcmd ".bail ON"
} {0 {}} } {0 {}}
do_test shell-1.2.3 { do_test shell-2.2.3 {
catchcmd ".bail OFF" catchcmd ".bail OFF"
} {0 {}} } {0 {}}
do_test shell-2.2.4 {
# too many arguments
catchcmd ".bail OFF BAD"
} {1 {Error: unknown command or invalid arguments: "bail". Enter ".help" for help}}
# .databases List names and files of attached databases # .databases List names and files of attached databases
do_test shell-1.3.1 { do_test shell-2.3.1 {
set res [catchcmd ".databases"] set res [catchcmd ".databases"]
regexp {0.*main.*test\.db} $res regexp {0.*main.*test\.db} $res
} {1} } {1}
do_test shell-2.3.2 {
# too many arguments
catchcmd ".databases BAD"
} {1 {Error: unknown command or invalid arguments: "databases". Enter ".help" for help}}
# .dump ?TABLE? ... Dump the database in an SQL text format # .dump ?TABLE? ... Dump the database in an SQL text format
# If TABLE specified, only dump tables matching # If TABLE specified, only dump tables matching
# LIKE pattern TABLE. # LIKE pattern TABLE.
do_test shell-1.4.1 { do_test shell-2.4.1 {
set res [catchcmd ".dump"] set res [catchcmd ".dump"]
list [regexp {BEGIN TRANSACTION;} $res] \ list [regexp {BEGIN TRANSACTION;} $res] \
[regexp {COMMIT;} $res] [regexp {COMMIT;} $res]
} {1 1} } {1 1}
do_test shell-1.4.2 { do_test shell-2.4.2 {
set res [catchcmd ".dump FOO"] set res [catchcmd ".dump FOO"]
list [regexp {BEGIN TRANSACTION;} $res] \ list [regexp {BEGIN TRANSACTION;} $res] \
[regexp {COMMIT;} $res] [regexp {COMMIT;} $res]
} {1 1} } {1 1}
do_test shell-2.4.3 {
# too many arguments
catchcmd ".dump FOO BAD"
} {1 {Error: unknown command or invalid arguments: "dump". Enter ".help" for help}}
# .echo ON|OFF Turn command echo on or off # .echo ON|OFF Turn command echo on or off
do_test shell-1.5.1 { do_test shell-2.5.1 {
catchcmd ".echo" catchcmd ".echo"
} {1 {Error: unknown command or invalid arguments: "echo". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "echo". Enter ".help" for help}}
do_test shell-1.5.2 { do_test shell-2.5.2 {
catchcmd ".echo ON" catchcmd ".echo ON"
} {0 {}} } {0 {}}
do_test shell-1.5.3 { do_test shell-2.5.3 {
catchcmd ".echo OFF" catchcmd ".echo OFF"
} {0 {}} } {0 {}}
do_test shell-2.5.4 {
# too many arguments
catchcmd ".echo OFF BAD"
} {1 {Error: unknown command or invalid arguments: "echo". Enter ".help" for help}}
# .exit Exit this program # .exit Exit this program
do_test shell-1.6.1 { do_test shell-2.6.1 {
catchcmd ".exit" catchcmd ".exit"
} {0 {}} } {0 {}}
do_test shell-2.6.2 {
# too many arguments
catchcmd ".exit BAD"
} {1 {Error: unknown command or invalid arguments: "exit". Enter ".help" for help}}
# .explain ON|OFF Turn output mode suitable for EXPLAIN on or off. # .explain ON|OFF Turn output mode suitable for EXPLAIN on or off.
do_test shell-1.7.1 { do_test shell-2.7.1 {
catchcmd ".echo" catchcmd ".explain"
} {1 {Error: unknown command or invalid arguments: "echo". Enter ".help" for help}} # explain is the exception to the booleans. without an option, it turns it on.
do_test shell-1.7.2 { } {0 {}}
do_test shell-2.7.2 {
catchcmd ".explain ON" catchcmd ".explain ON"
} {0 {}} } {0 {}}
do_test shell-1.7.3 { do_test shell-2.7.3 {
catchcmd ".explain OFF" catchcmd ".explain OFF"
} {0 {}} } {0 {}}
do_test shell-2.7.4 {
# too many arguments
catchcmd ".explain OFF BAD"
} {1 {Error: unknown command or invalid arguments: "explain". Enter ".help" for help}}
# .genfkey ?OPTIONS? Options are: # .genfkey ?OPTIONS? Options are:
# --no-drop: Do not drop old fkey triggers. # --no-drop: Do not drop old fkey triggers.
@@ -125,58 +235,87 @@ do_test shell-1.7.3 {
# --exec: Execute generated SQL immediately # --exec: Execute generated SQL immediately
# See file tool/genfkey.README in the source # See file tool/genfkey.README in the source
# distribution for further information. # distribution for further information.
do_test shell-1.8.1 { do_test shell-2.8.1 {
} {} catchcmd ".genfkey"
} {0 {}}
do_test shell-2.8.2 {
catchcmd ".genfkey FOO"
} {1 {unknown option: FOO}}
# .header(s) ON|OFF Turn display of headers on or off # .header(s) ON|OFF Turn display of headers on or off
do_test shell-1.9.1 { do_test shell-2.9.1 {
catchcmd ".header" catchcmd ".header"
} {1 {Error: unknown command or invalid arguments: "header". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "header". Enter ".help" for help}}
do_test shell-1.9.2 { do_test shell-2.9.2 {
catchcmd ".header ON" catchcmd ".header ON"
} {0 {}} } {0 {}}
do_test shell-1.9.3 { do_test shell-2.9.3 {
catchcmd ".header OFF" catchcmd ".header OFF"
} {0 {}} } {0 {}}
do_test shell-1.9.4 { do_test shell-2.9.4 {
# too many arguments
catchcmd ".header OFF BAD"
} {1 {Error: unknown command or invalid arguments: "header". Enter ".help" for help}}
do_test shell-2.9.5 {
catchcmd ".headers" catchcmd ".headers"
} {1 {Error: unknown command or invalid arguments: "headers". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "headers". Enter ".help" for help}}
do_test shell-1.9.5 { do_test shell-2.9.6 {
catchcmd ".headers ON" catchcmd ".headers ON"
} {0 {}} } {0 {}}
do_test shell-1.9.6 { do_test shell-2.9.7 {
catchcmd ".headers OFF" catchcmd ".headers OFF"
} {0 {}} } {0 {}}
do_test shell-2.9.8 {
# too many arguments
catchcmd ".headers OFF BAD"
} {1 {Error: unknown command or invalid arguments: "headers". Enter ".help" for help}}
# .help Show this message # .help Show this message
do_test shell-1.10.1 { do_test shell-2.10.1 {
set res [catchcmd ".help"] set res [catchcmd ".help"]
# look for a few of the possible help commands # look for a few of the possible help commands
list [regexp {.help} $res] \ list [regexp {.help} $res] \
[regexp {.quit} $res] \ [regexp {.quit} $res] \
[regexp {.show} $res] [regexp {.show} $res]
} {1 1 1} } {1 1 1}
do_test shell-2.10.2 {
# we allow .help to take extra args (it is help after all)
set res [catchcmd ".help BAD"]
# look for a few of the possible help commands
list [regexp {.help} $res] \
[regexp {.quit} $res] \
[regexp {.show} $res]
} {1 1 1}
# .import FILE TABLE Import data from FILE into TABLE # .import FILE TABLE Import data from FILE into TABLE
do_test shell-1.11.1 { do_test shell-2.11.1 {
catchcmd ".import" catchcmd ".import"
} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}}
do_test shell-1.11.2 { do_test shell-2.11.2 {
catchcmd ".import FOO" catchcmd ".import FOO"
} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}}
do_test shell-1.11.2 { do_test shell-2.11.2 {
catchcmd ".import FOO BAR" catchcmd ".import FOO BAR"
} {1 {Error: no such table: BAR}} } {1 {Error: no such table: BAR}}
do_test shell-2.11.3 {
# too many arguments
catchcmd ".import FOO BAR BAD"
} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}}
# .indices ?TABLE? Show names of all indices # .indices ?TABLE? Show names of all indices
# If TABLE specified, only show indices for tables # If TABLE specified, only show indices for tables
# matching LIKE pattern TABLE. # matching LIKE pattern TABLE.
do_test shell-1.12.1 { do_test shell-2.12.1 {
catchcmd ".indices" catchcmd ".indices"
} {0 {}} } {0 {}}
do_test shell-1.12.2 { do_test shell-2.12.2 {
catchcmd ".indices FOO" catchcmd ".indices FOO"
} {0 {}} } {0 {}}
do_test shell-2.12.3 {
# too many arguments
catchcmd ".indices FOO BAD"
} {1 {Error: unknown command or invalid arguments: "indices". Enter ".help" for help}}
# .mode MODE ?TABLE? Set output mode where MODE is one of: # .mode MODE ?TABLE? Set output mode where MODE is one of:
# csv Comma-separated values # csv Comma-separated values
@@ -187,112 +326,166 @@ do_test shell-1.12.2 {
# list Values delimited by .separator string # list Values delimited by .separator string
# tabs Tab-separated values # tabs Tab-separated values
# tcl TCL list elements # tcl TCL list elements
do_test shell-1.13.1 { do_test shell-2.13.1 {
catchcmd ".mode" catchcmd ".mode"
} {1 {Error: unknown command or invalid arguments: "mode". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "mode". Enter ".help" for help}}
do_test shell-1.13.2 { do_test shell-2.13.2 {
catchcmd ".mode FOO" catchcmd ".mode FOO"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}} } {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell-1.13.3 { do_test shell-2.13.3 {
catchcmd ".mode csv" catchcmd ".mode csv"
} {0 {}} } {0 {}}
do_test shell-1.13.4 { do_test shell-2.13.4 {
catchcmd ".mode column" catchcmd ".mode column"
} {0 {}} } {0 {}}
do_test shell-1.13.5 { do_test shell-2.13.5 {
catchcmd ".mode html" catchcmd ".mode html"
} {0 {}} } {0 {}}
do_test shell-1.13.6 { do_test shell-2.13.6 {
catchcmd ".mode insert" catchcmd ".mode insert"
} {0 {}} } {0 {}}
do_test shell-1.13.7 { do_test shell-2.13.7 {
catchcmd ".mode line" catchcmd ".mode line"
} {0 {}} } {0 {}}
do_test shell-1.13.8 { do_test shell-2.13.8 {
catchcmd ".mode list" catchcmd ".mode list"
} {0 {}} } {0 {}}
do_test shell-1.13.9 { do_test shell-2.13.9 {
catchcmd ".mode tabs" catchcmd ".mode tabs"
} {0 {}} } {0 {}}
do_test shell-1.13.10 { do_test shell-2.13.10 {
catchcmd ".mode tcl" catchcmd ".mode tcl"
} {0 {}} } {0 {}}
do_test shell-2.13.11 {
# too many arguments
catchcmd ".mode tcl BAD"
} {1 {Error: invalid arguments: "BAD". Enter ".help" for help}}
# don't allow partial mode type matches
do_test shell-2.13.12 {
catchcmd ".mode l"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell-2.13.13 {
catchcmd ".mode li"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
do_test shell-2.13.14 {
catchcmd ".mode lin"
} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
# .nullvalue STRING Print STRING in place of NULL values # .nullvalue STRING Print STRING in place of NULL values
do_test shell-1.14.1 { do_test shell-2.14.1 {
catchcmd ".nullvalue" catchcmd ".nullvalue"
} {1 {Error: unknown command or invalid arguments: "nullvalue". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "nullvalue". Enter ".help" for help}}
do_test shell-1.14.2 { do_test shell-2.14.2 {
catchcmd ".nullvalue FOO" catchcmd ".nullvalue FOO"
} {0 {}} } {0 {}}
do_test shell-2.14.3 {
# too many arguments
catchcmd ".nullvalue FOO BAD"
} {1 {Error: unknown command or invalid arguments: "nullvalue". Enter ".help" for help}}
# .output FILENAME Send output to FILENAME # .output FILENAME Send output to FILENAME
do_test shell-1.15.1 { do_test shell-2.15.1 {
catchcmd ".output" catchcmd ".output"
} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}}
do_test shell-1.15.2 { do_test shell-2.15.2 {
catchcmd ".output FOO" catchcmd ".output FOO"
} {0 {}} } {0 {}}
do_test shell-2.15.3 {
# too many arguments
catchcmd ".output FOO BAD"
} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}}
# .output stdout Send output to the screen # .output stdout Send output to the screen
do_test shell-1.16.1 { do_test shell-2.16.1 {
catchcmd ".output stdout" catchcmd ".output stdout"
} {0 {}} } {0 {}}
do_test shell-2.16.2 {
# too many arguments
catchcmd ".output stdout BAD"
} {1 {Error: unknown command or invalid arguments: "output". Enter ".help" for help}}
# .prompt MAIN CONTINUE Replace the standard prompts # .prompt MAIN CONTINUE Replace the standard prompts
do_test shell-1.17.1 { do_test shell-2.17.1 {
catchcmd ".prompt" catchcmd ".prompt"
} {1 {Error: unknown command or invalid arguments: "prompt". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "prompt". Enter ".help" for help}}
do_test shell-1.17.2 { do_test shell-2.17.2 {
catchcmd ".prompt FOO" catchcmd ".prompt FOO"
} {0 {}} } {0 {}}
do_test shell-1.17.3 { do_test shell-2.17.3 {
catchcmd ".prompt FOO BAR" catchcmd ".prompt FOO BAR"
} {0 {}} } {0 {}}
do_test shell-2.17.4 {
# too many arguments
catchcmd ".prompt FOO BAR BAD"
} {1 {Error: unknown command or invalid arguments: "prompt". Enter ".help" for help}}
# .quit Exit this program # .quit Exit this program
do_test shell-1.18.1 { do_test shell-2.18.1 {
catchcmd ".quit" catchcmd ".quit"
} {0 {}} } {0 {}}
do_test shell-2.18.2 {
# too many arguments
catchcmd ".quit BAD"
} {1 {Error: unknown command or invalid arguments: "quit". Enter ".help" for help}}
# .read FILENAME Execute SQL in FILENAME # .read FILENAME Execute SQL in FILENAME
do_test shell-1.19.1 { do_test shell-2.19.1 {
catchcmd ".read" catchcmd ".read"
} {1 {Error: unknown command or invalid arguments: "read". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "read". Enter ".help" for help}}
do_test shell-1.19.2 { do_test shell-2.19.2 {
file delete -force FOO file delete -force FOO
catchcmd ".read FOO" catchcmd ".read FOO"
} {1 {Error: cannot open "FOO"}} } {1 {Error: cannot open "FOO"}}
do_test shell-2.19.3 {
# too many arguments
catchcmd ".read FOO BAD"
} {1 {Error: unknown command or invalid arguments: "read". Enter ".help" for help}}
# .restore ?DB? FILE Restore content of DB (default "main") from FILE # .restore ?DB? FILE Restore content of DB (default "main") from FILE
do_test shell-1.20.1 { do_test shell-2.20.1 {
catchcmd ".restore" catchcmd ".restore"
} {1 {Error: unknown command or invalid arguments: "restore". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "restore". Enter ".help" for help}}
do_test shell-1.20.2 { do_test shell-2.20.2 {
# catchcmd ".restore FOO" # catchcmd ".restore FOO"
#TBD!!! this asserts currently #TBD!!! this asserts currently
} {} } {}
do_test shell-2.20.3 {
catchcmd ".restore FOO BAR"
} {1 {Error: unknown database FOO}}
do_test shell-2.20.4 {
# too many arguments
catchcmd ".restore FOO BAR BAD"
} {1 {Error: unknown command or invalid arguments: "restore". Enter ".help" for help}}
# .schema ?TABLE? Show the CREATE statements # .schema ?TABLE? Show the CREATE statements
# If TABLE specified, only show tables matching # If TABLE specified, only show tables matching
# LIKE pattern TABLE. # LIKE pattern TABLE.
do_test shell-1.21.1 { do_test shell-2.21.1 {
catchcmd ".schema" catchcmd ".schema"
} {0 {}} } {0 {}}
do_test shell-1.21.2 { do_test shell-2.21.2 {
catchcmd ".schema FOO" catchcmd ".schema FOO"
} {0 {}} } {0 {}}
do_test shell-2.21.3 {
# too many arguments
catchcmd ".schema FOO BAD"
} {1 {Error: unknown command or invalid arguments: "schema". Enter ".help" for help}}
# .separator STRING Change separator used by output mode and .import # .separator STRING Change separator used by output mode and .import
do_test shell-1.22.1 { do_test shell-2.22.1 {
catchcmd ".separator" catchcmd ".separator"
} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}}
do_test shell-1.22.2 { do_test shell-2.22.2 {
catchcmd ".separator FOO" catchcmd ".separator FOO"
} {0 {}} } {0 {}}
do_test shell-2.22.3 {
# too many arguments
catchcmd ".separator FOO BAD"
} {1 {Error: unknown command or invalid arguments: "separator". Enter ".help" for help}}
# .show Show the current values for various settings # .show Show the current values for various settings
do_test shell-1.23.1 { do_test shell-2.23.1 {
set res [catchcmd ".show"] set res [catchcmd ".show"]
list [regexp {echo:} $res] \ list [regexp {echo:} $res] \
[regexp {explain:} $res] \ [regexp {explain:} $res] \
@@ -303,55 +496,71 @@ do_test shell-1.23.1 {
[regexp {separator:} $res] \ [regexp {separator:} $res] \
[regexp {width:} $res] [regexp {width:} $res]
} {1 1 1 1 1 1 1 1} } {1 1 1 1 1 1 1 1}
do_test shell-2.23.2 {
# too many arguments
catchcmd ".show BAD"
} {1 {Error: unknown command or invalid arguments: "show". Enter ".help" for help}}
# .tables ?TABLE? List names of tables # .tables ?TABLE? List names of tables
# If TABLE specified, only list tables matching # If TABLE specified, only list tables matching
# LIKE pattern TABLE. # LIKE pattern TABLE.
do_test shell-1.24.1 { do_test shell-2.24.1 {
catchcmd ".tables" catchcmd ".tables"
} {0 {}} } {0 {}}
do_test shell-1.24.2 { do_test shell-2.24.2 {
catchcmd ".tables FOO" catchcmd ".tables FOO"
} {0 {}} } {0 {}}
do_test shell-2.24.3 {
# too many arguments
catchcmd ".tables FOO BAD"
} {1 {Error: unknown command or invalid arguments: "tables". Enter ".help" for help}}
# .timeout MS Try opening locked tables for MS milliseconds # .timeout MS Try opening locked tables for MS milliseconds
do_test shell-1.25.1 { do_test shell-2.25.1 {
catchcmd ".timeout" catchcmd ".timeout"
} {1 {Error: unknown command or invalid arguments: "timeout". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "timeout". Enter ".help" for help}}
do_test shell-1.25.2 { do_test shell-2.25.2 {
catchcmd ".timeout zzz" catchcmd ".timeout zzz"
#TBD!!! this should probably produce an error # this should be treated the same as a '0' timeout
} {0 {}} } {0 {}}
do_test shell-1.25.2 { do_test shell-2.25.3 {
catchcmd ".timeout 1" catchcmd ".timeout 1"
} {0 {}} } {0 {}}
do_test shell-2.25.4 {
# too many arguments
catchcmd ".timeout 1 BAD"
} {1 {Error: unknown command or invalid arguments: "timeout". Enter ".help" for help}}
# .width NUM NUM ... Set column widths for "column" mode # .width NUM NUM ... Set column widths for "column" mode
do_test shell-1.26.1 { do_test shell-2.26.1 {
catchcmd ".width" catchcmd ".width"
#TBD!!! this should probably produce an error } {1 {Error: unknown command or invalid arguments: "width". Enter ".help" for help}}
} {0 {}} do_test shell-2.26.2 {
do_test shell-1.26.2 {
catchcmd ".width xxx" catchcmd ".width xxx"
#TBD!!! this should probably produce an error # this should be treated the same as a '0' width for col 1
} {0 {}} } {0 {}}
do_test shell-1.26.3 { do_test shell-2.26.3 {
catchcmd ".width xxx yyy" catchcmd ".width xxx yyy"
#TBD!!! this should probably produce an error # this should be treated the same as a '0' width for col 1 and 2
} {0 {}} } {0 {}}
do_test shell-1.26.4 { do_test shell-2.26.4 {
catchcmd ".width 1 1" catchcmd ".width 1 1"
# this should be treated the same as a '1' width for col 1 and 2
} {0 {}} } {0 {}}
# .timer ON|OFF Turn the CPU timer measurement on or off # .timer ON|OFF Turn the CPU timer measurement on or off
do_test shell-1.27.1 { do_test shell-2.27.1 {
catchcmd ".timer" catchcmd ".timer"
} {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}}
do_test shell-1.27.2 { do_test shell-2.27.2 {
catchcmd ".timer ON" catchcmd ".timer ON"
} {0 {}} } {0 {}}
do_test shell-1.27.3 { do_test shell-2.27.3 {
catchcmd ".timer OFF" catchcmd ".timer OFF"
} {0 {}} } {0 {}}
do_test shell-2.27.4 {
# too many arguments
catchcmd ".timer OFF BAD"
} {1 {Error: unknown command or invalid arguments: "timer". Enter ".help" for help}}
# #