diff --git a/01.workspace/heave/src/fun/sqlite_build_params.rs b/01.workspace/heave/src/fun/sqlite_build_params.rs index 166af0b..fda3f1f 100644 --- a/01.workspace/heave/src/fun/sqlite_build_params.rs +++ b/01.workspace/heave/src/fun/sqlite_build_params.rs @@ -9,6 +9,7 @@ pub fn run<'a>(filter: &'a Filter) -> Result>, FailedTo> Condition::Bool(value) => params.push(Box::new(value)), Condition::SignedInt(value) => params.push(Box::new(value)), Condition::UnsignedInt(value) => params.push(Box::new(value)), + Condition::Text(value) => params.push(Box::new(value)), } } Ok(params) diff --git a/01.workspace/heave/src/fun/sqlite_build_statement.rs b/01.workspace/heave/src/fun/sqlite_build_statement.rs index 9add4c3..edc7b4c 100644 --- a/01.workspace/heave/src/fun/sqlite_build_statement.rs +++ b/01.workspace/heave/src/fun/sqlite_build_statement.rs @@ -41,6 +41,7 @@ pub fn run(filter: &Filter) -> Result { (Comparison::LesserOrEqual, Condition::SignedInt(_)) => { compose_fragment(name, "value_int", "<=", i + 1) } + (_, Condition::SignedInt(_)) => return Err(FailedTo::ComposeFilter), // UNSIGNED INT (Comparison::Equal, Condition::UnsignedInt(_)) => { compose_fragment(name, "value_uint", "=", i + 1) @@ -57,6 +58,11 @@ pub fn run(filter: &Filter) -> Result { (Comparison::LesserOrEqual, Condition::UnsignedInt(_)) => { compose_fragment(name, "value_uint", "<=", i + 1) } + (_, Condition::UnsignedInt(_)) => return Err(FailedTo::ComposeFilter), + // TEXT + (Comparison::IsExactly, Condition::Text(_)) => { + compose_fragment(name, "value_text", "=", i + 1) + } _ => todo!(), }; statement.push_str(&fragment); diff --git a/01.workspace/heave/src/str/catalog.rs b/01.workspace/heave/src/str/catalog.rs index b77557f..855a05a 100644 --- a/01.workspace/heave/src/str/catalog.rs +++ b/01.workspace/heave/src/str/catalog.rs @@ -2275,4 +2275,62 @@ mod tests { assert_eq!(catalog.items.len(), 3); std::fs::remove_file(path).unwrap(); } + #[test] + fn load_by_filter_should_load_text_is_exactly_comparisons() { + let db_path = "target/test_dbs/lbf_text_is_exactly_comparisons.db"; + let path = std::path::Path::new(db_path); + std::fs::create_dir_all(path.parent().unwrap()).unwrap(); + if path.exists() { + std::fs::remove_file(path).unwrap(); + } + let mut catalog_setup = Catalog::new(db_path); + catalog_setup.init().unwrap(); + let items = vec![ + Item { + id: "item-1".to_string(), + name: "Item One".to_string(), + price: 100, + sell_trend: 0, + in_stock: true, + }, + Item { + id: "item-2".to_string(), + name: "Item Two".to_string(), + price: 200, + sell_trend: 0, + in_stock: false, + }, + Item { + id: "item-3".to_string(), + name: "Another Item".to_string(), + price: 300, + sell_trend: 0, + in_stock: true, + }, + ]; + catalog_setup.insert_many(items).unwrap(); + catalog_setup.persist().unwrap(); + // Exact match + let mut catalog = Catalog::new(db_path); + let filter = Filter::new().with_text("name", Comparison::IsExactly, "Item One"); + assert!(catalog.load_by_filter(&filter).is_ok()); + assert_eq!(catalog.items.len(), 1); + assert!(catalog.items.contains_key("item-1")); + // Partial match should not work + let mut catalog = Catalog::new(db_path); + let filter = Filter::new().with_text("name", Comparison::IsExactly, "Item"); + assert!(catalog.load_by_filter(&filter).is_ok()); + assert!(catalog.items.is_empty()); + // Case sensitive match + let mut catalog = Catalog::new(db_path); + let filter = Filter::new().with_text("name", Comparison::IsExactly, "item one"); + assert!(catalog.load_by_filter(&filter).is_ok()); + assert!(catalog.items.is_empty()); + // No match + let mut catalog = Catalog::new(db_path); + let filter = Filter::new().with_text("name", Comparison::IsExactly, "Item Four"); + assert!(catalog.load_by_filter(&filter).is_ok()); + assert!(catalog.items.is_empty()); + std::fs::remove_file(path).unwrap(); + } } diff --git a/01.workspace/heave/src/str/condition.rs b/01.workspace/heave/src/str/condition.rs index 15ff996..bedde5e 100644 --- a/01.workspace/heave/src/str/condition.rs +++ b/01.workspace/heave/src/str/condition.rs @@ -1,6 +1,7 @@ #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)] -pub enum E { +pub enum E<'a> { Bool(bool), SignedInt(i64), UnsignedInt(i64), + Text(&'a str), } diff --git a/01.workspace/heave/src/str/filter.rs b/01.workspace/heave/src/str/filter.rs index a358cb9..43cc1a8 100644 --- a/01.workspace/heave/src/str/filter.rs +++ b/01.workspace/heave/src/str/filter.rs @@ -1,11 +1,11 @@ use crate::*; #[derive(Debug, Default, PartialEq, Clone)] -pub struct O { - conditions: Vec<(String, Comparison, Condition)>, +pub struct O<'a> { + conditions: Vec<(String, Comparison, Condition<'a>)>, } -impl Filter { +impl<'a> Filter<'a> { pub fn new() -> Self { Self { conditions: Vec::new(), @@ -45,7 +45,20 @@ impl Filter { )); self } - pub(crate) fn conditions(&self) -> impl Iterator { + pub fn with_text( + mut self, + attribute_name: &str, + comparison: Comparison, + value: &'a str, + ) -> Self { + self.conditions.push(( + attribute_name.to_string(), + comparison, + Condition::Text(value), + )); + self + } + pub(crate) fn conditions(&self) -> impl Iterator)> { self.conditions.iter() } }