From 09b229541467d4b9a556f708251bd4afdd31f078 Mon Sep 17 00:00:00 2001 From: "jabber.developer2" Date: Mon, 4 May 2026 17:35:59 +0300 Subject: [PATCH] fix(export): open sqlite on demand when flatfile is active backend --- src/database.h | 1 + src/database_export.c | 58 +++++++++++++++++++++++++++++++++++++++++++ src/database_sqlite.c | 6 +++++ 3 files changed, 65 insertions(+) diff --git a/src/database.h b/src/database.h index 473d9f7a..c897230f 100644 --- a/src/database.h +++ b/src/database.h @@ -93,6 +93,7 @@ void db_sqlite_begin_transaction(void); void db_sqlite_end_transaction(void); void db_sqlite_rollback_transaction(void); int db_sqlite_last_changes(void); +gboolean db_sqlite_is_open(void); #endif db_backend_t* db_backend_flatfile(void); diff --git a/src/database_export.c b/src/database_export.c index 38eb8aea..1e0b45d5 100644 --- a/src/database_export.c +++ b/src/database_export.c @@ -30,10 +30,12 @@ #include "log.h" #include "common.h" #include "config/files.h" +#include "config/accounts.h" #include "database.h" #include "database_flatfile.h" #include "config/preferences.h" #include "ui/ui.h" +#include "xmpp/session.h" #include "xmpp/xmpp.h" #include "xmpp/message.h" @@ -46,6 +48,43 @@ // Print progress to console every N messages during export/import #define EXPORT_PROGRESS_INTERVAL 500 +// Open SQLite if it isn't already (e.g. when flatfile is the active backend +// and sqlite was never initialised this session, or was closed by /history +// switch). Returns 1 if we opened it (caller must close), 0 if it was already +// open, -1 on failure. +static int +_ensure_sqlite_open(void) +{ + if (db_sqlite_is_open()) + return 0; + + db_backend_t* sqlite_be = db_backend_sqlite(); + if (!sqlite_be || !sqlite_be->init) + return -1; + + const char* account_name = session_get_account_name(); + if (!account_name) + return -1; + + ProfAccount* account = accounts_get_account(account_name); + if (!account) + return -1; + + gboolean ok = sqlite_be->init(account); + account_free(account); + return ok ? 1 : -1; +} + +static void +_close_temp_sqlite(int opened) +{ + if (opened != 1) + return; + db_backend_t* sqlite_be = db_backend_sqlite(); + if (sqlite_be && sqlite_be->close) + sqlite_be->close(); +} + // ========================================================================= // Dedup key: stanza_id if present, else hash of timestamp+from+body // ========================================================================= @@ -429,6 +468,15 @@ log_database_export_to_flatfile(const gchar* const contact_jid) return -1; } + // SQLite must be open for db_sqlite_list_contacts/db_sqlite_get_all_chat + // to return rows. When the flatfile backend is active, sqlite is closed — + // queries silently return NULL and the export reports zero changes. + int sqlite_opened = _ensure_sqlite_open(); + if (sqlite_opened < 0) { + cons_show_error("Export failed: could not open SQLite database."); + return -1; + } + // Determine contact list GSList* contacts = NULL; if (contact_jid) { @@ -437,6 +485,7 @@ log_database_export_to_flatfile(const gchar* const contact_jid) contacts = db_sqlite_list_contacts(); if (!contacts) { cons_show("No contacts found in SQLite database."); + _close_temp_sqlite(sqlite_opened); return 0; } cons_show("Exporting %d contact(s) to flat-file format...", g_slist_length(contacts)); @@ -452,6 +501,7 @@ log_database_export_to_flatfile(const gchar* const contact_jid) } g_slist_free_full(contacts, g_free); + _close_temp_sqlite(sqlite_opened); return total_exported; } @@ -478,6 +528,12 @@ log_database_import_from_flatfile(const gchar* const contact_jid) return -1; } + int sqlite_opened = _ensure_sqlite_open(); + if (sqlite_opened < 0) { + cons_show_error("Import failed: could not open SQLite database."); + return -1; + } + // Determine contacts GSList* contacts = NULL; if (contact_jid) { @@ -486,6 +542,7 @@ log_database_import_from_flatfile(const gchar* const contact_jid) contacts = _ff_list_contacts(); if (!contacts) { cons_show("No flat-file history found to import."); + _close_temp_sqlite(sqlite_opened); return 0; } } @@ -613,6 +670,7 @@ log_database_import_from_flatfile(const gchar* const contact_jid) } g_slist_free_full(contacts, g_free); + _close_temp_sqlite(sqlite_opened); return total_imported; } diff --git a/src/database_sqlite.c b/src/database_sqlite.c index 3013655a..2061c1ee 100644 --- a/src/database_sqlite.c +++ b/src/database_sqlite.c @@ -65,6 +65,12 @@ static gboolean _check_available_space_for_db_migration(char* path_to_db); static const int latest_version = 2; +gboolean +db_sqlite_is_open(void) +{ + return g_chatlog_database != NULL; +} + // Helper: close DB handle (if any), warn on busy, and shutdown SQLite static void _db_teardown(const char* ctx)