feat: add /history switch for runtime database backend switching
Some checks failed
CI Code / Check coding style (pull_request) Successful in 47s
CI Code / Check spelling (pull_request) Successful in 55s
CI Code / Linux (ubuntu) (pull_request) Failing after 2m46s
CI Code / Code Coverage (pull_request) Failing after 5m17s
CI Code / Linux (debian) (pull_request) Failing after 6m3s
CI Code / Linux (arch) (pull_request) Failing after 7m21s
Some checks failed
CI Code / Check coding style (pull_request) Successful in 47s
CI Code / Check spelling (pull_request) Successful in 55s
CI Code / Linux (ubuntu) (pull_request) Failing after 2m46s
CI Code / Code Coverage (pull_request) Failing after 5m17s
CI Code / Linux (debian) (pull_request) Failing after 6m3s
CI Code / Linux (arch) (pull_request) Failing after 7m21s
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
This commit is contained in:
@@ -276,6 +276,7 @@ static Autocomplete logging_group_ac;
|
|||||||
static Autocomplete privacy_ac;
|
static Autocomplete privacy_ac;
|
||||||
static Autocomplete privacy_log_ac;
|
static Autocomplete privacy_log_ac;
|
||||||
static Autocomplete history_ac;
|
static Autocomplete history_ac;
|
||||||
|
static Autocomplete history_switch_ac;
|
||||||
static Autocomplete color_ac;
|
static Autocomplete color_ac;
|
||||||
static Autocomplete correction_ac;
|
static Autocomplete correction_ac;
|
||||||
static Autocomplete avatar_ac;
|
static Autocomplete avatar_ac;
|
||||||
@@ -431,6 +432,7 @@ static Autocomplete* all_acs[] = {
|
|||||||
&privacy_ac,
|
&privacy_ac,
|
||||||
&privacy_log_ac,
|
&privacy_log_ac,
|
||||||
&history_ac,
|
&history_ac,
|
||||||
|
&history_switch_ac,
|
||||||
&color_ac,
|
&color_ac,
|
||||||
&correction_ac,
|
&correction_ac,
|
||||||
&avatar_ac,
|
&avatar_ac,
|
||||||
@@ -1144,10 +1146,14 @@ cmd_ac_init(void)
|
|||||||
|
|
||||||
autocomplete_add(history_ac, "on");
|
autocomplete_add(history_ac, "on");
|
||||||
autocomplete_add(history_ac, "off");
|
autocomplete_add(history_ac, "off");
|
||||||
|
autocomplete_add(history_ac, "switch");
|
||||||
autocomplete_add(history_ac, "verify");
|
autocomplete_add(history_ac, "verify");
|
||||||
autocomplete_add(history_ac, "export");
|
autocomplete_add(history_ac, "export");
|
||||||
autocomplete_add(history_ac, "import");
|
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, "on");
|
||||||
autocomplete_add(logging_group_ac, "off");
|
autocomplete_add(logging_group_ac, "off");
|
||||||
autocomplete_add(logging_group_ac, "color");
|
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);
|
result = autocomplete_param_with_ac(input, "/history", history_ac, TRUE, previous);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -1882,17 +1882,20 @@ static const struct cmd_t command_defs[] = {
|
|||||||
CMD_TAG_CHAT)
|
CMD_TAG_CHAT)
|
||||||
CMD_SYN(
|
CMD_SYN(
|
||||||
"/history on|off",
|
"/history on|off",
|
||||||
|
"/history switch sqlite|flatfile",
|
||||||
"/history verify [<jid>]",
|
"/history verify [<jid>]",
|
||||||
"/history export [<jid>]",
|
"/history export [<jid>]",
|
||||||
"/history import [<jid>]")
|
"/history import [<jid>]")
|
||||||
CMD_DESC(
|
CMD_DESC(
|
||||||
"Switch chat history on or off, /logging chat will automatically be enabled when this setting is on. "
|
"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. "
|
"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 '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. "
|
"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).")
|
"Both export and import merge with existing data (duplicates are skipped).")
|
||||||
CMD_ARGS(
|
CMD_ARGS(
|
||||||
{ "on|off", "Enable or disable showing chat history." },
|
{ "on|off", "Enable or disable showing chat history." },
|
||||||
|
{ "switch sqlite|flatfile", "Switch the active database backend at runtime." },
|
||||||
{ "verify [<jid>]", "Verify integrity of message history. Optionally specify a JID to check only one contact." },
|
{ "verify [<jid>]", "Verify integrity of message history. Optionally specify a JID to check only one contact." },
|
||||||
{ "export [<jid>]", "Export SQLite history to flat-file format. Optionally specify a JID to export only one contact." },
|
{ "export [<jid>]", "Export SQLite history to flat-file format. Optionally specify a JID to export only one contact." },
|
||||||
{ "import [<jid>]", "Import flat-file history into SQLite. Optionally specify a JID to import only one contact." })
|
{ "import [<jid>]", "Import flat-file history into SQLite. Optionally specify a JID to import only one contact." })
|
||||||
|
|||||||
@@ -6735,6 +6735,37 @@ cmd_history(ProfWin* window, const char* const command, gchar** args)
|
|||||||
return TRUE;
|
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) {
|
if (g_strcmp0(args[0], "verify") == 0) {
|
||||||
const gchar* contact_jid = args[1]; // may be NULL (verify all)
|
const gchar* contact_jid = args[1]; // may be NULL (verify all)
|
||||||
cons_show("Verifying history integrity...");
|
cons_show("Verifying history integrity...");
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "config/preferences.h"
|
#include "config/preferences.h"
|
||||||
|
#include "config/accounts.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#include "xmpp/xmpp.h"
|
#include "xmpp/xmpp.h"
|
||||||
#include "xmpp/message.h"
|
#include "xmpp/message.h"
|
||||||
@@ -96,6 +97,34 @@ log_database_close(void)
|
|||||||
active_db_backend = NULL;
|
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
|
void
|
||||||
log_database_add_incoming(ProfMessage* message)
|
log_database_add_incoming(ProfMessage* message)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ db_backend_t* db_backend_flatfile(void);
|
|||||||
|
|
||||||
// Public API (dispatches to active_db_backend)
|
// Public API (dispatches to active_db_backend)
|
||||||
gboolean log_database_init(ProfAccount* account);
|
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_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_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);
|
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user