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