Skip to content

Commit

Permalink
feat: reworked the sql module in order to take full advantage of the …
Browse files Browse the repository at this point in the history
…SqlBuilder trait
  • Loading branch information
thibault-cne committed Apr 12, 2024
1 parent b9c2e51 commit 05bc3af
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 444 deletions.
185 changes: 113 additions & 72 deletions crates/application/src/circuit.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use sea_query::{Expr, Query, SelectStatement, SimpleExpr};
use sea_query::{Expr, Query, SelectStatement};

use shared::models::Circuits as CircuitsModel;
use shared::parameters::GetCircuitsParameter;

use crate::{
iden::*,
one_of,
pagination::{Paginate, Paginated},
sql::*,
};
Expand Down Expand Up @@ -34,6 +35,10 @@ impl CircuitQueryBuilder {
.into_iter()
.map(|c| (Circuits::Table, c)),
)
.order_by(
(Circuits::Table, Circuits::CircuitRef),
sea_query::Order::Asc,
)
.to_owned();

Self { stmt, params }
Expand All @@ -43,82 +48,118 @@ impl CircuitQueryBuilder {
let page: u64 = self.params.page.unwrap_or_default().0;
let limit: u64 = self.params.limit.unwrap_or_default().0;

self.races_table()
.results_table()
.constructors_table()
.drivers_table()
.and_status()
.and_circuits()
.and_races()
.and_drivers()
.and_constructors()
.and_grid()
.and_fastest()
.and_result()
.and_round()
.and_year()
.stmt
.paginate(page)
.per_page(limit)
}

fn one_of(&self) -> bool {
self.params.driver_ref.is_some()
|| self.params.constructor_ref.is_some()
|| self.params.status.is_some()
|| self.params.grid.is_some()
|| self.params.fastest.is_some()
|| self.params.result.is_some()
|| self.params.year.is_some()
|| self.params.round.is_some()
self.from(
|s| {
one_of!(
s.params.year,
s.params.driver_ref,
s.params.constructor_ref,
s.params.status,
s.params.grid,
s.params.fastest,
s.params.result
)
},
Races::Table,
)
.from(
|s| {
one_of!(
s.params.driver_ref,
s.params.constructor_ref,
s.params.status,
s.params.grid,
s.params.fastest,
s.params.result
)
},
Results::Table,
)
.from(|s| s.params.driver_ref.is_some(), Drivers::Table)
.from(|s| s.params.constructor_ref.is_some(), Constructors::Table)
.and_where(|s| {
one_of!(
s.params.year,
s.params.driver_ref,
s.params.constructor_ref,
s.params.status,
s.params.grid,
s.params.fastest,
s.params.result
)
.then_some(
Expr::col((Circuits::Table, Circuits::CircuitId))
.equals((Races::Table, Races::CircuitId)),
)
})
.and_where(|s| {
one_of!(
s.params.driver_ref,
s.params.constructor_ref,
s.params.status,
s.params.grid,
s.params.fastest,
s.params.result
)
.then_some(
Expr::col((Results::Table, Results::RaceId)).equals((Races::Table, Races::RaceId)),
)
})
.and_where(|s| {
s.params.constructor_ref.as_ref().map(|c| {
Expr::col((Constructors::Table, Constructors::ConstructorId))
.equals((Results::Table, Results::ConstructorId))
.and(
Expr::col((Constructors::Table, Constructors::ConstructorRef))
.eq(Expr::value(&**c)),
)
})
})
.and_where(|s| {
s.params.driver_ref.as_ref().map(|d| {
Expr::col((Drivers::Table, Drivers::DriverId))
.equals((Results::Table, Results::DriverId))
.and(Expr::col((Drivers::Table, Drivers::DriverRef)).eq(Expr::value(&**d)))
})
})
.and_where(|s| {
s.params
.status
.map(|s| Expr::col((Results::Table, Results::StatusId)).eq(Expr::value(*s)))
})
.and_where(|s| {
s.params
.grid
.map(|g| Expr::col((Results::Table, Results::Grid)).eq(Expr::value(*g)))
})
.and_where(|s| {
s.params
.fastest
.map(|f| Expr::col((Results::Table, Results::Rank)).eq(Expr::value(*f)))
})
.and_where(|s| {
s.params
.result
.map(|r| Expr::col((Results::Table, Results::PositionText)).eq(Expr::value(*r)))
})
.and_where(|s| {
s.params
.round
.map(|r| Expr::col((Races::Table, Races::Round)).eq(Expr::value(*r)))
})
.and_where(|s| {
s.params
.year
.map(|y| Expr::col((Races::Table, Races::Year)).eq(Expr::value(*y)))
})
.stmt
.paginate(page)
.per_page(limit)
}
}

impl SqlBuilder for CircuitQueryBuilder {
fn stmt(&mut self) -> &mut sea_query::SelectStatement {
&mut self.stmt
}

fn check_and_circuits(&self) -> bool {
self.one_of()
}

fn check_and_races(&self) -> bool {
self.one_of()
}

fn check_and_drivers(&self) -> Option<SimpleExpr> {
self.params.driver_ref.as_ref().map(|d| Expr::value(&**d))
}

fn check_and_constructors(&self) -> Option<SimpleExpr> {
self.params
.constructor_ref
.as_ref()
.map(|c| Expr::value(&**c))
}

fn check_and_status(&self) -> Option<SimpleExpr> {
self.params.status.as_ref().map(|s| Expr::value(**s))
}

fn check_and_grid(&self) -> Option<SimpleExpr> {
self.params.grid.as_ref().map(|g| Expr::value(**g))
}

fn check_and_result(&self) -> Option<SimpleExpr> {
self.params.result.as_ref().map(|r| Expr::value(**r))
}

fn check_and_round(&self) -> Option<SimpleExpr> {
self.params.round.as_ref().map(|r| Expr::value(**r))
}

fn check_and_year(&self) -> Option<SimpleExpr> {
self.params.year.as_ref().map(|y| Expr::value(**y))
}

fn check_and_fastest(&self) -> Option<SimpleExpr> {
self.params.fastest.as_ref().map(|f| Expr::value(**f))
}
}
76 changes: 32 additions & 44 deletions crates/application/src/constructor.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use sea_query::{Expr, Func, IntoTableRef, Query, SelectStatement, SimpleExpr};
use sea_query::{Expr, Func, Query, SelectStatement};

