mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-02-11 09:23:26 +00:00
74 lines
2.1 KiB
Rust
74 lines
2.1 KiB
Rust
//! SQLite storage backend.
|
|
|
|
use rusqlite::Connection;
|
|
use std::path::Path;
|
|
|
|
use crate::StorageError;
|
|
|
|
/// Configuration for SQLite storage.
|
|
#[derive(Debug, Clone)]
|
|
pub enum StorageConfig {
|
|
/// In-memory database (for testing).
|
|
InMemory,
|
|
/// File-based SQLite database.
|
|
File(String),
|
|
/// SQLCipher encrypted database.
|
|
Encrypted { path: String, key: String },
|
|
}
|
|
|
|
/// SQLite database wrapper.
|
|
///
|
|
/// This provides the core database connection and can be shared
|
|
/// across different domain-specific storage implementations.
|
|
pub struct SqliteDb {
|
|
conn: Connection,
|
|
}
|
|
|
|
impl SqliteDb {
|
|
/// Creates a new SQLite database with the given configuration.
|
|
pub fn new(config: StorageConfig) -> Result<Self, StorageError> {
|
|
let conn = match config {
|
|
StorageConfig::InMemory => Connection::open_in_memory()?,
|
|
StorageConfig::File(ref path) => Connection::open(path)?,
|
|
StorageConfig::Encrypted { ref path, ref key } => {
|
|
let conn = Connection::open(path)?;
|
|
conn.pragma_update(None, "key", key)?;
|
|
conn
|
|
}
|
|
};
|
|
|
|
// Enable foreign keys
|
|
conn.execute_batch("PRAGMA foreign_keys = ON;")?;
|
|
|
|
Ok(Self { conn })
|
|
}
|
|
|
|
/// Opens an existing database file.
|
|
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, StorageError> {
|
|
let conn = Connection::open(path)?;
|
|
conn.execute_batch("PRAGMA foreign_keys = ON;")?;
|
|
Ok(Self { conn })
|
|
}
|
|
|
|
/// Creates an in-memory database (useful for testing).
|
|
pub fn in_memory() -> Result<Self, StorageError> {
|
|
Self::new(StorageConfig::InMemory)
|
|
}
|
|
|
|
pub fn sqlcipher(path: String, key: String) -> Result<Self, StorageError> {
|
|
Self::new(StorageConfig::Encrypted { path, key })
|
|
}
|
|
|
|
/// Returns a reference to the underlying connection.
|
|
///
|
|
/// Use this for domain-specific storage operations.
|
|
pub fn connection(&self) -> &Connection {
|
|
&self.conn
|
|
}
|
|
|
|
/// Begins a transaction.
|
|
pub fn transaction(&mut self) -> Result<rusqlite::Transaction<'_>, StorageError> {
|
|
Ok(self.conn.transaction()?)
|
|
}
|
|
}
|