Commit 3f16a719 authored by Ronan's avatar Ronan

feat(MainDb):

- Allow only move constructor/assignment operator on DbSession
- Check thread id of AbstractDb in transaction
- Fix a copy session in MainDb::init
parent 9ea10688
......@@ -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
......
......@@ -20,6 +20,8 @@
#ifndef _L_ABSTRACT_DB_P_H_
#define _L_ABSTRACT_DB_P_H_
#include <thread>
#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;
......
......@@ -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<InternalReturnType>(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<InternalReturnType>(tr);
} catch (const std::exception &e) {
lError() << "Unable to execute query after reconnect in MainDb::" << name << "(" << e.what() << ").";
......
......@@ -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.
......
/*
* 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<soci::session> backendSession;
#endif // ifdef SOCI_ENABLED
L_DECLARE_PUBLIC(DbSession);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _L_DB_SESSION_P_H_
......@@ -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<soci::session> 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();
......
......@@ -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);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment