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