feat: oneToMany relation

This commit is contained in:
Elias Renman
2023-11-18 00:15:12 +01:00
parent 511df2438e
commit e94fcc36c4
2 changed files with 91 additions and 4 deletions

View File

@@ -68,3 +68,47 @@ impl OneToOne {
serde_json::from_value(value).unwrap()
}
}
#[derive(Serialize, Deserialize)]
pub struct OneToMany {
foreign_ids: Vec<u64>,
relation_name: String,
}
impl OneToMany {
pub fn new(foreign_ids: Vec<u64>, relation_name: String) -> OneToMany {
OneToMany {
foreign_ids,
relation_name
}
}
pub fn get_ids(&self) -> Vec<u64> {
self.foreign_ids.clone()
}
pub fn get(&self, table_name: String, database: &mut Database) -> Result<Vec<Row>, 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()
}
}

View File

@@ -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()
);
};
}
}