** tables. The table must be in the TEMP schema. Only rows with
** uses=PTU_Binding are eligible for parameter binding.
*/
-static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
+static void bind_prepared_stmt(sqlite3 *db, sqlite3_stmt *pStmt){
int nVar;
int i;
int rc;
sqlite3_stmt *pQ = 0;
nVar = sqlite3_bind_parameter_count(pStmt);
- if( nVar==0 || !param_table_exists(pArg->db) ) return; /* Nothing to do */
- rc = sqlite3_prepare_v2(pArg->db,
+ if( nVar==0 || !param_table_exists(db) ) return; /* Nothing to do */
+ rc = sqlite3_prepare_v2(db,
"SELECT value FROM "PARAM_TABLE_SNAME
" WHERE key=?1 AND uses=0", -1, &pQ, 0);
if( rc || pQ==0 ) return;
}
}
- bind_prepared_stmt(pArg, pStmt);
+ bind_prepared_stmt(pArg->db, pStmt);
exec_prepared_stmt(pArg, pStmt);
explain_data_delete(pArg);
eqp_render(pArg);
" -e Send output to the system text editor",
" -x Send output as CSV to a spreadsheet",
".parameter CMD ... Manage SQL parameter bindings and scripts table",
- " clear ?NAMES? Erase some or all named parameters",
+ " clear ?NAMES? Erase all or only given named parameters",
#ifndef SQLITE_NOHAVE_SYSTEM
- " edit NAME Use edit() to create or alter parameter NAME",
+ " edit ?OPT? NAME ... Use edit() to create or alter parameter NAME",
+ " OPT may be -t or -e to use edited value as text or evaluate it first.",
#endif
" init Initialize TEMP table for bindings and scripts",
" list List parameters table binding and script values",
/*
** Run an SQL command and return the single integer result.
+** No parameter binding is done.
*/
-static int db_int(ShellState *p, const char *zSql){
+static int db_int(sqlite3 *db, const char *zSql){
sqlite3_stmt *pStmt;
int res = 0;
- sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
res = sqlite3_column_int(pStmt,0);
}
return res;
}
+/*
+** Run an SQL command and return the single text result,
+** Parameter binding is done iff bBind is true.
+** The return must be freed by caller.
+*/
+static char *db_text(sqlite3 *db, const char *zSql, int bBind){
+ sqlite3_stmt *pStmt;
+ char *zRes = 0;
+ sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+ if( pStmt ){
+ if( bBind ) bind_prepared_stmt(db, pStmt);
+ if( sqlite3_step(pStmt)==SQLITE_ROW ){
+ zRes = sqlite3_mprintf("%s", sqlite3_column_text(pStmt,0));
+ shell_check_oom(zRes);
+ }
+ }
+ sqlite3_finalize(pStmt);
+ return zRes;
+}
+
/*
** Convert a 2-byte or 4-byte big-endian integer into a native integer
*/
}
for(i=0; i<ArraySize(aQuery); i++){
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
- int val = db_int(p, zSql);
+ int val = db_int(p->db, zSql);
sqlite3_free(zSql);
utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
}
static int edit_one_param(sqlite3 *db, char *name, int eval,
ParamTableUse uses, const char * zEditor){
struct param_row paramVU = {0,0,0};
+ int rc;
+ char * zVal = 0;
char * zSql = sqlite3_mprintf
("SELECT value, uses FROM " PARAM_TABLE_SNAME " WHERE key=%Q", name);
shell_check_oom(zSql);
sqlite3_exec(db, zSql, param_find_callback, ¶mVU, 0);
sqlite3_free(zSql);
assert(paramVU.hits<2);
- if( eval!=0 ){
- /* ToDo: Run an eval-like update, leaving as-is if it's a bad expr. */
- // int rv = edit_one_param(db, name, 0, uses);
- }
if( paramVU.hits==1 && paramVU.uses==uses){
/* Editing an existing value of same kind. */
sqlite3_free(paramVU.value);
- zSql = sqlite3_mprintf
- ("UPDATE "PARAM_TABLE_SNAME" SET value=edit(value, %Q) WHERE"
- " key=%Q AND uses=%d", zEditor, name, uses);
+ if( eval!=0 ){
+ zSql = sqlite3_mprintf
+ ("SELECT edit(value, %Q) FROM " PARAM_TABLE_SNAME
+ " WHERE key=%Q AND uses=%d", zEditor, name, uses);
+ zVal = db_text(db, zSql, 1);
+ sqlite3_free(zSql);
+ zSql = sqlite3_mprintf
+ ("UPDATE "PARAM_TABLE_SNAME" SET value=(SELECT %s) WHERE"
+ " key=%Q AND uses=%d", zVal, name, uses);
+ }else{
+ zSql = sqlite3_mprintf
+ ("UPDATE "PARAM_TABLE_SNAME" SET value=edit(value, %Q) WHERE"
+ " key=%Q AND uses=%d", zEditor, name, uses);
+ }
}else{
/* Editing a new value of same kind. */
assert(paramVU.value==0 || paramVU.uses!=uses);
- zSql = sqlite3_mprintf
- ("INSERT INTO "PARAM_TABLE_SNAME"(key,value,uses)"
- " VALUES (%Q,edit('-- %q%s', %Q),%d)",
- name, name, "\n", zEditor, uses);
+ if( eval!=0 ){
+ zSql = sqlite3_mprintf
+ ("SELECT edit('-- %q%s', %Q)", name, "\n", zEditor);
+ zVal = db_text(db, zSql, 1);
+ sqlite3_free(zSql);
+ zSql = sqlite3_mprintf
+ ("INSERT INTO "PARAM_TABLE_SNAME"(key,value,uses)"
+ " VALUES (%Q,(SELECT %s LIMIT 1),%d)",
+ name, zVal, uses);
+ }else{
+ zSql = sqlite3_mprintf
+ ("INSERT INTO "PARAM_TABLE_SNAME"(key,value,uses)"
+ " VALUES (%Q,edit('-- %q%s', %Q),%d)",
+ name, name, "\n", zEditor, uses);
+ }
}
shell_check_oom(zSql);
- sqlite3_exec(db, zSql, 0, 0, 0);
+ if( eval!=0 ){
+ }
+ rc = sqlite3_exec(db, zSql, 0, 0, 0);
sqlite3_free(zSql);
- return 0; /* ToDo: add some error checks */
+ sqlite3_free(zVal);
+ return rc!=SQLITE_OK;
}
#endif
char *zValue = (zValGlom==0)? *valBeg : zValGlom;
if( cCast ){
struct ParamSetOpts *pSO = param_set_opts;
- for(; param_set_opts-pSO < ArraySize(param_set_opts); ++pSO ){
+ for(; pSO-param_set_opts < ArraySize(param_set_opts); ++pSO ){
if( cCast==pSO->cCast ){
zCastTo = pSO->zTypename;
needsEval = pSO->evalKind > 0;
if( len ){
utf8_printf(p->out, "%-*s %-8s %s\n", len, "name", "usage", "value");
rc = sqlite3_prepare_v2
- (p->db, "SELECT key, uses, quote(value) FROM "
- PARAM_TABLE_SNAME" WHERE ?1=3 OR uses=?1", -1, &pStmt, 0);
+ (p->db, "SELECT key, uses, quote(value) FROM " PARAM_TABLE_SNAME
+ " WHERE ?1=3 OR uses=?1 ORDER BY key", -1, &pStmt, 0);
sqlite3_bind_int(pStmt, 1, ptu);
while( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
ParamTableUse ptux = sqlite3_column_int(pStmt,1);
"Either set env-var VISUAL to name an"
" editor and restart, or rerun\n "
".parameter edit with an initial "
- "edit option, --editor=EDITOR_NAME .\n");
+ "edit option, --editor=EDITOR_COMMAND .\n");
rc = 1;
goto meta_command_exit;
}
break;
case Cmd:
echo_group_input(p, *pzLineUse);
- switch( do_meta_command(*pzLineUse, p) ){
+ switch( do_meta_command(*pzLineUse+ndcLeadWhite, p) ){
default: ++nErrors; /* fall thru */
case 0: break;
case 2: bExitDemand = 1; break;
char *zErrMsg = 0;
ShellState data;
const char *zInitFile = 0;
+ int bQuiet = 0; /* for testing, to suppress banner and history actions */
int i;
int rc = 0;
int warnInmemoryDb = 0;
/* 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,
- ** and the first command to execute.
+ ** the first command to execute,
+ ** and whether testing certain interactive behavior.
*/
verify_uninitialized();
for(i=1; i<argc; i++){
}else if( strcmp(z,"-nonce")==0 ){
free(data.zNonce);
data.zNonce = strdup(argv[++i]);
+ }else if( strcmp(z,"-quiet")==0 ){
+ bQuiet = (int)integerValue(cmdline_option_value(argc,argv,++i));
}else if( strcmp(z,"-safe")==0 ){
/* no-op - catch this on the second pass */
}
#endif
}else if( strcmp(z,"-safe")==0 ){
data.bSafeMode = data.bSafeModePersist = 1;
+ }else if( strcmp(z,"-quiet")==0 ){
+ ++i;
}else{
utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
raw_printf(stderr,"Use -help for a list of options.\n");
*/
if( stdin_is_interactive ){
char *zHome;
- char *zHistory;
+ char *zHistory = 0;
int nHistory;
- printf(
- "SQLite version %s %.19s\n" /*extra-version-info*/
- "Enter \".help\" for usage hints.\n",
- sqlite3_libversion(), sqlite3_sourceid()
- );
- if( warnInmemoryDb ){
- printf("Connected to a ");
- printBold("transient in-memory database");
- printf(".\nUse \".open FILENAME\" to reopen on a "
- "persistent database.\n");
- }
- zHistory = getenv("SQLITE_HISTORY");
- if( zHistory ){
- zHistory = strdup(zHistory);
- }else if( (zHome = find_home_dir(0))!=0 ){
- nHistory = strlen30(zHome) + 20;
- if( (zHistory = malloc(nHistory))!=0 ){
- sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
- }
- }
- if( zHistory ){ shell_read_history(zHistory); }
+ if( bQuiet ){
+ /* bQuiet is almost like normal interactive, but quieter. */
+ mainPrompt[0] = 0;
+ continuePrompt[0] = 0;
+ }else{
+ printf(
+ "SQLite version %s %.19s\n" /*extra-version-info*/
+ "Enter \".help\" for usage hints.\n",
+ sqlite3_libversion(), sqlite3_sourceid()
+ );
+ if( warnInmemoryDb ){
+ printf("Connected to a ");
+ printBold("transient in-memory database");
+ printf(".\nUse \".open FILENAME\" to reopen on a "
+ "persistent database.\n");
+ }
+ zHistory = getenv("SQLITE_HISTORY");
+ if( zHistory ){
+ zHistory = strdup(zHistory);
+ }else if( (zHome = find_home_dir(0))!=0 ){
+ nHistory = strlen30(zHome) + 20;
+ if( (zHistory = malloc(nHistory))!=0 ){
+ sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
+ }
+ }
+ if( zHistory ){ shell_read_history(zHistory); }
#if HAVE_READLINE || HAVE_EDITLINE
- rl_attempted_completion_function = readline_completion;
+ rl_attempted_completion_function = readline_completion;
#elif HAVE_LINENOISE
- linenoiseSetCompletionCallback(linenoise_completion);
+ linenoiseSetCompletionCallback(linenoise_completion);
#endif
+ }
data.pInSource = &termInSource; /* read from stdin interactively */
rc = process_input(&data);
- if( zHistory ){
- shell_stifle_history(2000);
- shell_write_history(zHistory);
- free(zHistory);
+ if( !bQuiet ){
+ if( zHistory ){
+ shell_stifle_history(2000);
+ shell_write_history(zHistory);
+ free(zHistory);
+ }
}
}else{
data.pInSource = &stdInSource; /* read from stdin without prompts */