Skip to content

Commit

Permalink
Migrate TCNs storage to Sqlite (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivnsch authored Jun 30, 2020
1 parent 90e7efa commit 46b1df8
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 110 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ name = "coepi_core"
crate-type = ["staticlib", "cdylib"]

[dependencies]
persy = "0.9"
once_cell = "1.3.1"
cbindgen = "0.9.0"
serde_json = "1.0"
Expand Down
21 changes: 9 additions & 12 deletions src/composition_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::reports_updater::{
};
use crate::{
errors::ServicesError,
expect_log, init_persy,
expect_log,
preferences::{Database, Preferences, PreferencesDao, PreferencesImpl},
reporting::{
memo::{MemoMapper, MemoMapperImpl},
Expand Down Expand Up @@ -65,11 +65,6 @@ pub static COMP_ROOT: OnceCell<
pub fn bootstrap(db_path: &str) -> Result<(), ServicesError> {
info!("Bootstrapping with db path: {:?}", db_path);

// TODO should be in a dependency
let persy_path = format!("{}/db.persy", db_path);
debug!("Persy path: {:?}", persy_path);
init_persy(persy_path).map_err(ServicesError::from)?;

let sqlite_path = format!("{}/db.sqlite", db_path);
debug!("Sqlite path: {:?}", sqlite_path);

Expand Down Expand Up @@ -98,7 +93,7 @@ pub fn dependencies() -> &'static CompositionRoot<
>,
>,
>,
ObservedTcnProcessorImpl<'static, TcnDaoImpl>,
ObservedTcnProcessorImpl<TcnDaoImpl>,
MemoMapperImpl,
TcnKeysImpl<PreferencesImpl>,
> {
Expand Down Expand Up @@ -129,7 +124,7 @@ fn create_comp_root(
>,
>,
>,
ObservedTcnProcessorImpl<'static, TcnDaoImpl>,
ObservedTcnProcessorImpl<TcnDaoImpl>,
MemoMapperImpl,
TcnKeysImpl<PreferencesImpl>,
> {
Expand All @@ -139,7 +134,7 @@ fn create_comp_root(
let connection = expect_log!(connection_res, "Couldn't create database!");
let database = Arc::new(Database::new(connection));

let preferences_dao = PreferencesDao::new(database);
let preferences_dao = PreferencesDao::new(database.clone());
let preferences = Arc::new(PreferencesImpl {
dao: preferences_dao,
});
Expand All @@ -156,13 +151,13 @@ fn create_comp_root(
api,
};

let tcn_dao = &TcnDaoImpl {};
let tcn_dao = Arc::new(TcnDaoImpl::new(database.clone()));

CompositionRoot {
api,
reports_updater: ReportsUpdater {
preferences: preferences.clone(),
tcn_dao,
tcn_dao: tcn_dao.clone(),
tcn_matcher: TcnMatcherRayon {},
api,
memo_mapper,
Expand All @@ -173,7 +168,9 @@ fn create_comp_root(
inputs_submitter: symptom_inputs_submitter,
},
},
observed_tcn_processor: ObservedTcnProcessorImpl { tcn_dao },
observed_tcn_processor: ObservedTcnProcessorImpl {
tcn_dao: tcn_dao.clone(),
},
tcn_keys: tcn_keys.clone(),
}
}
9 changes: 0 additions & 9 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,6 @@ impl From<serde_json::Error> for ServicesError {
}
}

impl From<persy::PersyError> for ServicesError {
fn from(error: persy::PersyError) -> Self {
ServicesError::Error(Box::new(StdError::new(
ErrorKind::Other,
format!("{}", error),
)))
}
}

impl From<hex::FromHexError> for ServicesError {
fn from(error: hex::FromHexError) -> Self {
ServicesError::Error(Box::new(StdError::new(
Expand Down
23 changes: 0 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#[macro_use]
extern crate serde_big_array;
use errors::Error;
use once_cell::sync::OnceCell;
use persy::{Config, Persy, ValueMode};
use std::path::Path;
mod composition_root;
mod errors;
mod networking;
Expand All @@ -22,26 +19,6 @@ mod android;

pub type Res<T> = Result<T, Error>;

const CENS_BY_TS: &str = "cens by ts";

pub fn init_persy<P: AsRef<Path>>(p: P) -> Res<()> {
let db = Persy::open_or_create_with(p, Config::new(), |db| {
let mut tx = db.begin()?;
tx.create_segment("tcn")?;
tx.create_index::<i64, u128>(CENS_BY_TS, ValueMode::CLUSTER)?;
tx.prepare_commit()?.commit()?;
Ok(())
})?;
DB.set(db).map_err(|_| DB_ALREADY_INIT)?;
Ok(())
}

const DB_ALREADY_INIT: &str = "DB failed to initalize";
pub const DB_UNINIT: &str = "DB not initialized";

// TODO since we're using DI put this in a dependency, to be consistent
pub static DB: OnceCell<Persy> = OnceCell::new();

// TODO refactor these (byte_vec_to) convertions or better way?

// TODO move to utils file or similar. Consider returning Result instead of panicking.
Expand Down
25 changes: 22 additions & 3 deletions src/preferences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ impl PreferencesDao {
fn create_table_if_not_exists(db: &Arc<Database>) {
let res = db.execute_sql(
"create table if not exists preferences(
key text primary key,
value text not null
)",
key text primary key,
value text not null
)",
params![],
);
expect_log!(res, "Couldn't create preferences table");
Expand All @@ -122,6 +122,25 @@ impl Database {
conn.execute(sql, pars)
}

pub fn query<T, P, F>(&self, sql: &str, params: P, f: F) -> Result<Vec<T>, rusqlite::Error>
where
P: IntoIterator,
P::Item: ToSql,
F: Fn(&Row<'_>) -> T,
{
let res = self.conn.lock();
let conn = expect_log!(res, "Couldn't lock mutex");

let mut statement = conn.prepare(sql)?;
let mut rows = statement.query(params)?;

let mut objs = Vec::new();
while let Some(row) = rows.next().unwrap() {
objs.push(f(row));
}
Ok(objs)
}

pub fn query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> Result<T, rusqlite::Error>
where
P: IntoIterator,
Expand Down
Loading

0 comments on commit 46b1df8

Please sign in to comment.