You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

116 lines
4.4 KiB

#include "db_manager.h"
#include "../src/debug_ui.h"
DbManager::DbManager(const QString& path, QObject* parent)
: QObject(parent)
{
int rc = sqlite3_open(path.toUtf8().constData(), &m_db);
if (rc != SQLITE_OK) {
GUI_ERROR("Cannot open database: %s", sqlite3_errmsg(m_db));
sqlite3_close(m_db);
m_db = nullptr;
return;
}
sqlite3_exec(m_db, "PRAGMA journal_mode=WAL", nullptr, nullptr, nullptr);
initTables();
GUI_INFO("Database opened: %s", path.toUtf8().constData());
}
DbManager::~DbManager() {
if (m_db) {
sqlite3_close(m_db);
m_db = nullptr;
GUI_INFO("Database closed");
}
}
void DbManager::initTables() {
sqlite3_exec(m_db, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
const char* sql =
"CREATE TABLE IF NOT EXISTS local_identity ("
" id INTEGER PRIMARY KEY CHECK (id = 1),"
" node_id INTEGER NOT NULL UNIQUE,"
" name TEXT NOT NULL,"
" x25519_pubkey BLOB NOT NULL,"
" ed25519_pubkey BLOB,"
" created_at TEXT DEFAULT (datetime('now')),"
" updated_at TEXT DEFAULT (datetime('now'))"
");"
"CREATE TABLE IF NOT EXISTS nodes ("
" node_id INTEGER PRIMARY KEY,"
" name TEXT,"
" x25519_pubkey BLOB,"
" ed25519_pubkey BLOB,"
" hop_count INTEGER DEFAULT 0,"
" is_online INTEGER DEFAULT 0,"
" last_seen_ver INTEGER DEFAULT 0,"
" connectivity_json TEXT,"
" created_at TEXT DEFAULT (datetime('now')),"
" updated_at TEXT DEFAULT (datetime('now'))"
");"
"CREATE TABLE IF NOT EXISTS node_addresses ("
" id INTEGER PRIMARY KEY AUTOINCREMENT,"
" node_id INTEGER NOT NULL REFERENCES nodes(node_id) ON DELETE CASCADE,"
" family INTEGER NOT NULL DEFAULT 4,"
" ip BLOB NOT NULL,"
" port INTEGER NOT NULL,"
" addr_type INTEGER NOT NULL DEFAULT 0,"
" socket_type INTEGER DEFAULT 0,"
" priority INTEGER DEFAULT 0"
");"
"CREATE INDEX IF NOT EXISTS idx_node_addr_node ON node_addresses(node_id);"
"CREATE TABLE IF NOT EXISTS node_subnets ("
" id INTEGER PRIMARY KEY AUTOINCREMENT,"
" node_id INTEGER NOT NULL REFERENCES nodes(node_id) ON DELETE CASCADE,"
" family INTEGER NOT NULL DEFAULT 4,"
" network BLOB NOT NULL,"
" prefix_length INTEGER NOT NULL"
");"
"CREATE INDEX IF NOT EXISTS idx_subnet_node ON node_subnets(node_id);"
"CREATE TABLE IF NOT EXISTS channels ("
" id INTEGER PRIMARY KEY AUTOINCREMENT,"
" channel_id TEXT NOT NULL UNIQUE,"
" name TEXT NOT NULL,"
" member_ids_json TEXT NOT NULL,"
" is_dm INTEGER DEFAULT 0,"
" last_message TEXT,"
" last_msg_at TEXT,"
" created_at TEXT DEFAULT (datetime('now'))"
");"
"CREATE UNIQUE INDEX IF NOT EXISTS idx_channel_cid ON channels(channel_id);"
"CREATE TABLE IF NOT EXISTS messages ("
" id INTEGER PRIMARY KEY AUTOINCREMENT,"
" channel_id TEXT NOT NULL REFERENCES channels(channel_id) ON DELETE CASCADE,"
" author_node_id INTEGER NOT NULL,"
" content TEXT NOT NULL,"
" content_type TEXT DEFAULT 'text/plain',"
" timestamp INTEGER NOT NULL,"
" local_seq INTEGER DEFAULT 0,"
" signature BLOB,"
" is_outgoing INTEGER DEFAULT 0,"
" is_read INTEGER DEFAULT 0,"
" created_at TEXT DEFAULT (datetime('now'))"
");"
"CREATE INDEX IF NOT EXISTS idx_msg_channel_time ON messages(channel_id, timestamp);"
"CREATE INDEX IF NOT EXISTS idx_msg_author ON messages(author_node_id);"
"CREATE UNIQUE INDEX IF NOT EXISTS idx_msg_dedup ON messages(channel_id, author_node_id, timestamp);";
char* errMsg = nullptr;
int rc = sqlite3_exec(m_db, sql, nullptr, nullptr, &errMsg);
if (rc != SQLITE_OK) {
GUI_ERROR("Failed to create tables: %s", errMsg);
sqlite3_free(errMsg);
return;
}
GUI_INFO("Database tables initialized (6 tables, 6 indexes)");
}