mirror of
https://github.com/eliasrenman/r-database.git
synced 2026-03-16 20:46:08 +01:00
feat: select processor
This commit is contained in:
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -2,10 +2,21 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "assert-json-diff"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "db"
|
name = "db"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"assert-json-diff",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
assert-json-diff = "2.0.2"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ pub mod index;
|
|||||||
pub mod relation;
|
pub mod relation;
|
||||||
pub mod row;
|
pub mod row;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
|
pub mod select_processor;
|
||||||
|
pub mod query_builder;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
@@ -37,14 +39,22 @@ impl Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_table(&mut self, name: String) -> Result<&mut Table, String> {
|
pub fn get_table(&self, name: String) -> Result<&Table, String> {
|
||||||
for table in self.tables.iter_mut() {
|
for table in self.tables.iter() {
|
||||||
if table.name == name {
|
if table.name == name {
|
||||||
return Ok(table);
|
return Ok(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err("Failed to find table".to_string())
|
Err("Failed to find table".to_string())
|
||||||
}
|
}
|
||||||
|
pub fn get_table_mut(&mut self, name: String) -> Result<&mut Table, String> {
|
||||||
|
for table in self.tables.iter_mut() {
|
||||||
|
if table.name == name {
|
||||||
|
return Ok(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err("Failed to find table".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_table_relation(
|
pub fn get_table_relation(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
3
src/database/query_builder.rs
Normal file
3
src/database/query_builder.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// select query builder
|
||||||
|
// where query builder
|
||||||
|
// Combine them
|
||||||
@@ -5,7 +5,7 @@ use serde_json::Value;
|
|||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct Relation {
|
pub struct Relation {
|
||||||
pub table_name: String,
|
pub table_name: String,
|
||||||
variation: String,
|
pub variation: String,
|
||||||
}
|
}
|
||||||
impl Relation {
|
impl Relation {
|
||||||
pub fn new(table_name: String, variation: String) -> Relation {
|
pub fn new(table_name: String, variation: String) -> Relation {
|
||||||
@@ -15,7 +15,7 @@ impl Relation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_foreign_row(&self, database: &mut Database, foreign_id: u64) -> Result<Row, String> {
|
pub fn get_foreign_row(&self, database: &Database, foreign_id: u64) -> Result<Row, String> {
|
||||||
// Find foreign table
|
// Find foreign table
|
||||||
let table = database.get_table(self.table_name.clone()).unwrap();
|
let table = database.get_table(self.table_name.clone()).unwrap();
|
||||||
// Get row from foreign table
|
// Get row from foreign table
|
||||||
@@ -43,10 +43,10 @@ impl OneToOne {
|
|||||||
self.foreign_id
|
self.foreign_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, table_name: String, database: &mut Database) -> Result<Row, String> {
|
pub fn get(&self, table_name: String, database: &Database) -> Result<Row, String> {
|
||||||
let relation_result: Result<&Relation, String> = {
|
let relation_result: Result<&Relation, String> = {
|
||||||
// Get table
|
// Get table
|
||||||
let table: &mut Table = match database.get_table(table_name) {
|
let table: &Table = match database.get_table(table_name) {
|
||||||
Ok(relation) => relation,
|
Ok(relation) => relation,
|
||||||
Err(error) => return Err(error),
|
Err(error) => return Err(error),
|
||||||
};
|
};
|
||||||
@@ -86,9 +86,9 @@ impl OneToMany {
|
|||||||
self.foreign_ids.clone()
|
self.foreign_ids.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, table_name: String, database: &mut Database) -> Result<Vec<Row>, String> {
|
pub fn get(&self, table_name: String, database: &Database) -> Result<Vec<Row>, String> {
|
||||||
let relation_result: Result<&Relation, String> = {
|
let relation_result: Result<&Relation, String> = {
|
||||||
let table: &mut Table = match database.get_table(table_name) {
|
let table: &Table = match database.get_table(table_name) {
|
||||||
Ok(relation) => relation,
|
Ok(relation) => relation,
|
||||||
Err(error) => return Err(error),
|
Err(error) => return Err(error),
|
||||||
};
|
};
|
||||||
@@ -111,4 +111,4 @@ impl OneToMany {
|
|||||||
pub fn from_value(value: Value) -> OneToMany {
|
pub fn from_value(value: Value) -> OneToMany {
|
||||||
serde_json::from_value(value).unwrap()
|
serde_json::from_value(value).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub type Row = HashMap<String, Value>;
|
pub type Row = HashMap<String, Value>;
|
||||||
79
src/database/select_processor.rs
Normal file
79
src/database/select_processor.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use std::{borrow::Borrow, collections::HashMap, str::FromStr};
|
||||||
|
|
||||||
|
use serde_json::{map::Values, Value, json};
|
||||||
|
|
||||||
|
use crate::database::relation::{OneToOne, OneToMany};
|
||||||
|
|
||||||
|
use super::{row::Row, table::Table, Database};
|
||||||
|
|
||||||
|
pub struct SelectProcessor {
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
{
|
||||||
|
select: [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"relation.*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
{
|
||||||
|
select: [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"relation.id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
impl SelectProcessor {
|
||||||
|
// recursively select relations
|
||||||
|
|
||||||
|
pub fn selector(database: &Database, table_name: &String, row: &Row, select: Vec<String>, mut output: HashMap<String,Value>) -> HashMap<String,Value> {
|
||||||
|
|
||||||
|
for value in select {
|
||||||
|
let key = value.to_string();
|
||||||
|
if(key.eq("*")) {
|
||||||
|
return row.clone();// recursive call
|
||||||
|
}
|
||||||
|
else if(key.contains(".")) {
|
||||||
|
let split: Vec<String> = key.split(".").map(|part| String::from_str(part).unwrap()).collect();
|
||||||
|
|
||||||
|
if(split.len() == 2 && split[1].eq("*")) {
|
||||||
|
let relation_rows = SelectProcessor::resolve_relation(database, table_name, row, &split[0]);
|
||||||
|
output.insert(split[0].clone(), json!(relation_rows));
|
||||||
|
}
|
||||||
|
// recursive call
|
||||||
|
} else {
|
||||||
|
let value = row.get(&key);
|
||||||
|
match value.is_some() {
|
||||||
|
true => output.insert(key, value.unwrap().to_owned()),
|
||||||
|
false => panic!("Failed to read key: {key} on table: {table_name}"),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_relation(database: &Database, table_name: &String, row: &Row, key: &String) -> Vec<Row> {
|
||||||
|
let table = database.get_table(table_name.clone()).unwrap();
|
||||||
|
|
||||||
|
println!("Attempting to find relation for '{key}' in table: '{table_name}'");
|
||||||
|
|
||||||
|
|
||||||
|
let value = row.get(key).unwrap();
|
||||||
|
let relation_name = match value.get("relation_name") {
|
||||||
|
Some(val) => String::from(val.as_str().unwrap()),
|
||||||
|
None => panic!("Value was not a valid relation")
|
||||||
|
};
|
||||||
|
let relation = table.get_relation(&relation_name).unwrap();
|
||||||
|
let relation_variation = relation.variation.as_str();
|
||||||
|
return match relation_variation {
|
||||||
|
"one_to_one" => vec![OneToOne::from_value(value.to_owned()).get(table_name.clone(), database).unwrap()],
|
||||||
|
"one_to_many" => OneToMany::from_value(value.to_owned()).get(table_name.clone(), database).unwrap(),
|
||||||
|
other => panic!("Unsupported relationship type: {other}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -115,11 +115,12 @@ impl Table {
|
|||||||
.clone());
|
.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_relation(&self, name: &String) -> Result<&Relation, String> {
|
pub fn get_relation(&self, column_name: &String) -> Result<&Relation, String> {
|
||||||
let relation = self.relations.get(name);
|
let relation = self.relations.get(column_name);
|
||||||
if relation.is_some() {
|
|
||||||
|
if !relation.is_none() {
|
||||||
return Ok(relation.unwrap());
|
return Ok(relation.unwrap());
|
||||||
}
|
}
|
||||||
Err("Failed to find relation".to_string())
|
Err(format!("Failed to find relation, '{column_name}'").to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ mod database_test;
|
|||||||
mod index_test;
|
mod index_test;
|
||||||
mod relation_test;
|
mod relation_test;
|
||||||
mod table_test;
|
mod table_test;
|
||||||
|
mod select_processor_test;
|
||||||
@@ -11,20 +11,20 @@ mod relation_test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_succed_one_to_one_relationship_found() {
|
fn should_succed_one_to_one_relationship_found() {
|
||||||
let cat_relations =
|
let cat_relations =
|
||||||
hashmap!["cat_food" => Relation::new("Food".to_string(), "one_to_one".to_string())];
|
hashmap!["cat_food" => Relation::new("Foods".to_string(), "one_to_one".to_string())];
|
||||||
let cat_table: Table = Table::new("Cats", "id", None, Some(cat_relations));
|
let cat_table: Table = Table::new("Cats", "id", None, Some(cat_relations));
|
||||||
|
|
||||||
let food_table: Table = Table::new("Food", "id", None, None);
|
let food_table: Table = Table::new("Foods", "id", None, None);
|
||||||
|
|
||||||
let mut database: Database = Database::new(vec![cat_table, food_table]);
|
let mut database: Database = Database::new(vec![cat_table, food_table]);
|
||||||
|
|
||||||
_ = database
|
_ = database
|
||||||
.get_table("Food".to_string())
|
.get_table_mut("Foods".to_string())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert_row(row!["id" => 123, "name" => "Dry Feed"]);
|
.insert_row(row!["id" => 123, "name" => "Dry Feed"]);
|
||||||
let _ = database.get_table("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "food" => OneToOne::new(123u64, "cat_food".to_string())]);
|
let _ = database.get_table_mut("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "food" => OneToOne::new(123u64, "cat_food".to_string())]);
|
||||||
|
|
||||||
let cat_table = database.get_table("Cats".to_string()).unwrap();
|
let cat_table = database.get_table_mut("Cats".to_string()).unwrap();
|
||||||
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
||||||
|
|
||||||
let cat_1_food = cat_1.get("food").unwrap();
|
let cat_1_food = cat_1.get("food").unwrap();
|
||||||
@@ -52,17 +52,17 @@ mod relation_test {
|
|||||||
fn should_fail_no_one_to_one_relation_found() {
|
fn should_fail_no_one_to_one_relation_found() {
|
||||||
let cat_table: Table = Table::new("Cats", "id", None, None);
|
let cat_table: Table = Table::new("Cats", "id", None, None);
|
||||||
|
|
||||||
let food_table: Table = Table::new("Food", "id", None, None);
|
let food_table: Table = Table::new("Foods", "id", None, None);
|
||||||
|
|
||||||
let mut database: Database = Database::new(vec![cat_table, food_table]);
|
let mut database: Database = Database::new(vec![cat_table, food_table]);
|
||||||
|
|
||||||
_ = database
|
_ = database
|
||||||
.get_table("Food".to_string())
|
.get_table_mut("Foods".to_string())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert_row(row!["id" => 123, "name" => "Dry Feed"]);
|
.insert_row(row!["id" => 123, "name" => "Dry Feed"]);
|
||||||
let _ = database.get_table("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "food" => OneToOne::new(123u64, "cat_food".to_string())]);
|
let _ = database.get_table_mut("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "food" => OneToOne::new(123u64, "cat_food".to_string())]);
|
||||||
|
|
||||||
let cat_table = database.get_table("Cats".to_string()).unwrap();
|
let cat_table = database.get_table_mut("Cats".to_string()).unwrap();
|
||||||
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
||||||
|
|
||||||
let cat_1_food = cat_1.get("food").unwrap();
|
let cat_1_food = cat_1.get("food").unwrap();
|
||||||
@@ -70,20 +70,20 @@ mod relation_test {
|
|||||||
let relation = OneToOne::from_value(cat_1_food.to_owned());
|
let relation = OneToOne::from_value(cat_1_food.to_owned());
|
||||||
assert_eq!(relation.get_id(), 123u64);
|
assert_eq!(relation.get_id(), 123u64);
|
||||||
|
|
||||||
let foreign_row = relation.get("Food".to_string(), database.borrow_mut());
|
let foreign_row = relation.get("Foods".to_string(), database.borrow_mut());
|
||||||
|
|
||||||
assert_eq!(foreign_row.is_err(), true);
|
assert_eq!(foreign_row.is_err(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_fail_no_table_found() {
|
fn should_fail_no_table_found() {
|
||||||
let cat_table: Table = Table::new("Cats", "id", None, None);
|
let cat_table: Table = Table::new("Cats", "id", None, None);
|
||||||
|
|
||||||
let mut database: Database = Database::new(vec![cat_table]);
|
let mut database: Database = Database::new(vec![cat_table]);
|
||||||
|
|
||||||
let _ = database.get_table("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "food" => OneToOne::new(123u64, "cat_food".to_string())]);
|
let _ = database.get_table_mut("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "food" => OneToOne::new(123u64, "cat_food".to_string())]);
|
||||||
|
|
||||||
let cat_table = database.get_table("Cats".to_string()).unwrap();
|
let cat_table = database.get_table_mut("Cats".to_string()).unwrap();
|
||||||
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
||||||
|
|
||||||
let cat_1_food = cat_1.get("food").unwrap();
|
let cat_1_food = cat_1.get("food").unwrap();
|
||||||
@@ -91,7 +91,7 @@ mod relation_test {
|
|||||||
let relation = OneToOne::from_value(cat_1_food.to_owned());
|
let relation = OneToOne::from_value(cat_1_food.to_owned());
|
||||||
assert_eq!(relation.get_id(), 123u64);
|
assert_eq!(relation.get_id(), 123u64);
|
||||||
|
|
||||||
let foreign_row = relation.get("Food".to_string(), database.borrow_mut());
|
let foreign_row = relation.get("Foods".to_string(), database.borrow_mut());
|
||||||
print!(
|
print!(
|
||||||
"Printing foreign row error {}\n",
|
"Printing foreign row error {}\n",
|
||||||
&foreign_row.unwrap_err().as_str()
|
&foreign_row.unwrap_err().as_str()
|
||||||
@@ -101,13 +101,13 @@ mod relation_test {
|
|||||||
fn should_fail_no_one_to_one_row_found() {
|
fn should_fail_no_one_to_one_row_found() {
|
||||||
let cat_table: Table = Table::new("Cats", "id", None, None);
|
let cat_table: Table = Table::new("Cats", "id", None, None);
|
||||||
|
|
||||||
let food_table: Table = Table::new("Food", "id", None, None);
|
let food_table: Table = Table::new("Foodss", "id", None, None);
|
||||||
|
|
||||||
let mut database: Database = Database::new(vec![cat_table, food_table]);
|
let mut database: Database = Database::new(vec![cat_table, food_table]);
|
||||||
|
|
||||||
let _ = database.get_table("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "food" => OneToOne::new(123u64, "cat_food".to_string())]);
|
let _ = database.get_table_mut("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "food" => OneToOne::new(123u64, "cat_food".to_string())]);
|
||||||
|
|
||||||
let cat_table = database.get_table("Cats".to_string()).unwrap();
|
let cat_table = database.get_table_mut("Cats".to_string()).unwrap();
|
||||||
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
||||||
|
|
||||||
let cat_1_food = cat_1.get("food").unwrap();
|
let cat_1_food = cat_1.get("food").unwrap();
|
||||||
@@ -126,22 +126,22 @@ mod relation_test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_succed_one_to_many_relationship_found() {
|
fn should_succed_one_to_many_relationship_found() {
|
||||||
let cat_relations =
|
let cat_relations =
|
||||||
hashmap!["cat_food" => Relation::new("Food".to_string(), "one_to_many".to_string())];
|
hashmap!["cat_food" => Relation::new("Foods".to_string(), "one_to_many".to_string())];
|
||||||
let cat_table: Table = Table::new("Cats", "id", None, Some(cat_relations));
|
let cat_table: Table = Table::new("Cats", "id", None, Some(cat_relations));
|
||||||
|
|
||||||
let food_table: Table = Table::new("Food", "id", None, None);
|
let food_table: Table = Table::new("Foods", "id", None, None);
|
||||||
|
|
||||||
let mut database: Database = Database::new(vec![cat_table, food_table]);
|
let mut database: Database = Database::new(vec![cat_table, food_table]);
|
||||||
|
|
||||||
_ = database
|
_ = database
|
||||||
.get_table("Food".to_string())
|
.get_table_mut("Foods".to_string())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert_row(row!["id" => 123, "name" => "Dry Feed"]);
|
.insert_row(row!["id" => 123, "name" => "Dry Feed"]);
|
||||||
_ = database
|
_ = database
|
||||||
.get_table("Food".to_string())
|
.get_table_mut("Foods".to_string())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert_row(row!["id" => 12, "name" => "Dry Feed"]);
|
.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 _ = database.get_table_mut("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_table = database.get_table("Cats".to_string()).unwrap();
|
||||||
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
||||||
|
|||||||
91
src/tests/select_processor_test.rs
Normal file
91
src/tests/select_processor_test.rs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
//hashmap!(["food" => Relation::new("food","one_to_one")])
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod select_processor_test {
|
||||||
|
use crate::database::{
|
||||||
|
relation::{OneToMany, Relation},
|
||||||
|
select_processor::SelectProcessor,
|
||||||
|
table::Table,
|
||||||
|
Database,
|
||||||
|
};
|
||||||
|
use assert_json_diff::assert_json_include;
|
||||||
|
use serde_json::json;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub fn initialize() -> Database {
|
||||||
|
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_mut("Food".to_string())
|
||||||
|
.unwrap()
|
||||||
|
.insert_row(row!["id" => 123, "name" => "Wet Feed"]);
|
||||||
|
_ = database
|
||||||
|
.get_table_mut("Food".to_string())
|
||||||
|
.unwrap()
|
||||||
|
.insert_row(row!["id" => 12, "name" => "Dry Feed"]);
|
||||||
|
_ = database.get_table_mut("Cats".to_string()).unwrap().insert_row(row!["id" => 1, "name" => "Ozzy", "breed" => "mixed", "foods" => OneToMany::new(vec![123u64,12u64], "cat_food".to_string())]);
|
||||||
|
|
||||||
|
return database;
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn should_succed_select_processor_one_level_resolved() {
|
||||||
|
let database = initialize();
|
||||||
|
|
||||||
|
let cat_table = database.get_table("Cats".to_string()).unwrap();
|
||||||
|
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
||||||
|
let select = vec!["id".to_string(), "name".to_string(), "foods.*".to_string()];
|
||||||
|
let output =
|
||||||
|
SelectProcessor::selector(&database, &cat_table.name, cat_1, select, HashMap::new());
|
||||||
|
assert_json_include!(
|
||||||
|
actual: &output,
|
||||||
|
expected:
|
||||||
|
&row!["id" => 1, "name" =>"Ozzy", "foods" =>
|
||||||
|
vec![
|
||||||
|
row!["id" => 123, "name" => "Wet Feed"],
|
||||||
|
row!["id" => 12, "name" => "Dry Feed"]
|
||||||
|
|
||||||
|
]]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn should_succed_select_processor_zero_level_resolved() {
|
||||||
|
let database = initialize();
|
||||||
|
|
||||||
|
let cat_table = database.get_table("Cats".to_string()).unwrap();
|
||||||
|
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
||||||
|
let select = vec!["id".to_string(), "name".to_string(), "breed".to_string()];
|
||||||
|
let output =
|
||||||
|
SelectProcessor::selector(&database, &cat_table.name, cat_1, select, HashMap::new());
|
||||||
|
assert_json_include!(
|
||||||
|
actual: &output,
|
||||||
|
expected: &row!["id" => 1, "name" =>"Ozzy", "breed" => "mixed"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn should_succed_select_processor_zero_level_asterix_resolved() {
|
||||||
|
let database = initialize();
|
||||||
|
|
||||||
|
let cat_table = database.get_table("Cats".to_string()).unwrap();
|
||||||
|
let cat_1 = cat_table.find_by_pk(1u64).unwrap();
|
||||||
|
let select = vec!["*".to_string()];
|
||||||
|
let output =
|
||||||
|
SelectProcessor::selector(&database, &cat_table.name, cat_1, select, HashMap::new());
|
||||||
|
|
||||||
|
assert_json_include!(
|
||||||
|
actual: &output,
|
||||||
|
expected:
|
||||||
|
&json!({"id": 1, "name":"Ozzy", "breed": "mixed", "foods":
|
||||||
|
{
|
||||||
|
"relation_name": "cat_food",
|
||||||
|
"foreign_ids": [123,12]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user