mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Add a new sqlite3_is_interrupted() interface that can be used by long-running
app-defined functions and similar to see if they need to exit early due to an sqlite3_interrupt() call. FossilOrigin-Name: d030f341369b7f32789cbcf3d0ad9a2ac5cad99a56dac7dfe68b7f06dc339b17
This commit is contained in:
@@ -510,7 +510,9 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
#endif
|
||||
sqlite3_db_name,
|
||||
/* Version 3.40.0 and later */
|
||||
sqlite3_value_encoding
|
||||
sqlite3_value_encoding,
|
||||
/* Version 3.41.0 and later */
|
||||
sqlite3_is_interrupted
|
||||
};
|
||||
|
||||
/* True if x is the directory separator character
|
||||
|
||||
19
src/main.c
19
src/main.c
@@ -1796,7 +1796,9 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
||||
*/
|
||||
void sqlite3_interrupt(sqlite3 *db){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) ){
|
||||
if( !sqlite3SafetyCheckOk(db)
|
||||
&& (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE)
|
||||
){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return;
|
||||
}
|
||||
@@ -1804,6 +1806,21 @@ void sqlite3_interrupt(sqlite3 *db){
|
||||
AtomicStore(&db->u1.isInterrupted, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true or false depending on whether or not an interrupt is
|
||||
** pending on connection db.
|
||||
*/
|
||||
int sqlite3_is_interrupted(sqlite3 *db){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db)
|
||||
&& (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE)
|
||||
){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return AtomicLoad(&db->u1.isInterrupted)!=0;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is exactly the same as sqlite3_create_function(), except
|
||||
|
||||
@@ -2679,8 +2679,12 @@ sqlite3_int64 sqlite3_total_changes64(sqlite3*);
|
||||
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
|
||||
** SQL statements is a no-op and has no effect on SQL statements
|
||||
** that are started after the sqlite3_interrupt() call returns.
|
||||
**
|
||||
** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether
|
||||
** or not an interrupt is currently in effect for [database connection] D.
|
||||
*/
|
||||
void sqlite3_interrupt(sqlite3*);
|
||||
int sqlite3_is_interrupted(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine If An SQL Statement Is Complete
|
||||
|
||||
@@ -359,6 +359,8 @@ struct sqlite3_api_routines {
|
||||
const char *(*db_name)(sqlite3*,int);
|
||||
/* Version 3.40.0 and later */
|
||||
int (*value_encoding)(sqlite3_value*);
|
||||
/* Version 3.41.0 and later */
|
||||
int (*is_interrupted)(sqlite3*);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -685,6 +687,8 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_db_name sqlite3_api->db_name
|
||||
/* Version 3.40.0 and later */
|
||||
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||
/* Version 3.41.0 and later */
|
||||
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
25
src/test1.c
25
src/test1.c
@@ -5537,7 +5537,6 @@ static int SQLITE_TCLAPI test_stmt_int(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_interrupt DB
|
||||
**
|
||||
@@ -5559,6 +5558,29 @@ static int SQLITE_TCLAPI test_interrupt(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_is_interrupted DB
|
||||
**
|
||||
** return true if an interrupt is current in effect on DB
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_is_interrupted(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int argc,
|
||||
char **argv
|
||||
){
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
if( argc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
rc = sqlite3_is_interrupted(db);
|
||||
Tcl_AppendResult(interp, rc ? "1" : "0", (void*)0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite_delete_function DB function-name
|
||||
**
|
||||
@@ -8631,6 +8653,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_key", (Tcl_CmdProc*)test_key },
|
||||
{ "sqlite3_rekey", (Tcl_CmdProc*)test_rekey },
|
||||
{ "sqlite3_interrupt", (Tcl_CmdProc*)test_interrupt },
|
||||
{ "sqlite3_is_interrupted", (Tcl_CmdProc*)test_is_interrupted },
|
||||
{ "sqlite_delete_function", (Tcl_CmdProc*)delete_function },
|
||||
{ "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation },
|
||||
{ "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit },
|
||||
|
||||
Reference in New Issue
Block a user