From 941356e8bc6d20203f12876cf0e8875db98b9596 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 27 May 2021 15:53:52 +0800 Subject: [PATCH] Refactor as SelectorTrait --- src/connector/select.rs | 116 ++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/src/connector/select.rs b/src/connector/select.rs index 627cb848..dcc48f2c 100644 --- a/src/connector/select.rs +++ b/src/connector/select.rs @@ -1,16 +1,29 @@ use crate::{ query::combine, Connection, Database, EntityTrait, FromQueryResult, JsonValue, QueryErr, - Select, SelectTwo, Statement, + QueryResult, Select, SelectTwo, Statement, TypeErr, }; use sea_query::{QueryBuilder, SelectStatement}; use std::marker::PhantomData; #[derive(Clone, Debug)] +pub struct Selector +where + S: SelectorTrait, +{ + query: SelectStatement, + selector: S, +} + +pub trait SelectorTrait { + type Item: Sized; + + fn from_raw_query_result(res: QueryResult) -> Result; +} + pub struct SelectModel where M: FromQueryResult, { - query: SelectStatement, model: PhantomData, } @@ -20,29 +33,54 @@ where M: FromQueryResult, N: FromQueryResult, { - query: SelectStatement, model: PhantomData<(M, N)>, } +impl SelectorTrait for SelectModel +where + M: FromQueryResult + Sized, +{ + type Item = M; + + fn from_raw_query_result(res: QueryResult) -> Result { + Ok(M::from_query_result(&res, "")?) + } +} + +impl SelectorTrait for SelectTwoModel +where + M: FromQueryResult + Sized, + N: FromQueryResult + Sized, +{ + type Item = (M, N); + + fn from_raw_query_result(res: QueryResult) -> Result { + Ok(( + M::from_query_result(&res, combine::SELECT_A)?, + N::from_query_result(&res, combine::SELECT_B)?, + )) + } +} + impl Select where E: EntityTrait, { - pub fn into_model(self) -> SelectModel + pub fn into_model(self) -> Selector> where M: FromQueryResult, { - SelectModel { + Selector { query: self.query, - model: PhantomData, + selector: SelectModel { model: PhantomData }, } } #[cfg(feature = "with-json")] - pub fn into_json(self) -> SelectModel { - SelectModel { + pub fn into_json(self) -> Selector> { + Selector { query: self.query, - model: PhantomData, + selector: SelectModel { model: PhantomData }, } } @@ -60,22 +98,22 @@ where E: EntityTrait, F: EntityTrait, { - fn into_model(self) -> SelectTwoModel + fn into_model(self) -> Selector> where M: FromQueryResult, N: FromQueryResult, { - SelectTwoModel { + Selector { query: self.query, - model: PhantomData, + selector: SelectTwoModel { model: PhantomData }, } } #[cfg(feature = "with-json")] - pub fn into_json(self) -> SelectTwoModel { - SelectTwoModel { + pub fn into_json(self) -> Selector> { + Selector { query: self.query, - model: PhantomData, + selector: SelectTwoModel { model: PhantomData }, } } @@ -88,9 +126,9 @@ where } } -impl SelectModel +impl Selector where - M: FromQueryResult, + S: SelectorTrait, { pub fn build(&self, builder: B) -> Statement where @@ -99,55 +137,19 @@ where self.query.build(builder).into() } - pub async fn one(mut self, db: &Database) -> Result { + pub async fn one(mut self, db: &Database) -> Result { let builder = db.get_query_builder_backend(); self.query.limit(1); let row = db.get_connection().query_one(self.build(builder)).await?; - Ok(M::from_query_result(&row, "")?) + Ok(S::from_raw_query_result(row)?) } - pub async fn all(self, db: &Database) -> Result, QueryErr> { + pub async fn all(self, db: &Database) -> Result, QueryErr> { let builder = db.get_query_builder_backend(); let rows = db.get_connection().query_all(self.build(builder)).await?; let mut models = Vec::new(); for row in rows.into_iter() { - models.push(M::from_query_result(&row, "")?); - } - Ok(models) - } -} - -impl SelectTwoModel -where - M: FromQueryResult, - N: FromQueryResult, -{ - pub fn build(&self, builder: B) -> Statement - where - B: QueryBuilder, - { - self.query.build(builder).into() - } - - pub async fn one(mut self, db: &Database) -> Result<(M, N), QueryErr> { - let builder = db.get_query_builder_backend(); - self.query.limit(1); - let row = db.get_connection().query_one(self.build(builder)).await?; - Ok(( - M::from_query_result(&row, combine::SELECT_A)?, - N::from_query_result(&row, combine::SELECT_B)?, - )) - } - - pub async fn all(self, db: &Database) -> Result, QueryErr> { - let builder = db.get_query_builder_backend(); - let rows = db.get_connection().query_all(self.build(builder)).await?; - let mut models = Vec::new(); - for row in rows.into_iter() { - models.push(( - M::from_query_result(&row, combine::SELECT_A)?, - N::from_query_result(&row, combine::SELECT_B)?, - )); + models.push(S::from_raw_query_result(row)?); } Ok(models) }