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) seaography: SeaographyColumnAttr,
18}
19
20#[non_exhaustive]
22#[derive(Debug, Default, Clone, PartialEq)]
23pub struct SeaographyColumnAttr {
24 pub ignore: bool,
26}
27
28impl ColumnDef {
29 pub fn unique(mut self) -> Self {
31 self.unique = true;
32 self
33 }
34
35 pub fn seaography_ignore(mut self) -> Self {
37 self.seaography.ignore = true;
38 self
39 }
40
41 pub fn unique_key(mut self, key: &str) -> Self {
43 self.unique_key = Some(key.into());
44 self
45 }
46
47 pub fn comment(mut self, v: &str) -> Self {
49 self.comment = Some(v.into());
50 self
51 }
52
53 pub fn null(self) -> Self {
55 self.nullable()
56 }
57
58 pub fn nullable(mut self) -> Self {
60 self.null = true;
61 self
62 }
63
64 pub fn indexed(mut self) -> Self {
66 self.indexed = true;
67 self
68 }
69
70 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 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 pub fn get_column_type(&self) -> &ColumnType {
90 &self.col_type
91 }
92
93 pub fn get_column_default(&self) -> Option<&SimpleExpr> {
95 self.default.as_ref()
96 }
97
98 pub fn is_null(&self) -> bool {
100 self.null
101 }
102
103 pub fn is_unique(&self) -> bool {
105 self.unique
106 }
107
108 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}