Commit 335f19b2 authored by Ronan's avatar Ronan
Browse files

feat(MainDb): legacy friends import

parent 588bea60
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#endif #endif
#include "c-wrapper/c-wrapper.h" #include "c-wrapper/c-wrapper.h"
#include "core/core-p.h"
#include "db/main-db.h"
// TODO: From coreapi. Remove me later. // TODO: From coreapi. Remove me later.
#include "private.h" #include "private.h"
...@@ -1722,6 +1724,10 @@ bctbx_list_t* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) { ...@@ -1722,6 +1724,10 @@ bctbx_list_t* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) {
#endif #endif
void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path) { 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){ if (lc->friends_db_file){
ms_free(lc->friends_db_file); ms_free(lc->friends_db_file);
lc->friends_db_file = NULL; lc->friends_db_file = NULL;
...@@ -1729,8 +1735,6 @@ void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path) ...@@ -1729,8 +1735,6 @@ void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path)
if (path) { if (path) {
lc->friends_db_file = ms_strdup(path); lc->friends_db_file = ms_strdup(path);
linphone_core_friends_storage_init(lc); 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) { ...@@ -1738,69 +1742,6 @@ const char* linphone_core_get_friends_database_path(LinphoneCore *lc) {
return lc->friends_db_file; 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) { LinphoneSubscriptionState linphone_friend_get_subscription_state(const LinphoneFriend *lf) {
return lf->out_sub_state; return lf->out_sub_state;
} }
......
...@@ -6692,11 +6692,8 @@ int linphone_core_get_video_dscp(const LinphoneCore *lc){ ...@@ -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) { void linphone_core_set_chat_database_path (LinphoneCore *lc, const char *path) {
if ( if (!linphone_core_conference_server_enabled(lc))
linphone_core_conference_server_enabled(lc) || L_GET_PRIVATE(lc->cppPtr)->mainDb->import(LinphonePrivate::MainDb::Sqlite3, path);
!L_GET_PRIVATE(lc->cppPtr)->mainDb->import(LinphonePrivate::MainDb::Sqlite3, path)
)
lError() << "Do not use `linphone_core_set_chat_database_path`. Not necessary.";
} }
const char *linphone_core_get_chat_database_path (const LinphoneCore *) { const char *linphone_core_get_chat_database_path (const LinphoneCore *) {
......
...@@ -5287,13 +5287,6 @@ LINPHONE_PUBLIC void linphone_core_set_friends_database_path(LinphoneCore *lc, c ...@@ -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); 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. * Create a new empty LinphoneFriendList object.
* @param[in] lc LinphoneCore object. * @param[in] lc LinphoneCore object.
......
...@@ -154,6 +154,13 @@ private: ...@@ -154,6 +154,13 @@ private:
unsigned int getModuleVersion (const std::string &name); unsigned int getModuleVersion (const std::string &name);
void updateModuleVersion (const std::string &name, unsigned int version); void updateModuleVersion (const std::string &name, unsigned int version);
// ---------------------------------------------------------------------------
// Import.
// ---------------------------------------------------------------------------
void importLegacyFriends (DbSession &inDbSession);
void importLegacyHistory (DbSession &inDbSession);
L_DECLARE_PUBLIC(MainDb); L_DECLARE_PUBLIC(MainDb);
}; };
......
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
#include "main-db-p.h" #include "main-db-p.h"
#define DB_MODULE_VERSION_EVENTS L_VERSION(1, 0, 0) #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) #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 ...@@ -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<typename T>
static T getValueFromRow (const soci::row &row, int index, bool &isNull) {
isNull = false;
try {
return row.get<T>(static_cast<size_t>(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::session>();
soci::transaction tr(*dbSession.getBackendSession<soci::session>());
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<int, long long> resolvedListsIds;
soci::session *session = dbSession.getBackendSession<soci::session>();
soci::rowset<soci::row> friendsLists = (inSession->prepare << "SELECT * FROM friends_lists");
try {
set<string> names;
for (const auto &friendList : friendsLists) {
const string &name = friendList.get<string>(LEGACY_FRIEND_LIST_COL_NAME, "");
const string &rlsUri = friendList.get<string>(LEGACY_FRIEND_LIST_COL_RLS_URI, "");
const string &syncUri = friendList.get<string>(LEGACY_FRIEND_LIST_COL_SYNC_URI, "");
const int &revision = friendList.get<int>(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<int>(LEGACY_FRIEND_LIST_COL_ID)] = q->getLastInsertId();
}
} catch (const exception &e) {
lWarning() << "Failed to import legacy friends list: " << e.what() << ".";
return;
}
soci::rowset<soci::row> friends = (inSession->prepare << "SELECT * FROM friends");
try {
for (const auto &friendInfo : friends) {
long long friendsListId;
{
auto it = resolvedListsIds.find(friendInfo.get<int>(LEGACY_FRIEND_COL_FRIEND_LIST_ID, -1));
if (it == resolvedListsIds.end())
continue;
friendsListId = it->second;
}
const long long &sipAddressId = insertSipAddress(friendInfo.get<string>(LEGACY_FRIEND_COL_SIP_ADDRESS, ""));
const int &subscribePolicy = friendInfo.get<int>(LEGACY_FRIEND_COL_SUBSCRIBE_POLICY, LinphoneSPAccept);
const int &sendSubscribe = friendInfo.get<int>(LEGACY_FRIEND_COL_SEND_SUBSCRIBE, 1);
const string &vCard = friendInfo.get<string>(LEGACY_FRIEND_COL_V_CARD, "");
const string &vCardEtag = friendInfo.get<string>(LEGACY_FRIEND_COL_V_CARD_ETAG, "");
const string &vCardSyncUri = friendInfo.get<string>(LEGACY_FRIEND_COL_V_CARD_SYNC_URI, "");
const int &presenceReveived = friendInfo.get<int>(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<string>(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::session>();
soci::transaction tr(*dbSession.getBackendSession<soci::session>());
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<soci::row> messages = (inSession->prepare << "SELECT * FROM history");
try {
for (const auto &message : messages) {
const int direction = message.get<int>(LEGACY_MESSAGE_COL_DIRECTION);
if (direction != 0 && direction != 1) {
lWarning() << "Unable to import legacy message with invalid direction.";
continue;
}
const int &state = message.get<int>(
LEGACY_MESSAGE_COL_STATE, static_cast<int>(ChatMessage::State::Displayed)
);
if (state < 0 || state > static_cast<int>(ChatMessage::State::Displayed)) {
lWarning() << "Unable to import legacy message with invalid state.";
continue;
}
const tm &creationTime = Utils::getTimeTAsTm(message.get<int>(LEGACY_MESSAGE_COL_DATE, 0));
bool isNull;
getValueFromRow<string>(message, LEGACY_MESSAGE_COL_URL, isNull);
const int &contentId = message.get<int>(LEGACY_MESSAGE_COL_CONTENT_ID, -1);
ContentType contentType(message.get<string>(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<string>(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<string>(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<soci::session>();
const int &eventType = static_cast<int>(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<string>(LEGACY_MESSAGE_COL_LOCAL_ADDRESS));
const long long &remoteSipAddressId = insertSipAddress(message.get<string>(LEGACY_MESSAGE_COL_REMOTE_ADDRESS));
const long long &chatRoomId = insertOrUpdateImportedBasicChatRoom(
remoteSipAddressId,
localSipAddressId,
creationTime
);
const int &isSecured = message.get<int>(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<int>(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 () { void MainDb::init () {
L_D(); L_D();
...@@ -1335,6 +1596,52 @@ void MainDb::init () { ...@@ -1335,6 +1596,52 @@ void MainDb::init () {
*session << participantMessageDeleter; *session << participantMessageDeleter;
#endif #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 << *session <<
"CREATE TABLE IF NOT EXISTS db_module_version (" "CREATE TABLE IF NOT EXISTS db_module_version ("
" name" + varcharPrimaryKeyStr(255) + "," " name" + varcharPrimaryKeyStr(255) + ","
...@@ -1342,6 +1649,7 @@ void MainDb::init () { ...@@ -1342,6 +1649,7 @@ void MainDb::init () {
") " + charset; ") " + charset;
d->updateModuleVersion("events", DB_MODULE_VERSION_EVENTS); d->updateModuleVersion("events", DB_MODULE_VERSION_EVENTS);
d->updateModuleVersion("friends", DB_MODULE_VERSION_FRIENDS);
} }
bool MainDb::addEvent (const shared_ptr<EventLog> &eventLog) { bool MainDb::addEvent (const shared_ptr<EventLog> &eventLog) {
...@@ -2320,37 +2628,6 @@ void MainDb::enableChatRoomMigration (const ChatRoomId &chatRoomId, bool enable) ...@@ -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<typename T>
static T getValueFromLegacyMessage (const soci::row &message, int index, bool &isNull) {
isNull = false;
try {
return message.get<T>(static_cast<size_t>(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 &parameters) { bool MainDb::import (Backend, const string &parameters) {
L_D(); L_D();
...@@ -2368,118 +2645,13 @@ bool MainDb::import (Backend, const string &parameters) { ...@@ -2368,118 +2645,13 @@ bool MainDb::import (Backend, const string &parameters) {
return false; return false;
} }
soci::session *inSession = inDbSession.getBackendSession<soci::session>(); L_BEGIN_LOG_EXCEPTION
d->importLegacyFriends(inDbSession);
// Import messages. L_END_LOG_EXCEPTION
try {
soci::transaction tr(*d->dbSession.getBackendSession<soci::session>());
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<soci::row> messages = (inSession->prepare << "SELECT * FROM history");
for (const auto &message : messages) {
const int direction = message.get<int>(LEGACY_MESSAGE_COL_DIRECTION);
if (direction != 0 && direction != 1) {
lWarning() << "Unable to import legacy message with invalid direction.";
continue;
}
const int &state = message.get<int>(
LEGACY_MESSAGE_COL_STATE, static_cast<int>(ChatMessage::State::Displayed)
);
if (state < 0 || state > static_cast<int>(ChatMessage::State::Displayed)) {
lWarning() << "Unable to import legacy message with invalid state.";
continue;
}
const tm &creationTime = Utils::getTimeTAsTm(message.get<int>(LEGACY_MESSAGE_COL_DATE, 0));
bool isNull;
getValueFromLegacyMessage<string>(message, LEGACY_MESSAGE_COL_URL, isNull);
const int &contentId = message.get<int>(LEGACY_MESSAGE_COL_CONTENT_ID, -1);
ContentType contentType(message.get<string>(LEGACY_MESSAGE_COL_CONTENT_TYPE, ""));
if (!contentType.isValid())
contentType = contentId != -1
? ContentType::FileTransfer