| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 51b8576 commit 94e2ea6
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,10 +9,13 @@ | |||
| 9 | 9 | #include "util.h" | |
| 10 | 10 | ||
| 11 | 11 | #include <map> | |
| 12 | + #include <unordered_set> | ||
| 12 | 13 | ||
| 13 | 14 | namespace node { | |
| 14 | 15 | namespace sqlite { | |
| 15 | 16 | ||
| 17 | + class StatementSync; | ||
| 18 | + | ||
| 16 | 19 | class DatabaseSync : public BaseObject { | |
| 17 | 20 | public: | |
| 18 | 21 | DatabaseSync(Environment* env, | |
@@ -25,6 +28,10 @@ class DatabaseSync : public BaseObject { | |||
| 25 | 28 | static void Close(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 26 | 29 | static void Prepare(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 27 | 30 | static void Exec(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 31 | + void FinalizeStatements(); | ||
| 32 | + void UntrackStatement(StatementSync* statement); | ||
| 33 | + bool IsOpen(); | ||
| 34 | + sqlite3* Connection(); | ||
| 28 | 35 | ||
| 29 | 36 | SET_MEMORY_INFO_NAME(DatabaseSync) | |
| 30 | 37 | SET_SELF_SIZE(DatabaseSync) | |
@@ -35,19 +42,20 @@ class DatabaseSync : public BaseObject { | |||
| 35 | 42 | ~DatabaseSync() override; | |
| 36 | 43 | std::string location_; | |
| 37 | 44 | sqlite3* connection_; | |
| 45 | + std::unordered_set<StatementSync*> statements_; | ||
| 38 | 46 | }; | |
| 39 | 47 | ||
| 40 | 48 | class StatementSync : public BaseObject { | |
| 41 | 49 | public: | |
| 42 | 50 | StatementSync(Environment* env, | |
| 43 | 51 | v8::Local<v8::Object> object, | |
| 44 | - sqlite3* db, | ||
| 52 | + DatabaseSync* db, | ||
| 45 | 53 | sqlite3_stmt* stmt); | |
| 46 | 54 | void MemoryInfo(MemoryTracker* tracker) const override; | |
| 47 | 55 | static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( | |
| 48 | 56 | Environment* env); | |
| 49 | 57 | static BaseObjectPtr<StatementSync> Create(Environment* env, | |
| 50 | - sqlite3* db, | ||
| 58 | + DatabaseSync* db, | ||
| 51 | 59 | sqlite3_stmt* stmt); | |
| 52 | 60 | static void All(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 53 | 61 | static void Get(const v8::FunctionCallbackInfo<v8::Value>& args); | |
@@ -57,13 +65,15 @@ class StatementSync : public BaseObject { | |||
| 57 | 65 | static void SetAllowBareNamedParameters( | |
| 58 | 66 | const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 59 | 67 | static void SetReadBigInts(const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 68 | + void Finalize(); | ||
| 69 | + bool IsFinalized(); | ||
| 60 | 70 | ||
| 61 | 71 | SET_MEMORY_INFO_NAME(StatementSync) | |
| 62 | 72 | SET_SELF_SIZE(StatementSync) | |
| 63 | 73 | ||
| 64 | 74 | private: | |
| 65 | 75 | ~StatementSync() override; | |
| 66 | - sqlite3* db_; | ||
| 76 | + DatabaseSync* db_; | ||
| 67 | 77 | sqlite3_stmt* statement_; | |
| 68 | 78 | bool use_big_ints_; | |
| 69 | 79 | bool allow_bare_named_params_; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments