diff --git a/src/database/relation.rs b/src/database/relation.rs index 1c9b201..75c1ea7 100644 --- a/src/database/relation.rs +++ b/src/database/relation.rs @@ -68,3 +68,47 @@ impl OneToOne { serde_json::from_value(value).unwrap() } } + +#[derive(Serialize, Deserialize)] +pub struct OneToMany { + foreign_ids: Vec, + relation_name: String, +} +impl OneToMany { + pub fn new(foreign_ids: Vec, relation_name: String) -> OneToMany { + OneToMany { + foreign_ids, + relation_name + } + } + + pub fn get_ids(&self) -> Vec { + self.foreign_ids.clone() + } + + pub fn get(&self, table_name: String, database: &mut Database) -> Result, String> { + let relation_result: Result<&Relation, String> = { + let table: &mut Table = match database.get_table(table_name) { + Ok(relation) => relation, + Err(error) => return Err(error), + }; + + // Fetch the Relation + table.get_relation(&self.relation_name) + }; + + let relation: Relation = match relation_result { + Ok(relation) => relation.clone(), + Err(error) => return Err(error), + }; + + let rows = self.foreign_ids.iter().map(|id| { + relation.get_foreign_row(database, *id).unwrap() + }); + Ok(rows.collect()) + } + + pub fn from_value(value: Value) -> OneToMany { + serde_json::from_value(value).unwrap() + } +} \ No newline at end of file diff --git a/src/tests/relation_test.rs b/src/tests/relation_test.rs index bda2463..f704168 100644 --- a/src/tests/relation_test.rs +++ b/src/tests/relation_test.rs @@ -3,13 +3,13 @@ mod relation_test { use std::borrow::BorrowMut; use crate::database::{ - relation::{OneToOne, Relation}, + relation::{OneToOne, Relation, OneToMany}, table::Table, Database, }; #[test] - fn should_succed_relationship_found() { + fn should_succed_one_to_one_relationship_found() { let cat_relations = hashmap!["cat_food" => Relation::new("Food".to_string(), "one_to_one".to_string())]; let cat_table: Table = Table::new("Cats", "id", None, Some(cat_relations)); @@ -49,7 +49,7 @@ mod relation_test { } #[test] - fn should_fail_no_relation_found() { + fn should_fail_no_one_to_one_relation_found() { let cat_table: Table = Table::new("Cats", "id", None, None); let food_table: Table = Table::new("Food", "id", None, None); @@ -98,7 +98,7 @@ mod relation_test { ); } #[test] - fn should_fail_no_row_found() { + fn should_fail_no_one_to_one_row_found() { let cat_table: Table = Table::new("Cats", "id", None, None); let food_table: Table = Table::new("Food", "id", None, None); @@ -123,4 +123,47 @@ mod relation_test { } // Fail without table found, invalid relation // Fail row and table found but not row + #[test] + fn should_succed_one_to_many_relationship_found() { + let cat_relations = + hashmap!["cat_food" => Relation::new("Food".to_string(), "one_to_many".to_string())]; + let cat_table: Table = Table::new("Cats", "id", None, Some(cat_relations)); + + let food_table: Table = Table::new("Food", "id", None, None); + + let mut database: Database = Database::new(vec![cat_table, food_table]); + + _ = database + .get_table("Food".to_string()) + .unwrap() + .insert_row(row!["id" => 123, "name" => "Dry Feed"]); + _ = database + .get_table("Food".to_string()) + .unwrap() + .insert_row(row!["id" => 12, "name" => "Dry Feed"]); + let _ = database.get_table("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "foods" => OneToMany::new(vec![123u64,12u64], "cat_food".to_string())]); + + let cat_table = database.get_table("Cats".to_string()).unwrap(); + let cat_1 = cat_table.find_by_pk(1u64).unwrap(); + + let cat_1_food = cat_1.get("foods").unwrap(); + + let relation = OneToMany::from_value(cat_1_food.to_owned()); + assert_eq!(relation.get_ids(), vec![123u64, 12u64]); + + let foreign_row = relation.get("Cats".to_string(), database.borrow_mut()); + + assert_eq!(foreign_row.is_ok(), true); + + let foreign_rows_unwrapped = foreign_row.unwrap(); + + assert_eq!(foreign_rows_unwrapped.len(), 2); + for row in foreign_rows_unwrapped.into_iter() { + print!( + "Printing foreign row {}\n", + serde_json::to_string(&row).unwrap() + ); + }; + + } }