diff options
| author | Kevin Hoerr <kjhoerr@submelon.dev> | 2026-04-16 11:37:21 -0400 |
|---|---|---|
| committer | Kevin Hoerr <kjhoerr@submelon.dev> | 2026-04-16 11:37:21 -0400 |
| commit | 615d44041d35ee1a08ddc66423f67a9d48f53ae9 (patch) | |
| tree | 9720d6a192e0bae9c7393b8b99ff8ae401ec7f72 /src/main/rust/store/sqlite.rs | |
| parent | 51623bc995c29937bb0a13d5b71ff908be8d1a1c (diff) | |
| download | equity-tracker-615d44041d35ee1a08ddc66423f67a9d48f53ae9.tar.gz equity-tracker-615d44041d35ee1a08ddc66423f67a9d48f53ae9.tar.bz2 equity-tracker-615d44041d35ee1a08ddc66423f67a9d48f53ae9.zip | |
Switch to distrobox as base for development
Diffstat (limited to 'src/main/rust/store/sqlite.rs')
| -rw-r--r-- | src/main/rust/store/sqlite.rs | 199 |
1 files changed, 0 insertions, 199 deletions
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); - } -} |
