aboutsummaryrefslogtreecommitdiff
path: root/src/main/rust/store
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/rust/store')
-rw-r--r--src/main/rust/store/mod.rs58
-rw-r--r--src/main/rust/store/sqlite.rs199
2 files changed, 0 insertions, 257 deletions
diff --git a/src/main/rust/store/mod.rs b/src/main/rust/store/mod.rs
deleted file mode 100644
index 2cce3e9..0000000
--- a/src/main/rust/store/mod.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-mod sqlite;
-
-use crate::store::sqlite::SQLiteStore;
-use miette::{Diagnostic, Result};
-use thiserror::Error;
-
-pub enum Context {
- SQLite(SQLiteStore),
-}
-
-#[derive(Debug, Diagnostic, Error)]
-pub enum ContextError {
- #[error("Data storage error")]
- DataError(#[from] ::sqlite::Error),
- #[error("Int conversion error")]
- ConversionError(#[from] std::num::TryFromIntError),
-}
-
-impl Default for Context {
- fn default() -> Self {
- Context::SQLite(SQLiteStore::default())
- }
-}
-
-pub trait Store {
- fn init(&mut self) -> Result<(), ContextError>;
- fn get_counter(&self) -> Result<u8, ContextError>;
- fn set_counter(&mut self, new_count: u8) -> Result<u8, ContextError>;
-}
-
-impl Context {
- pub fn unwrap_store(&mut self) -> &mut impl Store {
- match self {
- Context::SQLite(store) => store,
- }
- }
-
- pub fn get_store(&self) -> &impl Store {
- match self {
- Context::SQLite(store) => store,
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn context_default() {
- let context = Context::default();
-
- let res = match context {
- Context::SQLite(_) => true,
- };
- assert!(res);
- }
-}
diff --git a/src/main/rust/store/sqlite.rs b/src/main/rust/store/sqlite.rs
deleted file mode 100644
index 6647556..0000000
--- a/src/main/rust/store/sqlite.rs
+++ /dev/null
@@ -1,199 +0,0 @@
-use crate::store::{ContextError, Store};
-use miette::Result;
-use sqlite::Connection;
-
-pub struct SQLiteStore {
- location: String,
- connection: Option<Connection>,
-}
-
-impl SQLiteStore {
- /// Wrap connection in a Result to make it easier to unwrap later
- fn get_connection(&self) -> Result<&Connection, sqlite::Error> {
- match &self.connection {
- Some(conn) => Ok(conn),
- None => Err(sqlite::Error {
- code: None,
- message: Some("Uninitialized".into()),
- }),
- }
- }
-
- fn create_table(&mut self) -> Result<(), sqlite::Error> {
- let conn = self.get_connection()?;
- let mut statement = conn.prepare("CREATE TABLE RATAT ( COUNTER SMALLINT )")?;
- statement.next()?;
- Ok(())
- }
-
- fn insert_counter(&mut self, counter: i64) -> Result<(), sqlite::Error> {
- let conn = self.get_connection()?;
- let mut statement = conn.prepare("INSERT INTO RATAT ( COUNTER ) VALUES ( :counter )")?;
- statement.bind((":counter", counter))?;
- statement.next()?;
- Ok(())
- }
-
- fn select_counter(&self) -> Result<i64, sqlite::Error> {
- let conn = self.get_connection()?;
- let mut statement = conn.prepare("SELECT COUNTER FROM RATAT")?;
- statement.next()?;
- statement.read("COUNTER")
- }
-
- fn update_counter(&mut self, counter: i64) -> Result<(), sqlite::Error> {
- let conn = self.get_connection()?;
- let mut statement = conn.prepare("UPDATE RATAT SET COUNTER = :counter")?;
- statement.bind((":counter", counter))?;
- statement.next()?;
- Ok(())
- }
-}
-
-impl Default for SQLiteStore {
- fn default() -> Self {
- SQLiteStore {
- location: ":memory:".into(),
- connection: Option::None,
- }
- }
-}
-
-impl Store for SQLiteStore {
- /// Init SQLite for counting. Creates `RATAT` table with single row, with
- /// counter set to `0`
- fn init(&mut self) -> Result<(), ContextError> {
- let conn_path = self.location.clone();
- let conn = sqlite::open(conn_path)?;
- self.connection = Option::Some(conn);
-
- self.create_table()?;
- self.insert_counter(0)?;
-
- Ok(())
- }
-
- /// Selects counter from `RATAT` table. Since sqlite doesn't scrutinize the
- /// value and we have a more restricted datatype (i64 -> u8), we use
- /// `try_from` which may produce an error result.
- fn get_counter(&self) -> Result<u8, ContextError> {
- let result = self.select_counter()?;
-
- let count = u8::try_from(result)?;
- Ok(count)
- }
-
- /// Updates row with counter value on `RATAT` table
- fn set_counter(&mut self, new_count: u8) -> Result<u8, ContextError> {
- self.update_counter(i64::from(new_count))?;
-
- Ok(new_count)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- // Practically, the `Store` trait is what we interface with externally, and
- // provides the more general `Result` interface we want to work with so
- // that's what we test here
-
- #[test]
- fn default() {
- let context = SQLiteStore::default();
-
- assert_eq!(context.location, ":memory:");
- assert!(context.connection.is_none());
- }
-
- #[test]
- fn init() {
- let mut context = SQLiteStore::default();
-
- let res = context.init();
-
- assert!(res.is_ok());
- assert!(context.connection.is_some());
- }
-
- #[test]
- fn get_counter() {
- let mut context = SQLiteStore::default();
- assert!(context.init().is_ok());
-
- let res = context.get_counter();
-
- assert!(res.is_ok());
- assert_eq!(res.unwrap(), 0);
- }
-
- #[test]
- fn get_counter_error() {
- let context = SQLiteStore::default();
- // don't initialize
-
- let res = context.get_counter();
-
- assert!(res.is_err());
- }
-
- #[test]
- fn get_counter_outside_range() {
- let mut context = SQLiteStore::default();
- assert!(context.init().is_ok());
-
- let new_value = -1;
- if let Some(conn) = &context.connection {
- let mut statement = conn.prepare("UPDATE RATAT SET COUNTER = ?").unwrap();
- statement.bind((1, new_value)).unwrap();
- statement.next().unwrap();
- }
- let res = context.get_counter();
-
- assert!(res.is_err());
- }
-
- #[test]
- fn set_counter() {
- let mut context = SQLiteStore::default();
- assert!(context.init().is_ok());
-
- let expected = 240;
- let res = context.set_counter(expected);
-
- assert!(res.is_ok());
- assert_eq!(res.unwrap(), expected);
- }
-
- #[test]
- fn set_counter_error() {
- let mut context = SQLiteStore::default();
- // don't initialize
-
- let res = context.set_counter(1);
-
- assert!(res.is_err());
- }
-
- #[test]
- fn set_and_get() {
- let mut context = SQLiteStore::default();
- assert!(context.init().is_ok());
-
- let count_0 = context.get_counter().unwrap();
-
- assert_eq!(count_0, 0);
-
- let new_num = 244;
- let res = context.set_counter(new_num);
-
- assert!(res.is_ok());
- assert_eq!(res.unwrap(), new_num);
-
- let count_1 = context.get_counter().unwrap();
-
- assert_eq!(count_1, new_num);
- assert_ne!(count_0, count_1);
- }
-}