Remove the ill-designed "-end" option from the command-line shell. Instead,
allow multiple SQL or dot-commands as command-line arguments. Any -cmd commands are processed first, followed by other command-line arguments, for backwards compatibility. FossilOrigin-Name: 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e
This commit is contained in:
parent
cb7fe0ab9c
commit
ac5649a985
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Add\sthe\s-end\soption\sto\sthe\scommand-line\sshell,\swhich\sforces\sit\sto\sexit\safter\nreading\sprior\scommand-line\soptions\s(presumably\sincluding\sone\sor\smore\s-cmd\noptions)\sand\swithout\sreading\sstandard\sinput.
|
||||
D 2014-11-28T11:54:44.417
|
||||
C Remove\sthe\sill-designed\s"-end"\soption\sfrom\sthe\scommand-line\sshell.\s\sInstead,\nallow\smultiple\sSQL\sor\sdot-commands\sas\scommand-line\sarguments.\s\sAny\s-cmd\ncommands\sare\sprocessed\sfirst,\sfollowed\sby\sother\scommand-line\sarguments,\sfor\nbackwards\scompatibility.
|
||||
D 2014-11-28T13:35:03.566
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -229,7 +229,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 428165951748151e87a15295b7357221433e311b
|
||||
F src/shell.c f49ecad5afcae4c7fa2754a1446848582b105509
|
||||
F src/shell.c 45d9c9bd7cde07845af957f2d849933b990773cf
|
||||
F src/sqlite.h.in c63db0117aeb749ca02b6016dbbbccbbbd9a141d
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
@ -848,8 +848,8 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
|
||||
F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test d60946b5fde4d85fe06db7331dfe89011f564350
|
||||
F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
|
||||
F test/shell1.test ab6025d941f9c84c5b83412c6b4d8b57f78dfa3a
|
||||
F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862
|
||||
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
|
||||
F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
|
||||
F test/shell5.test 15a419cc1df21c892ed64f5596ae7a501f2816f2
|
||||
@ -1223,7 +1223,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 f095cde579e7417306e11b5c1d2dd90b6bb547d5
|
||||
R 705c89a250127228fc15e4e2150ad4c0
|
||||
P b59397b1f1e32c478b5fa96659cd4300177d39f7
|
||||
R 1ff83ec33f372c19416fe00ba6e9161c
|
||||
U drh
|
||||
Z ed3d85af1529a8fcb757b6e7459b553e
|
||||
Z 816c9b1778ea4dbed9ea56de4b3769ca
|
||||
|
@ -1 +1 @@
|
||||
b59397b1f1e32c478b5fa96659cd4300177d39f7
|
||||
24fa2e9832daaa5d68ee28a00c56c55f97a4da9e
|
80
src/shell.c
80
src/shell.c
@ -3944,7 +3944,6 @@ static const char zOptions[] =
|
||||
" -cmd COMMAND run \"COMMAND\" before reading stdin\n"
|
||||
" -csv set output mode to 'csv'\n"
|
||||
" -echo print commands before execution\n"
|
||||
" -end Halt. Useful after one or more -cmd\n"
|
||||
" -init FILENAME read/process named file\n"
|
||||
" -[no]header turn headers on or off\n"
|
||||
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
|
||||
@ -4039,10 +4038,12 @@ int main(int argc, char **argv){
|
||||
char *zErrMsg = 0;
|
||||
ShellState data;
|
||||
const char *zInitFile = 0;
|
||||
char *zFirstCmd = 0;
|
||||
int i;
|
||||
int rc = 0;
|
||||
int warnInmemoryDb = 0;
|
||||
int readStdin = 1;
|
||||
int nCmd = 0;
|
||||
char **azCmd = 0;
|
||||
|
||||
#if USE_SYSTEM_SQLITE+0!=1
|
||||
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
|
||||
@ -4062,6 +4063,18 @@ int main(int argc, char **argv){
|
||||
signal(SIGINT, interrupt_handler);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_SHELL_DBNAME_PROC
|
||||
{
|
||||
/* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
|
||||
** of a C-function that will provide the name of the database file. Use
|
||||
** this compile-time option to embed this shell program in larger
|
||||
** applications. */
|
||||
extern void SQLITE_SHELL_DBNAME_PROC(const char**);
|
||||
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
|
||||
warnInmemoryDb = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do an initial pass through the command-line argument to locate
|
||||
** the name of the database file, the name of the initialization file,
|
||||
** the size of the alternative malloc heap,
|
||||
@ -4073,15 +4086,18 @@ int main(int argc, char **argv){
|
||||
if( z[0]!='-' ){
|
||||
if( data.zDbFilename==0 ){
|
||||
data.zDbFilename = z;
|
||||
continue;
|
||||
}else{
|
||||
/* Excesss arguments are interpreted as SQL (or dot-commands) and
|
||||
** mean that nothing is read from stdin */
|
||||
readStdin = 0;
|
||||
nCmd++;
|
||||
azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
|
||||
if( azCmd==0 ){
|
||||
fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
azCmd[nCmd-1] = z;
|
||||
}
|
||||
if( zFirstCmd==0 ){
|
||||
zFirstCmd = z;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
|
||||
fprintf(stderr,"Use -help for a list of options.\n");
|
||||
return 1;
|
||||
}
|
||||
if( z[1]=='-' ) z++;
|
||||
if( strcmp(z,"-separator")==0
|
||||
@ -4171,11 +4187,6 @@ int main(int argc, char **argv){
|
||||
#else
|
||||
fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef SQLITE_SHELL_DBNAME_PROC
|
||||
{ extern void SQLITE_SHELL_DBNAME_PROC(const char**);
|
||||
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
|
||||
warnInmemoryDb = 0; }
|
||||
#endif
|
||||
}
|
||||
data.out = stdout;
|
||||
@ -4273,6 +4284,10 @@ int main(int argc, char **argv){
|
||||
}else if( strcmp(z,"-help")==0 ){
|
||||
usage(1);
|
||||
}else if( strcmp(z,"-cmd")==0 ){
|
||||
/* Run commands that follow -cmd first and separately from commands
|
||||
** that simply appear on the command-line. This seems goofy. It would
|
||||
** be better if all commands ran in the order that they appear. But
|
||||
** we retain the goofy behavior for historical compatibility. */
|
||||
if( i==argc-1 ) break;
|
||||
z = cmdline_option_value(argc,argv,++i);
|
||||
if( z[0]=='.' ){
|
||||
@ -4289,8 +4304,6 @@ int main(int argc, char **argv){
|
||||
if( bail_on_error ) return rc;
|
||||
}
|
||||
}
|
||||
}else if( strcmp(z, "-end")==0 ){
|
||||
return 0;
|
||||
}else{
|
||||
fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
|
||||
fprintf(stderr,"Use -help for a list of options.\n");
|
||||
@ -4298,23 +4311,28 @@ int main(int argc, char **argv){
|
||||
}
|
||||
}
|
||||
|
||||
if( zFirstCmd ){
|
||||
/* Run just the command that follows the database name
|
||||
if( !readStdin ){
|
||||
/* Run all arguments that do not begin with '-' as if they were separate
|
||||
** command-line inputs, except for the argToSkip argument which contains
|
||||
** the database filename.
|
||||
*/
|
||||
if( zFirstCmd[0]=='.' ){
|
||||
rc = do_meta_command(zFirstCmd, &data);
|
||||
if( rc==2 ) rc = 0;
|
||||
}else{
|
||||
open_db(&data, 0);
|
||||
rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
|
||||
if( zErrMsg!=0 ){
|
||||
fprintf(stderr,"Error: %s\n", zErrMsg);
|
||||
return rc!=0 ? rc : 1;
|
||||
}else if( rc!=0 ){
|
||||
fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
|
||||
return rc;
|
||||
for(i=0; i<nCmd; i++){
|
||||
if( azCmd[i][0]=='.' ){
|
||||
rc = do_meta_command(azCmd[i], &data);
|
||||
if( rc ) return rc==2 ? 0 : rc;
|
||||
}else{
|
||||
open_db(&data, 0);
|
||||
rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
|
||||
if( zErrMsg!=0 ){
|
||||
fprintf(stderr,"Error: %s\n", zErrMsg);
|
||||
return rc!=0 ? rc : 1;
|
||||
}else if( rc!=0 ){
|
||||
fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(azCmd);
|
||||
}else{
|
||||
/* Run commands received from standard input
|
||||
*/
|
||||
|
@ -45,20 +45,21 @@ do_test shell1-1.1.1 {
|
||||
list $rc \
|
||||
[regexp {Error: unknown option: -bad} $res]
|
||||
} {1 1}
|
||||
do_test shell1-1.1.1b {
|
||||
set res [catchcmd "test.db -bad" ""]
|
||||
set rc [lindex $res 0]
|
||||
list $rc \
|
||||
[regexp {Error: unknown option: -bad} $res]
|
||||
} {1 1}
|
||||
# error on extra options
|
||||
do_test shell1-1.1.2 {
|
||||
set res [catchcmd "-bad test.db \"select 3\" \"select 4\"" ""]
|
||||
set rc [lindex $res 0]
|
||||
list $rc \
|
||||
[regexp {Error: too many options: "select 4"} $res]
|
||||
} {1 1}
|
||||
catchcmd "test.db \"select 3\" \"select 4\"" ""
|
||||
} {0 {3
|
||||
4}}
|
||||
# error on extra options
|
||||
do_test shell1-1.1.3 {
|
||||
set res [catchcmd "-bad FOO test.db BAD" ".quit"]
|
||||
set rc [lindex $res 0]
|
||||
list $rc \
|
||||
[regexp {Error: too many options: "BAD"} $res]
|
||||
} {1 1}
|
||||
catchcmd "test.db FOO test.db BAD" ".quit"
|
||||
} {1 {Error: near "FOO": syntax error}}
|
||||
|
||||
# -help
|
||||
do_test shell1-1.2.1 {
|
||||
@ -75,11 +76,11 @@ do_test shell1-1.3.1 {
|
||||
catchcmd "-init FOO test.db" ""
|
||||
} {0 {}}
|
||||
do_test shell1-1.3.2 {
|
||||
set res [catchcmd "-init FOO test.db .quit BAD" ""]
|
||||
set rc [lindex $res 0]
|
||||
list $rc \
|
||||
[regexp {Error: too many options: "BAD"} $res]
|
||||
} {1 1}
|
||||
catchcmd "-init FOO test.db .quit BAD" ""
|
||||
} {0 {}}
|
||||
do_test shell1-1.3.3 {
|
||||
catchcmd "-init FOO test.db BAD .quit" ""
|
||||
} {1 {Error: near "BAD": syntax error}}
|
||||
|
||||
# -echo print commands before execution
|
||||
do_test shell1-1.4.1 {
|
||||
|
@ -52,9 +52,9 @@ do_test shell2-1.1.1 {
|
||||
# Ticket [f5cb008a65].
|
||||
do_test shell2-1.2.1 {
|
||||
set rc [catch { eval exec $CLI \":memory:\" \"select 3\" \"select 4\" } msg]
|
||||
list $rc \
|
||||
[regexp {Error: too many options: "select 4"} $msg]
|
||||
} {1 1}
|
||||
list $rc $msg
|
||||
} {0 {3
|
||||
4}}
|
||||
|
||||
# Test a problem reported on the mailing list. The shell was at one point
|
||||
# returning the generic SQLITE_ERROR message ("SQL error or missing database")
|
||||
|
Loading…
Reference in New Issue
Block a user