Fossil SCM
Make use of the new sqlite3_prepare_v3() interface and the SQLITE_PREPARE_PERSISTENT flag in SQLite.
Commit
11c46fd6aa605aa6c2a058433c3501717ee321e3ae05baffc632d0289031f68d
Parent
ee71f347eece252…
1 file changed
+17
-5
M
src/db.c
+17
-5
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -242,25 +242,37 @@ | ||
| 242 | 242 | db.aHook[db.nCommitHook].sequence = sequence; |
| 243 | 243 | db.aHook[db.nCommitHook].xHook = x; |
| 244 | 244 | db.nCommitHook++; |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | +#if INTERFACE | |
| 248 | +/* | |
| 249 | +** Possible flags to db_vprepare | |
| 250 | +*/ | |
| 251 | +#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */ | |
| 252 | +#define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */ | |
| 253 | +#endif | |
| 254 | + | |
| 247 | 255 | /* |
| 248 | 256 | ** Prepare a Stmt. Assume that the Stmt is previously uninitialized. |
| 249 | 257 | ** If the input string contains multiple SQL statements, only the first |
| 250 | 258 | ** one is processed. All statements beyond the first are silently ignored. |
| 251 | 259 | */ |
| 252 | -int db_vprepare(Stmt *pStmt, int errOk, const char *zFormat, va_list ap){ | |
| 260 | +int db_vprepare(Stmt *pStmt, int flags, const char *zFormat, va_list ap){ | |
| 253 | 261 | int rc; |
| 262 | + int prepFlags = 0; | |
| 254 | 263 | char *zSql; |
| 255 | 264 | blob_zero(&pStmt->sql); |
| 256 | 265 | blob_vappendf(&pStmt->sql, zFormat, ap); |
| 257 | 266 | va_end(ap); |
| 258 | 267 | zSql = blob_str(&pStmt->sql); |
| 259 | 268 | db.nPrepare++; |
| 260 | - rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt->pStmt, 0); | |
| 261 | - if( rc!=0 && !errOk ){ | |
| 269 | + if( flags & DB_PREPARE_PERSISTENT ){ | |
| 270 | + prepFlags = SQLITE_PREPARE_PERSISTENT; | |
| 271 | + } | |
| 272 | + rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, 0); | |
| 273 | + if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)!=0 ){ | |
| 262 | 274 | db_err("%s\n%s", sqlite3_errmsg(g.db), zSql); |
| 263 | 275 | } |
| 264 | 276 | pStmt->pNext = pStmt->pPrev = 0; |
| 265 | 277 | pStmt->nStep = 0; |
| 266 | 278 | return rc; |
| @@ -275,20 +287,20 @@ | ||
| 275 | 287 | } |
| 276 | 288 | int db_prepare_ignore_error(Stmt *pStmt, const char *zFormat, ...){ |
| 277 | 289 | int rc; |
| 278 | 290 | va_list ap; |
| 279 | 291 | va_start(ap, zFormat); |
| 280 | - rc = db_vprepare(pStmt, 1, zFormat, ap); | |
| 292 | + rc = db_vprepare(pStmt, DB_PREPARE_IGNORE_ERROR, zFormat, ap); | |
| 281 | 293 | va_end(ap); |
| 282 | 294 | return rc; |
| 283 | 295 | } |
| 284 | 296 | int db_static_prepare(Stmt *pStmt, const char *zFormat, ...){ |
| 285 | 297 | int rc = SQLITE_OK; |
| 286 | 298 | if( blob_size(&pStmt->sql)==0 ){ |
| 287 | 299 | va_list ap; |
| 288 | 300 | va_start(ap, zFormat); |
| 289 | - rc = db_vprepare(pStmt, 0, zFormat, ap); | |
| 301 | + rc = db_vprepare(pStmt, DB_PREPARE_PERSISTENT, zFormat, ap); | |
| 290 | 302 | pStmt->pNext = db.pAllStmt; |
| 291 | 303 | pStmt->pPrev = 0; |
| 292 | 304 | if( db.pAllStmt ) db.pAllStmt->pPrev = pStmt; |
| 293 | 305 | db.pAllStmt = pStmt; |
| 294 | 306 | va_end(ap); |
| 295 | 307 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -242,25 +242,37 @@ | |
| 242 | db.aHook[db.nCommitHook].sequence = sequence; |
| 243 | db.aHook[db.nCommitHook].xHook = x; |
| 244 | db.nCommitHook++; |
| 245 | } |
| 246 | |
| 247 | /* |
| 248 | ** Prepare a Stmt. Assume that the Stmt is previously uninitialized. |
| 249 | ** If the input string contains multiple SQL statements, only the first |
| 250 | ** one is processed. All statements beyond the first are silently ignored. |
| 251 | */ |
| 252 | int db_vprepare(Stmt *pStmt, int errOk, const char *zFormat, va_list ap){ |
| 253 | int rc; |
| 254 | char *zSql; |
| 255 | blob_zero(&pStmt->sql); |
| 256 | blob_vappendf(&pStmt->sql, zFormat, ap); |
| 257 | va_end(ap); |
| 258 | zSql = blob_str(&pStmt->sql); |
| 259 | db.nPrepare++; |
| 260 | rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt->pStmt, 0); |
| 261 | if( rc!=0 && !errOk ){ |
| 262 | db_err("%s\n%s", sqlite3_errmsg(g.db), zSql); |
| 263 | } |
| 264 | pStmt->pNext = pStmt->pPrev = 0; |
| 265 | pStmt->nStep = 0; |
| 266 | return rc; |
| @@ -275,20 +287,20 @@ | |
| 275 | } |
| 276 | int db_prepare_ignore_error(Stmt *pStmt, const char *zFormat, ...){ |
| 277 | int rc; |
| 278 | va_list ap; |
| 279 | va_start(ap, zFormat); |
| 280 | rc = db_vprepare(pStmt, 1, zFormat, ap); |
| 281 | va_end(ap); |
| 282 | return rc; |
| 283 | } |
| 284 | int db_static_prepare(Stmt *pStmt, const char *zFormat, ...){ |
| 285 | int rc = SQLITE_OK; |
| 286 | if( blob_size(&pStmt->sql)==0 ){ |
| 287 | va_list ap; |
| 288 | va_start(ap, zFormat); |
| 289 | rc = db_vprepare(pStmt, 0, zFormat, ap); |
| 290 | pStmt->pNext = db.pAllStmt; |
| 291 | pStmt->pPrev = 0; |
| 292 | if( db.pAllStmt ) db.pAllStmt->pPrev = pStmt; |
| 293 | db.pAllStmt = pStmt; |
| 294 | va_end(ap); |
| 295 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -242,25 +242,37 @@ | |
| 242 | db.aHook[db.nCommitHook].sequence = sequence; |
| 243 | db.aHook[db.nCommitHook].xHook = x; |
| 244 | db.nCommitHook++; |
| 245 | } |
| 246 | |
| 247 | #if INTERFACE |
| 248 | /* |
| 249 | ** Possible flags to db_vprepare |
| 250 | */ |
| 251 | #define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */ |
| 252 | #define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */ |
| 253 | #endif |
| 254 | |
| 255 | /* |
| 256 | ** Prepare a Stmt. Assume that the Stmt is previously uninitialized. |
| 257 | ** If the input string contains multiple SQL statements, only the first |
| 258 | ** one is processed. All statements beyond the first are silently ignored. |
| 259 | */ |
| 260 | int db_vprepare(Stmt *pStmt, int flags, const char *zFormat, va_list ap){ |
| 261 | int rc; |
| 262 | int prepFlags = 0; |
| 263 | char *zSql; |
| 264 | blob_zero(&pStmt->sql); |
| 265 | blob_vappendf(&pStmt->sql, zFormat, ap); |
| 266 | va_end(ap); |
| 267 | zSql = blob_str(&pStmt->sql); |
| 268 | db.nPrepare++; |
| 269 | if( flags & DB_PREPARE_PERSISTENT ){ |
| 270 | prepFlags = SQLITE_PREPARE_PERSISTENT; |
| 271 | } |
| 272 | rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, 0); |
| 273 | if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)!=0 ){ |
| 274 | db_err("%s\n%s", sqlite3_errmsg(g.db), zSql); |
| 275 | } |
| 276 | pStmt->pNext = pStmt->pPrev = 0; |
| 277 | pStmt->nStep = 0; |
| 278 | return rc; |
| @@ -275,20 +287,20 @@ | |
| 287 | } |
| 288 | int db_prepare_ignore_error(Stmt *pStmt, const char *zFormat, ...){ |
| 289 | int rc; |
| 290 | va_list ap; |
| 291 | va_start(ap, zFormat); |
| 292 | rc = db_vprepare(pStmt, DB_PREPARE_IGNORE_ERROR, zFormat, ap); |
| 293 | va_end(ap); |
| 294 | return rc; |
| 295 | } |
| 296 | int db_static_prepare(Stmt *pStmt, const char *zFormat, ...){ |
| 297 | int rc = SQLITE_OK; |
| 298 | if( blob_size(&pStmt->sql)==0 ){ |
| 299 | va_list ap; |
| 300 | va_start(ap, zFormat); |
| 301 | rc = db_vprepare(pStmt, DB_PREPARE_PERSISTENT, zFormat, ap); |
| 302 | pStmt->pNext = db.pAllStmt; |
| 303 | pStmt->pPrev = 0; |
| 304 | if( db.pAllStmt ) db.pAllStmt->pPrev = pStmt; |
| 305 | db.pAllStmt = pStmt; |
| 306 | va_end(ap); |
| 307 |