From 650686c2412beecfb8dd6de9e1a937c2f253eca8 Mon Sep 17 00:00:00 2001 From: "jabber.developer2" Date: Thu, 26 Feb 2026 14:04:38 +0300 Subject: [PATCH] feat: add /history switch for runtime database backend switching Add log_database_switch_backend() that closes the current backend, updates PREF_DBLOG preference, and reinitializes with the new backend without requiring a reconnect or restart. New command: /history switch sqlite|flatfile - Validates connection state and backend name - Skips if already using the requested backend - Autocomplete support for the subcommand --- src/command/cmd_ac.c | 11 +++++++++++ src/command/cmd_defs.c | 3 +++ src/command/cmd_funcs.c | 31 +++++++++++++++++++++++++++++++ src/database.c | 29 +++++++++++++++++++++++++++++ src/database.h | 1 + 5 files changed, 75 insertions(+) diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 7c133fc6..23f5c749 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -276,6 +276,7 @@ static Autocomplete logging_group_ac; static Autocomplete privacy_ac; static Autocomplete privacy_log_ac; static Autocomplete history_ac; +static Autocomplete history_switch_ac; static Autocomplete color_ac; static Autocomplete correction_ac; static Autocomplete avatar_ac; @@ -431,6 +432,7 @@ static Autocomplete* all_acs[] = { &privacy_ac, &privacy_log_ac, &history_ac, + &history_switch_ac, &color_ac, &correction_ac, &avatar_ac, @@ -1144,10 +1146,14 @@ cmd_ac_init(void) autocomplete_add(history_ac, "on"); autocomplete_add(history_ac, "off"); + autocomplete_add(history_ac, "switch"); autocomplete_add(history_ac, "verify"); autocomplete_add(history_ac, "export"); autocomplete_add(history_ac, "import"); + autocomplete_add(history_switch_ac, "sqlite"); + autocomplete_add(history_switch_ac, "flatfile"); + autocomplete_add(logging_group_ac, "on"); autocomplete_add(logging_group_ac, "off"); autocomplete_add(logging_group_ac, "color"); @@ -1795,6 +1801,11 @@ _cmd_ac_complete_params(ProfWin* window, const char* const input, gboolean previ } } + result = autocomplete_param_with_ac(input, "/history switch", history_switch_ac, TRUE, previous); + if (result) { + return result; + } + result = autocomplete_param_with_ac(input, "/history", history_ac, TRUE, previous); if (result) { return result; diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 3f80fa39..b9a308a2 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -1882,17 +1882,20 @@ static const struct cmd_t command_defs[] = { CMD_TAG_CHAT) CMD_SYN( "/history on|off", + "/history switch sqlite|flatfile", "/history verify []", "/history export []", "/history import []") CMD_DESC( "Switch chat history on or off, /logging chat will automatically be enabled when this setting is on. " "When history is enabled, previous messages are shown in chat windows. " + "Use 'switch' to change the active database backend at runtime without reconnecting. " "Use 'verify' to check integrity of stored message history. " "Use 'export' to copy messages from SQLite to flat-file format, or 'import' to copy from flat-file to SQLite. " "Both export and import merge with existing data (duplicates are skipped).") CMD_ARGS( { "on|off", "Enable or disable showing chat history." }, + { "switch sqlite|flatfile", "Switch the active database backend at runtime." }, { "verify []", "Verify integrity of message history. Optionally specify a JID to check only one contact." }, { "export []", "Export SQLite history to flat-file format. Optionally specify a JID to export only one contact." }, { "import []", "Import flat-file history into SQLite. Optionally specify a JID to import only one contact." }) diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 5258afe5..5a24b44d 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -6735,6 +6735,37 @@ cmd_history(ProfWin* window, const char* const command, gchar** args) return TRUE; } + if (g_strcmp0(args[0], "switch") == 0) { + jabber_conn_status_t conn_status = connection_get_status(); + if (conn_status != JABBER_CONNECTED) { + cons_show_error("You must be connected to switch database backend."); + return TRUE; + } + + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + return TRUE; + } + + if (g_strcmp0(args[1], "sqlite") != 0 && g_strcmp0(args[1], "flatfile") != 0) { + cons_show_error("Backend must be 'sqlite' or 'flatfile'."); + return TRUE; + } + + if (active_db_backend && g_strcmp0(active_db_backend->name, args[1]) == 0) { + cons_show("Already using '%s' backend.", args[1]); + return TRUE; + } + + cons_show("Switching database backend to '%s'...", args[1]); + if (log_database_switch_backend(args[1])) { + cons_show("Database backend switched to '%s'.", args[1]); + } else { + cons_show_error("Failed to switch database backend."); + } + return TRUE; + } + if (g_strcmp0(args[0], "verify") == 0) { const gchar* contact_jid = args[1]; // may be NULL (verify all) cons_show("Verifying history integrity..."); diff --git a/src/database.c b/src/database.c index 46689484..6469404a 100644 --- a/src/database.c +++ b/src/database.c @@ -44,6 +44,7 @@ #include "config.h" #include "database.h" #include "config/preferences.h" +#include "config/accounts.h" #include "ui/ui.h" #include "xmpp/xmpp.h" #include "xmpp/message.h" @@ -96,6 +97,34 @@ log_database_close(void) active_db_backend = NULL; } +gboolean +log_database_switch_backend(const char* new_backend) +{ + // Close current backend + log_database_close(); + + // Update preference + prefs_set_string(PREF_DBLOG, new_backend); + prefs_save(); + + // Get current account to reinitialize + const char* account_name = session_get_account_name(); + if (!account_name) { + log_error("log_database_switch_backend: no active session"); + return FALSE; + } + + ProfAccount* account = accounts_get_account(account_name); + if (!account) { + log_error("log_database_switch_backend: account '%s' not found", account_name); + return FALSE; + } + + gboolean result = log_database_init(account); + account_free(account); + return result; +} + void log_database_add_incoming(ProfMessage* message) { diff --git a/src/database.h b/src/database.h index 9b29f014..7a9e48b2 100644 --- a/src/database.h +++ b/src/database.h @@ -93,6 +93,7 @@ db_backend_t* db_backend_flatfile(void); // Public API (dispatches to active_db_backend) gboolean log_database_init(ProfAccount* account); +gboolean log_database_switch_backend(const char* new_backend); void log_database_add_incoming(ProfMessage* message); void log_database_add_outgoing_chat(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc);