| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7aff78d commit 7c61b08
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1194,6 +1194,15 @@ added: v22.5.0 | |||
| 1194 | 1194 | The source SQL text of the prepared statement. This property is a | |
| 1195 | 1195 | wrapper around [`sqlite3_sql()`][]. | |
| 1196 | 1196 | ||
| 1197 | + ### `statement[Symbol.dispose]()` | ||
| 1198 | + | ||
| 1199 | + <!-- YAML | ||
| 1200 | + added: REPLACEME | ||
| 1201 | + --> | ||
| 1202 | + | ||
| 1203 | + Finalizes the prepared statement. If the prepared statement is already | ||
| 1204 | + finalized, then this is a no-op. | ||
| 1205 | + | ||
| 1197 | 1206 | ## Class: `SQLTagStore` | |
| 1198 | 1207 | ||
| 1199 | 1208 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1058,10 +1058,7 @@ void DatabaseSync::FinalizeStatements() { | |||
| 1058 | 1058 | } | |
| 1059 | 1059 | ||
| 1060 | 1060 | void DatabaseSync::UntrackStatement(StatementSync* statement) { | |
| 1061 | - auto it = statements_.find(statement); | ||
| 1062 | - if (it != statements_.end()) { | ||
| 1063 | - statements_.erase(it); | ||
| 1064 | - } | ||
| 1061 | + statements_.erase(statement); | ||
| 1065 | 1062 | } | |
| 1066 | 1063 | ||
| 1067 | 1064 | inline bool DatabaseSync::IsOpen() { | |
@@ -2634,6 +2631,10 @@ StatementSync::StatementSync(Environment* env, | |||
| 2634 | 2631 | } | |
| 2635 | 2632 | ||
| 2636 | 2633 | StatementSync::~StatementSync() { | |
| 2634 | + Close(); | ||
| 2635 | + } | ||
| 2636 | + | ||
| 2637 | + void StatementSync::Close() { | ||
| 2637 | 2638 | if (!IsFinalized()) { | |
| 2638 | 2639 | db_->UntrackStatement(this); | |
| 2639 | 2640 | Finalize(); | |
@@ -2654,6 +2655,12 @@ inline bool StatementSync::IsFinalized() { | |||
| 2654 | 2655 | return statement_ == nullptr; | |
| 2655 | 2656 | } | |
| 2656 | 2657 | ||
| 2658 | + void StatementSync::Close(const FunctionCallbackInfo<Value>& args) { | ||
| 2659 | + StatementSync* stmt; | ||
| 2660 | + ASSIGN_OR_RETURN_UNWRAP(&stmt, args.This()); | ||
| 2661 | + stmt->Close(); | ||
| 2662 | + } | ||
| 2663 | + | ||
| 2657 | 2664 | inline int StatementSync::ResetStatement() { | |
| 2658 | 2665 | reset_generation_++; | |
| 2659 | 2666 | return sqlite3_reset(statement_); | |
@@ -3687,6 +3694,7 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate( | |||
| 3687 | 3694 | isolate, tmpl, "setReadBigInts", StatementSync::SetReadBigInts); | |
| 3688 | 3695 | SetProtoMethod( | |
| 3689 | 3696 | isolate, tmpl, "setReturnArrays", StatementSync::SetReturnArrays); | |
| 3697 | + SetProtoDispose(isolate, tmpl, StatementSync::Close); | ||
| 3690 | 3698 | env->set_sqlite_statement_sync_constructor_template(tmpl); | |
| 3691 | 3699 | } | |
| 3692 | 3700 | return tmpl; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -284,6 +284,7 @@ class StatementSync : public BaseObject { | |||
| 284 | 284 | const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 285 | 285 | static void SetReadBigInts(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 286 | 286 | static void SetReturnArrays(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 287 | + static void Close(const v8::FunctionCallbackInfo<v8::Value>& args); | ||
| 287 | 288 | v8::MaybeLocal<v8::Value> ColumnToValue(const int column); | |
| 288 | 289 | v8::MaybeLocal<v8::Name> ColumnNameToName(const int column); | |
| 289 | 290 | bool GetCachedColumnNames(v8::LocalVector<v8::Name>* keys); | |
@@ -295,6 +296,7 @@ class StatementSync : public BaseObject { | |||
| 295 | 296 | ||
| 296 | 297 | private: | |
| 297 | 298 | ~StatementSync() override; | |
| 299 | + void Close(); | ||
| 298 | 300 | BaseObjectPtr<DatabaseSync> db_; | |
| 299 | 301 | sqlite3_stmt* statement_; | |
| 300 | 302 | bool return_arrays_ = false; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -969,3 +969,46 @@ suite('options.allowBareNamedParameters', () => { | |||
| 969 | 969 | ); | |
| 970 | 970 | }); | |
| 971 | 971 | }); | |
| 972 | + | ||
| 973 | + | ||
| 974 | + suite('StatementSync.prototype[Symbol.dispose]()', () => { | ||
| 975 | + test('finalizes an open statement', (t) => { | ||
| 976 | + using db = new DatabaseSync(':memory:'); | ||
| 977 | + db.exec('CREATE TABLE storage(key TEXT, val TEXT)'); | ||
| 978 | + const stmt = db.prepare('SELECT * FROM storage'); | ||
| 979 | + stmt[Symbol.dispose](); | ||
| 980 | + t.assert.throws(() => stmt.get(), { | ||
| 981 | + code: 'ERR_INVALID_STATE', | ||
| 982 | + message: /statement has been finalized/, | ||
| 983 | + }); | ||
| 984 | + }); | ||
| 985 | + | ||
| 986 | + test('does not throw on an already-finalized statement', () => { | ||
| 987 | + using db = new DatabaseSync(':memory:'); | ||
| 988 | + const stmt = db.prepare('CREATE TABLE storage(key TEXT, val TEXT)'); | ||
| 989 | + stmt[Symbol.dispose](); | ||
| 990 | + stmt[Symbol.dispose](); | ||
| 991 | + }); | ||
| 992 | + | ||
| 993 | + test('works with a using declaration', (t) => { | ||
| 994 | + using db = new DatabaseSync(':memory:'); | ||
| 995 | + db.exec('CREATE TABLE storage(key TEXT, val TEXT)'); | ||
| 996 | + let captured; | ||
| 997 | + { | ||
| 998 | + using stmt = db.prepare('SELECT * FROM storage'); | ||
| 999 | + captured = stmt; | ||
| 1000 | + t.assert.deepStrictEqual(stmt.all(), []); | ||
| 1001 | + } | ||
| 1002 | + t.assert.throws(() => captured.get(), { | ||
| 1003 | + code: 'ERR_INVALID_STATE', | ||
| 1004 | + message: /statement has been finalized/, | ||
| 1005 | + }); | ||
| 1006 | + }); | ||
| 1007 | + | ||
| 1008 | + test('closing the database after dispose does not double-finalize', () => { | ||
| 1009 | + using db = new DatabaseSync(':memory:'); | ||
| 1010 | + const stmt = db.prepare('CREATE TABLE storage(key TEXT, val TEXT)'); | ||
| 1011 | + stmt[Symbol.dispose](); | ||
| 1012 | + db.close(); | ||
| 1013 | + }); | ||
| 1014 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments