@@ -2421,6 +2421,11 @@ inline bool StatementSync::IsFinalized() { |
2421 | 2421 | return statement_ == nullptr; |
2422 | 2422 | } |
2423 | 2423 |
|
| 2424 | +inline int StatementSync::ResetStatement() { |
| 2425 | + reset_generation_++; |
| 2426 | + return sqlite3_reset(statement_); |
| 2427 | +} |
| 2428 | + |
2424 | 2429 | bool StatementSync::BindParams(const FunctionCallbackInfo<Value>& args) { |
2425 | 2430 | int r = sqlite3_clear_bindings(statement_); |
2426 | 2431 | CHECK_ERROR_OR_THROW(env()->isolate(), db_.get(), r, SQLITE_OK, false); |
@@ -2812,7 +2817,7 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) { |
2812 | 2817 | THROW_AND_RETURN_ON_BAD_STATE( |
2813 | 2818 | env, stmt->IsFinalized(), "statement has been finalized"); |
2814 | 2819 | Isolate* isolate = env->isolate(); |
2815 | | - int r = sqlite3_reset(stmt->statement_); |
| 2820 | + int r = stmt->ResetStatement(); |
2816 | 2821 | CHECK_ERROR_OR_THROW(isolate, stmt->db_.get(), r, SQLITE_OK, void()); |
2817 | 2822 |
|
2818 | 2823 | if (!stmt->BindParams(args)) { |
@@ -2838,7 +2843,7 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) { |
2838 | 2843 | Environment* env = Environment::GetCurrent(args); |
2839 | 2844 | THROW_AND_RETURN_ON_BAD_STATE( |
2840 | 2845 | env, stmt->IsFinalized(), "statement has been finalized"); |
2841 | | - int r = sqlite3_reset(stmt->statement_); |
| 2846 | + int r = stmt->ResetStatement(); |
2842 | 2847 | CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK, void()); |
2843 | 2848 |
|
2844 | 2849 | if (!stmt->BindParams(args)) { |
@@ -2861,7 +2866,7 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) { |
2861 | 2866 | Environment* env = Environment::GetCurrent(args); |
2862 | 2867 | THROW_AND_RETURN_ON_BAD_STATE( |
2863 | 2868 | env, stmt->IsFinalized(), "statement has been finalized"); |
2864 | | - int r = sqlite3_reset(stmt->statement_); |
| 2869 | + int r = stmt->ResetStatement(); |
2865 | 2870 | CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK, void()); |
2866 | 2871 |
|
2867 | 2872 | if (!stmt->BindParams(args)) { |
@@ -2885,7 +2890,7 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) { |
2885 | 2890 | Environment* env = Environment::GetCurrent(args); |
2886 | 2891 | THROW_AND_RETURN_ON_BAD_STATE( |
2887 | 2892 | env, stmt->IsFinalized(), "statement has been finalized"); |
2888 | | - int r = sqlite3_reset(stmt->statement_); |
| 2893 | + int r = stmt->ResetStatement(); |
2889 | 2894 | CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK, void()); |
2890 | 2895 |
|
2891 | 2896 | if (!stmt->BindParams(args)) { |
@@ -3430,6 +3435,7 @@ StatementSyncIterator::StatementSyncIterator(Environment* env, |
3430 | 3435 | : BaseObject(env, object), stmt_(std::move(stmt)) { |
3431 | 3436 | MakeWeak(); |
3432 | 3437 | done_ = false; |
| 3438 | + statement_reset_generation_ = stmt_->reset_generation_; |
3433 | 3439 | } |
3434 | 3440 |
|
3435 | 3441 | StatementSyncIterator::~StatementSyncIterator() {} |
@@ -3488,6 +3494,11 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) { |
3488 | 3494 | return; |
3489 | 3495 | } |
3490 | 3496 |
|
| 3497 | + THROW_AND_RETURN_ON_BAD_STATE( |
| 3498 | + env, |
| 3499 | + iter->statement_reset_generation_ != iter->stmt_->reset_generation_, |
| 3500 | + "iterator was invalidated"); |
| 3501 | + |
3491 | 3502 | int r = sqlite3_step(iter->stmt_->statement_); |
3492 | 3503 | if (r != SQLITE_ROW) { |
3493 | 3504 | CHECK_ERROR_OR_THROW( |
|