Fossil SCM

Taught "fossil settings" how to accept multiple ?VALUES? parameters, storing the result as a JSON-encoded array in the config table. Nothing uses this yet, but the resulting SQL DB manipulation appears to work correctly.

wyoung 2021-06-22 02:37 fossil-spawn
Commit ca069402f8fb2d53e6d05bd5066e1d7c564f365bf9590c3af02c7c30df1cbbd4
1 file changed +36 -3
+36 -3
--- src/db.c
+++ src/db.c
@@ -3218,10 +3218,38 @@
32183218
if( globalFlag && g.repositoryOpen ){
32193219
db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
32203220
}
32213221
db_end_transaction(0);
32223222
db_protect_pop();
3223
+}
3224
+void db_set_array(const char *zName, char* azValues[], size_t nValues, int globalFlag){
3225
+ Stmt q;
3226
+ db_assert_protection_off_or_not_sensitive(zName);
3227
+ db_unprotect(PROTECT_CONFIG);
3228
+ db_begin_transaction();
3229
+ if( globalFlag ){
3230
+ db_swap_connections();
3231
+ sqlite3_carray_init(g.db, 0, 0); /* not registered globally on purpose */
3232
+ db_prepare(&q, "REPLACE INTO global_config(name,value) VALUES(%Q,"
3233
+ "(SELECT json_group_array(value) FROM carray(?1)))",
3234
+ zName);
3235
+ sqlite3_carray_bind(q.pStmt, 1, azValues, nValues, CARRAY_TEXT, SQLITE_STATIC);
3236
+ db_exec(&q);
3237
+ db_swap_connections();
3238
+ }else{
3239
+ sqlite3_carray_init(g.db, 0, 0); /* ditto */
3240
+ db_prepare(&q, "REPLACE INTO config(name,value,mtime) VALUES(%Q,"
3241
+ "(SELECT json_group_array(value) FROM carray(?1)),now())",
3242
+ zName);
3243
+ sqlite3_carray_bind(q.pStmt, 1, azValues, nValues, CARRAY_TEXT, SQLITE_STATIC);
3244
+ db_exec(&q);
3245
+ }
3246
+ if( globalFlag && g.repositoryOpen ){
3247
+ db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
3248
+ }
3249
+ db_end_transaction(0);
3250
+ db_protect_pop();
32233251
}
32243252
void db_unset(const char *zName, int globalFlag){
32253253
db_begin_transaction();
32263254
db_unprotect(PROTECT_CONFIG);
32273255
if( globalFlag ){
@@ -4385,21 +4413,21 @@
43854413
43864414
if( g.argc==2 ){
43874415
for(i=0; i<nSetting; i++){
43884416
print_setting(&aSetting[i]);
43894417
}
4390
- }else if( g.argc==3 || g.argc==4 ){
4418
+ }else if( g.argc>=3 ){
43914419
const char *zName = g.argv[2];
43924420
int n = (int)strlen(zName);
43934421
const Setting *pSetting = db_find_setting(zName, !exactFlag);
43944422
if( pSetting==0 ){
43954423
fossil_fatal("no such setting: %s", zName);
43964424
}
43974425
if( globalFlag && fossil_strcmp(pSetting->name, "manifest")==0 ){
43984426
fossil_fatal("cannot set 'manifest' globally");
43994427
}
4400
- if( unsetFlag || g.argc==4 ){
4428
+ if( unsetFlag || g.argc>=4 ){
44014429
int isManifest = fossil_strcmp(pSetting->name, "manifest")==0;
44024430
if( n!=strlen(pSetting[0].name) && pSetting[1].name &&
44034431
fossil_strncmp(pSetting[1].name, zName, n)==0 ){
44044432
Blob x;
44054433
int i;
@@ -4416,11 +4444,16 @@
44164444
}
44174445
if( unsetFlag ){
44184446
db_unset(pSetting->name, globalFlag);
44194447
}else{
44204448
db_protect_only(PROTECT_NONE);
4421
- db_set(pSetting->name, g.argv[3], globalFlag);
4449
+ if( g.argc==4 ){
4450
+ db_set(pSetting->name, g.argv[3], globalFlag);
4451
+ }
4452
+ else {
4453
+ db_set_array(pSetting->name, g.argv+3, g.argc-3, globalFlag);
4454
+ }
44224455
db_protect_pop();
44234456
}
44244457
if( isManifest && g.localOpen ){
44254458
manifest_to_disk(db_lget_int("checkout", 0));
44264459
}
44274460
--- src/db.c
+++ src/db.c
@@ -3218,10 +3218,38 @@
3218 if( globalFlag && g.repositoryOpen ){
3219 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
3220 }
3221 db_end_transaction(0);
3222 db_protect_pop();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3223 }
3224 void db_unset(const char *zName, int globalFlag){
3225 db_begin_transaction();
3226 db_unprotect(PROTECT_CONFIG);
3227 if( globalFlag ){
@@ -4385,21 +4413,21 @@
4385
4386 if( g.argc==2 ){
4387 for(i=0; i<nSetting; i++){
4388 print_setting(&aSetting[i]);
4389 }
4390 }else if( g.argc==3 || g.argc==4 ){
4391 const char *zName = g.argv[2];
4392 int n = (int)strlen(zName);
4393 const Setting *pSetting = db_find_setting(zName, !exactFlag);
4394 if( pSetting==0 ){
4395 fossil_fatal("no such setting: %s", zName);
4396 }
4397 if( globalFlag && fossil_strcmp(pSetting->name, "manifest")==0 ){
4398 fossil_fatal("cannot set 'manifest' globally");
4399 }
4400 if( unsetFlag || g.argc==4 ){
4401 int isManifest = fossil_strcmp(pSetting->name, "manifest")==0;
4402 if( n!=strlen(pSetting[0].name) && pSetting[1].name &&
4403 fossil_strncmp(pSetting[1].name, zName, n)==0 ){
4404 Blob x;
4405 int i;
@@ -4416,11 +4444,16 @@
4416 }
4417 if( unsetFlag ){
4418 db_unset(pSetting->name, globalFlag);
4419 }else{
4420 db_protect_only(PROTECT_NONE);
4421 db_set(pSetting->name, g.argv[3], globalFlag);
 
 
 
 
 
4422 db_protect_pop();
4423 }
4424 if( isManifest && g.localOpen ){
4425 manifest_to_disk(db_lget_int("checkout", 0));
4426 }
4427
--- src/db.c
+++ src/db.c
@@ -3218,10 +3218,38 @@
3218 if( globalFlag && g.repositoryOpen ){
3219 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
3220 }
3221 db_end_transaction(0);
3222 db_protect_pop();
3223 }
3224 void db_set_array(const char *zName, char* azValues[], size_t nValues, int globalFlag){
3225 Stmt q;
3226 db_assert_protection_off_or_not_sensitive(zName);
3227 db_unprotect(PROTECT_CONFIG);
3228 db_begin_transaction();
3229 if( globalFlag ){
3230 db_swap_connections();
3231 sqlite3_carray_init(g.db, 0, 0); /* not registered globally on purpose */
3232 db_prepare(&q, "REPLACE INTO global_config(name,value) VALUES(%Q,"
3233 "(SELECT json_group_array(value) FROM carray(?1)))",
3234 zName);
3235 sqlite3_carray_bind(q.pStmt, 1, azValues, nValues, CARRAY_TEXT, SQLITE_STATIC);
3236 db_exec(&q);
3237 db_swap_connections();
3238 }else{
3239 sqlite3_carray_init(g.db, 0, 0); /* ditto */
3240 db_prepare(&q, "REPLACE INTO config(name,value,mtime) VALUES(%Q,"
3241 "(SELECT json_group_array(value) FROM carray(?1)),now())",
3242 zName);
3243 sqlite3_carray_bind(q.pStmt, 1, azValues, nValues, CARRAY_TEXT, SQLITE_STATIC);
3244 db_exec(&q);
3245 }
3246 if( globalFlag && g.repositoryOpen ){
3247 db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
3248 }
3249 db_end_transaction(0);
3250 db_protect_pop();
3251 }
3252 void db_unset(const char *zName, int globalFlag){
3253 db_begin_transaction();
3254 db_unprotect(PROTECT_CONFIG);
3255 if( globalFlag ){
@@ -4385,21 +4413,21 @@
4413
4414 if( g.argc==2 ){
4415 for(i=0; i<nSetting; i++){
4416 print_setting(&aSetting[i]);
4417 }
4418 }else if( g.argc>=3 ){
4419 const char *zName = g.argv[2];
4420 int n = (int)strlen(zName);
4421 const Setting *pSetting = db_find_setting(zName, !exactFlag);
4422 if( pSetting==0 ){
4423 fossil_fatal("no such setting: %s", zName);
4424 }
4425 if( globalFlag && fossil_strcmp(pSetting->name, "manifest")==0 ){
4426 fossil_fatal("cannot set 'manifest' globally");
4427 }
4428 if( unsetFlag || g.argc>=4 ){
4429 int isManifest = fossil_strcmp(pSetting->name, "manifest")==0;
4430 if( n!=strlen(pSetting[0].name) && pSetting[1].name &&
4431 fossil_strncmp(pSetting[1].name, zName, n)==0 ){
4432 Blob x;
4433 int i;
@@ -4416,11 +4444,16 @@
4444 }
4445 if( unsetFlag ){
4446 db_unset(pSetting->name, globalFlag);
4447 }else{
4448 db_protect_only(PROTECT_NONE);
4449 if( g.argc==4 ){
4450 db_set(pSetting->name, g.argv[3], globalFlag);
4451 }
4452 else {
4453 db_set_array(pSetting->name, g.argv+3, g.argc-3, globalFlag);
4454 }
4455 db_protect_pop();
4456 }
4457 if( isManifest && g.localOpen ){
4458 manifest_to_disk(db_lget_int("checkout", 0));
4459 }
4460

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button