|
@@ -1,269 +0,0 @@
|
|
|
-use crate::{entity::EntityColumn, model::Modelable, Entity};
|
|
|
-
|
|
|
-use std::marker::PhantomData;
|
|
|
-
|
|
|
-pub trait BuildingBlock {
|
|
|
- fn build_query(&self) -> String {
|
|
|
- String::new()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-pub struct Builder {}
|
|
|
-
|
|
|
-impl Builder {
|
|
|
- pub fn get<T: Entity>() -> Select<T> {
|
|
|
- Select {
|
|
|
- _ghost: PhantomData,
|
|
|
- }
|
|
|
- }
|
|
|
- pub fn update<T: Entity>() -> Update<T> {
|
|
|
- Update {
|
|
|
- _ghost: PhantomData,
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-pub struct Select<T: Entity> {
|
|
|
- _ghost: PhantomData<T>,
|
|
|
-}
|
|
|
-
|
|
|
-pub trait Conditionable: BuildingBlock {
|
|
|
- type Table: Entity;
|
|
|
-
|
|
|
- fn with<G: Modelable, Col: EntityColumn<Entity = Self::Table>>(
|
|
|
- self,
|
|
|
- column: Col,
|
|
|
- _given: G,
|
|
|
- ) -> WhereClause<Self, Col, Self::Table, G>
|
|
|
- where
|
|
|
- Self: Sized,
|
|
|
- {
|
|
|
- WhereClause {
|
|
|
- conditionable: self,
|
|
|
- column,
|
|
|
- _ghost: PhantomData,
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<T: Entity> Conditionable for Select<T> {
|
|
|
- type Table = T;
|
|
|
-}
|
|
|
-
|
|
|
-pub struct WhereClause<
|
|
|
- S: Conditionable<Table = T>,
|
|
|
- Col: EntityColumn<Entity = T>,
|
|
|
- T: Entity,
|
|
|
- Given: Modelable,
|
|
|
-> {
|
|
|
- conditionable: S,
|
|
|
- column: Col,
|
|
|
- _ghost: PhantomData<(S, Col, Given)>,
|
|
|
-}
|
|
|
-
|
|
|
-impl<S: Conditionable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable>
|
|
|
- Conditionable for WhereClause<S, Col, T, Given>
|
|
|
-{
|
|
|
- type Table = T;
|
|
|
-}
|
|
|
-
|
|
|
-pub trait Joinable: BuildingBlock {
|
|
|
- type Table: Entity;
|
|
|
-
|
|
|
- fn join<
|
|
|
- BaseColumn: EntityColumn<Entity = Self::Table>,
|
|
|
- Target: Entity,
|
|
|
- TargetColumn: EntityColumn<Entity = Target>,
|
|
|
- >(
|
|
|
- self,
|
|
|
- base_column: BaseColumn,
|
|
|
- target_column: TargetColumn,
|
|
|
- ) -> JoinClause<Self::Table, Self, BaseColumn, Target, TargetColumn>
|
|
|
- where
|
|
|
- Self: Sized,
|
|
|
- {
|
|
|
- JoinClause {
|
|
|
- joinable: self,
|
|
|
- base_column,
|
|
|
- target_column,
|
|
|
- _ghost: PhantomData,
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-pub struct JoinClause<
|
|
|
- T: Entity,
|
|
|
- Base: Joinable<Table = T>,
|
|
|
- BaseColumn: EntityColumn<Entity = T>,
|
|
|
- Target: Entity,
|
|
|
- TargetColumn: EntityColumn<Entity = Target>,
|
|
|
-> {
|
|
|
- joinable: Base,
|
|
|
- base_column: BaseColumn,
|
|
|
- target_column: TargetColumn,
|
|
|
- _ghost: PhantomData<(Base, BaseColumn, Target, TargetColumn)>,
|
|
|
-}
|
|
|
-
|
|
|
-impl<T: Entity> Joinable for Select<T> {
|
|
|
- type Table = T;
|
|
|
-}
|
|
|
-
|
|
|
-impl<
|
|
|
- S: Joinable + Conditionable<Table = T>,
|
|
|
- T: Entity,
|
|
|
- Col: EntityColumn<Entity = T>,
|
|
|
- Given: Modelable,
|
|
|
- > Joinable for WhereClause<S, Col, T, Given>
|
|
|
-{
|
|
|
- type Table = T;
|
|
|
-}
|
|
|
-
|
|
|
-pub struct Update<T: Entity> {
|
|
|
- _ghost: PhantomData<T>,
|
|
|
-}
|
|
|
-
|
|
|
-impl<T: Entity> Conditionable for Update<T> {
|
|
|
- type Table = T;
|
|
|
-}
|
|
|
-
|
|
|
-impl<T: Entity> Settable for Update<T> {
|
|
|
- type Table = T;
|
|
|
-}
|
|
|
-
|
|
|
-pub trait Settable {
|
|
|
- type Table: Entity;
|
|
|
-
|
|
|
- fn update<G: Modelable, Col: EntityColumn<Entity = Self::Table>>(
|
|
|
- self,
|
|
|
- column: Col,
|
|
|
- _given: G,
|
|
|
- ) -> SetClause<Self, Col, Self::Table, G>
|
|
|
- where
|
|
|
- Self: Sized,
|
|
|
- {
|
|
|
- SetClause {
|
|
|
- settable: self,
|
|
|
- column,
|
|
|
- _ghost: (PhantomData, PhantomData, PhantomData),
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-pub struct SetClause<
|
|
|
- S: Settable<Table = T>,
|
|
|
- Col: EntityColumn<Entity = T>,
|
|
|
- T: Entity,
|
|
|
- Given: Modelable,
|
|
|
-> {
|
|
|
- settable: S,
|
|
|
- column: Col,
|
|
|
- _ghost: (PhantomData<S>, PhantomData<Col>, PhantomData<Given>),
|
|
|
-}
|
|
|
-
|
|
|
-impl<S: Settable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable>
|
|
|
- Conditionable for SetClause<S, Col, T, Given>
|
|
|
-{
|
|
|
- type Table = T;
|
|
|
-}
|
|
|
-
|
|
|
-// BuildingBlock implementations
|
|
|
-impl<T: Entity> BuildingBlock for Select<T> {
|
|
|
- fn build_query(&self) -> String {
|
|
|
- format!("SELECT * FROM {} WHERE true", T::table_name())
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<S: Conditionable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable>
|
|
|
- BuildingBlock for WhereClause<S, Col, T, Given>
|
|
|
-{
|
|
|
- fn build_query(&self) -> String {
|
|
|
- format!(
|
|
|
- "{} AND {} = ?",
|
|
|
- self.conditionable.build_query(),
|
|
|
- self.column.name()
|
|
|
- )
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<
|
|
|
- T: Entity,
|
|
|
- Base: Joinable<Table = T>,
|
|
|
- BaseColumn: EntityColumn<Entity = T>,
|
|
|
- Target: Entity,
|
|
|
- TargetColumn: EntityColumn<Entity = Target>,
|
|
|
- > BuildingBlock for JoinClause<T, Base, BaseColumn, Target, TargetColumn>
|
|
|
-{
|
|
|
- fn build_query(&self) -> String {
|
|
|
- format!(
|
|
|
- "{} JOIN {} ON {}.{} = {}.{}",
|
|
|
- self.joinable.build_query(),
|
|
|
- self.target_column.table_name(),
|
|
|
- self.base_column.table_name(),
|
|
|
- self.base_column.name(),
|
|
|
- self.target_column.table_name(),
|
|
|
- self.target_column.name()
|
|
|
- )
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<T: Entity> BuildingBlock for Update<T> {
|
|
|
- fn build_query(&self) -> String {
|
|
|
- format!("update?")
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl<S: Settable<Table = T>, Col: EntityColumn<Entity = T>, T: Entity, Given: Modelable>
|
|
|
- BuildingBlock for SetClause<S, Col, T, Given>
|
|
|
-{
|
|
|
- fn build_query(&self) -> String {
|
|
|
- //format!("UPDATE {} SET {} = ? WHERE true", T::table_name(), self.column.name())
|
|
|
- format!("<>")
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#[cfg(test)]
|
|
|
-mod builder_test {
|
|
|
- use super::*;
|
|
|
-
|
|
|
- #[derive(crate::Entity, serde::Deserialize, serde::Serialize)]
|
|
|
- #[microrm_internal]
|
|
|
- pub struct SimpleEntity {
|
|
|
- a: usize,
|
|
|
- b: usize,
|
|
|
- }
|
|
|
-
|
|
|
- #[derive(crate::Entity, serde::Deserialize, serde::Serialize)]
|
|
|
- #[microrm_internal]
|
|
|
- pub struct ChildType {
|
|
|
- r: SimpleEntityID,
|
|
|
- b: usize,
|
|
|
- }
|
|
|
-
|
|
|
- #[test]
|
|
|
- fn simple_builder_select_test() {
|
|
|
- println!("{}", Builder::get::<SimpleEntity>().build_query());
|
|
|
- println!(
|
|
|
- "{}",
|
|
|
- Builder::get::<SimpleEntity>()
|
|
|
- .with(SimpleEntity::A, 0u8)
|
|
|
- .with(SimpleEntity::B, 1u8)
|
|
|
- .build_query()
|
|
|
- );
|
|
|
-
|
|
|
- println!(
|
|
|
- "{}",
|
|
|
- Builder::get::<SimpleEntity>()
|
|
|
- .with(SimpleEntity::A, 0u8)
|
|
|
- .join(SimpleEntity::ID, ChildType::R)
|
|
|
- .build_query()
|
|
|
- );
|
|
|
-
|
|
|
- println!(
|
|
|
- "{}",
|
|
|
- Builder::update::<SimpleEntity>()
|
|
|
- .update(SimpleEntity::A, 1u8)
|
|
|
- .with(SimpleEntity::ID, 1u8)
|
|
|
- .build_query()
|
|
|
- );
|
|
|
- }
|
|
|
-}
|