︙ | | |
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
|
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
|
-
-
-
+
+
|
/* shell event subscription list */
int numSubscriptions; /* Number of active entries in below list */
struct EventSubscription {
ExtensionId eid;
void *pvUserData;
ShellEventNotify eventHandler;
} *pSubscriptions; /* The current shell event subscriptions */
u8 bDbDispatch; /* Cache fact of dbShell dispatch table */
#endif
ShellExState *pSXS; /* Pointer to companion, exposed shell state */
} ShellInState;
/*
** Limit input nesting via .read or any other input redirect.
** It's not too expensive, so a generous allowance can be made.
*/
#define MAX_INPUT_NESTING 25
/*
** This procedure updates the bSafeMode flag after completion of any
** operation (meta-command, SQL submission, or script execution) that
** counts as one for which safe mode might be suspended.
** operation (meta-command or SQL submission) that counts as one for
** which safe mode might be suspended.
** bSafeModeFuture has 3 states salient here:
** equal 0 => Safe mode is and will remain inactive.
** equal 1 => Safe mode is and will remain active.
** N > 1 => Safe mode is suspended for N-1 operations.
*/
static void updateSafeMode(ShellInState *psi){
switch( psi->bSafeModeFuture ){
|
︙ | | |
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
|
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
if( (psi->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
raw_printf(psi->out, "Progress %u\n", psi->nProgress);
}
return 0;
}
#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
/* For debugging or experimentation, the shell DB can be made file-based. */
#ifndef SHELL_DB_FILE
# define SHELL_DB_STORE ":memory:"
#else
# define SHELL_DB_STORE SHELL_STRINGIFY(SHELL_DB_FILE)
#endif
#define SHELL_DISP_SCHEMA "main"
#define SHELL_DISP_TAB "ShellCommands"
#define SHELL_DISP_VIEW "ShellActiveCmds"
/*
** Ensure dbShell exists and return SQLITE_OK,
** or complain and return SQLITE_ERROR.
*/
static int ensure_shell_db(ShellExState *psx){
if( psx->dbShell!=0 ) return SQLITE_OK;
else{
int rc = sqlite3_open(SHELL_DB_STORE, &psx->dbShell);
if( rc!=SQLITE_OK ){
utf8_printf(STD_ERR, "Shell DB open failure: %s\n", sqlite3_errstr(rc));
return SQLITE_ERROR;
}
#ifndef SQLITE_NOHAVE_SYSTEM
sqlite3_create_function(psx->dbShell, "edit", 1,
SQLITE_UTF8, 0, editFunc, 0, 0);
sqlite3_create_function(psx->dbShell, "edit", 2,
SQLITE_UTF8, 0, editFunc, 0, 0);
#endif
return rc;
}
}
/* Tell whether the above-created table exists, return true iff exists. */
static int dispatch_table_exists(sqlite3 *dbs){
return sqlite3_table_column_metadata
(dbs, SHELL_DISP_SCHEMA, SHELL_DISP_TAB, 0, 0, 0, 0, 0, 0)==SQLITE_OK;
}
static int ensure_dispatch_table(ShellExState *psx){
int rc = ensure_shell_db(psx);
if( rc==SQLITE_OK ){
char *zErr = 0;
int rc1, rc2;
if( dispatch_table_exists(psx->dbShell) ) return rc;
/* Create the dispatch table and view on it. */
#ifdef SHELL_DB_FILE
sqlite3_exec(psx->dbShell, "DROP TABLE IF EXISTS "SHELL_DISP_TAB, 0,0,0);
sqlite3_exec(psx->dbShell, "DROP VIEW IF EXISTS "SHELL_DISP_VIEW, 0,0,0);
#endif
rc1 = sqlite3_exec(psx->dbShell, "CREATE TABLE "SHELL_DISP_TAB"("
"name TEXT, extIx INT, cmdIx INT,"
"PRIMARY KEY(extIx,cmdIx)) WITHOUT ROWID", 0, 0, &zErr);
rc2 = sqlite3_exec(psx->dbShell,
"CREATE VIEW "SHELL_DISP_VIEW
" AS SELECT s.name AS name,"
" max(s.extIx) AS extIx, s.cmdIx AS cmdIx"
" FROM "SHELL_DISP_TAB" s GROUP BY name",
0, 0, &zErr);
if( rc1!=SQLITE_OK || rc2!=SQLITE_OK || zErr!=0 ){
utf8_printf(STD_ERR, "Shell DB init failure, %s\n", zErr? zErr : "?");
rc = SQLITE_ERROR;
}else rc = SQLITE_OK;
sqlite3_free(zErr);
}
return rc;
}
/*
** Skip over whitespace, returning remainder.
*/
static const char *skipWhite( const char *z ){
while( IsSpace(*z) ) ++z;
return z;
}
|
︙ | | |
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
|
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
char c = *zName;
switch( c ){
case '$': case ':': case '@': case '?': return PTU_Binding;
default: return isalpha(c)? PTU_Script : PTU_Nil;
}
}
#ifndef SQLITE_NOHAVE_SYSTEM
/* Possibly using a -editor=X argument and env-var VISUAL, attempt
* to get the zEditor shell state member set iff not already set.
* If there is no such argument, the env-var is retrieved if set.
* If the argument is -editor=X or --editor=X, use that and leave
* the zEditor member set accordingly. Returns are:
* 0 => editor set, zEd was not the -editor option
* 1 => editor set, zEd consumed as -editor option
* -1 => editor not set, and error/advice message issued.
*
* This implements an undocumented fall-back for the .vars and
* .parameters edit subcommands, so that users need not restart
* a shell session to get an editor specified upon need for it. */
int attempt_editor_set(ShellInState *psi, char *zDot, const char *zEd){
if( psi->zEditor==0 ){
const char *zE = getenv("VISUAL");
if( zE!=0 ) psi->zEditor = smprintf("%s", zE);
}
if( zEd && zEd[0]=='-' ){
zEd += 1 + (zEd[1]=='-');
if( strncmp(zEd,"editor=",7)==0 ){
sqlite3_free(psi->zEditor);
/* Accept an initial -editor=? option. */
psi->zEditor = smprintf("%s", zEd+7);
return 1;
}
}
if( psi->zEditor==0 ){
utf8_printf(STD_ERR,
"Either set env-var VISUAL to name an"
" editor and restart, or rerun\n "
".%s edit with an initial edit option,"
" --editor=EDITOR_COMMAND .\n", zDot);
return -1;
}
return 0;
}
#endif
/* The table kept for user DBs if .parameter command is used usefully. */
#define PARAM_TABLE_NAME "sqlite_parameters"
#define PARAM_TABLE_SCHEMA "temp"
#define PARAM_TABLE_SNAME PARAM_TABLE_SCHEMA"."PARAM_TABLE_NAME
/* The table kept for the shell DB if .vars command is used usefully. */
#define SHVAR_TABLE_NAME "sqlite_variables"
#define SHVAR_TABLE_SCHEMA "main"
#define SHVAR_TABLE_SNAME SHVAR_TABLE_SCHEMA"."SHVAR_TABLE_NAME
#ifndef SH_KV_STORE_NAME
#ifndef PARAM_STORE_NAME
/* Name for table keeping user's saved parameters */
# define SH_KV_STORE_NAME "SQLiteShell_KeyValuePairs"
# define PARAM_STORE_NAME "SQLiteShellParameters"
#endif
#ifndef SH_KV_STORE_SCHEMA
#ifndef PARAM_STORE_SCHEMA
/* Schema name used to attach saved parameters DB during load/save */
# define SH_KV_STORE_SCHEMA "SQLiteShell"
# define PARAM_STORE_SCHEMA "SQLiteShell"
#endif
#define SH_KV_STORE_SNAME SH_KV_STORE_SCHEMA"."SH_KV_STORE_NAME
#define PARAM_STORE_SNAME PARAM_STORE_SCHEMA"."PARAM_STORE_NAME
/* Create the TEMP table used to store parameter bindings */
/* Create the TEMP table used to store parameter bindings and SQL statements */
static void param_table_init(sqlite3 *db){
DbProtectState dps = allow_sys_schema_change(db);
sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS "PARAM_TABLE_SNAME"(\n"
" key TEXT PRIMARY KEY,\n"
" value,\n"
" uses INT DEFAULT (0)" /* aka PTU_Binding */
") WITHOUT ROWID;",
0, 0, 0);
restore_sys_schema_protection( db, &dps );
}
/* Tell whether the above-created table exists, return true iff exists. */
static int param_table_exists( sqlite3 *db ){
return sqlite3_table_column_metadata
(db, PARAM_TABLE_SCHEMA, PARAM_TABLE_NAME, 0, 0, 0, 0, 0, 0)==SQLITE_OK;
}
/* Create the shell DB table used to store shell variables or scripts */
static int shvars_table_init(sqlite3 *db){
DbProtectState dps = allow_sys_schema_change(db);
int rc = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS "SHVAR_TABLE_SNAME"(\n"
" key TEXT PRIMARY KEY,\n"
" value,\n"
" uses INT DEFAULT (0)" /* aka PTU_Binding */
") WITHOUT ROWID;",
0, 0, 0);
restore_sys_schema_protection( db, &dps );
return rc!=SQLITE_OK;
}
/* Tell whether the above-created table exists, return true iff exists. */
static int shvars_table_exists( sqlite3 *db ){
return sqlite3_table_column_metadata
(db, SHVAR_TABLE_SCHEMA, SHVAR_TABLE_NAME, 0, 0, 0, 0, 0, 0)==SQLITE_OK;
}
/* Make shell vars table exist. */
static int ensure_shvars_table(sqlite3 *dbs){
if( shvars_table_exists(dbs) ) return SQLITE_OK;
else return shvars_table_init(dbs);
}
/*
** Bind parameters on a prepared statement.
**
** Parameter bindings are taken from a TEMP table of the form:
**
** CREATE TEMP TABLE
** sqlite_parameters(key TEXT PRIMARY KEY, value, uses INT)
|
︙ | | |
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
|
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
|
-
+
|
/* Register a meta-command, to be called during extension load/init. */
static int register_meta_command(ShellExState *p,
ExtensionId eid, MetaCommand *pMC){
ShellInState *psi = ISS(p);
ShExtInfo *psei = pending_ext_info(psi);
const char *zSql
= "INSERT INTO "SHELL_DISP_TAB"(name, extIx, cmdIx) VALUES(?, ?, ?)";
= "INSERT INTO ShellCommands (name, extIx, cmdIx) VALUES(?, ?, ?)";
int ie = psi->ixExtPending;
assert(psi->pShxLoaded!=0 && p->dbShell!=0);
if( pMC==0 ) return SQLITE_ERROR;
else{
const char *zName = pMC->pMethods->name(pMC);
sqlite3_stmt *pStmt;
int nc = psei->numMetaCommands;
|
︙ | | |
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
|
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
|
-
+
-
|
ExtensionId eid, ImportHandler *pIH){
return SQLITE_ERROR;
}
static int register_scripting(ShellExState *p, ExtensionId eid,
ScriptSupport *pSS){
ShellInState *psi = ISS(p);
if( psi->scriptXid!=0 || psi->script!=0 ){
if( psi->scriptXid!=0 ){
/* Scripting support already provided. Only one provider is allowed. */
return SQLITE_BUSY;
}
if( eid==0 || pSS==0 || psi->ixExtPending==0 ){
/* Scripting addition allowed only when sqlite3_*_init() runs. */
return SQLITE_MISUSE;
}
psi->script = pSS;
psi->scriptXid = eid;
return SQLITE_OK;
}
|
︙ | | |
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
|
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
|
+
+
+
+
+
+
-
+
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
|
break;
default:
pv = 0;
}
if( pv==0 ) sqlite3_result_null(context);
else sqlite3_result_pointer(context, pv, SHELLEXT_API_POINTERS, 0);
}
#ifndef SHELL_DB_FILE
# define SHELL_DB_STORE ":memory:"
#else
# define SHELL_DB_STORE SHELL_STRINGIFY(SHELL_DB_FILE)
#endif
/* Do the initialization needed for use of dbShell for command lookup
* and dispatch and for I/O handler lookup and dispatch.
*/
static int begin_db_dispatch(ShellExState *psx){
ShellInState *psi = ISS(psx);
sqlite3_stmt *pStmt = 0;
int ic, rc1, rc2;
int ic, rc, rc1, rc2;
int rc = 0;
char *zErr = 0;
const char *zSql;
ShExtInfo sei = {0};
/* Consider: Store these dynamic arrays in the DB as indexed-into blobs. */
assert(psx->dbShell==0 || (psi->numExtLoaded==0 && psi->pShxLoaded==0));
assert(psx->dbShell==0 && psi->numExtLoaded==0 && psi->pShxLoaded==0);
rc = ensure_shell_db(psx);
if( rc!=SQLITE_OK ){
utf8_printf(STD_ERR, "Error: Shell DB uncreatable. Best to .quit soon.\n");
return SQLITE_ERROR;
}
if( ensure_dispatch_table(psx)!=SQLITE_OK ) return 1;
psi->pShxLoaded = (ShExtInfo *)sqlite3_malloc(2*sizeof(ShExtInfo));
sei.ppMetaCommands
= (MetaCommand **)sqlite3_malloc((numCommands+2)*sizeof(MetaCommand *));
sei.ppExportHandlers
= (ExportHandler **)sqlite3_malloc(2*sizeof(ExportHandler *));
sei.ppImportHandlers
= (ImportHandler **)sqlite3_malloc(2*sizeof(ImportHandler *));
if( sei.ppMetaCommands==0||sei.ppExportHandlers==0||sei.ppImportHandlers==0
|| psi->pShxLoaded==0 ){
shell_out_of_memory();
}
sei.numExportHandlers = 0;
sei.numImportHandlers = 0;
for( ic=0; ic<numCommands; ++ic ){
sei.ppMetaCommands[ic] = builtInCommand(ic);
}
sei.numMetaCommands = ic;
psi->pShxLoaded[psi->numExtLoaded++] = sei;
rc = sqlite3_open(SHELL_DB_STORE, &psx->dbShell);
if( rc!=SQLITE_OK ) return 1;
#ifdef SHELL_DB_FILE
sqlite3_exec(psx->dbShell, "DROP TABLE IF EXISTS ShellCommands", 0,0,0);
sqlite3_exec(psx->dbShell, "DROP VIEW IF EXISTS ActiveCommands", 0,0,0);
#endif
rc1 = sqlite3_exec(psx->dbShell, "CREATE TABLE ShellCommands("
"name TEXT, extIx INT, cmdIx INT,"
"PRIMARY KEY(extIx,cmdIx)) WITHOUT ROWID",
0, 0, &zErr);
rc2 = sqlite3_exec(psx->dbShell, "CREATE VIEW ActiveCommands AS SELECT "
"s.name AS name, max(s.extIx) AS extIx, s.cmdIx AS cmdIx "
"FROM ShellCommands s GROUP BY name",
0, 0, &zErr);
if( rc1!=SQLITE_OK || rc2!=SQLITE_OK || zErr!=0 ){
utf8_printf(STD_ERR, "Shell DB init failure, %s\n", zErr? zErr : "");
return 1;
}
zSql = "INSERT INTO "SHELL_DISP_TAB"(name, extIx, cmdIx) VALUES(?, 0, ?)";
zSql = "INSERT INTO ShellCommands (name, extIx, cmdIx) VALUES(?, 0, ?)";
rc1 = sqlite3_prepare_v2(psx->dbShell, zSql, -1, &pStmt, 0);
rc2 = sqlite3_exec(psx->dbShell, "BEGIN TRANSACTION", 0, 0, &zErr);
if( rc1!=SQLITE_OK || rc2!=SQLITE_OK ) return 1;
assert(sei.numMetaCommands>0);
for( ic=0; ic<sei.numMetaCommands; ++ic ){
MetaCommand *pmc = sei.ppMetaCommands[ic];
const char *zName = pmc->pMethods->name(pmc);
sqlite3_reset(pStmt);
sqlite3_bind_text(pStmt, 1, zName, -1, 0);
sqlite3_bind_int(pStmt, 2, ic);
rc = sqlite3_step(pStmt);
if( rc!=SQLITE_DONE ){
sqlite3_exec(psx->dbShell, "ABORT", 0, 0, 0);
break;
}
}
sqlite3_finalize(pStmt);
if( rc!=SQLITE_DONE ) return 1;
rc = sqlite3_exec(psx->dbShell, "COMMIT", 0, 0, &zErr);
sqlite3_enable_load_extension(psx->dbShell, 1);
sqlite3_free(zErr);
psi->bDbDispatch = 1;
return SQLITE_OK;
}
/* Call one loaded extension's destructors, in reverse order
* of their objects' creation, then free the tracking dyna-arrays.
*/
static void free_one_shext_tracking(ShExtInfo *psei){
|
︙ | | |
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
|
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
|
-
+
|
ShellInState *psi = ISS(psx);
/* save script support state for possible fallback if load fails */
ScriptSupport *pssSave = psi->script;
ExtensionId ssiSave = psi->scriptXid;
int rc;
if( pzErr ) *pzErr = 0;
if( psx->dbShell==0 || ISS(psx)->numExtLoaded==0 ){
if( psx->dbShell==0 ){
rc = begin_db_dispatch(psx);
if( rc!=SQLITE_OK ) return rc;
assert(ISS(psx)->numExtLoaded==1 && psx->dbShell!=0);
}
psi->ixExtPending = psi->numExtLoaded;
sqlite3_create_function(psx->dbShell, "shext_pointer", 1,
SQLITE_DIRECTONLY|SQLITE_UTF8,
|
︙ | | |
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
|
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
|
-
+
-
+
-
+
-
+
|
DISPATCHABLE_COMMAND( nullvalue ? 2 2 ){
sqlite3_snprintf(sizeof(ISS(p)->nullValue), ISS(p)->nullValue, "%.*s",
(int)ArraySize(ISS(p)->nullValue)-1, azArg[1]);
return DCR_Ok;
}
/* Helper functions for .parameter and .vars commands
/* Helper functions for .parameter command
*/
struct keyval_row { char * value; int uses; int hits; };
struct param_row { char * value; int uses; int hits; };
static int kv_find_callback(void *pData, int nc, char **pV, char **pC){
static int param_find_callback(void *pData, int nc, char **pV, char **pC){
assert(nc>=1);
assert(strcmp(pC[0],"value")==0);
struct keyval_row *pParam = (struct keyval_row *)pData;
struct param_row *pParam = (struct param_row *)pData;
assert(pParam->value==0); /* key values are supposedly unique. */
if( pParam->value!=0 ) sqlite3_free( pParam->value );
pParam->value = smprintf("%s", pV[0]); /* source owned by statement */
if( nc>1 ) pParam->uses = (int)integerValue(pV[1]);
++pParam->hits;
return 0;
}
|
︙ | | |
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
|
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
|
-
+
-
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
-
-
-
-
-
-
-
+
-
+
-
-
-
+
+
-
+
-
-
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
-
-
-
-
-
-
-
+
-
-
+
-
-
+
+
-
+
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
+
-
+
+
-
+
-
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
* If it is an empty list, all parameters will be saved or loaded.
* Otherwise, only the named parameters are transferred, if they exist.
* It is not an error to specify a name that cannot be transferred
* because it does not exist in the source table.
*
* Returns are SQLITE_OK for success, or other codes for failure.
*/
static int kv_xfr_table(sqlite3 *db, const char *zStoreDbName,
static int param_xfr_table(sqlite3 *db, const char *zStoreDbName,
int bSaveNotLoad, ParamTableUse ptu,
const char *azNames[], int nNames){
int bSaveNotLoad, const char *azNames[], int nNames){
int rc = 0;
char *zSql = 0; /* to be sqlite3_free()'ed */
sqlite3_str *sbCopy = 0;
const char *zHere = 0;
const char *zThere = SH_KV_STORE_SNAME;
const char *zTo;
const char *zFrom;
const char *zHere = PARAM_TABLE_SNAME;
const char *zThere = PARAM_STORE_SNAME;
const char *zTo = (bSaveNotLoad)? zThere : zHere;
const char *zFrom = (bSaveNotLoad)? zHere : zThere;
sqlite3 *dbStore = 0;
int openFlags = (bSaveNotLoad)
? SQLITE_OPEN_URI|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE
: SQLITE_OPEN_READONLY;
switch( ptu ){
case PTU_Binding: zHere = PARAM_TABLE_SNAME; break;
case PTU_Script: zHere = SHVAR_TABLE_SNAME; break;
default: assert(0); return 1;
}
zTo = (bSaveNotLoad)? zThere : zHere;
zFrom = (bSaveNotLoad)? zHere : zThere;
/* Ensure store DB can be opened and/or created appropriately. */
rc = sqlite3_open_v2(zStoreDbName, &dbStore, openFlags, 0);
if( rc!=SQLITE_OK ){
utf8_printf(STD_ERR, "Error: Cannot %s key/value store DB %s\n",
utf8_printf(STD_ERR, "Error: Cannot %s parameter store DB %s\n",
bSaveNotLoad? "open/create" : "read", zStoreDbName);
return rc;
}
/* Ensure it has the kv store table, or handle its absence. */
/* Ensure it has the parameter store table, or handle its absence. */
assert(dbStore!=0);
if( sqlite3_table_column_metadata
(dbStore, "main", SH_KV_STORE_NAME, 0, 0, 0, 0, 0, 0)!=SQLITE_OK ){
(dbStore, "main", PARAM_STORE_NAME, 0, 0, 0, 0, 0, 0)!=SQLITE_OK ){
if( !bSaveNotLoad ){
utf8_printf(STD_ERR, "Error: No key/value pairs ever stored in DB %s\n",
utf8_printf(STD_ERR, "Error: No parameters ever stored in DB %s\n",
zStoreDbName);
rc = 1;
}else{
/* The saved parameters table is not there yet; create it. */
const char *zCT =
"CREATE TABLE IF NOT EXISTS "SH_KV_STORE_NAME"(\n"
"CREATE TABLE IF NOT EXISTS "PARAM_STORE_NAME"(\n"
" key TEXT PRIMARY KEY,\n"
" value,\n"
" uses INT\n"
") WITHOUT ROWID;";
rc = sqlite3_exec(dbStore, zCT, 0, 0, 0);
if( rc!=SQLITE_OK ){
utf8_printf(STD_ERR, "Cannot create table %s. Nothing saved.", zThere);
}
}
}
sqlite3_close(dbStore);
if( rc!=0 ) return rc;
zSql = smprintf("ATTACH %Q AS %s;", zStoreDbName, SH_KV_STORE_SCHEMA);
zSql = smprintf("ATTACH %Q AS %s;", zStoreDbName, PARAM_STORE_SCHEMA);
shell_check_oom(zSql);
rc = sqlite3_exec(db, zSql, 0, 0, 0);
sqlite3_free(zSql);
if( rc!=SQLITE_OK ) return rc;
sbCopy = sqlite3_str_new(db);
sqlite3_str_appendf
(sbCopy, "INSERT OR REPLACE INTO %s(key,value,uses)"
"SELECT key, value, uses FROM %s WHERE key ", zTo, zFrom);
append_in_clause(sbCopy, azNames, azNames+nNames);
zSql = sqlite3_str_finish(sbCopy);
shell_check_oom(zSql);
rc = sqlite3_exec(db, zSql, 0, 0, 0);
sqlite3_free(zSql);
sqlite3_exec(db, "DETACH "SH_KV_STORE_SCHEMA";", 0, 0, 0);
sqlite3_exec(db, "DETACH "PARAM_STORE_SCHEMA";", 0, 0, 0);
return rc;
}
/* Default locations of kv store DBs for .parameters and .vars save/load. */
/* Default location of parameters store DB for .parameters save/load. */
static const char *zDefaultParamStore = "~/sqlite_params.sdb";
static const char *zDefaultVarStore = "~/sqlite_vars.sdb";
/* Possibly generate a derived path from input spec, with defaulting
* and conversion of leading (or only) tilde as home directory.
* The above-set default is used for zSpec NULL, "" or "~".
* When return is 0, there is an error; what needs doing cannnot be done.
* If the return is exactly the input, it must not be sqlite3_free()'ed.
* If the return differs from the input, it must be sqlite3_free()'ed.
*/
static const char *kv_store_path(const char *zSpec, ParamTableUse ptu){
static const char *params_store_path(const char *zSpec){
if( zSpec==0 || zSpec[0]==0 || strcmp(zSpec,"~")==0 ){
const char *zDef;
switch( ptu ){
case PTU_Binding: zDef = zDefaultParamStore; break;
case PTU_Script: zDef = zDefaultVarStore; break;
default: return 0;
}
return home_based_path(zDef);
return home_based_path(zDefaultParamStore);
}else if ( zSpec[0]=='~' ){
return home_based_path(zSpec);
}
return zSpec;
}
/* Load some or all kv pairs. Arguments are "load FILE ?NAMES?". */
/* Load some or all parameters. Arguments are "load FILE ?NAMES?". */
static int kv_pairs_load(sqlite3 *db, ParamTableUse ptu,
const char *azArg[], int nArg){
const char *zStore = kv_store_path((nArg>1)? azArg[1] : 0, ptu);
static int parameters_load(sqlite3 *db, const char *azArg[], int nArg){
const char *zStore = params_store_path((nArg>1)? azArg[1] : 0);
if( zStore==0 ){
utf8_printf(STD_ERR, "Cannot form parameter load path. Nothing loaded.\n");
return DCR_Error;
}else{
const char **pzFirst = (nArg>2)? azArg+2 : 0;
int nNames = (nArg>2)? nArg-2 : 0;
int rc = kv_xfr_table(db, zStore, 0, ptu, pzFirst, nNames);
int rc = param_xfr_table(db, zStore, 0, pzFirst, nNames);
if( nArg>1 && zStore!=azArg[1] ) sqlite3_free((void*)zStore);
return rc;
}
}
/* Save some or all parameters. Arguments are "save FILE ?NAMES?". */
static int kv_pairs_save(sqlite3 *db, ParamTableUse ptu,
const char *azArg[], int nArg){
const char *zStore = kv_store_path((nArg>1)? azArg[1] : 0, ptu);
static int parameters_save(sqlite3 *db, const char *azArg[], int nArg){
const char *zStore = params_store_path((nArg>1)? azArg[1] : 0);
if( zStore==0 ){
utf8_printf(STD_ERR, "Cannot form parameter save path. Nothing saved.\n");
return DCR_Error;
}else{
const char **pzFirst = (nArg>2)? azArg+2 : 0;
int nNames = (nArg>2)? nArg-2 : 0;
int rc = kv_xfr_table(db, zStore, 1, ptu, pzFirst, nNames);
int rc = param_xfr_table(db, zStore, 1, pzFirst, nNames);
if( nArg>1 && zStore!=azArg[1] ) sqlite3_free((void*)zStore);
return rc;
}
}
#ifndef SQLITE_NOHAVE_SYSTEM
/*
* Edit one named value in the parameters or shell variables table.
* If it does not yet exist, create it. If eval is true, the value
* is treated as a bare expression, otherwise it is a text value.
* The "uses" argument sets the 3rd column in the selected table,
* and serves to select which of the two tables is modified.
* Edit one named parameter in the parameters table. If it does not
* yet exist, create it. If eval is true, the value is treated as a
* bare expression, otherwise it is a text value. The uses argument
* sets the 3rd column in the parameters table, and may also serve
* to partition the key namespace. (This is not done now.)
*/
static int edit_one_kvalue(sqlite3 *db, char *name, int eval,
ParamTableUse uses, const char * zEditor){
struct keyval_row kvRow = {0,0,0};
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;
const char *zTab = 0;
char * zSql = 0;
char * zSql = smprintf
switch( uses ){
case PTU_Script: zTab = SHVAR_TABLE_SNAME; break;
case PTU_Binding: zTab = PARAM_TABLE_SNAME; break;
default: assert(0);
}
zSql = smprintf("SELECT value, uses FROM %s "
("SELECT value, uses FROM " PARAM_TABLE_SNAME " WHERE key=%Q", name);
"WHERE key=%Q AND uses=%d", zTab, name, uses);
shell_check_oom(zSql);
sqlite3_exec(db, zSql, kv_find_callback, &kvRow, 0);
sqlite3_exec(db, zSql, param_find_callback, ¶mVU, 0);
sqlite3_free(zSql);
assert(kvRow.hits<2);
if( kvRow.hits==1 && kvRow.uses==uses){
assert(paramVU.hits<2);
if( paramVU.hits==1 && paramVU.uses==uses){
/* Editing an existing value of same kind. */
sqlite3_free(kvRow.value);
sqlite3_free(paramVU.value);
if( eval!=0 ){
zSql = smprintf("SELECT edit(value, %Q) FROM %s "
"WHERE key=%Q AND uses=%d", zEditor, zTab, name, uses);
zSql = smprintf
("SELECT edit(value, %Q) FROM " PARAM_TABLE_SNAME
" WHERE key=%Q AND uses=%d", zEditor, name, uses);
shell_check_oom(zSql);
zVal = db_text(db, zSql, 1);
sqlite3_free(zSql);
zSql = smprintf("UPDATE %s SET value=(SELECT %s) "
"WHERE key=%Q AND uses=%d", zTab, zVal, name, uses);
zSql = smprintf
("UPDATE "PARAM_TABLE_SNAME" SET value=(SELECT %s) WHERE"
" key=%Q AND uses=%d", zVal, name, uses);
}else{
zSql = smprintf("UPDATE %s SET value=edit(value, %Q) WHERE"
" key=%Q AND uses=%d", zTab, zEditor, name, uses);
zSql = smprintf
("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(kvRow.value==0 || kvRow.uses!=uses);
assert(paramVU.value==0 || paramVU.uses!=uses);
if( eval!=0 ){
zSql = smprintf
zSql = smprintf("SELECT edit('-- %q%s', %Q)", name, "\n", zEditor);
("SELECT edit('-- %q%s', %Q)", name, "\n", zEditor);
zVal = db_text(db, zSql, 1);
sqlite3_free(zSql);
zSql = smprintf("INSERT INTO %s(key,value,uses)"
zSql = smprintf
("INSERT INTO "PARAM_TABLE_SNAME"(key,value,uses)"
" VALUES (%Q,(SELECT %s LIMIT 1),%d)",
zTab, name, zVal, uses);
name, zVal, uses);
}else{
zSql = smprintf("INSERT INTO %s(key,value,uses)"
" VALUES (%Q,edit('-- %q;%s', %Q),%d)",
zTab, name, name, "\n", zEditor, uses);
zSql = smprintf
("INSERT INTO "PARAM_TABLE_SNAME"(key,value,uses)"
" VALUES (%Q,edit('-- %q%s', %Q),%d)",
name, name, "\n", zEditor, uses);
}
}
shell_check_oom(zSql);
if( eval!=0 ){
}
rc = sqlite3_exec(db, zSql, 0, 0, 0);
sqlite3_free(zSql);
sqlite3_free(zVal);
return rc!=SQLITE_OK;
}
#endif
/* Space-join values in an argument list. *valLim is not included. */
char *values_join( char **valBeg, char **valLim ){
char *z = 0;
const char *zSep = 0;
while( valBeg < valLim ){
z = smprintf("%z%s%s", z, zSep, *valBeg);
zSep = " ";
++valBeg;
}
return z;
}
/* Get a named parameter value in form of stepped prepared statement,
* ready to have its value taken from the 0th column. If the name
* cannot be found for the given ParamTableUse, 0 is returned.
* The caller is responsible for calling sqlite3_finalize(pStmt),
* where pStmt is the return from this function.
*/
static sqlite3_stmt *get_param_value(sqlite3 *db, char *name,
ParamTableUse ptu){
sqlite3_stmt *rv = 0;
int rc;
char *zSql = smprintf
( "SELECT value FROM "PARAM_TABLE_SNAME
" WHERE key=%Q AND uses=%d", name, ptu );
shell_check_oom(zSql);
rc = sqlite3_prepare_v2(db, zSql, -1, &rv, 0);
sqlite3_free(zSql);
if( SQLITE_OK==rc ){
if( SQLITE_ROW==sqlite3_step(rv) ) return rv;
sqlite3_finalize(rv);
}
return 0;
}
static struct ParamSetOpts {
const char cCast;
const char *zTypename;
int evalKind;
} param_set_opts[] = {
/* { 'q', 0, 2 }, */
|
︙ | | |
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
|
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
-
+
-
-
+
-
+
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
|
++zArg;
if( zArg[0]=='-' ) ++zArg;
if( zArg[0]!=0 && zArg[1]==0 ) return zArg[0];
}
return 0;
}
/* Most of .vars set
* Return SQLITE_OK on success, else SQLITE_ERROR.
*/
static int shvar_set(sqlite3 *db, char *name, char **valBeg, char **valLim){
int rc = SQLITE_OK;
char *zValGlom = (valLim-valBeg>1)? values_join(valBeg, valLim) : 0;
sqlite3_stmt *pStmtSet = 0;
char *zValue = (zValGlom==0)? *valBeg : zValGlom;
char *zSql
= smprintf("REPLACE INTO "SHVAR_TABLE_SNAME"(key,value,uses)"
"VALUES(%Q,%Q,%d);", name, zValue, PTU_Script);
shell_check_oom(zSql);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmtSet, 0);
assert(rc==SQLITE_OK);
sqlite3_free(zSql);
rc = (SQLITE_DONE==sqlite3_step(pStmtSet))? SQLITE_OK : SQLITE_ERROR;
sqlite3_finalize(pStmtSet);
sqlite3_free(zValGlom);
return rc;
}
/* Most of the .parameter set subcommand (per help text)
/* The set subcommand (per help text)
*/
static int param_set(sqlite3 *db, char cCast,
char *name, char **valBeg, char **valLim){
char *name, char **valBeg, char **valLim,
ParamTableUse ptu){
char *zSql = 0;
int rc = SQLITE_OK, retries = 0, needsEval = 1;
char *zValGlom = (valLim-valBeg>1)? values_join(valBeg, valLim) : 0;
sqlite3_stmt *pStmtSet = 0;
const char *zCastTo = 0;
char *zValue = (zValGlom==0)? *valBeg : zValGlom;
if( cCast ){
struct ParamSetOpts *pSO = param_set_opts;
for(; pSO-param_set_opts < ArraySize(param_set_opts); ++pSO ){
if( cCast==pSO->cCast ){
zCastTo = pSO->zTypename;
needsEval = pSO->evalKind > 0;
break;
}
}
}
if( needsEval ){
if( zCastTo!=0 ){
zSql = smprintf
( "REPLACE INTO "PARAM_TABLE_SNAME"(key,value,uses)"
" VALUES(%Q,CAST((%s) AS %s),%d);",
" VALUES(%Q,CAST((%s) AS %s),%d);", name, zValue, zCastTo, ptu );
name, zValue, zCastTo, PTU_Binding );
}else{
zSql = smprintf
( "REPLACE INTO "PARAM_TABLE_SNAME"(key,value,uses)"
"VALUES(%Q,(%s),%d);", name, zValue, PTU_Binding );
"VALUES(%Q,(%s),%d);", name, zValue, ptu );
}
shell_check_oom(zSql);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmtSet, 0);
sqlite3_free(zSql);
}
if( !needsEval || rc!=SQLITE_OK ){
/* Reach here when value either requested to be cast to text, or must be. */
sqlite3_finalize(pStmtSet);
pStmtSet = 0;
zSql = smprintf
( "REPLACE INTO "PARAM_TABLE_SNAME"(key,value,uses)"
"VALUES(%Q,%Q,%d);", name, zValue, PTU_Binding );
"VALUES(%Q,%Q,%d);", name, zValue, ptu );
shell_check_oom(zSql);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmtSet, 0);
assert(rc==SQLITE_OK);
sqlite3_free(zSql);
}
sqlite3_step(pStmtSet);
sqlite3_finalize(pStmtSet);
sqlite3_free(zValGlom);
return rc;
}
/* list or ls subcommand for .parameter and .vars dot-commands */
static void list_pov_entries(ShellExState *psx, ParamTableUse ptu, u8 bShort,
char **pzArgs, int nArg){
/* list or ls subcommand for .parameter dot-command */
static void list_params(ShellExState *psx, ParamTableUse ptu, u8 bShort,
char **pzArgs, int nArg){
sqlite3_stmt *pStmt = 0;
sqlite3 *db = DBX(psx);
sqlite3_str *sbList;
sqlite3_str *sbList = sqlite3_str_new(db);
int len = 0, rc;
char *zFromWhere = 0;
char *zSql = 0;
sqlite3 *db;
const char *zTab;
switch( ptu ){
case PTU_Binding:
db = DBX(psx);
zTab = PARAM_TABLE_SNAME;
break;
case PTU_Script:
db = psx->dbShell;
zTab = SHVAR_TABLE_NAME;
break;
default: assert(0); return;
}
sbList = sqlite3_str_new(db);
sqlite3_str_appendf(sbList, "FROM ");
sqlite3_str_appendf(sbList, "FROM "PARAM_TABLE_SNAME
sqlite3_str_appendf(sbList, zTab);
sqlite3_str_appendf(sbList, " WHERE (uses=?1) AND ");
" WHERE (?1=3 OR uses=?1) AND ");
append_glob_terms(sbList, "key",
(const char **)pzArgs, (const char **)pzArgs+nArg);
zFromWhere = sqlite3_str_finish(sbList);
shell_check_oom(zFromWhere);
zSql = smprintf("SELECT max(length(key)) %s", zFromWhere);
shell_check_oom(zSql);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
︙ | | |
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
|
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
|
-
+
-
-
-
+
+
+
+
|
".parameter CMD ... Manage SQL parameter bindings and scripts table",
" clear ?NAMES? Erase all or only given named parameters",
#ifndef SQLITE_NOHAVE_SYSTEM
" edit ?OPT? NAME ... Use edit() to create or alter parameter NAME",
" OPT may be -t to use edited value as text or -e to evaluate it.",
#endif
" init Initialize TEMP table for bindings and scripts",
" list ?PATTERNS? List current DB parameters table binding values",
" list ?PATTERNS? List parameters table binding and script values",
" Alternatively, to list just some or all names: ls ?PATTERNS?",
" load ?FILE? ?NAMES? Load some or all named parameters from FILE",
" If FILE missing, empty or '~', it defaults to ~/sqlite_params.sdb",
" save ?FILE? ?NAMES? Save some or all named parameters into FILE",
" If FILE missing, empty or '~', it defaults to ~/sqlite_params.sdb",
" set ?TOPT? NAME VALUE Give SQL parameter NAME a value of VALUE",
" NAME must begin with one of $,:,@,? for bindings, VALUE is the space-",
" joined argument list. TOPT may be one of {-b -i -n -r -t} to cast the",
" effective value to BLOB, INT, NUMERIC, REAL or TEXT respectively.",
" NAME must begin with one of $,:,@,? for bindings, or with a letter",
" to be executable; value is the space-joined argument list.",
" Option TOPT may be one of {-b -i -n -r -t} to cast effective value",
" to BLOB, INT, NUMERIC, REAL or TEXT respectively.",
" unset ?NAMES? Remove named parameter(s) from parameters table",
];
DISPATCHABLE_COMMAND( parameter 2 2 0 ){
int rc = 0;
open_db(p,0);
sqlite3 *db = DBX(p);
|
︙ | | |
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
|
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
|
+
-
-
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
|
sqlite3_exec(db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
}else
#ifndef SQLITE_NOHAVE_SYSTEM
/* .parameter edit ?NAMES?
** Edit the named parameters. Any that do not exist are created.
** New ones get a uses tag auto-selected by their leading char.
*/
if( strcmp(azArg[1],"edit")==0 ){
ShellInState *psi = ISS(p);
int ia = 2;
int eval = 0;
int edSet;
if( !INSOURCE_IS_INTERACTIVE(psi->pInSource) ){
utf8_printf(STD_ERR, "Error: "
".parameter edit can only be used interactively.\n");
return DCR_Error;
}
param_table_init(db);
if( psi->zEditor==0 ){
const char *zE = getenv("VISUAL");
if( zE!=0 ) psi->zEditor = smprintf("%s", zE);
}
if( nArg>=3 && azArg[2][0]=='-' ){
edSet = attempt_editor_set(psi, azArg[0], (nArg>2)? azArg[2] : 0 );
if( edSet < 0 ) return DCR_Error;
char *zArg = (azArg[2][1]=='-')? azArg[2]+2 : azArg[2]+1;
if( strncmp(zArg,"editor=",7)==0 ){
sqlite3_free(psi->zEditor);
/* Accept an initial -editor=? option. */
psi->zEditor = smprintf("%s", zArg+7);
++ia;
}
}
if( psi->zEditor==0 ){
utf8_printf(STD_ERR,
"Either set env-var VISUAL to name an"
" editor and restart, or rerun\n "
".parameter edit with an initial "
"edit option, --editor=EDITOR_COMMAND .\n");
return DCR_Error;
else ia += edSet;
}
/* Future: Allow an option whereby new value can be evaluated
* the way that .parameter set ... does.
*/
while( ia < nArg ){
ParamTableUse ptu;
char *zA = azArg[ia];
char cf = (zA[0]=='-')? zA[1] : 0;
if( cf!=0 && zA[2]==0 ){
char cf = (azArg[ia][0]=='-')? azArg[ia][1] : 0;
if( cf!=0 && azArg[ia][2]==0 ){
++ia;
switch( cf ){
case 'e': eval = 1; continue;
case 't': eval = 0; continue;
default:
utf8_printf(STD_ERR, "Error: bad .parameter name: %s\n", zA);
utf8_printf(STD_ERR, "Error: bad .parameter name: %s\n",
azArg[--ia]);
return DCR_Error;
}
}
ptu = classify_param_name(zA);
if( ptu!=PTU_Binding ){
utf8_printf(STD_ERR, "Error: "
"%s cannot be a binding parameter name.\n", zA);
ptu = classify_param_name(azArg[ia]);
if( ptu==PTU_Nil ){
utf8_printf(STD_ERR, "Error: %s cannot be a binding or executable"
" parameter name.\n", azArg[ia]);
return DCR_Error;
}
rc = edit_one_kvalue(db, zA, eval, ptu, psi->zEditor);
rc = edit_one_param(db, azArg[ia], eval, ptu, psi->zEditor);
++ia;
if( rc!=0 ) return DCR_Error;
if( rc!=0 ) return rc;
}
}else
#endif
/* .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 ){
param_table_init(db);
}else
/* .parameter list|ls
** List all or selected bind parameters.
** list displays names, values and uses.
** ls displays just the names.
*/
if( nArg>=2 && ((strcmp(azArg[1],"list")==0)
|| (strcmp(azArg[1],"ls")==0)) ){
list_pov_entries(p, PTU_Binding, azArg[1][1]=='s', azArg+2, nArg-2);
list_params(p, PTU_Nil, azArg[1][1]=='s', azArg+2, nArg-2);
}else
/* .parameter load
** Load all or named parameters from specified or default (DB) file.
*/
if( strcmp(azArg[1],"load")==0 ){
param_table_init(db);
rc = kv_pairs_load(db, PTU_Binding, (const char **)azArg+1, nArg-1);
rc = parameters_load(db, (const char **)azArg+1, nArg-1);
}else
/* .parameter save
** Save all or named parameters into specified or default (DB) file.
*/
if( strcmp(azArg[1],"save")==0 ){
rc = kv_pairs_save(db, PTU_Binding, (const char **)azArg+1, nArg-1);
rc = parameters_save(db, (const char **)azArg+1, nArg-1);
}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 ){
char cCast = option_char(azArg[2]);
int inv = 2 + (cCast != 0);
ParamTableUse ptu = classify_param_name(azArg[inv]);
if( ptu!=PTU_Binding ){
if( ptu==PTU_Nil ){
utf8_printf(STD_ERR,
"Error: %s is not a usable parameter name.\n", azArg[inv]);
rc = 1;
}else{
param_table_init(db);
rc = param_set(db, cCast, azArg[inv], &azArg[inv+1], &azArg[nArg]);
rc = param_set(db, cCast, azArg[inv],
&azArg[inv+1], &azArg[nArg], ptu);
if( rc!=SQLITE_OK ){
utf8_printf(STD_ERR, "Error: %s\n", sqlite3_errmsg(db));
rc = 1;
}
}
}else
{ /* If no command name and arg count matches, show a syntax error */
showHelp(ISS(p)->out, "parameter", p);
return DCR_CmdErred;
}
return DCR_Ok | (rc!=0);
return rc;
}
/*****************
* The .print, .progress and .prompt commands
*/
CONDITION_COMMAND( progress !defined(SQLITE_OMIT_PROGRESS_CALLBACK) );
COLLECT_HELP_TEXT[
|
︙ | | |
13013
13014
13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
13045
13046
13047
13048
13049
13050
13051
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070
13071
13072
13073
13074
13075
13076
13077
13078
13079
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102
13103
13104
13105
13106
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
|
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
}
}else{
goto teach_fail;
}
return DCR_Ok;
}
/*****************
* The .vars command
*/
COLLECT_HELP_TEXT[
".vars ?OPTIONS? ... Manipulate and display shell variables",
" clear ?NAMES? Erase all or only given named variables",
#ifndef SQLITE_NOHAVE_SYSTEM
" edit ?-e? NAME Use edit() to create or alter variable NAME",
" With a -e option, the edited value is evaluated as a SQL expression.",
#endif
" list ?PATTERNS? List shell variables table values",
" Alternatively, to list just some or all names: ls ?PATTERNS?",
" load ?FILE? ?NAMES? Load some or all named variables from FILE",
" If FILE missing, empty or '~', it defaults to ~/sqlite_vars.sdb",
" save ?FILE? ?NAMES? Save some or all named variables into FILE",
" If FILE missing, empty or '~', it defaults to ~/sqlite_vars.sdb",
" set NAME VALUE Give shell variable NAME a value of VALUE",
" NAME must begin with a letter to be executable by .x, Other leading",
" characters have special uses. VALUE is the space-joined arguments.",
" unset ?NAMES? Remove named variables(s) from variables table",
];
DISPATCHABLE_COMMAND( vars 2 1 0 ){
DotCmdRC rv = DCR_Ok;
sqlite3 *dbs = p->dbShell;
const char *zCmd = (nArg>1)? azArg[1] : "ls";
int rc = 0;
int ncCmd = strlen30(zCmd);
if( *zCmd>'e' && ncCmd<2 ) return DCR_Ambiguous|1;
#define SUBCMD(scn) (strncmp(zCmd, scn, ncCmd)==0)
/* This could be done lazily, but with more code. */
if( (dbs && ensure_shvars_table(dbs)!=SQLITE_OK) ){
return DCR_Error;
}else{
if( ensure_shell_db(p)!=SQLITE_OK ) return DCR_Error;
dbs = p->dbShell;
assert(dbs!=0);
if( ensure_shvars_table(dbs)!=SQLITE_OK ) return DCR_Error;
}
/* .vars clear and .vars unset ?NAMES?
** Delete some or all key/value pairs from the shell variables table.
** Without any arguments, clear deletes them all and unset does nothing.
*/
if( SUBCMD("clear") || SUBCMD("unset") ){
if( (nArg>2 || zCmd[0]=='c') ){
sqlite3_str *sbZap = sqlite3_str_new(dbs);
char *zSql;
sqlite3_str_appendf
(sbZap, "DELETE FROM "SHVAR_TABLE_SNAME" WHERE key ");
append_in_clause(sbZap,
(const char **)&azArg[2], (const char **)&azArg[nArg]);
zSql = sqlite3_str_finish(sbZap);
shell_check_oom(zSql);
rc = sqlite3_exec(dbs, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
#ifndef SQLITE_NOHAVE_SYSTEM
}else if( SUBCMD("edit") ){
ShellInState *psi = ISS(p);
int ia = 2;
int eval = 0;
int edSet;
if( !INSOURCE_IS_INTERACTIVE(psi->pInSource) ){
utf8_printf(STD_ERR, "Error: "
".vars edit can only be used interactively.\n");
return DCR_Error;
}
edSet = attempt_editor_set(psi, azArg[0], (nArg>2)? azArg[2] : 0 );
if( edSet < 0 ) return DCR_Error;
else ia += edSet;
while( ia < nArg ){
ParamTableUse ptu;
char *zA = azArg[ia];
char cf = (zA[0]=='-')? zA[1] : 0;
if( cf!=0 && zA[2]==0 ){
++ia;
switch( cf ){
case 'e': eval = 1; continue;
case 't': eval = 0; continue;
default:
utf8_printf(STD_ERR, "Error: bad .vars edit option: %s\n", zA);
return DCR_Error;
}
}
ptu = classify_param_name(zA);
if( ptu!=PTU_Script ){
utf8_printf(STD_ERR,
"Error: %s cannot be a shell variable name.\n", zA);
return DCR_Error;
}
rc = edit_one_kvalue(dbs, zA, eval, ptu, psi->zEditor);
++ia;
if( rc!=0 ) return DCR_Error;
}
#endif
}else if( SUBCMD("list") || SUBCMD("ls") ){
int nTailArgs = nArg - 1 - (nArg>1);
char **pzTailArgs = azArg + 1 + (nArg>1);
list_pov_entries(p, PTU_Script, zCmd[1]=='s', pzTailArgs, nTailArgs);
}else if( SUBCMD("load") ){
rc = kv_pairs_load(dbs, PTU_Script, (const char **)azArg+1, nArg-1);
}else if( SUBCMD("save") ){
rc = kv_pairs_save(dbs, PTU_Script, (const char **)azArg+1, nArg-1);
}else if( SUBCMD("set") ){
ParamTableUse ptu;
if( nArg<4 ) return DCR_Missing;
ptu = classify_param_name(azArg[2]);
if( ptu!=PTU_Script ){
utf8_printf(STD_ERR,
"Error: %s is not a valid shell variable name.\n", azArg[2]);
rc = 1;
}else{
rc = shvar_set(dbs, azArg[2], &azArg[3], &azArg[nArg]);
if( rc!=SQLITE_OK ){
utf8_printf(STD_ERR, "Error: %s\n", sqlite3_errmsg(dbs));
rc = 1;
}
}
}else{
showHelp(ISS(p)->out, "vars", p);
return DCR_CmdErred;
}
return DCR_Ok | (rv!=0) | (rc!=0);
#undef SUBCMD
}
/*****************
* The .vfsinfo, .vfslist, .vfsname and .version commands
*/
COLLECT_HELP_TEXT[
".version Show a variety of version info",
".vfsinfo ?AUX? Information about the top-level VFS",
".vfslist List all available VFSes",
|
︙ | | |
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
|
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159
13160
|
-
+
-
+
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
+
-
+
|
}
return rc;
}
DISPATCHABLE_COMMAND( x ? 1 0 ){
int ia, nErrors = 0;
sqlite3_stmt *pStmt = 0;
sqlite3 *dbs = p->dbShell;
sqlite3 *db = 0;
DotCmdRC rv = DCR_Ok;
enum { AsVar, AsString, AsFile } evalAs = AsVar;
enum { AsParam, AsString, AsFile } evalAs = AsParam;
for( ia=1; ia < nArg; ++ia ){
char *zSubmit = 0;
const char *zOpt = azArg[ia];
if ( *zOpt == '-' ){
static const char *azOpts[] = { "p", "s", "f" };
int io = ArraySize(azOpts);
while( io > 0 ){
if( optionMatch(zOpt, azOpts[--io]) ){
evalAs = io;
zOpt = 0;
break;
}
}
if( zOpt==0 ) continue;
}
switch( evalAs ){
case AsVar:
case AsParam:
if( pStmt==0 ){
int rc;
open_db(p, 0);
db = DBX(p);
if( dbs==0 || !shvars_table_exists(dbs) ){
utf8_printf(STD_ERR,
"\".x vname\" can only be done after .var set ... .\n");
if( db==0 ){
utf8_printf(STD_ERR, ".x can only be done with a database open.\n");
return DCR_Error;
}
if( sqlite3_table_column_metadata(db, PARAM_TABLE_SCHEMA,
PARAM_TABLE_NAME, "key",
0, 0, 0, 0, 0)!=SQLITE_OK ){
utf8_printf(STD_ERR, "No "PARAM_TABLE_SNAME" table exists.\n");
return DCR_Error;
}
rc = sqlite3_prepare_v2(dbs, "SELECT value FROM "SHVAR_TABLE_SNAME
rc = sqlite3_prepare_v2(db, "SELECT value FROM "PARAM_TABLE_SNAME
" WHERE key=$1 AND uses=1", -1, &pStmt, 0);
if( rc!=SQLITE_OK ){
utf8_printf(STD_ERR, SHVAR_TABLE_SNAME" is wrongly created.\n");
utf8_printf(STD_ERR, PARAM_TABLE_SNAME" is wrongly created.\n");
return DCR_Error;
}
}
if( isalpha(azArg[ia][0]) ){
int rc = sqlite3_reset(pStmt);
rc = sqlite3_bind_text(pStmt, 1, azArg[ia], -1, 0);
rc = sqlite3_step(pStmt);
|
︙ | | |
13436
13437
13438
13439
13440
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450
|
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
|
-
+
|
if( rv>DCR_Error ) break;
}
}else{
continue; /* All white (or OOM), ignore. */
}
}else{
utf8_printf(STD_ERR,
"Skipping var '%s' (not set and executable.)\n",
"Skipping parameter '%s' (not set and executable.)\n",
azArg[ia]);
++nErrors;
}
}else{
utf8_printf(STD_ERR,
"Skipping badly named %s. Run \".help x\"\n", azArg[ia]);
++nErrors;
|
︙ | | |
13596
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
|
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
|
-
+
-
+
|
} MetaMatchIter;
/* Prepare an iterator that will produce a sequence of MetaCommand
* pointers whose referents names match the given cmdFragment. */
static MetaMatchIter findMatchingMetaCmds(const char *cmdFragment,
ShellExState *psx){
MetaMatchIter rv = { psx, 0, 0 };
if( psx->dbShell==0 || ISS(psx)->bDbDispatch==0 ){
if( psx->dbShell==0 ){
rv.zPattern = smprintf("%s*", cmdFragment? cmdFragment : "");
shell_check_oom((void *)rv.zPattern);
rv.pMC = (MetaCommand *)command_table;
}else{
/* Prepare rv.stmt to yield results glob-matching cmdFragment. */
const char *zSql =
"SELECT name, extIx, cmdIx FROM "SHELL_DISP_VIEW" "
"SELECT name, extIx, cmdIx FROM ActiveCommands "
"WHERE name glob (?||'*') ORDER BY name";
sqlite3_prepare_v2(psx->dbShell, zSql, -1, &rv.stmt, 0);
sqlite3_bind_text(rv.stmt, 1, cmdFragment? cmdFragment : "", -1, 0);
}
return rv;
}
/* Produce the next MetaCommand pointer from the iterator, or 0 if no next. */
|
︙ | | |
13664
13665
13666
13667
13668
13669
13670
13671
13672
13673
13674
13675
13676
13677
13678
13679
13680
13681
13682
13683
|
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
|
-
+
-
+
|
** If shell extensions are loaded, the match must be long enough to
** result in a unique lookup.
*/
MetaCommand *findMetaCommand(const char *cmdName, ShellExState *psx,
/* out */ int *pnFound){
if( pnFound ) *pnFound = 0;
#if SHELL_DYNAMIC_EXTENSION
if( ISS(psx)->bDbDispatch ){
if( psx->dbShell!=0 ){
int rc;
int extIx = -1, cmdIx = -1, nf = 0;
sqlite3_stmt *pStmt = 0;
const char *zSql = "SELECT COUNT(*), extIx, cmdIx"
" FROM "SHELL_DISP_VIEW" WHERE name glob (?||'*')";
" FROM ActiveCommands WHERE name glob (?||'*')";
rc = sqlite3_prepare_v2(psx->dbShell, zSql, -1, &pStmt, 0);
sqlite3_bind_text(pStmt, 1, cmdName, -1, 0);
rc = sqlite3_step(pStmt);
nf = sqlite3_column_int(pStmt, 0);
extIx = sqlite3_column_int(pStmt, 1);
cmdIx = sqlite3_column_int(pStmt, 2);
sqlite3_finalize(pStmt);
|
︙ | | |
14636
14637
14638
14639
14640
14641
14642
14643
14644
14645
14646
14647
14648
14649
14650
|
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
14386
14387
|
-
+
|
} /* end glom another line */
} /* end group collection loop */
/* Here, the group is fully collected or known to be incomplete forever. */
switch( disposition ){
case Dumpable:
echo_group_input(psi, *pzLineUse);
#if SHELL_DYNAMIC_EXTENSION
if( inKind==Script && pSS!=0 ) pSS->pMethods->resetCompletionScan(pSS);
if( inKind==Script && pSS!=0 ) pSS->pMethods->restartCompletionScan(pSS);
#endif
break;
case Runnable:
switch( inKind ){
case Sql:
/* runOneSqlLine() does its own echo when requested. */
nErrors += runOneSqlLine(XSS(psi), *pzLineUse,
|
︙ | | |
14661
14662
14663
14664
14665
14666
14667
14668
14669
14670
14671
14672
14673
14674
14675
|
14398
14399
14400
14401
14402
14403
14404
14405
14406
14407
14408
14409
14410
14411
14412
|
-
+
|
break;
}
#if SHELL_DYNAMIC_EXTENSION
case Script: {
char *zErr = 0;
DotCmdRC dcr;
assert(pSS!=0);
pSS->pMethods->resetCompletionScan(pSS);
pSS->pMethods->restartCompletionScan(pSS);
dcr = pSS->pMethods->runScript(pSS, *pzLineUse+nLeadWhite,
XSS(psi), &zErr);
if( dcr!=DCR_Ok || zErr!=0 ){
/* ToDo: Handle errors more informatively and like dot commands. */
nErrors += (dcr!=DCR_Ok);
if( zErr!=0 ){
utf8_printf(STD_ERR, "Error: %s\n", zErr);
|
︙ | | |
14687
14688
14689
14690
14691
14692
14693
14694
14695
14696
14697
14698
14699
14700
14701
|
14424
14425
14426
14427
14428
14429
14430
14431
14432
14433
14434
14435
14436
14437
14438
|
-
+
|
termKind = DCR_Exit;
}
break;
case Erroneous:
utf8_printf(STD_ERR, "Error: Input incomplete at line %d of \"%s\"\n",
psi->pInSource->lineno, psi->pInSource->zSourceSay);
#if SHELL_DYNAMIC_EXTENSION
if( inKind==Script && pSS!=0 ) pSS->pMethods->resetCompletionScan(pSS);
if( inKind==Script && pSS!=0 ) pSS->pMethods->restartCompletionScan(pSS);
#endif
++nErrors;
break;
case Ignore:
break;
default: assert(0);
}
|
︙ | | |