1use crate::{Database, Model, Result};
2use std::marker::PhantomData;
3
4pub struct HasMany<P, C> {
6 parent_id: i64,
7 foreign_key: String,
8 _phantom: PhantomData<(P, C)>,
9}
10
11impl<P, C> HasMany<P, C>
12where
13 P: Model,
14 C: Model,
15{
16 pub fn new(parent_id: i64, foreign_key: impl Into<String>) -> Self {
17 Self {
18 parent_id,
19 foreign_key: foreign_key.into(),
20 _phantom: PhantomData,
21 }
22 }
23
24 pub async fn get(&self, db: &impl Database) -> Result<Vec<C>> {
26 let query = format!(
27 "SELECT * FROM {} WHERE {} = {}",
28 C::table_name(),
29 self.foreign_key,
30 self.parent_id
31 );
32 let rows = db.query(&query).await?;
33
34 let mut models = Vec::new();
35 for row in rows {
36 models.push(C::from_row(&row)?);
37 }
38 Ok(models)
39 }
40}
41
42pub struct HasOne<P, C> {
44 parent_id: i64,
45 foreign_key: String,
46 _phantom: PhantomData<(P, C)>,
47}
48
49impl<P, C> HasOne<P, C>
50where
51 P: Model,
52 C: Model,
53{
54 pub fn new(parent_id: i64, foreign_key: impl Into<String>) -> Self {
55 Self {
56 parent_id,
57 foreign_key: foreign_key.into(),
58 _phantom: PhantomData,
59 }
60 }
61
62 pub async fn get(&self, db: &impl Database) -> Result<Option<C>> {
64 let query = format!(
65 "SELECT * FROM {} WHERE {} = {}",
66 C::table_name(),
67 self.foreign_key,
68 self.parent_id
69 );
70 let row = db.query_one(&query).await?;
71
72 match row {
73 Some(row) => Ok(Some(C::from_row(&row)?)),
74 None => Ok(None),
75 }
76 }
77}
78
79pub struct BelongsTo<C, P> {
81 foreign_key_value: i64,
82 _phantom: PhantomData<(C, P)>,
83}
84
85impl<C, P> BelongsTo<C, P>
86where
87 C: Model,
88 P: Model,
89{
90 pub fn new(foreign_key_value: i64) -> Self {
91 Self {
92 foreign_key_value,
93 _phantom: PhantomData,
94 }
95 }
96
97 pub async fn get(&self, db: &impl Database) -> Result<Option<P>> {
99 P::find(db, self.foreign_key_value).await
100 }
101}