Fossil

Check-in [0ea56bb239]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Introduce a new version of db_multi_exec() that does not do printf-style formatting.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 0ea56bb239024a38a13e68507cd24fb1e1602715490f1ed7f9890b4d8b932e82
User & Date: drh 2020-03-15 15:43:01.554
Context
2020-03-15
18:35
Add support for the Range: attribute in HTTP requests for the "fossil server" and "fossil http" commands. check-in: b6892ccdd6 user: drh tags: trunk
15:43
Introduce a new version of db_multi_exec() that does not do printf-style formatting. check-in: 0ea56bb239 user: drh tags: trunk
15:37
Resolve mis-expansion of ATTACH DATABASE reported in [https://fossil-scm.org/forum/forumpost/e5cf69b8a0|forumpost/e5cf69b8a0]. check-in: bcdc2f4451 user: stephan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/alerts.c.
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
void alert_schema(int bOnlyIfEnabled){
  if( !alert_tables_exist() ){
    if( bOnlyIfEnabled
     && fossil_strcmp(db_get("email-send-method",0),"off")==0
    ){
      return;  /* Don't create table for disabled email */
    }
    db_multi_exec(zAlertInit/*works-like:""*/);
    alert_triggers_enable();
  }else if( !db_table_has_column("repository","pending_alert","sentMod") ){
    db_multi_exec(
      "ALTER TABLE repository.pending_alert"
      " ADD COLUMN sentMod BOOLEAN DEFAULT false;"
    );
  }







|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
void alert_schema(int bOnlyIfEnabled){
  if( !alert_tables_exist() ){
    if( bOnlyIfEnabled
     && fossil_strcmp(db_get("email-send-method",0),"off")==0
    ){
      return;  /* Don't create table for disabled email */
    }
    db_exec_sql(zAlertInit);
    alert_triggers_enable();
  }else if( !db_table_has_column("repository","pending_alert","sentMod") ){
    db_multi_exec(
      "ALTER TABLE repository.pending_alert"
      " ADD COLUMN sentMod BOOLEAN DEFAULT false;"
    );
  }
Changes to src/branch.c.
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
@   AND tag.tagname='branch'
@   AND event.objid=tagxref.rid
@ GROUP BY 1;
;

/* Call this routine to create the TEMP table */
static void brlist_create_temp_table(void){
  db_multi_exec(createBrlistQuery/*works-like:""*/);
}


#if INTERFACE
/*
** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
*/







|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
@   AND tag.tagname='branch'
@   AND event.objid=tagxref.rid
@ GROUP BY 1;
;

/* Call this routine to create the TEMP table */
static void brlist_create_temp_table(void){
  db_exec_sql(createBrlistQuery);
}


#if INTERFACE
/*
** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
*/
Changes to src/browse.c.
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
** temporary table named "fileage" that contains the file-id for each
** files, the pathname, the check-in where the file was added, and the
** mtime on that check-in. If zGlob and *zGlob then only files matching
** the given glob are computed.
*/
int compute_fileage(int vid, const char* zGlob){
  Stmt q;
  db_multi_exec(zComputeFileAgeSetup /*works-like:"constant"*/);
  db_prepare(&q, zComputeFileAgeRun  /*works-like:"constant"*/);
  db_bind_int(&q, ":ckin", vid);
  db_bind_text(&q, ":glob", zGlob && zGlob[0] ? zGlob : "*");
  db_exec(&q);
  db_finalize(&q);
  return 0;
}







|







916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
** temporary table named "fileage" that contains the file-id for each
** files, the pathname, the check-in where the file was added, and the
** mtime on that check-in. If zGlob and *zGlob then only files matching
** the given glob are computed.
*/
int compute_fileage(int vid, const char* zGlob){
  Stmt q;
  db_exec_sql(zComputeFileAgeSetup);
  db_prepare(&q, zComputeFileAgeRun  /*works-like:"constant"*/);
  db_bind_int(&q, ":ckin", vid);
  db_bind_text(&q, ":glob", zGlob && zGlob[0] ? zGlob : "*");
  db_exec(&q);
  db_finalize(&q);
  return 0;
}
Changes to src/db.c.
651
652
653
654
655
656
657
658

659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
















684
685
686
687
688
689
690
    z = zEnd;
  }
  blob_reset(&sql);
  return rc;
}

/*
** Execute multiple SQL statements.

*/
int db_multi_exec(const char *zSql, ...){
  Blob sql;
  int rc = SQLITE_OK;
  va_list ap;
  const char *z, *zEnd;
  sqlite3_stmt *pStmt;
  blob_init(&sql, 0, 0);
  va_start(ap, zSql);
  blob_vappendf(&sql, zSql, ap);
  va_end(ap);
  z = blob_str(&sql);
  while( rc==SQLITE_OK && z[0] ){
    pStmt = 0;
    rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
    if( rc ){
      db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
    }else if( pStmt ){
      db.nPrepare++;
      while( sqlite3_step(pStmt)==SQLITE_ROW ){}
      rc = sqlite3_finalize(pStmt);
      if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
    }
    z = zEnd;
  }
















  blob_reset(&sql);
  return rc;
}

/*
** Optionally make the following changes to the database if feasible and
** convenient.  Do not start a transaction for these changes, but only







|
>

|
<

<
<

<
<
<
|
<













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







651
652
653
654
655
656
657
658
659
660
661

662


663



664

665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
    z = zEnd;
  }
  blob_reset(&sql);
  return rc;
}

/*
** Execute multiple SQL statements.  The input text is executed
** directly without any formatting.
*/
int db_exec_sql(const char *z){

  int rc = SQLITE_OK;


  sqlite3_stmt *pStmt;



  const char *zEnd;

  while( rc==SQLITE_OK && z[0] ){
    pStmt = 0;
    rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
    if( rc ){
      db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
    }else if( pStmt ){
      db.nPrepare++;
      while( sqlite3_step(pStmt)==SQLITE_ROW ){}
      rc = sqlite3_finalize(pStmt);
      if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
    }
    z = zEnd;
  }
  return rc;
}

/*
** Execute multiple SQL statements using printf-style formatting.
*/
int db_multi_exec(const char *zSql, ...){
  Blob sql;
  int rc;
  va_list ap;

  blob_init(&sql, 0, 0);
  va_start(ap, zSql);
  blob_vappendf(&sql, zSql, ap);
  va_end(ap);
  rc = db_exec_sql(blob_str(&sql));
  blob_reset(&sql);
  return rc;
}

/*
** Optionally make the following changes to the database if feasible and
** convenient.  Do not start a transaction for these changes, but only
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
  Blob key;
  if( db_table_exists(zLabel,"sqlite_master") ) return;
  blob_init(&key, 0, 0);
  db_maybe_obtain_encryption_key(zDbName, &key);
  if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
    char *zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY %Q",
                                 zDbName, zLabel, blob_str(&key));
    db_multi_exec("%s", zCmd /*safe-for-%s*/);
    fossil_secure_zero(zCmd, strlen(zCmd));
    sqlite3_free(zCmd);
  }else{
    char *zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY ''",
                                 zDbName, zLabel);
    db_multi_exec("%s", zCmd /*safe-for-%s*/);
    sqlite3_free(zCmd);
