| | @@ -115,10 +115,12 @@ |
| 115 | 115 | struct sCommitHook { |
| 116 | 116 | int (*xHook)(void); /* Functions to call at db_end_transaction() */ |
| 117 | 117 | int sequence; /* Call functions in sequence order */ |
| 118 | 118 | } aHook[5]; |
| 119 | 119 | char *azDeleteOnFail[3]; /* Files to delete on a failure */ |
| 120 | + char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */ |
| 121 | + int nBeforeCommit; /* Number of entries in azBeforeCommit */ |
| 120 | 122 | } db = {0, 0, 0, 0, 0, 0, }; |
| 121 | 123 | |
| 122 | 124 | /* |
| 123 | 125 | ** Arrange for the given file to be deleted on a failure. |
| 124 | 126 | */ |
| | @@ -159,11 +161,18 @@ |
| 159 | 161 | if( db.nBegin<=0 ) return; |
| 160 | 162 | if( rollbackFlag ) db.doRollback = 1; |
| 161 | 163 | db.nBegin--; |
| 162 | 164 | if( db.nBegin==0 ){ |
| 163 | 165 | int i; |
| 164 | | - if( db.doRollback==0 ) leaf_do_pending_checks(); |
| 166 | + if( db.doRollback==0 ){ |
| 167 | + while( db.nBeforeCommit ){ |
| 168 | + db.nBeforeCommit--; |
| 169 | + db_multi_exec(db.azBeforeCommit[db.nBeforeCommit]); |
| 170 | + sqlite3_free(db.azBeforeCommit[db.nBeforeCommit]); |
| 171 | + } |
| 172 | + leaf_do_pending_checks(); |
| 173 | + } |
| 165 | 174 | for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){ |
| 166 | 175 | db.doRollback |= db.aHook[i].xHook(); |
| 167 | 176 | } |
| 168 | 177 | while( db.pAllStmt ){ |
| 169 | 178 | db_finalize(db.pAllStmt); |
| | @@ -487,10 +496,24 @@ |
| 487 | 496 | db_err("%s\n%s", zErr, blob_buffer(&sql)); |
| 488 | 497 | } |
| 489 | 498 | blob_reset(&sql); |
| 490 | 499 | return rc; |
| 491 | 500 | } |
| 501 | + |
| 502 | +/* |
| 503 | +** Optionally make the following changes to the database if feasible and |
| 504 | +** convenient. Do not start a transaction for these changes, but only |
| 505 | +** make these changes if other changes are also being made. |
| 506 | +*/ |
| 507 | +void db_optional_sql(const char *zSql, ...){ |
| 508 | + if( db.nBeforeCommit < count(db.azBeforeCommit) ){ |
| 509 | + va_list ap; |
| 510 | + va_start(ap, zSql); |
| 511 | + db.azBeforeCommit[db.nBeforeCommit++] = sqlite3_vmprintf(zSql, ap); |
| 512 | + va_end(ap); |
| 513 | + } |
| 514 | +} |
| 492 | 515 | |
| 493 | 516 | /* |
| 494 | 517 | ** Execute a query and return a single integer value. |
| 495 | 518 | */ |
| 496 | 519 | i64 db_int64(i64 iDflt, const char *zSql, ...){ |
| | @@ -1713,10 +1736,13 @@ |
| 1713 | 1736 | db_multi_exec( |
| 1714 | 1737 | "REPLACE INTO global_config(name, value)" |
| 1715 | 1738 | "VALUES('ckout:%q','%q');", |
| 1716 | 1739 | blob_str(&localRoot), blob_str(&full) |
| 1717 | 1740 | ); |
| 1741 | + db_optional_sql("REPLACE INTO config(name,value,mtime)" |
| 1742 | + "VALUES('ckout:%q',1,now())", |
| 1743 | + blob_str(&localRoot)); |
| 1718 | 1744 | blob_reset(&localRoot); |
| 1719 | 1745 | } |
| 1720 | 1746 | db_swap_connections(); |
| 1721 | 1747 | blob_reset(&full); |
| 1722 | 1748 | } |
| 1723 | 1749 | |