@@ -91,16 +91,19 @@ DatabaseSync::DatabaseSync(Environment* env,
91
91
}
92
92
93
93
DatabaseSync::~DatabaseSync () {
94
- sqlite3_close_v2 (connection_);
95
- connection_ = nullptr ;
94
+ if (IsOpen ()) {
95
+ FinalizeStatements ();
96
+ sqlite3_close_v2 (connection_);
97
+ connection_ = nullptr ;
98
+ }
96
99
}
97
100
98
101
void DatabaseSync::MemoryInfo (MemoryTracker* tracker) const {
99
102
tracker->TrackField (" location" , location_);
100
103
}
101
104
102
105
bool DatabaseSync::Open () {
103
- if (connection_ != nullptr ) {
106
+ if (IsOpen () ) {
104
107
node::THROW_ERR_INVALID_STATE (env (), " database is already open" );
105
108
return false ;
106
109
}
@@ -112,6 +115,29 @@ bool DatabaseSync::Open() {
112
115
return true ;
113
116
}
114
117
118
+ void DatabaseSync::FinalizeStatements () {
119
+ for (auto stmt : statements_) {
120
+ stmt->Finalize ();
121
+ }
122
+
123
+ statements_.clear ();
124
+ }
125
+
126
+ void DatabaseSync::UntrackStatement (StatementSync* statement) {
127
+ auto it = statements_.find (statement);
128
+ if (it != statements_.end ()) {
129
+ statements_.erase (it);
130
+ }
131
+ }
132
+
133
+ inline bool DatabaseSync::IsOpen () {
134
+ return connection_ != nullptr ;
135
+ }
136
+
137
+ inline sqlite3* DatabaseSync::Connection () {
138
+ return connection_;
139
+ }
140
+
115
141
void DatabaseSync::New (const FunctionCallbackInfo<Value>& args) {
116
142
Environment* env = Environment::GetCurrent (args);
117
143
@@ -164,8 +190,8 @@ void DatabaseSync::Close(const FunctionCallbackInfo<Value>& args) {
164
190
DatabaseSync* db;
165
191
ASSIGN_OR_RETURN_UNWRAP (&db, args.This ());
166
192
Environment* env = Environment::GetCurrent (args);
167
- THROW_AND_RETURN_ON_BAD_STATE (
168
- env, db->connection_ == nullptr , " database is not open " );
193
+ THROW_AND_RETURN_ON_BAD_STATE (env, !db-> IsOpen (), " database is not open " );
194
+ db->FinalizeStatements ( );
169
195
int r = sqlite3_close_v2 (db->connection_ );
170
196
CHECK_ERROR_OR_THROW (env->isolate (), db->connection_ , r, SQLITE_OK, void ());
171
197
db->connection_ = nullptr ;
@@ -175,8 +201,7 @@ void DatabaseSync::Prepare(const FunctionCallbackInfo<Value>& args) {
175
201
DatabaseSync* db;
176
202
ASSIGN_OR_RETURN_UNWRAP (&db, args.This ());
177
203
Environment* env = Environment::GetCurrent (args);
178
- THROW_AND_RETURN_ON_BAD_STATE (
179
- env, db->connection_ == nullptr , " database is not open" );
204
+ THROW_AND_RETURN_ON_BAD_STATE (env, !db->IsOpen (), " database is not open" );
180
205
181
206
if (!args[0 ]->IsString ()) {
182
207
node::THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
@@ -188,17 +213,16 @@ void DatabaseSync::Prepare(const FunctionCallbackInfo<Value>& args) {
188
213
sqlite3_stmt* s = nullptr ;
189
214
int r = sqlite3_prepare_v2 (db->connection_ , *sql, -1 , &s, 0 );
190
215
CHECK_ERROR_OR_THROW (env->isolate (), db->connection_ , r, SQLITE_OK, void ());
191
- BaseObjectPtr<StatementSync> stmt =
192
- StatementSync::Create (env, db->connection_ , s );
216
+ BaseObjectPtr<StatementSync> stmt = StatementSync::Create (env, db, s);
217
+ db->statements_ . insert (stmt. get () );
193
218
args.GetReturnValue ().Set (stmt->object ());
194
219
}
195
220
196
221
void DatabaseSync::Exec (const FunctionCallbackInfo<Value>& args) {
197
222
DatabaseSync* db;
198
223
ASSIGN_OR_RETURN_UNWRAP (&db, args.This ());
199
224
Environment* env = Environment::GetCurrent (args);
200
- THROW_AND_RETURN_ON_BAD_STATE (
201
- env, db->connection_ == nullptr , " database is not open" );
225
+ THROW_AND_RETURN_ON_BAD_STATE (env, !db->IsOpen (), " database is not open" );
202
226
203
227
if (!args[0 ]->IsString ()) {
204
228
node::THROW_ERR_INVALID_ARG_TYPE (env->isolate (),
@@ -213,7 +237,7 @@ void DatabaseSync::Exec(const FunctionCallbackInfo<Value>& args) {
213
237
214
238
StatementSync::StatementSync (Environment* env,
215
239
Local<Object> object,
216
- sqlite3 * db,
240
+ DatabaseSync * db,
217
241
sqlite3_stmt* stmt)
218
242
: BaseObject(env, object) {
219
243
MakeWeak ();
@@ -227,13 +251,25 @@ StatementSync::StatementSync(Environment* env,
227
251
}
228
252
229
253
StatementSync::~StatementSync () {
254
+ if (!IsFinalized ()) {
255
+ db_->UntrackStatement (this );
256
+ Finalize ();
257
+ }
258
+ }
259
+
260
+ void StatementSync::Finalize () {
230
261
sqlite3_finalize (statement_);
231
262
statement_ = nullptr ;
232
263
}
233
264
265
+ inline bool StatementSync::IsFinalized () {
266
+ return statement_ == nullptr ;
267
+ }
268
+
234
269
bool StatementSync::BindParams (const FunctionCallbackInfo<Value>& args) {
235
270
int r = sqlite3_clear_bindings (statement_);
236
- CHECK_ERROR_OR_THROW (env ()->isolate (), db_, r, SQLITE_OK, false );
271
+ CHECK_ERROR_OR_THROW (
272
+ env ()->isolate (), db_->Connection (), r, SQLITE_OK, false );
237
273
238
274
int anon_idx = 1 ;
239
275
int anon_start = 0 ;
@@ -364,7 +400,8 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
364
400
return false ;
365
401
}
366
402
367
- CHECK_ERROR_OR_THROW (env ()->isolate (), db_, r, SQLITE_OK, false );
403
+ CHECK_ERROR_OR_THROW (
404
+ env ()->isolate (), db_->Connection (), r, SQLITE_OK, false );
368
405
return true ;
369
406
}
370
407
@@ -435,8 +472,11 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
435
472
StatementSync* stmt;
436
473
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
437
474
Environment* env = Environment::GetCurrent (args);
475
+ THROW_AND_RETURN_ON_BAD_STATE (
476
+ env, stmt->IsFinalized (), " statement has been finalized" );
438
477
int r = sqlite3_reset (stmt->statement_ );
439
- CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ , r, SQLITE_OK, void ());
478
+ CHECK_ERROR_OR_THROW (
479
+ env->isolate (), stmt->db_ ->Connection (), r, SQLITE_OK, void ());
440
480
441
481
if (!stmt->BindParams (args)) {
442
482
return ;
@@ -462,7 +502,8 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
462
502
rows.emplace_back (row);
463
503
}
464
504
465
- CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ , r, SQLITE_DONE, void ());
505
+ CHECK_ERROR_OR_THROW (
506
+ env->isolate (), stmt->db_ ->Connection (), r, SQLITE_DONE, void ());
466
507
args.GetReturnValue ().Set (
467
508
Array::New (env->isolate (), rows.data (), rows.size ()));
468
509
}
@@ -471,8 +512,11 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
471
512
StatementSync* stmt;
472
513
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
473
514
Environment* env = Environment::GetCurrent (args);
515
+ THROW_AND_RETURN_ON_BAD_STATE (
516
+ env, stmt->IsFinalized (), " statement has been finalized" );
474
517
int r = sqlite3_reset (stmt->statement_ );
475
- CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ , r, SQLITE_OK, void ());
518
+ CHECK_ERROR_OR_THROW (
519
+ env->isolate (), stmt->db_ ->Connection (), r, SQLITE_OK, void ());
476
520
477
521
if (!stmt->BindParams (args)) {
478
522
return ;
@@ -482,7 +526,7 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
482
526
r = sqlite3_step (stmt->statement_ );
483
527
if (r == SQLITE_DONE) return ;
484
528
if (r != SQLITE_ROW) {
485
- THROW_ERR_SQLITE_ERROR (env->isolate (), stmt->db_ );
529
+ THROW_ERR_SQLITE_ERROR (env->isolate (), stmt->db_ -> Connection () );
486
530
return ;
487
531
}
488
532
@@ -511,8 +555,11 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
511
555
StatementSync* stmt;
512
556
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
513
557
Environment* env = Environment::GetCurrent (args);
558
+ THROW_AND_RETURN_ON_BAD_STATE (
559
+ env, stmt->IsFinalized (), " statement has been finalized" );
514
560
int r = sqlite3_reset (stmt->statement_ );
515
- CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ , r, SQLITE_OK, void ());
561
+ CHECK_ERROR_OR_THROW (
562
+ env->isolate (), stmt->db_ ->Connection (), r, SQLITE_OK, void ());
516
563
517
564
if (!stmt->BindParams (args)) {
518
565
return ;
@@ -521,7 +568,7 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
521
568
auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
522
569
r = sqlite3_step (stmt->statement_ );
523
570
if (r != SQLITE_ROW && r != SQLITE_DONE) {
524
- THROW_ERR_SQLITE_ERROR (env->isolate (), stmt->db_ );
571
+ THROW_ERR_SQLITE_ERROR (env->isolate (), stmt->db_ -> Connection () );
525
572
return ;
526
573
}
527
574
@@ -530,8 +577,9 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
530
577
FIXED_ONE_BYTE_STRING (env->isolate (), " lastInsertRowid" );
531
578
Local<String> changes_string =
532
579
FIXED_ONE_BYTE_STRING (env->isolate (), " changes" );
533
- sqlite3_int64 last_insert_rowid = sqlite3_last_insert_rowid (stmt->db_ );
534
- sqlite3_int64 changes = sqlite3_changes64 (stmt->db_ );
580
+ sqlite3_int64 last_insert_rowid =
581
+ sqlite3_last_insert_rowid (stmt->db_ ->Connection ());
582
+ sqlite3_int64 changes = sqlite3_changes64 (stmt->db_ ->Connection ());
535
583
Local<Value> last_insert_rowid_val;
536
584
Local<Value> changes_val;
537
585
@@ -557,6 +605,8 @@ void StatementSync::SourceSQL(const FunctionCallbackInfo<Value>& args) {
557
605
StatementSync* stmt;
558
606
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
559
607
Environment* env = Environment::GetCurrent (args);
608
+ THROW_AND_RETURN_ON_BAD_STATE (
609
+ env, stmt->IsFinalized (), " statement has been finalized" );
560
610
Local<String> sql;
561
611
if (!String::NewFromUtf8 (env->isolate (), sqlite3_sql (stmt->statement_ ))
562
612
.ToLocal (&sql)) {
@@ -569,6 +619,8 @@ void StatementSync::ExpandedSQL(const FunctionCallbackInfo<Value>& args) {
569
619
StatementSync* stmt;
570
620
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
571
621
Environment* env = Environment::GetCurrent (args);
622
+ THROW_AND_RETURN_ON_BAD_STATE (
623
+ env, stmt->IsFinalized (), " statement has been finalized" );
572
624
char * expanded = sqlite3_expanded_sql (stmt->statement_ );
573
625
auto maybe_expanded = String::NewFromUtf8 (env->isolate (), expanded);
574
626
sqlite3_free (expanded);
@@ -584,6 +636,8 @@ void StatementSync::SetAllowBareNamedParameters(
584
636
StatementSync* stmt;
585
637
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
586
638
Environment* env = Environment::GetCurrent (args);
639
+ THROW_AND_RETURN_ON_BAD_STATE (
640
+ env, stmt->IsFinalized (), " statement has been finalized" );
587
641
588
642
if (!args[0 ]->IsBoolean ()) {
589
643
node::THROW_ERR_INVALID_ARG_TYPE (
@@ -599,6 +653,8 @@ void StatementSync::SetReadBigInts(const FunctionCallbackInfo<Value>& args) {
599
653
StatementSync* stmt;
600
654
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
601
655
Environment* env = Environment::GetCurrent (args);
656
+ THROW_AND_RETURN_ON_BAD_STATE (
657
+ env, stmt->IsFinalized (), " statement has been finalized" );
602
658
603
659
if (!args[0 ]->IsBoolean ()) {
604
660
node::THROW_ERR_INVALID_ARG_TYPE (
@@ -640,7 +696,7 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
640
696
}
641
697
642
698
BaseObjectPtr<StatementSync> StatementSync::Create (Environment* env,
643
- sqlite3 * db,
699
+ DatabaseSync * db,
644
700
sqlite3_stmt* stmt) {
645
701
Local<Object> obj;
646
702
if (!GetConstructorTemplate (env)
0 commit comments