#if USE_SEE
    if( blob_size(&key)>0 ){
      sqlite3_key_v2(g.db, zLabel, blob_str(&key), -1);
    }
#endif
  }







|





|







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
  Blob key;
  if( db_table_exists(zLabel,"sqlite_master") ) return;
  blob_init(&key, 0, 0);
  db_maybe_obtain_encryption_key(zDbName, &key);
  if( fossil_getenv("FOSSIL_USE_SEE_TEXTKEY")==0 ){
    char *zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY %Q",
                                 zDbName, zLabel, blob_str(&key));
    db_exec_sql(zCmd);
    fossil_secure_zero(zCmd, strlen(zCmd));
    sqlite3_free(zCmd);
  }else{
    char *zCmd = sqlite3_mprintf("ATTACH DATABASE %Q AS %Q KEY ''",
                                 zDbName, zLabel);
    db_exec_sql(zCmd);
    sqlite3_free(zCmd);
#if USE_SEE
    if( blob_size(&key)>0 ){
      sqlite3_key_v2(g.db, zLabel, blob_str(&key), -1);
    }
#endif
  }
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
      db_multi_exec("ALTER TABLE vfile ADD COLUMN mhash;");
      db_multi_exec(
        "UPDATE vfile"
        "   SET mhash=(SELECT uuid FROM blob WHERE blob.rid=vfile.mrid)"
        " WHERE mrid!=rid;"
      );
      if( !db_table_has_column("localdb", "vmerge", "mhash") ){
        db_multi_exec("ALTER TABLE vmerge RENAME TO old_vmerge;");
        db_multi_exec(zLocalSchemaVmerge /*works-like:""*/);
        db_multi_exec(  
           "INSERT OR IGNORE INTO vmerge(id,merge,mhash)"
           "  SELECT id, merge, blob.uuid FROM old_vmerge, blob"
           "   WHERE old_vmerge.merge=blob.rid;"
           "DROP TABLE old_vmerge;"
        );
      }
    }







|
|
|







1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
      db_multi_exec("ALTER TABLE vfile ADD COLUMN mhash;");
      db_multi_exec(
        "UPDATE vfile"
        "   SET mhash=(SELECT uuid FROM blob WHERE blob.rid=vfile.mrid)"
        " WHERE mrid!=rid;"
      );
      if( !db_table_has_column("localdb", "vmerge", "mhash") ){
        db_exec_sql("ALTER TABLE vmerge RENAME TO old_vmerge;");
        db_exec_sql(zLocalSchemaVmerge);
        db_exec_sql(  
           "INSERT OR IGNORE INTO vmerge(id,merge,mhash)"
           "  SELECT id, merge, blob.uuid FROM old_vmerge, blob"
           "   WHERE old_vmerge.merge=blob.rid;"
           "DROP TABLE old_vmerge;"
        );
      }
    }
Changes to src/undo.c.
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  static const char zSql[] =
    @ DROP TABLE IF EXISTS undo;
    @ DROP TABLE IF EXISTS undo_vfile;
    @ DROP TABLE IF EXISTS undo_vmerge;
    @ DROP TABLE IF EXISTS undo_stash;
    @ DROP TABLE IF EXISTS undo_stashfile;
    ;
  db_multi_exec(zSql /*works-like:""*/);
  db_lset_int("undo_available", 0);
  db_lset_int("undo_checkout", 0);
}

/*
** The following variable stores the original command-line of the
** command that is a candidate to be undone.







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  static const char zSql[] =
    @ DROP TABLE IF EXISTS undo;
    @ DROP TABLE IF EXISTS undo_vfile;
    @ DROP TABLE IF EXISTS undo_vmerge;
    @ DROP TABLE IF EXISTS undo_stash;
    @ DROP TABLE IF EXISTS undo_stashfile;
    ;
  db_exec_sql(zSql);
  db_lset_int("undo_available", 0);
  db_lset_int("undo_checkout", 0);
}

/*
** The following variable stores the original command-line of the
** command that is a candidate to be undone.
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    @   content BLOB                      -- Saved content
    @ );
    @ CREATE TABLE localdb.undo_vfile AS SELECT * FROM vfile;
    @ CREATE TABLE localdb.undo_vmerge AS SELECT * FROM vmerge;
  ;
  if( undoDisable ) return;
  undo_reset();
  db_multi_exec(zSql/*works-like:""*/);
  cid = db_lget_int("checkout", 0);
  db_lset_int("undo_checkout", cid);
  db_lset_int("undo_available", 1);
  db_lset("undo_cmdline", undoCmd);
  undoActive = 1;
}








|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
    @   content BLOB                      -- Saved content
    @ );
    @ CREATE TABLE localdb.undo_vfile AS SELECT * FROM vfile;
    @ CREATE TABLE localdb.undo_vmerge AS SELECT * FROM vmerge;
  ;
  if( undoDisable ) return;
  undo_reset();
  db_exec_sql(zSql);
  cid = db_lget_int("checkout", 0);
  db_lset_int("undo_checkout", cid);
  db_lset_int("undo_available", 1);
  db_lset("undo_cmdline", undoCmd);
  undoActive = 1;
}