sea_query/table/column.rs
1use std::fmt;
2
3use crate::{expr::*, table::Check, types::*};
4
5/// Specification of a table column
6#[derive(Debug, Clone)]
7pub struct ColumnDef {
8 pub(crate) table: Option<TableRef>,
9 pub(crate) name: DynIden,
10 pub(crate) types: Option<ColumnType>,
11 pub(crate) spec: ColumnSpec,
12}
13
14pub trait IntoColumnDef: Into<ColumnDef> {
15 fn into_column_def(self) -> ColumnDef;
16}
17
18impl<T> IntoColumnDef for T
19where
20 T: Into<ColumnDef>,
21{
22 fn into_column_def(self) -> ColumnDef {
23 self.into()
24 }
25}
26
27impl From<&mut ColumnDef> for ColumnDef {
28 fn from(col: &mut ColumnDef) -> Self {
29 col.clone()
30 }
31}
32
33/// All column types
34///
35/// | ColumnType | MySQL data type | PostgreSQL data type | SQLite data type |
36/// |-----------------------|-------------------|-----------------------------|------------------------------|
37/// | Char | char | char | char |
38/// | String | varchar | varchar | varchar |
39/// | Text | text | text | text |
40/// | TinyInteger | tinyint | smallint | tinyint |
41/// | SmallInteger | smallint | smallint | smallint |
42/// | Integer | int | integer | integer |
43/// | BigInteger | bigint | bigint | integer |
44/// | TinyUnsigned | tinyint unsigned | smallint | tinyint |
45/// | SmallUnsigned | smallint unsigned | smallint | smallint |
46/// | Unsigned | int unsigned | integer | integer |
47/// | BigUnsigned | bigint unsigned | bigint | integer |
48/// | Float | float | real | float |
49/// | Double | double | double precision | double |
50/// | Decimal | decimal | decimal | real |
51/// | DateTime | datetime | timestamp without time zone | datetime_text |
52/// | Timestamp | timestamp | timestamp | timestamp_text |
53/// | TimestampWithTimeZone | timestamp | timestamp with time zone | timestamp_with_timezone_text |
54/// | Time | time | time | time_text |
55/// | Date | date | date | date_text |
56/// | Year | year | N/A | N/A |
57/// | Interval | N/A | interval | N/A |
58/// | Blob | blob | bytea | blob |
59/// | Binary | binary | bytea | blob |
60/// | VarBinary | varbinary | bytea | varbinary_blob |
61/// | Bit | bit | bit | N/A |
62/// | VarBit | bit | varbit | N/A |
63/// | Boolean | bool | bool | boolean |
64/// | Money | decimal | money | real_money |
65/// | Json | json | json | json_text |
66/// | JsonBinary | json | jsonb | jsonb_text |
67/// | Uuid | binary(16) | uuid | uuid_text |
68/// | Enum | ENUM(...) | ENUM_NAME | enum_text |
69/// | Array | N/A | DATA_TYPE[] | N/A |
70/// | Vector | N/A | vector | N/A |
71/// | Cidr | N/A | cidr | N/A |
72/// | Inet | N/A | inet | N/A |
73/// | MacAddr | N/A | macaddr | N/A |
74/// | LTree | N/A | ltree | N/A |
75#[non_exhaustive]
76#[derive(Debug, Clone)]
77pub enum ColumnType {
78 Char(Option<u32>),
79 String(StringLen),
80 Text,
81 Blob,
82 TinyInteger,
83 SmallInteger,
84 Integer,
85 BigInteger,
86 TinyUnsigned,
87 SmallUnsigned,
88 Unsigned,
89 BigUnsigned,
90 Float,
91 Double,
92 Decimal(Option<(u32, u32)>),
93 DateTime,
94 Timestamp,
95 TimestampWithTimeZone,
96 Time,
97 Date,
98 Year,
99 Interval(Option<PgInterval>, Option<u32>),
100 Binary(u32),
101 VarBinary(StringLen),
102 Bit(Option<u32>),
103 VarBit(u32),
104 Boolean,
105 Money(Option<(u32, u32)>),
106 Json,
107 JsonBinary,
108 Uuid,
109 Custom(DynIden),
110 Enum {
111 name: DynIden,
112 variants: Vec<DynIden>,
113 },
114 Array(RcOrArc<ColumnType>),
115 Vector(Option<u32>),
116 Cidr,
117 Inet,
118 MacAddr,
119 LTree,
120}
121
122/// Length for var-char/binary; default to 255
123#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
124pub enum StringLen {
125 /// String size
126 N(u32),
127 Max,
128 #[default]
129 None,
130}
131
132impl PartialEq for ColumnType {
133 fn eq(&self, other: &Self) -> bool {
134 match (self, other) {
135 (Self::Char(l0), Self::Char(r0)) => l0 == r0,
136 (Self::String(l0), Self::String(r0)) => l0 == r0,
137 (Self::Decimal(l0), Self::Decimal(r0)) => l0 == r0,
138 (Self::Interval(l0, l1), Self::Interval(r0, r1)) => l0 == r0 && l1 == r1,
139 (Self::Binary(l0), Self::Binary(r0)) => l0 == r0,
140 (Self::VarBinary(l0), Self::VarBinary(r0)) => l0 == r0,
141 (Self::Bit(l0), Self::Bit(r0)) => l0 == r0,
142 (Self::VarBit(l0), Self::VarBit(r0)) => l0 == r0,
143 (Self::Money(l0), Self::Money(r0)) => l0 == r0,
144 (Self::Custom(l0), Self::Custom(r0)) => l0.to_string() == r0.to_string(),
145 (
146 Self::Enum {
147 name: l_name,
148 variants: l_variants,
149 },
150 Self::Enum {
151 name: r_name,
152 variants: r_variants,
153 },
154 ) => {
155 l_name.to_string() == r_name.to_string()
156 && l_variants
157 .iter()
158 .map(|v| v.to_string())
159 .eq(r_variants.iter().map(|v| v.to_string()))
160 }
161 (Self::Array(l0), Self::Array(r0)) => l0 == r0,
162 _ => core::mem::discriminant(self) == core::mem::discriminant(other),
163 }
164 }
165}
166
167impl ColumnType {
168 pub fn custom<T>(ty: T) -> ColumnType
169 where
170 T: IntoIden,
171 {
172 ColumnType::Custom(ty.into_iden())
173 }
174
175 pub fn string(length: Option<u32>) -> ColumnType {
176 match length {
177 Some(s) => ColumnType::String(StringLen::N(s)),
178 None => ColumnType::String(StringLen::None),
179 }
180 }
181
182 pub fn var_binary(length: u32) -> ColumnType {
183 ColumnType::VarBinary(StringLen::N(length))
184 }
185}
186
187#[derive(Debug, Clone, Default)]
188pub struct ColumnSpec {
189 pub nullable: Option<bool>,
190 pub default: Option<Expr>,
191 pub auto_increment: bool,
192 pub unique: bool,
193 pub primary_key: bool,
194 pub check: Option<Check>,
195 pub generated: Option<Generated>,
196 pub extra: Option<String>,
197 pub comment: Option<String>,
198 pub using: Option<Expr>,
199}
200
201#[derive(Debug, Clone)]
202pub struct Generated {
203 pub expr: Expr,
204 pub stored: bool,
205}
206
207// All interval fields
208#[derive(Debug, Clone, Eq, PartialEq)]
209#[non_exhaustive]
210pub enum PgInterval {
211 Year,
212 Month,
213 Day,
214 Hour,
215 Minute,
216 Second,
217 YearToMonth,
218 DayToHour,
219 DayToMinute,
220 DayToSecond,
221 HourToMinute,
222 HourToSecond,
223 MinuteToSecond,
224}
225
226// All possible inputs to DATE_TRUNC (https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC)
227#[derive(Debug, Clone, Eq, PartialEq)]
228#[non_exhaustive]
229pub enum PgDateTruncUnit {
230 Microseconds,
231 Milliseconds,
232 Second,
233 Minute,
234 Hour,
235 Day,
236 Week,
237 Month,
238 Quarter,
239 Year,
240 Decade,
241 Century,
242 Millennium,
243}
244
245impl fmt::Display for PgDateTruncUnit {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 let text = match self {
248 PgDateTruncUnit::Microseconds => "microseconds",
249 PgDateTruncUnit::Milliseconds => "milliseconds",
250 PgDateTruncUnit::Second => "second",
251 PgDateTruncUnit::Minute => "minute",
252 PgDateTruncUnit::Hour => "hour",
253 PgDateTruncUnit::Day => "day",
254 PgDateTruncUnit::Week => "week",
255 PgDateTruncUnit::Month => "month",
256 PgDateTruncUnit::Quarter => "quarter",
257 PgDateTruncUnit::Year => "year",
258 PgDateTruncUnit::Decade => "decade",
259 PgDateTruncUnit::Century => "century",
260 PgDateTruncUnit::Millennium => "millennium",
261 };
262 f.write_str(text)
263 }
264}
265
266impl ColumnDef {
267 /// Construct a table column
268 pub fn new<T>(name: T) -> Self
269 where
270 T: IntoIden,
271 {
272 Self {
273 table: None,
274 name: name.into_iden(),
275 types: None,
276 spec: ColumnSpec::default(),
277 }
278 }
279
280 /// Construct a table column with column type
281 pub fn new_with_type<T>(name: T, types: ColumnType) -> Self
282 where
283 T: IntoIden,
284 {
285 Self {
286 table: None,
287 name: name.into_iden(),
288 types: Some(types),
289 spec: ColumnSpec::default(),
290 }
291 }
292
293 /// Set column not null
294 pub fn not_null(&mut self) -> &mut Self {
295 self.spec.nullable = Some(false);
296 self
297 }
298
299 /// Set column null
300 pub fn null(&mut self) -> &mut Self {
301 self.spec.nullable = Some(true);
302 self
303 }
304
305 /// Set default expression of a column
306 ///
307 /// ```
308 /// use sea_query::{tests_cfg::*, *};
309 ///
310 /// let table = Table::create()
311 /// .table(Char::Table)
312 /// .col(ColumnDef::new(Char::FontId).integer().default(12i32))
313 /// .col(
314 /// ColumnDef::new(Char::CreatedAt)
315 /// .timestamp()
316 /// .default(Expr::current_timestamp())
317 /// .not_null(),
318 /// )
319 /// .to_owned();
320 ///
321 /// assert_eq!(
322 /// table.to_string(MysqlQueryBuilder),
323 /// [
324 /// "CREATE TABLE `character` (",
325 /// "`font_id` int DEFAULT 12,",
326 /// "`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP",
327 /// ")",
328 /// ]
329 /// .join(" ")
330 /// );
331 ///
332 /// assert_eq!(
333 /// table.to_string(PostgresQueryBuilder),
334 /// [
335 /// r#"CREATE TABLE "character" ("#,
336 /// r#""font_id" integer DEFAULT 12,"#,
337 /// r#""created_at" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"#,
338 /// r#")"#,
339 /// ]
340 /// .join(" ")
341 /// );
342 /// ```
343 pub fn default<T>(&mut self, value: T) -> &mut Self
344 where
345 T: Into<Expr>,
346 {
347 self.spec.default = Some(value.into());
348 self
349 }
350
351 /// Set column auto increment
352 pub fn auto_increment(&mut self) -> &mut Self {
353 self.spec.auto_increment = true;
354 self
355 }
356
357 /// Set column unique constraint
358 pub fn unique_key(&mut self) -> &mut Self {
359 self.spec.unique = true;
360 self
361 }
362
363 /// Set column as primary key
364 pub fn primary_key(&mut self) -> &mut Self {
365 self.spec.primary_key = true;
366 self
367 }
368
369 /// Set column type as char with custom length
370 pub fn char_len(&mut self, length: u32) -> &mut Self {
371 self.types = Some(ColumnType::Char(Some(length)));
372 self
373 }
374
375 /// Set column type as char
376 pub fn char(&mut self) -> &mut Self {
377 self.types = Some(ColumnType::Char(None));
378 self
379 }
380
381 /// Set column type as string with custom length
382 pub fn string_len(&mut self, length: u32) -> &mut Self {
383 self.types = Some(ColumnType::String(StringLen::N(length)));
384 self
385 }
386
387 /// Set column type as string
388 pub fn string(&mut self) -> &mut Self {
389 self.types = Some(ColumnType::String(Default::default()));
390 self
391 }
392
393 /// Set column type as text
394 pub fn text(&mut self) -> &mut Self {
395 self.types = Some(ColumnType::Text);
396 self
397 }
398
399 /// Set column type as tiny_integer
400 pub fn tiny_integer(&mut self) -> &mut Self {
401 self.types = Some(ColumnType::TinyInteger);
402 self
403 }
404
405 /// Set column type as small_integer
406 pub fn small_integer(&mut self) -> &mut Self {
407 self.types = Some(ColumnType::SmallInteger);
408 self
409 }
410
411 /// Set column type as integer
412 pub fn integer(&mut self) -> &mut Self {
413 self.types = Some(ColumnType::Integer);
414 self
415 }
416
417 /// Set column type as big_integer
418 pub fn big_integer(&mut self) -> &mut Self {
419 self.types = Some(ColumnType::BigInteger);
420 self
421 }
422
423 /// Set column type as tiny_unsigned
424 pub fn tiny_unsigned(&mut self) -> &mut Self {
425 self.types = Some(ColumnType::TinyUnsigned);
426 self
427 }
428
429 /// Set column type as small_unsigned
430 pub fn small_unsigned(&mut self) -> &mut Self {
431 self.types = Some(ColumnType::SmallUnsigned);
432 self
433 }
434
435 /// Set column type as unsigned
436 pub fn unsigned(&mut self) -> &mut Self {
437 self.types = Some(ColumnType::Unsigned);
438 self
439 }
440
441 /// Set column type as big_unsigned
442 pub fn big_unsigned(&mut self) -> &mut Self {
443 self.types = Some(ColumnType::BigUnsigned);
444 self
445 }
446
447 /// Set column type as float
448 pub fn float(&mut self) -> &mut Self {
449 self.types = Some(ColumnType::Float);
450 self
451 }
452
453 /// Set column type as double
454 pub fn double(&mut self) -> &mut Self {
455 self.types = Some(ColumnType::Double);
456 self
457 }
458
459 /// Set column type as decimal with custom precision and scale
460 pub fn decimal_len(&mut self, precision: u32, scale: u32) -> &mut Self {
461 self.types = Some(ColumnType::Decimal(Some((precision, scale))));
462 self
463 }
464
465 /// Set column type as decimal
466 pub fn decimal(&mut self) -> &mut Self {
467 self.types = Some(ColumnType::Decimal(None));
468 self
469 }
470
471 /// Set column type as date_time
472 pub fn date_time(&mut self) -> &mut Self {
473 self.types = Some(ColumnType::DateTime);
474 self
475 }
476
477 /// Set column type as interval type with optional fields and precision. Postgres only
478 ///
479 /// ```
480 /// use sea_query::{tests_cfg::*, *};
481 /// assert_eq!(
482 /// Table::create()
483 /// .table(Glyph::Table)
484 /// .col(ColumnDef::new("I1").interval(None, None).not_null())
485 /// .col(
486 /// ColumnDef::new("I2")
487 /// .interval(Some(PgInterval::YearToMonth), None)
488 /// .not_null()
489 /// )
490 /// .col(ColumnDef::new("I3").interval(None, Some(42)).not_null())
491 /// .col(
492 /// ColumnDef::new("I4")
493 /// .interval(Some(PgInterval::Hour), Some(43))
494 /// .not_null()
495 /// )
496 /// .to_string(PostgresQueryBuilder),
497 /// [
498 /// r#"CREATE TABLE "glyph" ("#,
499 /// r#""I1" interval NOT NULL,"#,
500 /// r#""I2" interval YEAR TO MONTH NOT NULL,"#,
501 /// r#""I3" interval(42) NOT NULL,"#,
502 /// r#""I4" interval HOUR(43) NOT NULL"#,
503 /// r#")"#,
504 /// ]
505 /// .join(" ")
506 /// );
507 /// ```
508 #[cfg(feature = "backend-postgres")]
509 pub fn interval(&mut self, fields: Option<PgInterval>, precision: Option<u32>) -> &mut Self {
510 self.types = Some(ColumnType::Interval(fields, precision));
511 self
512 }
513
514 #[cfg(feature = "postgres-vector")]
515 pub fn vector(&mut self, size: Option<u32>) -> &mut Self {
516 self.types = Some(ColumnType::Vector(size));
517 self
518 }
519
520 /// Set column type as timestamp
521 pub fn timestamp(&mut self) -> &mut Self {
522 self.types = Some(ColumnType::Timestamp);
523 self
524 }
525
526 /// Set column type as timestamp with time zone. Postgres only
527 pub fn timestamp_with_time_zone(&mut self) -> &mut Self {
528 self.types = Some(ColumnType::TimestampWithTimeZone);
529 self
530 }
531
532 /// Set column type as time
533 pub fn time(&mut self) -> &mut Self {
534 self.types = Some(ColumnType::Time);
535 self
536 }
537
538 /// Set column type as date
539 pub fn date(&mut self) -> &mut Self {
540 self.types = Some(ColumnType::Date);
541 self
542 }
543
544 /// Set column type as year
545 /// Only MySQL supports year
546 pub fn year(&mut self) -> &mut Self {
547 self.types = Some(ColumnType::Year);
548 self
549 }
550
551 /// Set column type as binary with custom length
552 pub fn binary_len(&mut self, length: u32) -> &mut Self {
553 self.types = Some(ColumnType::Binary(length));
554 self
555 }
556
557 /// Set column type as binary with default length of 1
558 pub fn binary(&mut self) -> &mut Self {
559 self.binary_len(1)
560 }
561
562 /// Set column type as binary with variable length
563 pub fn var_binary(&mut self, length: u32) -> &mut Self {
564 self.types = Some(ColumnType::VarBinary(StringLen::N(length)));
565 self
566 }
567
568 /// Set column type as bit with variable length
569 pub fn bit(&mut self, length: Option<u32>) -> &mut Self {
570 self.types = Some(ColumnType::Bit(length));
571 self
572 }
573
574 /// Set column type as varbit with variable length
575 pub fn varbit(&mut self, length: u32) -> &mut Self {
576 self.types = Some(ColumnType::VarBit(length));
577 self
578 }
579
580 /// Set column type as blob
581 pub fn blob(&mut self) -> &mut Self {
582 self.types = Some(ColumnType::Blob);
583 self
584 }
585
586 /// Set column type as boolean
587 pub fn boolean(&mut self) -> &mut Self {
588 self.types = Some(ColumnType::Boolean);
589 self
590 }
591
592 /// Set column type as money with custom precision and scale
593 pub fn money_len(&mut self, precision: u32, scale: u32) -> &mut Self {
594 self.types = Some(ColumnType::Money(Some((precision, scale))));
595 self
596 }
597
598 /// Set column type as money
599 pub fn money(&mut self) -> &mut Self {
600 self.types = Some(ColumnType::Money(None));
601 self
602 }
603
604 /// Set column type as json.
605 pub fn json(&mut self) -> &mut Self {
606 self.types = Some(ColumnType::Json);
607 self
608 }
609
610 /// Set column type as json binary.
611 pub fn json_binary(&mut self) -> &mut Self {
612 self.types = Some(ColumnType::JsonBinary);
613 self
614 }
615
616 /// Set column type as uuid
617 pub fn uuid(&mut self) -> &mut Self {
618 self.types = Some(ColumnType::Uuid);
619 self
620 }
621
622 /// Use a custom type on this column.
623 ///
624 /// # Example
625 ///
626 /// ```
627 /// use sea_query::{tests_cfg::*, *};
628 ///
629 /// let table = Table::create()
630 /// .table(Char::Table)
631 /// .col(
632 /// ColumnDef::new(Char::Id)
633 /// .custom("new_type")
634 /// .not_null()
635 /// .primary_key(),
636 /// )
637 /// .to_owned();
638 ///
639 /// assert_eq!(
640 /// table.to_string(MysqlQueryBuilder),
641 /// [
642 /// r#"CREATE TABLE `character` ("#,
643 /// r#"`id` new_type NOT NULL PRIMARY KEY"#,
644 /// r#")"#,
645 /// ]
646 /// .join(" ")
647 /// );
648 /// assert_eq!(
649 /// table.to_string(PostgresQueryBuilder),
650 /// [
651 /// r#"CREATE TABLE "character" ("#,
652 /// r#""id" new_type NOT NULL PRIMARY KEY"#,
653 /// r#")"#,
654 /// ]
655 /// .join(" ")
656 /// );
657 /// assert_eq!(
658 /// table.to_string(SqliteQueryBuilder),
659 /// [
660 /// r#"CREATE TABLE "character" ("#,
661 /// r#""id" new_type NOT NULL PRIMARY KEY"#,
662 /// r#")"#,
663 /// ]
664 /// .join(" ")
665 /// );
666 /// ```
667 pub fn custom<T>(&mut self, name: T) -> &mut Self
668 where
669 T: IntoIden,
670 {
671 self.types = Some(ColumnType::Custom(name.into_iden()));
672 self
673 }
674
675 /// Set column type as enum.
676 pub fn enumeration<N, S, V>(&mut self, name: N, variants: V) -> &mut Self
677 where
678 N: IntoIden,
679 S: IntoIden,
680 V: IntoIterator<Item = S>,
681 {
682 self.types = Some(ColumnType::Enum {
683 name: name.into_iden(),
684 variants: variants.into_iter().map(IntoIden::into_iden).collect(),
685 });
686 self
687 }
688
689 /// Set column type as an array with a specified element type.
690 /// This is only supported on Postgres.
691 pub fn array(&mut self, elem_type: ColumnType) -> &mut Self {
692 self.types = Some(ColumnType::Array(RcOrArc::new(elem_type)));
693 self
694 }
695
696 /// Set columnt type as cidr.
697 /// This is only supported on Postgres.
698 pub fn cidr(&mut self) -> &mut Self {
699 self.types = Some(ColumnType::Cidr);
700 self
701 }
702
703 /// Set columnt type as inet.
704 /// This is only supported on Postgres.
705 pub fn inet(&mut self) -> &mut Self {
706 self.types = Some(ColumnType::Inet);
707 self
708 }
709
710 /// Set columnt type as macaddr.
711 /// This is only supported on Postgres.
712 pub fn mac_address(&mut self) -> &mut Self {
713 self.types = Some(ColumnType::MacAddr);
714 self
715 }
716
717 /// Set column type as `ltree`
718 /// This is only supported on Postgres.
719 ///
720 /// ```
721 /// use sea_query::{tests_cfg::*, *};
722 /// assert_eq!(
723 /// Table::create()
724 /// .table(Glyph::Table)
725 /// .col(
726 /// ColumnDef::new(Glyph::Id)
727 /// .integer()
728 /// .not_null()
729 /// .auto_increment()
730 /// .primary_key()
731 /// )
732 /// .col(ColumnDef::new(Glyph::Tokens).ltree())
733 /// .to_string(PostgresQueryBuilder),
734 /// [
735 /// r#"CREATE TABLE "glyph" ("#,
736 /// r#""id" integer GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY,"#,
737 /// r#""tokens" ltree"#,
738 /// r#")"#,
739 /// ]
740 /// .join(" ")
741 /// );
742 /// ```
743 pub fn ltree(&mut self) -> &mut Self {
744 self.types = Some(ColumnType::LTree);
745 self
746 }
747
748 /// Set constraints as Expr
749 ///
750 /// ```
751 /// use sea_query::{tests_cfg::*, *};
752 ///
753 /// assert_eq!(
754 /// Table::create()
755 /// .table(Glyph::Table)
756 /// .col(
757 /// ColumnDef::new(Glyph::Id)
758 /// .integer()
759 /// .not_null()
760 /// .check(Expr::col(Glyph::Id).gt(10))
761 /// )
762 /// .to_string(MysqlQueryBuilder),
763 /// r#"CREATE TABLE `glyph` ( `id` int NOT NULL CHECK (`id` > 10) )"#,
764 /// );
765 ///
766 /// assert_eq!(
767 /// Table::create()
768 /// .table(Glyph::Table)
769 /// .col(
770 /// ColumnDef::new(Glyph::Id)
771 /// .integer()
772 /// .not_null()
773 /// .check(("positive_id", Expr::col(Glyph::Id).gt(10)))
774 /// )
775 /// .to_string(MysqlQueryBuilder),
776 /// r#"CREATE TABLE `glyph` ( `id` int NOT NULL CONSTRAINT `positive_id` CHECK (`id` > 10) )"#,
777 /// );
778 /// ```
779 pub fn check<T>(&mut self, check: T) -> &mut Self
780 where
781 T: Into<Check>,
782 {
783 self.spec.check = Some(check.into());
784 self
785 }
786
787 /// Sets the column as generated with Expr
788 pub fn generated<T>(&mut self, expr: T, stored: bool) -> &mut Self
789 where
790 T: Into<Expr>,
791 {
792 self.spec.generated = Some(Generated {
793 expr: expr.into(),
794 stored,
795 });
796 self
797 }
798
799 /// Some extra options in custom string
800 /// ```
801 /// use sea_query::{tests_cfg::*, *};
802 /// let table = Table::create()
803 /// .table(Char::Table)
804 /// .col(
805 /// ColumnDef::new(Char::Id)
806 /// .uuid()
807 /// .extra("DEFAULT gen_random_uuid()")
808 /// .primary_key()
809 /// .not_null(),
810 /// )
811 /// .col(
812 /// ColumnDef::new(Char::CreatedAt)
813 /// .timestamp_with_time_zone()
814 /// .extra("DEFAULT NOW()")
815 /// .not_null(),
816 /// )
817 /// .to_owned();
818 /// assert_eq!(
819 /// table.to_string(PostgresQueryBuilder),
820 /// [
821 /// r#"CREATE TABLE "character" ("#,
822 /// r#""id" uuid NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(),"#,
823 /// r#""created_at" timestamp with time zone NOT NULL DEFAULT NOW()"#,
824 /// r#")"#,
825 /// ]
826 /// .join(" ")
827 /// );
828 /// ```
829 pub fn extra<T>(&mut self, string: T) -> &mut Self
830 where
831 T: Into<String>,
832 {
833 self.spec.extra = Some(string.into());
834 self
835 }
836
837 /// Some extra options in custom string
838 /// ```
839 /// use sea_query::{tests_cfg::*, *};
840 /// let table = Table::alter()
841 /// .table(Char::Table)
842 /// .modify_column(
843 /// ColumnDef::new(Char::Id)
844 /// .integer()
845 /// .using(Expr::col(Char::Id).cast_as("integer")),
846 /// )
847 /// .to_owned();
848 /// assert_eq!(
849 /// table.to_string(PostgresQueryBuilder),
850 /// [
851 /// r#"ALTER TABLE "character""#,
852 /// r#"ALTER COLUMN "id" TYPE integer USING CAST("id" AS integer)"#,
853 /// ]
854 /// .join(" ")
855 /// );
856 /// ```
857 pub fn using<T>(&mut self, value: T) -> &mut Self
858 where
859 T: Into<Expr>,
860 {
861 self.spec.using = Some(value.into());
862 self
863 }
864
865 /// MySQL only.
866 pub fn comment<T>(&mut self, string: T) -> &mut Self
867 where
868 T: Into<String>,
869 {
870 self.spec.comment = Some(string.into());
871 self
872 }
873
874 pub fn get_column_name(&self) -> String {
875 self.name.to_string()
876 }
877
878 pub fn get_column_type(&self) -> Option<&ColumnType> {
879 self.types.as_ref()
880 }
881
882 pub fn get_column_spec(&self) -> &ColumnSpec {
883 &self.spec
884 }
885
886 pub fn take(&mut self) -> Self {
887 Self {
888 table: self.table.take(),
889 name: std::mem::replace(&mut self.name, NullAlias::new().into_iden()),
890 types: self.types.take(),
891 spec: std::mem::take(&mut self.spec),
892 }
893 }
894}