sea_orm/entity/
column_def.rs

1use sea_query::{SimpleExpr, Value};
2
3// The original `sea_orm::ColumnType` enum was dropped since 0.11.0
4// It was replaced by `sea_query::ColumnType`, we reexport it here to keep the `ColumnType` symbol
5pub use sea_query::ColumnType;
6
7/// Defines a Column for an Entity
8#[derive(Debug, Clone, PartialEq)]
9pub struct ColumnDef {
10    pub(crate) col_type: ColumnType,
11    pub(crate) null: bool,
12    pub(crate) unique: bool,
13    pub(crate) indexed: bool,
14    pub(crate) default: Option<SimpleExpr>,
15    pub(crate) comment: Option<String>,
16    pub(crate) unique_key: Option<String>,
17    pub(crate) seaography: SeaographyColumnAttr,
18}
19
20/// Seaography specific attributes
21#[non_exhaustive]
22#[derive(Debug, Default, Clone, PartialEq)]
23pub struct SeaographyColumnAttr {
24    /// Ignore this column in seaography
25    pub ignore: bool,
26}
27
28impl ColumnDef {
29    /// Marks the column as `UNIQUE`
30    pub fn unique(mut self) -> Self {
31        self.unique = true;
32        self
33    }
34
35    /// Set Seaography ignore
36    pub fn seaography_ignore(mut self) -> Self {
37        self.seaography.ignore = true;
38        self
39    }
40
41    /// This column belongs to a unique key
42    pub fn unique_key(mut self, key: &str) -> Self {
43        self.unique_key = Some(key.into());
44        self
45    }
46
47    /// Set column comment
48    pub fn comment(mut self, v: &str) -> Self {
49        self.comment = Some(v.into());
50        self
51    }
52
53    /// Mark the column as nullable
54    pub fn null(self) -> Self {
55        self.nullable()
56    }
57
58    /// Mark the column as nullable
59    pub fn nullable(mut self) -> Self {
60        self.null = true;
61        self
62    }
63
64    /// Set the `indexed` field  to `true`
65    pub fn indexed(mut self) -> Self {
66        self.indexed = true;
67        self
68    }
69
70    /// Set the default value
71    pub fn default_value<T>(mut self, value: T) -> Self
72    where
73        T: Into<Value>,
74    {
75        self.default = Some(value.into().into());
76        self
77    }
78
79    /// Set the default value or expression of a column
80    pub fn default<T>(mut self, default: T) -> Self
81    where
82        T: Into<SimpleExpr>,
83    {
84        self.default = Some(default.into());
85        self
86    }
87
88    /// Get [ColumnType] as reference
89    pub fn get_column_type(&self) -> &ColumnType {
90        &self.col_type
91    }
92
93    /// Get [Option<SimpleExpr>] as reference
94    pub fn get_column_default(&self) -> Option<&SimpleExpr> {
95        self.default.as_ref()
96    }
97
98    /// Returns true if the column is nullable
99    pub fn is_null(&self) -> bool {
100        self.null
101    }
102
103    /// Returns true if the column is unique
104    pub fn is_unique(&self) -> bool {
105        self.unique
106    }
107
108    /// Get Seaography attribute
109    pub fn seaography(&self) -> &SeaographyColumnAttr {
110        &self.seaography
111    }
112}
113
114#[cfg(test)]
115mod tests {
116    use crate::tests_cfg::*;
117
118    #[test]
119    fn test_col_from_str() {
120        use crate::IdenStatic;
121        use std::str::FromStr;
122
123        assert!(matches!(
124            fruit::Column::from_str("id"),
125            Ok(fruit::Column::Id)
126        ));
127        assert!(matches!(
128            fruit::Column::from_str("name"),
129            Ok(fruit::Column::Name)
130        ));
131        assert!(matches!(
132            fruit::Column::from_str("cake_id"),
133            Ok(fruit::Column::CakeId)
134        ));
135        assert!(matches!(
136            fruit::Column::from_str("cakeId"),
137            Ok(fruit::Column::CakeId)
138        ));
139        assert!(matches!(
140            fruit::Column::from_str("CakeId"),
141            Err(crate::ColumnFromStrErr(_))
142        ));
143        assert!(matches!(
144            fruit::Column::from_str("does_not_exist"),
145            Err(crate::ColumnFromStrErr(_))
146        ));
147        assert!(matches!(fruit::Column::CakeId.as_str(), "cake_id"));
148    }
149
150    #[test]
151    #[cfg(feature = "macros")]
152    fn entity_model_column_1() {
153        use crate::prelude::*;
154
155        mod hello {
156            use crate as sea_orm;
157            use crate::entity::prelude::*;
158
159            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
160            #[sea_orm(table_name = "hello")]
161            pub struct Model {
162                #[sea_orm(primary_key)]
163                pub id: i32,
164                pub one: i32,
165                #[sea_orm(unique)]
166                pub two: i8,
167                #[sea_orm(indexed)]
168                pub three: i16,
169                #[sea_orm(nullable)]
170                pub four: i32,
171                #[sea_orm(unique, indexed, nullable)]
172                pub five: i64,
173                #[sea_orm(unique)]
174                pub six: u8,
175                #[sea_orm(indexed)]
176                pub seven: u16,
177                #[sea_orm(nullable)]
178                pub eight: u32,
179                #[sea_orm(unique, indexed, nullable)]
180                pub nine: u64,
181                #[sea_orm(default_expr = "Expr::current_timestamp()")]
182                pub ten: DateTimeUtc,
183                #[sea_orm(default_value = 7)]
184                pub eleven: u8,
185                #[sea_orm(default_value = "twelve_value")]
186                pub twelve: String,
187                #[sea_orm(default_expr = "\"twelve_value\"")]
188                pub twelve_two: String,
189            }
190
191            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
192            pub enum Relation {}
193
194            impl ActiveModelBehavior for ActiveModel {}
195        }
196
197        assert_eq!(hello::Column::One.def(), ColumnType::Integer.def());
198        assert_eq!(
199            hello::Column::Two.def(),
200            ColumnType::TinyInteger.def().unique()
201        );
202        assert_eq!(
203            hello::Column::Three.def(),
204            ColumnType::SmallInteger.def().indexed()
205        );
206        assert_eq!(
207            hello::Column::Four.def(),
208            ColumnType::Integer.def().nullable()
209        );
210        assert_eq!(
211            hello::Column::Five.def(),
212            ColumnType::BigInteger.def().unique().indexed().nullable()
213        );
214        assert_eq!(
215            hello::Column::Six.def(),
216            ColumnType::TinyUnsigned.def().unique()
217        );
218        assert_eq!(
219            hello::Column::Seven.def(),
220            ColumnType::SmallUnsigned.def().indexed()
221        );
222        assert_eq!(
223            hello::Column::Eight.def(),
224            ColumnType::Unsigned.def().nullable()
225        );
226        assert_eq!(
227            hello::Column::Nine.def(),
228            ColumnType::BigUnsigned.def().unique().indexed().nullable()
229        );
230        assert_eq!(
231            hello::Column::Ten.def(),
232            ColumnType::TimestampWithTimeZone
233                .def()
234                .default(Expr::current_timestamp())
235        );
236        assert_eq!(
237            hello::Column::Eleven.def(),
238            ColumnType::TinyUnsigned.def().default(7)
239        );
240        assert_eq!(
241            hello::Column::Twelve.def(),
242            ColumnType::String(StringLen::None)
243                .def()
244                .default("twelve_value")
245        );
246        assert_eq!(
247            hello::Column::TwelveTwo.def(),
248            ColumnType::String(StringLen::None)
249                .def()
250                .default("twelve_value")
251        );
252    }
253
254    #[test]
255    #[cfg(feature = "macros")]
256    fn column_name_1() {
257        use crate::ColumnTrait;
258        use sea_query::Iden;
259
260        mod hello {
261            use crate as sea_orm;
262            use crate::entity::prelude::*;
263
264            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
265            #[sea_orm(table_name = "hello")]
266            pub struct Model {
267                #[sea_orm(primary_key)]
268                pub id: i32,
269                #[sea_orm(column_name = "ONE")]
270                pub one: i32,
271                #[seaography(ignore)]
272                pub two: i32,
273                #[sea_orm(column_name = "3")]
274                #[seaography(ignore)]
275                pub three: i32,
276            }
277
278            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
279            pub enum Relation {}
280
281            impl ActiveModelBehavior for ActiveModel {}
282        }
283
284        assert_eq!(hello::Column::One.to_string().as_str(), "ONE");
285        assert_eq!(hello::Column::Two.to_string().as_str(), "two");
286        assert_eq!(hello::Column::Three.to_string().as_str(), "3");
287
288        assert!(!hello::Column::One.def().seaography().ignore);
289        assert!(hello::Column::Two.def().seaography().ignore);
290        assert!(hello::Column::Three.def().seaography().ignore);
291    }
292
293    #[test]
294    #[cfg(feature = "macros")]
295    fn column_name_2() {
296        use sea_query::Iden;
297
298        mod hello {
299            use crate as sea_orm;
300            use crate::entity::prelude::*;
301
302            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
303            pub struct Entity;
304
305            impl EntityName for Entity {
306                fn table_name(&self) -> &'static str {
307                    "hello"
308                }
309            }
310
311            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
312            pub struct Model {
313                pub id: i32,
314                pub one: i32,
315                pub two: i32,
316                pub three: i32,
317            }
318
319            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
320            pub enum Column {
321                Id,
322                #[sea_orm(column_name = "ONE")]
323                One,
324                Two,
325                #[sea_orm(column_name = "3")]
326                Three,
327            }
328
329            impl ColumnTrait for Column {
330                type EntityName = Entity;
331
332                fn def(&self) -> ColumnDef {
333                    match self {
334                        Column::Id => ColumnType::Integer.def(),
335                        Column::One => ColumnType::Integer.def(),
336                        Column::Two => ColumnType::Integer.def(),
337                        Column::Three => ColumnType::Integer.def(),
338                    }
339                }
340            }
341
342            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
343            pub enum PrimaryKey {
344                Id,
345            }
346
347            impl PrimaryKeyTrait for PrimaryKey {
348                type ValueType = i32;
349
350                fn auto_increment() -> bool {
351                    true
352                }
353            }
354
355            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
356            pub enum Relation {}
357
358            impl ActiveModelBehavior for ActiveModel {}
359        }
360
361        assert_eq!(hello::Column::One.to_string().as_str(), "ONE");
362        assert_eq!(hello::Column::Two.to_string().as_str(), "two");
363        assert_eq!(hello::Column::Three.to_string().as_str(), "3");
364    }
365
366    #[test]
367    #[cfg(feature = "macros")]
368    fn enum_name_1() {
369        use sea_query::Iden;
370
371        mod hello {
372            use crate as sea_orm;
373            use crate::entity::prelude::*;
374
375            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
376            #[sea_orm(table_name = "hello")]
377            pub struct Model {
378                #[sea_orm(primary_key)]
379                pub id: i32,
380                #[sea_orm(enum_name = "One1")]
381                pub one: i32,
382                pub two: i32,
383                #[sea_orm(enum_name = "Three3")]
384                pub three: i32,
385            }
386
387            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
388            pub enum Relation {}
389
390            impl ActiveModelBehavior for ActiveModel {}
391        }
392
393        assert_eq!(hello::Column::One1.to_string().as_str(), "one1");
394        assert_eq!(hello::Column::Two.to_string().as_str(), "two");
395        assert_eq!(hello::Column::Three3.to_string().as_str(), "three3");
396    }
397
398    #[test]
399    #[cfg(feature = "macros")]
400    fn enum_name_2() {
401        use sea_query::Iden;
402
403        mod hello {
404            use crate as sea_orm;
405            use crate::entity::prelude::*;
406
407            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
408            pub struct Entity;
409
410            impl EntityName for Entity {
411                fn table_name(&self) -> &'static str {
412                    "hello"
413                }
414            }
415
416            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
417            pub struct Model {
418                pub id: i32,
419                #[sea_orm(enum_name = "One1")]
420                pub one: i32,
421                pub two: i32,
422                #[sea_orm(enum_name = "Three3")]
423                pub three: i32,
424            }
425
426            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
427            pub enum Column {
428                Id,
429                One1,
430                Two,
431                Three3,
432            }
433
434            impl ColumnTrait for Column {
435                type EntityName = Entity;
436
437                fn def(&self) -> ColumnDef {
438                    match self {
439                        Column::Id => ColumnType::Integer.def(),
440                        Column::One1 => ColumnType::Integer.def(),
441                        Column::Two => ColumnType::Integer.def(),
442                        Column::Three3 => ColumnType::Integer.def(),
443                    }
444                }
445            }
446
447            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
448            pub enum PrimaryKey {
449                Id,
450            }
451
452            impl PrimaryKeyTrait for PrimaryKey {
453                type ValueType = i32;
454
455                fn auto_increment() -> bool {
456                    true
457                }
458            }
459
460            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
461            pub enum Relation {}
462
463            impl ActiveModelBehavior for ActiveModel {}
464        }
465
466        assert_eq!(hello::Column::One1.to_string().as_str(), "one1");
467        assert_eq!(hello::Column::Two.to_string().as_str(), "two");
468        assert_eq!(hello::Column::Three3.to_string().as_str(), "three3");
469    }
470
471    #[test]
472    #[cfg(feature = "macros")]
473    fn column_name_enum_name_1() {
474        use sea_query::Iden;
475
476        #[allow(clippy::enum_variant_names)]
477        mod hello {
478            use crate as sea_orm;
479            use crate::entity::prelude::*;
480
481            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
482            #[sea_orm(table_name = "hello")]
483            pub struct Model {
484                #[sea_orm(primary_key, column_name = "ID", enum_name = "IdentityColumn")]
485                pub id: i32,
486                #[sea_orm(column_name = "ONE", enum_name = "One1")]
487                pub one: i32,
488                pub two: i32,
489                #[sea_orm(column_name = "THREE", enum_name = "Three3")]
490                pub three: i32,
491            }
492
493            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
494            pub enum Relation {}
495
496            impl ActiveModelBehavior for ActiveModel {}
497        }
498
499        assert_eq!(hello::Column::IdentityColumn.to_string().as_str(), "ID");
500        assert_eq!(hello::Column::One1.to_string().as_str(), "ONE");
501        assert_eq!(hello::Column::Two.to_string().as_str(), "two");
502        assert_eq!(hello::Column::Three3.to_string().as_str(), "THREE");
503    }
504
505    #[test]
506    #[cfg(feature = "macros")]
507    fn column_name_enum_name_2() {
508        use sea_query::Iden;
509
510        mod hello {
511            use crate as sea_orm;
512            use crate::entity::prelude::*;
513
514            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
515            pub struct Entity;
516
517            impl EntityName for Entity {
518                fn table_name(&self) -> &'static str {
519                    "hello"
520                }
521            }
522
523            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
524            pub struct Model {
525                #[sea_orm(enum_name = "IdentityCol")]
526                pub id: i32,
527                #[sea_orm(enum_name = "One1")]
528                pub one: i32,
529                pub two: i32,
530                #[sea_orm(enum_name = "Three3")]
531                pub three: i32,
532            }
533
534            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
535            pub enum Column {
536                #[sea_orm(column_name = "ID")]
537                IdentityCol,
538                #[sea_orm(column_name = "ONE")]
539                One1,
540                Two,
541                #[sea_orm(column_name = "THREE")]
542                Three3,
543            }
544
545            impl ColumnTrait for Column {
546                type EntityName = Entity;
547
548                fn def(&self) -> ColumnDef {
549                    match self {
550                        Column::IdentityCol => ColumnType::Integer.def(),
551                        Column::One1 => ColumnType::Integer.def(),
552                        Column::Two => ColumnType::Integer.def(),
553                        Column::Three3 => ColumnType::Integer.def(),
554                    }
555                }
556            }
557
558            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
559            pub enum PrimaryKey {
560                IdentityCol,
561            }
562
563            impl PrimaryKeyTrait for PrimaryKey {
564                type ValueType = i32;
565
566                fn auto_increment() -> bool {
567                    true
568                }
569            }
570
571            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
572            pub enum Relation {}
573
574            impl ActiveModelBehavior for ActiveModel {}
575        }
576
577        assert_eq!(hello::Column::IdentityCol.to_string().as_str(), "ID");
578        assert_eq!(hello::Column::One1.to_string().as_str(), "ONE");
579        assert_eq!(hello::Column::Two.to_string().as_str(), "two");
580        assert_eq!(hello::Column::Three3.to_string().as_str(), "THREE");
581    }
582
583    #[test]
584    #[cfg(feature = "macros")]
585    fn column_name_enum_name_3() {
586        use sea_query::Iden;
587
588        mod my_entity {
589            use crate as sea_orm;
590            use crate::entity::prelude::*;
591
592            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
593            #[sea_orm(table_name = "my_entity")]
594            pub struct Model {
595                #[sea_orm(primary_key, enum_name = "IdentityColumn", column_name = "id")]
596                pub id: i32,
597                #[sea_orm(column_name = "type")]
598                pub type_: String,
599            }
600
601            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
602            pub enum Relation {}
603
604            impl ActiveModelBehavior for ActiveModel {}
605        }
606
607        assert_eq!(my_entity::Column::IdentityColumn.to_string().as_str(), "id");
608        assert_eq!(my_entity::Column::Type.to_string().as_str(), "type");
609    }
610
611    #[test]
612    #[cfg(feature = "macros")]
613    fn column_def_unique_key() {
614        use crate as sea_orm;
615        use crate::entity::prelude::*;
616
617        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
618        #[sea_orm(table_name = "my_entity")]
619        pub struct Model {
620            #[sea_orm(primary_key)]
621            pub id: i32,
622            #[sea_orm(column_name = "my_a", unique_key = "my_unique")]
623            pub a: String,
624            #[sea_orm(unique_key = "my_unique")]
625            pub b: String,
626        }
627
628        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
629        pub enum Relation {}
630
631        impl ActiveModelBehavior for ActiveModel {}
632
633        assert_eq!(
634            Column::A.def(),
635            ColumnType::string(None).def().unique_key("my_unique")
636        );
637        assert_eq!(
638            Column::B.def(),
639            ColumnType::string(None).def().unique_key("my_unique")
640        );
641    }
642}