diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d6dd47a28..f68cc58d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -293,7 +293,8 @@ if (SOCI_FOUND) add_definitions(-DSOCI_ENABLED) list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES - db/internal/safe-transaction.h + db/internal/db-exception-handler.h + db/internal/smart-transaction.h db/internal/statements.h ) diff --git a/src/db/internal/safe-transaction.h b/src/db/internal/db-exception-handler.h similarity index 79% rename from src/db/internal/safe-transaction.h rename to src/db/internal/db-exception-handler.h index 865867110..5e8cdd646 100644 --- a/src/db/internal/safe-transaction.h +++ b/src/db/internal/db-exception-handler.h @@ -1,5 +1,5 @@ /* - * safe-transaction.h + * db-exception-handler.h * Copyright (C) 2010-2018 Belledonne Communications SARL * * This program is free software; you can redistribute it and/or @@ -17,8 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef _L_SAFE_TRANSACTION_H_ -#define _L_SAFE_TRANSACTION_H_ +#ifndef _L_DB_EXCEPTION_HANDLER_H_ +#define _L_DB_EXCEPTION_HANDLER_H_ #include @@ -27,15 +27,15 @@ // ============================================================================= -#define L_SAFE_TRANSACTION_C(CONTEXT) \ - LinphonePrivate::SafeTransactionInfo().set(__func__, CONTEXT) * [&]() +#define L_DB_EXCEPTION_HANDLER_C(CONTEXT) \ + LinphonePrivate::DbExceptionHandlerInfo().set(__func__, CONTEXT) * [&]() -#define L_SAFE_TRANSACTION L_SAFE_TRANSACTION_C(this) +#define L_DB_EXCEPTION_HANDLER L_DB_EXCEPTION_HANDLER_C(this) LINPHONE_BEGIN_NAMESPACE -struct SafeTransactionInfo { - SafeTransactionInfo &set (const char *_name, const MainDb *_mainDb) { +struct DbExceptionHandlerInfo { + DbExceptionHandlerInfo &set (const char *_name, const MainDb *_mainDb) { name = _name; mainDb = const_cast(_mainDb); return *this; @@ -46,7 +46,7 @@ struct SafeTransactionInfo { }; template -class SafeTransaction { +class DbExceptionHandler { using InternalReturnType = typename std::remove_reference()())>::type; public: @@ -56,7 +56,7 @@ public: InternalReturnType >::type; - SafeTransaction (SafeTransactionInfo &info, Function function) : mFunction(std::move(function)) { + DbExceptionHandler (DbExceptionHandlerInfo &info, Function function) : mFunction(std::move(function)) { try { mResult= exec(); } catch (const soci::soci_error &e) { @@ -80,7 +80,7 @@ public: } } - SafeTransaction (SafeTransaction &&safeTransaction) : mFunction(std::move(safeTransaction.mFunction)) {} + DbExceptionHandler (DbExceptionHandler &&dbExceptionHandler) : mFunction(std::move(dbExceptionHandler.mFunction)) {} operator ReturnType () const { return mResult; @@ -128,14 +128,14 @@ private: Function mFunction; ReturnType mResult{}; - L_DISABLE_COPY(SafeTransaction); + L_DISABLE_COPY(DbExceptionHandler); }; template -typename SafeTransaction::ReturnType operator* (SafeTransactionInfo &info, Function &&function) { - return SafeTransaction(info, std::forward(function)); +typename DbExceptionHandler::ReturnType operator* (DbExceptionHandlerInfo &info, Function &&function) { + return DbExceptionHandler(info, std::forward(function)); } LINPHONE_END_NAMESPACE -#endif // ifndef _L_SAFE_TRANSACTION_H_ +#endif // ifndef _L_DB_EXCEPTION_HANDLER_H_ diff --git a/src/db/internal/smart-transaction.h b/src/db/internal/smart-transaction.h new file mode 100644 index 000000000..c76eadbd3 --- /dev/null +++ b/src/db/internal/smart-transaction.h @@ -0,0 +1,55 @@ +/* + * 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 + +#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_ diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 584186215..f0f5079a8 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -38,7 +38,8 @@ #include "main-db-p.h" #ifdef SOCI_ENABLED - #include "internal/safe-transaction.h" + #include "internal/db-exception-handler.h" + #include "internal/smart-transaction.h" #include "internal/statements.h" #endif // ifdef SOCI_ENABLED @@ -222,6 +223,14 @@ static constexpr string &blobToString (string &in) { return in; } +// ----------------------------------------------------------------------------- +// Transaction. +// ----------------------------------------------------------------------------- + +class Transaction { + +}; + // ----------------------------------------------------------------------------- // Statements and helpers. // ----------------------------------------------------------------------------- @@ -1191,7 +1200,7 @@ static T getValueFromRow (const soci::row &row, int index, bool &isNull) { void MainDbPrivate::importLegacyFriends (DbSession &inDbSession) { soci::session *inSession = inDbSession.getBackendSession(); - soci::transaction tr(*dbSession.getBackendSession()); + SmartTransaction tr(dbSession.getBackendSession(), __func__); if (getModuleVersion("legacy-friends-import") >= makeVersion(1, 0, 0)) return; @@ -1272,7 +1281,7 @@ void MainDbPrivate::importLegacyFriends (DbSession &inDbSession) { void MainDbPrivate::importLegacyHistory (DbSession &inDbSession) { soci::session *inSession = inDbSession.getBackendSession(); - soci::transaction tr(*dbSession.getBackendSession()); + SmartTransaction tr(dbSession.getBackendSession(), __func__); unsigned int version = getModuleVersion("legacy-history-import"); if (version >= makeVersion(1, 0, 0)) @@ -1771,12 +1780,12 @@ bool MainDb::addEvent (const shared_ptr &eventLog) { return false; } - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); long long storageId = 0; - soci::transaction tr(*d->dbSession.getBackendSession()); + SmartTransaction tr(d->dbSession.getBackendSession(), __func__); EventLog::Type type = eventLog->getType(); switch (type) { @@ -1835,10 +1844,10 @@ bool MainDb::updateEvent (const shared_ptr &eventLog) { return false; } - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); - soci::transaction tr(*d->dbSession.getBackendSession()); + SmartTransaction tr(d->dbSession.getBackendSession(), __func__); switch (eventLog->getType()) { case EventLog::Type::None: @@ -1881,7 +1890,7 @@ bool MainDb::deleteEvent (const shared_ptr &eventLog) { MainDb &mainDb = *core->getPrivate()->mainDb.get(); - return L_SAFE_TRANSACTION_C(&mainDb) { + return L_DB_EXCEPTION_HANDLER_C(&mainDb) { soci::session *session = mainDb.getPrivate()->dbSession.getBackendSession(); *session << "DELETE FROM event WHERE id = :id", soci::use(dEventKey->storageId); @@ -1904,7 +1913,7 @@ int MainDb::getEventCount (FilterMask mask) const { "Get events count with mask=" + Utils::toString(mask) + "." ); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); int count; @@ -1939,9 +1948,9 @@ shared_ptr MainDb::getEventFromKey (const MainDbKey &dbKey) { " AND chat_room.peer_sip_address_id = peer_sip_address.id" " AND chat_room.local_sip_address_id = local_sip_address.id"; - return L_SAFE_TRANSACTION_C(q.get()) { + return L_DB_EXCEPTION_HANDLER_C(q.get()) { soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); string peerSipAddress; string localSipAddress; @@ -1976,11 +1985,11 @@ list> MainDb::getConferenceNotifiedEvents ( ", lastNotifyId=" + Utils::toString(lastNotifyId) + ")." ); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); @@ -2008,7 +2017,7 @@ int MainDb::getChatMessageCount (const ChatRoomId &chatRoomId) const { ", local=" + chatRoomId.getLocalAddress().asString() + ")." ); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); int count; @@ -2023,7 +2032,7 @@ int MainDb::getChatMessageCount (const ChatRoomId &chatRoomId) const { " SELECT event_id FROM conference_event WHERE chat_room_id = :chatRoomId" ")"; - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); *session << query, soci::use(dbChatRoomId), soci::into(count); } @@ -2047,7 +2056,7 @@ int MainDb::getUnreadChatMessageCount (const ChatRoomId &chatRoomId) const { ", local=" + chatRoomId.getLocalAddress().asString() + ")." ); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); int count = 0; @@ -2057,7 +2066,7 @@ int MainDb::getUnreadChatMessageCount (const ChatRoomId &chatRoomId) const { if (!chatRoomId.isValid()) *session << query, soci::into(count); else { - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); *session << query, soci::use(dbChatRoomId), soci::into(count); } @@ -2084,7 +2093,7 @@ void MainDb::markChatMessagesAsRead (const ChatRoomId &chatRoomId) const { ", local=" + chatRoomId.getLocalAddress().asString() + ")." ); - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); @@ -2092,7 +2101,7 @@ void MainDb::markChatMessagesAsRead (const ChatRoomId &chatRoomId) const { if (!chatRoomId.isValid()) *session << query; else { - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); *session << query, soci::use(dbChatRoomId); tr.commit(); @@ -2117,11 +2126,11 @@ list> MainDb::getUnreadChatMessages (const ChatRoomId &c ", local=" + chatRoomId.getLocalAddress().asString() + ")." ); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); long long dbChatRoomId; if (chatRoomId.isValid()) @@ -2153,7 +2162,7 @@ list> MainDb::getUnreadChatMessages (const ChatRoomId &c } list MainDb::getChatMessageParticipantStates (const shared_ptr &eventLog) const { - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); @@ -2180,7 +2189,7 @@ ChatMessage::State MainDb::getChatMessageParticipantState ( const shared_ptr &eventLog, const IdentityAddress &participantAddress ) const { - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); @@ -2204,7 +2213,7 @@ void MainDb::setChatMessageParticipantState ( const IdentityAddress &participantAddress, ChatMessage::State state ) { - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); @@ -2245,11 +2254,11 @@ list> MainDb::findChatMessages ( ", local=" + chatRoomId.getLocalAddress().asString() + ")." ); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); list> chatMessages; @@ -2318,11 +2327,11 @@ list> MainDb::getHistoryRange ( ", begin=" + Utils::toString(begin) + ", end=" + Utils::toString(end) + ")." ); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); shared_ptr core = getCore(); shared_ptr chatRoom = core->findChatRoom(chatRoomId); @@ -2383,11 +2392,11 @@ int MainDb::getHistorySize (const ChatRoomId &chatRoomId, FilterMask mask) const ConferenceCallFilter, ConferenceChatMessageFilter, ConferenceInfoFilter, ConferenceInfoNoDeviceFilter }, mask, "AND"); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); int count; const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); @@ -2398,11 +2407,11 @@ int MainDb::getHistorySize (const ChatRoomId &chatRoomId, FilterMask mask) const } void MainDb::loadChatMessageContents (const shared_ptr &chatMessage) { - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); bool hasFileTransferContent = false; @@ -2474,11 +2483,11 @@ void MainDb::cleanHistory (const ChatRoomId &chatRoomId, FilterMask mask) { ", mask=" + Utils::toString(mask) + ")." ); - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); @@ -2500,14 +2509,14 @@ list> MainDb::getChatRooms () const { DurationLogger durationLogger("Get chat rooms."); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); list> chatRooms; shared_ptr core = getCore(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); soci::rowset rows = (session->prepare << query); for (const auto &row : rows) { @@ -2633,10 +2642,10 @@ void MainDb::insertChatRoom (const shared_ptr &chatRoom) { ", local=" + chatRoomId.getLocalAddress().asString() + ")." ); - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); - soci::transaction tr(*d->dbSession.getBackendSession()); + SmartTransaction tr(d->dbSession.getBackendSession(), __func__); d->insertChatRoom(chatRoom); tr.commit(); }; @@ -2648,10 +2657,10 @@ void MainDb::deleteChatRoom (const ChatRoomId &chatRoomId) { ", local=" + chatRoomId.getLocalAddress().asString() + "`)." ); - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); @@ -2673,13 +2682,13 @@ void MainDb::migrateBasicToClientGroupChatRoom ( L_ASSERT(basicChatRoom->getCapabilities().isSet(ChatRoom::Capabilities::Basic)); L_ASSERT(clientGroupChatRoom->getCapabilities().isSet(ChatRoom::Capabilities::Conference)); - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); // TODO: Update events and chat messages. (Or wait signals.) soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(basicChatRoom->getChatRoomId()); @@ -2726,11 +2735,11 @@ IdentityAddress MainDb::findMissingOneToOneConferenceChatRoomParticipantAddress L_ASSERT(chatRoom->getCapabilities() & ChatRoom::Capabilities::OneToOne); L_ASSERT(chatRoom->getParticipantCount() == 1); - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); string missingParticipantAddress; string participantASipAddress; @@ -2760,11 +2769,11 @@ IdentityAddress MainDb::findOneToOneConferenceChatRoomAddress ( const IdentityAddress &participantA, const IdentityAddress &participantB ) const { - return L_SAFE_TRANSACTION { + return L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &participantASipAddressId = d->selectSipAddressId(participantA.asString()); const long long &participantBSipAddressId = d->selectSipAddressId(participantB.asString()); @@ -2787,10 +2796,10 @@ void MainDb::insertOneToOneConferenceChatRoom (const shared_ptrgetCore()->getCCore())); L_ASSERT(chatRoom->getCapabilities() & ChatRoom::Capabilities::OneToOne); - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); - soci::transaction tr(*d->dbSession.getBackendSession()); + SmartTransaction tr(d->dbSession.getBackendSession(), __func__); const list> &participants = chatRoom->getParticipants(); const long long &participantASipAddressId = d->selectSipAddressId(participants.front()->getAddress().asString()); @@ -2813,11 +2822,11 @@ void MainDb::insertOneToOneConferenceChatRoom (const shared_ptrdbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); @@ -2839,11 +2848,11 @@ void MainDb::updateChatRoomParticipantDevice ( const shared_ptr &chatRoom, const shared_ptr &device ) { - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { L_D(); soci::session *session = d->dbSession.getBackendSession(); - soci::transaction tr(*session); + SmartTransaction tr(session, __func__); const long long &dbChatRoomId = d->selectChatRoomId(chatRoom->getChatRoomId()); const long long &participantSipAddressId = d->selectSipAddressId(device->getParticipant()->getAddress().asString()); @@ -2872,13 +2881,13 @@ bool MainDb::import (Backend, const string ¶meters) { return false; } - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { // TODO: Remove condition after cpp migration in friends/friends list. if (false) d->importLegacyFriends(inDbSession); }; - L_SAFE_TRANSACTION { + L_DB_EXCEPTION_HANDLER { d->importLegacyHistory(inDbSession); };