@@ -386,13 +386,16 @@ class CustomAggregate {
386386 }
387387
388388 Local<Value> ret;
389- if (!(self->*mptr)
390- .Get (isolate)
391- ->Call (env->context (), recv, argc + 1 , js_argv.data ())
392- .ToLocal (&ret)) {
393- self->db_ ->SetIgnoreNextSQLiteError (true );
394- sqlite3_result_error (ctx, " " , 0 );
395- return ;
389+ {
390+ auto guard = self->db_ ->EnterUserFunctionCallback ();
391+ if (!(self->*mptr)
392+ .Get (isolate)
393+ ->Call (env->context (), recv, argc + 1 , js_argv.data ())
394+ .ToLocal (&ret)) {
395+ self->db_ ->SetIgnoreNextSQLiteError (true );
396+ sqlite3_result_error (ctx, " " , 0 );
397+ return ;
398+ }
396399 }
397400
398401 agg->value .Reset (isolate, ret);
@@ -422,6 +425,7 @@ class CustomAggregate {
422425 Local<Function>::New (env->isolate (), self->result_fn_ );
423426 Local<Value> js_arg[] = {Local<Value>::New (isolate, agg->value )};
424427
428+ auto guard = self->db_ ->EnterUserFunctionCallback ();
425429 if (!fn->Call (env->context (), Null (isolate), 1 , js_arg)
426430 .ToLocal (&result)) {
427431 self->db_ ->SetIgnoreNextSQLiteError (true );
@@ -455,6 +459,7 @@ class CustomAggregate {
455459 Local<Value> start_v = Local<Value>::New (isolate, start_);
456460 if (start_v->IsFunction ()) {
457461 auto fn = start_v.As <Function>();
462+ auto guard = db_->EnterUserFunctionCallback ();
458463 MaybeLocal<Value> retval =
459464 fn->Call (env_->context (), Null (isolate), 0 , nullptr );
460465 if (!retval.ToLocal (&start_v)) {
@@ -698,6 +703,7 @@ void UserDefinedFunction::xFunc(sqlite3_context* ctx,
698703 js_argv.emplace_back (local);
699704 }
700705
706+ auto guard = self->db_ ->EnterUserFunctionCallback ();
701707 MaybeLocal<Value> retval =
702708 fn->Call (env->context (), recv, argc, js_argv.data ());
703709 Local<Value> result;
@@ -1420,6 +1426,10 @@ void DatabaseSync::Close(const FunctionCallbackInfo<Value>& args) {
14201426 ASSIGN_OR_RETURN_UNWRAP (&db, args.This ());
14211427 Environment* env = Environment::GetCurrent (args);
14221428 THROW_AND_RETURN_ON_BAD_STATE (env, !db->IsOpen (), " database is not open" );
1429+ THROW_AND_RETURN_ON_BAD_STATE (
1430+ env,
1431+ db->IsInUserFunctionCallback (),
1432+ " database cannot be closed inside a user-defined function callback" );
14231433 db->FinalizeStatements ();
14241434 db->DeleteSessions ();
14251435 int r = sqlite3_close_v2 (db->connection_ );
@@ -1808,6 +1818,11 @@ void DatabaseSync::Deserialize(const FunctionCallbackInfo<Value>& args) {
18081818 ASSIGN_OR_RETURN_UNWRAP (&db, args.This ());
18091819 Environment* env = Environment::GetCurrent (args);
18101820 THROW_AND_RETURN_ON_BAD_STATE (env, !db->IsOpen (), " database is not open" );
1821+ THROW_AND_RETURN_ON_BAD_STATE (
1822+ env,
1823+ db->IsInUserFunctionCallback (),
1824+ " database operation is not allowed inside a user-defined function "
1825+ " callback" );
18111826
18121827 if (!args[0 ]->IsUint8Array ()) {
18131828 THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
@@ -2505,8 +2520,12 @@ int DatabaseSync::AuthorizerCallback(void* user_data,
25052520 NullableSQLiteStringToValue (isolate, param4).ToLocalChecked (),
25062521 });
25072522
2508- MaybeLocal<Value> retval = callback->Call (
2509- context, Undefined (isolate), js_argv.size (), js_argv.data ());
2523+ MaybeLocal<Value> retval;
2524+ {
2525+ auto guard = db->EnterUserFunctionCallback ();
2526+ retval = callback->Call (
2527+ context, Undefined (isolate), js_argv.size (), js_argv.data ());
2528+ }
25102529
25112530 Local<Value> result;
25122531
@@ -2576,10 +2595,6 @@ void StatementSync::Finalize() {
25762595 if (statement_ == nullptr ) {
25772596 return ;
25782597 }
2579- if (stepping_) {
2580- finalize_pending_ = true ;
2581- return ;
2582- }
25832598 sqlite3_finalize (statement_);
25842599 statement_ = nullptr ;
25852600 InvalidateColumnNameCache ();
@@ -2905,10 +2920,6 @@ MaybeLocal<Object> StatementExecutionHelper::Run(Environment* env,
29052920 EscapableHandleScope scope (isolate);
29062921 sqlite3_step (stmt);
29072922 int r = sqlite3_reset (stmt);
2908- if (db->Connection () == nullptr ) {
2909- THROW_ERR_INVALID_STATE (env, " database connection was closed mid-query" );
2910- return MaybeLocal<Object>();
2911- }
29122923 CHECK_ERROR_OR_THROW (isolate, db, r, SQLITE_OK, MaybeLocal<Object>());
29132924
29142925 sqlite3_int64 last_insert_rowid = sqlite3_last_insert_rowid (db->Connection ());
@@ -3029,6 +3040,11 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
30293040 Environment* env = Environment::GetCurrent (args);
30303041 THROW_AND_RETURN_ON_BAD_STATE (
30313042 env, stmt->IsFinalized (), " statement has been finalized" );
3043+ THROW_AND_RETURN_ON_BAD_STATE (
3044+ env,
3045+ stmt->db_ ->IsInUserFunctionCallback (),
3046+ " database operation is not allowed inside a user-defined function "
3047+ " callback" );
30323048 Isolate* isolate = env->isolate ();
30333049 int r = stmt->ResetStatement ();
30343050 CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_OK, void ());
@@ -3038,7 +3054,6 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
30383054 }
30393055
30403056 Local<Value> result;
3041- auto step = stmt->MarkStepping ();
30423057 auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
30433058 if (StatementExecutionHelper::All (env,
30443059 stmt->db_ .get (),
@@ -3056,6 +3071,11 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
30563071 Environment* env = Environment::GetCurrent (args);
30573072 THROW_AND_RETURN_ON_BAD_STATE (
30583073 env, stmt->IsFinalized (), " statement has been finalized" );
3074+ THROW_AND_RETURN_ON_BAD_STATE (
3075+ env,
3076+ stmt->db_ ->IsInUserFunctionCallback (),
3077+ " database operation is not allowed inside a user-defined function "
3078+ " callback" );
30593079 int r = stmt->ResetStatement ();
30603080 CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ .get (), r, SQLITE_OK, void ());
30613081
@@ -3079,6 +3099,11 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
30793099 Environment* env = Environment::GetCurrent (args);
30803100 THROW_AND_RETURN_ON_BAD_STATE (
30813101 env, stmt->IsFinalized (), " statement has been finalized" );
3102+ THROW_AND_RETURN_ON_BAD_STATE (
3103+ env,
3104+ stmt->db_ ->IsInUserFunctionCallback (),
3105+ " database operation is not allowed inside a user-defined function "
3106+ " callback" );
30823107 int r = stmt->ResetStatement ();
30833108 CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ .get (), r, SQLITE_OK, void ());
30843109
@@ -3087,7 +3112,6 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
30873112 }
30883113
30893114 Local<Value> result;
3090- auto step = stmt->MarkStepping ();
30913115 if (StatementExecutionHelper::Get (env,
30923116 stmt->db_ .get (),
30933117 stmt->statement_ ,
@@ -3104,6 +3128,11 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
31043128 Environment* env = Environment::GetCurrent (args);
31053129 THROW_AND_RETURN_ON_BAD_STATE (
31063130 env, stmt->IsFinalized (), " statement has been finalized" );
3131+ THROW_AND_RETURN_ON_BAD_STATE (
3132+ env,
3133+ stmt->db_ ->IsInUserFunctionCallback (),
3134+ " database operation is not allowed inside a user-defined function "
3135+ " callback" );
31073136 int r = stmt->ResetStatement ();
31083137 CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ .get (), r, SQLITE_OK, void ());
31093138
@@ -3112,7 +3141,6 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
31123141 }
31133142
31143143 Local<Object> result;
3115- auto step = stmt->MarkStepping ();
31163144 if (StatementExecutionHelper::Run (
31173145 env, stmt->db_ .get (), stmt->statement_ , stmt->use_big_ints_ )
31183146 .ToLocal (&result)) {
@@ -3358,6 +3386,11 @@ void SQLTagStore::Run(const FunctionCallbackInfo<Value>& args) {
33583386
33593387 THROW_AND_RETURN_ON_BAD_STATE (
33603388 env, !session->database_ ->IsOpen (), " database is not open" );
3389+ THROW_AND_RETURN_ON_BAD_STATE (
3390+ env,
3391+ session->database_ ->IsInUserFunctionCallback (),
3392+ " database operation is not allowed inside a user-defined function "
3393+ " callback" );
33613394
33623395 BaseObjectPtr<StatementSync> stmt = PrepareStatement (args);
33633396
@@ -3366,7 +3399,7 @@ void SQLTagStore::Run(const FunctionCallbackInfo<Value>& args) {
33663399 }
33673400
33683401 uint32_t n_params = args.Length () - 1 ;
3369- int r = sqlite3_reset ( stmt->statement_ );
3402+ int r = stmt->ResetStatement ( );
33703403 CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ .get (), r, SQLITE_OK, void ());
33713404 int param_count = sqlite3_bind_parameter_count (stmt->statement_ );
33723405 for (int i = 0 ; i < static_cast <int >(n_params) && i < param_count; ++i) {
@@ -3377,7 +3410,6 @@ void SQLTagStore::Run(const FunctionCallbackInfo<Value>& args) {
33773410 }
33783411
33793412 Local<Object> result;
3380- auto step = stmt->MarkStepping ();
33813413 if (StatementExecutionHelper::Run (
33823414 env, stmt->db_ .get (), stmt->statement_ , stmt->use_big_ints_ )
33833415 .ToLocal (&result)) {
@@ -3392,6 +3424,11 @@ void SQLTagStore::Iterate(const FunctionCallbackInfo<Value>& args) {
33923424
33933425 THROW_AND_RETURN_ON_BAD_STATE (
33943426 env, !session->database_ ->IsOpen (), " database is not open" );
3427+ THROW_AND_RETURN_ON_BAD_STATE (
3428+ env,
3429+ session->database_ ->IsInUserFunctionCallback (),
3430+ " database operation is not allowed inside a user-defined function "
3431+ " callback" );
33953432
33963433 BaseObjectPtr<StatementSync> stmt = PrepareStatement (args);
33973434
@@ -3400,7 +3437,7 @@ void SQLTagStore::Iterate(const FunctionCallbackInfo<Value>& args) {
34003437 }
34013438
34023439 uint32_t n_params = args.Length () - 1 ;
3403- int r = sqlite3_reset ( stmt->statement_ );
3440+ int r = stmt->ResetStatement ( );
34043441 CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ .get (), r, SQLITE_OK, void ());
34053442 int param_count = sqlite3_bind_parameter_count (stmt->statement_ );
34063443 for (int i = 0 ; i < static_cast <int >(n_params) && i < param_count; ++i) {
@@ -3427,6 +3464,11 @@ void SQLTagStore::Get(const FunctionCallbackInfo<Value>& args) {
34273464
34283465 THROW_AND_RETURN_ON_BAD_STATE (
34293466 env, !session->database_ ->IsOpen (), " database is not open" );
3467+ THROW_AND_RETURN_ON_BAD_STATE (
3468+ env,
3469+ session->database_ ->IsInUserFunctionCallback (),
3470+ " database operation is not allowed inside a user-defined function "
3471+ " callback" );
34303472
34313473 BaseObjectPtr<StatementSync> stmt = PrepareStatement (args);
34323474
@@ -3437,7 +3479,7 @@ void SQLTagStore::Get(const FunctionCallbackInfo<Value>& args) {
34373479 uint32_t n_params = args.Length () - 1 ;
34383480 Isolate* isolate = env->isolate ();
34393481
3440- int r = sqlite3_reset ( stmt->statement_ );
3482+ int r = stmt->ResetStatement ( );
34413483 CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_OK, void ());
34423484
34433485 int param_count = sqlite3_bind_parameter_count (stmt->statement_ );
@@ -3449,7 +3491,6 @@ void SQLTagStore::Get(const FunctionCallbackInfo<Value>& args) {
34493491 }
34503492
34513493 Local<Value> result;
3452- auto step = stmt->MarkStepping ();
34533494 if (StatementExecutionHelper::Get (env,
34543495 stmt->db_ .get (),
34553496 stmt->statement_ ,
@@ -3467,6 +3508,11 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
34673508
34683509 THROW_AND_RETURN_ON_BAD_STATE (
34693510 env, !session->database_ ->IsOpen (), " database is not open" );
3511+ THROW_AND_RETURN_ON_BAD_STATE (
3512+ env,
3513+ session->database_ ->IsInUserFunctionCallback (),
3514+ " database operation is not allowed inside a user-defined function "
3515+ " callback" );
34703516
34713517 BaseObjectPtr<StatementSync> stmt = PrepareStatement (args);
34723518
@@ -3477,7 +3523,7 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
34773523 uint32_t n_params = args.Length () - 1 ;
34783524 Isolate* isolate = env->isolate ();
34793525
3480- int r = sqlite3_reset ( stmt->statement_ );
3526+ int r = stmt->ResetStatement ( );
34813527 CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_OK, void ());
34823528
34833529 int param_count = sqlite3_bind_parameter_count (stmt->statement_ );
@@ -3489,7 +3535,6 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
34893535 }
34903536
34913537 Local<Value> result;
3492- auto step = stmt->MarkStepping ();
34933538 auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
34943539 if (StatementExecutionHelper::All (env,
34953540 stmt->db_ .get (),
@@ -3504,6 +3549,11 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
35043549void SQLTagStore::Clear (const FunctionCallbackInfo<Value>& args) {
35053550 SQLTagStore* store;
35063551 ASSIGN_OR_RETURN_UNWRAP (&store, args.This ());
3552+ Environment* env = Environment::GetCurrent (args);
3553+ THROW_AND_RETURN_ON_BAD_STATE (
3554+ env,
3555+ store->database_ ->IsInUserFunctionCallback (),
3556+ " tag store cannot be cleared inside a user-defined function callback" );
35073557 store->sql_tags_ .Clear ();
35083558}
35093559
@@ -3695,6 +3745,11 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
36953745 Environment* env = Environment::GetCurrent (args);
36963746 THROW_AND_RETURN_ON_BAD_STATE (
36973747 env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
3748+ THROW_AND_RETURN_ON_BAD_STATE (
3749+ env,
3750+ iter->stmt_ ->db_ ->IsInUserFunctionCallback (),
3751+ " database operation is not allowed inside a user-defined function "
3752+ " callback" );
36983753 Isolate* isolate = env->isolate ();
36993754
37003755 auto iter_template = getLazyIterTemplate (env);
@@ -3717,7 +3772,6 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
37173772 iter->statement_reset_generation_ != iter->stmt_ ->reset_generation_ ,
37183773 " iterator was invalidated" );
37193774
3720- auto step = iter->stmt_ ->MarkStepping ();
37213775 int r = sqlite3_step (iter->stmt_ ->statement_ );
37223776 if (r != SQLITE_ROW) {
37233777 CHECK_ERROR_OR_THROW (
@@ -3772,6 +3826,11 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
37723826 Environment* env = Environment::GetCurrent (args);
37733827 THROW_AND_RETURN_ON_BAD_STATE (
37743828 env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
3829+ THROW_AND_RETURN_ON_BAD_STATE (
3830+ env,
3831+ iter->stmt_ ->db_ ->IsInUserFunctionCallback (),
3832+ " database operation is not allowed inside a user-defined function "
3833+ " callback" );
37753834 Isolate* isolate = env->isolate ();
37763835
37773836 sqlite3_reset (iter->stmt_ ->statement_ );
0 commit comments