diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cf0c965bb..fec6c0eda 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -112,7 +112,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES db/main-db-key.h db/main-db-p.h db/main-db.h - db/session/db-session-p.h + db/session/db-session.h dial-plan/dial-plan-p.h dial-plan/dial-plan.h enums.h diff --git a/src/db/abstract/abstract-db-p.h b/src/db/abstract/abstract-db-p.h index fa2d12c3f..b74a82157 100644 --- a/src/db/abstract/abstract-db-p.h +++ b/src/db/abstract/abstract-db-p.h @@ -20,6 +20,8 @@ #ifndef _L_ABSTRACT_DB_P_H_ #define _L_ABSTRACT_DB_P_H_ +#include + #include "abstract-db.h" #include "db/session/db-session.h" #include "object/object-p.h" @@ -34,6 +36,8 @@ public: DbSession dbSession; + const std::thread::id threadId = std::this_thread::get_id(); + private: AbstractDb::Backend backend; diff --git a/src/db/internal/db-exception-handler.h b/src/db/internal/db-exception-handler.h index a0135c6d6..2993c58e0 100644 --- a/src/db/internal/db-exception-handler.h +++ b/src/db/internal/db-exception-handler.h @@ -85,19 +85,24 @@ public: >::type; DbExceptionHandler (DbExceptionHandlerInfo &info, Function &&function) : mFunction(std::move(function)) { + MainDb *mainDb = info.mainDb; + L_ASSERT(mainDb->getPrivate()->threadId == std::this_thread::get_id()); + const char *name = info.name; + soci::session *session = mainDb->getPrivate()->dbSession.getBackendSession(); + try { - SmartTransaction tr(info.mainDb->getPrivate()->dbSession.getBackendSession(), name); + SmartTransaction tr(session, name); mResult = exec(tr); } catch (const soci::soci_error &e) { lWarning() << "Catched exception in MainDb::" << name << "(" << e.what() << ")."; soci::soci_error::error_category category = e.get_error_category(); if ( (category == soci::soci_error::connection_error || category == soci::soci_error::unknown) && - info.mainDb->forceReconnect() + mainDb->forceReconnect() ) { try { - SmartTransaction tr(info.mainDb->getPrivate()->dbSession.getBackendSession(), name); + SmartTransaction tr(session, name); mResult = exec(tr); } catch (const std::exception &e) { lError() << "Unable to execute query after reconnect in MainDb::" << name << "(" << e.what() << ")."; diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index a86b8eccd..5e7aa74c2 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -1386,10 +1386,10 @@ void MainDb::init () { soci::session *session = d->dbSession.getBackendSession(); using namespace placeholders; - auto primaryKeyRefStr = bind(&DbSession::primaryKeyRefStr, d->dbSession, _1); - auto primaryKeyStr = bind(&DbSession::primaryKeyStr, d->dbSession, _1); - auto timestampType = bind(&DbSession::timestampType, d->dbSession); - auto varcharPrimaryKeyStr = bind(&DbSession::varcharPrimaryKeyStr, d->dbSession, _1); + auto primaryKeyRefStr = bind(&DbSession::primaryKeyRefStr, &d->dbSession, _1); + auto primaryKeyStr = bind(&DbSession::primaryKeyStr, &d->dbSession, _1); + auto timestampType = bind(&DbSession::timestampType, &d->dbSession); + auto varcharPrimaryKeyStr = bind(&DbSession::varcharPrimaryKeyStr, &d->dbSession, _1); auto createTableSanitizer = [](const char *statement) { // TODO. diff --git a/src/db/session/db-session-p.h b/src/db/session/db-session-p.h deleted file mode 100644 index aae12db9c..000000000 --- a/src/db/session/db-session-p.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * db-session-p.h - * Copyright (C) 2010-2018 Belledonne Communications SARL - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _L_DB_SESSION_P_H_ -#define _L_DB_SESSION_P_H_ - -#include "db-session.h" -#include "object/clonable-object-p.h" - -// ============================================================================= - -LINPHONE_BEGIN_NAMESPACE - -class DbSessionPrivate : public ClonableObjectPrivate { -private: - enum class Backend { - None, - Mysql, - Sqlite3 - } backend = Backend::None; - - #ifdef SOCI_ENABLED - std::unique_ptr backendSession; - #endif // ifdef SOCI_ENABLED - - L_DECLARE_PUBLIC(DbSession); -}; - -LINPHONE_END_NAMESPACE - -#endif // ifndef _L_DB_SESSION_P_H_ diff --git a/src/db/session/db-session.cpp b/src/db/session/db-session.cpp index 7e4f141d1..b38550e35 100644 --- a/src/db/session/db-session.cpp +++ b/src/db/session/db-session.cpp @@ -19,7 +19,7 @@ #include "linphone/utils/utils.h" -#include "db-session-p.h" +#include "db-session.h" #include "logger/logger.h" // ============================================================================= @@ -28,7 +28,20 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -DbSession::DbSession () : ClonableObject(*new DbSessionPrivate) {} +class DbSessionPrivate { +public: + enum class Backend { + None, + Mysql, + Sqlite3 + } backend = Backend::None; + + #ifdef SOCI_ENABLED + std::unique_ptr backendSession; + #endif // ifdef SOCI_ENABLED +}; + +DbSession::DbSession () : mPrivate(new DbSessionPrivate) {} DbSession::DbSession (const string &uri) : DbSession() { #ifdef SOCI_ENABLED @@ -44,13 +57,24 @@ DbSession::DbSession (const string &uri) : DbSession() { #endif // ifdef SOCI_ENABLED } +DbSession::DbSession (DbSession &&other) : mPrivate(other.mPrivate) { + other.mPrivate = nullptr; +} + +DbSession::~DbSession () { + delete mPrivate; +} + +DbSession &DbSession::operator= (DbSession &&other) { + std::swap(mPrivate, other.mPrivate); + return *this; +} + DbSession::operator bool () const { L_D(); return d->backend != DbSessionPrivate::Backend::None; } -L_USE_DEFAULT_CLONABLE_OBJECT_SHARED_IMPL(DbSession); - soci::session *DbSession::getBackendSession () const { #ifdef SOCI_ENABLED L_D(); diff --git a/src/db/session/db-session.h b/src/db/session/db-session.h index a94fa7abb..6d4bf7b1c 100644 --- a/src/db/session/db-session.h +++ b/src/db/session/db-session.h @@ -39,15 +39,16 @@ LINPHONE_BEGIN_NAMESPACE class DbSessionPrivate; -class DbSession : public ClonableObject { +class DbSession { friend class DbSessionProvider; public: DbSession (); explicit DbSession (const std::string &uri); - DbSession (const DbSession &other); + DbSession (DbSession &&other); + ~DbSession (); - DbSession &operator= (const DbSession &other); + DbSession &operator= (DbSession &&other); operator bool () const; @@ -70,6 +71,8 @@ public: long long resolveId (const soci::row &row, int col) const; private: + DbSessionPrivate *mPrivate; + L_DECLARE_PRIVATE(DbSession); };