/* * database.h * vim: expandtab:ts=4:sts=4:sw=4 * * Copyright (C) 2020 - 2026 Michael Vetter * * SPDX-License-Identifier: GPL-3.0-or-later WITH OpenSSL-exception */ #ifndef DATABASE_H #define DATABASE_H #include #include "config/account.h" #include "xmpp/xmpp.h" #define MESSAGES_TO_RETRIEVE 100 typedef enum { DB_RESPONSE_ERROR, DB_RESPONSE_EMPTY, DB_RESPONSE_SUCCESS } db_history_result_t; // Integrity verification issue levels typedef enum { INTEGRITY_ERROR, INTEGRITY_WARNING, INTEGRITY_INFO } integrity_level_t; // A single integrity issue found during verification typedef struct { integrity_level_t level; char* file; int line; char* message; } integrity_issue_t; void integrity_issue_free(integrity_issue_t* issue); // Backend vtable: pluggable storage backends implement this interface typedef struct db_backend_t { const char* name; gboolean (*init)(ProfAccount* account); void (*close)(void); void (*add_incoming)(ProfMessage* message); void (*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 (*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 (*add_outgoing_muc_pm)(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); db_history_result_t (*get_previous_chat)(const gchar* const contact_barejid, const gchar* start_time, const gchar* end_time, gboolean from_start, gboolean flip, GSList** result); ProfMessage* (*get_limits_info)(const gchar* const contact_barejid, gboolean is_last); GSList* (*verify_integrity)(const gchar* const contact_barejid); } db_backend_t; // Active backend (set during init based on PREF_DBLOG) extern db_backend_t* active_db_backend; // Backend registry #ifdef HAVE_SQLITE db_backend_t* db_backend_sqlite(void); GSList* db_sqlite_list_contacts(void); GSList* db_sqlite_get_all_chat(const gchar* const contact_barejid); 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); // 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); void log_database_add_outgoing_muc_pm(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); db_history_result_t log_database_get_previous_chat(const gchar* const contact_barejid, const gchar* start_time, const gchar* end_time, gboolean from_start, gboolean flip, GSList** result); ProfMessage* log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last); void log_database_close(void); GSList* log_database_verify_integrity(const gchar* const contact_barejid); // FALSE if no backend, or PREF_DBLOG is "off" / "redact". gboolean log_database_can_recover_messages(void); // Cross-backend export/import (requires HAVE_SQLITE) #ifdef HAVE_SQLITE int log_database_export_to_flatfile(const gchar* const contact_jid); int log_database_import_from_flatfile(const gchar* const contact_jid); #endif #endif // DATABASE_H