merge/upstream-full #105
@@ -61,9 +61,10 @@ static prof_msg_type_t _get_message_type_type(const char* const type);
|
|||||||
static prof_enc_t _get_message_enc_type(const char* const encstr);
|
static prof_enc_t _get_message_enc_type(const char* const encstr);
|
||||||
static int _get_db_version(void);
|
static int _get_db_version(void);
|
||||||
static gboolean _migrate_to_v2(void);
|
static gboolean _migrate_to_v2(void);
|
||||||
|
static gboolean _migrate_to_v3(void);
|
||||||
static gboolean _check_available_space_for_db_migration(char* path_to_db);
|
static gboolean _check_available_space_for_db_migration(char* path_to_db);
|
||||||
|
|
||||||
static const int latest_version = 2;
|
static const int latest_version = 3;
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
db_sqlite_is_open(void)
|
db_sqlite_is_open(void)
|
||||||
@@ -187,7 +188,7 @@ _sqlite_init(ProfAccount* account)
|
|||||||
"`timestamp` TEXT, "
|
"`timestamp` TEXT, "
|
||||||
"`type` TEXT, "
|
"`type` TEXT, "
|
||||||
"`stanza_id` TEXT, "
|
"`stanza_id` TEXT, "
|
||||||
"`archive_id` TEXT, "
|
"`archive_id` TEXT UNIQUE, "
|
||||||
"`encryption` TEXT, "
|
"`encryption` TEXT, "
|
||||||
"`marked_read` INTEGER, "
|
"`marked_read` INTEGER, "
|
||||||
"`replace_id` TEXT, "
|
"`replace_id` TEXT, "
|
||||||
@@ -228,8 +229,10 @@ _sqlite_init(ProfAccount* account)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (db_version == -1) {
|
if (db_version == -1) {
|
||||||
query = "INSERT OR IGNORE INTO `DbVersion` (`version`) VALUES ('2')";
|
auto_sqlite char* init_version_query = sqlite3_mprintf(
|
||||||
if (SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) {
|
"INSERT INTO `DbVersion` (`version`) VALUES (%d) ON CONFLICT(`version`) DO NOTHING",
|
||||||
|
latest_version);
|
||||||
|
if (SQLITE_OK != sqlite3_exec(g_chatlog_database, init_version_query, NULL, 0, &err_msg)) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
db_version = _get_db_version();
|
db_version = _get_db_version();
|
||||||
@@ -246,6 +249,10 @@ _sqlite_init(ProfAccount* account)
|
|||||||
cons_show_error("Database Initialization Error: Unable to migrate database to version 2. Please, check error logs for details.");
|
cons_show_error("Database Initialization Error: Unable to migrate database to version 2. Please, check error logs for details.");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (db_version < 3 && (!_check_available_space_for_db_migration(filename) || !_migrate_to_v3())) {
|
||||||
|
cons_show_error("Database Initialization Error: Unable to migrate database to version 3. Please, check error logs for details.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
cons_show("Database schema migration was successful.");
|
cons_show("Database schema migration was successful.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,7 +806,8 @@ _migrate_to_v2(void)
|
|||||||
"replace_id = COALESCE(NULLIF(replace_id, ''), NULL), "
|
"replace_id = COALESCE(NULLIF(replace_id, ''), NULL), "
|
||||||
"type = COALESCE(NULLIF(type, ''), NULL), "
|
"type = COALESCE(NULLIF(type, ''), NULL), "
|
||||||
"encryption = COALESCE(NULLIF(encryption, ''), NULL);",
|
"encryption = COALESCE(NULLIF(encryption, ''), NULL);",
|
||||||
"UPDATE `DbVersion` SET `version` = 2;",
|
"DELETE FROM `DbVersion`;",
|
||||||
|
"INSERT INTO `DbVersion` (`version`) VALUES (2);",
|
||||||
"END TRANSACTION"
|
"END TRANSACTION"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -829,6 +837,82 @@ cleanup:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_migrate_to_v3(void)
|
||||||
|
{
|
||||||
|
char* err_msg = NULL;
|
||||||
|
|
||||||
|
const char* sql_statements[] = {
|
||||||
|
"BEGIN TRANSACTION",
|
||||||
|
"CREATE TABLE `ChatLogs_v3_migration` ("
|
||||||
|
"`id` INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
|
"`from_jid` TEXT NOT NULL, "
|
||||||
|
"`to_jid` TEXT NOT NULL, "
|
||||||
|
"`from_resource` TEXT, "
|
||||||
|
"`to_resource` TEXT, "
|
||||||
|
"`message` TEXT, "
|
||||||
|
"`timestamp` TEXT, "
|
||||||
|
"`type` TEXT, "
|
||||||
|
"`stanza_id` TEXT, "
|
||||||
|
"`archive_id` TEXT UNIQUE, "
|
||||||
|
"`encryption` TEXT, "
|
||||||
|
"`marked_read` INTEGER, "
|
||||||
|
"`replace_id` TEXT, "
|
||||||
|
"`replaces_db_id` INTEGER, "
|
||||||
|
"`replaced_by_db_id` INTEGER)",
|
||||||
|
|
||||||
|
"INSERT INTO `ChatLogs_v3_migration` "
|
||||||
|
"SELECT * FROM `ChatLogs` "
|
||||||
|
"WHERE `archive_id` IS NULL "
|
||||||
|
"UNION ALL "
|
||||||
|
"SELECT * FROM (SELECT * FROM `ChatLogs` WHERE `archive_id` IS NOT NULL GROUP BY `archive_id`)",
|
||||||
|
|
||||||
|
"DROP TABLE `ChatLogs` ",
|
||||||
|
"ALTER TABLE `ChatLogs_v3_migration` RENAME TO `ChatLogs` ",
|
||||||
|
|
||||||
|
"CREATE INDEX ChatLogs_timestamp_IDX ON `ChatLogs` (`timestamp`)",
|
||||||
|
"CREATE INDEX ChatLogs_to_from_jid_IDX ON `ChatLogs` (`to_jid`, `from_jid`)",
|
||||||
|
"CREATE TRIGGER update_corrected_message "
|
||||||
|
"AFTER INSERT ON ChatLogs "
|
||||||
|
"FOR EACH ROW "
|
||||||
|
"WHEN NEW.replaces_db_id IS NOT NULL "
|
||||||
|
"BEGIN "
|
||||||
|
"UPDATE ChatLogs "
|
||||||
|
"SET replaced_by_db_id = NEW.id "
|
||||||
|
"WHERE id = NEW.replaces_db_id; "
|
||||||
|
"END;",
|
||||||
|
|
||||||
|
"DELETE FROM `DbVersion`;",
|
||||||
|
"INSERT INTO `DbVersion` (`version`) VALUES (3);",
|
||||||
|
"END TRANSACTION"
|
||||||
|
};
|
||||||
|
|
||||||
|
int statements_count = sizeof(sql_statements) / sizeof(sql_statements[0]);
|
||||||
|
|
||||||
|
for (int i = 0; i < statements_count; i++) {
|
||||||
|
if (SQLITE_OK != sqlite3_exec(g_chatlog_database, sql_statements[i], NULL, 0, &err_msg)) {
|
||||||
|
log_error("SQLite error in _migrate_to_v3() on statement %d: %s", i, err_msg);
|
||||||
|
if (err_msg) {
|
||||||
|
sqlite3_free(err_msg);
|
||||||
|
err_msg = NULL;
|
||||||
|
}
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (SQLITE_OK != sqlite3_exec(g_chatlog_database, "ROLLBACK;", NULL, 0, &err_msg)) {
|
||||||
|
log_error("[DB Migration] Unable to ROLLBACK: %s", err_msg);
|
||||||
|
if (err_msg) {
|
||||||
|
sqlite3_free(err_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_check_available_space_for_db_migration(char* path_to_db)
|
_check_available_space_for_db_migration(char* path_to_db)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,7 +81,9 @@ sv_ev_login_account_success(char* account_name, gboolean secured)
|
|||||||
omemo_on_connect(account);
|
omemo_on_connect(account);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
log_database_init(account);
|
if (!log_database_init(account)) {
|
||||||
|
log_error("Failed to initialize database for account: %s", account->jid);
|
||||||
|
}
|
||||||
vcard_user_refresh();
|
vcard_user_refresh();
|
||||||
avatar_pep_subscribe();
|
avatar_pep_subscribe();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user