Add the ".parameter" command to the CLI.

FossilOrigin-Name: 1f9fa58541dc974989eee9c9a5d453956f7dbcf42965ece2db2cb5dee3f3f5e2
This commit is contained in:
drh 2019-02-28 20:10:52 +00:00
parent c06ede105d
commit 9cb0264041
3 changed files with 128 additions and 7 deletions

View File

@ -1,5 +1,5 @@
C Add\sthe\snew\s"bind_fallback"\smethod\sto\sthe\s"sqlite3"\sobject\sin\sthe\sTCL\ninterface.
D 2019-02-28T17:29:19.212
C Add\sthe\s".parameter"\scommand\sto\sthe\sCLI.
D 2019-02-28T20:10:52.766
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 1ad7263f38329c0ecea543c80f30af839ee714ea77fc391bf1a3fbb919a5b6b5
@ -516,7 +516,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 09419ad5c432190b69be7c0c326e03abb548a97c2c50675b81b459e1b382d1d2
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c c998f694759e37799929e28df8a2649747f8774d4fc233529ab6bda689388e15
F src/shell.c.in a238f3f80f7085d31056c69930ec13a87872da0d0d08fd561f5aff78cc618f5d
F src/shell.c.in 249c0bf34f7ce272cb17162c297c45ab674a52a5d85193a86191f131196de47f
F src/sqlite.h.in 8859e0b45b48d4186fbc466885e508f8272420a349099acdebcdb8d410d54824
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
@ -1805,7 +1805,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 00ae0c6c4815366bd2f36bc054b13bc7b568dd0a3caceddf0eba4db33f010ee4
R 448ca78435be9ef8ac1ee1c7bdd459a0
P c7f70b6d96338dba201e005104e7f7148c1a8cd767ab05e35b44617c4c797bc5
R 2fecd2e603ada3a0c6460ef11e6e9c28
U drh
Z 8dd6bd727b5289a2522f6d5168203921
Z f7dd879e1ba76ea61ec7d6d44725ec74

View File

@ -1 +1 @@
c7f70b6d96338dba201e005104e7f7148c1a8cd767ab05e35b44617c4c797bc5
1f9fa58541dc974989eee9c9a5d453956f7dbcf42965ece2db2cb5dee3f3f5e2

View File

@ -2750,6 +2750,16 @@ static void restore_debug_trace_modes(void){
/* Name of the TEMP table that holds bind parameter values */
#define BIND_PARAM_TABLE "$Parameters"
/* Create the TEMP table used to store parameter bindings */
static void bind_table_init(ShellState *p){
sqlite3_exec(p->db,
"CREATE TABLE IF NOT EXISTS temp.[" BIND_PARAM_TABLE "](\n"
" key TEXT PRIMARY KEY,\n"
" value ANY\n"
") WITHOUT ROWID;",
0, 0, 0);
}
/*
** Bind parameters on a prepared statement.
**
@ -3547,6 +3557,13 @@ static const char *(azHelp[]) = {
" --zip FILE is a ZIP archive",
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
" If FILE begins with '|' then open it as a pipe.",
".parameter CMD ... Manage SQL parameter bindings",
" clear Erase all bindings",
" init Initialize the TEMP table that holds bindings",
" list List the current parameter bindings",
" set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
" PARAMETER should start with '$', ':', '@', or '?'",
" unset PARAMETER Remove PARAMETER from the binding table",
".print STRING... Print literal STRING",
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
".progress N Invoke progress handler after every N opcodes",
@ -7078,6 +7095,110 @@ static int do_meta_command(char *zLine, ShellState *p){
}
}else
if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
open_db(p,0);
if( nArg<=1 ) goto parameter_syntax_error;
/* .parameter clear
** Clear all bind parameters by dropping the TEMP table that holds them.
*/
if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.[" BIND_PARAM_TABLE "];",
0, 0, 0);
}else
/* .parameter list
** List all bind parameters.
*/
if( nArg==2 && strcmp(azArg[1],"list")==0 ){
sqlite3_stmt *pStmt = 0;
int rx;
int len = 0;
rx = sqlite3_prepare_v2(p->db,
"SELECT max(length(key)) "
"FROM temp.[" BIND_PARAM_TABLE "];", -1, &pStmt, 0);
if( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
len = sqlite3_column_int(pStmt, 0);
if( len>40 ) len = 40;
}
sqlite3_finalize(pStmt);
pStmt = 0;
if( len ){
rx = sqlite3_prepare_v2(p->db,
"SELECT key, quote(value) "
"FROM temp.[" BIND_PARAM_TABLE "];", -1, &pStmt, 0);
while( sqlite3_step(pStmt)==SQLITE_ROW ){
utf8_printf(p->out, "%-*s %s\n", len, sqlite3_column_text(pStmt,0),
sqlite3_column_text(pStmt,1));
}
sqlite3_finalize(pStmt);
}
}else
/* .parameter init
** Make sure the TEMP table used to hold bind parameters exists.
** Create it if necessary.
*/
if( nArg==2 && strcmp(azArg[1],"init")==0 ){
bind_table_init(p);
}else
/* .parameter set NAME VALUE
** Set or reset a bind parameter. NAME should be the full parameter
** name exactly as it appears in the query. (ex: $abc, @def). The
** VALUE can be in either SQL literal notation, or if not it will be
** understood to be a text string.
*/
if( nArg==4 && strcmp(azArg[1],"set")==0 ){
int rx;
char *zSql;
sqlite3_stmt *pStmt;
const char *zKey = azArg[2];
const char *zValue = azArg[3];
bind_table_init(p);
zSql = sqlite3_mprintf(
"REPLACE INTO temp.[" BIND_PARAM_TABLE "](key,value)"
"VALUES(%Q,%s);", zKey, zValue);
if( zSql==0 ) shell_out_of_memory();
pStmt = 0;
rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rx!=SQLITE_OK ){
sqlite3_finalize(pStmt);
pStmt = 0;
zSql = sqlite3_mprintf(
"REPLACE INTO temp.[" BIND_PARAM_TABLE "](key,value)"
"VALUES(%Q,%Q);", zKey, zValue);
if( zSql==0 ) shell_out_of_memory();
rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rx!=SQLITE_OK ){
utf8_printf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
pStmt = 0;
rc = 1;
}
}
sqlite3_step(pStmt);
sqlite3_finalize(pStmt);
}else
/* .parameter unset NAME
** Remove the NAME binding from the parameter binding table, if it
** exists.
*/
if( nArg==3 && strcmp(azArg[1],"unset")==0 ){
char *zSql = sqlite3_mprintf(
"DELETE FROM temp.[" BIND_PARAM_TABLE "] WHERE key=%Q", azArg[2]);
if( zSql==0 ) shell_out_of_memory();
sqlite3_exec(p->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}else
/* If no command name matches, show a syntax error */
parameter_syntax_error:
showHelp(p->out, "parameter");
}else
if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
int i;
for(i=1; i<nArg; i++){