diff --git a/manifest b/manifest index 25145ebadc..4e8a365192 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Accept\sa\s"/"\sor\s"go"\son\sa\sline\sby\sitself\sas\san\sSQL\sstatement\sterminator\nin\sthe\scommand-line\sshell.\s\sThis\sallows\sSQL\sServer\sand\sOracle\sscripts\sto\nbe\splayed\sinto\sSQLite\swithout\schange.\s(CVS\s944) -D 2003-04-29T18:01:28 +C In\sthe\sshell\stool,\sdelay\sopening\sthe\sdatabase\suntil\sit\sis\sneeded\sbut\salso\nmake\ssure\sit\sis\sopened\sbefore\strying\sto\suse\sthe\s"db"\spointer.\s\sTicket\s#302.\s(CVS\s945) +D 2003-04-30T11:38:26 F Makefile.in 004acec253ecdde985c8ecd5b7c9accdb210378f F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -44,7 +44,7 @@ F src/pragma.c 118fe400d71b7fdcc03580d5eab6bb5aa00772a5 F src/printf.c fc5fdef6e92ad205005263661fe9716f55a49f3e F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe F src/select.c d1c876b9078894bc956cf1a5b38abd1a5abaf70b -F src/shell.c 4dc33c49cc69ef864c1e19283b7b683a7639a251 +F src/shell.c 6f59240f69e65a1c4e1d06492eb9238092defc34 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in eec06462cba262c0ee03f38462a18a4bc66dda4e F src/sqliteInt.h faf133e1441b7c7b93ad5d8a58201d4849033b75 @@ -165,7 +165,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 1a0c542088618ba24d1efae9b13a8eca104d6cc8 -R b08733b79775152cc384c5b58062cc88 +P 8211f57b38b87a42c856e267bd243984b5abf9cc +R 8d1a651464b57a75eca847d54be66b6a U drh -Z 5e48773d80f83c12274e19cd1dafe308 +Z 1057a8e7247edddeca55cdc3ce6cad4c diff --git a/manifest.uuid b/manifest.uuid index 05f78f7b1d..5084c9730b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8211f57b38b87a42c856e267bd243984b5abf9cc \ No newline at end of file +20fcead42bc875f13eec52971530342ff00c5eda \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 3f7094e096..2be8ccbfe4 100644 --- a/src/shell.c +++ b/src/shell.c @@ -12,7 +12,7 @@ ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** -** $Id: shell.c,v 1.74 2003/04/29 18:01:28 drh Exp $ +** $Id: shell.c,v 1.75 2003/04/30 11:38:26 drh Exp $ */ #include #include @@ -76,6 +76,7 @@ static char *Argv0; static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ + /* ** Determines if a string is a number of not. */ @@ -183,8 +184,8 @@ struct callback_data { struct previous_mode_data explainPrev; /* Holds the mode information just before ** .explain ON */ - char outfile[FILENAME_MAX]; - /* Filename for *out */ + char outfile[FILENAME_MAX]; /* Filename for *out */ + const char *zDbFilename; /* name of the database file */ }; /* @@ -498,13 +499,38 @@ static char zHelp[] = /* Forward reference */ static void process_input(struct callback_data *p, FILE *in); +/* +** 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. +*/ +static void open_db(struct callback_data *p){ + if( p->db==0 ){ + char *zErrMsg = 0; + p->db = db = sqlite_open(p->zDbFilename, 0666, &zErrMsg); + if( db==0 ){ + p->db = db = sqlite_open(p->zDbFilename, 0444, &zErrMsg); + if( db==0 ){ + if( zErrMsg ){ + fprintf(stderr,"Unable to open database \"%s\": %s\n", + p->zDbFilename, zErrMsg); + }else{ + fprintf(stderr,"Unable to open database %s\n", p->zDbFilename); + } + exit(1); + }else{ + fprintf(stderr,"Database \"%s\" opened READ ONLY!\n", p->zDbFilename); + } + } + } +} + /* ** If an input line begins with "." then invoke this routine to ** process that line. ** ** Return 1 to exit and 0 to continue. */ -static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ +static int do_meta_command(char *zLine, struct callback_data *p){ int i = 1; int nArg = 0; int n, c; @@ -536,9 +562,10 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ c = azArg[0][0]; if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ char *zErrMsg = 0; + open_db(p); fprintf(p->out, "BEGIN TRANSACTION;\n"); if( nArg==1 ){ - sqlite_exec(db, + sqlite_exec(p->db, "SELECT name, type, sql FROM sqlite_master " "WHERE type!='meta' AND sql NOT NULL " "ORDER BY substr(type,2,1), name", @@ -547,7 +574,7 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ }else{ int i; for(i=1; idb, "SELECT name, type, sql FROM sqlite_master " "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL " "ORDER BY substr(type,2,1), name", @@ -648,10 +675,11 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){ struct callback_data data; char *zErrMsg = 0; + open_db(p); memcpy(&data, p, sizeof(data)); data.showHeader = 0; data.mode = MODE_List; - sqlite_exec_printf(db, + sqlite_exec_printf(p->db, "SELECT name FROM sqlite_master " "WHERE type='index' AND tbl_name LIKE '%q' " "UNION ALL " @@ -724,7 +752,7 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ }else if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ - sqlite_close(db); + sqlite_close(p->db); exit(0); }else @@ -741,6 +769,7 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ struct callback_data data; char *zErrMsg = 0; + open_db(p); memcpy(&data, p, sizeof(data)); data.showHeader = 0; data.mode = MODE_Semi; @@ -773,7 +802,7 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ new_colv[1] = 0; callback(&data, 1, new_argv, new_colv); }else{ - sqlite_exec_printf(db, + sqlite_exec_printf(p->db, "SELECT sql FROM " " (SELECT * FROM sqlite_master UNION ALL" " SELECT * FROM sqlite_temp_master) " @@ -782,7 +811,7 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ callback, &data, &zErrMsg, azArg[1]); } }else{ - sqlite_exec(db, + sqlite_exec(p->db, "SELECT sql FROM " " (SELECT * FROM sqlite_master UNION ALL" " SELECT * FROM sqlite_temp_master) " @@ -822,8 +851,9 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ char **azResult; int nRow, rc; char *zErrMsg; + open_db(p); if( nArg==1 ){ - rc = sqlite_get_table(db, + rc = sqlite_get_table(p->db, "SELECT name FROM sqlite_master " "WHERE type IN ('table','view') " "UNION ALL " @@ -833,7 +863,7 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ &azResult, &nRow, 0, &zErrMsg ); }else{ - rc = sqlite_get_table_printf(db, + rc = sqlite_get_table_printf(p->db, "SELECT name FROM sqlite_master " "WHERE type IN ('table','view') AND name LIKE '%%%q%%' " "UNION ALL " @@ -871,7 +901,8 @@ static int do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ }else if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){ - sqlite_busy_timeout(db, atoi(azArg[1])); + open_db(p); + sqlite_busy_timeout(p->db, atoi(azArg[1])); }else if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ @@ -958,7 +989,7 @@ static void process_input(struct callback_data *p, FILE *in){ if( p->echoOn ) printf("%s\n", zLine); if( _all_whitespace(zLine) ) continue; if( zLine && zLine[0]=='.' && nSql==0 ){ - int rc = do_meta_command(zLine, db, p); + int rc = do_meta_command(zLine, p); free(zLine); if( rc ) break; continue; @@ -988,7 +1019,8 @@ static void process_input(struct callback_data *p, FILE *in){ free(zLine); if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite_complete(zSql) ){ p->cnt = 0; - rc = sqlite_exec(db, zSql, callback, p, &zErrMsg); + open_db(p); + rc = sqlite_exec(p->db, zSql, callback, p, &zErrMsg); if( rc || zErrMsg ){ if( in!=0 && !p->echoOn ) printf("%s\n",zSql); if( zErrMsg!=0 ){ @@ -1103,6 +1135,8 @@ int main(int argc, char **argv){ struct callback_data data; int origArgc = argc; char **origArgv = argv; + int i; + extern int sqliteOsFileExists(const char*); #ifdef __MACOS__ argc = ccommand(&argv); @@ -1112,11 +1146,44 @@ int main(int argc, char **argv){ Argv0 = argv[0]; main_init(&data); - process_sqliterc(&data,NULL); + /* Make sure we have a valid signal handler early, before anything + ** else is done. + */ #ifdef SIGINT signal(SIGINT, interrupt_handler); #endif + + /* Locate the name of the database file + */ + for(i=1; i=2 && argv[1][0]=='-' ){ if( argc>=3 && strcmp(argv[1],"-init")==0 ){ /* If we get a -init to do, we have to pretend that @@ -1182,31 +1249,16 @@ int main(int argc, char **argv){ return 1; } } - if( argc!=2 && argc!=3 ){ - fprintf(stderr,"Usage: %s ?OPTIONS? FILENAME ?SQL?\n", Argv0); - exit(1); - } - data.db = db = sqlite_open(argv[1], 0666, &zErrMsg); - if( db==0 ){ - data.db = db = sqlite_open(argv[1], 0444, &zErrMsg); - if( db==0 ){ - if( zErrMsg ){ - fprintf(stderr,"Unable to open database \"%s\": %s\n", argv[1],zErrMsg); - }else{ - fprintf(stderr,"Unable to open database %s\n", argv[1]); - } - exit(1); - }else{ - fprintf(stderr,"Database \"%s\" opened READ ONLY!\n", argv[1]); - } - } - data.out = stdout; + if( argc==3 ){ + /* Run just the command that follows the database name + */ if( argv[2][0]=='.' ){ - do_meta_command(argv[2], db, &data); + do_meta_command(argv[2], &data); exit(0); }else{ int rc; + open_db(&data); rc = sqlite_exec(db, argv[2], callback, &data, &zErrMsg); if( rc!=0 && zErrMsg!=0 ){ fprintf(stderr,"SQL error: %s\n", zErrMsg); @@ -1214,6 +1266,8 @@ int main(int argc, char **argv){ } } }else{ + /* Run commands received from standard input + */ if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){ char *zHome; char *zHistory = 0; @@ -1237,6 +1291,6 @@ int main(int argc, char **argv){ } } set_table_name(&data, 0); - sqlite_close(db); + if( db ) sqlite_close(db); return 0; }