Fossil SCM
Clean shutdown in the "fossil sql" command.
Commit
fbb15cc4a8610588303c2679c77d753b89f3823a119865f21be373122b87e068
Parent
0feb4128695ad71…
2 files changed
+13
-1
+5
M
src/db.c
+13
-1
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -2381,16 +2381,28 @@ | ||
| 2381 | 2381 | char c = i==argc-1 ? '\n' : ' '; |
| 2382 | 2382 | fossil_print("%s%c", sqlite3_value_text(argv[i]), c); |
| 2383 | 2383 | } |
| 2384 | 2384 | } |
| 2385 | 2385 | } |
| 2386 | -LOCAL int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){ | |
| 2386 | + | |
| 2387 | +/* | |
| 2388 | +** Callback for sqlite3_trace_v2(); | |
| 2389 | +*/ | |
| 2390 | +int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){ | |
| 2387 | 2391 | sqlite3_stmt *pStmt = (sqlite3_stmt*)pP; |
| 2388 | 2392 | char *zSql; |
| 2389 | 2393 | int n; |
| 2390 | 2394 | const char *zArg = (const char*)pX; |
| 2391 | 2395 | char zEnd[40]; |
| 2396 | + if( m & SQLITE_TRACE_CLOSE ){ | |
| 2397 | + /* If we are tracking closes, that means we want to clean up static | |
| 2398 | + ** prepared statements. */ | |
| 2399 | + while( db.pAllStmt ){ | |
| 2400 | + db_finalize(db.pAllStmt); | |
| 2401 | + } | |
| 2402 | + return 0; | |
| 2403 | + } | |
| 2392 | 2404 | if( zArg[0]=='-' ) return 0; |
| 2393 | 2405 | if( m & SQLITE_TRACE_PROFILE ){ |
| 2394 | 2406 | sqlite3_int64 nNano = *(sqlite3_int64*)pX; |
| 2395 | 2407 | double rMillisec = 0.000001 * nNano; |
| 2396 | 2408 | sqlite3_snprintf(sizeof(zEnd),zEnd," /* %.3fms */\n", rMillisec); |
| 2397 | 2409 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -2381,16 +2381,28 @@ | |
| 2381 | char c = i==argc-1 ? '\n' : ' '; |
| 2382 | fossil_print("%s%c", sqlite3_value_text(argv[i]), c); |
| 2383 | } |
| 2384 | } |
| 2385 | } |
| 2386 | LOCAL int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){ |
| 2387 | sqlite3_stmt *pStmt = (sqlite3_stmt*)pP; |
| 2388 | char *zSql; |
| 2389 | int n; |
| 2390 | const char *zArg = (const char*)pX; |
| 2391 | char zEnd[40]; |
| 2392 | if( zArg[0]=='-' ) return 0; |
| 2393 | if( m & SQLITE_TRACE_PROFILE ){ |
| 2394 | sqlite3_int64 nNano = *(sqlite3_int64*)pX; |
| 2395 | double rMillisec = 0.000001 * nNano; |
| 2396 | sqlite3_snprintf(sizeof(zEnd),zEnd," /* %.3fms */\n", rMillisec); |
| 2397 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -2381,16 +2381,28 @@ | |
| 2381 | char c = i==argc-1 ? '\n' : ' '; |
| 2382 | fossil_print("%s%c", sqlite3_value_text(argv[i]), c); |
| 2383 | } |
| 2384 | } |
| 2385 | } |
| 2386 | |
| 2387 | /* |
| 2388 | ** Callback for sqlite3_trace_v2(); |
| 2389 | */ |
| 2390 | int db_sql_trace(unsigned m, void *notUsed, void *pP, void *pX){ |
| 2391 | sqlite3_stmt *pStmt = (sqlite3_stmt*)pP; |
| 2392 | char *zSql; |
| 2393 | int n; |
| 2394 | const char *zArg = (const char*)pX; |
| 2395 | char zEnd[40]; |
| 2396 | if( m & SQLITE_TRACE_CLOSE ){ |
| 2397 | /* If we are tracking closes, that means we want to clean up static |
| 2398 | ** prepared statements. */ |
| 2399 | while( db.pAllStmt ){ |
| 2400 | db_finalize(db.pAllStmt); |
| 2401 | } |
| 2402 | return 0; |
| 2403 | } |
| 2404 | if( zArg[0]=='-' ) return 0; |
| 2405 | if( m & SQLITE_TRACE_PROFILE ){ |
| 2406 | sqlite3_int64 nNano = *(sqlite3_int64*)pX; |
| 2407 | double rMillisec = 0.000001 * nNano; |
| 2408 | sqlite3_snprintf(sizeof(zEnd),zEnd," /* %.3fms */\n", rMillisec); |
| 2409 |
+5
| --- src/sqlcmd.c | ||
| +++ src/sqlcmd.c | ||
| @@ -164,10 +164,11 @@ | ||
| 164 | 164 | static int sqlcmd_autoinit( |
| 165 | 165 | sqlite3 *db, |
| 166 | 166 | const char **pzErrMsg, |
| 167 | 167 | const void *notUsed |
| 168 | 168 | ){ |
| 169 | + int mTrace = SQLITE_TRACE_CLOSE; | |
| 169 | 170 | add_content_sql_commands(db); |
| 170 | 171 | db_add_aux_functions(db); |
| 171 | 172 | re_add_sql_func(db); |
| 172 | 173 | search_sql_setup(db); |
| 173 | 174 | foci_register(db); |
| @@ -186,10 +187,14 @@ | ||
| 186 | 187 | char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''", |
| 187 | 188 | g.zConfigDbName); |
| 188 | 189 | sqlite3_exec(db, zSql, 0, 0, 0); |
| 189 | 190 | sqlite3_free(zSql); |
| 190 | 191 | } |
| 192 | + /* Arrange to trace close operations so that static prepared statements | |
| 193 | + ** will get cleaned up when the shell closes the database connection */ | |
| 194 | + if( g.fSqlTrace ) mTrace |= SQLITE_TRACE_PROFILE; | |
| 195 | + sqlite3_trace_v2(db, mTrace, db_sql_trace, 0); | |
| 191 | 196 | return SQLITE_OK; |
| 192 | 197 | } |
| 193 | 198 | |
| 194 | 199 | /* |
| 195 | 200 | ** atexit() handler that cleans up global state modified by this module. |
| 196 | 201 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -164,10 +164,11 @@ | |
| 164 | static int sqlcmd_autoinit( |
| 165 | sqlite3 *db, |
| 166 | const char **pzErrMsg, |
| 167 | const void *notUsed |
| 168 | ){ |
| 169 | add_content_sql_commands(db); |
| 170 | db_add_aux_functions(db); |
| 171 | re_add_sql_func(db); |
| 172 | search_sql_setup(db); |
| 173 | foci_register(db); |
| @@ -186,10 +187,14 @@ | |
| 186 | char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''", |
| 187 | g.zConfigDbName); |
| 188 | sqlite3_exec(db, zSql, 0, 0, 0); |
| 189 | sqlite3_free(zSql); |
| 190 | } |
| 191 | return SQLITE_OK; |
| 192 | } |
| 193 | |
| 194 | /* |
| 195 | ** atexit() handler that cleans up global state modified by this module. |
| 196 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -164,10 +164,11 @@ | |
| 164 | static int sqlcmd_autoinit( |
| 165 | sqlite3 *db, |
| 166 | const char **pzErrMsg, |
| 167 | const void *notUsed |
| 168 | ){ |
| 169 | int mTrace = SQLITE_TRACE_CLOSE; |
| 170 | add_content_sql_commands(db); |
| 171 | db_add_aux_functions(db); |
| 172 | re_add_sql_func(db); |
| 173 | search_sql_setup(db); |
| 174 | foci_register(db); |
| @@ -186,10 +187,14 @@ | |
| 187 | char *zSql = sqlite3_mprintf("ATTACH %Q AS 'configdb' KEY ''", |
| 188 | g.zConfigDbName); |
| 189 | sqlite3_exec(db, zSql, 0, 0, 0); |
| 190 | sqlite3_free(zSql); |
| 191 | } |
| 192 | /* Arrange to trace close operations so that static prepared statements |
| 193 | ** will get cleaned up when the shell closes the database connection */ |
| 194 | if( g.fSqlTrace ) mTrace |= SQLITE_TRACE_PROFILE; |
| 195 | sqlite3_trace_v2(db, mTrace, db_sql_trace, 0); |
| 196 | return SQLITE_OK; |
| 197 | } |
| 198 | |
| 199 | /* |
| 200 | ** atexit() handler that cleans up global state modified by this module. |
| 201 |