| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent cf425ad commit 90a8b23
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -912,10 +912,9 @@ void DatabaseSync::RemoveBackup(BackupJob* job) { | |||
| 912 | 912 | void DatabaseSync::DeleteSessions() { | |
| 913 | 913 | // all attached sessions need to be deleted before the database is closed | |
| 914 | 914 | // https://www.sqlite.org/session/sqlite3session_create.html | |
| 915 | - for (auto* session : sessions_) { | ||
| 916 | - sqlite3session_delete(session); | ||
| 915 | + while (!sessions_.empty()) { | ||
| 916 | + (*sessions_.begin())->Delete(); | ||
| 917 | 917 | } | |
| 918 | - sessions_.clear(); | ||
| 919 | 918 | } | |
| 920 | 919 | ||
| 921 | 920 | DatabaseSync::~DatabaseSync() { | |
@@ -2118,13 +2117,22 @@ void DatabaseSync::CreateSession(const FunctionCallbackInfo<Value>& args) { | |||
| 2118 | 2117 | sqlite3_session* pSession; | |
| 2119 | 2118 | int r = sqlite3session_create(db->connection_, db_name.c_str(), &pSession); | |
| 2120 | 2119 | CHECK_ERROR_OR_THROW(env->isolate(), db, r, SQLITE_OK, void()); | |
| 2121 | - db->sessions_.insert(pSession); | ||
| 2120 | + bool wrapper_owns_session = false; | ||
| 2121 | + auto delete_session_on_failure = OnScopeLeave([&]() { | ||
| 2122 | + if (!wrapper_owns_session) { | ||
| 2123 | + sqlite3session_delete(pSession); | ||
| 2124 | + } | ||
| 2125 | + }); | ||
| 2122 | 2126 | ||
| 2123 | 2127 | r = sqlite3session_attach(pSession, table == "" ? nullptr : table.c_str()); | |
| 2124 | 2128 | CHECK_ERROR_OR_THROW(env->isolate(), db, r, SQLITE_OK, void()); | |
| 2125 | 2129 | ||
| 2126 | 2130 | BaseObjectPtr<Session> session = | |
| 2127 | 2131 | Session::Create(env, BaseObjectPtr<DatabaseSync>(db), pSession); | |
| 2132 | + if (!session) { | ||
| 2133 | + return; | ||
| 2134 | + } | ||
| 2135 | + wrapper_owns_session = true; | ||
| 2128 | 2136 | args.GetReturnValue().Set(session->object()); | |
| 2129 | 2137 | } | |
| 2130 | 2138 | ||
@@ -3813,6 +3821,7 @@ Session::Session(Environment* env, | |||
| 3813 | 3821 | : BaseObject(env, object), | |
| 3814 | 3822 | session_(session), | |
| 3815 | 3823 | database_(std::move(database)) { | |
| 3824 | + database_->sessions_.insert(this); | ||
| 3816 | 3825 | MakeWeak(); | |
| 3817 | 3826 | } | |
| 3818 | 3827 | ||
@@ -3905,10 +3914,12 @@ void Session::Dispose(const v8::FunctionCallbackInfo<v8::Value>& args) { | |||
| 3905 | 3914 | } | |
| 3906 | 3915 | ||
| 3907 | 3916 | void Session::Delete() { | |
| 3908 | - if (!database_ || !database_->connection_ || session_ == nullptr) return; | ||
| 3917 | + if (session_ == nullptr) return; | ||
| 3909 | 3918 | sqlite3session_delete(session_); | |
| 3910 | - database_->sessions_.erase(session_); | ||
| 3911 | 3919 | session_ = nullptr; | |
| 3920 | + if (database_) { | ||
| 3921 | + database_->sessions_.erase(this); | ||
| 3922 | + } | ||
| 3912 | 3923 | } | |
| 3913 | 3924 | ||
| 3914 | 3925 | void DefineConstants(Local<Object> target) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -133,6 +133,7 @@ class DatabaseSyncLimits; | |||
| 133 | 133 | class StatementSyncIterator; | |
| 134 | 134 | class StatementSync; | |
| 135 | 135 | class BackupJob; | |
| 136 | + class Session; | ||
| 136 | 137 | ||
| 137 | 138 | class StatementExecutionHelper { | |
| 138 | 139 | public: | |
@@ -243,7 +244,7 @@ class DatabaseSync : public BaseObject { | |||
| 243 | 244 | bool ignore_next_sqlite_error_; | |
| 244 | 245 | ||
| 245 | 246 | std::set<BackupJob*> backups_; | |
| 246 | - std::set<sqlite3_session*> sessions_; | ||
| 247 | + std::unordered_set<Session*> sessions_; | ||
| 247 | 248 | std::unordered_set<StatementSync*> statements_; | |
| 248 | 249 | ||
| 249 | 250 | friend class DatabaseSyncLimits; | |
@@ -360,6 +361,8 @@ class Session : public BaseObject { | |||
| 360 | 361 | void Delete(); | |
| 361 | 362 | sqlite3_session* session_; | |
| 362 | 363 | BaseObjectPtr<DatabaseSync> database_; // The Parent Database | |
| 364 | + | ||
| 365 | + friend class DatabaseSync; | ||
| 363 | 366 | }; | |
| 364 | 367 | ||
| 365 | 368 | class SQLTagStore : public BaseObject { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -81,6 +81,22 @@ test('session.changeset() - closed database results in exception', (t) => { | |||
| 81 | 81 | }); | |
| 82 | 82 | }); | |
| 83 | 83 | ||
| 84 | + test('session methods - reopened database results in exception', (t) => { | ||
| 85 | + for (const method of ['changeset', 'close']) { | ||
| 86 | + const database = new DatabaseSync(':memory:'); | ||
| 87 | + const session = database.createSession(); | ||
| 88 | + database.close(); | ||
| 89 | + database.open(); | ||
| 90 | + | ||
| 91 | + t.assert.throws(() => { | ||
| 92 | + session[method](); | ||
| 93 | + }, { | ||
| 94 | + name: 'Error', | ||
| 95 | + message: 'session is not open', | ||
| 96 | + }); | ||
| 97 | + } | ||
| 98 | + }); | ||
| 99 | + | ||
| 84 | 100 | test('database.applyChangeset() - closed database results in exception', (t) => { | |
| 85 | 101 | const database = new DatabaseSync(':memory:'); | |
| 86 | 102 | const session = database.createSession(); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments