From add2e1ca0c77a12217ac50672536250e51b8f665 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Sat, 8 May 2021 17:38:55 +0800 Subject: [PATCH] Relation with Fruit --- examples/bakery.sql | 11 ++++++- src/query/result.rs | 11 +++++++ src/query/select.rs | 14 ++++----- src/tests_cfg/cake.rs | 13 +++++++-- src/tests_cfg/fruit.rs | 65 ++++++++++++++++++++++++++++++++++++++++++ src/tests_cfg/mod.rs | 1 + 6 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 src/tests_cfg/fruit.rs diff --git a/examples/bakery.sql b/examples/bakery.sql index 97988223..54206992 100644 --- a/examples/bakery.sql +++ b/examples/bakery.sql @@ -4,4 +4,13 @@ CREATE TABLE `cake` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +DROP TABLE IF EXISTS `fruit`; + +CREATE TABLE `fruit` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `cake_id` int, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/query/result.rs b/src/query/result.rs index 39fc8b30..c9c9d112 100644 --- a/src/query/result.rs +++ b/src/query/result.rs @@ -53,6 +53,17 @@ impl QueryResult { { T::try_get(self, col) } + + pub fn try_get_option(&self, col: &str) -> Result, TypeErr> + where + T: TryGetable, + { + if let Ok(v) = T::try_get(self, col) { + Ok(Some(v)) + } else { + Ok(None) + } + } } // TypeErr // diff --git a/src/query/select.rs b/src/query/select.rs index c844238c..6b2686d0 100644 --- a/src/query/select.rs +++ b/src/query/select.rs @@ -69,16 +69,16 @@ where self } - pub fn left_join(self, relation: RelationDef) -> Self { - self.prepare_join(JoinType::LeftJoin, relation) + pub fn left_join(self, rel: E::Relation) -> Self { + self.prepare_join(JoinType::LeftJoin, E::Relation::rel_def(&rel)) } - pub fn right_join(self, relation: RelationDef) -> Self { - self.prepare_join(JoinType::RightJoin, relation) + pub fn right_join(self, rel: E::Relation) -> Self { + self.prepare_join(JoinType::RightJoin, E::Relation::rel_def(&rel)) } - pub fn inner_join(self, relation: RelationDef) -> Self { - self.prepare_join(JoinType::InnerJoin, relation) + pub fn inner_join(self, rel: E::Relation) -> Self { + self.prepare_join(JoinType::InnerJoin, E::Relation::rel_def(&rel)) } pub fn query(&mut self) -> &mut SelectStatement { @@ -103,7 +103,7 @@ where #[cfg(test)] mod tests { - use crate::tests_cfg::cake; + use crate::tests_cfg::{cake, fruit}; use crate::{ColumnTrait, EntityTrait}; use sea_query::MysqlQueryBuilder; diff --git a/src/tests_cfg/cake.rs b/src/tests_cfg/cake.rs index 41b58116..cd6d74dd 100644 --- a/src/tests_cfg/cake.rs +++ b/src/tests_cfg/cake.rs @@ -1,6 +1,6 @@ use crate::{ ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, Identity, IntoIdentity, ModelTrait, - QueryResult, RelationDef, RelationTrait, TypeErr, + QueryResult, RelationBuilder, RelationDef, RelationTrait, TypeErr, }; #[derive(Default, Debug, Iden)] @@ -20,7 +20,9 @@ pub enum Column { } #[derive(Copy, Clone, EnumIter)] -pub enum Relation {} +pub enum Relation { + Fruit, +} impl EntityTrait for Entity { type Model = Model; @@ -56,6 +58,11 @@ impl ColumnTrait for Column { impl RelationTrait for Relation { fn rel_def(&self) -> RelationDef { - panic!() + match self { + Self::Fruit => RelationBuilder::has_many(super::fruit::Entity) + .from(Column::Id) + .to(super::fruit::Column::CakeId) + .into(), + } } } diff --git a/src/tests_cfg/fruit.rs b/src/tests_cfg/fruit.rs new file mode 100644 index 00000000..9953fe77 --- /dev/null +++ b/src/tests_cfg/fruit.rs @@ -0,0 +1,65 @@ +use crate::{ + ColumnTrait, ColumnType, EntityTrait, EnumIter, Iden, Identity, IntoIdentity, ModelTrait, + QueryResult, RelationDef, RelationTrait, TypeErr, +}; + +#[derive(Default, Debug, Iden)] +#[iden = "fruit"] +pub struct Entity; + +#[derive(Debug, Default, PartialEq)] +pub struct Model { + pub id: i32, + pub name: String, + pub cake_id: Option, +} + +#[derive(Copy, Clone, Iden, EnumIter)] +pub enum Column { + Id, + Name, + CakeId, +} + +#[derive(Copy, Clone, EnumIter)] +pub enum Relation {} + +impl EntityTrait for Entity { + type Model = Model; + + type Column = Column; + + type Relation = Relation; + + fn primary_key() -> Identity { + Column::Id.into_identity() + } +} + +impl ModelTrait for Model { + fn from_query_result(row: QueryResult) -> Result { + Ok(Self { + id: row.try_get("id")?, + name: row.try_get("name")?, + cake_id: row.try_get_option("cake_id")?, + }) + } +} + +impl ColumnTrait for Column { + type Entity = Entity; + + fn col_type(&self) -> ColumnType { + match self { + Self::Id => ColumnType::Integer(None), + Self::Name => ColumnType::String(None), + Self::CakeId => ColumnType::Integer(None), + } + } +} + +impl RelationTrait for Relation { + fn rel_def(&self) -> RelationDef { + panic!() + } +} diff --git a/src/tests_cfg/mod.rs b/src/tests_cfg/mod.rs index 5fd53bef..d0eefde2 100644 --- a/src/tests_cfg/mod.rs +++ b/src/tests_cfg/mod.rs @@ -1 +1,2 @@ pub mod cake; +pub mod fruit;