Files
escarmouche/src/util.rs
T
2023-03-09 14:04:12 -05:00

98 lines
2.6 KiB
Rust

use std::io;
use std::path::PathBuf;
use rusqlite::{Connection, OpenFlags};
#[derive(Debug)]
pub enum Error {
SqlError(rusqlite::Error),
InvalidDrawer(String),
InvalidAmount(String),
InvalidPayee(String),
DoubleSpendingError(String),
IOError(io::Error),
UserInputError(String),
FuckingError(String),
Testing(String),
}
pub type CustomResult<T, E = Error> = Result<T, E>;
#[derive(Clone)]
struct PathSQLiteConnectionCreator {
path: PathBuf,
}
impl PathSQLiteConnectionCreator {
fn connection(&self) -> CustomResult<Connection> {
Connection::open(&self.path).map_err(Error::SqlError)
}
fn readonly(&self) -> CustomResult<Connection> {
let flags = OpenFlags::SQLITE_OPEN_READ_ONLY;
Connection::open_with_flags(&self.path, flags).map_err(Error::SqlError)
}
}
#[derive(Clone)]
struct EphemeralSQLiteConnectionCreator {}
// todo: fix this horrible implementation. All connections
// must share the same data.
impl EphemeralSQLiteConnectionCreator {
fn connection(&self) -> CustomResult<Connection> {
Connection::open_in_memory().map_err(Error::SqlError)
}
fn readonly(&self) -> CustomResult<Connection> {
let flags = OpenFlags::SQLITE_OPEN_READ_ONLY;
Connection::open_in_memory_with_flags(flags).map_err(Error::SqlError)
}
}
#[derive(Clone)]
enum SQLiteConnectionCreator {
Path(PathSQLiteConnectionCreator),
Ephemeral(EphemeralSQLiteConnectionCreator),
}
#[derive(Clone)]
pub struct SQLiteConnectionFactory {
creator: SQLiteConnectionCreator,
}
impl SQLiteConnectionFactory {
pub fn new(path: PathBuf) -> SQLiteConnectionFactory {
SQLiteConnectionFactory {
creator: SQLiteConnectionCreator::Path(PathSQLiteConnectionCreator { path }),
}
}
pub fn in_memory() -> SQLiteConnectionFactory {
SQLiteConnectionFactory {
creator: SQLiteConnectionCreator::Ephemeral(EphemeralSQLiteConnectionCreator {}),
}
}
pub fn connection(&self) -> CustomResult<Connection> {
match &self.creator {
SQLiteConnectionCreator::Path(c) => c.connection(),
SQLiteConnectionCreator::Ephemeral(c) => c.connection(),
}
}
pub fn readonly(&self) -> CustomResult<Connection> {
match &self.creator {
SQLiteConnectionCreator::Path(c) => c.readonly(),
SQLiteConnectionCreator::Ephemeral(c) => c.readonly(),
}
}
pub fn path(&self) -> Option<PathBuf> {
match &self.creator {
SQLiteConnectionCreator::Path(c) => Some(c.path.clone()),
_ => None,
}
}
}