sea_orm/entity/
compound.rs

1#![allow(missing_docs)]
2use super::{ColumnTrait, EntityTrait, PrimaryKeyToColumn, PrimaryKeyTrait};
3use crate::{IntoSimpleExpr, Iterable, QueryFilter, QueryOrder, Related};
4use sea_query::{IntoValueTuple, Order, TableRef};
5mod has_many;
6mod has_one;
7
8pub use has_many::{HasMany, Iter as HasManyIter};
9pub use has_one::HasOne;
10
11pub trait EntityLoaderTrait<E: EntityTrait>: QueryFilter + QueryOrder {
12    /// Find a model by primary key
13    fn filter_by_id<T>(mut self, values: T) -> Self
14    where
15        T: Into<<E::PrimaryKey as PrimaryKeyTrait>::ValueType>,
16    {
17        let mut keys = E::PrimaryKey::iter();
18        for v in values.into().into_value_tuple() {
19            if let Some(key) = keys.next() {
20                let col = key.into_column();
21                self.filter_mut(col.eq(v));
22            } else {
23                unreachable!("primary key arity mismatch");
24            }
25        }
26        self
27    }
28
29    /// Apply order by primary key to the query statement
30    fn order_by_id_asc(self) -> Self {
31        self.order_by_id(Order::Asc)
32    }
33
34    /// Apply order by primary key to the query statement
35    fn order_by_id_desc(self) -> Self {
36        self.order_by_id(Order::Desc)
37    }
38
39    /// Apply order by primary key to the query statement
40    fn order_by_id(mut self, order: Order) -> Self {
41        for key in E::PrimaryKey::iter() {
42            let col = key.into_column();
43            <Self as QueryOrder>::query(&mut self)
44                .order_by_expr(col.into_simple_expr(), order.clone());
45        }
46        self
47    }
48}
49
50#[derive(Debug, Clone, PartialEq)]
51pub enum LoadTarget {
52    TableRef(TableRef),
53    Relation(String),
54}
55
56pub trait EntityLoaderWithParam<E: EntityTrait> {
57    fn into_with_param(self) -> (LoadTarget, Option<LoadTarget>);
58}
59
60impl<E, R> EntityLoaderWithParam<E> for R
61where
62    E: EntityTrait,
63    R: EntityTrait,
64    E: Related<R>,
65{
66    fn into_with_param(self) -> (LoadTarget, Option<LoadTarget>) {
67        (LoadTarget::TableRef(self.table_ref()), None)
68    }
69}
70
71impl<E, R, S> EntityLoaderWithParam<E> for (R, S)
72where
73    E: EntityTrait,
74    R: EntityTrait,
75    E: Related<R>,
76    S: EntityTrait,
77    R: Related<S>,
78{
79    fn into_with_param(self) -> (LoadTarget, Option<LoadTarget>) {
80        (
81            LoadTarget::TableRef(self.0.table_ref()),
82            Some(LoadTarget::TableRef(self.1.table_ref())),
83        )
84    }
85}
86
87#[cfg(test)]
88mod test {
89    use crate::ModelTrait;
90    use crate::tests_cfg::cake;
91
92    #[test]
93    fn test_model_ex_convert() {
94        let cake = cake::Model {
95            id: 12,
96            name: "hello".into(),
97        };
98        let cake_ex: cake::ModelEx = cake.clone().into();
99
100        assert_eq!(cake, cake_ex);
101        assert_eq!(cake_ex, cake);
102        assert_eq!(cake.id, cake_ex.id);
103        assert_eq!(cake.name, cake_ex.name);
104
105        assert_eq!(cake_ex.get(cake::Column::Id), 12i32.into());
106        assert_eq!(cake_ex.get(cake::Column::Name), "hello".into());
107
108        assert_eq!(cake::Model::from(cake_ex), cake);
109    }
110}