rws_server/model/
relation.rs1use std::marker::PhantomData;
7
8use super::pool::DbPool;
9use super::repository::placeholder;
10use super::{DbError, Model, Value};
11
12#[derive(Debug, Clone)]
23pub struct HasMany<T: Model> {
24 owner_pk: Value,
25 fk_col: &'static str,
26 _phantom: PhantomData<T>,
27}
28
29impl<T: Model> HasMany<T> {
30 pub fn new(owner_pk: Value, fk_col: &'static str) -> Self {
31 HasMany { owner_pk, fk_col, _phantom: PhantomData }
32 }
33
34 pub async fn load(&self, pool: &DbPool) -> Result<Vec<T>, DbError> {
36 let sql = format!(
37 "SELECT * FROM {} WHERE {} = {}",
38 T::table_name(), self.fk_col, placeholder(pool.backend(), 1),
39 );
40 let rows = pool.query_rows(&sql, &[self.owner_pk.clone()]).await?;
41 rows.iter().map(|r| T::from_row(r)).collect()
42 }
43}
44
45#[derive(Debug, Clone)]
51pub struct HasOne<O: Model> {
52 owner_pk: Value,
53 fk_col: &'static str,
54 _phantom: PhantomData<O>,
55}
56
57impl<O: Model> HasOne<O> {
58 pub fn new(owner_pk: Value, fk_col: &'static str) -> Self {
59 HasOne { owner_pk, fk_col, _phantom: PhantomData }
60 }
61
62 pub async fn load(&self, pool: &DbPool) -> Result<Option<O>, DbError> {
64 let sql = format!(
65 "SELECT * FROM {} WHERE {} = {} LIMIT 1",
66 O::table_name(), self.fk_col, placeholder(pool.backend(), 1),
67 );
68 let rows = pool.query_rows(&sql, &[self.owner_pk.clone()]).await?;
69 match rows.into_iter().next() {
70 Some(row) => Ok(Some(O::from_row(&row)?)),
71 None => Ok(None),
72 }
73 }
74}
75
76#[derive(Debug, Clone)]
82pub struct BelongsTo<O: Model> {
83 fk_value: Value,
84 _phantom: PhantomData<O>,
85}
86
87impl<O: Model> BelongsTo<O> {
88 pub fn new(fk_value: Value) -> Self {
89 BelongsTo { fk_value, _phantom: PhantomData }
90 }
91
92 pub async fn load(&self, pool: &DbPool) -> Result<Option<O>, DbError> {
94 let sql = format!(
95 "SELECT * FROM {} WHERE {} = {} LIMIT 1",
96 O::table_name(), O::primary_key_name(), placeholder(pool.backend(), 1),
97 );
98 let rows = pool.query_rows(&sql, &[self.fk_value.clone()]).await?;
99 match rows.into_iter().next() {
100 Some(row) => Ok(Some(O::from_row(&row)?)),
101 None => Ok(None),
102 }
103 }
104}