@@ -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) { |
|