mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-07 14:18:25 +00:00
feat(MainDb): forward transaction in with lambda
This commit is contained in:
parent
c0e48a8339
commit
89a62c4428
5 changed files with 43 additions and 95 deletions
|
|
@ -294,7 +294,6 @@ if (SOCI_FOUND)
|
|||
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
||||
db/internal/db-exception-handler.h
|
||||
db/internal/smart-transaction.h
|
||||
db/internal/statements.h
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,18 +22,40 @@
|
|||
|
||||
#include <soci/soci.h>
|
||||
|
||||
#include "db/main-db.h"
|
||||
#include "db/main-db-p.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
#define L_DB_EXCEPTION_HANDLER_C(CONTEXT) \
|
||||
LinphonePrivate::DbExceptionHandlerInfo().set(__func__, CONTEXT) * [&]()
|
||||
LinphonePrivate::DbExceptionHandlerInfo().set(__func__, CONTEXT) * [&](SmartTransaction &tr)
|
||||
|
||||
#define L_DB_EXCEPTION_HANDLER L_DB_EXCEPTION_HANDLER_C(this)
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class SmartTransaction {
|
||||
public:
|
||||
SmartTransaction (soci::session *session, const char *name) : mTransaction(*session), mName(name) {
|
||||
lInfo() << "Start transaction " << this << " in `" << mName << "`.";
|
||||
}
|
||||
|
||||
~SmartTransaction () {
|
||||
lInfo() << "Rollback transaction " << this << " in `" << mName << "`.";
|
||||
}
|
||||
|
||||
void commit () {
|
||||
lInfo() << "Commit transaction " << this << " in `" << mName << "`.";
|
||||
mTransaction.commit();
|
||||
}
|
||||
|
||||
private:
|
||||
soci::transaction mTransaction;
|
||||
const char *mName;
|
||||
|
||||
L_DISABLE_COPY(SmartTransaction);
|
||||
};
|
||||
|
||||
struct DbExceptionHandlerInfo {
|
||||
DbExceptionHandlerInfo &set (const char *_name, const MainDb *_mainDb) {
|
||||
name = _name;
|
||||
|
|
@ -47,7 +69,9 @@ struct DbExceptionHandlerInfo {
|
|||
|
||||
template<typename Function>
|
||||
class DbExceptionHandler {
|
||||
using InternalReturnType = typename std::remove_reference<decltype(std::declval<Function>()())>::type;
|
||||
using InternalReturnType = typename std::remove_reference<
|
||||
decltype(std::declval<Function>()(std::declval<SmartTransaction &>()))
|
||||
>::type;
|
||||
|
||||
public:
|
||||
using ReturnType = typename std::conditional<
|
||||
|
|
@ -57,26 +81,29 @@ public:
|
|||
>::type;
|
||||
|
||||
DbExceptionHandler (DbExceptionHandlerInfo &info, Function function) : mFunction(std::move(function)) {
|
||||
const char *name = info.name;
|
||||
try {
|
||||
mResult= exec<InternalReturnType>();
|
||||
SmartTransaction tr(info.mainDb->getPrivate()->dbSession.getBackendSession(), name);
|
||||
mResult = exec<InternalReturnType>(tr);
|
||||
} catch (const soci::soci_error &e) {
|
||||
lWarning() << "Catched exception in MainDb::" << info.name << "(" << e.what() << ").";
|
||||
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()
|
||||
) {
|
||||
try {
|
||||
mResult = exec<InternalReturnType>();
|
||||
SmartTransaction tr(info.mainDb->getPrivate()->dbSession.getBackendSession(), name);
|
||||
mResult = exec<InternalReturnType>(tr);
|
||||
} catch (const std::exception &e) {
|
||||
lError() << "Unable to execute query after reconnect in MainDb::" << info.name << "(" << e.what() << ").";
|
||||
lError() << "Unable to execute query after reconnect in MainDb::" << name << "(" << e.what() << ").";
|
||||
}
|
||||
return;
|
||||
}
|
||||
lError() << "Unhandled [" << getErrorCategoryAsString(category) << "] exception in MainDb::" <<
|
||||
info.name << ": `" << e.what() << "`.";
|
||||
name << ": `" << e.what() << "`.";
|
||||
} catch (const std::exception &e) {
|
||||
lError() << "Unhandled generic exception in MainDb::" << info.name << ": `" << e.what() << "`.";
|
||||
lError() << "Unhandled generic exception in MainDb::" << name << ": `" << e.what() << "`.";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,15 +116,15 @@ public:
|
|||
private:
|
||||
// Exec function with no return type.
|
||||
template<typename T>
|
||||
typename std::enable_if<std::is_same<T, void>::value, bool>::type exec () const {
|
||||
mFunction();
|
||||
typename std::enable_if<std::is_same<T, void>::value, bool>::type exec (SmartTransaction &tr) const {
|
||||
mFunction(tr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Exec function with return type.
|
||||
template<typename T>
|
||||
typename std::enable_if<!std::is_same<T, void>::value, T>::type exec () const {
|
||||
return mFunction();
|
||||
typename std::enable_if<!std::is_same<T, void>::value, T>::type exec (SmartTransaction &tr) const {
|
||||
return mFunction(tr);
|
||||
}
|
||||
|
||||
static const char *getErrorCategoryAsString (soci::soci_error::error_category category) {
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* smart-transaction.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_SMART_TRANSACTION_H_
|
||||
#define _L_SMART_TRANSACTION_H_
|
||||
|
||||
#include <soci/soci.h>
|
||||
|
||||
#include "logger/logger.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class SmartTransaction {
|
||||
public:
|
||||
SmartTransaction (soci::session *session, const char *name) : mTransaction(*session), mName(name) {
|
||||
lInfo() << "Start transaction " << this << " in `" << mName << "`.";
|
||||
}
|
||||
|
||||
~SmartTransaction () {
|
||||
lInfo() << "Rollback transaction " << this << " in `" << mName << "`.";
|
||||
}
|
||||
|
||||
void commit () {
|
||||
lInfo() << "Commit transaction " << this << " in `" << mName << "`.";
|
||||
mTransaction.commit();
|
||||
}
|
||||
|
||||
private:
|
||||
soci::transaction mTransaction;
|
||||
const char *mName;
|
||||
|
||||
L_DISABLE_COPY(SmartTransaction);
|
||||
};
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_SMART_TRANSACTION_H_
|
||||
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
#ifdef SOCI_ENABLED
|
||||
#include "internal/db-exception-handler.h"
|
||||
#include "internal/smart-transaction.h"
|
||||
#include "internal/statements.h"
|
||||
#endif // ifdef SOCI_ENABLED
|
||||
|
||||
|
|
@ -1785,8 +1784,6 @@ bool MainDb::addEvent (const shared_ptr<EventLog> &eventLog) {
|
|||
|
||||
long long storageId = 0;
|
||||
|
||||
SmartTransaction tr(d->dbSession.getBackendSession(), __func__);
|
||||
|
||||
EventLog::Type type = eventLog->getType();
|
||||
switch (type) {
|
||||
case EventLog::Type::None:
|
||||
|
|
@ -1847,8 +1844,6 @@ bool MainDb::updateEvent (const shared_ptr<EventLog> &eventLog) {
|
|||
return L_DB_EXCEPTION_HANDLER {
|
||||
L_D();
|
||||
|
||||
SmartTransaction tr(d->dbSession.getBackendSession(), __func__);
|
||||
|
||||
switch (eventLog->getType()) {
|
||||
case EventLog::Type::None:
|
||||
return false;
|
||||
|
|
@ -1950,7 +1945,6 @@ shared_ptr<EventLog> MainDb::getEventFromKey (const MainDbKey &dbKey) {
|
|||
|
||||
return L_DB_EXCEPTION_HANDLER_C(q.get()) {
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
string peerSipAddress;
|
||||
string localSipAddress;
|
||||
|
|
@ -1989,7 +1983,6 @@ list<shared_ptr<EventLog>> MainDb::getConferenceNotifiedEvents (
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
|
||||
|
|
@ -2032,7 +2025,6 @@ int MainDb::getChatMessageCount (const ChatRoomId &chatRoomId) const {
|
|||
" SELECT event_id FROM conference_event WHERE chat_room_id = :chatRoomId"
|
||||
")";
|
||||
|
||||
SmartTransaction tr(session, __func__);
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
*session << query, soci::use(dbChatRoomId), soci::into(count);
|
||||
}
|
||||
|
|
@ -2066,7 +2058,6 @@ int MainDb::getUnreadChatMessageCount (const ChatRoomId &chatRoomId) const {
|
|||
if (!chatRoomId.isValid())
|
||||
*session << query, soci::into(count);
|
||||
else {
|
||||
SmartTransaction tr(session, __func__);
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
*session << query, soci::use(dbChatRoomId), soci::into(count);
|
||||
}
|
||||
|
|
@ -2101,7 +2092,6 @@ void MainDb::markChatMessagesAsRead (const ChatRoomId &chatRoomId) const {
|
|||
if (!chatRoomId.isValid())
|
||||
*session << query;
|
||||
else {
|
||||
SmartTransaction tr(session, __func__);
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
*session << query, soci::use(dbChatRoomId);
|
||||
tr.commit();
|
||||
|
|
@ -2130,7 +2120,6 @@ list<shared_ptr<ChatMessage>> MainDb::getUnreadChatMessages (const ChatRoomId &c
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
long long dbChatRoomId;
|
||||
if (chatRoomId.isValid())
|
||||
|
|
@ -2258,7 +2247,6 @@ list<shared_ptr<ChatMessage>> MainDb::findChatMessages (
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
list<shared_ptr<ChatMessage>> chatMessages;
|
||||
|
||||
|
|
@ -2331,7 +2319,6 @@ list<shared_ptr<EventLog>> MainDb::getHistoryRange (
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
shared_ptr<Core> core = getCore();
|
||||
shared_ptr<AbstractChatRoom> chatRoom = core->findChatRoom(chatRoomId);
|
||||
|
|
@ -2396,7 +2383,6 @@ int MainDb::getHistorySize (const ChatRoomId &chatRoomId, FilterMask mask) const
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
int count;
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
|
|
@ -2411,7 +2397,6 @@ void MainDb::loadChatMessageContents (const shared_ptr<ChatMessage> &chatMessage
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
bool hasFileTransferContent = false;
|
||||
|
||||
|
|
@ -2487,7 +2472,6 @@ void MainDb::cleanHistory (const ChatRoomId &chatRoomId, FilterMask mask) {
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
|
||||
|
|
@ -2516,7 +2500,6 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
|
|||
shared_ptr<Core> core = getCore();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
soci::rowset<soci::row> rows = (session->prepare << query);
|
||||
for (const auto &row : rows) {
|
||||
|
|
@ -2645,7 +2628,6 @@ void MainDb::insertChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom) {
|
|||
L_DB_EXCEPTION_HANDLER {
|
||||
L_D();
|
||||
|
||||
SmartTransaction tr(d->dbSession.getBackendSession(), __func__);
|
||||
d->insertChatRoom(chatRoom);
|
||||
tr.commit();
|
||||
};
|
||||
|
|
@ -2660,7 +2642,6 @@ void MainDb::deleteChatRoom (const ChatRoomId &chatRoomId) {
|
|||
L_DB_EXCEPTION_HANDLER {
|
||||
L_D();
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
|
||||
|
|
@ -2688,7 +2669,6 @@ void MainDb::migrateBasicToClientGroupChatRoom (
|
|||
// TODO: Update events and chat messages. (Or wait signals.)
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(basicChatRoom->getChatRoomId());
|
||||
|
||||
|
|
@ -2739,7 +2719,6 @@ IdentityAddress MainDb::findMissingOneToOneConferenceChatRoomParticipantAddress
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
string missingParticipantAddress;
|
||||
string participantASipAddress;
|
||||
|
|
@ -2773,7 +2752,6 @@ IdentityAddress MainDb::findOneToOneConferenceChatRoomAddress (
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
const long long &participantASipAddressId = d->selectSipAddressId(participantA.asString());
|
||||
const long long &participantBSipAddressId = d->selectSipAddressId(participantB.asString());
|
||||
|
|
@ -2799,8 +2777,6 @@ void MainDb::insertOneToOneConferenceChatRoom (const shared_ptr<AbstractChatRoom
|
|||
L_DB_EXCEPTION_HANDLER {
|
||||
L_D();
|
||||
|
||||
SmartTransaction tr(d->dbSession.getBackendSession(), __func__);
|
||||
|
||||
const list<shared_ptr<Participant>> &participants = chatRoom->getParticipants();
|
||||
const long long &participantASipAddressId = d->selectSipAddressId(participants.front()->getAddress().asString());
|
||||
const long long &participantBSipAddressId = d->selectSipAddressId(participants.back()->getAddress().asString());
|
||||
|
|
@ -2826,7 +2802,6 @@ void MainDb::enableChatRoomMigration (const ChatRoomId &chatRoomId, bool enable)
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
|
||||
|
|
@ -2852,7 +2827,6 @@ void MainDb::updateChatRoomParticipantDevice (
|
|||
L_D();
|
||||
|
||||
soci::session *session = d->dbSession.getBackendSession();
|
||||
SmartTransaction tr(session, __func__);
|
||||
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoom->getChatRoomId());
|
||||
const long long &participantSipAddressId = d->selectSipAddressId(device->getParticipant()->getAddress().asString());
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ class MainDbPrivate;
|
|||
class ParticipantDevice;
|
||||
|
||||
class MainDb : public AbstractDb, public CoreAccessor {
|
||||
template<typename Function>
|
||||
friend class DbExceptionHandler;
|
||||
|
||||
friend class MainDbChatMessageKey;
|
||||
friend class MainDbEventKey;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue