sea_orm/entity/
primary_key.rs

1use super::{ColumnTrait, IdenStatic, Iterable};
2use crate::{TryFromU64, TryGetableMany};
3use sea_query::{FromValueTuple, IntoValueTuple};
4use std::fmt::Debug;
5
6//LINT: composite primary key cannot auto increment
7/// A Trait for to be used to define a Primary Key.
8///
9/// A primary key can be derived manually
10///
11/// ### Example
12/// ```text
13/// use sea_orm::entity::prelude::*;
14///
15/// #[derive(Copy, Clone, Debug, EnumIter)]
16/// pub enum PrimaryKey {
17///     Id,
18/// }
19/// impl PrimaryKeyTrait for PrimaryKey {
20///     type ValueType = i32;
21///
22///     fn auto_increment() -> bool {
23///         true
24///     }
25/// }
26/// ```
27///
28/// Alternatively, use derive macros to automatically implement the trait for a Primary Key
29///
30/// ### Example
31/// ```text
32/// use sea_orm::entity::prelude::*;
33///
34/// #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
35/// pub enum PrimaryKey {
36///     Id,
37/// }
38/// ```
39/// See module level docs [crate::entity] for a full example
40pub trait PrimaryKeyTrait: IdenStatic + Iterable {
41    #[allow(missing_docs)]
42    type ValueType: Sized
43        + Send
44        + Debug
45        + PartialEq
46        + IntoValueTuple
47        + FromValueTuple
48        + TryGetableMany
49        + TryFromU64
50        + PrimaryKeyArity;
51
52    /// Method to call to perform `AUTOINCREMENT` operation on a Primary Key
53    fn auto_increment() -> bool;
54}
55
56/// How to map a Primary Key to a column
57pub trait PrimaryKeyToColumn {
58    #[allow(missing_docs)]
59    type Column: ColumnTrait;
60
61    /// Method to map a primary key to a column in an Entity
62    fn into_column(self) -> Self::Column;
63
64    /// Method to map a primary key from a column in an Entity
65    fn from_column(col: Self::Column) -> Option<Self>
66    where
67        Self: Sized;
68}
69
70/// How many columns this Primary Key comprises
71pub trait PrimaryKeyArity {
72    /// Arity of the Primary Key
73    const ARITY: usize;
74}
75
76impl<V> PrimaryKeyArity for V
77where
78    V: crate::TryGetable,
79{
80    const ARITY: usize = 1;
81}
82
83macro_rules! impl_pk_arity {
84    ($len:expr, $($tuple_arg:ident),*) => {
85        impl<$($tuple_arg: crate::TryGetableMany,)*> PrimaryKeyArity for ($($tuple_arg,)*) {
86            const ARITY: usize = $len;
87        }
88    }
89}
90
91impl_pk_arity!(1, T1);
92impl_pk_arity!(2, T1, T2);
93impl_pk_arity!(3, T1, T2, T3);
94impl_pk_arity!(4, T1, T2, T3, T4);
95impl_pk_arity!(5, T1, T2, T3, T4, T5);
96impl_pk_arity!(6, T1, T2, T3, T4, T5, T6);
97impl_pk_arity!(7, T1, T2, T3, T4, T5, T6, T7);
98impl_pk_arity!(8, T1, T2, T3, T4, T5, T6, T7, T8);
99impl_pk_arity!(9, T1, T2, T3, T4, T5, T6, T7, T8, T9);
100impl_pk_arity!(10, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
101impl_pk_arity!(11, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
102impl_pk_arity!(12, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
103
104#[cfg(test)]
105mod tests {
106    #[test]
107    #[cfg(feature = "macros")]
108    fn test_composite_primary_key() {
109        mod primary_key_of_1 {
110            use crate as sea_orm;
111            use crate::entity::prelude::*;
112
113            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
114            #[sea_orm(table_name = "primary_key_of_1")]
115            pub struct Model {
116                #[sea_orm(primary_key)]
117                pub id: i32,
118                pub owner: String,
119                pub name: String,
120                pub description: String,
121            }
122
123            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
124            pub enum Relation {}
125
126            impl ActiveModelBehavior for ActiveModel {}
127        }
128
129        mod primary_key_of_2 {
130            use crate as sea_orm;
131            use crate::entity::prelude::*;
132
133            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
134            #[sea_orm(table_name = "primary_key_of_2")]
135            pub struct Model {
136                #[sea_orm(primary_key, auto_increment = false)]
137                pub id_1: i32,
138                #[sea_orm(primary_key, auto_increment = false)]
139                pub id_2: String,
140                pub owner: String,
141                pub name: String,
142                pub description: String,
143            }
144
145            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
146            pub enum Relation {}
147
148            impl ActiveModelBehavior for ActiveModel {}
149        }
150
151        mod primary_key_of_3 {
152            use crate as sea_orm;
153            use crate::entity::prelude::*;
154
155            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
156            #[sea_orm(table_name = "primary_key_of_3")]
157            pub struct Model {
158                #[sea_orm(primary_key, auto_increment = false)]
159                pub id_1: i32,
160                #[sea_orm(primary_key, auto_increment = false)]
161                pub id_2: String,
162                #[sea_orm(primary_key, auto_increment = false)]
163                pub id_3: Uuid,
164                pub owner: String,
165                pub name: String,
166                pub description: String,
167            }
168
169            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
170            pub enum Relation {}
171
172            impl ActiveModelBehavior for ActiveModel {}
173        }
174
175        mod primary_key_of_4 {
176            use crate as sea_orm;
177            use crate::entity::prelude::*;
178
179            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
180            #[sea_orm(table_name = "primary_key_of_4")]
181            pub struct Model {
182                #[sea_orm(primary_key, auto_increment = false)]
183                pub id_1: TimeDateTimeWithTimeZone,
184                #[sea_orm(primary_key, auto_increment = false)]
185                pub id_2: Uuid,
186                #[sea_orm(primary_key, auto_increment = false)]
187                pub id_3: Json,
188                #[sea_orm(primary_key, auto_increment = false)]
189                pub id_4: Decimal,
190                pub owner: String,
191                pub name: String,
192                pub description: String,
193            }
194
195            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
196            pub enum Relation {}
197
198            impl ActiveModelBehavior for ActiveModel {}
199        }
200
201        mod primary_key_of_11 {
202            use crate as sea_orm;
203            use crate::entity::prelude::*;
204
205            #[derive(Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
206            #[sea_orm(
207                rs_type = "String",
208                db_type = "String(StringLen::N(1))",
209                enum_name = "category"
210            )]
211            pub enum DeriveCategory {
212                #[sea_orm(string_value = "B")]
213                Big,
214                #[sea_orm(string_value = "S")]
215                Small,
216            }
217
218            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
219            #[sea_orm(table_name = "primary_key_of_11")]
220            pub struct Model {
221                #[sea_orm(primary_key, auto_increment = false)]
222                pub id_1: Vec<u8>,
223                #[sea_orm(primary_key, auto_increment = false)]
224                pub id_2: DeriveCategory,
225                #[sea_orm(primary_key, auto_increment = false)]
226                pub id_3: Date,
227                #[sea_orm(primary_key, auto_increment = false)]
228                pub id_4: DateTime,
229                #[sea_orm(primary_key, auto_increment = false)]
230                pub id_5: Time,
231                #[sea_orm(primary_key, auto_increment = false)]
232                pub id_6: TimeTime,
233                #[sea_orm(primary_key, auto_increment = false)]
234                pub id_7: DateTime,
235                #[sea_orm(primary_key, auto_increment = false)]
236                pub id_8: TimeDateTime,
237                #[sea_orm(primary_key, auto_increment = false)]
238                pub id_9: DateTimeLocal,
239                #[sea_orm(primary_key, auto_increment = false)]
240                pub id_10: DateTimeUtc,
241                #[sea_orm(primary_key, auto_increment = false)]
242                pub id_11: DateTimeWithTimeZone,
243                pub owner: String,
244                pub name: String,
245                pub description: String,
246            }
247
248            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
249            pub enum Relation {}
250
251            impl ActiveModelBehavior for ActiveModel {}
252        }
253
254        mod primary_key_of_12 {
255            use crate as sea_orm;
256            use crate::entity::prelude::*;
257
258            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
259            #[sea_orm(table_name = "primary_key_of_12")]
260            pub struct Model {
261                #[sea_orm(primary_key, auto_increment = false)]
262                pub id_1: String,
263                #[sea_orm(primary_key, auto_increment = false)]
264                pub id_2: i8,
265                #[sea_orm(primary_key, auto_increment = false)]
266                pub id_3: u8,
267                #[sea_orm(primary_key, auto_increment = false)]
268                pub id_4: i16,
269                #[sea_orm(primary_key, auto_increment = false)]
270                pub id_5: u16,
271                #[sea_orm(primary_key, auto_increment = false)]
272                pub id_6: i32,
273                #[sea_orm(primary_key, auto_increment = false)]
274                pub id_7: u32,
275                #[sea_orm(primary_key, auto_increment = false)]
276                pub id_8: i64,
277                #[sea_orm(primary_key, auto_increment = false)]
278                pub id_9: u64,
279                #[sea_orm(primary_key, auto_increment = false)]
280                pub id_10: f32,
281                #[sea_orm(primary_key, auto_increment = false)]
282                pub id_11: f64,
283                #[sea_orm(primary_key, auto_increment = false)]
284                pub id_12: bool,
285                pub owner: String,
286                pub name: String,
287                pub description: String,
288            }
289
290            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
291            pub enum Relation {}
292
293            impl ActiveModelBehavior for ActiveModel {}
294        }
295    }
296}