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