use shared::models::Constructors as ConstructorsModel;
use shared::parameters::GetConstructorsParameter;

use crate::{
iden::*,
one_of,
pagination::{Paginate, Paginated},
sql::SqlBuilder,
};

pub struct ConstructorQueryBuilder {
Expand Down Expand Up @@ -34,22 +36,24 @@ impl ConstructorQueryBuilder {
Self { params, stmt }
}

pub fn build(mut self) -> Paginated<ConstructorsModel> {
pub fn build(self) -> Paginated<ConstructorsModel> {
let page: u64 = self.params.page.unwrap_or_default().0;
let limit: u64 = self.params.limit.unwrap_or_default().0;

self.join(
self.from(
|s| {
s.params.year.is_some()
|| s.params.circuit_ref.is_some()
|| s.params.constructor_standing.is_some()
one_of!(
s.params.year,
s.params.circuit_ref,
s.params.constructor_standing
)
},
Races::Table,
)
.join(Self::one_of, Results::Table)
.join(|s| s.params.driver_ref.is_some(), Drivers::Table)
.join(|s| s.params.circuit_ref.is_some(), Circuits::Table)
.join(
.from(Self::one_of, Results::Table)
.from(|s| s.params.driver_ref.is_some(), Drivers::Table)
.from(|s| s.params.circuit_ref.is_some(), Circuits::Table)
.from(
|s| s.params.constructor_standing.is_some(),
ConstructorStandings::Table,
)
Expand All @@ -60,7 +64,7 @@ impl ConstructorQueryBuilder {
)
})
.and_where(|s| {
(s.params.year.is_some() || s.params.circuit_ref.is_some()).then_some(
one_of!(s.params.year, s.params.circuit_ref).then_some(
Expr::col((Results::Table, Results::RaceId)).equals((Races::Table, Races::RaceId)),
)
})
Expand Down Expand Up @@ -123,7 +127,7 @@ impl ConstructorQueryBuilder {
.per_page(limit)
}

fn and_clause(&mut self) -> &mut Self {
fn and_clause(self) -> Self {
if let Some(round) = self.params.round {
return self.and_where(|_| {
Some(Expr::col((Races::Table, Races::Round)).eq(Expr::value(*round)))
Expand Down Expand Up @@ -158,43 +162,27 @@ impl ConstructorQueryBuilder {
},
);

self.and_where(|_| Some(expr));
self.and_where(|_| Some(expr))
} else {
self
}

self
}

fn one_of(&self) -> bool {
self.params.year.is_some()
|| self.params.driver_ref.is_some()
|| self.params.status.is_some()
|| self.params.grid.is_some()
|| self.params.result.is_some()
|| self.params.circuit_ref.is_some()
|| self.params.fastest.is_some()
}

fn join<F, R>(&mut self, f: F, table: R) -> &mut Self
where
F: FnOnce(&Self) -> bool,
R: IntoTableRef,
{
if f(self) {
self.stmt
.join(sea_query::JoinType::Join, table, Expr::val(1).eq(1));
}

self
one_of!(
self.params.year,
self.params.driver_ref,
self.params.status,
self.params.grid,
self.params.result,
self.params.circuit_ref,
self.params.fastest
)
}
}

fn and_where<F>(&mut self, f: F) -> &mut Self
where
F: FnOnce(&Self) -> Option<SimpleExpr>,
{
if let Some(expr) = f(self) {
self.stmt.and_where(expr);
}

self
impl SqlBuilder for ConstructorQueryBuilder {
fn stmt(&mut self) -> &mut sea_query::SelectStatement {
&mut self.stmt
}
}
16 changes: 6 additions & 10 deletions crates/application/src/constructor_standing.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use sea_query::{Expr, Func, IntoColumnRef, Query, SelectStatement, SimpleExpr};
use sea_query::{Expr, Func, IntoColumnRef, Query, SelectStatement};

use shared::models::ConstructorStandings as ConstructorStandingsModel;
use shared::parameters::GetConstructorStandingsParameter;

use crate::{
iden::*,
pagination::{Paginate, Paginated},
sql::SqlBuilder,
};

pub struct ConstructorStandingQueryBuilder {
Expand Down Expand Up @@ -131,15 +132,10 @@ impl ConstructorStandingQueryBuilder {

self.and_where(|_| Some(expr))
}
}

fn and_where<F>(mut self, f: F) -> Self
where
F: FnOnce(&Self) -> Option<SimpleExpr>,
{
if let Some(expr) = f(&self) {
self.stmt.and_where(expr);
}

self
impl SqlBuilder for ConstructorStandingQueryBuilder {
fn stmt(&mut self) -> &mut SelectStatement {
&mut self.stmt
}
}
Loading

0 comments on commit 05bc3af

Please sign in to comment.