From 335f19b20b160e35cb305d26d4c6614353c1c448 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Wed, 3 Jan 2018 14:12:22 +0100 Subject: [PATCH] feat(MainDb): legacy friends import --- coreapi/friend.c | 75 +------ coreapi/linphonecore.c | 7 +- include/linphone/core.h | 7 - src/db/main-db-p.h | 7 + src/db/main-db.cpp | 456 +++++++++++++++++++++++++++------------- src/db/main-db.h | 2 +- 6 files changed, 332 insertions(+), 222 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 9f39717c5..f5d915a4a 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -41,6 +41,8 @@ #endif #include "c-wrapper/c-wrapper.h" +#include "core/core-p.h" +#include "db/main-db.h" // TODO: From coreapi. Remove me later. #include "private.h" @@ -529,11 +531,11 @@ void linphone_friend_invalidate_subscription(LinphoneFriend *lf){ } static void close_presence_notification(SalPresenceOp *op) { - op->notify_presence_close(); + op->notify_presence_close(); } static void release_sal_op(SalOp *op) { - op->release(); + op->release(); } static void linphone_friend_close_incoming_subscriptions(LinphoneFriend *lf) { @@ -1722,6 +1724,10 @@ bctbx_list_t* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) { #endif void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path) { + if (!linphone_core_conference_server_enabled(lc)) + L_GET_PRIVATE(lc->cppPtr)->mainDb->import(LinphonePrivate::MainDb::Sqlite3, path); + + // TODO: Remove me later. if (lc->friends_db_file){ ms_free(lc->friends_db_file); lc->friends_db_file = NULL; @@ -1729,8 +1735,6 @@ void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path) if (path) { lc->friends_db_file = ms_strdup(path); linphone_core_friends_storage_init(lc); - - linphone_core_migrate_friends_from_rc_to_db(lc); } } @@ -1738,69 +1742,6 @@ const char* linphone_core_get_friends_database_path(LinphoneCore *lc) { return lc->friends_db_file; } -void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) { - LpConfig *lpc = NULL; - LinphoneFriend *lf = NULL; - LinphoneFriendList *lfl = linphone_core_get_default_friend_list(lc); - int i; -#ifndef SQLITE_STORAGE_ENABLED - ms_warning("linphone has been compiled without sqlite, can't migrate friends"); - return; -#endif - if (!lc) { - return; - } - - lpc = linphone_core_get_config(lc); - if (!lpc) { - ms_warning("this core has been started without a rc file, nothing to migrate"); - return; - } - if (lp_config_get_int(lpc, "misc", "friends_migration_done", 0) == 1) { - ms_warning("the friends migration has already been done, skipping..."); - return; - } - - if (bctbx_list_size(linphone_friend_list_get_friends(lfl)) > 0 && lfl->storage_id == 0) { - linphone_core_remove_friend_list(lc, lfl); - lfl = linphone_core_create_friend_list(lc); - linphone_core_add_friend_list(lc, lfl); - linphone_friend_list_unref(lfl); - } - - for (i = 0; (lf = linphone_friend_new_from_config_file(lc, i)) != NULL; i++) { - char friend_section[32]; - - const LinphoneAddress *addr = linphone_friend_get_address(lf); - if (addr) { - char *address = NULL; - const char *displayName = linphone_address_get_display_name(addr); - if (!displayName) displayName = linphone_address_get_username(addr); - - address = linphone_address_as_string(addr); - if (linphone_core_vcard_supported()) { - if (!linphone_friend_create_vcard(lf, displayName)) { - ms_warning("Couldn't create vCard for friend %s", address); - } else { - linphone_vcard_add_sip_address(linphone_friend_get_vcard(lf), address); - linphone_address_unref(lf->uri); - lf->uri = NULL; - } - } - ms_free(address); - - linphone_friend_list_add_friend(lfl, lf); - linphone_friend_unref(lf); - - snprintf(friend_section, sizeof(friend_section), "friend_%i", i); - lp_config_clean_section(lpc, friend_section); - } - } - - ms_debug("friends migration successful: %i friends migrated", i); - lp_config_set_int(lpc, "misc", "friends_migration_done", 1); -} - LinphoneSubscriptionState linphone_friend_get_subscription_state(const LinphoneFriend *lf) { return lf->out_sub_state; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 29eb6eda4..4a9845196 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -6692,11 +6692,8 @@ int linphone_core_get_video_dscp(const LinphoneCore *lc){ } void linphone_core_set_chat_database_path (LinphoneCore *lc, const char *path) { - if ( - linphone_core_conference_server_enabled(lc) || - !L_GET_PRIVATE(lc->cppPtr)->mainDb->import(LinphonePrivate::MainDb::Sqlite3, path) - ) - lError() << "Do not use `linphone_core_set_chat_database_path`. Not necessary."; + if (!linphone_core_conference_server_enabled(lc)) + L_GET_PRIVATE(lc->cppPtr)->mainDb->import(LinphonePrivate::MainDb::Sqlite3, path); } const char *linphone_core_get_chat_database_path (const LinphoneCore *) { diff --git a/include/linphone/core.h b/include/linphone/core.h index 46652ebae..3b4018c27 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -5287,13 +5287,6 @@ LINPHONE_PUBLIC void linphone_core_set_friends_database_path(LinphoneCore *lc, c **/ LINPHONE_PUBLIC const char* linphone_core_get_friends_database_path(LinphoneCore *lc); -/** - * Migrates the friends from the linphonerc to the database if not done yet - * @ingroup initializing - * @param lc the linphone core -**/ -LINPHONE_PUBLIC void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc); - /** * Create a new empty LinphoneFriendList object. * @param[in] lc LinphoneCore object. diff --git a/src/db/main-db-p.h b/src/db/main-db-p.h index 16d318617..3f772f7e9 100644 --- a/src/db/main-db-p.h +++ b/src/db/main-db-p.h @@ -154,6 +154,13 @@ private: unsigned int getModuleVersion (const std::string &name); void updateModuleVersion (const std::string &name, unsigned int version); + // --------------------------------------------------------------------------- + // Import. + // --------------------------------------------------------------------------- + + void importLegacyFriends (DbSession &inDbSession); + void importLegacyHistory (DbSession &inDbSession); + L_DECLARE_PUBLIC(MainDb); }; diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 449522345..de45c0850 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -42,6 +42,8 @@ #include "main-db-p.h" #define DB_MODULE_VERSION_EVENTS L_VERSION(1, 0, 0) +#define DB_MODULE_VERSION_FRIENDS L_VERSION(1, 0, 0) +#define DB_MODULE_VERSION_LEGACY_FRIENDS_IMPORT L_VERSION(1, 0, 0) #define DB_MODULE_VERSION_LEGACY_HISTORY_IMPORT L_VERSION(1, 0, 0) // ============================================================================= @@ -1051,6 +1053,265 @@ void MainDbPrivate::updateModuleVersion (const string &name, unsigned int versio // ----------------------------------------------------------------------------- +#define CHECK_LEGACY_TABLE_EXISTS(SESSION, NAME) \ + do { \ + SESSION << "SELECT name FROM sqlite_master WHERE type='table' AND name='" NAME "'"; \ + return SESSION.got_data() > 0; \ + } while (false); + +static inline bool checkLegacyFriendsTableExists (soci::session &session) { + CHECK_LEGACY_TABLE_EXISTS(session, "friends"); +} + +static inline bool checkLegacyHistoryTableExists (soci::session &session) { + CHECK_LEGACY_TABLE_EXISTS(session, "history"); +} + +template +static T getValueFromRow (const soci::row &row, int index, bool &isNull) { + isNull = false; + + try { + return row.get(static_cast(index)); + } catch (const exception &) { + isNull = true; + } + + return T(); +} + +// ----------------------------------------------------------------------------- + +#define LEGACY_FRIEND_LIST_COL_ID 0 +#define LEGACY_FRIEND_LIST_COL_NAME 1 +#define LEGACY_FRIEND_LIST_COL_RLS_URI 2 +#define LEGACY_FRIEND_LIST_COL_SYNC_URI 3 +#define LEGACY_FRIEND_LIST_COL_REVISION 4 + +#define LEGACY_FRIEND_COL_FRIEND_LIST_ID 1 +#define LEGACY_FRIEND_COL_SIP_ADDRESS 2 +#define LEGACY_FRIEND_COL_SUBSCRIBE_POLICY 3 +#define LEGACY_FRIEND_COL_SEND_SUBSCRIBE 4 +#define LEGACY_FRIEND_COL_REF_KEY 5 +#define LEGACY_FRIEND_COL_V_CARD 6 +#define LEGACY_FRIEND_COL_V_CARD_ETAG 7 +#define LEGACY_FRIEND_COL_V_CARD_SYNC_URI 8 +#define LEGACY_FRIEND_COL_PRESENCE_RECEIVED 9 + +void MainDbPrivate::importLegacyFriends (DbSession &inDbSession) { + L_Q(); + + soci::session *inSession = inDbSession.getBackendSession(); + soci::transaction tr(*dbSession.getBackendSession()); + + if (getModuleVersion("legacy-friends-import") >= L_VERSION(1, 0, 0)) + return; + updateModuleVersion("legacy-friends-import", DB_MODULE_VERSION_LEGACY_FRIENDS_IMPORT); + + if (!checkLegacyFriendsTableExists(*inSession)) + return; + + unordered_map resolvedListsIds; + soci::session *session = dbSession.getBackendSession(); + + soci::rowset friendsLists = (inSession->prepare << "SELECT * FROM friends_lists"); + try { + set names; + for (const auto &friendList : friendsLists) { + const string &name = friendList.get(LEGACY_FRIEND_LIST_COL_NAME, ""); + const string &rlsUri = friendList.get(LEGACY_FRIEND_LIST_COL_RLS_URI, ""); + const string &syncUri = friendList.get(LEGACY_FRIEND_LIST_COL_SYNC_URI, ""); + const int &revision = friendList.get(LEGACY_FRIEND_LIST_COL_REVISION, 0); + + string uniqueName = name; + for (int id = 0; names.find(uniqueName) != names.end(); uniqueName = name + "-" + Utils::toString(id++)); + names.insert(uniqueName); + + *session << "INSERT INTO friends_list (name, rls_uri, sync_uri, revision) VALUES (" + " :name, :rlsUri, :syncUri, :revision" + ")", soci::use(uniqueName), soci::use(rlsUri), soci::use(syncUri), soci::use(revision); + resolvedListsIds[friendList.get(LEGACY_FRIEND_LIST_COL_ID)] = q->getLastInsertId(); + } + } catch (const exception &e) { + lWarning() << "Failed to import legacy friends list: " << e.what() << "."; + return; + } + + soci::rowset friends = (inSession->prepare << "SELECT * FROM friends"); + try { + for (const auto &friendInfo : friends) { + long long friendsListId; + { + auto it = resolvedListsIds.find(friendInfo.get(LEGACY_FRIEND_COL_FRIEND_LIST_ID, -1)); + if (it == resolvedListsIds.end()) + continue; + friendsListId = it->second; + } + + const long long &sipAddressId = insertSipAddress(friendInfo.get(LEGACY_FRIEND_COL_SIP_ADDRESS, "")); + const int &subscribePolicy = friendInfo.get(LEGACY_FRIEND_COL_SUBSCRIBE_POLICY, LinphoneSPAccept); + const int &sendSubscribe = friendInfo.get(LEGACY_FRIEND_COL_SEND_SUBSCRIBE, 1); + const string &vCard = friendInfo.get(LEGACY_FRIEND_COL_V_CARD, ""); + const string &vCardEtag = friendInfo.get(LEGACY_FRIEND_COL_V_CARD_ETAG, ""); + const string &vCardSyncUri = friendInfo.get(LEGACY_FRIEND_COL_V_CARD_SYNC_URI, ""); + const int &presenceReveived = friendInfo.get(LEGACY_FRIEND_COL_PRESENCE_RECEIVED, 0); + + *session << "INSERT INTO friend (" + " sip_address_id, friends_list_id, subscribe_policy, send_subscribe," + " presence_received, v_card, v_card_etag, v_card_sync_uri" + ") VALUES (" + " :sipAddressId, :friendsListId, :subscribePolicy, :sendSubscribe," + " :presenceReceived, :vCard, :vCardEtag, :vCardSyncUri" + ")", soci::use(sipAddressId), soci::use(friendsListId), soci::use(subscribePolicy), soci::use(sendSubscribe), + soci::use(presenceReveived), soci::use(vCard), soci::use(vCardEtag), soci::use(vCardSyncUri); + + bool isNull; + const string &data = getValueFromRow(friendInfo, LEGACY_FRIEND_COL_REF_KEY, isNull); + if (!isNull) + *session << "INSERT INTO friend_app_data (friend_id, name, data) VALUES" + " (:friendId, 'legacy', :data)", + soci::use(q->getLastInsertId()), soci::use(data); + } + tr.commit(); + } catch (const exception &e) { + lWarning() << "Failed to import legacy friends: " << e.what() << "."; + return; + } + + lInfo() << "Successful import of legacy friends."; +} + +#define LEGACY_MESSAGE_COL_LOCAL_ADDRESS 1 +#define LEGACY_MESSAGE_COL_REMOTE_ADDRESS 2 +#define LEGACY_MESSAGE_COL_DIRECTION 3 +#define LEGACY_MESSAGE_COL_TEXT 4 +#define LEGACY_MESSAGE_COL_STATE 7 +#define LEGACY_MESSAGE_COL_URL 8 +#define LEGACY_MESSAGE_COL_DATE 9 +#define LEGACY_MESSAGE_COL_APP_DATA 10 +#define LEGACY_MESSAGE_COL_CONTENT_ID 11 +#define LEGACY_MESSAGE_COL_IMDN_MESSAGE_ID 12 +#define LEGACY_MESSAGE_COL_CONTENT_TYPE 13 +#define LEGACY_MESSAGE_COL_IS_SECURED 14 + +void MainDbPrivate::importLegacyHistory (DbSession &inDbSession) { + L_Q(); + + soci::session *inSession = inDbSession.getBackendSession(); + soci::transaction tr(*dbSession.getBackendSession()); + + unsigned int version = getModuleVersion("legacy-history-import"); + if (version >= L_VERSION(1, 0, 0)) + return; + updateModuleVersion("legacy-history-import", DB_MODULE_VERSION_LEGACY_HISTORY_IMPORT); + + if (!checkLegacyHistoryTableExists(*inSession)) + return; + + soci::rowset messages = (inSession->prepare << "SELECT * FROM history"); + try { + for (const auto &message : messages) { + const int direction = message.get(LEGACY_MESSAGE_COL_DIRECTION); + if (direction != 0 && direction != 1) { + lWarning() << "Unable to import legacy message with invalid direction."; + continue; + } + + const int &state = message.get( + LEGACY_MESSAGE_COL_STATE, static_cast(ChatMessage::State::Displayed) + ); + if (state < 0 || state > static_cast(ChatMessage::State::Displayed)) { + lWarning() << "Unable to import legacy message with invalid state."; + continue; + } + + const tm &creationTime = Utils::getTimeTAsTm(message.get(LEGACY_MESSAGE_COL_DATE, 0)); + + bool isNull; + getValueFromRow(message, LEGACY_MESSAGE_COL_URL, isNull); + + const int &contentId = message.get(LEGACY_MESSAGE_COL_CONTENT_ID, -1); + ContentType contentType(message.get(LEGACY_MESSAGE_COL_CONTENT_TYPE, "")); + if (!contentType.isValid()) + contentType = contentId != -1 + ? ContentType::FileTransfer + : (isNull ? ContentType::PlainText : ContentType::ExternalBody); + if (contentType == ContentType::ExternalBody) { + lInfo() << "Import of external body content is skipped."; + continue; + } + + const string &text = getValueFromRow(message, LEGACY_MESSAGE_COL_TEXT, isNull); + + Content content; + content.setContentType(contentType); + if (contentType == ContentType::PlainText) { + if (isNull) { + lWarning() << "Unable to import legacy message with no text."; + continue; + } + content.setBody(text); + } else { + if (contentType != ContentType::FileTransfer) { + lWarning() << "Unable to import unsupported legacy content."; + continue; + } + + const string appData = getValueFromRow(message, LEGACY_MESSAGE_COL_APP_DATA, isNull); + if (isNull) { + lWarning() << "Unable to import legacy file message without app data."; + continue; + } + + content.setAppData("legacy", appData); + } + + soci::session *session = dbSession.getBackendSession(); + const int &eventType = static_cast(EventLog::Type::ConferenceChatMessage); + *session << "INSERT INTO event (type, creation_time) VALUES (:type, :creationTime)", + soci::use(eventType), soci::use(creationTime); + + const long long &eventId = q->getLastInsertId(); + const long long &localSipAddressId = insertSipAddress(message.get(LEGACY_MESSAGE_COL_LOCAL_ADDRESS)); + const long long &remoteSipAddressId = insertSipAddress(message.get(LEGACY_MESSAGE_COL_REMOTE_ADDRESS)); + const long long &chatRoomId = insertOrUpdateImportedBasicChatRoom( + remoteSipAddressId, + localSipAddressId, + creationTime + ); + const int &isSecured = message.get(LEGACY_MESSAGE_COL_IS_SECURED, 0); + + *session << "INSERT INTO conference_event (event_id, chat_room_id)" + " VALUES (:eventId, :chatRoomId)", soci::use(eventId), soci::use(chatRoomId); + + *session << "INSERT INTO conference_chat_message_event (" + " event_id, from_sip_address_id, to_sip_address_id," + " time, state, direction, imdn_message_id, is_secured" + ") VALUES (" + " :eventId, :localSipAddressId, :remoteSipAddressId," + " :creationTime, :state, :direction, '', :isSecured" + ")", soci::use(eventId), soci::use(localSipAddressId), soci::use(remoteSipAddressId), + soci::use(creationTime), soci::use(state), soci::use(direction), + soci::use(isSecured); + + insertContent(eventId, content); + insertChatRoomParticipant(chatRoomId, remoteSipAddressId, false); + + if (state != static_cast(ChatMessage::State::Displayed)) + insertChatMessageParticipant(eventId, remoteSipAddressId, state); + } + + tr.commit(); + } catch (const exception &e) { + lInfo() << "Failed to import legacy messages: " << e.what() << "."; + return; + } + + lInfo() << "Successful import of legacy messages."; +} + +// ----------------------------------------------------------------------------- + void MainDb::init () { L_D(); @@ -1335,6 +1596,52 @@ void MainDb::init () { *session << participantMessageDeleter; #endif + *session << + "CREATE TABLE IF NOT EXISTS friends_list (" + " id" + primaryKeyStr("INT UNSIGNED") + "," + + " name VARCHAR(255) UNIQUE," + " rls_uri VARCHAR(2047)," + " sync_uri VARCHAR(2047)," + " revision INT UNSIGNED NOT NULL" + ") " + charset; + + *session << + "CREATE TABLE IF NOT EXISTS friend (" + " id" + primaryKeyStr("INT UNSIGNED") + "," + + " sip_address_id" + primaryKeyRefStr("BIGINT UNSIGNED") + " NOT NULL," + " friends_list_id" + primaryKeyRefStr("INT UNSIGNED") + " NOT NULL," + + " subscribe_policy TINYINT UNSIGNED NOT NULL," + " send_subscribe BOOLEAN NOT NULL," + " presence_received BOOLEAN NOT NULL," + + " v_card MEDIUMTEXT," + " v_card_etag VARCHAR(255)," + " v_card_sync_uri VARCHAR(2047)," + + " FOREIGN KEY (sip_address_id)" + " REFERENCES sip_address(id)" + " ON DELETE CASCADE," + " FOREIGN KEY (friends_list_id)" + " REFERENCES friends_list(id)" + " ON DELETE CASCADE" + ") " + charset; + + *session << + "CREATE TABLE IF NOT EXISTS friend_app_data (" + " friend_id" + primaryKeyRefStr("INT UNSIGNED") + "," + + " name VARCHAR(255)," + " data BLOB NOT NULL," + + " PRIMARY KEY (friend_id, name)," + " FOREIGN KEY (friend_id)" + " REFERENCES friend(id)" + " ON DELETE CASCADE" + ") " + charset; + *session << "CREATE TABLE IF NOT EXISTS db_module_version (" " name" + varcharPrimaryKeyStr(255) + "," @@ -1342,6 +1649,7 @@ void MainDb::init () { ") " + charset; d->updateModuleVersion("events", DB_MODULE_VERSION_EVENTS); + d->updateModuleVersion("friends", DB_MODULE_VERSION_FRIENDS); } bool MainDb::addEvent (const shared_ptr &eventLog) { @@ -2320,37 +2628,6 @@ void MainDb::enableChatRoomMigration (const ChatRoomId &chatRoomId, bool enable) // ----------------------------------------------------------------------------- -#define LEGACY_MESSAGE_COL_LOCAL_ADDRESS 1 -#define LEGACY_MESSAGE_COL_REMOTE_ADDRESS 2 -#define LEGACY_MESSAGE_COL_DIRECTION 3 -#define LEGACY_MESSAGE_COL_TEXT 4 -#define LEGACY_MESSAGE_COL_STATE 7 -#define LEGACY_MESSAGE_COL_URL 8 -#define LEGACY_MESSAGE_COL_DATE 9 -#define LEGACY_MESSAGE_COL_APP_DATA 10 -#define LEGACY_MESSAGE_COL_CONTENT_ID 11 -#define LEGACY_MESSAGE_COL_IMDN_MESSAGE_ID 12 -#define LEGACY_MESSAGE_COL_CONTENT_TYPE 13 -#define LEGACY_MESSAGE_COL_IS_SECURED 14 - -template -static T getValueFromLegacyMessage (const soci::row &message, int index, bool &isNull) { - isNull = false; - - try { - return message.get(static_cast(index)); - } catch (const exception &) { - isNull = true; - } - - return T(); -} - -static bool checkLegacyHistoryTableExists (soci::session &session) { - session << "SELECT name FROM sqlite_master WHERE type='table' AND name='history'"; - return session.got_data() > 0; -} - bool MainDb::import (Backend, const string ¶meters) { L_D(); @@ -2368,118 +2645,13 @@ bool MainDb::import (Backend, const string ¶meters) { return false; } - soci::session *inSession = inDbSession.getBackendSession(); + L_BEGIN_LOG_EXCEPTION + d->importLegacyFriends(inDbSession); + L_END_LOG_EXCEPTION - // Import messages. - try { - soci::transaction tr(*d->dbSession.getBackendSession()); - - if (!checkLegacyHistoryTableExists(*inSession)) - return false; - - unsigned int version = d->getModuleVersion("legacy-history-import"); - if (version >= L_VERSION(1, 0, 0)) - return false; - d->updateModuleVersion("legacy-history-import", DB_MODULE_VERSION_LEGACY_HISTORY_IMPORT); - - soci::rowset messages = (inSession->prepare << "SELECT * FROM history"); - for (const auto &message : messages) { - const int direction = message.get(LEGACY_MESSAGE_COL_DIRECTION); - if (direction != 0 && direction != 1) { - lWarning() << "Unable to import legacy message with invalid direction."; - continue; - } - - const int &state = message.get( - LEGACY_MESSAGE_COL_STATE, static_cast(ChatMessage::State::Displayed) - ); - if (state < 0 || state > static_cast(ChatMessage::State::Displayed)) { - lWarning() << "Unable to import legacy message with invalid state."; - continue; - } - - const tm &creationTime = Utils::getTimeTAsTm(message.get(LEGACY_MESSAGE_COL_DATE, 0)); - - bool isNull; - getValueFromLegacyMessage(message, LEGACY_MESSAGE_COL_URL, isNull); - - const int &contentId = message.get(LEGACY_MESSAGE_COL_CONTENT_ID, -1); - ContentType contentType(message.get(LEGACY_MESSAGE_COL_CONTENT_TYPE, "")); - if (!contentType.isValid()) - contentType = contentId != -1 - ? ContentType::FileTransfer - : (isNull ? ContentType::PlainText : ContentType::ExternalBody); - if (contentType == ContentType::ExternalBody) { - lInfo() << "Import of external body content is skipped."; - continue; - } - - const string &text = getValueFromLegacyMessage(message, LEGACY_MESSAGE_COL_TEXT, isNull); - - Content content; - content.setContentType(contentType); - if (contentType == ContentType::PlainText) { - if (isNull) { - lWarning() << "Unable to import legacy message with no text."; - continue; - } - content.setBody(text); - } else { - if (contentType != ContentType::FileTransfer) { - lWarning() << "Unable to import unsupported legacy content."; - continue; - } - - const string appData = getValueFromLegacyMessage(message, LEGACY_MESSAGE_COL_APP_DATA, isNull); - if (isNull) { - lWarning() << "Unable to import legacy file message without app data."; - continue; - } - - content.setAppData("legacy", appData); - } - - soci::session *session = d->dbSession.getBackendSession(); - const int &eventType = static_cast(EventLog::Type::ConferenceChatMessage); - *session << "INSERT INTO event (type, creation_time) VALUES (:type, :creationTime)", - soci::use(eventType), soci::use(creationTime); - - const long long &eventId = getLastInsertId(); - const long long &localSipAddressId = d->insertSipAddress(message.get(LEGACY_MESSAGE_COL_LOCAL_ADDRESS)); - const long long &remoteSipAddressId = d->insertSipAddress(message.get(LEGACY_MESSAGE_COL_REMOTE_ADDRESS)); - const long long &chatRoomId = d->insertOrUpdateImportedBasicChatRoom( - remoteSipAddressId, - localSipAddressId, - creationTime - ); - const int &isSecured = message.get(LEGACY_MESSAGE_COL_IS_SECURED, 0); - - *session << "INSERT INTO conference_event (event_id, chat_room_id)" - " VALUES (:eventId, :chatRoomId)", soci::use(eventId), soci::use(chatRoomId); - - *session << "INSERT INTO conference_chat_message_event (" - " event_id, from_sip_address_id, to_sip_address_id," - " time, state, direction, imdn_message_id, is_secured" - ") VALUES (" - " :eventId, :localSipAddressId, :remoteSipAddressId," - " :creationTime, :state, :direction, '', :isSecured" - ")", soci::use(eventId), soci::use(localSipAddressId), soci::use(remoteSipAddressId), - soci::use(creationTime), soci::use(state), soci::use(direction), - soci::use(isSecured); - - d->insertContent(eventId, content); - d->insertChatRoomParticipant(chatRoomId, remoteSipAddressId, false); - - if (state != static_cast(ChatMessage::State::Displayed)) - d->insertChatMessageParticipant(eventId, remoteSipAddressId, state); - } - - tr.commit(); - } catch (const exception &e) { - lInfo() << "Failed to import legacy messages from: `" << uri << "`. (" << e.what() << ")"; - return false; - } - lInfo() << "Successful import of legacy messages from: `" << uri << "`."; + L_BEGIN_LOG_EXCEPTION + d->importLegacyHistory(inDbSession); + L_END_LOG_EXCEPTION return true; } diff --git a/src/db/main-db.h b/src/db/main-db.h index ca153e705..28a54489a 100644 --- a/src/db/main-db.h +++ b/src/db/main-db.h @@ -129,7 +129,7 @@ public: // Other. // --------------------------------------------------------------------------- - // Import legacy messages from old db. + // Import legacy calls/messages from old db. bool import (Backend backend, const std::string ¶meters) override; protected: