Skip to main content

wae_database/orm/
entity.rs

1//! 实体定义模块
2//!
3//! 提供实体与数据库表的映射关系
4
5use crate::{
6    DatabaseResult,
7    connection::{DatabaseRow, FromDatabaseValue},
8};
9use wae_types::Value;
10
11/// 数据库实体 trait
12///
13/// 定义实体与数据库表的映射关系
14///
15/// # Example
16///
17/// ```ignore
18/// struct User {
19///     id: i64,
20///     name: String,
21///     email: String,
22/// }
23///
24/// impl Entity for User {
25///     type Id = i64;
26///
27///     fn table_name() -> &'static str {
28///         "users"
29///     }
30///
31///     fn id(&self) -> Self::Id {
32///         self.id
33///     }
34/// }
35/// ```
36pub trait Entity: Sized + Send + Sync + 'static {
37    /// 主键类型
38    type Id: FromDatabaseValue + Into<Value> + Send + Sync + Clone;
39
40    /// 表名
41    fn table_name() -> &'static str;
42
43    /// 获取主键值
44    fn id(&self) -> Self::Id;
45
46    /// 主键列名,默认为 "id"
47    fn id_column() -> &'static str {
48        "id"
49    }
50}
51
52/// 从数据库行解析实体
53pub trait FromRow: Sized {
54    /// 从数据库行解析
55    fn from_row(row: &DatabaseRow) -> DatabaseResult<Self>;
56}
57
58/// 将实体转换为数据库行
59pub trait ToRow {
60    /// 转换为列名和值的列表
61    fn to_row(&self) -> Vec<(&'static str, Value)>;
62}
63
64/// 一对多关系 trait
65///
66/// 定义主实体与从实体的一对多关系
67///
68/// # Example
69///
70/// ```ignore
71/// struct User {
72///     id: i64,
73///     posts: Vec<Post>,
74/// }
75///
76/// struct Post {
77///     id: i64,
78///     user_id: i64,
79/// }
80///
81/// impl HasMany<Post> for User {
82///     fn foreign_key() -> &'static str {
83///         "user_id"
84///     }
85///
86///     fn local_key() -> &'static str {
87///         "id"
88///     }
89/// }
90/// ```
91pub trait HasMany<T: Entity>: Entity {
92    /// 外键列名(从表中的列名)
93    fn foreign_key() -> &'static str;
94
95    /// 本地键列名(主表中的列名),默认为主键列名
96    fn local_key() -> &'static str {
97        Self::id_column()
98    }
99}
100
101/// 一对多关系的反向 trait
102///
103/// 定义从实体与主实体的多对一关系
104///
105/// # Example
106///
107/// ```ignore
108/// struct Post {
109///     id: i64,
110///     user_id: i64,
111///     user: Option<User>,
112/// }
113///
114/// impl BelongsTo<User> for Post {
115///     fn foreign_key() -> &'static str {
116///         "user_id"
117///     }
118///
119///     fn owner_key() -> &'static str {
120///         "id"
121///     }
122/// }
123/// ```
124pub trait BelongsTo<T: Entity>: Entity {
125    /// 外键列名(当前表中的列名)
126    fn foreign_key() -> &'static str;
127
128    /// 拥有者键列名(主表中的列名),默认为主键列名
129    fn owner_key() -> &'static str {
130        T::id_column()
131    }
132}
133
134/// 多对多关系 trait
135///
136/// 定义实体之间的多对多关系
137///
138/// # Example
139///
140/// ```ignore
141/// struct User {
142///     id: i64,
143///     roles: Vec<Role>,
144/// }
145///
146/// struct Role {
147///     id: i64,
148///     users: Vec<User>,
149/// }
150///
151/// impl ManyToMany<Role> for User {
152///     fn join_table() -> &'static str {
153///         "user_roles"
154///     }
155///
156///     fn local_key() -> &'static str {
157///         "user_id"
158///     }
159///
160///     fn foreign_key() -> &'static str {
161///         "role_id"
162///     }
163/// }
164/// ```
165pub trait ManyToMany<T: Entity>: Entity {
166    /// 中间表名
167    fn join_table() -> &'static str;
168
169    /// 本地键列名(中间表中指向当前表的列名)
170    fn local_key() -> &'static str;
171
172    /// 外键列名(中间表中指向关联表的列名)
173    fn foreign_key() -> &'static str;
174}